pax_global_header00006660000000000000000000000064141705256760014527gustar00rootroot0000000000000052 comment=830a432d7754c7b30838af83950604d364bd3bcd RaySession-0.12.2/000077500000000000000000000000001417052567600137105ustar00rootroot00000000000000RaySession-0.12.2/.github/000077500000000000000000000000001417052567600152505ustar00rootroot00000000000000RaySession-0.12.2/.github/FUNDING.yml000066400000000000000000000000271417052567600170640ustar00rootroot00000000000000liberapay: Houston4444 RaySession-0.12.2/.gitignore000066400000000000000000000005421417052567600157010ustar00rootroot00000000000000#ignore hidden files except git and github /.* !/.github !/.git #UI builds /src/gui/ui/*.py /src/clients/proxy/ui_*.py #resources qt build /src/gui/resources_rc.py /src/.* /src/*/.* /src/*/*/.* #translations /locale/*.qm #python cache /src/*/__pycache__/ /src/*/*/__pycache__/ # ignore kdevelop file RaySession.kdev4 # ignore memo memo_snapshots RaySession-0.12.2/CHANGELOG000066400000000000000000000364031417052567600151300ustar00rootroot000000000000000.12.0 / 2021-1?-?? Features: Add "Startup" dialog which let you open a recent session. This way, just lanch RaySession and press Enter to load the last session. Add optional systray icon, activated only when a session is loaded, but user can also decide to use it always or never. "Open Session" dialog largely improved, user can now see clients, notes and snapshots in the session to load. We can also see session folder size and date, and if session contains scripts. It is also now possible to rename, duplicate or save as template a not loaded session, or to load in the current session a client from another session. add "long jack naming" checkbox in "add executable" dialog. Add "utility scripts" to menubar: convert an ardour session to a Ray session (containing this ardour session) Convert the current session to the NSM file format Convert Ray-Hack clients to NSM, for Jack-Mixer and Hydrogen Add "recent sessions" to menubar and to systray icon. Add "prevent overlap" default option, with this, when a box is moved on front of other ones, theses other boxes are moved elsewhere (near). double click on patchbay box to show/hide optional-gui, if this box is recognized as a client box Add 'Find a box' (Ctrl+F) filter bar, to highlight boxes matching with a given pattern Add 'Find patchbay boxes' in client menu, it highlights boxes of the client (if recognized with their name) Add box wrap button if box is fat. Limit patchbay port width, truncking port name in the middle, the max width can be changed in canvas options dialog Ports in portgroups can now be larger if their name requires that Specific decorations for pipewire Monitor clients ray_control: trashed_client remove_keep_files option added. Add :monitor: NSM capability, a client can now be aware of other clients events. Behavior changes: Patchbay is now shown by default. "Keep Focus while opening clients" option is now de-activated by default, its shortcut has been changed to Ctrl+H. In patchbay, if zoom is lower than 40%, a mouse click and drag anywhere in a box moves this box. Session file is now automatically saved in case of consequent changes: session renamed, client prefix changed, client definitely removed. Sessions in a session directory are not listed anymore, mostly for faster listing. Bug Fixes: Display true client names if "use graceful names" canvas option is unchecked Remove the vertical white line on the left, in fullscreen patchbay No more possibility to see boxes with no ports Fix connections moving with a delay in case of fast box move. Fix too long or empty Midi-Bridge port names with pipewire option jack.filter_name=true fix crashes with recent versions of python or python-qt consider '/' as box title divisor only if it seems to be a client of session, and this way prevent some pipewire titles to be wrongly splitted fix crashes because of recursives error while moving a patchbay box. fix crash with Ray-Net (Network Session) save client template action sooperlooper_nsm now follows given jack_client_name (with option, to prevent connections loses) New Templates: seq192 0.11.1 / 2021-08-27 Bug Fixes: fix GUI crash when showing snapshots without config for info dialog fix missing icons and applications infos in "Add Application" dialog under Fedora fix patchbay context menu displayed at wrong place under Wayland grey background for all QGroupBox, because some qt styles doesn't separate them from the rest of window (grrr...), and it becomes not understandable). patchbay: ardour "physical_audio_input_monitor_enable" becomes "physical monitor" with graceful names enable, same for midi Improvements: Manual : style review and patchbay section added Patchbay boxes allow 3 or 4 lines title, because PipeWire uses sometimes veryyyy long group names for hardware boxes 0.11.0 / 2021-08-05 The most important new feature in this release is the apparition of the JACK patchbay. You also can press Ctrl+J to show/hide the patchbay. The patchbay has been forked from Carla, with some improvements. For the moment, there are only 3 advantages to have the patchbay directly in RaySession's GUI Boxes positions are memorized and replaced per session Boxes have icons of the corresponding NSM client of course: only one window for two things you generally need in a session Note that : The session frame is now "responsive design" to be reduced in width and allow more space to the patchbay. messages were moved from the right to the bottom left (under the session frame) The list below concerns the improvements of patchbay: Most important probably: portgroups and stereo detection. Ports are automatically grouped into a portgroup if they seems to form a stereo pair. This allows faster connections, and also a more readable canvas, with less and less useless text. This improve has been proposed for PR to Carla. Portgroups can be also set by JACK metadatas, and without limitation of number of ports. wrap/unwrap boxes: you can hide all ports of a box, very useful for big groups as Ardour or Hydrogen boxes. Hide what you don't need let's you see better what you need ! hardware boxes have specific decorations Port order follows JACK metadata "port-order" Boxes have their application icon if possible. Box header is a little higher, but it allows box to be consequently shorter in width in case group name is long. connect menu by right click: by right click on a port, you can directly connect the port to any connectable port of the canvas. Connect a port doesn't close the context menu, so you can connect to many ports quickly. It also works for portgroups. Clipboard: cut/copy connections of a port to another port, in port context menu. Also works for portgroups. filter ports: by right click in the background, you can display only Audio ports, or only MIDI ports, or all ports of course. when you click and drag to connect 2 ports, you also can connect with right click (while keeping left mouse button down), this way you can connect quickly one port to many others. with click and drag on a port, you can also move to a port with same mode (input/output), it will cut and copy connections from the first port to the second one. To prevent wrong movements, it works only if the second port has no connections Beziers connections lines have been reviewed to be more visible when the ports are close in abscissa and distant in ordinate canvas option window is a tool dialog where options take effect on place graceful names (default option): port names are shortened with custom rules, it doesn't uses JACK aliases. Allow boxes to be less large. elastic canvas (default option): the scene is automatically resized to the contents, so the view is directly optimized when group is added or moved option to group or not hardware A2J ports Box moves are animated when they are moved to their session position, when the port type filter change, or when they are joined/splitted Double-click anywhere in patchbay to toggle fullscreen patchbay Regressions: No option to use straight lines instead of bezier lines, I find it very ugly and unusable No option to animate box apparition No theme support, only color scheme 0.10.1 / 2021-02-04 Manual: Add a complete online and offline manual accessible from the help tab of the menu bar. It opens RaySession's manual in your web browser. Note that english is not my mother language, corrections are welcome. Bug Fixes: Client label is now grayed out when client is added stopped Jack config memory script won't prevent anymore to load the session if ALSA device is set to 'none' French translation fixes (thanks to Olivier Humbert) New Template: Rakarack-plus 0.10.0 / 2020-11-10 New Features: Add option "Remember optional GUI states" which recalls the optional GUIs visibility state Add Application dialog largely improved with access to all possible informations about the templates Session Notes dialog where you can edit...session notes 'duplicate', 'save session as template' and 'rename session' moved to a menu at top left of the session frame provide log files in ~/.config/RaySession/logs/ improve open session dialog behavior between filter bar and treelist add "Make Reappear all hidden dialogs" action add RayNet client protocol, which is used only for Network Sessions change icon for optional GUI visible/hidden (shamelessly pricked idea at Agordejo) ray_control : add_client_template not started option added clients now remember their template origin "save as template" button becomes "Update the Template" in save as template (session/client) dialog if template exists Jack config script now saves all pulse2jack configurations, even the more complex ones API change: raysession's --session argument has been replaced with --start-session because --session was taken by Qt, -s still works fine Bug Fixes: Now translated in french for french speaking users out of France Add all default Qt translations raysession should connect to a running daemon without GUI, even after a GUI crash (GUI crash should not happen of course ;) ) ray_control start now start with the good session root if it is not the default one (~/Ray Sessions) remove Hydrogen NSM template because RayHack template is safer for now Sequencer64 template has a -m option to work fine with JACK connections New Templates: Xtuner Mamba 0.9.2 / 2020-08-01 Bug Fix: Strong: Fix empty client templates list if there was no user client template 0.9.1 / 2020-07-21 Bug Fix: Remove a binary file added by error to source code 0.9.0 / 2020-07-16 New Features: CLI: Control allmost all GUI actions and more with the CLI ray_control. Session scripts: allow user to edit shell scripts at session load, save and close. JACK config session script: script that saves and recalls the JACK configuration for the session. Add this from session templates in "New Session" window. RayHack: New client protocol which is an alternative to ray-proxy. This allows to launch directly the process and to edit its properties even if process is stopped. I know this feature will be considered as heretic by someones, this is not strong, I know it doesn't changes things too much. Factory client templates are installed in /etc/xdg/raysession to allow packagers to add some templates. Get client label, icon and description from their .desktop file. Subfolder combobox removed in New Session Dialog Daemon option "Save from client" has been removed. Please affect a global keyboard shortcut (Meta+Ctrl+S) to ray_control save instead. 0.8.3 / 2019-11-25 This release fixes the link for src/bin/ray_control from absolute to relative path. Sorry for the inconvenience. 0.8.2 / 2019-11-20 this new version is here to fix a big bug with snapshots. If user name and user email were not mentioned to git, snapshot always failed with some versions of git. Fix snapshot/git bug Fix network session not working Provide fallback icons for allmost all system icons add little script 'ray_control', this way you can use 'ray_control save' to save your running session (and affect this to a global keyboard shortcut (eg, Meta+Ctrl+S)). 0.8.1 / 2019-10-23 Just a bug fix release. In v0.8.0 , first session creation failed (first session of the directory (e.g. ~/Ray Sessions/first session). Ray Session has also been renamed to RaySession everywhere it was. 0.8.0 / 2019-10-15 Autumn Release. This release contains many new features. Mainly the snapshot manager. Snapshot manager (requires git): Take a snapshot at each session save. User can go back to a previous snapshot with the "rewind" button at the right of "executable" button. See "snapshots explain" file in code root for more info. Proxy: Improve integration of non savable clients. Possibility to display a special save icon and prevent accidental close on RaySession in this case. Try to close gracefully client window is possible (requires wmctrl). Favorites: User can quickly add a favorite template with "Favorites" button or with a right click below clients. Add Application dialog: Now shows an "User" icon at right of each user template, click on it to remove this template. Click on favorite icon to add the template to favorites. Double click on template to launch it. Open Session dialog: Now shows all session in a tree-view (if some sessions are under a sub-folder). Double-click on session to open it. New Session Dialog: If some sessions are in a sub-folder, shows a sub-folder combo box for the new session. Add Executable Dialog: Click on "Show More Options" to change Prefix or client_id. Useful to integrate in the session files made outside (for advanced users). Client Properties Dialog: global re-design, edit line added to edit extensions ignored for snapshots. add a donations Dialog NSM Compatibility review: Possibility to launch a client externally with the environment variable NSM_URL, Absolute PATH are not allowed anymore when adding an executable. Integration of server-control NSM OSC messages which try to reproduce exact NSM behavior. Bug Fix: fix prevent desktop session disconnection (on KDE and maybe other ones desktops). 0.7.2 / 2019-07-15 New Application Templates for OPNplug* and amsynth. fix unsaved stop signal in ray-proxy faster pid check for desktops memory Thanks to jpcima for the OPNplug template pull request. 0.7.1 / 2019-01-16 Bug Fixes: Fix bug with drag and drop client items. Clients order wasn't saved. Fix untranslated proxy window. Fix non removed stopped clients at session close. Fix search of switchable clients if client executable or arguments have been recently modified Now send hide_optional_gui to client only once "open" has been sent. This can now makes some window flashes but it did make crash some softwares as Patroneo and Fluajho. New Templates: Add Patroneo and Fluajho templates to Factory 0.7.0 / 2019-01-07 New features: New Option (activated by default): provide bookmark (shortcut) of the session folder for gtk2, gtk3, qt4, qt5, fltk and kde5 file pickers. New Option: Desktops Memory (requires wmctrl). If activated, clients windows will be moved to the given desktop when session is ready, or when a client is ready. It may not works depending on your D.E. Edit executable and arguments in client properties window. Arguments are supposed to be not supported by NSM. Sometimes it works and it can be useful. option -s to load session at startup ray-proxy: new option "wait window for reply" (requires wmctrl) sooperlooper_nsm: option to pause and trig with jack_transport events (play/pause) new factory templates for ADLplug, Petri-Foo, Shuriken, Sequencer64 and SooperLooper +Transport RaySession-0.12.2/COPYING000066400000000000000000000355641417052567600147600ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS RaySession-0.12.2/INSTALL.md000066400000000000000000000022151417052567600153400ustar00rootroot00000000000000# --- INSTALL for RAYSESSION --- Before installing, please uninstall any existing RaySession installation:
`$ [sudo] make uninstall` To install RaySession, simply run as usual:
`$ make`
`$ [sudo] make install` depending of the distribution you'll need to use LRELEASE variable to install. If you don't have 'lrelease' executable but 'lrelease-qt5' use: `$ make LRELEASE=lrelease-qt5`
`$ [sudo] make install` You can run RaySession without install, by using instead:
`$ make`
`$ ./src/bin/raysession` Packagers can make use of the 'PREFIX' and 'DESTDIR' variable during install, like this:
`$ make install PREFIX=/usr DESTDIR=./test-dir` To uninstall RaySession, run:
`$ [sudo] make uninstall`
===== BUILD DEPENDENCIES ===== -------------------------------- The required build dependencies are: (devel packages of these) - PyQt5 - Qt5 dev tools - qtchooser On Debian and Ubuntu, use these commands to install all build dependencies:
`$ sudo apt-get install python3-pyqt5 pyqt5-dev-tools qtchooser qttools5-dev-tools` To run it, you'll additionally need: - python3-liblo - pyxdg RaySession-0.12.2/Makefile000066400000000000000000000204301417052567600153470ustar00rootroot00000000000000#!/usr/bin/make -f # Makefile for RaySession # # ---------------------- # # Created by houston4444 # PREFIX ?= /usr/local DESTDIR = DEST_RAY := $(DESTDIR)$(PREFIX)/share/raysession LINK = ln -s -f PYUIC := pyuic5 PYRCC := pyrcc5 LRELEASE := lrelease ifeq (, $(shell which $(LRELEASE))) LRELEASE := lrelease-qt5 endif ifeq (, $(shell which $(LRELEASE))) LRELEASE := lrelease-qt4 endif PYTHON := python3 ifeq (, $(shell which $(PYTHON))) PYTHON := python endif # ----------------------------------------------------------------------------------------------------------------------------------------- all: RES UI LOCALE # ----------------------------------------------------------------------------------------------------------------------------------------- # Resources RES: src/gui/resources_rc.py src/gui/resources_rc.py: resources/resources.qrc $(PYRCC) $< -o $@ # ----------------------------------------------------------------------------------------------------------------------------------------- # UI code UI: mkdir_ui raysession ray_proxy mkdir_ui: @if ! [ -e src/gui/ui ];then mkdir -p src/gui/ui; fi raysession: src/gui/ui/abort_copy.py \ src/gui/ui/abort_session.py \ src/gui/ui/about_raysession.py \ src/gui/ui/add_application.py \ src/gui/ui/ardour_convert.py \ src/gui/ui/canvas_options.py \ src/gui/ui/canvas_port_info.py \ src/gui/ui/client_properties.py \ src/gui/ui/client_rename.py \ src/gui/ui/client_slot.py \ src/gui/ui/client_trash.py \ src/gui/ui/donations.py \ src/gui/ui/daemon_url.py \ src/gui/ui/error_dialog.py \ src/gui/ui/filter_frame.py \ src/gui/ui/hydro_rh_nsm.py \ src/gui/ui/jack_config_info.py \ src/gui/ui/list_snapshots.py \ src/gui/ui/new_executable.py \ src/gui/ui/new_session.py \ src/gui/ui/nsm_properties.py \ src/gui/ui/ray_hack_copy.py \ src/gui/ui/nsm_open_info.py \ src/gui/ui/open_session.py \ src/gui/ui/patchbay_tools.py \ src/gui/ui/preview_client_slot.py \ src/gui/ui/quit_app.py \ src/gui/ui/ray_hack_properties.py \ src/gui/ui/ray_net_properties.py \ src/gui/ui/ray_to_nsm.py \ src/gui/ui/raysession.py \ src/gui/ui/remove_template.py \ src/gui/ui/save_template_session.py \ src/gui/ui/session_scripts_info.py \ src/gui/ui/script_info.py \ src/gui/ui/script_user_action.py \ src/gui/ui/session_notes.py \ src/gui/ui/snapshot_name.py \ src/gui/ui/snapshots_info.py \ src/gui/ui/snapshot_progress.py \ src/gui/ui/startup_dialog.py \ src/gui/ui/systray_close.py \ src/gui/ui/systray_management.py \ src/gui/ui/stop_client.py \ src/gui/ui/stop_client_no_save.py \ src/gui/ui/template_slot.py \ src/gui/ui/waiting_close_user.py src/gui/ui/%.py: resources/ui/%.ui $(PYUIC) $< -o $@ ray_proxy: src/clients/proxy/ui_proxy_copy.py \ src/clients/proxy/ui_proxy_gui.py src/clients/proxy/ui_%.py: resources/ui/%.ui $(PYUIC) $< -o $@ PY_CACHE: $(PYTHON) -m compileall src/ # ----------------------------------------------------------------------------------------------------------------------------------------- # # Translations Files LOCALE: locale locale: locale/raysession_en.qm locale/raysession_fr.qm locale/%.qm: locale/%.ts $(LRELEASE) $< -qm $@ # ----------------------------------------------------------------------------------------------------------------------------------------- clean: rm -f *~ src/*~ src/*.pyc src/clients/proxy/ui_*.py \ src/gui/resources_rc.py locale/*.qm rm -f -R src/gui/ui rm -f -R src/__pycache__ src/*/__pycache__ src/*/*/__pycache__ # ----------------------------------------------------------------------------------------------------------------------------------------- debug: $(MAKE) DEBUG=true # ----------------------------------------------------------------------------------------------------------------------------------------- install: # Create directories install -d $(DESTDIR)$(PREFIX)/bin/ install -d $(DESTDIR)$(PREFIX)/share/applications/ install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/16x16/apps/ install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/24x24/apps/ install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/32x32/apps/ install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps/ install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/64x64/apps/ install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/96x96/apps/ install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/128x128/apps/ install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/256x256/apps/ install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/ install -d $(DEST_RAY)/ install -d $(DEST_RAY)/locale/ install -d $(DESTDIR)/etc/xdg/ install -d $(DESTDIR)/etc/xdg/raysession/ install -d $(DESTDIR)/etc/xdg/raysession/client_templates/ # Copy Templates Factory cp -r client_templates/40_ray_nsm $(DESTDIR)/etc/xdg/raysession/client_templates/ cp -r client_templates/60_ray_lash $(DESTDIR)/etc/xdg/raysession/client_templates/ cp -r client_templates $(DEST_RAY)/ cp -r session_templates $(DEST_RAY)/ cp -r session_scripts $(DEST_RAY)/ cp -r data $(DEST_RAY)/ # Copy Desktop Files install -m 644 data/share/applications/*.desktop \ $(DESTDIR)$(PREFIX)/share/applications/ # Install icons install -m 644 resources/16x16/raysession.png \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/16x16/apps/ install -m 644 resources/24x24/raysession.png \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/24x24/apps/ install -m 644 resources/32x32/raysession.png \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/32x32/apps/ install -m 644 resources/48x48/raysession.png \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps/ install -m 644 resources/48x48/raysession.png \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps/ install -m 644 resources/64x64/raysession.png \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/64x64/apps/ install -m 644 resources/96x96/raysession.png \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/96x96/apps/ install -m 644 resources/128x128/raysession.png \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/128x128/apps/ install -m 644 resources/256x256/raysession.png \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/256x256/apps/ # Install icons, scalable install -m 644 resources/scalable/raysession.svg \ $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/ # Install main code cp -r src $(DEST_RAY)/ $(LINK) $(DEST_RAY)/src/bin/ray-jack_checker_daemon $(DESTDIR)$(PREFIX)/bin/ $(LINK) $(DEST_RAY)/src/bin/ray-jack_config_script $(DESTDIR)$(PREFIX)/bin/ $(LINK) $(DEST_RAY)/src/bin/ray-pulse2jack $(DESTDIR)$(PREFIX)/bin/ $(LINK) $(DEST_RAY)/src/bin/ray_git $(DESTDIR)$(PREFIX)/bin/ # compile python files $(PYTHON) -m compileall $(DEST_RAY)/src/ # install local manual cp -r manual $(DEST_RAY)/ # install utility-scripts cp -r utility-scripts $(DEST_RAY)/ # install main bash scripts to bin install -m 755 data/raysession $(DESTDIR)$(PREFIX)/bin/ install -m 755 data/ray-daemon $(DESTDIR)$(PREFIX)/bin/ install -m 755 data/ray_control $(DESTDIR)$(PREFIX)/bin/ install -m 755 data/ray-proxy $(DESTDIR)$(PREFIX)/bin/ # modify PREFIX in main bash scripts sed -i "s?X-PREFIX-X?$(PREFIX)?" \ $(DESTDIR)$(PREFIX)/bin/raysession \ $(DESTDIR)$(PREFIX)/bin/ray-daemon \ $(DESTDIR)$(PREFIX)/bin/ray_control \ $(DESTDIR)$(PREFIX)/bin/ray-proxy # Install Translations install -m 644 locale/*.qm $(DEST_RAY)/locale/ ----------------------------------------------------------------------------------------------------------------------------------------- uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/raysession rm -f $(DESTDIR)$(PREFIX)/bin/ray-daemon rm -f $(DESTDIR)$(PREFIX)/bin/ray-proxy rm -f $(DESTDIR)$(PREFIX)/bin/ray-jack_checker_daemon rm -f $(DESTDIR)$(PREFIX)/bin/ray-jack_config_script rm -f $(DESTDIR)$(PREFIX)/bin/ray-pulse2jack rm -f $(DESTDIR)$(PREFIX)/bin/ray_control rm -f $(DESTDIR)$(PREFIX)/bin/ray_git rm -f $(DESTDIR)$(PREFIX)/share/applications/raysession.desktop rm -f $(DESTDIR)$(PREFIX)/share/icons/hicolor/*/apps/raysession.png rm -f $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/raysession.svg rm -rf $(DESTDIR)/etc/xdg/raysession/client_templates/40_ray_nsm rm -rf $(DESTDIR)/etc/xdg/raysession/client_templates/60_ray_lash rm -rf $(DEST_RAY) RaySession-0.12.2/README.md000066400000000000000000000043061417052567600151720ustar00rootroot00000000000000# ![RaySession Logo](https://raw.githubusercontent.com/Houston4444/RaySession/master/resources/128x128/raysession.png) RaySession What is RaySession ? --------------------- ![Screenshot](https://raw.githubusercontent.com/Houston4444/RaySession/master/resources/screenshots/Screenshot_20211203_173011.png) RaySession is a GNU/Linux session manager for audio programs such as Ardour, Carla, QTractor, Guitarix, Patroneo, Jack Mixer, etc...
The principle is to load together audio programs, then be able to save or close all documents together.
Its main purpose is to manage NSM compatible programs, but it also helps for other programs.

it benefits from a nice patchbay, a [complete manual](https://raysession.tuxfamily.org/en/manual) as well as a splendid [web site](https://raysession.tuxfamily.org) .
An integrated client can save and restore JACK connections.
Except this, RaySession doesn't deals with JACK, the recommended user behavior is to use it when JACK is already started.
Features --------------------- * Load many programs together and remember their documents and jack connections in an unified folder * Nice patchbay with stereo connections, wrappable boxes and a search tool * Snapshot at each save (optional), then you can go back to the snapshot (it uses `git`) * Save client as template, and then restore it easily * Save session as template * Make almost all actions and get several informations with the CLI named `ray_control` * Script sessions and clients actions with shell scripts * Remember and recall JACK configuration with the jack_config session scripts * Having sub-sessions working through the network with the "Network Session" template * Remember the virtual desktop of the programs (requires `wmctrl`, doesn't works with Wayland) * Bookmark the current session folder in your file manager and file pickers (gtk, kde, qt, fltk) * Many others... ![Screenshot](https://raw.githubusercontent.com/Houston4444/RaySession/master/resources/screenshots/Screenshot_20211203_162333.png) You can see documentation on NSM protocol at: https://linuxaudio.github.io/new-session-manager/api/index.html RaySession is being developed by Mathieu Picot (houston4444), using Python3 and Qt5. RaySession-0.12.2/RaySession.kdev4000066400000000000000000000001151417052567600167430ustar00rootroot00000000000000[Project] CreatedFrom=Makefile Manager=KDevCustomMakeManager Name=RaySession RaySession-0.12.2/TODO000066400000000000000000000015571417052567600144100ustar00rootroot00000000000000client noSavelLevel gardé comme ça pour l'instant parce client.no_save_level existe -> Déprecier no_save_level de l'exterieur, uniquement en RayHack afficher le sous dossier -> preview ; session en cours Display server address in window title (network session). Icons with multiple possibilities ??? Start/Stop all clients f ray_control doc /ray/server/clear_client_templates_database Patchbay: Code linting Custom Theming Right click to wrap/unwrap box while connecting Fix other box moving too far after join Zones (far future) ? PW video ports ? Damn connections (with ray-jackpatch) generic icon for client set client id in add application dialog list ardour templates and select a template in add_application dialog for Ardour templates select client and patchbay boxes together (click another time to select another box) Forget connections of removed client RaySession-0.12.2/TRANSLATORS000066400000000000000000000011041417052567600154430ustar00rootroot00000000000000If you want to translate RaySession, you're welcome ! go to ./locale : cd locale copy file raysession_en_US.ts to raysession_xx_XX.ts replace xx and XX with the letters of your language. cp raysession_en_US.ts raysession_xx_XX.ts open your .ts file with QLinguist, make your translations and publish. in order to try it: go to parent dir: cd .. open Makefile in a text editor add raysession_xx_XX.qm to the Makefile (line 42) save Makefile then make: make RaySession-0.12.2/client_templates/000077500000000000000000000000001417052567600172445ustar00rootroot00000000000000RaySession-0.12.2/client_templates/40_ray_nsm/000077500000000000000000000000001417052567600212175ustar00rootroot00000000000000RaySession-0.12.2/client_templates/40_ray_nsm/client_templates.xml000066400000000000000000000116671417052567600253100ustar00rootroot00000000000000 RaySession-0.12.2/client_templates/60_ray_lash/000077500000000000000000000000001417052567600213535ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Calf JACK Host/000077500000000000000000000000001417052567600236075ustar00rootroot00000000000000XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX/000077500000000000000000000000001417052567600316405ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Calf JACK HostXXX_SESSION_NAME_XXX.calf000066400000000000000000000000661417052567600357320ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Calf JACK Host/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX RaySession-0.12.2/client_templates/60_ray_lash/Jack Mixer/000077500000000000000000000000001417052567600232705ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Jack Mixer/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX/000077500000000000000000000000001417052567600314005ustar00rootroot00000000000000XXX_SESSION_NAME_XXX.xml000066400000000000000000000002461417052567600353060ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Jack Mixer/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX RaySession-0.12.2/client_templates/60_ray_lash/QMidiRoute/000077500000000000000000000000001417052567600233755ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/QMidiRoute/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX/000077500000000000000000000000001417052567600315055ustar00rootroot00000000000000XXX_SESSION_NAME_XXX.qmr000066400000000000000000000000041417052567600354020ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/QMidiRoute/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX1 0 RaySession-0.12.2/client_templates/60_ray_lash/Qsampler/000077500000000000000000000000001417052567600231375ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Qsampler/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX/000077500000000000000000000000001417052567600312475ustar00rootroot00000000000000XXX_SESSION_NAME_XXX.lscp000066400000000000000000000005401417052567600353130ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Qsampler/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX# Qsampler - A LinuxSampler Qt GUI Interface # Version: 0.4.2 # Build: Dec 12 2017 23:26 +0000 # # File: test_megascène.lscp # Date: déc. 13 2017 22:49:48 # RESET # MIDI instrument map 0 - Chromatic ADD MIDI_INSTRUMENT_MAP 'Chromatic' # MIDI instrument map 1 - Drum Kits ADD MIDI_INSTRUMENT_MAP 'Drum Kits' # Global volume level SET VOLUME 0.35 RaySession-0.12.2/client_templates/60_ray_lash/Rakarrack-plus/000077500000000000000000000000001417052567600242355ustar00rootroot00000000000000XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX/000077500000000000000000000000001417052567600322665ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Rakarrack-plusXXX_SESSION_NAME_XXX.rkr000066400000000000000000000130241417052567600362470ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Rakarrack-plus/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX1.0.0 Ryan Billing Rodent Airlines 0.500000,0.500000,1.000000,0 -55,37,24,46,8050,76,1,1 36,91,0 0,64,35,105,48,26,1,5406,708,0,1,0,0,0 32,-44,0,0,110,2,1 0,64,0,160,0,0,0,56,4,0,0,0,/usr/share/rakarrack-plus/5.wav 64,20,25,50,1,64,93,40,6,48,0,58,1,0 -32,0,0,110,800,10,-27,16000,1,0,24,64,1,10,0,0 63,28,39,8,0,10,0,64,3,32,4,64,1,1,0,1,1,/usr/share/rakarrack-plus/4.dly 64,17,1,400,0,0,34,6,1,0,0,64,1,0,2524,0,1,/usr/share/rakarrack-plus/2.rvb 64,0,1,0,1,0,64,1,0,1,64,1,0,0,0 25,36,3,39,29,18,20,41,40,30 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 278,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 277,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 276,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 275,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 272,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 273,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 268,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 269,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 279,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 RaySession-0.12.2/client_templates/60_ray_lash/Rosegarden/000077500000000000000000000000001417052567600234445ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Rosegarden/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX/000077500000000000000000000000001417052567600315545ustar00rootroot00000000000000XXX_SESSION_NAME_XXX.rg000066400000000000000000000222631417052567600352750ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Rosegarden/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX]]6}Üx68gw^b͋ȞxZOŖWo?B$Sv˓¿?̷L*+2/VU7{%n>> 5DCۯLWʊ[^D:+e%VϦ~+"򭨟45Cfⷪ*ZɡR~ųg<ה/DͅM^T?u|v_ᆧ𒬬Vd< *7IJ ,Wy .$(s"U_7;o 77_/~d}Z|J J֗,S~.Tb!W=N.._D1QA{ D|QS * 8 Q!ATDE@Ԕ@A)5#5s5{ DbQS jN j jbל9|s4|ssٓ=g= QtٓEg= QtٓMg~:{*)z=uDS⪳^_=8[gO$FSu[gO$JSu[gO$N哂:{"*:{"*:{"*:{"*oiī|;)޺֟Fʧx[oiī8񪚫d+dj_ORJP|d*EY6\|ZZ1Uj+*~|'˸*w>t/:>ZMσGot% *!*z_fLEJZ.6#]]gOp iK|J$2^k=6_K^5ąyvj<ߦH~'q~̪6RnXnQm8]X.^|<}+_]o5bUYF'y6?Vw<)F\&UR*`SnQ WS?*eGGeMS}/SEu!g&SF;Jٱ0 ?7px熕_GsRSUDwe\Rg׫Kų>Hy#G`8xHyNG#p6xHyG"+3 W"g8D$p\I9q%B%겉 (}Vm]_'ٱe~S#HmPOINHG,fE')~d"aYtHG,b#N ȑE'(ȢEB(rdѹ?]q,k`q\<!X.vyǵC8]qq,k`q\<6"O?k.U"dɩlT$y <6~UkyoUH*o ܶi(dveQɍdǬ/d-Ė'vLԣޗ(.}7y_g2HйB%rE }g_Įf& fϗIu_'5ѣuARi(>]&[Q8w{5tS?OTN7َ_m䘷ubE*` Q|;y,ȳuQ'nU&(xtxY Ocܡ?JN^;,^kyIBZhvp z^'eM"ڈLcH/y*$[B9FIE}_J%I*u8&@HL$R;&*&MHR*mIeӱ9{s؜9q]<6coN7lJ׭YGqj B=zCl =đ!6}{cC=qlG֞~w;4rISu ucMūjb >Ajw-SVNQίRyt >ր4/{<ë7X&oD;9{MV.:dq9R5AY)E%^OZB6vQ$w)PWB7nʿWDp^wKH Ї?E̳uхoCW+Dk|;2Y)>sߟ?(v{^1m*IC!-/}" s^T13H)'~'EߗBfU'Tޏ"sWrgew)db0W{u@s]CSQ5Wy{rˮ[u9{kNB~U49CēvL%!/An\|2'ű2^Wu!B,M0Wnv- ;h ^LV:eiTF?#ĉh-4Bu W p/nS^ \5*ݰ >99$Hލ]%mYyda ~ALPY~[ g~yL>TE ) ߾WkTl0Tݩ^ +6gP$]+=Z32͉uf 0t+u/Ɩ:3kBf)"Sm_Y}TVH* X8=O}9xA<Ä0FF÷?iaq,кU-P%ͳ0<^Z۟EovWYWsQ!у9^#mlJ{/"n+p6fpxVW)AtGۉkEwIwiI`O_#nHpb] aY-$xp[ 4DbVLkrcL)"w6RM`Aɏjd4F"F&[naj1Qa6wQWcPح`kW)h_eaQb_:+5VK)8a.ꮻ;<5tZH)VMlc!AЦ {y!Wm$(¥lj(|] XM{B* T]@VW"D?D ΐBil)yYȪidhٯ0 #k Wndp}=@Z=RQ֒؉@eʦaF,Q ce1&F Ad } 4\w9Z{n0L ; LDkkQ0hAvN{W@s9%P ̋}`N>rbhu u0D)D=`}!h a~ ~?].ݨ'UbS oo6T)c$e$X茣z:e9(sHScMum 2yh8 䁗$TYq/tf1a⢞9XU݉ruB ^T T!3})|B wU`J}s-Wu*:C0A|$&LO} j8&'٭eP4h'@}4eHߝ$0;H_pArՍB-Ђ=hEG !Sn,pەes,v>),Na`&Da R|-Y>)0 צ~iqQ蟶.Uw\$fcnF&:h2MMÿ,{QxRUߜ70jS1ZRsc67 cK˓;FaTǠ6S:)in8d}{S(Sw̺Fs[CD O ȟgO.Ue1Ȃ]j[{.EZD#n=Z9ag' am90'aܢ5'e.6_oV~!HTJ^ m84 |1g%t[t/s ~e5n^$DZeh#3`m՝KgEb6"QűVd`F0-(24Y2 {ʈε1i#1 R"sUgK"q ,92xNj 1WxeXZ99 1P֨T#/n~ɑ]t3Dvg#sJw`Pm:{)H-h4PR_HMc;z^p#N_DQ <4rA╡ 7bvBniR#[VC۠58p$AӁ5!v`#sdiB:6 3l>q$$\p4?ᨃ`~f˵8`b,J`t:eqltO {nלcIPfG4Ǝ9BwI{:+h Ѹ`ӡu'  6HCt63 C4'Hi540vp55ffik1PIچc{~%c8>G l | %ٷkk-RFZSiVhC6W LI }  CdS@49jJ@Q 9nE{ \J*6X~i bI˰. VunD@lgv KB =A>p{50pmGvj\&,.Ŕ{[vKA4vJI$ xg'8\lЅu8$ذ pHQ9 dz?/mN)  ְ E"DڢbOUAaE.Ea =PRNA)RcUh950<4'3q$(-2{JZEs;]tb3=nA;etKM٥&RJ /A.4%=bReg&[dlB:H%AMH3%}]U5 %QT68ʞ  0=j6{HӦd YguȊ(@‘u{}Ҥ 1X?X/pg3| rjc%Fq [Z@9KJ+3|4V)@`Z4eQHisIڌ=>a *:5Dt w{ A 26&YF2#Lb?jL{Z`R5>jL #AQqgQ? @QqTzeJ|aGS쨸ure1rtDyu*thX+D аа6jsC(i (H;4YHal|Ш6baLNyhTHL-Pz,NyTսˆ6>#TS)wS~i;yH8c?2In!(7Pn4. D y ^&uࡧX̢%%e/DDimYm$zb85`>3FI Is S9M?$&;M)T  I~yU- ʨ!BF @QC؄tBd"%Fh%N&]w2b(@@ZC&Q  J84KA2ViC?AA.Ԡq]rzQF;Pbv6 (4CGg6Gh6!lk4dعWPfؖ&mT .@=uBN@HAqhAOq2|YTN1 YQNщ  唅BfH$L(W8-I A %d'm)AK$qe2<Ϡ%8ep 8Ɖ]Fr@(a`;vGHBc6zt-lohn)!0"ۋ h0ml8 R6̂pQ&m"ee*D?҆iHDNl DrC8@ڀqd֧qٌ4\9d? 9Hr"#g2TgعP!:)A+~;VRoJPt)k-Bdv]z[:,9dfm- "!*$FWd hrx$+O$]Na' lж|gGD& h _O+H(wb!j;I(@ QP[m#牲f1iNW߇F>jSo2ZZchK .k/=.Ryg LoAWRaySession-0.12.2/client_templates/60_ray_lash/Seq24/000077500000000000000000000000001417052567600222515ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Seq24/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX/000077500000000000000000000000001417052567600303615ustar00rootroot00000000000000XXX_SESSION_NAME_XXX.midi000066400000000000000000000105201417052567600344050ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Seq24/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXXMThdMTrkTUntitled`9d.9dB;d.;d4d.4d$$$$$$$$R/$$$$$$ $$x$$  RaySession-0.12.2/client_templates/60_ray_lash/Sequencer64/000077500000000000000000000000001417052567600234575ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Sequencer64/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXX/000077500000000000000000000000001417052567600315675ustar00rootroot00000000000000XXX_SESSION_NAME_XXX.midi000066400000000000000000000005051417052567600356150ustar00rootroot00000000000000RaySession-0.12.2/client_templates/60_ray_lash/Sequencer64/XXX_SESSION_NAME_XXX.XXX_CLIENT_ID_XXXMThdMTrk]Untitled`9d.9dB;d.;d4d.4d$$$$$$$$$$R/MTrk? Sequencer64-S$$$$F$$ $$$$$$$$$$$$$$/RaySession-0.12.2/client_templates/60_ray_lash/client_templates.xml000066400000000000000000000074771417052567600254500ustar00rootroot00000000000000 RaySession-0.12.2/data/000077500000000000000000000000001417052567600146215ustar00rootroot00000000000000RaySession-0.12.2/data/ray-daemon000066400000000000000000000001511417052567600165750ustar00rootroot00000000000000#!/bin/bash INSTALL_PREFIX="X-PREFIX-X" exec "$INSTALL_PREFIX/share/raysession/src/bin/ray-daemon" "$@" RaySession-0.12.2/data/ray-proxy000066400000000000000000000001501417052567600165120ustar00rootroot00000000000000#!/bin/bash INSTALL_PREFIX="X-PREFIX-X" exec "$INSTALL_PREFIX/share/raysession/src/bin/ray-proxy" "$@" RaySession-0.12.2/data/ray_control000066400000000000000000000001521417052567600170750ustar00rootroot00000000000000#!/bin/bash INSTALL_PREFIX="X-PREFIX-X" exec "$INSTALL_PREFIX/share/raysession/src/bin/ray_control" "$@" RaySession-0.12.2/data/raysession000066400000000000000000000001511417052567600167400ustar00rootroot00000000000000#!/bin/bash INSTALL_PREFIX="X-PREFIX-X" exec "$INSTALL_PREFIX/share/raysession/src/bin/raysession" "$@" RaySession-0.12.2/data/share/000077500000000000000000000000001417052567600157235ustar00rootroot00000000000000RaySession-0.12.2/data/share/applications/000077500000000000000000000000001417052567600204115ustar00rootroot00000000000000RaySession-0.12.2/data/share/applications/ray-jack_checker.desktop000066400000000000000000000005221417052567600251700ustar00rootroot00000000000000[Desktop Entry] Name=Ray Jack Checker Name[fr]=Contremaître de JACK Comment=Daemon that monitors JACK configuration Comment[fr]=Démon qui surveille de la configuration de JACK Exec=ray-jack_checker_daemon --force-reliable Terminal=false Type=Application Icon=raysession StartupNotify=false NoDisplay=true Hidden=true Categories=System; RaySession-0.12.2/data/share/applications/ray-jackpatch.desktop000066400000000000000000000005201417052567600245220ustar00rootroot00000000000000[Desktop Entry] Name=Jack Connections Name[fr]=Connexions JACK Comment=Stores and reconnects JACK patch connections Comment[fr]=Mémorise et reconnecte les connexions de la baie de brassage de JACK Exec=ray-jackpatch Terminal=false Type=Application Icon=curve-connector StartupNotify=false NoDisplay=true Hidden=true Categories=System; RaySession-0.12.2/data/share/applications/ray-network.desktop000066400000000000000000000005011417052567600242620ustar00rootroot00000000000000[Desktop Entry] Name=Network Session Name[fr]=Session réseau Comment=Manage a ray session working on another machine Comment[fr]=Gère une session ray fonctionnant sur une autre machine Exec=ray-network Terminal=false Type=Application Icon=network-wired StartupNotify=false NoDisplay=true Hidden=true Categories=System; RaySession-0.12.2/data/share/applications/raysession.desktop000066400000000000000000000003411417052567600242010ustar00rootroot00000000000000[Desktop Entry] Name=RaySession GenericName=RaySession Comment=Audio Session Manager Comment[fr]=Gestionnaire de sessions audios Exec=raysession Icon=raysession Terminal=false Type=Application Categories=AudioVideo;Audio;Qt; RaySession-0.12.2/locale/000077500000000000000000000000001417052567600151475ustar00rootroot00000000000000RaySession-0.12.2/locale/control000077700000000000000000000000001417052567600211522../src/controlustar00rootroot00000000000000RaySession-0.12.2/locale/raysession.pro000066400000000000000000000064421417052567600200760ustar00rootroot00000000000000FORMS += ../resources/ui/abort_copy.ui FORMS += ../resources/ui/abort_session.ui FORMS += ../resources/ui/about_raysession.ui FORMS += ../resources/ui/add_application.ui FORMS += ../resources/ui/ardour_convert.ui FORMS += ../resources/ui/canvas_options.ui FORMS += ../resources/ui/canvas_port_info.ui FORMS += ../resources/ui/client_properties.ui FORMS += ../resources/ui/client_rename.ui FORMS += ../resources/ui/client_slot.ui FORMS += ../resources/ui/client_trash.ui FORMS += ../resources/ui/daemon_url.ui FORMS += ../resources/ui/donations.ui FORMS += ../resources/ui/error_dialog.ui FORMS += ../resources/ui/filter_frame.ui FORMS += ../resources/ui/hydro_rh_nsm.ui FORMS += ../resources/ui/jack_config_info.ui FORMS += ../resources/ui/list_snapshots.ui FORMS += ../resources/ui/new_executable.ui FORMS += ../resources/ui/new_session.ui FORMS += ../resources/ui/nsm_open_info.ui FORMS += ../resources/ui/nsm_properties.ui FORMS += ../resources/ui/open_session.ui FORMS += ../resources/ui/patchbay_tools.ui FORMS += ../resources/ui/preview_client_slot.ui FORMS += ../resources/ui/proxy_copy.ui FORMS += ../resources/ui/proxy_gui.ui FORMS += ../resources/ui/quit_app.ui FORMS += ../resources/ui/ray_hack_copy.ui FORMS += ../resources/ui/ray_hack_properties.ui FORMS += ../resources/ui/ray_net_properties.ui FORMS += ../resources/ui/raysession.ui FORMS += ../resources/ui/ray_to_nsm.ui FORMS += ../resources/ui/remove_template.ui FORMS += ../resources/ui/save_template_session.ui FORMS += ../resources/ui/script_info.ui FORMS += ../resources/ui/script_user_action.ui FORMS += ../resources/ui/session_notes.ui FORMS += ../resources/ui/session_scripts_info.ui FORMS += ../resources/ui/snapshot_and_save.ui FORMS += ../resources/ui/snapshot_name.ui FORMS += ../resources/ui/snapshot_progress.ui FORMS += ../resources/ui/snapshots_info.ui FORMS += ../resources/ui/startup_dialog.ui FORMS += ../resources/ui/stop_client_no_save.ui FORMS += ../resources/ui/stop_client.ui FORMS += ../resources/ui/systray_close.ui FORMS += ../resources/ui/systray_management.ui FORMS += ../resources/ui/template_slot.ui FORMS += ../resources/ui/waiting_close_user.ui FORMS += ../resources/ui/zoom_slider.ui SOURCES += ../src/daemon/client.py SOURCES += ../src/daemon/daemon_tools.py SOURCES += ../src/daemon/osc_server_thread.py SOURCES += ../src/daemon/ray-daemon.py SOURCES += ../src/daemon/scripter.py SOURCES += ../src/daemon/session.py SOURCES += ../src/daemon/session_signaled.py SOURCES += ../src/gui/add_application_dialog.py SOURCES += ../src/gui/canvas_options.py SOURCES += ../src/gui/child_dialogs.py SOURCES += ../src/gui/client_properties_dialog.py SOURCES += ../src/gui/daemon_manager.py SOURCES += ../src/gui/gui_tools.py SOURCES += ../src/gui/list_widget_clients.py SOURCES += ../src/gui/list_widget_preview_clients.py SOURCES += ../src/gui/main_window.py SOURCES += ../src/gui/nsm_child.py SOURCES += ../src/gui/open_session_dialog.py SOURCES += ../src/gui/patchbay_manager.py SOURCES += ../src/gui/patchbay_tools.py SOURCES += ../src/gui/snapshots_dialog.py SOURCES += ../src/gui/utility_scripts.py SOURCES += ../src/gui/patchcanvas/canvasbox.py SOURCES += ../src/gui/patchcanvas/canvasportgroup.py SOURCES += ../src/gui/patchcanvas/canvasport.py SOURCES += ../src/gui/patchcanvas/connect_menu.py TRANSLATIONS += raysession_en.ts TRANSLATIONS += raysession_fr.ts RaySession-0.12.2/locale/raysession_en.ts000066400000000000000000005353061417052567600204140ustar00rootroot00000000000000 AbortSession Abort Session ? <html><head/><body><p>Are you sure to want to abort session without saving ?</p></body></html> Abort Cancel ClientSlotWidget Frame ... ClientName Launch <html><head/><body><p>Politely ask the client to stop.</p></body></html> Status stopped Save Remove Save As Application Template Properties Return To A Previous State Rename Display client Ray-Hack properties Hack Add to the current session Find boxes in patchbay Dialog Abort Copy ? Do you want to abort current copy ? Abort Copy Cancel Properties : Executable executable ... Label nsmid Icon Client id Snapshots <html><head/><body><p>Edit here what types of files inside the client folders<br/>should be ignored in session snapshots.</p><p>Indexed files will remain so.</p></body></html> Snapshots ignored extensions : Save Changes <html><head/><body><p align="center">Do you want to restore this client in the session ?<br/>You can also definitely remove the client and its files.</p></body></html> <html><head/><body><p>Remove definitely the client and its files.</p></body></html> Remove <html><head/><body><p>Restore this client in current session.</p></body></html> Restore Client Daemon URL ray-daemon url to connect to : osc.udp://192.168.XX.XX:1234/ Error ! Error Text Snapshots Manager <html><head/><body><p>Select from the list below the snapshot to be recalled<br/>to return to a past state of the session :</p></body></html> Take a snapshot now ! <html><head/><body><p>Make a snapshot at each session save.</p></body></html> Auto snapshot at save for this session Opening NSM Session Don't Show this Message Again Copy File ? file is not in proxy directory. <html><head/><body><p>Do you want to copy this file to proxy directory or to use directly this file ?</p></body></html> Copy file and rename it with session name Copy And Rename File Copy File Use This File Name Snapshot Snapshot Name : <html><head/><body><p>You can save the session before the snapshot.</p><p>Save is recommended,<br/>unless you made unwanted changes since the last session save.</p></body></html> Save && Snapshot Snapshot Only <html><head/><body><p>Snapshot process seems to be long.<br/>Maybe your session's folder contains too many new files<br/>whose extension is not ignored.</p><p>You can abort this snapshot,<br/>it will de-activate snapshots for this session.</p></body></html> Abort Snapshot Snapshots Informations <html><head/><body><p>Snapshots are NOT backups !!!</p><p>Besides, It's not overrated to copy your session folder elsewhere<br/>before to ask a previous snapshot.</p><p>Snapshots ignore audio files and other big files (&gt;50Mb),<br/>else snapshot process would be too long, <br/>and the session folder size would be too big.</p><p>That being said, you can decide that your work in the last hours<br/>was not a good idea and return to a previous snapshot !</p></body></html> Do not show this message again Stop Client ? <html><head/><body><p><span style=" font-weight:600;">%s</span> contains unsaved changes. </p><p>Do you really want to stop it ?</p></body></html> Don't prevent to stop this client again ! Save && Stop Just Stop Prevent to stop without recent or possible save Donations <html><head/><body><p>Hi !</p><p>it seems that you appreciate RaySession, that is already a good new.<br/>This software is free as in Speech and as in Beer,<br/>but it has required and still takes time.</p><p>Make a donation (even small) is a simple way to say &quot;Thank you&quot;.<br/>You can donate <a href="https://liberapay.com/Houston4444"><span style=" text-decoration: underline; color:#2980b9;">here</span></a>.</p><p>If ever you donate nothing,<br/>this program will continue to work without limits of functionnality,<br/>without limit of duration, and even without insulting you ;) .</p></body></html> Remove Template ? <html><head/><body><p>Are you sure to want to remove this template ?</p></body></html> <html><head/><body><p>We have no possibility to save the client <span style=" font-weight:600;">%s</span>.</p><p>For this reason, it's preferable that you close yourself this client,<br/>probably by closing its window, saving its changes or not.</p></body></html> Don't prevent to stop this client again (discouraged) Stop Anyway Close clients yourself ! <html><head/><body><p align="center">Some active clients do not offer any save possibility !</p><p align="center">Therefore, it is best that you close these clients yourself,<br/>probably by closing their windows and saving changes.</p><p align="center"><span style=" font-weight:600;">Please close yourself the programs with this save icon:</span></p></body></html> <html><head/><body><p>You've got 2 minutes !<br/><span style=" font-style:italic;">You can do it without closing this dialog window.</span></p></body></html> Do not show again Undo Ok Skip General Description Protocol client_protocol Jack Configuration Infos <html><head/><body><p>You create a session from the JACK configuration reminder template.</p><p>This means that when you re-open this session, JACK may be restarted with the configuration used by that session.</p><p>This session callback is made from the session scripts.</p></body></html> Session Scripts Infos <!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" /><title>Session Scripts Infos</title><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; 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;">Session scripts are located in the <span style=" font-style:italic;">ray-scripts</span> folder in the session folder, but they could also be located in a <span style=" font-style:italic;">ray-scripts</span> folder in a parent folder of the session folder.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For example:</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the scripts folder for this new session will be:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">But could just as well be:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and thus apply to all sessions contained in <span style=" font-weight:600;">%s</span>.</p></body></html> Jack Config Script Infos <!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:'Noto Sans'; font-size:10pt; 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;"><span style=" font-weight:600;">The principle is as follows:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Each time the session is saved, the JACK configuration is saved in the session.<br />Before opening, JACK is restarted if the session configuration is different from the current one.<br />After closing, JACK is restarted as it was configured before opening if needed.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If you open this session on another computer, the JACK configuration will not be recalled but will be overwritten when you save.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If you wish to open this session without reloading the JACK configuration, simply disable the session scripts.</p></body></html> <html><head/><body><p>Unfortunately, at the moment it is not possible to get the current JACK configuration with certainty, so JACK will be restarted at the first session opening.<br/>You can work around this problem by automatically starting a light daemon at your desktop session startup.</p></body></html> Automatically start ray-jack_checker daemon at startup <html><head/><body><p>You are opening a session created by Non Session Manager.</p><p><br/>RaySession will open it, but changes won't be applied to NSM file (session.nsm).</p><p>Also, Once you start to work with RaySession, you have to continue with it !</p></body></html> file is not in client working directory. <html><head/><body><p>Do you want to copy this file to client working directory or to use directly this file ?</p></body></html> Script Info Script info text Script User Action Info Label <html><head/><body><p><hr/></p></body></html> Script user action text. Are you ready ? <html><head/><body><p>You create a session with the basic session scripts.<br/>If you don't know what a script is, or you have absolutely no knowledge in shell scripting, you don't belong here, get out of here right now.</p><p>While you've not edited the scripts, session will behave as a normal session.</p><p>You will find in the session folder a <span style=" font-style:italic;">ray-scripts</span> folder.<br/>In the <span style=" font-style:italic;">ray-scripts </span>folder you will find 3 files:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">load.sh</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">save.sh</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">close.sh</li></ul><p>In theses 3 scripts you can edit some actions to do before or after load, save, or close the session.<br/>If you don't need custom actions at one of theses 3 steps, you can safely remove its file.</p></body></html> %s is not in client working directory Select File to use as CONFIG_FILE Rename Client TextLabel Rename this client to : Trashed client Prettier Name <html><head/><body><p>Get more informations on this trashed client.</p></body></html> Dialog Notes of session : Session name Canvas Options <html><head/><body><p>Display shorter and more readable ports and groups names.</p><p>If unchecked, displayed port names will be the trought port names.</p></body></html> Use graceful names Group A2J hardware ports Boxes have shadows <html><head/><body><p>Always resize the canvas scene to the mininum contents.</p><p>This way, the view is directly optimized while moving boxes.</p></body></html> Elastic canvas Theme : Port Infos Full port name : Type Flags Port Flags Audio Port JACK UUID Metadatas Port-Group Order Pretty name Convert Ardour session to Ray This script helps you to load an ardour session made with Ardour into a RaySession session. For performance reasons, the ardour project will be moved (and not copied) to the session directory. This script seems to work well, but there is absolutely no warranty that some problems could appear, so it is advisable to backup your ardour session first. In the future, think to always start Ardour from RaySession ! You can never be sure to not need another software, and auto snapshots can help you a lot. Now let choose the Ardour session you want to convert to a Ray session. Do not display this message again Hydrogen NSM script <html><head/><body><p>This script converts all regular <span style=" font-weight:600;">Hydrogen<br/></span>Ray-Hack clients to the NSM protocol.</p><p>Where do you want the script to proceed:</p></body></html> In the current session In all sessions In application templates In session templates <html><head/><body><p><span style=" font-style:italic;">Note that you could lose some JACK connections,<br/>but it's still worth it.</span></p></body></html> convert to NSM file format <html><head/><body><p>This script will convert a session to the NSM file format.<br/>This way, you will be able to open it with <span style=" font-weight:600;">New Session Manager</span>,<br/><span style=" font-weight:600;">Non Session Manager</span> or <span style=" font-weight:600;">Agordejo</span>, you will still can open it<br/>with <span style=" font-weight:600;">RaySession</span>.</p><p>Note that some specifics things will change :</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">All client projects will be named with their client name<br/>and not with the session name.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Allmost JACK clients will have a longer name,<br/>containing the client_id.</li></ul></body></html> <html><head/><body><p>jackpatch is the program in the session which<br/>remembers and connects JACK connections.<br/><br/>If this option is enabled, the session will replace ray-jackpatch<br/>with jackpatch (the NSM one), else session will works only if<br/>RaySession is installed.</p></body></html> Use NSM jackpatch Previous session <html><head/><body><p>Welcome to <span style=" font-weight:600;">RaySession</span> !</p></body></html> New session Open session Do you want to load this previous session ? Display at startup System Tray Your session is still runing. RaySession will run in the background. You can make the window re-appear from your system tray. Tray Icon Options Pro&vide system tray icon Only when session is running <html><head/><body><p>Never ask what to do and close GUI process<br/>if you close RaySession while a session is running. </p><p>The session will still running and you just have<br/>to restart RaySession to manage it.</p><p>This method uses less RAM than<br/>keeping window in system tray.</p></body></html> Quit shutdowns the GUI <html><head/><body><p>When this option is active, boxes are automatically moved when another box has been moved over them.</p></body></html> Prevent overlapping of boxes Maximum port width : Enable it if your systray is at bottom of the screen. Reversed menu order DialogAboutRaysession <html><head/><body><p><img src=":/128x128/raysession.png"/></p></body></html> <html><head/><body><p>Ray Session is a Qt interface for the ray-daemon.</p><p>Its goal is to manage together audio programs as Ardour, Carla, Qtractor, Non-Timeline in an unique session.</p><p>Programs just have to be compatible with the <a href="http://non.tuxfamily.org/wiki/Non%20Session%20Manager"><span style=" text-decoration: underline; color:#2980b9;">NSM</span></a> API to work with Ray Session.<br/></p><p align="right">Copyright (C) 2016-2021 houston4444</p><p><br/></p></body></html> About RaySession <html><head/><body><p><span style=" font-weight:600;">RaySession</span></p><p>version : %s</p></body></html> DialogAddApplication Add Application Filter : Factory User <html><head/><body><p>NSM is the protocol used by modern audio programs to ensure a good session management.</p></body></html> NSM <html><head/><body><p><span style=" font-weight:600;">Ray-Hack</span> is a fake protocol that tries to manage non NSM compatible programs as it can.</p><p>It can be useful :</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">for audio programs that don't have NSM implementation yet</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">for non-audio programs</li></ul></body></html> Ray-Hack ... MacronDemission <html><head/><body><p>Add this template to favorites / Remove this template from favorites</p></body></html> resistance to the oppression of pests Non Saveable Program !!! : Protocol Executable label Label lallement NLP Name Program Name <html><head/><body><p>Get more informations on this template.</p></body></html> No template selected Filter application templates Refresh Applications Refresh\nApplications F5 DialogNewExecutable New Executable Client Executable : <html><head/><body><p>If program is not compatible with the NSM API, </p><p>you should launch it in proxy to define a config file !</p></body></html> <html><head/><body><p>Show more options ...</p></body></html> ... Advanced Prefix : Prefix Mode : Client ID : <html><head/><body><p>The Prefix Mode determines the pattern of the client files.</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Session Name (Default) :<br/>The client files names start with the session name.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Client Name :<br/>The client files names start with the client name given by the client itself<br/>(as in Non Session Manager).</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Custom :<br/>The client files names start with the prefix written below.</li></ul></body></html> <html><head/><body><p>Use it If you want to add to session a file made outside from a session.</p><p>If you let this line empty, the client_id will be automaticely generated.</p></body></html> NSM Protocol Start the client <html><head/><body><p>With this option checked, NSM programs should name their JACK client names starting with ClientName.ClientId (as in NSM), else it will be ClientName (with a digit suffix if needed).</p></body></html> Long JACK Naming DialogNewSession New Session /home/user/Ray Sessions Folder New Session Name : Template : <html><head/><body><p><span style=" font-size:9pt; font-weight:600;">Sessions Folder :</span></p></body></html> Original session : session name DialogOpenSession Open Session Folder Filter : <html><head/><body><p><span style=" font-size:9pt; font-weight:600;">Sessions Folder :</span></p></body></html> %p% Sort by dates >_ ... 0 Mo Clients Notes Snapshots /ho&me/user/Ray Sessions Listing sessions Cancel Name Date Save the current session DialogQuitApp Quit RaySession <p>Session <bold>%s</bold> is running.</p><p>RaySession will be closed.</p><p>Do you want to save session ? Save && Quit Quit Without Saving Cancel <html><head/><body><p>Do you want to save the session before snapshot ?</p><p>Save is recommended,<br/>unless you made unwanted changes since the last session save.</p></body></html> Save && Snapshot Snapshot Keep Daemon Running DialogSaveTemplateSession New Template Session Template Name : Create Template Cancel Session : ... Client Label Duplicate Duplicated session name : Duplicate Session Form Form 48.000 Hz Buffer : 0 Xruns <p style="color:red">JACK is not started !</p> JACK Samplerate Number of audio Xruns. Click on it to reset them. DSP: %p% 100 % Frame Frame ... Template Name client_name : client_capabilities Name Capabilities <html><head/><body><p>Edit executable is strongly discouraged !<br/>It can be useful if you use many versions of a same software.<br/>Change it only if you are sure of what you are doing.</p></body></html> Executable : <html><head/><body><p>Arguments are supposed to not be supported by NSM protocol.<br/>In some cases it can works, but no warranty !</p></body></html> Arguments : <html><head/><body><p>Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly.</p><p>Some audio programs doesn't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> session_name.client_id <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> Browse Config File : <html><head/><body><p>Ray Hack protocol is a convenience way to manage non NSM compatible programs in the session.</p><p>Some audio programs don't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> <html><head/><body><p>The environment variables $NSM_CLIENT_ID and $RAY_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.<br/>The variable $CONFIG_FILE will contain the name of the config file selected above.</p></body></html> <html><head/><body><p>The environment variable $RAY_CLIENT_ID will contain the RaySession client_id of this client.$RAY_SESSION_NAME will contain the display name for the session.<br/>$RAY_JACK_CLIENT_NAME will contain a string suitable for use as e.g. a JACK client name.<br/>$CONFIG_FILE will contain the name of the config file selected above.</p></body></html> Folder : <html><head/><body><p>If wmctrl is present and compatible with window manager,</p><p>and if this box is checked,</p><p>the program will be considered as ready only when it displays a window.</p><p>Else the program will be considered as ready after 500ms.</p></body></html> wait for a window before considering it ready (needs wmctrl) <html><head/><body><p>Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal.<br/>It's impossible to know which signal a specific program will respond to.<br/>A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK).<br/>Check the program's documentation or source code to determine which signal to use to stop it gracefully.</p></body></html> Stop Signal : <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then Ray Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> Save Signal : <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then this signal will be sent to the program when we ask to save it.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> Without save method <html><head/><body><p>Because we have no method to save the state of this program,<br/>if this box is checked the program won't be closed by session manager at session close,</p><p>it will ask user to close it himself (saving changes or not).</p></body></html> Tell user to close program himself at session close <html><head/><body><p>If wmctrl is present and compatible with window manager,<br/>the program will try to close gracefully its windows before asking user to close them himself.<br/>This way, in a lot of cases, program will be closed when it has no unsaved changes,<br/>or will display an exit confirmation dialog to save changes or not. </p></body></html> Try to close window gracefully (needs wmctrl) Launch Stop Status stopped Save executable failed to launch ! <html><head/><body><p>Edit the daemon URL only if you meet troubles !!!</p></body></html> Daemon URL : <html><head/><body><p>Here, sessions root folder is the sessions root folder used by the slave daemon.<br/>Edit it only if you have changed the sessions root folder<br/>used by the slave daemon.</p></body></html> Sessions root folder : <html><head/><body><p>Template session that will be used on the slave daemon if there is no existing session at the same path than the master one (relatively to their sessions root folder).</p><p>The templates used in network sessions are in a hidden folder of the sessions root folder.</p></body></html> Template : Test &Zone <html><head/><body><p>here many fields are available to you. This is not necessarily good news, the idea is to be able to load a program into the session that is not (yet) compatible with NSM. If properly implemented in the client, the NSM protocol will always be much more comfortable to use and more reliable than this hack. That said, if we can expect the NSM implementation in all audio programs, this is not the case for other programs which can still be useful in the session.</p><p><br/></p><p>The Ray-Hack pseudo-protocol uses the attributes of proxies (nsm-proxy or ray-proxy), except that the client is launched directly in the session.</p></body></html> <html><head/><body><p>The program will be started in the folder named above.</p><p>It is recommended that you only refer to files in the current directory.</p><p>$RAY_SESSION_NAME will be replaced with the name of the session.</p></body></html> Hide filter bar Find a box... Audio Midi adjust the opacity of boxes not matching with the filter Opacity : % Environment variables : <html><head/><body><p>Set here the environment variables you want to set to the process, separate them with spaces.<br/><br/>for example :</p><pre style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Hack';">MY_VAR1=my_value MY_VAR2=&quot;other value&quot;</span></pre></body></html> Environment : GUIMSG Can't save session, session file is unwriteable ! Creating new session "%s" Session is ready Stop all clients before rename session ! Session %s has been renamed to %s . Session directory is now: %s %s is started but not active %s failed to save! %s failed to open! %s: saved %s: project loaded can't start %s, it is a dummy client ! %s is exiting. %s seems to can not open %s: launched %s: terminated by server instruction %s: terminated itself. %s: project probably loaded %s: Failed to start ! %s failed to launch %s is already saving, please wait! %s: stopping impossible to remove %s ! %s is not writeable ! Copy has been aborted ! script %s failed to start ! script %s terminated with exit code %i ...script %s finished. --- --- Custom step script %s started... --- Custom script %s started...%s %s didn't announce. %s still alive ! -- Saving session %s -- waiting for %s to save... waiting for %i clients to save... Session '%s' saved. snapshot started... Snapshot aborted! waiting for no saveable clients to be closed gracefully... waiting you to close yourself unsaveable clients... waiting for %s to quit... waiting for %i clients to quit... -- Duplicating session %s to %s -- waiting for network daemons to start duplicate... start session copy... ...session copy finished. waiting for network daemons to finish duplicate start session copy to template... ...session saved as template named %s start copy from template to session folder -- Opening session %s -- waiting for %s to load its project... waiting for %s clients to load their project... session %s is loaded. %s is not an existing template ! No client with this client_id:%s Impossible, copy running ! session %s is already opened ! session %s is already used by another daemon ! abort ordered from elsewhere, sorry ! %s already exists ! session %s is already used by this or another daemon ! No session to list clients ! client %s is already running. client %s is already active. %s is not saveable. %s seems to not be a proxy client ! impossible to read %s correctly ! Impossible to set proxy properties while client is running. %s is not writeable %s is not running. Impossible to run Ray-Net client when session is not in root folder ...Snapshot finished. GUI_daemon Connecting GUI to existing ray-daemon port %i Load Error Unknown error Could not create session file! Session is locked by another process! The named session does not exist. Could not load session file. Can't create session in a dir containing a session for better organization. MainWindow Ray Proxy <html><head/><body><p>Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly.</p><p>Some audio programs doesn't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> Config File : Executable : Browse <html><head/><body><p>The environment variables $NSM_CLIENT_ID and $RAY_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.<br/>The variable $CONFIG_FILE will contain the name of the config file selected above.</p></body></html> Arguments : <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then Ray Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> <html><head/><body><p>Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal.<br/>It's impossible to know which signal a specific program will respond to.<br/>A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK).<br/>Check the program's documentation or source code to determine which signal to use to stop it gracefully.</p></body></html> Save Signal : Stop Signal : Test Wait window before reply (needs wmctrl) executable failed to launch ! Launch Stop ... <html><head/><body><p>Save &amp; Close Session</p></body></html> Open Session Folder Run Command Application Executable <html><head/><body><p>Go back to a previous state of the session.</p></body></html> Snapshots Server Status off Save Session <html><head/><body><p>Trash</p><p>You will find here removed clients.</p></body></html> Fi&le &Session &View &Help Add Options toolBar &Show Messages Ctrl+L &Save Ctrl+S &Open Session Ctrl+O &New Session Ctrl+N &Quit Ctrl+Q &About Ray Session Show &Menu Bar Ctrl+M Control &Close Save and Close Session Ctrl+W &Abort Abort Current Session Ctrl+Shift+W &Open Session Folder Open session folder with file manager &Keep focus while opening clients About &Qt &Duplicate <html><head/><body><p>Duplicate the current session</p></body></html> Ctrl+D &Executable Add executable to current session Ctrl+E Sa&ve As Template Save current session as template &Application Add application to current session Ctrl+A &Rename &Provide bookmarks for session folder &Desktops Memory (requires wmctrl) Return To A &Previous State (requires git) Auto Snapshot at Save (requires git) No Save Level : <html><head/><body><p>If this proxy has no save signal,<br/>it can sends to session manager this information.</p><p><ul><li>0 - this information is not sent.</li><li>1 - this information is sent, session manager will ask user to close programs himself at session unload.</li><li>2 - this information is sent, session manager can try to close window gracefully before to ask user to close programs himself at session unload. Good choice if the program displays a dialog if changes are not saved.</li></ul></p></body></html> Favorite Applications Run the session scripts inside the directory ray-scripts RaySession &Auto Snapshot At Save (requires git) &Donate &Session Scripts &Remember optional GUI states Remember if optional GUIs were shown &Edit Session Notes Make &reappear all dialog windows Save as Template the current session Duplicate the current session Rename the current session Open the online manual in the web browser Displays internal manual in a web browser &Online Manual &Internal Manual Show &JACK patchbay Ctrl+J &Recent sessions &Utilities System tray &icon options ezf Convert all &Hydrogen Ray-Hack clients to NSM Convert all &Jack Mixer Ray-Hack clients to NSM Convert &session to NSM file format Ctrl+H Convert an &Ardour session to a Ray session Snapshot Error Unknown error git didn't stop normally. %s git crashes. %s git exit with an error code. %s Snapshot error command didn't stop normally: %s command crashes: %s command exit with an error code: %s error reading file: %s actions Desktops Memory Auto Snapshot at Save add_app_dialog <p>Are you sure to want to remove<br>the template "%s" and all its files ?</p> capabilities switch dirty optional-gui child_session Child Session client failed to move %s/%s to %s/%s, sorry. client status stopped launch open ready copy save switch quit noop error removed client_properties Properties of client %s Properties of template %s client_slot Protocol Executable client id client_status invalid script client_stop <strong>%s</strong> seems to has not been saved for %i minute(s).<br />Do you really want to stop it ? daemon Ray Network Sessions port %i is not free, try another one daemon runs at %s error impossible to read %s Some clients could not save Impossible to save template, unwriteable file ! No template named %s No announce from ray-daemon. RaySession can't works. Sorry. Folder %s already exists Can't create session in a dir containing a session for better organization. client_id %s is not alphanumeric client_id %s is already used errors daemon crash! ray-daemon crashed, sorry ! guimsg Can't create session in a dir containing a session" for better organization. help A session manager based on the Non-Session-Manager API for sound applications. connect to this daemon url Use this folder as root for sessions Open this session at startup use a custom config dir display OSC messages debug without client messages connect to this daemon port do not print client messages prevent to attach to an already running daemon hidden_dialogs Make reappear dialog windows Do you want to make reappear all dialogs you wanted to hide ? main view No Session Loaded menu remove Favorites Add message Client template %s created network_session Network Session new client template New application template name : new_executable Custom Client Name Session Name notes_dialog %s Notes - %s open_session This session is scripted Listing sessions Cancel Session copy Ok Session saved as template Remove session <p>Are you really sure to want to remove the following session:</p><p><strong>%s</strong></p><p>This action is irreversible. patchbay Silver Gold Black Gold Modern Dark Audio MIDI Input Output Physical Monitor Terminal Control Voltage Toggle Full Screen Type filter Audio + Midi Audio only MIDI only Zoom auto-fit Zoom + Zoom - Zoom 100% Refresh the canvas Canvas options JACK server lose JACK server seems to be totally busy... ;( Wrap Unwrap Connect Disconnect No connections Clipboard Cut connections Copy connections Paste connections Disconnect All Disconnect &All Info Rename Split Join Split to Monos Set as Stereo with Get &Info &Rename Patchbay Audio | DANGEROUS !!! CV | DANGEROUS !!! Patchbay manual Find a box...Ctrl+F ray_hack None rename Impossible to rename session. Folder %s already exists, rename_session Rename Session <p>In order to rename current session,<br>please first stop all clients.<br>then, double click on session name.</p> root_folder_dialogs Choose root folder for sessions unwritable dir <p>You have no permissions for %s,<br>choose another directory !</p> server status off new open clear switch launch copy ready save close invalid server_status snapshot rewind waiting save script session template Overwrite Template ? Update the template session_menu Duplicate session Save session as template Rename session Remove session Remove session (too big) session_notes Too long notes <p>Because notes are spread to the OSC server,<br>they can't be longer than 65000 characters.<br>Sorry !</p> session_template empty with JACK patch memory Template <strong>%s</strong> already exists. Overwrite it ? with JACK config memory with basic scripts snapshots Today Yesterday %s at %s at %s before rewind to This session does not contains any snapshot. There is no existing snapshot for this client. trashed_client Remove definitely Are you sure to want to remove definitely this client and all its files ? url window <p align="left">To run a network session,<br>open a terminal on another computer of this network.<br>Launch ray-daemon on port 1234 (for example)<br>by typing the command :</p><p align="left"><code>ray-daemon -p 1234</code></p><p align="left">Then paste below the first url<br>that ray-daemon gives you at startup.</p><p></p> url_window <p>daemon at<br><strong>%s</strong><br>didn't announce !<br></p> <p>daemon at<br><strong>%s</strong><br>uses an other session root folder !<.p> <p>daemon at<br><strong>%s</strong><br>uses a forbidden session root folder !<.p> <p>daemon at<br><strong>%s</strong><br>uses another %s version.<.p> <p>daemon at<br><strong>%s</strong><br>has a loaded session.<br>It can't be used for slave session</p> utilities Choose a session Convert the current session Other script running An utility script is already running, please close its terminal and start again ! Convert Ardour session to Ray Choose an Ardour session to convert... Ardour sessions (*.ardour) Hydrogen Ray-Hack->NSM Jack Mixer Ray-Hack->NSM Session to NSM file format Choose a session to convert to NSM wrong_version The running daemon has not the same version than the interface RaySession will quit now. What do you want to do with the current session ? RaySession-0.12.2/locale/raysession_fr.ts000066400000000000000000007516111417052567600204200ustar00rootroot00000000000000 AbortSession Abort Session ? Abandonner la session ? <html><head/><body><p>Are you sure to want to abort session without saving ?</p></body></html> <html><head/><body><p>Êtes vous sûr de vouloir abandonner<br>la session sans la sauvegarder ?</p></body></html> Abort Abandonner Cancel Annuler ClientSlotWidget Frame Trame ... ... ClientName NomDuClient Show GUI Afficher l'interface graphique utilisateur GUI IUG Launch Lancer Status État stopped arrêté Save Sauvegarder Remove Supprimer <html><head/><body><p>Politely ask the client to stop.</p></body></html> <html><head/><body><p>Demander poliment au client de s'arrêter.</p></body></html> <html><head/><body><p>Kill !</p></body></html> <html><head/><body><p>Tuer !</p></body></html> Save As Application Template Sauvegarder comme modèle d'application Properties Propriétés Return To A Previous State Retourner à un état précédent Rename Renommer Display client Ray-Hack properties Afficher les propriétés Ray-Hack du client Hack Hack Add to the current session Ajouter à la session en cours Find boxes in patchbay Trouver les boîtes dans la baie de brassage Dialog Error ! Erreur ! Error Text Texte d'erreur Copy File ? Copier le fichier ? file is not in proxy directory. Le fichier n'est pas dans le repertoire du proxy. <html><head/><body><p>Do you want to copy this file to proxy directory or to use directly this file ?</p></body></html> <html><head/><body><p>Voulez-vous copier ce fichier dans le repertoire du proxy<br>ou utiliser directement ce fichier ?</p></body></html> Copy file and rename it with session name Copier le fichier et le renommer avec le nom de la session Copy And Rename File Copier et renommer le fichier Copy File Copier le fichier Use This File Utiliser ce fichier %s is not in proxy directory %s n'est pas dans le répertoire du proxy Select File to use as CONFIG_FILE Sélectionnez le fichier à utiliser comme CONFIG_FILE Executable failed to launch ! It's maybe not present on system. Échec du lancement ! L'exécutable n'est peut-être pas présent sur le système. Properties Propriétés Client id Identifiant Executable Exécutable nsmid nsmid Label Étiquette executable exécutable client_name nom du client Name Nom Save Changes Sauvegarder les changements Icon Icône ... ... : : Opening NSM Session Ouverture d'une session NSM <html><head/><body><p>You are opening a session created by Non Session Manager.</p><p><br/>Ray Session will open it, but changes won't be applied to NSM file (session.nsm).</p><p>Also, Once you start to work with Ray Session, you have to continue with it !</p></body></html> <html><head/><body><p>Vous ouvrez une session créée par Non Session Manager</p><p><br/>Ray Session va l'ouvrir, mais les changements ne seront pas appliqués au fichier de session NSM (session.nsm).</p><p>En fait, dès que vous commencez à travailler sur une session avec Ray Session, vous devez continuer avec.</p></body></html> Don't Show this Message Again Ne plus afficher ce message Prevent to stop without recent save Empêcher l'arrêt sans sauvegarde récente Stop Client ? Arrêter le client ? <html><head/><body><p><span style=" font-weight:600;">%s</span> contains unsaved changes. </p><p>Do you really want to stop it ?</p></body></html> <html><head/><body><p><span style=" font-weight:600;">%s</span> contient des changements non sauvegardés. </p><p>Voulez-vous vraiment l'arrêter ?</p></body></html> Don't prevent to stop this client again ! Ne plus empêcher l'arrêt de ce client ! Save && Stop Sauvegarder && Arrêter Just Stop Arrêter Cancel Annuler client_label éltiquette du client client_icon icône du client <html><head/><body><p align="center">Do you want to restore this client in the session ?<br/>You can also definitely remove the client and its files.</p></body></html> <html><head/><body><p align="center">Voulez-vous restaurer ce client dans la session ?<br/>Vous pouvez aussi supprimer le client et tous ses fichiers.</p></body></html> <html><head/><body><p>Remove definitely the client and its files.</p></body></html> <html><head/><body><p>Supprimer définitivement le client et tous ses fichiers.</p></body></html> Remove Supprimer <html><head/><body><p>Restore this client in current session.</p></body></html> <html><head/><body><p>Restaurer ce client dans la session en cours.</p></body></html> Restore Client Restaurer le client Abort Copy ? Abandonner la copie ? Do you want to abort current copy ? Voulez-vous abandonner la copie en cours ? Abort Copy Abandonner la copie Daemon URL URL du démon ray-daemon url to connect to : se connecter à l'url du ray-daemon : osc.udp://192.168.XX.XX:1234/ osc.udp://192.168.XX.XX:1234/ Arguments Arguments Edit executable Éditer l'exécutable Edit Executable Éditer l'exécutable <html><head/><body><p>Edit executable is strongly discouraged !<br/>It can be useful if you use many versions of a same software.<br/>Change it only if you are sure of what you are doing.</p></body></html> <html><head/><body><p>Éditer l'exécutable est vivement déconseillé !<br/>Ça peut s'avérer pratique si vous utilisez plusieurs versions d'un même programme.<br/>Ne changez cela que si vous êtes certains de ce que vous faites.</p></body></html> Executable : Exécutable : <html><head/><body><p>Arguments are supposed to not be supported by NSM protocol.<br/>In some cases it can works, but no warranty !</p></body></html> <html><head/><body><p>Les arguments sont censés ne pas être supportés par le protocole NSM.<br/>Dans certains cas ça peut fonctionner, mais aucune garantie !</p></body></html> Arguments : Arguments : <html><head/><body><p align="right"><span style=" font-style:italic;">You will have to save changes in Properties window<br/>and restart the client to apply these changes.</span></p></body></html> <html><head/><body><p align="right"><span style=" font-style:italic;">Vous devez sauvegarder les changements dans la fenêtre de propriétés<br/>et redémarrer le client pour appliquer ces changements.</span></p></body></html> Snapshots Clichés <html><head/><body><p>Edit here what types of files inside the client folders<br/>should be ignored in session snapshots.</p><p>Indexed files will remain so.</p></body></html> <html><head/><body><p>Éditez ici quels types de fichiers dans les dossiers du client<br/>doivent être ignorés dans les clichés de la session.</p><p>Les fichiers déjà indexés le resteront.</p></body></html> Snapshots ignored extensions : Extensions ignorées par les clichés : Name Snapshot Nommer le cliché Snapshot Name : Nom du cliché : <html><head/><body><p>Snapshot process seems to be long.<br/>Maybe your session's folder contains too many new files<br/>whose extension is not ignored.</p><p>You can abort this snapshot,<br/>it will de-activate snapshots for this session.</p></body></html> <html><head/><body><p>Le processus du cliché semble être long.<br/>Peut-être que votre dossier de session contient trop de fichiers<br/>dont l'extension n'est pas ignorée.</p><p>Vous pouvez abandonner ce cliché,<br/>celà désactivera les clichés automatiques pour cette session.</p></body></html> Abort Snapshot Abandonner le Cliché Snapshots Manager Gestionnaire de clichés <html><head/><body><p>Select from the list below the snapshot to be recalled<br/>to return to a past state of the session :</p></body></html> <html><head/><body><p>Selectionnez parmi la liste ci-dessous le cliché à rappeller<br/>pour revenir à un état antérieur de la session :</p></body></html> Take a snapshot now ! Prendre un cliché maintenant ! <html><head/><body><p>Make a snapshot at each session save.</p></body></html> <html><head/><body><p>Prendre un cliché à chaque sauvegarde de session.</p></body></html> Auto snapshot at save for this session Cliché automatique à la sauvegarde pour cette session Snapshots Informations Infos sur les clichés <html><head/><body><p>Snapshots are NOT backups !!!</p><p>Besides, It's not overrated to copy your session folder elsewhere<br/>before to ask a previous snapshot.</p><p>Snapshots ignore audio files and other big files (&gt;50Mb),<br/>else snapshot process would be too long, <br/>and the session folder size would be too big.</p><p>That being said, you can decide that your work in the last hours<br/>was not a good idea and return to a previous snapshot !</p></body></html> <html><head/><body><p>Les clichés ne sont PAS des copies de sauvegarde !!!</p><p>D'ailleurs, il n'est pas surfait de copier votre dossier de session ailleurs<br/>avant de rappeler un cliché.</p><p>Les clichés ignorent les fichiers audios et les autres gros fichiers(&gt;50Mb),<br/>sinon le processus de cliché serait trop long,<br/>et le dossier de la session deviendrait trop lourd.</p><p>Ceci étant dit, vous pouvez estimer que le travail effectué ces dernières heures<br>n'était finalement pas une bonne idée, et décider de revenir à un cliché précédent !</p></body></html> Do not show this message again Ne plus afficher ce message <html><head/><body><p>You can save the session before the snapshot.</p><p>Save is recommended,<br/>unless you made unwanted changes since the last session save.</p></body></html> <html><head/><body><p>Vous pouvez sauvegarder la session avant de prendre le cliché.</p><p>La sauvegarde est recommandée,<br/>sauf si vous avez fait des changements indésirés depuis la dernière sauvegarde.</p></body></html> Save && Snapshot Sauvegarde && cliché Snapshot Only Cliché uniquement Prevent to stop without recent or possible save Empêcher l'arrêt sans sauvegarde récente ou possible Donations Dons <html><head/><body><p>Hi !</p><p>it seems that you appreciate RaySession, that is already a good new.<br/>This software is free as in Speech and as in Beer,<br/>but it has required and still takes time.</p><p>Make a donation (even small) is a simple way to say &quot;Thank you&quot;.<br/>You can donate <a href="https://liberapay.com/Houston4444"><span style=" text-decoration: underline; color:#2980b9;">here</span></a>.</p><p>If ever you donate nothing,<br/>this program will continue to work without limits of functionnality,<br/>without limit of duration, and even without insulting you ;) .</p></body></html> <html><head/><body><p>Bonjour !</p><p>Il semble que vous appréciiez RaySession, c'est déjà une bonne nouvelle.<br/>C'est un logiciel libre,<br/>mais il a demandé et demande encore du temps.</p><p>Faire une donation (même petite) est un moyen simple de dire &quot;Merci&quot;.<br/>Vous pouvez donner <a href="https://liberapay.com/Houston4444"><span style=" text-decoration: underline; color:#2980b9;">ici</span></a>.</p><p>Si jamais vous ne donnez rien,<br/>ce programme continuera de fonctionner sans limite de fonctionnalité,<br/>sans limite de durée, et même sans vous insulter ;) .</p></body></html> Remove Template ? Supprimer le modèle ? <html><head/><body><p>Are you sure to want to remove this template ?</p></body></html> <html><head/><body><p>Êtes-vous sûr de vouloir supprimer ce modèle ?</p></body></html> <html><head/><body><p>We have no possibility to save the client <span style=" font-weight:600;">%s</span>.</p><p>For this reason, it's preferable that you close yourself this client,<br/>probably by closing its window, saving its changes or not.</p></body></html> <html><head/><body><p>Nous n'avons aucune possibilité de sauvegarder le client <span style=" font-weight:600;">%s</span>.</p><p>Pour cette raison, il est préférable que vous fermiez ce client vous-même,<br/>Probablement en fermant sa fenêtre, en sauvegardant ou non ses changements.</p></body></html> Don't prevent to stop this client again (discouraged) Ne plus empêcher la fermeture de ce client (déconseillé) Stop Anyway Arrêter malgré tout Close clients yourself ! Fermez les clients vous-même ! <html><head/><body><p align="center">Some active clients do not offer any save possibility !</p><p align="center">Therefore, it is best that you close these clients yourself,<br/>probably by closing their windows and saving changes.</p><p align="center"><span style=" font-weight:600;">Please close yourself the programs with this save icon:</span></p></body></html> <html><head/><body><p align="center">Certains clients actifs n'offrent aucune possibilité de sauvegarde !</p><p align="center">Par conséquent, il est préférable que vous fermiez ces clients vous-même<br/>probablement en fermant leurs fenêtres et en sauvegardant leurs changements.</p><p align="center"><span style=" font-weight:600;">Merci de fermer vous-même les programmes ayant cette icône de sauvegarde:</span></p></body></html> <html><head/><body><p>You've got 2 minutes !<br/><span style=" font-style:italic;">You can do it without closing this dialog window.</span></p></body></html> <html><head/><body><p>Vous avez 2 minutes !<br/><span style=" font-style:italic;">Vous pouvez le faire sans fermer cette fenêtre de dialogue.</span></p></body></html> Do not show again Ne plus afficher ce message Undo Défaire Ok Ok Skip Passer General General Description Description Protocol Protocole client_protocol Protocole du client Jack Configuration Infos Infos sur la configuration de JACK <html><head/><body><p>You create a session from the JACK configuration reminder template.</p><p>This means that when you re-open this session, JACK may be restarted with the configuration used by that session.</p><p>This session callback is made from the session scripts.</p></body></html> <html><head/><body><p>Vous créez une session à partir du modèle à mémoire de configuration de JACK.</p><p>Celà veut dire que lorsque vous re-ouvrirez cette session, JACK peut être redémarré avec la configuration utilisée par cette session.</p><p>Ce rappel de session est effectué à partir des scripts de session.</p></body></html> Session Scripts Infos Infos sur les scripts de session <!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" /><title>Session Scripts Infos</title><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; 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;">Session scripts are located in the <span style=" font-style:italic;">ray-scripts</span> folder in the session folder, but they could also be located in a <span style=" font-style:italic;">ray-scripts</span> folder in a parent folder of the session folder.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For example:</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the scripts folder for this new session will be:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">But could just as well be:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and thus apply to all sessions contained in <span style=" font-weight:600;">%s</span>.</p></body></html> <!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" /><title>Infos sur les scripts de session</title><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; 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;">Les scripts de session se trouvent dans le dossier <span style=" font-style:italic;">ray-scripts</span> dans le dossier de la session, mais ils pourraient tout aussi bien se trouver dans le dossier <span style=" font-style:italic;">ray-scripts</span> d'un dossier parent de celui de la session.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Par exemple:</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Le dossier des scripts pour cette nouvelle session sera:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Mais pourrait tout aussi bien être:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">et ainsi s'appliquer à toutes les sessions contenues dans: <span style=" font-weight:600;">%s</span>.</p></body></html> Jack Config Script Infos Infos sur les scripts de mémoire de configuration de JACK <!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:'Noto Sans'; font-size:10pt; 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;"><span style=" font-weight:600;">The principle is as follows:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Each time the session is saved, the JACK configuration is saved in the session.<br />Before opening, JACK is restarted if the session configuration is different from the current one.<br />After closing, JACK is restarted as it was configured before opening if needed.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If you open this session on another computer, the JACK configuration will not be recalled but will be overwritten when you save.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If you wish to open this session without reloading the JACK configuration, simply disable the session scripts.</p></body></html> <!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:'Noto Sans'; font-size:10pt; 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;"><span style=" font-weight:600;">Le principe est le suivant:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">À chaque fois que la session est sauvegardée, la configuration de JACK est sauvegardée dans la session.<br />Avant l'ouverture, JACK est rédemarré si la configuration de la session est différente de la configuration actuelle de JACK.<br />Après la fermeture, JACK est redémarré avec la configuration en cours avant l'ouverture.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Si vous ouvrez cette session sur un autre ordinateur, la configuration de JACK ne sera pas rappellée mais sera écrasée lors de la sauvegarde.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Si vous souhaitez ouvrir cette session sans recharger la configuration de JACK, désactivez tout simplement les scripts de session.</p></body></html> <html><head/><body><p>Unfortunately, at the moment it is not possible to get the current JACK configuration with certainty, so JACK will be restarted at the first session opening.<br/>You can work around this problem by automatically starting a light daemon at your desktop session startup.</p></body></html> <html><head/><body><p>Hélas, pour le moment il est impossible de connaître la configuration en cours de JACK avec certitude, donc JACK sera redémarré à la première ouverture de session.<br>Vous pouvez contourner ce problème en démarrant automatiquement un petit démon au démarrage de votre session de bureau.</p></body></html> Automatically start ray-jack_checker daemon at startup Lancer automatiquement ray-jack_checker_daemon au démarrage <html><head/><body><p>You are opening a session created by Non Session Manager.</p><p><br/>RaySession will open it, but changes won't be applied to NSM file (session.nsm).</p><p>Also, Once you start to work with RaySession, you have to continue with it !</p></body></html> <html><head/><body><p>Vous ouvrez une session créée par Non Session Manager (or New Session Manager).</p><p><br/>RaySession peut l'ouvrir, mais les changements ne seront pas appliqués au fichier NSM (session.nsm).</p><p>Par conséquent , Une fois que vous avez commencé à travailler avec RaySession, vous devez continuer avec !</p></body></html> file is not in client working directory. Le fichier n'est pas dans le dossier de travail du client. <html><head/><body><p>Do you want to copy this file to client working directory or to use directly this file ?</p></body></html> <html><head/><body><p>Voulez-vous copier ce fichier dans le dossier de travail du client ou utiliser directement ce fichier ?</p></body></html> Script Info Informations de script Script info text texte d'informations de script Script User Action Action d'utisateur du script Info Label Étiquette d'information <html><head/><body><p><hr/></p></body></html> <html><head/><body><p><hr/></p></body></html> Script user action text. Are you ready ? text d'action d'utisateur du script.Êtes-vous prêts ? <html><head/><body><p>You create a session with the basic session scripts.<br/>If you don't know what a script is, or you have absolutely no knowledge in shell scripting, you don't belong here, get out of here right now.</p><p>While you've not edited the scripts, session will behave as a normal session.</p><p>You will find in the session folder a <span style=" font-style:italic;">ray-scripts</span> folder.<br/>In the <span style=" font-style:italic;">ray-scripts </span>folder you will find 3 files:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">load.sh</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">save.sh</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">close.sh</li></ul><p>In theses 3 scripts you can edit some actions to do before or after load, save, or close the session.<br/>If you don't need custom actions at one of theses 3 steps, you can safely remove its file.</p></body></html> <html><head/><body> <p> Vous créez une session avec les scripts de session de base.<br/>Si vous ne savez pas ce qu'est un script, ou si vous n'avez absolument aucune connaissance en script shell, vous ne n'avez rien à faire ici.</p><p>Tant que vous n'aurez pas modifié les scripts, la session se comportera comme une session normale. </p> <p> Vous trouverez dans le dossier de la session un dossier <span style u003d "font-style: italic;"> ray-scripts </span>. <br/> Dans le dossier <span style u003d "font-style: italic;"> ray-scripts </span> vous trouverez 3 fichiers: </p> <ul style u003d "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"> <li style u003d "margin-top: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> load.sh < / li> <li style u003d "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> save.sh </li> <li style u003d "margin-top: 0px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px; "> close.sh </li> </ul> <p> Dans ces 3 scripts, vous pouvez modifier certaines actions à effectuer avant ou après le chargement, la sauvegarde ou la fermeture de la session. <br/>Si vous n'avez pas besoin d'actions personnalisées à l'une de ces 3 étapes, vous pouvez supprimer son fichier en toute sécurité. </p> </body> </html> %s is not in client working directory % s n'est pas dans le répertoire de travail du client Non NSM properties Propriétés non NSM <html><head/><body><p>Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly.</p><p>Some audio programs doesn't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> <html><head/><body><p>Pour plusieurs raisons, les arguments de ligne de commande sont incompatibles avec une gestion de session robuste, Ray Session ne les supporte donc pas directement.</p><p>Quelques programmes audios n'ont pas (encore) d'implémentation NSM mais peuvent avoir l'implémentation LASH/LADISH que nous pouvons utiliser pour le signal de sauvegarde.</p><p>Si vous faites référence à des fichiers qui ne sont pas placés dans le repertoire de la session, vous aurez des soucis si vous copiez/deplacez la session, vous êtes prévenus ! <br/><br/>L'implémentation du protocole NSM dans le programme reste le fonctionnement idéal.</p></body></html> <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> <html><head/><body><p>Le programme sera démarré avec comme dossier courant un sous-dossier de la session.</p><p>Il est recommandé de faire référence uniquement à des fichiers contenus dans ce dossier.</p></body></html> Config File : Fichier de configuration : Browse Naviguer <html><head/><body><p>The environment variables $NSM_CLIENT_ID and $RAY_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.<br/>The variable $CONFIG_FILE will contain the name of the config file selected above.</p></body></html> <html><head/><body><p>Les variables d'environnement $NSM_CLIENT_ID et $RAY_SESSION_NAME contiennent respectivement l'identifiant du client et le nom de la session.<br/>La variable $CONFIG_FILE contient le nom du fichier sélectionné ci-dessus.</p></body></html> Wait window before reply (needs wmctrl) Attendre une fenêtre avant de répondre au serveur (requiert wmctrl) <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then Ray Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> <html><head/><body><p>Quelques programmes (vraiment très peu) peuvent répondre à un signal spécifiquement Unix pour sauvegarder leur état.</p><p>Si le signal de sauvegarde est réglé sur autre chose que 'Aucun', alors Ray-Proxy délivrera le signal choisi au processus lors de la sauvegarde du proxy.</p><p>Si le programme est compatible LASH/LADISH, le signal de sauvegarde est SIGUSR1</p><p>La plupart des programmes vont traiter ce signal comme un SIGTERM et s'éteindre.</p><p>Vous êtes prévenus !</p></body></html> <html><head/><body><p>Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal.<br/>It's impossible to know which signal a specific program will respond to.<br/>A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK).<br/>Check the program's documentation or source code to determine which signal to use to stop it gracefully.</p></body></html> <html><head/><body><p>La plupart des programmes vont s'éteindre tranquillement avec l'envoi d'un signal SIGTERM ou SIGINT. <br/>Il est impossible de savoir à quel signal un programme spécifique va répondre.<br/>Un signal non géré peut simplement tuer le processus et causer des problèmes avec le pilote audio (JACK par exemple).<br/>Consultez la documentation ou le code source du programme pour déterminer quel signal utiliser pour une extinction sereine.</p></body></html> Stop Signal : Signal d'extinction : Test Tester Save Signal : Signal de sauvegarde : No Save Level : Niveau de non-sauvegarde : <html><head/><body><p>If this proxy has no save signal,<br/>it can sends to session manager this information.</p><p><ul><li>0 - this information is not sent.</li><li>1 - this information is sent, session manager will ask user to close programs himself at session unload.</li><li>2 - this information is sent, session manager can try to close window gracefully before to ask user to close programs himself at session unload. Good choice if the program displays a dialog if changes are not saved.</li></ul></p></body></html> <html><head/><body><p>Si ce proxy n'a pas de signal de sauvegarde,<br/>il peut transmettre au gestionnaire de session cette information.</p><p><ul><li>0 - cette information n'est pas transmise.</li><li>1 - cette information est transmise, le gestionnaire de session demandera à l'utilisateur de fermer le programme lui-même au déchargement de la session.</li><li>2 - cette information est transmise, le gestionnaire de session peut essayer de fermer gracieusement les fenêtres du programme au déchargement de la session. Bon choix si le programme affiche une fenêtre de dialogue si des changements n'ont pas été sauvegardés.</li></ul></p></body></html> executable failed to launch ! L'exécutable n'a pas réussi à se lancer ! Notes Notes Edit some notes for the session Éditer les notes de session Rename Client Renommer le client TextLabel Étiquette Rename this client to : Renommer ce client en : Trashed client Client à la corbeille Prettier Name Plus joli nom <html><head/><body><p>Get more informations on this trashed client.</p></body></html> <html><head/><body><p>Obtenir plus d'informations sur ce client à la corbeille.</p></body></html> Dialog Dialogue Notes of session : Notes de la session : Session name Nom de la session Canvas Options Préférences du canevas <html><head/><body><p>Display shorter and more readable ports and groups names.</p><p>If unchecked, displayed port names will be the trought port names.</p></body></html> <html><head/><body><p>Afficher des noms de ports et de groupes plus courts et plus lisibles.</p><p>Si décochée, les noms de ports affichés seront les vrais noms de ports.</p></body></html> Use graceful names Utiliser des noms digestes Group A2J hardware ports Grouper les ports A2J matériels Boxes have shadows Les boîtes ont des ombres <html><head/><body><p>Always resize the canvas scene to the mininum contents.</p><p>This way, the view is directly optimized while moving boxes.</p></body></html> <html><head/><body><p>Toujours redimensionner la scène à son contenu minimum.</p><p>De cette façon, la vue est optimisée en direct lors du déplacement des boîtes.</p></body></html> Elastic canvas Canevas élastique Theme : Thème : Port Infos Infos sur le port Full port name : Nom complet du port : Type Type Flags Attributs Port Flags Attributs du port Audio Port Port audio JACK UUID UUID de JACK Metadatas Métadonnées Port-Group Port-Group Order Ordre Pretty name Joli nom Convert Ardour session to Ray Convertir une session Ardour en session Ray This script helps you to load an ardour session made with Ardour into a RaySession session. For performance reasons, the ardour project will be moved (and not copied) to the session directory. This script seems to work well, but there is absolutely no warranty that some problems could appear, so it is advisable to backup your ardour session first. In the future, think to always start Ardour from RaySession ! You can never be sure to not need another software, and auto snapshots can help you a lot. Now let choose the Ardour session you want to convert to a Ray session. Ce script permet de charger une session Ardour faite avec Ardour dans une session RaySession. Pour des raisons de performances, le projet Ardour sera deplacé (et non copié) dans le dossier de la session. Ce script semble fonctionner correctement, mais il n'y a aucune garantie qu'aucun problème ne puisse apparaître, donc il est conseillé de faire une copie de sauvegarde de votre session ardour d'abord. À l'avenir, pensez à toujours démarrer Ardour depuis RaySession ! Vous ne pouvez jamais être sûr de ne pas avoir besoin d'un autre programme, et les clichés automatiques peuvent vous sauver la mise. Vous allez maintenant pouvoir choisir la session Ardour à convertir en session RaySession. Do not display this message again Ne plus afficher ce message Hydrogen NSM script script Hydrogen NSM <html><head/><body><p>This script converts all regular <span style=" font-weight:600;">Hydrogen<br/></span>Ray-Hack clients to the NSM protocol.</p><p>Where do you want the script to proceed:</p></body></html> <html><head/><body><p>Ce script convertit tous les clients <span style=" font-weight:600;">Hydrogen<br/></span> de type Ray-Hack au protocole NSM.</p><p>Où voulez-vous que le script procède ?</p></body></html> In the current session Dans la session en cours In all sessions Dans toutes les sessions In application templates Dans les modèles d'application In session templates Dans les modèles de session <html><head/><body><p><span style=" font-style:italic;">Note that you could lose some JACK connections,<br/>but it's still worth it.</span></p></body></html> convert to NSM file format Convertir au format de fichier NSM <html><head/><body><p>This script will convert a session to the NSM file format.<br/>This way, you will be able to open it with <span style=" font-weight:600;">New Session Manager</span>,<br/><span style=" font-weight:600;">Non Session Manager</span> or <span style=" font-weight:600;">Agordejo</span>, you will still can open it<br/>with <span style=" font-weight:600;">RaySession</span>.</p><p>Note that some specifics things will change :</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">All client projects will be named with their client name<br/>and not with the session name.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Allmost JACK clients will have a longer name,<br/>containing the client_id.</li></ul></body></html> <html><head/><body><p>Ce script convertit une session au format de fichier NSM.<br/>De cette façon, vous pourrez l'ouvrir avec <span style=" font-weight:600;">New Session Manager</span>,<br/><span style=" font-weight:600;">Non Session Manager</span> ou <span style=" font-weight:600;">Agordejo</span>, vous pourrez toujours l'ouvrir <br/>avec <span style=" font-weight:600;">RaySession</span>.</p><p>Notez que quelques petites choses vont changer</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Tous les projets des clients seront nommés avec le nom du client<br/>et non avec le nom de la session.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">La plupart des clients JACK auront un nom plus long<br/>contenant l'identifiant du client.</li></ul></body></html> <html><head/><body><p>jackpatch is the program in the session which<br/>remembers and connects JACK connections.<br/><br/>If this option is enabled, the session will replace ray-jackpatch<br/>with jackpatch (the NSM one), else session will works only if<br/>RaySession is installed.</p></body></html> <html><head/><body><p>jackpatch est le programme dans la session qui<br/>mémorise et refait les connexions JACK.<br/><br/>Si cette option est cochée, ray-jackpatch sera remplacé par jackpatch (celui de NSM), sinon la session fonctionnera uniquement si RaySession est installé.</p></body></html> Use NSM jackpatch Utiliser le jackpatch de NSM Previous session Session précédente <html><head/><body><p>Welcome to <span style=" font-weight:600;">RaySession</span> !</p></body></html> <html><head/><body><p>Bienvenue en <span style=" font-weight:600;">RaySession</span> !</p></body></html> New session Nouvelle session Open session Ouvrir une session Do you want to load this previous session ? Voulez-vous charger cette session précédente ? Display at startup Afficher au démarrage System Tray Boîte à miniatures Your session is still runing. RaySession will run in the background. You can make the window re-appear from your system tray. Votre session est toujours en cours. RaySession va tourner en tâche de fond. Vous pouvez faire ré-apparaître la fenêtre depuis votre boîte à miniatures. Tray Icon Options Options de la boîte à miniatures Pro&vide system tray icon Fournir une &icône dans la boîte à miniatures Only when session is running Seulement quand une session tourne <html><head/><body><p>Never ask what to do and close GUI process<br/>if you close RaySession while a session is running. </p><p>The session will still running and you just have<br/>to restart RaySession to manage it.</p><p>This method uses less RAM than<br/>keeping window in system tray.</p></body></html> <html><head/><body><p>Ne jamais demander quoi faire et arrêter le processus de l'IGU<br/>si vous fermez RaySession quand une session est en cours. </p><p>La session sera toujours en cours et vous n'aurez<br/>qu'à redémarrer RaySession pour la gérer.</p><p>Cette méthode utilise moins de mémoire vive que si vous capturez la fenêtre dans la boîte à miniatures.</p></body></html> Quit shutdowns the GUI Quitter éteint l'interface graphique <html><head/><body><p>When this option is active, boxes are automatically moved when another box has been moved over them.</p></body></html> <html><head/><body><p>Quand cette option est active, les boîtes sont automatiquement déplacées quand une autre boîte est placée par dessus.</p></body></html> Prevent overlapping of boxes Empêcher la superposition des boîtes Maximum port width : Largeur maxi des ports : Enable it if your systray is at bottom of the screen. Activez cette option si votre boîte à miniatures est en bas de l'écran. Reversed menu order Ordre de menu inversé DialogAboutRaysession About Ray Session À propos de Ray Session <html><head/><body><p><img src=":/128x128/raysession.png"/></p></body></html> <html><head/><body><p><img src=":/128x128/raysession.png"/></p></body></html> <html><head/><body><p>Ray Session is a Qt interface for the ray-daemon.</p><p>Its goal is to manage together audio programs as Ardour, Carla, Qtractor, Non-Timeline in an unique session.</p><p>Programs just have to be compatible with the <a href="http://non.tuxfamily.org/wiki/Non%20Session%20Manager"><span style=" text-decoration: underline; color:#2980b9;">NSM</span></a> API to work with Ray Session.<br/></p><p align="right">Copyright (C) 2016-2021 houston4444</p><p><br/></p></body></html> <html><head/><body><p>Ray Session est une interface Qt pour ray-daemon.</p><p>Son rôle est d'organiser ensemble des programmes audio comme Ardour, Carla, QTractor, Non-Timeline dans une session unique.</p><p>Les programmes doivent seulement être comptatibles avec l'API de <a href="http://non.tuxfamily.org/wiki/Non%20Session%20Manager"><span style=" text-decoration: underline; color:#2980b9;">NSM</span></a> pour fonctionner avec Ray Session.<br/></p><p align="right">Copyright (C) 2016-2021 houston4444</p><p><br/></p></body></html> About RaySession À propos de RaySession <html><head/><body><p><span style=" font-weight:600;">RaySession</span></p><p>version : %s</p></body></html> <html><head/><body><p><span style=" font-weight:600;">RaySession</span></p><p>version : %s</p></body></html> DialogAddApplication Add Application Ajouter une application Filter : Filtre : Factory Usine User Utilisateur <html><head/><body><p>NSM is the protocol used by modern audio programs to ensure a good session management.</p></body></html> <html><head/><body><p>NSM est le protocole utilisé par les programmes audio modernes pour assurer une bonne gestion de session.</p></body></html> NSM NSM <html><head/><body><p><span style=" font-weight:600;">Ray-Hack</span> is a fake protocol that tries to manage non NSM compatible programs as it can.</p><p>It can be useful :</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">for audio programs that don't have NSM implementation yet</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">for non-audio programs</li></ul></body></html> <html><head/><body><p><span style=" font-weight:600;">Ray-Hack</span> est un pseudo-protocole qui essaye de gérer comme il peut les programmes non compatibles NSM.</p><p>Il peut être utile :</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Pour les programmes audio qui n'ont pas encore d'implémentation NSM</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Pour les programmes non audios</li></ul></body></html> Ray-Hack Ray-Hack ... ... MacronDemission Nom du programme <html><head/><body><p>Add this template to favorites / Remove this template from favorites</p></body></html> <html><head/><body><p>Ajouter ce modèle aux favoris / Retirer ce modèle des favoris</p></body></html> resistance to the oppression of pests Description de l'application Non Saveable Program !!! Programme non sauvegardable !!! : : Protocol Protocole Executable Exécutable label étiquette Label Étiquette lallement NLP Name Nom Program Name Nom du programme <html><head/><body><p>Get more informations on this template.</p></body></html> <html><head/><body><p>Obtenir plus d'informations sur ce modèle.</p></body></html> No template selected Aucun modèle sélectionné Filter application templates Filtrer les modèles d'application Refresh Applications Raffraichir les applications Refresh\nApplications Raffraichir les\napplications F5 F5 DialogNewExecutable New Executable Client Ajouter un client exécutable Executable : Exécutable : <html><head/><body><p>If program is not compatible with the NSM API, </p><p>you should launch it in proxy to define a config file !</p></body></html> <html><head/><body><p>Si le programme n'est pas compatible avec l'API de NSM, </p><p>vous devriez le lancer dans un proxy pour définir un fichier de configuration !</p></body></html> Run via Proxy Lancer via un proxy <html><head/><body><p>Show more options ...</p></body></html> <html><head/><body><p>Afficher plus d'options ...</p></body></html> ... ... Advanced Options avancées Prefix : Préfixe : Prefix Mode : Mode de préfixe : Client ID : ID du client : <html><head/><body><p>The Prefix Mode determines the pattern of the client files.</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Session Name (Default) :<br/>The client files names start with the session name.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Client Name :<br/>The client files names start with the client name given by the client itself<br/>(as in Non Session Manager).</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Custom :<br/>The client files names start with the prefix written below.</li></ul></body></html> <html><head/><body><p>Le mode de préfixe détermine le motif des noms de fichier du client.</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Nom de la session (par défaut) :<br/>Les noms de fichier du client commencent par le nom de la session.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Nom du client :<br/>Les noms de fichier du client commencent par le nom de client donné par le client lui même<br/>(comme dans Non Session Manager).</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Personnalisé :<br/>Les noms de fichier du client commencent par le préfixe écrit ci-dessous.</li></ul></body></html> <html><head/><body><p>Use it If you want to add to session a file made outside from a session.</p><p>If you let this line empty, the client_id will be automaticely generated.</p></body></html> <html><head/><body><p>Utilisez ceci si vous voulez ajouter à la session un fichier fabriqué en dehors d'une session.</p><p>Si vous laissez cette ligne vide, l'ID du client sera généré automatiquement.</p></body></html> NSM Protocol Protocole NSM Start the client Démarrer le client <html><head/><body><p>With this option checked, NSM programs should name their JACK client names starting with ClientName.ClientId (as in NSM), else it will be ClientName (with a digit suffix if needed).</p></body></html> <html><head/><body><p>Avec cette option enclenchée, les programmes NSM devraient nommer leur client JACK avec le motif NomDuProgramme.Identifiant (comme dans NSM), sinon ce sera NomDuProgramme (éventuellement suivi d'un nombre si requis).</p></body></html> Long JACK Naming Longs noms de client JACK DialogNewSession New Session Nouvelle session NSM Folder : Dossier des sessions : /home/user/Ray Sessions Sessions /home/user/Ray Folder Dossier New Session Name : Nom de la nouvelle session : Template : Modèle : <html><head/><body><p><span style=" font-size:9pt; font-weight:600;">Sessions Folder :</span></p></body></html> <html><head/><body><p><span style=" font-size:9pt; font-weight:600;">Dossier des sessions :</span></p></body></html> Sub Folder : Sous-dossier : Original session : Session originale : session name Nom de la session DialogOpenSession Open Session Ouvrir une session Sessions Folder : Dossier des sessions : /home/user/NSM Sessions Sessions /home/user/NSM Folder Dossier Filter : Filtre : <html><head/><body><p><span style=" font-size:9pt; font-weight:600;">Sessions Folder :</span></p></body></html> <html><head/><body><p><span style=" font-size:9pt; font-weight:600;">Dossier des sessions :</span></p></body></html> /home/user/Ray Sessions /home/user/Ray Sessions %p% %p% Sort by dates Trier par dates >_ >_ ... ... 0 Mo O Mio Clients Clients Notes Notes Snapshots Clichés /ho&me/user/Ray Sessions /ho&me/utilisateur/Ray Sessions Listing sessions Recherche de sessions Cancel Annuler Name Nom Date Date Save the current session Sauvegarder la session en cours DialogQuitApp Quit RaySession Quitter Ray Session <p>Session <bold>%s</bold> is running.</p><p>RaySession will be closed.</p><p>Do you want to save session ? <p>La session <bold>%s</bold> est en cours.</p><p>RaySession va se fermer.</p><p>Voulez-vous sauvegarder la session ? Save && Quit Sauvegarder && quitter Quit Without Saving Quitter sans sauvegarder Cancel Annuler <html><head/><body><p>Do you want to save the session before snapshot ?</p><p>Save is recommended,<br/>unless you made unwanted changes since the last session save.</p></body></html> <html><head/><body><p>Voulez-vous sauvegarder la session avant de prendre le cliché ?</p><p>La sauvegarde est recommandée,<br/>sauf si vous avez fait des changements indésirés depuis la dernière sauvegarde de session.</p></body></html> Save && Snapshot Sauvegarde && cliché Snapshot Cliché Keep Daemon Running Laisser le démon tourner DialogSaveTemplateSession New Template Nouveau modèle Session Template Name : Nom du nouveau modèle de session : Create Template Créer le modèle Cancel Annuler Session : Session : ... ... Client Label Étiquette du client Duplicate Duplicated session name : Nom de la session dupliquée : Duplicate Session Dupliquer la session Form Form Forme Sample Rate : Échantillonage : 48.000 48.000 Hz Hz Buffer : Tampon : 0 Xruns 0 Xruns DSP : DSP : <p style="color:red">JACK is not started !</p> <p style="color:red">JACK n'est pas lancé !</p> JACK Samplerate Fréquence d'échantillonage de JACK Number of audio Xruns. Click on it to reset them. Nombre de décrochages audios (Xruns). Cliquez dessus pour réinitialiser le compteur. DSP: %p% DSP: %p% 100 % 100 % Frame Frame Trame ... ... Template Name Nom du modèle client_name nom du client : : client_capabilities capacités du client Name Nom Capabilities Capacités <html><head/><body><p>Edit executable is strongly discouraged !<br/>It can be useful if you use many versions of a same software.<br/>Change it only if you are sure of what you are doing.</p></body></html> <html><head/><body><p>Éditer l'exécutable est vivement déconseillé !<br/>Ça peut s'avérer pratique si vous utilisez plusieurs versions d'un même programme.<br/>Ne changez cela que si vous êtes certains de ce que vous faites.</p></body></html> Executable : Exécutable : <html><head/><body><p>Arguments are supposed to not be supported by NSM protocol.<br/>In some cases it can works, but no warranty !</p></body></html> <html><head/><body><p>Les arguments sont censés ne pas être supportés par le protocole NSM.<br/>Dans certains cas ça peut fonctionner, mais aucune garantie !</p></body></html> Arguments : Arguments : <html><head/><body><p>Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly.</p><p>Some audio programs doesn't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> <html><head/><body><p>Pour plusieurs raisons, les arguments de ligne de commande sont incompatibles avec une gestion de session robuste, Ray Session ne les supporte donc pas directement.</p><p>Quelques programmes audios n'ont pas (encore) d'implémentation NSM mais peuvent avoir l'implémentation LASH/LADISH que nous pouvons utiliser pour le signal de sauvegarde.</p><p>Si vous faites référence à des fichiers qui ne sont pas placés dans le repertoire de la session, vous aurez des soucis si vous copiez/deplacez la session, vous êtes prévenus ! <br/><br/>L'implémentation du protocole NSM dans le programme reste le fonctionnement idéal.</p></body></html> session_name.client_id session_name.client_id <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> <html><head/><body><p>Le programme sera démarré avec comme dossier courant un sous-dossier de la session.</p><p>Il est recommandé de faire référence uniquement à des fichiers contenus dans ce dossier.</p></body></html> Browse Naviguer Config File : Fichier de configuration : <html><head/><body><p>Ray Hack protocol is a convenience way to manage non NSM compatible programs in the session.</p><p>Some audio programs don't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> <html><head/><body> <p> Le protocole Ray Hack est un moyen pratique de gérer des programmes non compatibles NSM dans la session. </p> <p> Certains programmes audio n'ont pas encore d'implémentation NSM, mais ils peuvent avoir une implémentation LASH / LADISH, et nous pouvons l'utiliser pour le signal de sauvegarde. </p> <p> Soyez averti que la référence à des fichiers en dehors du répertoire de session nuira à votre capacité à archiver et transporter des sessions de manière fiable. <br/> <br/> Patcher le programme pour utiliser NSM nativement se traduira par une meilleure expérience. </p></body> </html> <html><head/><body><p>The environment variables $NSM_CLIENT_ID and $RAY_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.<br/>The variable $CONFIG_FILE will contain the name of the config file selected above.</p></body></html> <html><head/><body><p>Les variables d'environnement $NSM_CLIENT_ID et $RAY_SESSION_NAME contiennent respectivement l'identifiant du client et le nom de la session.<br/>La variable $CONFIG_FILE contient le nom du fichier sélectionné ci-dessus.</p></body></html> <html><head/><body><p>The environment variable $RAY_CLIENT_ID will contain the RaySession client_id of this client.$RAY_SESSION_NAME will contain the display name for the session.<br/>$RAY_JACK_CLIENT_NAME will contain a string suitable for use as e.g. a JACK client name.<br/>$CONFIG_FILE will contain the name of the config file selected above.</p></body></html> <html><head/><body> <p> Les variables d'environnement $RAY_CLIENT_ID et $RAY_SESSION_NAME contiendront l'ID client unique (utilisable par exemple comme nom de client JACK) et le nom d'affichage de la session, respectivement. <br /> La variable $CONFIG_FILE contiendra le nom du fichier de configuration sélectionné ci-dessus. </p> </body> </html> Folder : Dossier: <html><head/><body><p>If wmctrl is present and compatible with window manager,</p><p>and if this box is checked,</p><p>the program will be considered as ready only when it displays a window.</p><p>Else the program will be considered as ready after 500ms.</p></body></html> <html><head/><body> <p> Si wmctrl est présent et compatible avec le gestionnaire de fenêtres, </p> <p> et si cette case est cochée, </p> <p> le programme sera considéré comme prêt uniquement lorsqu'il affiche une fenêtre. </p> <p> Sinon, le programme sera considéré comme prêt après 500 ms. </p> </body> </html> wait for a window before considering it ready (needs wmctrl) attendre une fenêtre avant d'être considéré comme prêt (nécessite wmctrl) <html><head/><body><p>Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal.<br/>It's impossible to know which signal a specific program will respond to.<br/>A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK).<br/>Check the program's documentation or source code to determine which signal to use to stop it gracefully.</p></body></html> <html><head/><body><p>La plupart des programmes vont s'éteindre tranquillement avec l'envoi d'un signal SIGTERM ou SIGINT. <br/>Il est impossible de savoir à quel signal un programme spécifique va répondre.<br/>Un signal non géré peut simplement tuer le processus et causer des problèmes avec le pilote audio (JACK par exemple).<br/>Consultez la documentation ou le code source du programme pour déterminer quel signal utiliser pour une extinction sereine.</p></body></html> Stop Signal : Signal d'extinction : <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then Ray Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> <html><head/><body><p>Quelques programmes (vraiment très peu) peuvent répondre à un signal spécifiquement Unix pour sauvegarder leur état.</p><p>Si le signal de sauvegarde est réglé sur autre chose que 'Aucun', alors Ray-Proxy délivrera le signal choisi au processus lors de la sauvegarde du proxy.</p><p>Si le programme est compatible LASH/LADISH, le signal de sauvegarde est SIGUSR1</p><p>La plupart des programmes vont traiter ce signal comme un SIGTERM et s'éteindre.</p><p>Vous êtes prévenus !</p></body></html> Save Signal : Signal de sauvegarde : <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then this signal will be sent to the program when we ask to save it.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> <html><head/><body> <p> Certains (très peu) de programmes peuvent répondre à un signal Unix spécifique pour sauvegarder leur état. </p> <p> Si 'Save Signal' est réglé sur autre chose que 'Aucun', alors ce signal sera envoyé au programme lorsque nous demanderons de le sauvegarder. </p> <p> Si le programme est compatible avec LASH / LADISH, le signal de sauvegarde est SIGUSR1. </p> <p> La plupart des programmes traitera ce signal comme SIGTERM et mourra. </p> <p> Vous êtes prévenus. </p> </body> </html> Without save method Sans méthode de sauvegarde <html><head/><body><p>Because we have no method to save the state of this program,<br/>if this box is checked the program won't be closed by session manager at session close,</p><p>it will ask user to close it himself (saving changes or not).</p></body></html> <html><head/><body> <p> Parce que nous n'avons pas de méthode pour sauvegarder l'état de ce programme, <br/> si cette case est cochée, le programme ne sera pas fermé par le gestionnaire de session à la fermeture de la session, </p> <p>Le gestionnaire de session demandera à l'utilisateur de le fermer lui-même (en enregistrant les modifications ou non). </p> </body> </html> Tell user to close program himself at session close Demander à l'utilisateur de fermer lui-même le programme à la fermeture de la session <html><head/><body><p>If wmctrl is present and compatible with window manager,<br/>the program will try to close gracefully its windows before asking user to close them himself.<br/>This way, in a lot of cases, program will be closed when it has no unsaved changes,<br/>or will display an exit confirmation dialog to save changes or not. </p></body></html> <html><head/><body> <p> Si wmctrl est présent et compatible avec le gestionnaire de fenêtres, <br/> le programme essaiera de fermer gracieusement ses fenêtres avant de demander à l'utilisateur de les fermer lui-même. <br/> De cette façon , dans de nombreux cas, le programme sera fermé s'il n'a pas de modifications non enregistrées, <br/> ou affichera une boîte de dialogue de confirmation de sortie pour enregistrer les modifications ou non. </p></body> </html> Try to close window gracefully (needs wmctrl) Essayer de fermer gracieusement la fenêtre (nécessite wmctrl) Test Zone Zone de test Launch Lancer Stop Arrêter Status État stopped arrêté Save Sauvegarder executable failed to launch ! L'exécutable n'a pas réussi à se lancer ! <html><head/><body><p>Edit the daemon URL only if you meet troubles !!!</p></body></html> <html><head/><body><p>N'éditez l'URL du démon qu'en cas de problème !!!</p></body></html> Daemon URL : URL du démon : <html><head/><body><p>Here, sessions root folder is the sessions root folder used by the slave daemon.<br/>Edit it only if you have changed the sessions root folder<br/>used by the slave daemon.</p></body></html> <html><head/><body><p>Ici, le dossier racine des sessions désigne le dossier racine des sessions utilisé par le démon esclave<br/>Ne l'éditez que si vous avez changé le dossier racine des sessions du démon esclave</p></body></html> Sessions root folder : Dossier racine des sessions : <html><head/><body><p>Template session that will be used on the slave daemon if there is no existing session at the same path than the master one (relatively to their sessions root folder).</p><p>The templates used in network sessions are in a hidden folder of the sessions root folder.</p></body></html> <html><head/><body><p>Modèle de session qui sera utilisé par le démon esclave s'il n'existe pas de session<br>au même emplacement que celle utilisée dans le démon maître (relativement à leur dossier racine de sessions).</p><p>Les modèles utilisés dans les sessions réseau sont dans un dossier caché dans le dossier racine des sessions.</p></body></html> Template : Modèle : Test &Zone &Zone de test <html><head/><body><p>here many fields are available to you. This is not necessarily good news, the idea is to be able to load a program into the session that is not (yet) compatible with NSM. If properly implemented in the client, the NSM protocol will always be much more comfortable to use and more reliable than this hack. That said, if we can expect the NSM implementation in all audio programs, this is not the case for other programs which can still be useful in the session.</p><p><br/></p><p>The Ray-Hack pseudo-protocol uses the attributes of proxies (nsm-proxy or ray-proxy), except that the client is launched directly in the session.</p></body></html> <html><head/><body><p>.Ici, moult champs s'offrent à vous. Ce n'est pas forcément une bonne nouvelle, l'idée est de pouvoir charger dans la session un programme qui n'est pas (encore) compatible NSM. S'il est bien implémenté dans le client, le protocole NSM sera toujours bien plus confortable à utiliser et plus fiable que cette bidouille. Ceci dit, si l'on peut attendre l'implémentation NSM dans tous les programmes audio, ce n'est pas le cas des autres programmes qui peuvent tout de même avoir une utilité dans la session.</p><p><br/></p><p>Le pseudo-protocole Ray-Hack reprend les attributs des proxy (nsm-proxy ou ray-proxy), sauf que le client est lancé directement dans la session.</p></body></html> <html><head/><body><p>The program will be started in the folder named above.</p><p>It is recommended that you only refer to files in the current directory.</p><p>$RAY_SESSION_NAME will be replaced with the name of the session.</p></body></html> <html><head/><body><p>Le programme sera lancé dans le nom de dossier ci-dessus.</p><p>Il est recommandé de faire référence uniquement à des fichiers dans ce dossier.</p><p>$RAY_SESSION_NAME sera remplacé par le nom de la session.</p></body></html> Hide filter bar Cacher la barre de filtre Find a box... Trouver une boîte... Audio Audio Midi Midi adjust the opacity of boxes not matching with the filter réglez l'opacité des boîtes ne correspondant pas au filtre Opacity : Opacité : % % Environment variables : Variables d'environnement : <html><head/><body><p>Set here the environment variables you want to set to the process, separate them with spaces.<br/><br/>for example :</p><pre style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Hack';">MY_VAR1=my_value MY_VAR2=&quot;other value&quot;</span></pre></body></html> <html><head/><body><p>Entrez ici les variables d'environnement que vous voulez appliquer au programme, séparées par des espaces.<br/><br/>Par exemple :</p><pre style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Hack';">MA_VARIABLE=ma_valeur MA_VARIABLE2=&quot;autre valeur&quot;</span></pre></body></html> Environment : Environnement : GUIMSG Launching %s Lancement de %s Good Bye ! Clients are still running. Au revoir ! Les clients tournent encore. Good Bye ! Au revoir ! Client %s terminated because we told it to. Le client %s s'est arrêté car nous lui avons demandé. Client %s died unexpectedly. Le client %s s'est arrêté de manière inexpliquée. Failed to start %s Échec du lancement de %s Stopping client %s Arrêt du client %s waiting for clients announces... en attente des annonces des clients... waiting for clients to die... en attente de l'arrêt des clients... %sdidn't announce %s ne s'est pas annoncé %sstill alive ! %s est toujours en vie ! All expected clients are announced Tous les clients attendus sont annoncés All expected clients are died Tous les clients attendus sont arrêtés Can't save session, session file is unwriteable ! Impossible de sauvegarder la session, le fichier de session n'est pas inscriptible ! Session saved. Session sauvegardée. Commanding attached clients to quit. Ordonne aux clients attachés de s'arrêter. Creating new session "%s" Création d'une nouvelle session "%s" Session is ready La session est prête Opening session %s Ouverture de la session "%s" %s launching %s lancé %s terminated as planned %s s'est arrêté comme prévu %s died unexpectedly. %s s'est arrêté de manière inexpliquée. %s Failed to start ! %s n'a pas réussi à démarrer ! %s stopping %s est en train de s'arrêter Session saved as template named %s Session sauvegardée comme modèle nommé %s Stop all clients before rename session ! Arrêtez tous les clients avant de renommer la session ! Session %s has been renamed to %s . La session %s a été renommée %s. Session directory is now: %s Le répertoire de la session est maintenant: %s %s is started but not active %s est démarré mais pas actif %s failed to save! %s n'a pas pu être sauvegardé !! %s failed to open! %s n'a pas pu s'ouvrir! %s: saved %s: sauvegardé %s: project loaded %s: projet chargé can't start %s, it is a dummy client ! %s ne peut pas être démarré, c'est un client factice! %s is exiting. %s se termine. %s seems to can not open %s ne semble pas pouvoir s'ouvrir %s: launched %s: lancé %s: terminated by server instruction %s: terminé par instruction du serveur %s: terminated itself. %s: s'est terminé de lui-même. %s: project probably loaded %s: projet probablement chargé %s: Failed to start ! %s: échec du démarrage! %s failed to launch %s n'a pas pu se lancer %s is already saving, please wait! %s enregistre déjà, veuillez patienter! %s: stopping %s: arrêt impossible to remove %s ! impossible de supprimer %s! %s is not writeable ! %s n'est pas accessible en écriture ! Copy has been aborted ! La copie a été abandonnée ! script %s failed to start ! le script %s n'a pas pu démarrer ! script %s terminated with exit code %i Le script%s s'est terminé avec le code de sortie%i ...script %s finished. --- ...script%s terminé. --- --- Custom step script %s started... --- Le script d'étape personnalisé%s a commencé ... --- Custom script %s started...%s --- Le script personnalisé%s a commencé ...%s %s didn't announce. %s n'a pas annoncé. %s still alive ! %s est tourne encore! -- Saving session %s -- - Sauvegarde de la session %s - waiting for %s to save... en attente de %s pour enregistrer ... waiting for %i clients to save... attente de la sauvegarde de %i clients... Session '%s' saved. La session '%s' a été sauvegardée. snapshot started... cliché démarré... Snapshot aborted! cliché abandonné! ...snapshot finished. ...cliché terminé. waiting for no saveable clients to be closed gracefully... attente de la fermeture gracieuse des clients non sauvegardables... waiting you to close yourself unsaveable clients... en attente que vous fermiez vous même les clients non sauvegardables... waiting for %s to quit... attente de la fermeture de %s... waiting for %i clients to quit... attente de la fermeture de %i clients... -- Duplicating session %s to %s -- - Duplication de la session %s à %s - waiting for network daemons to start duplicate... attente que les démons du réseau commencent à dupliquer ... start session copy... démarrer la copie de session ... ...session copy finished. ...copie de session terminée. waiting for network daemons to finish duplicate attente que les démons réseau terminent la duplication start session copy to template... démarrer la copie de session dans le modèle... ...session saved as template named %s ...session sauvegardée comme modèle nommé %s start copy from template to session folder démarrer la copie du modèle vers le dossier de session -- Opening session %s -- - Ouverture de la session %s - waiting for %s to load its project... attente du chargement de projet de %s... waiting for %s clients to load their project... attente du chargement de projet de %s clients... session %s is loaded. la session%s est chargée. %s is missing or corrupted ! %s est manquant ou corrompu! %s has no RAY-CLIENT-TEMPLATES top element ! %s n'a pas d'élément supérieur RAY-CLIENT-TEMPLATES! %s is not an existing template ! %s n'est pas un modèle existant! No client with this client_id:%s Aucun client avec cet identifiant:%s Impossible, copy running ! Impossible, copie en cours ! session %s is already opened ! la session %s est déjà ouverte! session %s is already used by another daemon ! la session %s est déjà utilisée par un autre démon ! abort ordered from elsewhere, sorry ! abandon ordonné d'ailleurs, désolé ! %s already exists ! %s existe déjà ! session %s is already used by this or another daemon ! la session %s est déjà utilisée par ce démon ou un autre! No session to list clients ! Aucune session pour lister les clients! client %s is already running. le client %s est déjà en cours d'exécution. client %s is already active. le client %s est déjà actif. %s is not saveable. %s n'est pas sauvegardable. %s seems to not be a proxy client ! %s ne semble pas être un client proxy ! impossible to read %s correctly ! impossible de lire correctement %s! Impossible to set proxy properties while client is running. Impossible de définir les propriétés du proxy lorsque le client est en cours d'exécution. %s is not writeable %s n'est pas accessible en écriture %s is not running. %s n'est pas en cours d'exécution. Impossible to run Ray-Net client when session is not in root folder Impossible de lancer un client réseau Ray-Net quand la session en cours n'est pas dans le dossier racine des sessions ...Snapshot finished. ...Cliché terminé. GUI_daemon Connecting GUI to existing ray-daemon port %i Connexion de l'IGU au port ray-daemon existant %i Load Error Unknown error Erreur inconnue Could not create session file! Impossible de créer le fichier de session ! Session is locked by another process! La session est verrouillée par un autre processus ! The named session does not exist. La session sus-nommée n'existe pas. Could not load session file. Impossible de charger le fichier de session. Can't create session in a dir containing a session for better organization. Impossible de créer une session dans un répertoire contenant une session pour une meilleure organisation. MainWindow ... ... Session Name Nom de la session No Session Loaded Aucune session chargée Open Session Folder Ouvrir le dossier de la session Run Command Lancer une commande off éteint Save Session Sauvegarder la session &Messages &Messages Fi&le &Fichier &Session &Session &view &Affichage &Help &Aide toolBar Barre d'outils &Show Messages &Afficher les messages Ctrl+L Ctrl+L &Save &Sauvegarder Ctrl+S Ctrl+S &Open Session &Ouvrir une session Ctrl+O Ctrl+O &New Session &Nouvelle session Ctrl+N Ctrl+N &Quit &Quitter Ctrl+Q Ctrl+Q &About Ray Session À &propos de Ray Session Show &Menu Bar Afficher la barre de &menu Ctrl+M Ctrl+M Control Contrôle &Close &Fermer Ctrl+W Ctrl+W &Abort &Abandonner Abort Current Session Abandonner la session en cours Ctrl+Shift+W Ctrl+Maj+W &Open Session Folder &Ouvrir le dossier de la session Open session folder with file manager Ouvrir le dossier de la session avec le gestionnaire de fichiers &Keep focus while opening clients &Garder le focus lors de l'ouverture des clients Ctrl+F Ctrl+F About &Qt À propos de &Qt &Duplicate &Dupliquer <html><head/><body><p>Duplicate the current session</p></body></html> <html><head/><body><p>Dupliquer la session en cours</p></body></html> Ctrl+D Ctrl+D Ctrl+A Ctrl+A <html><head/><body><p>Save &amp; Close Session</p></body></html> <html><head/><body><p>Sauvegarder &amp; et fermer la session</p></body></html> Ray Proxy Ray Proxy <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> <html><head/><body><p>Le programme sera démarré avec comme dossier courant un sous-dossier de la session.</p><p>Il est recommandé de faire référence uniquement à des fichiers contenus dans ce dossier.</p></body></html> Config File : Fichier de configuration : <html><head/><body><p>Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly.</p><p>Some audio programs doesn't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> <html><head/><body><p>Pour plusieurs raisons, les arguments de ligne de commande sont incompatibles avec une gestion de session robuste, Ray Session ne les supporte donc pas directement.</p><p>Quelques programmes audios n'ont pas (encore) d'implémentation NSM mais peuvent avoir l'implémentation LASH/LADISH que nous pouvons utiliser pour le signal de sauvegarde.</p><p>Si vous faites référence à des fichiers qui ne sont pas placés dans le repertoire de la session, vous aurez des soucis si vous copiez/deplacez la session, vous êtes prévenus ! <br/><br/>L'implémentation du protocole NSM dans le programme reste le fonctionnement idéal.</p></body></html> Executable : Exécutable : Browse Naviguer Arguments : Arguments : <html><head/><body><p>Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal.<br/>It's impossible to know which signal a specific program will respond to.<br/>A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK).<br/>Check the program's documentation or source code to determine which signal to use to stop it gracefully.</p></body></html> <html><head/><body><p>La plupart des programmes vont s'éteindre tranquillement avec l'envoi d'un signal SIGTERM ou SIGINT. <br/>Il est impossible de savoir à quel signal un programme spécifique va répondre.<br/>Un signal non géré peut simplement tuer le processus et causer des problèmes avec le pilote audio (JACK par exemple).<br/>Consultez la documentation ou le code source du programme pour déterminer quel signal utiliser pour une extinction sereine.</p></body></html> Save Signal : Signal de sauvegarde : Stop Signal : Signal d'extinction : Test Tester executable failed to launch ! L'exécutable n'a pas réussi à se lancer ! Launch Lancer Stop Arrêter <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then Ray Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> <html><head/><body><p>Quelques programmes (vraiment très peu) peuvent répondre à un signal spécifiquement Unix pour sauvegarder leur état.</p><p>Si le signal de sauvegarde est réglé sur autre chose que 'Aucun', alors Ray-Proxy délivrera le signal choisi au processus lors de la sauvegarde du proxy.</p><p>Si le programme est compatible LASH/LADISH, le signal de sauvegarde est SIGUSR1</p><p>La plupart des programmes vont traiter ce signal comme un SIGTERM et s'éteindre.</p><p>Vous êtes prévenus !</p></body></html> <html><head/><body><p>Save Session as Template</p></body></html> <html><head/><body><p>Sauvegarder la session comme modèle</p></body></html> Application Application Executable Exécutable Sa&ve As Template Sau&vegarder comme modèle Save current session as template Sauvegarde la session en cours comme modèle Add Ajouter &Executable &Exécutable &Application &Application Server Status État du serveur Save and Close Session Sauvegarder et fermer la session Add executable to current session Ajouter un exécutable à la session en cours Ctrl+E Ctrl+E Add application to current session Ajouter une application à la session en cours <html><head/><body><p>The environment variables $NSM_CLIENT_ID and $RAY_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.<br/>The variable $CONFIG_FILE will contain the name of the config file selected above.</p></body></html> <html><head/><body><p>Les variables d'environnement $NSM_CLIENT_ID et $RAY_SESSION_NAME contiennent respectivement l'identifiant du client et le nom de la session.<br/>La variable $CONFIG_FILE contient le nom du fichier sélectionné ci-dessus.</p></body></html> <html><head/><body><p>Trash</p><p>You will find here removed clients.</p></body></html> <html><head/><body><p>Corbeille</p><p>Vous trouverez ici les clients supprimés.</p></body></html> &View &Affichage &Rename &Renommer &Save All From Saved Client Tout &sauvegarder depuis un client sauvegardé <html><head/><body><p>Some clients (Ardour, Qtractor...) sends their saved state to RaySession.</p><p>When this option is checked, the session is saved when a client sends that it has been saved.</p><p>For example, a Ctrl-S in Ardour will also save all the current Ray Session.</p></body></html> <html><head/><body><p>Certains clients (Ardour, Qtractor...) envoient leur statut de sauvegarde à RaySession.</p><p>Quand cette option est cochée, la session est sauvegardée quand un client envoie l'information comme quoi il a été sauvegardé.</p><p>Par exemple, un Ctrl-S dans Ardour sauvegardera aussi la session en cours dans Ray Session.</p></body></html> Wait window before reply (needs wmctrl) Attendre une fenêtre avant de répondre au serveur (requiert wmctrl) Options Options &Provide bookmarks for session folder Fournir des &raccourcis du dossier de la session Desktops Memory (requires wmctrl) Mémoire des bureaux (requiert wmctrl) <html><head/><body><p>Go back to a previous state of the session.</p></body></html> <html><head/><body><p>Retourner à un état précédent de la session.</p></body></html> Snapshots Clichés &Desktops Memory (requires wmctrl) Mémoire des &bureaux (nécessite wmctrl) Return To A &Previous State (requires git) Retourner à un état &précédent (nécessite git) Auto Snapshot At Save (requires git) Cliché automatique à la sauvegarde (nécessite git) Auto Snapshot at Save (requires git) Cliché automatique à la sauvegarde (nécessite git) No Save Level : Niveau de non-sauvegarde : <html><head/><body><p>If this proxy has no save signal,<br/>it can sends to session manager this information.</p><p><ul><li>0 - this information is not sent.</li><li>1 - this information is sent, session manager will ask user to close programs himself at session unload.</li><li>2 - this information is sent, session manager can try to close window gracefully before to ask user to close programs himself at session unload. Good choice if the program displays a dialog if changes are not saved.</li></ul></p></body></html> <html><head/><body><p>Si ce proxy n'a pas de signal de sauvegarde,<br/>il peut transmettre au gestionnaire de session cette information.</p><p><ul><li>0 - cette information n'est pas transmise.</li><li>1 - cette information est transmise, le gestionnaire de session demandera à l'utilisateur de fermer le programme lui-même au déchargement de la session.</li><li>2 - cette information est transmise, le gestionnaire de session peut essayer de fermer gracieusement les fenêtres du programme au déchargement de la session. Bon choix si le programme affiche une fenêtre de dialogue si des changements n'ont pas été sauvegardés.</li></ul></p></body></html> Favorite Applications Applications favorites Donate Donner Session Scripts Scripts de session Run the session scripts inside the directory ray-scripts Exécutez les scripts de session dans le répertoire ray-scripts RaySession RaySession &Auto Snapshot At Save (requires git) Cliché &automatique à la sauvegarde (nécessite git) &Donate &Dons &Session Scripts &Scripts de session &Remember optional GUI states Se souvenir de l'état des &IGUs Remember if optional GUIs were shown Se souvenir de l'état de visibilité des IGUs optionelles &Edit Session Notes &Éditer les notes de session Make &reappear all dialog windows Faire &ré-apparaître toutes les fenêtres de dialogue Save as Template the current session Sauvegarder la session en cours comme modèle Duplicate the current session Dupliquer la session en cours Rename the current session Renommer la session en cours Online Manual Manuel en ligne Open the online manual in the web browser Ouvrir le manuel en ligne dans le navigateur web Internal Manual Manuel interne Displays internal manual in a web browser Ouvrir le manuel interne dans le navigateur web &Online Manual &Manuel en ligne &Internal Manual Manuel &interne Show &JACK patchbay Afficher la baie de brassage de &JACK Ctrl+J Ctrl+J &Recent sessions Sessions &récentes &Utilities &Utilitaires System tray &icon options Options de la &boîte à miniatures ezf ezf &Convert an Ardour session to a Ray session Convertir une session &Ardour en session RaySession Convert all &Hydrogen Ray-Hack clients to NSM Convertir tous les clients &Hydrogen Ray-Hack en NSM Convert all &Jack Mixer Ray-Hack clients to NSM Convertir tous les clients &Jack Mixer Ray-Hack en NSM Convert &session to NSM file format Convertir la session au format de fichier &NSM Ctrl+H Ctrl+H Convert an &Ardour session to a Ray session Convertir une session &Ardour en session Ray Snapshot Snapshot aborted Cliché abandonné Snapshot Error Unknown error Erreur inconnue git didn't stop normally. %s git ne s'est pas arrêté normalement. %s git crashes. %s git a planté. %s git exit with an error code. %s git s'est terminé avec un code d'erreur. %s Snapshot error Erreur de cliché command didn't stop normally: %s la commande ne s'est pas arrêtée normalement: %s command crashes: %s la commande a planté : %s command exit with an error code: %s la commande s'est terminée avec un code d'erreur : %s error reading file: %s erreur de lecture du fichier : %s actions Desktops Memory Mémoire des bureaux Auto Snapshot at Save Cliché automatique à la sauvegarde add_app_dialog <p>Are you sure to want to remove<br>the template "%s" and all its files ?</p> <p>Êtes-vous sûr de vouloir supprimer<br>le modèle "%s" et tous ses fichiers ?</p> capabilities switch bascule dirty état de sauvegarde optional-gui Interface graphique cachable child_session Child Session Session enfant client Failed to launch process ! Échec de lancement du processus ! failed to move %s/%s to %s/%s, sorry. Échec du déplacement de %s/%s vers %s/%s, désolé. client status stopped arrêté launch lancé open ouverture ready prêt save sauvegarde switch bascule quit arrêt error erreur invalid invalide noop pas-op removed supprimé copy copie client_properties Properties of client %s Propriétés du client %s Properties of template %s Propriétés du modèle %s client_slot proxy proxy Display proxy window Afficher la fenêtre de proxy Protocol Protocole Executable Exécutable client id Identifiant Hack Hack Display client Ray-Hack properties Affichier les propriétés Ray-Hack du client client_status invalid invalide script script client_stop <strong>%s</strong> seems to has not been saved for %i minute(s).<br />Do you really want to stop it ? <strong>%s</strong> semble ne pas avoir été sauvegardé depuis %i minute(s).<br />Voulez-vous vraiment l'arrêter ? daemon Ray Network Sessions Ray Sessions reseau port %i is not free, try another one le port %i n'est pas libre, essayez-en un autre daemon runs at %s le démon tourne sur %s error Some clients could not save Certains clients ne peuvent pas être sauvegardés Impossible to save template, unwriteable file ! Impossible de sauvegarder le modèle, fichier non inscriptible ! No template named %s Pas de modèle nommé %s Folder %s already exists Le dossier %s existe déjà impossible to read %s impossible de lire %s No announce from ray-daemon. RaySession can't works. Sorry. Pas d'annonce de ray-daemon. RaySession ne peut pas fonctionner. Désolé. Folder %s already exists Le dossier %s existe déjà Can't create session in a dir containing a session for better organization. Impossible de créer une session dans un répertoire contenant une session pour une meilleure organisation. client_id %s is not alphanumeric l'identifiant de client %s n'est pas alphanumérique client_id %s is already used l'identifiant de client %s est déjà utilisé error_message Impossible, copy running Impossible, une copie est en cours errors daemon crash! Plantage du démon ! ray-daemon crashed, sorry ! ray-daemon a planté, désolé ! guimsg Can't create session in a dir containing a session" for better organization. Il n'est pas possible de créer une session dans un dossier contenant une session dans un souci d'organisation. help A session manager based on the Non-Session-Manager API for sound applications. Un gestionnaire de sessions basé sur l' API de Non-Session-Manager pour piloter les applications audio. connect to this daemon url connecter à cet url de démon Use this folder as root for sessions Utiliser ce dossier comme racine pour les sessions Open this session at startup Ouvrir cette session au démarrage use a custom config dir Utiliser un dossier de configuration personnalisé display OSC messages afficher les messages OSC debug without client messages débugger sans les messages des clients connect to this daemon port se connecter au démon à ce port do not print client messages ne pas affcher les messages des clients prevent to attach to an already running daemon empêcher l'attachement à un démon existant hidden_dialogs Make reappear dialog windows Faire ré-apparaître les boites de dialogue Do you want to make reappear all dialogs you wanted to hide ? Êtes-vous sûr de vouloir faire ré-apparaître toutes les boîtes de dialogue que vous avez voulu cacher ? main view No Session Loaded Pas de session chargée main_win App Appli exec Exéc menu remove supprimer Favorites Favoris Add Ajouter message Client template %s created Modèle d'application %s créé network_session Network Session Session réseau new client template New application template name : Nom du nouveau modèle d'application : new_executable Custom Personnalisé Client Name Nom du client Session Name Nom de la session new_session none Aucun notes_dialog %s Notes - %s Notes %s - %s open_session This session is scripted Cette session est scriptée Listing sessions Recherche de sessions Cancel Annuler Session copy Copie de session Ok Ok Session saved as template Session sauvegardée comme modèle Remove session Supprimer la session <p>Are you really sure to want to remove the following session:</p><p><strong>%s</strong></p><p>This action is irreversible. <p>Êtes vous absolument certain de vouloir supprimer la session suivante:</p><p><strong>%s</strong></p><p>Cette action est irréversible. patchbay Silver Gold Or et argent Black Gold Or noir Modern Dark Noir moderne Audio Audio MIDI MIDI Input Entrée Output Sortie Physical Matériel Monitor Moniteur Terminal Terminal Control Voltage Voltage de contrôle Toggle Full Screen Plein écran Type filter Filtrer les ports Audio + Midi Audio + Midi Audio only Audio seulement MIDI only MIDI seulement Zoom Zoom auto-fit Auto ajusté Zoom + Zoom + Zoom - Zoom - Zoom 100% Zoom 100% Refresh the canvas Rafraîchir le canevas Canvas options Préférences du canevas JACK server lose Serveur JACK perdu JACK server seems to be totally busy... ;( Le serveur JACK semble être complètement dans les choux... ;( Wrap Emballer Unwrap Déballer Connect Connecter Disconnect Déconnecter No connections Aucune connexion Clipboard Presse-papier Cut connections Couper les connexions Copy connections Copier les connexions Paste connections Coller les connexions Disconnect All Tout déconnecter Disconnect &All &Tout déconnecter Info Informations Rename Renommer Split Séparer Join Joindre Split to Monos Séparer en canaux monos Set as Stereo with Mettre en stéréo avec Get &Info &Informations &Rename &Renommer Patchbay Baie de brassage Audio | DANGEROUS !!! Audio | DANGEREUX !!! CV | DANGEROUS !!! CV | DANGEREUX !!! Patchbay manual Manuel du canevas Find a box... Ctrl+F Trouver une boîte... Ctrl+F proxy None Aucun ray_hack None Aucun rename Folder %s already exists, Folder %s already exists, Impossible to rename session. Impossible de renommer la session. Folder %s already exists, Le dossier %s existe déjà, rename_session Rename Session Renommer la session <p>In order to rename current session,<br>please first stop all clients.<br>then, double click on session name.</p> <p>Pour renommer la session en cours,<br>Arrêtez d'abord tous les clients.<br>Ensuite, double-cliquez sur le nom de la session.</p> root_folder_dialogs Choose root folder for sessions Sélectionnez le dossier de racine pour les sessions unwritable dir Dossier non-inscriptible <p>You have no permissions for %s,<br>choose another directory !</p> <p>Vous n'avez pas les permissions pour %s,<br>Sélectionnez un autre répertoire !</p> server status invalid invalide off éteint new création open ouverture clear nettoyage switch bascule launch lancement ready prêt save sauvegarde close fermeture copy copie server_status snapshot cliché rewind rappel waiting attente save sauvegarde script script session template Overwrite Template ? Écraser le modèle ? Update the template Mettre à jour le modèle session_menu Duplicate session Dupliquer la session Save session as template Sauvegarder la session comme modèle Rename session Renommer la session Remove session Supprimer la session Remove session (too big) Supprimer la session (trop lourde) session_notes Too long notes Notes trop longues <p>Because notes are spread to the OSC server,<br>they can't be longer than 65000 characters.<br>Sorry !</p> <p>Du fait que les notes sont diffusées par le serveur OSC,<br>elles ne peuvent pas excéder 65000 caractères.<br>Désolé !</p> session_template Template <strong>%s</strong> already exists. Overwrite it ? Le modèle <strong>%s</strong> existe déjà. Voulez-vous l'écraser ? empty vide with JACK patch memory avec mémoire du patch de JACK with JACK config memory avec mémoire de la configuration de JACK with basic scripts avec les scripts de base snapshots Today Aujourd'hui Yesterday Hier %s at %s %s à %s at %s à %s before rewind to Avant de revenir à This session does not contains any snapshot. Cette session ne contient aucun cliché. There is no existing snapshot for this client. Il n'existe pas de cliché pour ce client. trashed_client Remove definitely Supprimer définitivement Are you sure to want to remove definitely this client and all its files ? Êtes-vous sûr(e) de vouloir supprimer définitivement ce client et tous ses fichiers ? url window <p align="left">To run a network session,<br>open a terminal on another computer of this network.<br>Launch ray-daemon on port 1234 (for example)<br>by typing the command :</p><p align="left"><code>ray-daemon -p 1234</code></p><p align="left">Then paste below the first url<br>that ray-daemon gives you at startup.</p><p></p> <p align="left">Pour lancer une session réseau,<br>ouvrez un terminal sur un autre ordinateur de ce réseau.<br>Lancez ray-daemon sur le port 1234 (par exemple)<br>en tapant la commande suivante :</p><p align="left"><code>ray-daemon -p 1234</code></p><p align="left">Ensuite collez ci-dessous la première url<br>que ray-daemon affiche au démarrage.</p><p></p> url_window <p>daemon at<br><strong>%s</strong><br>didn't announce !<br></p> <p>Le démon à l'adresse<br><strong>%s</strong><br>ne s'est pas annoncé !<br></p> <p>daemon at<br><strong>%s</strong><br>has a loaded session.<br>It can't be used for slave session</p> <p>Le démon à<br><strong>%s</strong><br>à déjà une session chargée.<br>Il ne peut pas être utilisé pour une session esclave</p> <p>daemon at<br><strong>%s</strong><br>uses an other session root folder !<.p> <p>Le démon à l'adresse<br><strong>%s</strong><br>n'utilise pas le bon dossier de sessions racine !<.p> <p>daemon at<br><strong>%s</strong><br>uses a forbidden session root folder !<.p> <p>Le démon à l'adresse<br><strong>%s</strong><br>utilise un dossier de sessions racine interdit !<.p> <p>daemon at<br><strong>%s</strong><br>uses an other Ray Session version.<.p> <p>Le démon à 'adresse<br><strong>%s</strong><br>utilise une autre version de RaySession.<.p> <p>daemon at<br><strong>%s</strong><br>has a loaded self._session.<br>It can't be used for slave session</p> <p>le démon à<br><strong>%s</strong><br>a une session chargée.<br>Il ne peut pas être utilisé pour une session exclave</p> <p>daemon at<br><strong>%s</strong><br>uses another %s version.<.p> <p>le démon à <br> <strong>%s </strong> <br> utilise une autre version de %s. <. p> utilities Choose a session Choisissez une session Convert the current session Convertir la session en cours Other script running Un autre script tourne An utility script is already running, please close its terminal and start again ! Un autre script utilitaire est en train de tourner, fermez son terminal et recommencez ! Convert Ardour session to Ray Convertir une session Ardour en session RaySession Choose an Ardour session to convert... Choisissez une session Ardour à convertir... Ardour sessions (*.ardour) Sessions Ardour (*.ardour) Hydrogen Ray-Hack->NSM Hydrogen Ray-Hack->NSM Jack Mixer Ray-Hack->NSM Jack Mixer Ray-Hack->NSM Session to NSM file format Session au format de fichier NSM Choose a session to convert to NSM Choisissez une session à convertir au format NSM wrong_version The running daemon has not the same version than the interface RaySession will quit now. What do you want to do with the current session ? Le démon qui tourne n'a pas la même version que l'interface RaySession va s'arrêter maintenant. Que voulez-vous faire de la session en cours ? RaySession-0.12.2/locale/update_pro.sh000077500000000000000000000014501417052567600176500ustar00rootroot00000000000000#!/bin/bash # This is a little script for refresh raysession.pro and update .ts files. # TRANSLATOR: You don't need to run it ! contents="" this_script=`realpath "$0"` locale_root=`dirname "$this_script"` code_root=`dirname "$locale_root"` cd "$code_root/resources/ui/" for file in *.ui;do contents+="FORMS += ../resources/ui/$file " done for dir in daemon gui gui/patchcanvas shared;do cd "$code_root/src/$dir" for file in *.py;do [[ "$file" =~ ^ui_ ]] && continue if cat "$file"|grep -q _translate;then contents+="SOURCES += ../src/$dir/${file} " fi done done contents+=" TRANSLATIONS += raysession_en.ts TRANSLATIONS += raysession_fr.ts " echo "$contents" > "$locale_root/raysession.pro" pylupdate5 "$locale_root/raysession.pro" RaySession-0.12.2/manual/000077500000000000000000000000001417052567600151655ustar00rootroot00000000000000RaySession-0.12.2/manual/.directory000066400000000000000000000001531417052567600171710ustar00rootroot00000000000000[Dolphin] GroupedSorting=true SortRole=modificationtime Timestamp=2020,11,13,14,44,17 Version=4 ViewMode=1 RaySession-0.12.2/manual/de/000077500000000000000000000000001417052567600155555ustar00rootroot00000000000000RaySession-0.12.2/manual/de/.directory000066400000000000000000000001531417052567600175610ustar00rootroot00000000000000[Dolphin] GroupedSorting=true SortRole=modificationtime Timestamp=2020,11,10,10,48,39 Version=4 ViewMode=1 RaySession-0.12.2/manual/de/images000077700000000000000000000000001417052567600207452../en/imagesustar00rootroot00000000000000RaySession-0.12.2/manual/de/manual.adoc000066400000000000000000001541001417052567600176630ustar00rootroot00000000000000= RaySession Manual :toc: left :toclevels: 1 :imagesdir: images :stylesheet: rs_manual.css [.text-right] image:flags/en.jpeg[EN, 30, 20, link=../en/manual.html] image:flags/fr.jpeg[FR, 30, 20, link=../fr/manual.html] image:flags/de.jpeg[DE, 40, 30, link=../de/manual.html] image::raysession.svg["icon", 100, 100] _für Version 0.12.0_ == Einführung RaySession ist ein Audio Session Manager für GNU / Linux. Er ermöglicht, verschiedene Audio Programme in einer Session zu starten und zu speichern, wodurch die Wiederherstellung einer bereits konfigurierten Session das Ausführen mehrerer Einzelschritte vermeidet. Audio Programme, die in einer Raysession gestartet werden, sollten möglichst mit dem NSM Protokol kompatibel sein. Für eine Vielzahl an Programmen wie Ardour, Qtractor, Carla, Guitarix, Mamba, Patroneo, ZynAddSubFx und andere ist das bereits gegeben. RaySession setzt ein bereits vorhandenes Audio Setup für die Audio Produktion voraus. Ist dies noch nicht gegeben, muss dies erfolgen, bevor RaySession sinnvoll genutzt werden kann. Nun zur Nutzung: == Einfaches Nutzungs Beispiel Zur Audioproduktion unter GNU / Linux ist die Nutzung des JACK Server sehr empfehlenswert. Bevor eine Session gestartet oder geöffnet wird, sollte der Jack Server bereits laufen. RaySession hat keine direkte Verbindung zu JACK, er wird aber von den in einer Session laufenden Anwendungen benötigt. Nehmen wir ein Beispiel, in dem ein Song komponiert wird. Hiefür nutzen wir die Software Ardour und Guitarix, diese beiden Programme sollten also installiert sein. Um eine neue Session zu starten, klicken Sie oben links auf New Session (_oder Strg+N_). Ein Dialog Fenster wird sich öffnen. image::example_new_session.png[New session] Oben rechts ist der Root Ordner der Session zu sehen. Hier wird die neue Session gespeichert (eine RaySession ist ein Ordner, der die Datei `raysession.xml`, enthält). Geben Sie den gewünschten Namen in das das Eingabefeld ein. Um die neue Session in einem Unterordner zu erstellen, geben Sie den Namen folgendermassen ein: `Unterordner/My Session`. Die Session Vorlage lässt Sie zwischen den folgenden Optionen wählen: * Eine leere Session Vorlage * Eine Vorlage mit gespeicherten JACK Verbindungen * Eine durch Skript erstellte Vorlage mit gespeicherten JACK Konfiguration * Eine Vorlage mit grundlegenden Session Skripten (für fortgeschrittene Nutzer mit Kenntnissen in Shell Skripting) * Alle selbst erstellten Vorlagen Belassen sie es zunächst bei der Standard Vorlage *With JACK patch memory*, und klicken Sie auf *Ok*, um die Session zu starten. image::example_session_launched.png[Session launched] Das Session Fenster wird aktiviert, die Fensterleiste enthält den Namen ihrer Session und eine Klient Anwendung mit dem Namen *JACK Connections* ist bereits aktiviert. Dieser Klient wird die Verbindungen der JACK Patchbay speichern und wiederherstellen. Um Ardour zu ihrer Session hinzuzufügen, klicken Sie auf *Application*/Anwendung (_oder Strg+A_), und das Anwendungs Dialogfenster wird sich öffnen (mehr hierzu unter <>). Finden Sie auf der rechten Seite Ardour (je nach Version unter Umständen Ardour5 oder Ardour6 genannt) und Doppelklicken Sie darauf. image::example_add_ardour.png[Add Ardour to the session, 640, 480] Ein Ardour Klient wird unter dem JACK Connections Klienten erscheinen und Ardour wird gestartet (normalerweise direkt mit einer leeren Ardour Session). Gehen Sie für Guitarix auf die gleiche Weise vor. image::example_session_ready.png[Session ready with Ardour and Guitarix] Fügen Sie in Ardour eine Spur hinzu (Menu: Spur → Füge Spur hinzu). In dem sich öffnenden Fenster, nennen sie die Spur *Guitar* und setzen Sie die Kanaleinstellungen auf _Stereo_. [caption="Figure 1: ",link=images/example_ardour_track.png] image::example_ardour_track.png[Add a track in Ardour for Guitarix, 640, 480] Now use JACK's <> which occupies the right side of the RaySession window. Connect the Guitarix input to a hardware input and the Guitarix outputs to the inputs of this new Ardour track. Make sure your Guitar track inputs are not connected to the hardware inputs. [caption="Figure 1: ",link=images/example_patchbay.png] image::example_patchbay.png[My session patchbay] Dies ist ein Beispiel, in dem der Gitarrensound durch Guitarix verarbeitet direkt in Ardour aufgenommen wird. Falls Sie über keine Gitarre verfügen, können Sie auch in ein Mikrofon singen, es handelt sich lediglich um ein Beispiel. Now save the current session by clicking the floppy disk button to the top right of the session part(_or Ctrl+S_). Es ist empfehlenswert, zur Sicherung der Session eine systemweite Tastenkombination zu erstellen. Es hängt von der jeweiligen Desktopumgebung ab, aber indem Sie zB. die Tastenkombiation _Ctrl+Meta+S_ dem Kommando `ray_control save` (Meta ist die Windows-Taste) zuweisen lässt es sich vermeiden, zum Sichern stets zum RaySession Fenster zurückkehren zu müssen. Schliessen Sie nun die Session, indem Sie auf das Kreuz im roten Kreis oben rechts klicken (_oder Strg+W_). Nachdem sich die Session geschlossen hat, klicken Sie auf *Open Session* (_oder Strg+O_), und Doppelklicken Sie auf die Session, die Sie gerade erstellt und geschlossen haben, und diese wird sich wieder öffnen. Sie werden alle Programme und JACK Connections so vorfinden, wie sie waren, als die Session geschlossen wurde. Hierdurch wird alles ohne zusätzliche Aktionen Ihrerseits wieder nutzbar sein. Ein weiterer Vorteil des modularen Ansatzes im gegebenen Fall ist, dass nachdem die Gitarre aufgenommen wurde, Guitarix gestoppt werden kann und nicht unnötig Prozessorkapazitäten verwendet, aber trotzdem bei Bedarf jederzeit wieder gestartet werden kann. == Überblick Session Werkzeuge === Obere Zeile image::session_top_line.png[Top line of the session frame] Von links nach rechts: * Das Menu Symbol ermöglicht: ** *Save as Template: Die aktuelle Session als Vorlage speichern* + Die laufende Session wird dann als Vorlage in den Auswahlmöglichkeiten des New Session Dialogs zu finden sein. Da in dieser Vorglage alle Dateien der Session gespeichert werden, sollten Sessions, die viele Audio Dateien enthalten, nicht als Vorlage gespeichert werden. Erstens wäre die Kopie sehr gross und zweitens besteht die Gefahr, Dateien unnötig mehrfach zu kopieren, was viel Speicherplatz in Anspruch nehmen würde. ** *Duplicate: Die aktuelle Session duplizieren* + Dies entspricht dem gut bekannten "Speichern als ...", im Unterschied dazu muss RaySession aber die meisten Anwendungen stoppen und neu starten, um zwischen Sessions zu wechseln. Sessions, die viele Audio Dateien enthalten, zu duplizieren, könnte sehr lange dauern, aber eine solche Aktion kann gestoppt werden. ** *Rename: Session umbenennen* + Hierzu müssen alle Klienten gestoppt werden. + Alternativ kann eine Session auch dupliziert und der Original Ordner der ursprünglichen Session gelöscht werden. + Eine Session kann auch umbenannt werden, indem der Ordner umbenannt wird, aber mit VORSICHT, die Session darf währenddessen nicht laufen. * Das Bleistift Symbol öffnet die session notes/Anmerkungen. + Hier können Sie hilfreiche Informationen zB. über den Hardware Aufbau, Songtexte, und anderes, wie Grossmutter's Eintopf, aufschreiben. Belassen Sie es aber bei den notwendigen Informationen in der nötigen Kürze, da die notes/Anmerkungen aus technischen Gründen auf 65,000 Buchstaben beschränkt sind. Andere Anwendungen sind für ausführlichere Beschreibungen besser geeignet. * Der Name der laufenden Session (hier: *my session*) * Das *Abort session* Symbol, welches die Session ohne Speicherung schliesst. * Das *Close session* Symbol, das die Session speichert und dann schliesst. + Die laufende Session muss nicht geschlossen werden, um eine weitere zu starten. Einige Klienten sind in der Lage, zwischen verschiedenen Sessions zu wechseln, was weniger Zeit in Anspruch nehmen kann, als sie alle zu schliessen und neu zu starten. === Untere Zeile image::session_bottom_line.png[Bottom line of the session frame] Von links nach rechts: * Das Ordner Symbol öffnet den Sesssion Ordner im Dateimanager * Das gelbe Stern Symbol mit den favorisierten Anwendungen, falls sie vorhanden sind. * Das *Application* (Anwendungen) Feld, mit welchem bereits vorhandene Anwendungsvorlagen oder selbst erstellte als Klient zur Session hinzugefügt werden können. Dies ist die empfohlene Methode, eine neue Klient-Anwendung hinzuzufügen. Siehe <> Anwendung hinzufügen Fenster. * Das *Executable* Feld, durch welches eine Anwendung durch das entsprechende Kommando hinzugefügt werden kann. Dies benötigen Sie, falls für die Anwendung keine Vorlage vorhanden ist. Siehe <> Kommando hinzufügen Fenster. * Das Reverse Symbol ermöglicht die Rückkehr zum vorherigen Status der Session. Die Anwendung `git` muss installiert sein, ansonsten ist das Symbol nicht sichtbar. + Siehe <> für weitere Details. * Der Server Status Indikator. + Der Server Status kann sehr kurzfristig erscheinen, aber er wird lange genug bleiben, damit Sie ihn sehen können. Der Server Status kann folgende Anzeigen haben: ** *off*: keine Session ist geladen ** *ready*: die Session läuft ** *launch*: die Anwendungen der Session werden geladen ** *copy*: eine Kopie findet statt, entweder als Duplikat oder als Vorlage ** *close*: die Session wird geschlossen ** *snapshot*: Ein Snapshot der Session wird erstellt, so dass zum aktuellem Status der Session mit dem Reverse Symbol zurückgekehrt werden kann. + Siehe <>. ** *wait*: der Server wartet, damit Sie nicht sicherbare Anwendungen selbst schliessen können. ** *script*: ein Skript ist aktiviert + Falls der Status des Indikators *copy*, *snapshot*, oder *wait* ist, wird durch ein Klicken auf ihn ein Fenster geöffnet, in dem der Fortschritt des Vorgangs gesehen werden kann. * Das *Save Session* Symbol. * Der Papierkorb, in welchem die entfernten Klienten zu finden sind. Diese können wiederhergestellt oder inklusive aller Dateien dauerhaft aus dem Session Ordner entfernt werden. == Überblick Klient image::client_carla.png[trame d'un client] Von links nach rechts: * Das Symbol der Klient Anwendung enthält ein Menu mit den folgenden Aktionen ** *Anwendung als Vorlage sichern* + Die Vorlage wird im <> Anwendung hinzufügen Fenster erscheinen. Die gesicherte Vorlage ermöglicht, eine Anwendung direkt mit einer bestimmten Konfiguration zu starten (Ardour mit bestimmten Tracks, Hydrogen mit bestimmten Drumkits ...). Seien Sie mit dieser Speicherung vorsichtig, falls der Klient viele Audio Dateien enthält, da alle Dateien des Klienten kopiert werden. ** *Umbenennen* + Den Namen des Klienten, rechts vom Symbol sichtbar, ändern. Dieser Name dient lediglich ihrer Organisation. ** *zum vorherigen Status zurückkehren* + Stellt den vorherigen Status des Klienten wieder her, siehe <>. Sie können aber nicht zu einem Status vor dem Umbenennen einer Session zurückkehren, in diesem Fall müssen sie den Status der gesamten Session wieder herstellen. ** *Eigenschaften* + Öffnet das Eigenschaften Fenster des Klienten. + Dieses Menü erscheint auch, indem Sie irgendwo in der Klientzeile den rechten Mausklick ausführen. * Der Name des Klienten (hier Carla), der durch rechter Mausklick → Rename (Umbenennen) leicht geändert werden kann * Je nach Art und Möglichkeiten des Klienten sehen sie noch: ** ein Auge (unter Umständen durchgestrichen), welches bedeutet, dass der Klient NSM kompatibel ist und durch Klicken auf das Symbol Auge gezeigt oder verborgen werden kann. ** Das *Hack* Feld deutet an, dass der Klient entweder nicht NSM kompatibel ist oder bloss nicht mit dem NSM Protokoll gestartet wurde. Durch Mausklick auf *Hack* kann das Klient Eigenschaften Fenster geöffnet werden, in dem die Art, wie der Klient gestartet wird, geändert werden kann. * Das Start Symbol, welches ausgegraut ist, falls der Klient bereits gestartet ist. * Das Stop Symbol, welches ausgegraut ist, falls der Klient bereits gestoppt ist. + Falls der Klient nicht stoppt, wird das Symbol rot und Sie können den Klienten durch kill beenden. Seien Sie aber geduldig und nutzen Sie dies nur, wenn der Klient völlig eingefroren zu sein scheint. Ihn zu killen könnte zu Problemen führen, auch wenn Sie kaum dafür im Gefängnis landen werden. * der Status des Klienten: ** *stopped*: Der Klient ist gestoppt ** *ready*: der Klient ist gestartet und alles ist in Ordnung ** *open*: Die Klient Anwendung wird geöffnet und läd das Projekt, bitte gedulden Sie sich ** *close*: Die Klient Anwendung wird geschlossen ** *launch*: Falls der Status sich von launch nicht ändert, heisst dies: *** Es handelt sich um einen Ray-Hack Klienten ohne Konfigurations Datei *** es ist als NSM Klient gestartet, aber nicht NSM kompatibel, und kann deshalb nicht speichern. Bei manchen Anwendungen, wie einem Patchbay (z.B. Catia) oder eine Anwendung, die nicht gespeichert werden muss (Qrest), kann es sinnvoll sein, diese so zu starten. ** *switch*: Der Klient wechselt das Projekt während die Session gewechselt wird. * Das Floppy Disk Symbol, mit welchem der Klient gespeichert werden kann. + Ist die Maus über diesem Symbol gehalten, ist das Folgende zu sehen ** 3 rote Punkte: Der Klient enthält nicht gespeicherte Änderungen ** ein grünes V: der Klient enthält keine nicht gespeicherten Änderungen ** ein orangenes Ausfrufezeichen: es handelt sich nicht um einen NSM kompatiblen Klienten und damit ist es nicht möglich, das Projekt zu speichern.Sie müssen dies selbst tun. * Das rote Kreuz ermöglicht es Ihnen, den Klienten in den Papierkorb zu löschen. [#add_application] == Anwendung hinzufügen Fenster Durch Klicken auf das *Application* Feld (oder _Strg+A_) öffnet sich das Fenster, um eine Anwendung hinzuzufügen. image::add_application.png[Add Application window] Die Liste mit den verfügbaren Anwendungen ist auf der rechten Seite. Falls die Software, die sie hinzufügen wollen, hier nicht zu finden ist, siehe <> Nicht verfügbare Anwendung hinzufügen. ''' Oben links ist das Filter Feld image::add_application_filter.png[Filter block of Add Application window] * tDas Filter Feld erlaubt Ihnen, durch einen Teil des Namens der Anwendung nur die Anwendungen anzuzeigen, die diesen Teil enthalten. * Die *Factory* Checkbox zeigt die in RaySession integrierten oder durch die Distribution verfügbaren Vorlagen. * *User* zeigt die durch den User durch *Save as application template* erstellten Vorlagen. * *NSM* zeigt die NSM kompatiblen oder als solche gestartete Klienten * *Ray-Hack* zeigt die ohne NSM Protokoll startbaren Klienten ''' Unten links ist das Informations Feld zu der gewählten Vorlage auf der rechten Seite. image::add_application_infos.png[Informations block of Add Application window] * Oben rechts in diesem Feld ist ein Stern Symbol, mit welchem die Vorlage zu den Favoriten hinzugefügt werden kann. * Falls es eine durch den User erstellte Vorlage ist, kann durch ein *User* Feld die Vorlage gelöscht werden. * Das Symbol unten rechts in diesem Feld ermöglicht Ihnen, das Fenster mit allen Eigenschaften dieser Vorlage zu öffnen. Siehe auch <>. Dies dient lediglich der Information. |=== |*Tip:* Dieses Fenster verhält sich wie _Alt+F2_ auf dem Desktop, und Vorlagen können schnell hinzugefügt werden. + Um zum Beispiel aus dem Hauptfenster der RaySession Carla hinzuzufügen, benutzen sie die Keyboard Kombination _Ctrl+A_, tippen Sie im Suchfeld dann `carla`, und wählen Sie die entsprechende Vorlage durch die Pfeil-oben/unten Taste aus, und bestätigen das Hinzufügen durch die Enter Taste. |=== [#add_executable] == Kommando hinzufügen Fenster Das Fenster, mit dem ein ausführbares Kommando hinzugefügt werden kann, öffnet sich durch Klicken auf das *Executable* Feld (_oder Ctrl+E_). image::add_executable.png[Add Executable window] Dieses Fenster muss benutzt werden, falls der Klient sich nicht in der Liste vom <> findet. Dieses Fenster ist sehr übersichtlich: ein Fenster, in dem das ausführbare Kommando eingegeben wird, eine Checkbox für das *NSM Protocol* und das Pfeil-nach-unten-Symbol für erweiterte Optionen. Lassen sie die Checkbox für das NSM Protokoll aktiviert, wenn: * das zu startende Programm NSM kompatibel ist (wenn es trotzdem nicht in der Liste zu finden ist, lassen Sie es uns wissen!) * Das Programm ein Werkzeug ist, welches Projekte nicht sichern muss (QRest, Catia…). Der Status eines solchen Programmes wird immer auf *launch* bleiben und nie zu *ready* wechseln, was unbedeutend ist, da kein Projekt gesichert werden muss. Falls in der Checkbox das *NSM protocol* aktiviert ist, kann nicht der volle Pfad wie `/usr/bin/my_program` genutzt werden, es muss `my_program` genutzt werden. Ebenso können weder mit noch ohne aktiviertem NSM Protokoll Argumente von Kommandos genutzt werden. Ist in der Checkbox das *NSM Protocol* deaktiviert, gleicht dies dem Starten eines Programms durch das Ray-Hack Pseudo-Protokoll. Wenn Sie auf das *advanced options* (erweiterte Optionen) Feld klicken, wird sich ein Block mit den erweiterten Optionen öffnen image::add_executable_plus.png[Advanced Add Executable window] * Die *Start the client* Checkbox. Ist sie nicht aktiviert, wird der Klient lediglich hinzugefügt und nicht automatisch direkt gestartet. * Die Multiple Choice Box *Prefix Mode*, welche das Präfix der Klienten Dateien bestimmt ** *Session Name*, die Dateinamen beginnen mit dem Namen der Session, dies ist die default Voreinstellung ** *Klient Name*, die Dateinamen beginnen mit dem Namen des Klienten, wie es auch beim Neue Session Manager der Fall ist. ** *Custom*, die Dateinamen beginnen mit der Eingabe, die Sie im darunter liegenden Feld *Prefix* angeben. * Das *Prefix* Feld ist nur aktiv, wenn der *Prefix Mode* auf Custom gestellt wurde. * Das *Klient ID* Feld (der Klient Identifikator). Nutzen Sie lediglich alphanumerische Zeichen oder '_'. + Dies ist nützlich, wenn Sie in der Session bestehende Projekte bestimmen und starten wollen. Auch, wenn Sie Session Projekte ausserhalb der bestehenden Session laden wollen. Es gibt keine einfachere Weise, dies zu tun. Die Details hängen stark von der jeweilig genutzten Anwendung ab. Falls Sie eine in der Session bereits verwendete ID eingeben, wird RaySession darauf entsprechend lautstark hinweisen. * the *Long JACK naming* checkbox. If this box is checked, clients will be supposed to use `ProgramName.ClientId` as JACK client name, else it will be `ProgramName`, possibly followed by `_N` (where N is a number). This is very useful if you use many instances of the same program, and you want to identify them easily in the patchbay. [#client_properties] [#patchbay] == Patchbay the JACK patchbay is not displayed by default. You can display it by clicking on *Control* and then *Show JACK Patchbay* (__or Ctrl+J__). The patchbay contains all the JACK AUDIO and MIDI ports that you can interconnect. Obviously, if JACK is not started, this patchbay will be empty. It is advisable to have the A2J bridge running if you want to work properly with MIDI. You can configure this via *Cadence*, *Studio Control*, or via the command line utility `a2j_control`. RaySession does not include tools to configure the JACK server, *QJackCtl*, *Studio Control*, *Cadence*, or the command line utility `jack_control` do this job very well. Note that this patchbay also works with PipeWire. === Overview image::patchbay_base.png[Patchbay overview] This is what your patchbay can look like. Here there are 7 boxes: * a *system* box with your ports corresponding to the hardware inputs (microphone, guitar...) * a *system* box with your ports corresponding to the hardware outputs (headphones, speakers...) * an *a2j* box with your ports corresponding to the MIDI hardware inputs * an *a2j* box with your ports corresponding to the MIDI hardware outputs * a *PulseAudio JACK Source* box * a *PulseAudio JACK Sink* box, sound from firefox and all non JACK applications comes from theses ports * a *Guitarix* box Here A2J and pulse2jack bridges are launched. You notice that 4 of these boxes are surrounded by a decoration (2 *system* and 2 *a2j*), these are the boxes that contain the hardware ports (your audio interface, your USB piano, any controller...). ''' Some audio ports are grouped into subgroups, which we will call portgroups. These portgroups are mostly stereo pairs automatically detected by the port names. This is the case here for : * system:capture 1/2 * system:playback 1/2 * PulseAudio JACK Source:front L/R * PulseAudio JACK Sink:front L/R * Guitarix:out 0/1 These portgroups facilitate the connections and allow a better general readability. ''' The blue curved lines correspond to the audio connections. You can observe that : * hardware input audio ports are connected to *PulseAudio JACK Source*. * the *PulseAudio JACK Sink* ports are connected to the hardware outputs * only the first port of *system* is connected to the input (__in 0__) of the *Guitarix* software * the audio ports of *Guitarix* are connected to the hardware outputs === Make and break a connection You can establish a connection between 2 ports as long as they meet the following conditions: * he ports are of the same type (you can't connect an audio port to a MIDI port) * one is an input port, the other is an output port ==== Intuitive Method To connect or disconnect two ports, click on a port without releasing the mouse button, drag the cursor to the desired port and release the mouse button. ==== Alternative method Right click on a port, it will display a drop down menu, choose *Connect* then the desired port. Click elsewhere to make this menu disappear. The advantage of this method is that it allows you to quickly connect a port to several others, the menu remaining displayed during the connections. video::video/patchbay_simple_connect.mp4[width=640] === Options Right click anywhere on the patchbay to display the menu. This menu is also present in the RaySession menu (*Patchbay* menu). It will allow you to : * switch the patchbay to full screen * Find a box with its name * Filter ports: show only AUDIO or MIDI ports or both * adjust the zoom level * refresh the canvas: ask JACK again for the list of existing ports and their connections * Canvas Preferences: display a window of options + All changes in this window take effect immediately. Hover over the boxes to see the tooltips. === Shortcuts you should know * A double click anywhere switches the patchbay to full screen. * __Ctrl+Mouse Wheel__ allows you to zoom in/out. * __Alt+Mouse wheel__ allows to move the view horizontally. * The wheel button is used to move the view * __Ctrl+middle mouse button__ cuts all connections passing under the cursor * __Ctrl+F__ allows to search a box with its name ==== Burst Connections It is possible to connect a port or a portgroup to different ports quite quickly. You just have to end your connections with a right click. A video will be much more explicit. video::video/patchbay_rafal_connections.mp4[width=640] Here we want to connect the multiple outputs of Hydrogen to the Jack-Mixer tracks. In the video the blue circles appear with a right click. ==== Passing connections from one port to another Sometimes it is less tedious to switch connections from one port to another than to undo and redo everything. To do this, start from the port that contains the connections and act as if you wanted to make a connection, but go to the port to which you want to switch the connections. * This only works if the destination port does not contain any connections * It works from port to port or from portgroup to portgroup but not from port to portgroup video::video/patchbay_fast_cut_paste.mp4[width=640] In this video we have a rather complex case where the source is plugged into *3 Band Splitter*. The bass and treble (_Output 1_ and _Output 5_) are sent directly to *EQ6Q Mono* while the midrange (_Output 3_) goes through the distortion *GxTubeScreamer* first. We want to insert the *Dragonfly Room Reverb* before the *EQ6Q Mono* equalization. ''' Note that with the right-click connection and the switching of connections from one port to another, it is very quick to integrate a new plugin in a chain, as here where we plug *Plujain Ramp Live* between *Dragonfly Room Reverb* and *EQ6Q Mono*. video::video/fast_new_plugin.mp4[width=640] === A2J ports image::patchbay_a2j.png[ports a2j] The MIDI ports provided by the A2J (Alsa To Jack) bridge have a hole at the end to identify them. Their real name is a long name, but that's about the only thing that differs from the other MIDI ports. === Control Voltage ports (CV ports) image::patchbay_CV.png[ports CV] Control voltage ports, commonly called CV ports, work like regular audio ports, however, they can control one or more parameters with much more precision than MIDI ports. As their stream is not meant to be listened to, it is not possible to simply connect a CV output port to a regular audio input, as this could damage your headphones, your speakers, and maybe even your ears. + If you still want to do it, right click on one of the ports, then *Connect*, then the *DANGEROUS* menu. + You can't say you weren't warned, and it's almost impossible to do this by mistake. On the other hand, connecting a classic audio output port to a CV input port is perfectly possible, no problem. == Klient Eigenschaften/Properties Fenster Das Eigenschaften Fenster lässt sich öffnen, indem sie im Menu des Klienten (öffnet sich durch rechten Mausklick) auf Eigenschaften/Properties klicken Das Eigenschaften Fenster hat 2 Tabs, "General" (Allgemein) und einen Tab für das genutzte Protokoll. Dieser hängt von dem vom Klienten genutzten Protokoll ab und kann NSM, Ray-Hack oder Ray-Net heissen. === *General* Tab image::properties_general.png[Client properties] Der obere Block des General Tab zeigt ID, Protokoll, Label, Beschreibung/description und das Iconsymbol des Klienten. + Falls Sie diese Eingaben nicht bearbeiten, werden die Werte aus der entsprechenden .desktop Datei der verwendeten Anwendung genutzt, falls vorhanden. + Falls Sie wissen möchten, welche .desktop Datei hierfür verwendet wird, nutzen sie den Befehl `ray_control client CLIENT_ID get_properties` in einem Terminal-Emulator (ersetzen Sie CLIENT_ID mit der ID des Klienten). Darunter liegt der Block Snapshots, siehe <>. Unter diesem Block ist die Checkbox *Prevent stop without recent or possible save* (Stop ohne vorherige oder kürzliche Sicherung), die das Fenster beim stoppen eines Klienten betrifft + Ist die Checkbox deaktiviert, wird der Klient ohne ein Fenster mit entsprechender Warnung über Sicherungen gestoppt werden. * Der Klient kann nicht durch RaySession gespeichert werden * Der Klient enthält ungespeicherte Änderungen * Der Klient wurde länger als eine Minute nicht gespeichert Ob es sinnvoll ist, die Checkbox aktiviert oder deaktiviert zu haben, hängt davon ab, ob eine Speicherung wichtig ist; dies müssen Sie entscheiden. Falls Sie unschlüssig sind, können Sie im Warnfenster beim Schliessen *Don't prevent to stop this client again* (nicht nochmals die Schliessung des Klienten verhindern) aktivieren, und *Prevent stop without recent or possible save* wird automatisch deaktiviert. === *NSM* Tab image::properties_nsm.png[NSM Client properties] Der hier genutzte *Name* für den Klienten wird durch ihn selbst bestimmt. + *capabilities* (Kapazitäten) sind jene, die der Klient übermittelt, während er startet. Entsprechend ist dieses Feld bei nicht gestartetem Klienten leer. Wird das Feld executable (ausführbarer Befehl) bearbeitet, kann hierdurch geändert werden, wie der Klient gestartet wird. Die geänderte Startweise sollte in der Lage sein, das gegebene Projekt des Klienten auszuführen. Sinvoll ist die Bearbeitung des executable Felds zB falls Sie 2 verschiedene Version von Ardour installiert haben, eine wird durch `ardour`, die andere durch `Ardour6` gestartet, und Sie wollen die genutzte Version ändern. Ansonsten wird dringend davon abgeraten, die genutzten Argumente zu ändern, und um Dateien als Argument zu laden ist es völlig unbrauchbar. === *Ray-Hack* Tab Falls der Klient vom Typ Ray-Hack ist, stehen Ihnen hier viele Felder zur Verfügung. Das sind aber nicht unbedingt gute Nachrichten. Die Grundidee ist es zu ermöglichen, eine Anwendung, die (noch) nicht mit dem NSM Protokoll kompatibel ist, in der Session laden zu können. Das NSM Protokoll ist, falls sauber im Klienten implementiert, wesentlich komfortabler und verlässlicher als dieser Hack. Dies im Hinterkopf lässt sich dennoch sagen, dass wir zwar in allen Audio Programmen das NSM Protokoll erwarten können, es aber auch nützliche Programme gibt, bei denen dies nicht der Fall ist. Das Ray-Hack Pseudo-Protokoll nutzt die Attribute von Proxies (nsm-proxy oder ray-proxy), aber der Klient wird direkt in der Session gestartet. image::properties_ray_hack.png[Ray-Hack Client properties] ==== Launch block image::ray_hack_launch.png[] * *Folder* ist der Ordner Name für diesen Klienten im Session Ordner. * *Executable* ist das Kommando, mit dem die Anwendung gestartet wird. * *Config file* ist die Projekt Datei, die wir mit dieser Anwendung öffnen wollen. Es ist sehr zu empfehlen, eine Datei zu benennen, die sich im Klienten Ordner befindet. + Die Variable `$RAY_SESSION_NAME` wird automatisch durch den Namen der Session ersetzt. + Falls dieses Feld leer ist, wird der Status des Klienten immer auf *launch* bleiben und nicht zu *ready* wechseln. In manchen Fällen mag es besser sein, einen beliebigen Wert einzugeben anstatt ihn leer zu lassen. * Das *Browse* Feld öffnet ein Dialogfenster, um die Projekt Datei zu finden und im *Configuration file* Feld einzufügen. * Das *Arguments* Feld enthält etwaige Argumente für das Kommando. + Die Argumente werden wie in der Kommandozeile getrennt, vergessen Sie also falls nötig nicht " und '. + Um zum Beispiel das Kommando `my_command my_argument_1 "my argument 2"` zu reproduzieren, geben Sie `my_command` im *Executable* Feld und `my_command my_argument_1 "my argument 2 "` im *Arguments* Feld ein. ==== Signals block image::ray_hack_signals.png[] * *Save Signal* kann nur sehr selten genutzt werde. Für Anwendungen, die mit dem alten LASH Protokoll kompatibel sind, kann es SIGUSR1 sein. Ansonsten lassen Sie es auf _None_, wenn keine Speichermethode vorhanden ist, können wir sie nicht aus dem Ärmel zaubern. * *Stop Signal* wird normalerweise SIGTERM sein. Ändern Sie dies nur, wenn die Anwendung sich nicht korrekt schliesst. * Falls die *Wait for a window before considered it ready* (auf Fenster warten) Checkbox aktiviert ist, wechselt der Status des Klienten erst zu *ready* sobald das Anwendungsfenster sich geöffnet hat. + Falls `wmctrl` nicht installiert ist oder der WindowManager ihn aus Kompatibilitätsgründen nicht nutzen kann, wird der Status sonst zu schnell, eine halbe Sekunde, nach dem Starten auf *ready* wechseln. Mit `ray_control` können andere Signale als die der Multiple Choice Box zugewiesen werden. `ray_control client CLIENT_ID set_properties save_sig:22` wird zum Beispiel das SIGTTOU Signal für das Sichern des Klienten mit CLIENT_ID zuweisen. + Das Kommando `kill -l` zeigt Ihnen im Terminal-Emulator die möglichen Signale und ensprechenden Nummern. ==== Non-saveable management block image::ray_hack_non_saveable.png[] Dieser Block ist nur aktiv, falls *Save Signal* auf _None_ gestellt ist. * Falls *Tell user to close program himself at session close* (Nutzer informieren, dass er die Anwendung selbst schliessen muss) gewählt ist, gilt der Klient als nicht speicherbar und ein orangenes Ausrufezeichen ist vor dem Save Symbol sichtbar. Wird die Session beendet, wird RaySession warten, bis Sie die Anwendung selbst geschlossen haben, da es unklar ist, ob Sie ungespeicherte Änderungen haben. * Falls *Try to close window gracefully* (Fenster elegant schliessen) gewählt ist, wird RaySession beim Beenden der Session versuchen, die Anwendung so zu schliessen, als würden Sie es tun. Dies ist sehr nützlich, falls die Anwendung auch im Fall von keinen nicht gespeicherten Änderungen einen Bestätigungsdialog erfordert (was oft der Fall ist). Falls `wmctrl` nicht installiert oder mit dem WindowManager nicht kompatibel ist, müssen Sie die Anwendung in jedem Fall selbst schliessen. ==== Test area image::ray_hack_test_zone.png[] Das Areal gibt Ihnen die Möglichkeit Start, Stop und Einstellungen speichern zu testen, ohne vorher *Save the changes* (Änderungen Speichern) auszuführen. == Network Sessions Durch eine Network Session kann auf einem weiteren Computer zeitgleich eine weitere Session gestartet werden. Durch eine Network Session kann auf einem weiteren Computer zeitgleich eine weitere Session gestartet werden. Dies ist besonders nützlich, wenn Sie net-jack nutzen um das DSP zu entlasten, z.B. um ressourcenintensive Effekte auf einer anderen Maschine zu starten. Network Sesssions arbeiten nach dem Master-Slave Prinzip. Eine Session ist der Master und kann mehrere Slave sessions haben, die wiederum Master von anderen Slave Sessions sein können, aber dies wäre eher ungewöhnlich. Organisieren Sie dies besser einfach: Ein Master und ein oder mehrere Slaves von diesem. Um eine Network Session (also einen Slave) zu starten, nutzen Sie die *Network Session* Anwendungs Vorlage aus dem Anwendungs Fenster und folgen Sie den Anweisungen. image::network_session_template.png[Add a network session] Starten sie auf dem Remote Computer durch den Befehl `ray-daemon -p 1234` (`1234` ist lediglich ein Beispiel, Sie könne dies frei wählen) einen Dämon. Dieser wird etwas entsprechendes im Terminal anzeigen: ``` [ray-daemon]URL : osc.udp://192.168.1.00:1234/` [ray-daemon] osc.udp://nom-de-machine:1234/` [ray-daemon]ROOT: /home/utilisateur/Ray Sessions reseau ``` image::network_session_invitation.png[Configure a network session] Kopieren Sie eine der beiden URLs in das network session invitation window. Die erste Variante (startend mit osc.udp://192.168.) muss mit Sicherheit funktionieren, die zweite wird nur funktioneren, wenn `/etc/hosts` vom dem Master Computer einen Eintrag für den Slave Computer enthält. Den Namen des Slave Computers in `/etc/hosts` einzutragen und die zweite Variante der URL zu nutzen ist aber vorzuziehen, da sich die Addresse 192.168 ändern kann falls sich der Remote Computer durch den Wechsel von wired zu wifi oder durch eine Neuinstallation der Distribution ändern kann. Auf dem Master Computer haben Sie nun 2 RaySession Fenster, eines kontrolliert die Master Session, das andere die Slave Session. Sie erkennen die Slave Session daran, dass das Fenster weder die Toolbar mit *New Session*, *Open Session*, *Control*, noch *Abort session* oder *Close session* Felder hat. image::network_session_child.png[] Wie viele andere NSM Anwendungen kann das Slave Fenster verborgen werden. image::network_session_client.png[] Wenn Sie auf dem Slave Computer das Kommando `raysession -p 1234` nutzen, haben Sie das Slave Fenster doppelt, eines auf jedem Computer. *Tip:* Nutzen Sie auf dem Slave Computer `ray-daemon -p 1234` im Startup. [#add_program_not_provided] == Nicht verfügbare Anwendung hinzufügen Falls die Anwendung, die sie hinzufügen möchten, das Speichern von Projekten nicht leisten muss, klicken Sie auf *Executable*, fügen Sie den ausführbaren Namen der Anwendung ein und klicken auf *Ok*. Ansonsten folgen Sie dem Beispiel: Wir werden als Beispiel Audacity zu der bestehenden Session hinzufügen. Diese Anwendung ist sehr bekannt und gewöhnlicherweise in Audio Distributionen vorinstalliert. Klicken Sie auf *Executable* (_oder nutzen Sie Ctrl+E_). In dem sich öffnenden Fenster <> (auführbare Anwendung hinzufügen), entfernen Sie die Auswahl für das *NSM Protocol*, fügen Sie `audacity` in das *Executable* Feld ein und klicken auf *Ok*. image::audacity_executable.png[Add Executable window well done] Ein neuer Klient wird erstellt, sein Eigenschaften Fenster öffnet sich im *Ray-Hack* Tab und Audacity wird gestartet. Wir werden nun sofort ein leeres Projekt von Audacity im Ordner des Klienten speichern. Dieser befindet sich im Ordner der Session und hat den Namen, den Sie ihm im *Folder:* Feld im *Ray-Hack* Tab oben gelegen gegeben haben. Wir werden dieses Projekt GENAU so nennen, wie die aktuelle RaySession. Nutzen Sie in Audacity hierfür: _Menu → File → Save project → Save project_ (Menu, Datei, Projekt Sichern, Sichern). image::audacity_save project.png[Save empty Audacity project] Klicken Sie auf *Validate* (Bestätigen) falls sich ein Warnfenster öffnet. + In der sich öffnenden Box um die Datei zu speichern, finden Sie den Session Ordner unten links (siehe <>). Klicken Sie darauf, um ihn zu öffnen. Darin sollten Sie den Ordner des Klienten mit dem Namen, der ihm im RayHack Tab gegeben wurde,finden. Nutzen Sie diesen. Fügen Sie in der Speicherbox den genauen Namen, den sie der Session im *Name:* Feld gegeben haben und bestätigen Sie. [caption="Figure 1: ",link=images/audacity_save_file.png] image::audacity_save_file.png[Where to save Audacity project, 640, 480] Schliessen Sie Audacity. + Klicken Sie oben rechts im *Ray-Hack* Tab vom Eigenschaftern Fenster des Klienten auf *Browse*. [caption="Figure 1: ",link=images/audacity_load_config_file.png] image::audacity_load_config_file.png[Load CONFIG_FILE window, 640, 480] wählen Sie das gerade erstellte Audacity Projekt mit dem Session Namen und mit .aup endend. Das *Configuration File* Feld sollte nun `$RAY_SESSION_NAME.aup` und das *Arguments* Feld `"$CONFIG_FILE"` enthalten. + Aktivieren Sie *Wait for a window before being considered ready*, *Ask the user to close the program himself* und *Try to close the window gracefully*. Klicken Sie dann unten rechts auf *Save Changes*. image::audacity_ray_hack_final.png[Ray-Hack tab of Audacity client well done] Starten Sie den Audacity Klienten und versichern Sie sich, dass das Audacity Fenster den Namen der Session hat.. + Klicken Sie auf das Symbol für den Audacity Klienten, wählen Sie im Drop-Down Menü *Save as an application template*, und geben Sie in der sich öffnenden Dialog Box `Audacity` ein. Nun müssen Sie lediglich Audacity wie in <> beschrieben wählen, um Audacity in der Session zu starten. Vor dem Speichersymbol des Klienten ist ein orangenes Ausfrufungszeichen, welches bedeutet, dass RaySession nicht in der Lage ist, dieses Projekt zu sichern und Sie dies selbständig machen müssen. Je nach der Anwendung, die sie zur Session so hinzufügen möchten, kann dies auch schwieriger sein. Einige Programme benötigen zB ein Kommando Argument, um eine Konfigurationsdatei zu nutzen. Nutzen sie hierfür im Terminal-Emulator `my_program --help` oder `man my_program` und fügen die entsprechenden Argumente im *Arguments* Feld ein. == NSM Session importieren Um eine Session, die mit Non Session Manager oder New Session Manager erstellt wurde, zu importieren, kopieren oder verschieben Sie den entsprechenden Session Ordner in den Root Session Folder von RaySession (default ist ~/Ray Sessions). Wenn Sie nun auf *Open session* klicken, sollte die Session in der Liste der verfügbaren Sessions aufgelistet sein. Doppel-Klicken Sie darauf, um sie auszuwählen. RaySession wird danach hinzugefügte oder entfernte Klienten nicht in `session.nsm` speichern, Sie müssen also hierfür auch weiterhin RaySession nutzen. If ever you want to use another session manager, you will find in the menu *File -> Utilities -> Convert the session to NSM file format*. Obviously this leads to some changes, such as prefix mode or the way the JACK clients will be named, but nothing that prevents the session from working. == Die Dämon Optionen Die Dämon Optionen sind Services, die durch Klicken auf das *Control* Feld oben rechts im Hauptfenster im Untermenü aktiviert oder deaktiviert werden können. Das Untermenü findet sich ebenso unter options in der Menübar. image::daemon_options.png[Daemon options] Die Details zu den jeweiligen Optionen sind die folgenden: [#session_folder_shortcuts] === Bookmarks für den Session Ordner erstellen In der Audioproduktion wird häufig eine Audio oder Midi Datei mit einem Program erstellt und dann von einem anderem Program genutzt. Die vorliegende Option bietet hiefür einen praktischen Nutzen: einen Shortcut für den aktuellen Session Folder (Ordner) im Dateimanager und in der Dialogbox, um Dateien zu laden oder zu speichern. Sie vermeiden also den unnötigen Zeitaufwand, sich durch ihren persönlichen Ordner im Dateimanager klicken zu müssen, um eine Datei zu finden, die in ihrem Session Ordner ist. + Dieser Shortcut wird entfernt, sobald die Session geschlossen wird. + Diese Option funktioniert technisch für GTK2, GTK3, QT4, QT5, KDE and FLTK. === Automatisch Snapshot beim Sichern erstellen Diese Option ist alles andere als unbedeutend. Sie ermöglicht Ihnen, bei jeder Speicherung einen Snapshot der Session zu erstellen. Im Falle eines technischen oder künstlerischen Fehlers steht Ihnen also der Snaphot zur Verfügung. Um diese Option zu nutzen, muss `git` installiert sein. Unter <> finden Sie weitere Details. === Desktop Status Falls diese Option aktiviert ist, wird RaySession auch den virtuellen Desktop, auf dem sich ein Klient Fenster beim Schliessen der RaySession befindet, speichern (oder zumindest wird dies versucht). Falls Sie die Session oder den Klienten wieder starten, wird das entsprechende Fenster also auf dem Desktop gestartet, auf dem es beim Schliessen zu finden war. Für diese Option muss die Anwendung `wmctrl` installiert sein. Unter Wayland wird sie vermutlich nicht funktionieren === Session Skripte Deaktivieren Sie diese Option, um beim Öffnen, Speichern oder Schliessen einer Session diese Skripte völlig zu ignorieren. Die Skripte werden für <> genutzt. Unter <> finden Sie weitere Details. === Optionalen GUI Status erinnern Diese Option betrifft lediglich NSM Klienten, die ihre Fenster sowohl verbergen als auch anzeigen können. Einige Klienten starten immer verborgen, andere starten so, wie sie geschlossen wurden. Wird diese Option aktiviert, werden alle Clienten immer so gestartet, wie sie während der letzten Sicherung beendet wurden. Wurden sie noch nie gestartet, werden sie nicht verborgen gezeigt [#snapshots] == Snapshots Für Snaphots muss das Programm `git` installiert sein. Falls es nicht installiert ist, wird das Reverse Symbol nicht zu sehen sein und es ist unmöglich, Snaphots zu machen oder den entsprechenden Status wieder herzustellen. Der Snapshot speichert Dateien und deren Inhalt zu einer gegebenen Zeit. Grosse Dateien und Dateien mit Dateiendungen für Audio und Video werden ignoriert, da dies zuviel Zeit in Anspruch nehmen würde und der Session Ordner zu gross werden würde. Dies ist kein grosses Problem, im Gegenteil, da ihre erst kürzlich erstellten Audiodateien erhalten bleiben, falls Sie zu einem vorherigen Snapshot zurückkehren. + Sollte trotz all dem der Snaphot Vorgang zu lange dauern, wird sich ein Fenster öffnen und Sie können den aktuellen Snapshot bedenkenlos abbrechen. Der automatische Snapshot wird dann für diese Session nicht mehr stattfinden. Der Nutzen von Snapshots liegt in der Tatsache, dass Sie zu dem Stand der Arbeit zurückehren könne, bevor Sie diese eine brilliante Idee gehabt haben, die sich dann als fruchtlos erwiesen hat, oder bevor sie die Samples neu geschnitten und dadurch alle Musikalität zerstört haben, oder bevor die Anwendung aus unbekannten Gründen anfing, abzustürzen. Seien Sie aber sorglos, zu einem Snapshot zurückzukehren heisst nicht, dass Sie den aktuellen Stand nicht ebenso wieder herstellen könnten. Um die Session zu einem Snapshot zurückzusetzen, klicken Sie auf das Reverse Symbol rechts vom *Executable* Feld. image::snapshots.png[] Wählen Sie in der Auswahl den Snapshot, zu dem Sie zurücksetzen möchten und klicken Sie auf *Ok*. Zunächst wird ein neuer Snapshot erstellt, dann schliesst sich die aktuelle Session, es wird zum Snapshot zurückgekehrt und die Session öffnet sich wieder. Ebenso ist es möglich, lediglich einen Klienten in einen vorherigen Status zurückzusetzen. Wählen Sie nach einem Rechtsklick auf den Klienten im Menü hierfür *Return to a previous state* (zu vorherigem Status zurückkehren). Falls gewünscht können Sie für jeden Klienten die Dateien, die bei einem Snapshot ignoriert werden sollen, festlegen, indem Sie dies im <> unter "Snapshot ignored extensions" (bei Snapshots ignorierte Dateiendungen) entsprechend bearbeiten. Ist die Option *Automatic snapshot after save* (automatischer Snapshot beim Speichern) gewählt, wird nach jeder Speicherung der Session ein Snapshot erstellt, ausser es sind keine Änderungen vorhanden. Um Snapshots zu anderen Zeitpunkten zu erstellen, klicken Sie auf das Reverse Symbol rechts vom *Executable* und bestätigen Sie *Take a snapshot now*. Ein Vorteil dieser Methode liegt darin, dass Sie dem Snapshot aufschlussreichere Namen als lediglich Datum und Uhrzeit geben können. [#session_scripts] == Session Skripte Session Skripte ermöglicht Ihnen, beim Öffnen, Speichern oder Schliessen der Session eigene Aktionen auszuführen. Im Besonderen für die Möglichkeit <> ist dies nützlich. + Um diese Skripte zu bearbeiten, sind zwar Kenntnisse in Shell Skripting nötig, nutzen kann sie aber jeder. Die Session Skripte befinden sich in dem Ordner `ray-scripts`, entweder im Session folder oder einem Parent Ordner von diesem. + Eine Session, die sich im Ordner : + `~/Ray Sessions/avec_script_de_foo/ma session` findet, kann der Skript Ordner folgende Pfade haben: ``` ~/Ray Sessions/avec_script_de_foo/ma session/ray-scripts ~/Ray Sessions/avec_script_de_foo/ray-scripts ~/Ray Sessions/ray-scripts ~/ray-scripts ``` Der Vorteil, die Skripte in diesen möglichen Pfaden zu haben liegt darin, dass mehrere Sessions diese nutzen können, ohne die Skripte in den jeweiligen Ordner kopieren zu müssen. Ebenso eröffnet dies die Möglichkeit, jemandem eine nicht geskriptete Session für mögliches Teamwork einfach zu kopieren. + Es wird lediglich der Skript Ordner genutzt werden, der im Pfad dem Session Ordner am nächsten ist. Ein leerer `ray-scripts` innerhalb des Ordners der Session selbst wird also alle sonstigen Skripte leicht deaktivieren. Um die Skripte zu bearbeiten, erstellen Sie zunächst eine Session aus der Vorlage mit den Basisskripten. Die Vorlage enthält Skripte, die keine besondere Aktion ausführen werden. Gehen Sie im Session Ordner in den Ordner `ray-scripts`. Hier finden Sie die Dateien `load.sh`, `save.sh` und `close.sh`. In jedem dieser Skripte bezieht sich `ray_control run_step` auf die gewöhnlich ausgeführte Aktion (je nach Skript: Laden, Sichern oder Schliessen der Session). Ist eines dieser Skripte für Sie ohne Nutzen, löschen sie das Skript einfach. Es ist unnötig, dies dann zu bearbeiten. Die Skripte müssen zwingend ausführbar sein, also die entsprechenden Rechte haben, um funktionieren zu können. Um einem Klienten eine bestimmte Aktion zuzusprechen, werden Sie vermutlich das Kommando `ray_control` nutzen. Geben sie in der Kommandozeile `ray_control --help` ein, um sich einen Überblick zu verschaffen. Mehr Informationen finden Sie unter <> (RaySession von der Kommandozeile kontrollieren). Die Vorlage JACK memory configuration (JACK Konfiguration erinnern) nutzt Session Skripte, aber es sind viele Aktionen entsprechend ihren Bedürfnissen und Vorstellungen denkbar, z.B.: * die Reihenfolge festlegen, in der die Klienten gestartet werden sollen, sobald die Session geöffnet wird (ein Beispiel findet sich im Quellcode) * ein Backup der Session auf einem externen Datenträger erstellen, sobald die Session geschlossen wird * den Fenstern von nicht sicherbaren Klienten den Shortcut _Ctrl+S_ senden, sobald die Session beendet wird (ein Beispiel findet sich im Quellcode) * Das rote Licht beim Betreten des Studios anschalten, und beim Verlassen ausschalten * Beim Beenden der Session die Kaffeemaschine einschalten (ein blödes Beispiel, müssen Sie doch den Filter immer noch selbst wechseln) * Viele, viele Fehler machen, die ihre Session abstürzen lassen. Seien Sie also entsprechend vorsichtig! [#jack_configuration_memory] == JACK Konfiguration erhalten Dank der Session Skripte ist es möglich, die für eine zu ladende Session erstellten Jack Konfigurationen zu erinnern, bzw. wiederherzustellen. Dieses Verhalten erinnert an einige Operationen von LADISH Studios, tut dies, zumindest unserer Meinung nach, aber viel besser. === Anwendungsmöglichkeiten Dies kann nützlich sein wenn: * Sie ein bestimmtes Audio Interface in der Session müssen. * Sie an mehreren Projekten arbeiten, die unterschliedliche Sample Rates (Signalverarbeitungsraten) nutzen (eine Session mit 44100 Hz, eine andere mit 44800 Hz) + Sie müssen also JACK nicht selber neu konfigurieren, stoppen und wieder starten. Ausserdem verhindern Sie hierdurch, dies zu vergessen und von einigen Anwendungen entsprechend gewarnt zu werden. * Wenn Sie verhindern wollen, eine sehr DSP intensive Session (zB in der Phase des Mixens) mit einem zu kleinen Buffer (z.B. 128) zu laden + Die meisten Audio Interfaces sind aber durchaus in der Lage, die Buffergrösse ohne Neustart (also hot) von Jack zu wechseln. === Anwendungsweise Die Session Skripte Option muss aktiviert sein (dies ist die Voreinstellung) Um Jack configuration memory (Jack Konfiguration erhalten) zu nutzen, erstellen Sie eine neue Session aus der *With JACK configuration memory* Vorlage. Es handelt sich de facto um eine geskriptete Session (see <>) die ein Skript startet, das zwar mit RaySession vorhanden, zu diesem aber völlig extern ist, insofern hat RaySession noch immer keine direkte Beziehung zu JACK. Lesen Sie die Informationen im Fenster und bestätigen Sie dann. JACK wird neu gestartet und dann startet ihre Session. === Funktionsweise Bei jedem Speichern der Session wird die aktuelle JACK Konfiguration in der Datei `jack_parameters` gespeichert. + Beim Öffnen der Session wird JACK neu gestartet, falls sich die gespeicherte Konfiguration von der aktuellen unterscheidet. + Wird die Session geschlossen, wird JACK abermals gestartet, diesmal mit der vorherigen Konfiguration. + PulseAudio → JACK Konfigurationen werden ebenso gespeichert und wiederhergestellt. Wird die Session auf einen anderen Computer kopiert und dort genutzt, wird die Konfiguration von JACK nicht erinnert und beim Speichern überschrieben werden. Lediglich die gespeicherte Samplerate wird genutzt werden. === besondere Fälle ''' *Die gespeicherte JACK Konfiguration einer Session nicht nutzen:* * deaktivieren Sie die *Session scripts* Option * Öffnen Sie die Session ''' *Die JACK Konfiguration einer Session ändern:* * Starten Sie JACK mit der gewünschten Konfiguration. * Deaktivieren Sie die Option Session Skripte. * Starten Sie die Session. * Aktivieren Sie die Option Session Skripte wieder. * Speichern Sie die Session. ''' *In einer bereits bestehenden Session JACK Konfiguration zu ermöglichen* * Kopieren Sie den Ordner `ray-scripts` aus einer Session mit erhaltener JACK konfiguration in den Session Ordner. * Aktivieren Sie die Option Session Skripte. * Starten Sie die Session. *oder* * Verschieben Sie den Session Ordner in einen Unterordner mit `ray-scripts` Ordner * Öffnen Sie die Session. [#under_the_hood] == Unter der Haube RaySession ist lediglich eine grafische Oberfläche, GUI, für ray-daemon. Wenn sie RaySession starten, öffnet sich die grafische Oberfläche und verbindet sich mit dem Dämon, und sobald sie die Anwendung schliessen, stoppt diese den Dämon. Die grafische Oberfläche und der Dämon kommunizieren über OSC (Open Sound Control) Meldungen. Dasselbe gilt für den Dämon und die NSM Klienten. Dementsprechend können sie mehrere grafische Oberflächen mit dem Daemon verbinden, auch über das Netz. Tippen Sie `raysession --help` für die entsprechenden Informationen. Es können mehrere Dämonen gestartet werden. Falls Sie also RaySession starten, wenn bereits eine weitere Instanz gestartet ist, wird ein neuer Dämon gestartet werden. Trotzdem ist diese Vorgehensweise eher ungewöhnlich, die Nutzung nur eines Dämons ist zu bevorzugen. Falls ein Dämon bereits gestartet, ihm aber keine GUI zugewiesen ist, wird sich RaySession per Voreinstellung beim Start mit diesem Dämon verbinden. [#ray_control] == RaySession von der Kommandozeile steuern Mit dem Kommando `ray_control` können Sie alles tun, was Sie auch mit in GUI tun können, und ein wenig mehr. Tippen Sie `ray_control --help-all` in einem Terminal-Emulator, um alle Möglichkeiten kennezulernen. Falls mehrere Dämonen gestartet sind (siehe <>), wird `ray_control` den zuerst gestarteten in Betracht ziehen, ausser sie bestimmen den OSC Port mit der Option `--port` oder durch die Umgebungsvariable `RAY_CONTROL_PORT`. Anzunehmen, `ray_control` wäre überflüssig, da das Kommando `oscsend` OSC Mitteilungen an den Dämon schicken kann, ist falsch. + Zum einen kann `oscsend` zwar Mitteilungen senden, aber keine Informationen auf einfache Weise empfangen (welches sind die aktiven Klienten? Was ist der ausführbare Befehl von einem bestimmenten Clienten? ...); und zum anderen, weil `ray_control` nach dem Ausführen der verlangten Aktion sauber beendet wird. z.B. `ray_control open_session "my session"` wird beendet, sobald die Session geladen ist. Seien Sie hier noch einmal daran erinnert, einen globalen Keyboard-Shortcut für den Befehl`ray_control save` zuzuweisen (_Ctrl+Meta+S_). Dies wird Ihnen viel Arbeit ersparen. == Frequently Asked Questions - *Ist die direkte Nutzung von Ardour (oder einer anderen NSM kompatiblen DAW) anstatt in RaySession trotzdem noch sinnvoll?* + Ausser für wirklich winzige Projekte, eher nein. Falls Sie Ardour nutzen, starten Sie es immer in einer RaySession. Erstens können Ihnen die automatisierten Snapshots unerwartet von grossem Nutzen sein, zweitens ist es möglich, dass Sie später noch eine weitere Anwendung nutzen wollen, auch wenn Sie dies bisher noch nicht geplant haben. - *Can I launch an Ardour session launched normally into a RaySession session ?* + You will find in the menu *File -> Utililies -> Convert an Ardour session to a Ray session*, it creates and launch a RaySession session from an ardour session. It is adviced to backup your ardour session first. Obviously, Ardour must not be open with this session during the execution of this script, but you already knew that. RaySession-0.12.2/manual/de/manual.html000066400000000000000000002332121417052567600177230ustar00rootroot00000000000000 RaySession Manual

EN FR DE

icon

für Version 0.10.0

Einführung

RaySession ist ein Audio Session Manager für GNU / Linux. Er ermöglicht, verschiedene Audio Programme in einer Session zu starten und zu speichern, wodurch die Wiederherstellung einer bereits konfigurierten Session das Ausführen mehrerer Einzelschritte vermeidet.

Audio Programme, die in einer Raysession gestartet werden, sollten möglichst mit dem NSM Protokol kompatibel sein. Für eine Vielzahl an Programmen wie Ardour, Qtractor, Carla, Guitarix, Mamba, Patroneo, ZynAddSubFx und andere ist das bereits gegeben.

RaySession setzt ein bereits vorhandenes Audio Setup für die Audio Produktion voraus. Ist dies noch nicht gegeben, muss dies erfolgen, bevor RaySession sinnvoll genutzt werden kann.

Nun zur Nutzung:

Einfaches Nutzungs Beispiel

Zur Audioproduktion unter GNU / Linux ist die Nutzung des JACK Server sehr empfehlenswert. Bevor eine Session gestartet oder geöffnet wird, sollte der Jack Server bereits laufen. RaySession hat keine direkte Verbindung zu JACK, er wird aber von den in einer Session laufenden Anwendungen benötigt.

Nehmen wir ein Beispiel, in dem ein Song komponiert wird. Hiefür nutzen wir die Software Ardour und Guitarix, diese beiden Programme sollten also installiert sein.

Um eine neue Session zu starten, klicken Sie oben links auf New Session (oder Strg+N). Ein Dialog Fenster wird sich öffnen.

New session

Oben rechts ist der Root Ordner der Session zu sehen. Hier wird die neue Session gespeichert (eine RaySession ist ein Ordner, der die Datei raysession.xml, enthält).

Geben Sie den gewünschten Namen in das das Eingabefeld ein. Um die neue Session in einem Unterordner zu erstellen, geben Sie den Namen folgendermassen ein: Unterordner/My Session.

Die Session Vorlage lässt Sie zwischen den folgenden Optionen wählen:

  • Eine leere Session Vorlage

  • Eine Vorlage mit gespeicherten JACK Verbindungen

  • Eine durch Skript erstellte Vorlage mit gespeicherten JACK Konfiguration

  • Eine Vorlage mit grundlegenden Session Skripten (für fortgeschrittene Nutzer mit Kenntnissen in Shell Skripting)

  • Alle selbst erstellten Vorlagen

Belassen sie es zunächst bei der Standard Vorlage With JACK patch memory, und klicken Sie auf Ok, um die Session zu starten.

Session launched

Das Session Fenster wird aktiviert, die Fensterleiste enthält den Namen ihrer Session und eine Klient Anwendung mit dem Namen JACK Connections ist bereits aktiviert. Dieser Klient wird die Verbindungen der JACK Patchbay speichern und wiederherstellen.

Um Ardour zu ihrer Session hinzuzufügen, klicken Sie auf Application/Anwendung (oder Strg+A), und das Anwendungs Dialogfenster wird sich öffnen (mehr hierzu unter Anwendung hinzufügen Fenster). Finden Sie auf der rechten Seite Ardour (je nach Version unter Umständen Ardour5 oder Ardour6 genannt) und Doppelklicken Sie darauf.

Add Ardour to the session

Ein Ardour Klient wird unter dem JACK Connections Klienten erscheinen und Ardour wird gestartet (normalerweise direkt mit einer leeren Ardour Session).

Gehen Sie für Guitarix auf die gleiche Weise vor.

Session ready with Ardour and Guitarix

Fügen Sie in Ardour eine Spur hinzu (Menu: Spur → Füge Spur hinzu). In dem sich öffnenden Fenster, nennen sie die Spur Guitar und setzen Sie die Kanaleinstellungen auf Stereo.

Add a track in Ardour for Guitarix

Open the JACK Patchbay, for this go to ControlShow JACK Patchbay (or Ctrl+J). The patchbay appears at the right of the window.

Connect the Guitarix input to a hardware input and the Guitarix outputs to the inputs of this new Ardour track. Make sure your Guitar track inputs are not connected to the hardware inputs.

My session patchbay

Dies ist ein Beispiel, in dem der Gitarrensound durch Guitarix verarbeitet direkt in Ardour aufgenommen wird. Falls Sie über keine Gitarre verfügen, können Sie auch in ein Mikrofon singen, es handelt sich lediglich um ein Beispiel.

Kehren Sie nun zum Fenster der RaySession zurück. Sichern Sie die aktuelle Session, indem sie oben rechts auf das FloppyDisk Symbol klicken (oder Ctrl+S). Es ist empfehlenswert, zur Sicherung der Session eine systemweite Tastenkombination zu erstellen. Es hängt von der jeweiligen Desktopumgebung ab, aber indem Sie zB. die Tastenkombiation Ctrl+Meta+S dem Kommando ray_control save (Meta ist die Windows-Taste) zuweisen lässt es sich vermeiden, zum Sichern stets zum RaySession Fenster zurückkehren zu müssen.

Schliessen Sie nun die Session, indem Sie auf das Kreuz im roten Kreis oben rechts klicken (oder Strg+W).

Nachdem sich die Session geschlossen hat, klicken Sie auf Open Session (oder Strg+O), und Doppelklicken Sie auf die Session, die Sie gerade erstellt und geschlossen haben, und diese wird sich wieder öffnen.

Sie werden alle Programme und JACK Connections so vorfinden, wie sie waren, als die Session geschlossen wurde. Hierdurch wird alles ohne zusätzliche Aktionen Ihrerseits wieder nutzbar sein. Ein weiterer Vorteil des modularen Ansatzes im gegebenen Fall ist, dass nachdem die Gitarre aufgenommen wurde, Guitarix gestoppt werden kann und nicht unnötig Prozessorkapazitäten verwendet, aber trotzdem bei Bedarf jederzeit wieder gestartet werden kann.

Überblick Session Werkzeuge

Obere Zeile

Top line of the session frame

Von links nach rechts:

  • Das Menu Symbol ermöglicht:

    • Save as Template: Die aktuelle Session als Vorlage speichern
      Die laufende Session wird dann als Vorlage in den Auswahlmöglichkeiten des New Session Dialogs zu finden sein. Da in dieser Vorglage alle Dateien der Session gespeichert werden, sollten Sessions, die viele Audio Dateien enthalten, nicht als Vorlage gespeichert werden. Erstens wäre die Kopie sehr gross und zweitens besteht die Gefahr, Dateien unnötig mehrfach zu kopieren, was viel Speicherplatz in Anspruch nehmen würde.

    • Duplicate: Die aktuelle Session duplizieren
      Dies entspricht dem gut bekannten "Speichern als …​", im Unterschied dazu muss RaySession aber die meisten Anwendungen stoppen und neu starten, um zwischen Sessions zu wechseln. Sessions, die viele Audio Dateien enthalten, zu duplizieren, könnte sehr lange dauern, aber eine solche Aktion kann gestoppt werden.

    • Rename: Session umbenennen
      Hierzu müssen alle Klienten gestoppt werden.
      Alternativ kann eine Session auch dupliziert und der Original Ordner der ursprünglichen Session gelöscht werden.
      Eine Session kann auch umbenannt werden, indem der Ordner umbenannt wird, aber mit VORSICHT, die Session darf währenddessen nicht laufen.

  • Das Bleistift Symbol öffnet die session notes/Anmerkungen.
    Hier können Sie hilfreiche Informationen zB. über den Hardware Aufbau, Songtexte, und anderes, wie Grossmutter’s Eintopf, aufschreiben. Belassen Sie es aber bei den notwendigen Informationen in der nötigen Kürze, da die notes/Anmerkungen aus technischen Gründen auf 65,000 Buchstaben beschränkt sind. Andere Anwendungen sind für ausführlichere Beschreibungen besser geeignet.

  • Der Name der laufenden Session (hier: my session)

  • Das Abort session Symbol, welches die Session ohne Speicherung schliesst.

  • Das Close session Symbol, das die Session speichert und dann schliesst.
    Die laufende Session muss nicht geschlossen werden, um eine weitere zu starten. Einige Klienten sind in der Lage, zwischen verschiedenen Sessions zu wechseln, was weniger Zeit in Anspruch nehmen kann, als sie alle zu schliessen und neu zu starten.

Untere Zeile

Bottom line of the session frame

Von links nach rechts:

  • Das Ordner Symbol öffnet den Sesssion Ordner im Dateimanager

  • Das gelbe Stern Symbol mit den favorisierten Anwendungen, falls sie vorhanden sind.

  • Das Application (Anwendungen) Feld, mit welchem bereits vorhandene Anwendungsvorlagen oder selbst erstellte als Klient zur Session hinzugefügt werden können. Dies ist die empfohlene Methode, eine neue Klient-Anwendung hinzuzufügen. Siehe Anwendung hinzufügen Fenster Anwendung hinzufügen Fenster.

  • Das Executable Feld, durch welches eine Anwendung durch das entsprechende Kommando hinzugefügt werden kann. Dies benötigen Sie, falls für die Anwendung keine Vorlage vorhanden ist. Siehe Kommando hinzufügen Fenster Kommando hinzufügen Fenster.

  • Das Reverse Symbol ermöglicht die Rückkehr zum vorherigen Status der Session. Die Anwendung git muss installiert sein, ansonsten ist das Symbol nicht sichtbar.
    Siehe Snapshots für weitere Details.

  • Der Server Status Indikator.
    Der Server Status kann sehr kurzfristig erscheinen, aber er wird lange genug bleiben, damit Sie ihn sehen können. Der Server Status kann folgende Anzeigen haben:

    • off: keine Session ist geladen

    • ready: die Session läuft

    • launch: die Anwendungen der Session werden geladen

    • copy: eine Kopie findet statt, entweder als Duplikat oder als Vorlage

    • close: die Session wird geschlossen

    • snapshot: Ein Snapshot der Session wird erstellt, so dass zum aktuellem Status der Session mit dem Reverse Symbol zurückgekehrt werden kann.
      Siehe Snapshots.

    • wait: der Server wartet, damit Sie nicht sicherbare Anwendungen selbst schliessen können.

    • script: ein Skript ist aktiviert

      Falls der Status des Indikators copy, snapshot, oder wait ist, wird durch ein Klicken auf ihn ein Fenster geöffnet, in dem der Fortschritt des Vorgangs gesehen werden kann.

  • Das Save Session Symbol.

  • Der Papierkorb, in welchem die entfernten Klienten zu finden sind. Diese können wiederhergestellt oder inklusive aller Dateien dauerhaft aus dem Session Ordner entfernt werden.

Überblick Klient

trame d’un client

Von links nach rechts:

  • Das Symbol der Klient Anwendung enthält ein Menu mit den folgenden Aktionen

    • Anwendung als Vorlage sichern
      Die Vorlage wird im Anwendung hinzufügen Fenster Anwendung hinzufügen Fenster erscheinen. Die gesicherte Vorlage ermöglicht, eine Anwendung direkt mit einer bestimmten Konfiguration zu starten (Ardour mit bestimmten Tracks, Hydrogen mit bestimmten Drumkits …​). Seien Sie mit dieser Speicherung vorsichtig, falls der Klient viele Audio Dateien enthält, da alle Dateien des Klienten kopiert werden.

    • Umbenennen
      Den Namen des Klienten, rechts vom Symbol sichtbar, ändern. Dieser Name dient lediglich ihrer Organisation.

    • zum vorherigen Status zurückkehren
      Stellt den vorherigen Status des Klienten wieder her, siehe Snapshots. Sie können aber nicht zu einem Status vor dem Umbenennen einer Session zurückkehren, in diesem Fall müssen sie den Status der gesamten Session wieder herstellen.

    • Eigenschaften
      Öffnet das Eigenschaften Fenster des Klienten.

    Dieses Menü erscheint auch, indem Sie irgendwo in der Klientzeile den rechten Mausklick ausführen.

  • Der Name des Klienten (hier Carla), der durch rechter Mausklick → Rename (Umbenennen) leicht geändert werden kann

  • Je nach Art und Möglichkeiten des Klienten sehen sie noch:

    • ein Auge (unter Umständen durchgestrichen), welches bedeutet, dass der Klient NSM kompatibel ist und durch Klicken auf das Symbol Auge gezeigt oder verborgen werden kann.

    • Das Hack Feld deutet an, dass der Klient entweder nicht NSM kompatibel ist oder bloss nicht mit dem NSM Protokoll gestartet wurde. Durch Mausklick auf Hack kann das Klient Eigenschaften Fenster geöffnet werden, in dem die Art, wie der Klient gestartet wird, geändert werden kann.

  • Das Start Symbol, welches ausgegraut ist, falls der Klient bereits gestartet ist.

  • Das Stop Symbol, welches ausgegraut ist, falls der Klient bereits gestoppt ist.
    Falls der Klient nicht stoppt, wird das Symbol rot und Sie können den Klienten durch kill beenden. Seien Sie aber geduldig und nutzen Sie dies nur, wenn der Klient völlig eingefroren zu sein scheint. Ihn zu killen könnte zu Problemen führen, auch wenn Sie kaum dafür im Gefängnis landen werden.

  • der Status des Klienten:

    • stopped: Der Klient ist gestoppt

    • ready: der Klient ist gestartet und alles ist in Ordnung

    • open: Die Klient Anwendung wird geöffnet und läd das Projekt, bitte gedulden Sie sich

    • close: Die Klient Anwendung wird geschlossen

    • launch: Falls der Status sich von launch nicht ändert, heisst dies:

      • Es handelt sich um einen Ray-Hack Klienten ohne Konfigurations Datei

      • es ist als NSM Klient gestartet, aber nicht NSM kompatibel, und kann deshalb nicht speichern. Bei manchen Anwendungen, wie einem Patchbay (z.B. Catia) oder eine Anwendung, die nicht gespeichert werden muss (Qrest), kann es sinnvoll sein, diese so zu starten.

    • switch: Der Klient wechselt das Projekt während die Session gewechselt wird.

  • Das Floppy Disk Symbol, mit welchem der Klient gespeichert werden kann.
    Ist die Maus über diesem Symbol gehalten, ist das Folgende zu sehen

    • 3 rote Punkte: Der Klient enthält nicht gespeicherte Änderungen

    • ein grünes V: der Klient enthält keine nicht gespeicherten Änderungen

    • ein orangenes Ausfrufezeichen: es handelt sich nicht um einen NSM kompatiblen Klienten und damit ist es nicht möglich, das Projekt zu speichern.Sie müssen dies selbst tun.

  • Das rote Kreuz ermöglicht es Ihnen, den Klienten in den Papierkorb zu löschen.

Anwendung hinzufügen Fenster

Durch Klicken auf das Application Feld (oder Strg+A) öffnet sich das Fenster, um eine Anwendung hinzuzufügen.

Add Application window

Die Liste mit den verfügbaren Anwendungen ist auf der rechten Seite. Falls die Software, die sie hinzufügen wollen, hier nicht zu finden ist, siehe Nicht verfügbare Anwendung hinzufügen Nicht verfügbare Anwendung hinzufügen.


Oben links ist das Filter Feld

Filter block of Add Application window
  • tDas Filter Feld erlaubt Ihnen, durch einen Teil des Namens der Anwendung nur die Anwendungen anzuzeigen, die diesen Teil enthalten.

  • Die Factory Checkbox zeigt die in RaySession integrierten oder durch die Distribution verfügbaren Vorlagen.

  • User zeigt die durch den User durch Save as application template erstellten Vorlagen.

  • NSM zeigt die NSM kompatiblen oder als solche gestartete Klienten

  • Ray-Hack zeigt die ohne NSM Protokoll startbaren Klienten


Unten links ist das Informations Feld zu der gewählten Vorlage auf der rechten Seite.

Informations block of Add Application window
  • Oben rechts in diesem Feld ist ein Stern Symbol, mit welchem die Vorlage zu den Favoriten hinzugefügt werden kann.

  • Falls es eine durch den User erstellte Vorlage ist, kann durch ein User Feld die Vorlage gelöscht werden.

  • Das Symbol unten rechts in diesem Feld ermöglicht Ihnen, das Fenster mit allen Eigenschaften dieser Vorlage zu öffnen. Siehe auch [client_properties]. Dies dient lediglich der Information.

Tip: Dieses Fenster verhält sich wie Alt+F2 auf dem Desktop, und Vorlagen können schnell hinzugefügt werden.
Um zum Beispiel aus dem Hauptfenster der RaySession Carla hinzuzufügen, benutzen sie die Keyboard Kombination Ctrl+A, tippen Sie im Suchfeld dann carla, und wählen Sie die entsprechende Vorlage durch die Pfeil-oben/unten Taste aus, und bestätigen das Hinzufügen durch die Enter Taste.

Kommando hinzufügen Fenster

Das Fenster, mit dem ein ausführbares Kommando hinzugefügt werden kann, öffnet sich durch Klicken auf das Executable Feld (oder Ctrl+E).

Add Executable window

Dieses Fenster muss benutzt werden, falls der Klient sich nicht in der Liste vom Anwendung hinzufügen Fenster findet. Dieses Fenster ist sehr übersichtlich: ein Fenster, in dem das ausführbare Kommando eingegeben wird, eine Checkbox für das NSM Protocol und das Pfeil-nach-unten-Symbol für erweiterte Optionen.

Lassen sie die Checkbox für das NSM Protokoll aktiviert, wenn:

  • das zu startende Programm NSM kompatibel ist (wenn es trotzdem nicht in der Liste zu finden ist, lassen Sie es uns wissen!)

  • Das Programm ein Werkzeug ist, welches Projekte nicht sichern muss (QRest, Catia…). Der Status eines solchen Programmes wird immer auf launch bleiben und nie zu ready wechseln, was unbedeutend ist, da kein Projekt gesichert werden muss.

Falls in der Checkbox das NSM protocol aktiviert ist, kann nicht der volle Pfad wie /usr/bin/my_program genutzt werden, es muss my_program genutzt werden. Ebenso können weder mit noch ohne aktiviertem NSM Protokoll Argumente von Kommandos genutzt werden.

Ist in der Checkbox das NSM Protocol deaktiviert, gleicht dies dem Starten eines Programms durch das Ray-Hack Pseudo-Protokoll.

Wenn Sie auf das advanced options (erweiterte Optionen) Feld klicken, wird sich ein Block mit den erweiterten Optionen öffnen

Advanced Add Executable window
  • Die Start the client Checkbox. Ist sie nicht aktiviert, wird der Klient lediglich hinzugefügt und nicht automatisch direkt gestartet.

  • Die Multiple Choice Box Prefix Mode, welche das Präfix der Klienten Dateien bestimmt

    • Session Name, die Dateinamen beginnen mit dem Namen der Session, dies ist die default Voreinstellung

    • Klient Name, die Dateinamen beginnen mit dem Namen des Klienten, wie es auch beim Neue Session Manager der Fall ist.

    • Custom, die Dateinamen beginnen mit der Eingabe, die Sie im darunter liegenden Feld Prefix angeben.

  • Das Prefix Feld ist nur aktiv, wenn der Prefix Mode auf Custom gestellt wurde.

  • Das Klient ID Feld (der Klient Identifikator). Nutzen Sie lediglich alphanumerische Zeichen oder '_'.
    Dies ist nützlich, wenn Sie in der Session bestehende Projekte bestimmen und starten wollen. Auch, wenn Sie Session Projekte ausserhalb der bestehenden Session laden wollen. Es gibt keine einfachere Weise, dies zu tun. Die Details hängen stark von der jeweilig genutzten Anwendung ab. Falls Sie eine in der Session bereits verwendete ID eingeben, wird RaySession darauf entsprechend lautstark hinweisen.

Patchbay

the JACK patchbay is not displayed by default. You can display it by clicking on Control and then Show JACK Patchbay (or Ctrl+J). The patchbay contains all the JACK AUDIO and MIDI ports that you can interconnect.

Obviously, if JACK is not started, this patchbay will be empty.

It is advisable to have the A2J bridge running if you want to work properly with MIDI. You can configure this via Cadence, Studio Control, or via the command line utility a2j_control.

RaySession does not include tools to configure the JACK server, QJackCtl, Studio Control, Cadence, or the command line utility jack_control do this job very well. Note that this patchbay also works with PipeWire.

Overview

Patchbay overview

This is what your patchbay can look like. Here there are 7 boxes:

  • a system box with your ports corresponding to the hardware inputs (microphone, guitar…​)

  • a system box with your ports corresponding to the hardware outputs (headphones, speakers…​)

  • an a2j box with your ports corresponding to the MIDI hardware inputs

  • an a2j box with your ports corresponding to the MIDI hardware outputs

  • a PulseAudio JACK Source box

  • a PulseAudio JACK Sink box, sound from firefox and all non JACK applications comes from theses ports

  • a Guitarix box

Here A2J and pulse2jack bridges are launched.

You notice that 4 of these boxes are surrounded by a decoration (2 system and 2 a2j), these are the boxes that contain the hardware ports (your audio interface, your USB piano, any controller…​).


Some audio ports are grouped into subgroups, which we will call portgroups. These portgroups are mostly stereo pairs automatically detected by the port names. This is the case here for :

  • system:capture 1/2

  • system:playback 1/2

  • PulseAudio JACK Source:front L/R

  • PulseAudio JACK Sink:front L/R

  • Guitarix:out 0/1

These portgroups facilitate the connections and allow a better general readability.


The blue curved lines correspond to the audio connections. You can observe that :

  • hardware input audio ports are connected to PulseAudio JACK Source.

  • the PulseAudio JACK Sink ports are connected to the hardware outputs

  • only the first port of system is connected to the input (in 0) of the Guitarix software

  • the audio ports of Guitarix are connected to the hardware outputs

Make and break a connection

You can establish a connection between 2 ports as long as they meet the following conditions:

  • he ports are of the same type (you can’t connect an audio port to a MIDI port)

  • one is an input port, the other is an output port

Intuitive Method

To connect or disconnect two ports, click on a port without releasing the mouse button, drag the cursor to the desired port and release the mouse button.

Alternative method

Right click on a port, it will display a drop down menu, choose Connect then the desired port. Click elsewhere to make this menu disappear. The advantage of this method is that it allows you to quickly connect a port to several others, the menu remaining displayed during the connections.

Options

Right click anywhere on the patchbay to display the menu. This menu is also present in the RaySession menu (Patchbay menu). It will allow you to :

  • switch the patchbay to full screen

  • Filter ports: show only AUDIO or MIDI ports or both

  • adjust the zoom level

  • refresh the canvas: ask JACK again for the list of existing ports and their connections

  • Canvas Preferences: display a window of options
    All changes in this window take effect immediately. Hover over the boxes to see the tooltips.

Shortcuts you should know

  • A double click anywhere switches the patchbay to full screen.

  • Ctrl+Mouse Wheel allows you to zoom in/out.

  • Alt+Mouse wheel allows to move the view horizontally.

  • The wheel button is used to move the view

  • Ctrl+middle mouse button cuts all connections passing under the cursor

Burst Connections

It is possible to connect a port or a portgroup to different ports quite quickly. You just have to end your connections with a right click. A video will be much more explicit.

Here we want to connect the multiple outputs of Hydrogen to the Jack-Mixer tracks. In the video the blue circles appear with a right click.

Passing connections from one port to another

Sometimes it is less tedious to switch connections from one port to another than to undo and redo everything. To do this, start from the port that contains the connections and act as if you wanted to make a connection, but go to the port to which you want to switch the connections.

  • This only works if the destination port does not contain any connections

  • It works from port to port or from portgroup to portgroup but not from port to portgroup

In this video we have a rather complex case where the source is plugged into 3 Band Splitter. The bass and treble (Output 1 and Output 5) are sent directly to EQ6Q Mono while the midrange (Output 3) goes through the distortion GxTubeScreamer first. We want to insert the Dragonfly Room Reverb before the EQ6Q Mono equalization.


Note that with the right-click connection and the switching of connections from one port to another, it is very quick to integrate a new plugin in a chain, as here where we plug Plujain Ramp Live between Dragonfly Room Reverb and EQ6Q Mono.

A2J ports

ports a2j

The MIDI ports provided by the A2J (Alsa To Jack) bridge have a hole at the end to identify them. Their real name is a long name, but that’s about the only thing that differs from the other MIDI ports.

Control Voltage ports (CV ports)

ports CV

Control voltage ports, commonly called CV ports, work like regular audio ports, however, they can control one or more parameters with much more precision than MIDI ports. As their stream is not meant to be listened to, it is not possible to simply connect a CV output port to a regular audio input, as this could damage your headphones, your speakers, and maybe even your ears.
If you still want to do it, right click on one of the ports, then Connect, then the DANGEROUS menu.
You can’t say you weren’t warned, and it’s almost impossible to do this by mistake.

On the other hand, connecting a classic audio output port to a CV input port is perfectly possible, no problem.

Klient Eigenschaften/Properties Fenster

Das Eigenschaften Fenster lässt sich öffnen, indem sie im Menu des Klienten (öffnet sich durch rechten Mausklick) auf Eigenschaften/Properties klicken

Das Eigenschaften Fenster hat 2 Tabs, "General" (Allgemein) und einen Tab für das genutzte Protokoll. Dieser hängt von dem vom Klienten genutzten Protokoll ab und kann NSM, Ray-Hack oder Ray-Net heissen.

General Tab

Client properties

Der obere Block des General Tab zeigt ID, Protokoll, Label, Beschreibung/description und das Iconsymbol des Klienten.
Falls Sie diese Eingaben nicht bearbeiten, werden die Werte aus der entsprechenden .desktop Datei der verwendeten Anwendung genutzt, falls vorhanden.
Falls Sie wissen möchten, welche .desktop Datei hierfür verwendet wird, nutzen sie den Befehl ray_control client CLIENT_ID get_properties in einem Terminal-Emulator (ersetzen Sie CLIENT_ID mit der ID des Klienten).

Darunter liegt der Block Snapshots, siehe Snapshots.

Unter diesem Block ist die Checkbox Prevent stop without recent or possible save (Stop ohne vorherige oder kürzliche Sicherung), die das Fenster beim stoppen eines Klienten betrifft
Ist die Checkbox deaktiviert, wird der Klient ohne ein Fenster mit entsprechender Warnung über Sicherungen gestoppt werden.

  • Der Klient kann nicht durch RaySession gespeichert werden

  • Der Klient enthält ungespeicherte Änderungen

  • Der Klient wurde länger als eine Minute nicht gespeichert

Ob es sinnvoll ist, die Checkbox aktiviert oder deaktiviert zu haben, hängt davon ab, ob eine Speicherung wichtig ist; dies müssen Sie entscheiden. Falls Sie unschlüssig sind, können Sie im Warnfenster beim Schliessen Don’t prevent to stop this client again (nicht nochmals die Schliessung des Klienten verhindern) aktivieren, und Prevent stop without recent or possible save wird automatisch deaktiviert.

NSM Tab

NSM Client properties

Der hier genutzte Name für den Klienten wird durch ihn selbst bestimmt.
capabilities (Kapazitäten) sind jene, die der Klient übermittelt, während er startet. Entsprechend ist dieses Feld bei nicht gestartetem Klienten leer.

Wird das Feld executable (ausführbarer Befehl) bearbeitet, kann hierdurch geändert werden, wie der Klient gestartet wird. Die geänderte Startweise sollte in der Lage sein, das gegebene Projekt des Klienten auszuführen. Sinvoll ist die Bearbeitung des executable Felds zB falls Sie 2 verschiedene Version von Ardour installiert haben, eine wird durch ardour, die andere durch Ardour6 gestartet, und Sie wollen die genutzte Version ändern.

Ansonsten wird dringend davon abgeraten, die genutzten Argumente zu ändern, und um Dateien als Argument zu laden ist es völlig unbrauchbar.

Ray-Hack Tab

Falls der Klient vom Typ Ray-Hack ist, stehen Ihnen hier viele Felder zur Verfügung. Das sind aber nicht unbedingt gute Nachrichten. Die Grundidee ist es zu ermöglichen, eine Anwendung, die (noch) nicht mit dem NSM Protokoll kompatibel ist, in der Session laden zu können. Das NSM Protokoll ist, falls sauber im Klienten implementiert, wesentlich komfortabler und verlässlicher als dieser Hack. Dies im Hinterkopf lässt sich dennoch sagen, dass wir zwar in allen Audio Programmen das NSM Protokoll erwarten können, es aber auch nützliche Programme gibt, bei denen dies nicht der Fall ist.

Das Ray-Hack Pseudo-Protokoll nutzt die Attribute von Proxies (nsm-proxy oder ray-proxy), aber der Klient wird direkt in der Session gestartet.

Ray-Hack Client properties

Launch block

ray hack launch
  • Folder ist der Ordner Name für diesen Klienten im Session Ordner.

  • Executable ist das Kommando, mit dem die Anwendung gestartet wird.

  • Config file ist die Projekt Datei, die wir mit dieser Anwendung öffnen wollen. Es ist sehr zu empfehlen, eine Datei zu benennen, die sich im Klienten Ordner befindet.
    Die Variable $RAY_SESSION_NAME wird automatisch durch den Namen der Session ersetzt.
    Falls dieses Feld leer ist, wird der Status des Klienten immer auf launch bleiben und nicht zu ready wechseln. In manchen Fällen mag es besser sein, einen beliebigen Wert einzugeben anstatt ihn leer zu lassen.

  • Das Browse Feld öffnet ein Dialogfenster, um die Projekt Datei zu finden und im Configuration file Feld einzufügen.

  • Das Arguments Feld enthält etwaige Argumente für das Kommando.
    Die Argumente werden wie in der Kommandozeile getrennt, vergessen Sie also falls nötig nicht " und '.
    Um zum Beispiel das Kommando my_command my_argument_1 "my argument 2" zu reproduzieren, geben Sie my_command im Executable Feld und my_command my_argument_1 "my argument 2 " im Arguments Feld ein.

Signals block

ray hack signals
  • Save Signal kann nur sehr selten genutzt werde. Für Anwendungen, die mit dem alten LASH Protokoll kompatibel sind, kann es SIGUSR1 sein. Ansonsten lassen Sie es auf None, wenn keine Speichermethode vorhanden ist, können wir sie nicht aus dem Ärmel zaubern.

  • Stop Signal wird normalerweise SIGTERM sein. Ändern Sie dies nur, wenn die Anwendung sich nicht korrekt schliesst.

  • Falls die Wait for a window before considered it ready (auf Fenster warten) Checkbox aktiviert ist, wechselt der Status des Klienten erst zu ready sobald das Anwendungsfenster sich geöffnet hat.
    Falls wmctrl nicht installiert ist oder der WindowManager ihn aus Kompatibilitätsgründen nicht nutzen kann, wird der Status sonst zu schnell, eine halbe Sekunde, nach dem Starten auf ready wechseln.

Mit ray_control können andere Signale als die der Multiple Choice Box zugewiesen werden. ray_control client CLIENT_ID set_properties save_sig:22 wird zum Beispiel das SIGTTOU Signal für das Sichern des Klienten mit CLIENT_ID zuweisen.
Das Kommando kill -l zeigt Ihnen im Terminal-Emulator die möglichen Signale und ensprechenden Nummern.

Non-saveable management block

ray hack non saveable

Dieser Block ist nur aktiv, falls Save Signal auf None gestellt ist.

  • Falls Tell user to close program himself at session close (Nutzer informieren, dass er die Anwendung selbst schliessen muss) gewählt ist, gilt der Klient als nicht speicherbar und ein orangenes Ausrufezeichen ist vor dem Save Symbol sichtbar. Wird die Session beendet, wird RaySession warten, bis Sie die Anwendung selbst geschlossen haben, da es unklar ist, ob Sie ungespeicherte Änderungen haben.

  • Falls Try to close window gracefully (Fenster elegant schliessen) gewählt ist, wird RaySession beim Beenden der Session versuchen, die Anwendung so zu schliessen, als würden Sie es tun. Dies ist sehr nützlich, falls die Anwendung auch im Fall von keinen nicht gespeicherten Änderungen einen Bestätigungsdialog erfordert (was oft der Fall ist). Falls wmctrl nicht installiert oder mit dem WindowManager nicht kompatibel ist, müssen Sie die Anwendung in jedem Fall selbst schliessen.

Test area

ray hack test zone

Das Areal gibt Ihnen die Möglichkeit Start, Stop und Einstellungen speichern zu testen, ohne vorher Save the changes (Änderungen Speichern) auszuführen.

Network Sessions

Durch eine Network Session kann auf einem weiteren Computer zeitgleich eine weitere Session gestartet werden. Durch eine Network Session kann auf einem weiteren Computer zeitgleich eine weitere Session gestartet werden. Dies ist besonders nützlich, wenn Sie net-jack nutzen um das DSP zu entlasten, z.B. um ressourcenintensive Effekte auf einer anderen Maschine zu starten.

Network Sesssions arbeiten nach dem Master-Slave Prinzip. Eine Session ist der Master und kann mehrere Slave sessions haben, die wiederum Master von anderen Slave Sessions sein können, aber dies wäre eher ungewöhnlich. Organisieren Sie dies besser einfach: Ein Master und ein oder mehrere Slaves von diesem.

Um eine Network Session (also einen Slave) zu starten, nutzen Sie die Network Session Anwendungs Vorlage aus dem Anwendungs Fenster und folgen Sie den Anweisungen.

Add a network session

Starten sie auf dem Remote Computer durch den Befehl ray-daemon -p 1234 (1234 ist lediglich ein Beispiel, Sie könne dies frei wählen) einen Dämon. Dieser wird etwas entsprechendes im Terminal anzeigen:

[ray-daemon]URL : osc.udp://192.168.1.00:1234/`
[ray-daemon]      osc.udp://nom-de-machine:1234/`
[ray-daemon]ROOT: /home/utilisateur/Ray Sessions reseau
Configure a network session

Kopieren Sie eine der beiden URLs in das network session invitation window. Die erste Variante (startend mit osc.udp://192.168.) muss mit Sicherheit funktionieren, die zweite wird nur funktioneren, wenn /etc/hosts vom dem Master Computer einen Eintrag für den Slave Computer enthält. Den Namen des Slave Computers in /etc/hosts einzutragen und die zweite Variante der URL zu nutzen ist aber vorzuziehen, da sich die Addresse 192.168 ändern kann falls sich der Remote Computer durch den Wechsel von wired zu wifi oder durch eine Neuinstallation der Distribution ändern kann.

Auf dem Master Computer haben Sie nun 2 RaySession Fenster, eines kontrolliert die Master Session, das andere die Slave Session. Sie erkennen die Slave Session daran, dass das Fenster weder die Toolbar mit New Session, Open Session, Control, noch Abort session oder Close session Felder hat.

network session child

Wie viele andere NSM Anwendungen kann das Slave Fenster verborgen werden.

network session client

Wenn Sie auf dem Slave Computer das Kommando raysession -p 1234 nutzen, haben Sie das Slave Fenster doppelt, eines auf jedem Computer.

Tip: Nutzen Sie auf dem Slave Computer ray-daemon -p 1234 im Startup.

Nicht verfügbare Anwendung hinzufügen

Falls die Anwendung, die sie hinzufügen möchten, das Speichern von Projekten nicht leisten muss, klicken Sie auf Executable, fügen Sie den ausführbaren Namen der Anwendung ein und klicken auf Ok. Ansonsten folgen Sie dem Beispiel:

Wir werden als Beispiel Audacity zu der bestehenden Session hinzufügen. Diese Anwendung ist sehr bekannt und gewöhnlicherweise in Audio Distributionen vorinstalliert.

Klicken Sie auf Executable (oder nutzen Sie Ctrl+E). In dem sich öffnenden Fenster Kommando hinzufügen Fenster (auführbare Anwendung hinzufügen), entfernen Sie die Auswahl für das NSM Protocol, fügen Sie audacity in das Executable Feld ein und klicken auf Ok.

Add Executable window well done

Ein neuer Klient wird erstellt, sein Eigenschaften Fenster öffnet sich im Ray-Hack Tab und Audacity wird gestartet.

Wir werden nun sofort ein leeres Projekt von Audacity im Ordner des Klienten speichern. Dieser befindet sich im Ordner der Session und hat den Namen, den Sie ihm im Folder: Feld im Ray-Hack Tab oben gelegen gegeben haben. Wir werden dieses Projekt GENAU so nennen, wie die aktuelle RaySession. Nutzen Sie in Audacity hierfür: Menu → File → Save project → Save project (Menu, Datei, Projekt Sichern, Sichern).

Save empty Audacity project

Klicken Sie auf Validate (Bestätigen) falls sich ein Warnfenster öffnet.
In der sich öffnenden Box um die Datei zu speichern, finden Sie den Session Ordner unten links (siehe Bookmarks für den Session Ordner erstellen). Klicken Sie darauf, um ihn zu öffnen. Darin sollten Sie den Ordner des Klienten mit dem Namen, der ihm im RayHack Tab gegeben wurde,finden. Nutzen Sie diesen. Fügen Sie in der Speicherbox den genauen Namen, den sie der Session im Name: Feld gegeben haben und bestätigen Sie.

Where to save Audacity project

Schliessen Sie Audacity.
Klicken Sie oben rechts im Ray-Hack Tab vom Eigenschaftern Fenster des Klienten auf Browse.

Load CONFIG_FILE window

wählen Sie das gerade erstellte Audacity Projekt mit dem Session Namen und mit .aup endend.

Das Configuration File Feld sollte nun $RAY_SESSION_NAME.aup und das Arguments Feld "$CONFIG_FILE" enthalten.
Aktivieren Sie Wait for a window before being considered ready, Ask the user to close the program himself und Try to close the window gracefully. Klicken Sie dann unten rechts auf Save Changes.

Ray-Hack tab of Audacity client well done

Starten Sie den Audacity Klienten und versichern Sie sich, dass das Audacity Fenster den Namen der Session hat..
Klicken Sie auf das Symbol für den Audacity Klienten, wählen Sie im Drop-Down Menü Save as an application template, und geben Sie in der sich öffnenden Dialog Box Audacity ein. Nun müssen Sie lediglich Audacity wie in Anwendung hinzufügen Fenster beschrieben wählen, um Audacity in der Session zu starten.

Vor dem Speichersymbol des Klienten ist ein orangenes Ausfrufungszeichen, welches bedeutet, dass RaySession nicht in der Lage ist, dieses Projekt zu sichern und Sie dies selbständig machen müssen.

Je nach der Anwendung, die sie zur Session so hinzufügen möchten, kann dies auch schwieriger sein. Einige Programme benötigen zB ein Kommando Argument, um eine Konfigurationsdatei zu nutzen. Nutzen sie hierfür im Terminal-Emulator my_program --help oder man my_program und fügen die entsprechenden Argumente im Arguments Feld ein.

NSM Session importieren

Um eine Session, die mit Non Session Manager oder New Session Manager erstellt wurde, zu importieren, kopieren oder verschieben Sie den entsprechenden Session Ordner in den Root Session Folder von RaySession (default ist ~/Ray Sessions). Wenn Sie nun auf Open session klicken, sollte die Session in der Liste der verfügbaren Sessions aufgelistet sein. Doppel-Klicken Sie darauf, um sie auszuwählen.

RaySession wird danach hinzugefügte oder entfernte Klienten nicht in session.nsm speichern, Sie müssen also hierfür auch weiterhin RaySession nutzen.

Die Dämon Optionen

Die Dämon Optionen sind Services, die durch Klicken auf das Control Feld oben rechts im Hauptfenster im Untermenü aktiviert oder deaktiviert werden können. Das Untermenü findet sich ebenso unter options in der Menübar.

Daemon options

Die Details zu den jeweiligen Optionen sind die folgenden:

Bookmarks für den Session Ordner erstellen

In der Audioproduktion wird häufig eine Audio oder Midi Datei mit einem Program erstellt und dann von einem anderem Program genutzt. Die vorliegende Option bietet hiefür einen praktischen Nutzen: einen Shortcut für den aktuellen Session Folder (Ordner) im Dateimanager und in der Dialogbox, um Dateien zu laden oder zu speichern. Sie vermeiden also den unnötigen Zeitaufwand, sich durch ihren persönlichen Ordner im Dateimanager klicken zu müssen, um eine Datei zu finden, die in ihrem Session Ordner ist.
Dieser Shortcut wird entfernt, sobald die Session geschlossen wird.
Diese Option funktioniert technisch für GTK2, GTK3, QT4, QT5, KDE and FLTK.

Automatisch Snapshot beim Sichern erstellen

Diese Option ist alles andere als unbedeutend. Sie ermöglicht Ihnen, bei jeder Speicherung einen Snapshot der Session zu erstellen. Im Falle eines technischen oder künstlerischen Fehlers steht Ihnen also der Snaphot zur Verfügung. Um diese Option zu nutzen, muss git installiert sein. Unter Snapshots finden Sie weitere Details.

Desktop Status

Falls diese Option aktiviert ist, wird RaySession auch den virtuellen Desktop, auf dem sich ein Klient Fenster beim Schliessen der RaySession befindet, speichern (oder zumindest wird dies versucht). Falls Sie die Session oder den Klienten wieder starten, wird das entsprechende Fenster also auf dem Desktop gestartet, auf dem es beim Schliessen zu finden war. Für diese Option muss die Anwendung wmctrl installiert sein. Unter Wayland wird sie vermutlich nicht funktionieren

Session Skripte

Deaktivieren Sie diese Option, um beim Öffnen, Speichern oder Schliessen einer Session diese Skripte völlig zu ignorieren. Die Skripte werden für JACK Konfiguration erhalten genutzt. Unter Session Skripte finden Sie weitere Details.

Optionalen GUI Status erinnern

Diese Option betrifft lediglich NSM Klienten, die ihre Fenster sowohl verbergen als auch anzeigen können. Einige Klienten starten immer verborgen, andere starten so, wie sie geschlossen wurden. Wird diese Option aktiviert, werden alle Clienten immer so gestartet, wie sie während der letzten Sicherung beendet wurden. Wurden sie noch nie gestartet, werden sie nicht verborgen gezeigt

Snapshots

Für Snaphots muss das Programm git installiert sein. Falls es nicht installiert ist, wird das Reverse Symbol nicht zu sehen sein und es ist unmöglich, Snaphots zu machen oder den entsprechenden Status wieder herzustellen.

Der Snapshot speichert Dateien und deren Inhalt zu einer gegebenen Zeit. Grosse Dateien und Dateien mit Dateiendungen für Audio und Video werden ignoriert, da dies zuviel Zeit in Anspruch nehmen würde und der Session Ordner zu gross werden würde. Dies ist kein grosses Problem, im Gegenteil, da ihre erst kürzlich erstellten Audiodateien erhalten bleiben, falls Sie zu einem vorherigen Snapshot zurückkehren.
Sollte trotz all dem der Snaphot Vorgang zu lange dauern, wird sich ein Fenster öffnen und Sie können den aktuellen Snapshot bedenkenlos abbrechen. Der automatische Snapshot wird dann für diese Session nicht mehr stattfinden.

Der Nutzen von Snapshots liegt in der Tatsache, dass Sie zu dem Stand der Arbeit zurückehren könne, bevor Sie diese eine brilliante Idee gehabt haben, die sich dann als fruchtlos erwiesen hat, oder bevor sie die Samples neu geschnitten und dadurch alle Musikalität zerstört haben, oder bevor die Anwendung aus unbekannten Gründen anfing, abzustürzen.

Seien Sie aber sorglos, zu einem Snapshot zurückzukehren heisst nicht, dass Sie den aktuellen Stand nicht ebenso wieder herstellen könnten.

Um die Session zu einem Snapshot zurückzusetzen, klicken Sie auf das Reverse Symbol rechts vom Executable Feld.

snapshots

Wählen Sie in der Auswahl den Snapshot, zu dem Sie zurücksetzen möchten und klicken Sie auf Ok. Zunächst wird ein neuer Snapshot erstellt, dann schliesst sich die aktuelle Session, es wird zum Snapshot zurückgekehrt und die Session öffnet sich wieder.

Ebenso ist es möglich, lediglich einen Klienten in einen vorherigen Status zurückzusetzen. Wählen Sie nach einem Rechtsklick auf den Klienten im Menü hierfür Return to a previous state (zu vorherigem Status zurückkehren). Falls gewünscht können Sie für jeden Klienten die Dateien, die bei einem Snapshot ignoriert werden sollen, festlegen, indem Sie dies im [client_properties] unter "Snapshot ignored extensions" (bei Snapshots ignorierte Dateiendungen) entsprechend bearbeiten.

Ist die Option Automatic snapshot after save (automatischer Snapshot beim Speichern) gewählt, wird nach jeder Speicherung der Session ein Snapshot erstellt, ausser es sind keine Änderungen vorhanden. Um Snapshots zu anderen Zeitpunkten zu erstellen, klicken Sie auf das Reverse Symbol rechts vom Executable und bestätigen Sie Take a snapshot now. Ein Vorteil dieser Methode liegt darin, dass Sie dem Snapshot aufschlussreichere Namen als lediglich Datum und Uhrzeit geben können.

Session Skripte

Session Skripte ermöglicht Ihnen, beim Öffnen, Speichern oder Schliessen der Session eigene Aktionen auszuführen. Im Besonderen für die Möglichkeit JACK Konfiguration erhalten ist dies nützlich.
Um diese Skripte zu bearbeiten, sind zwar Kenntnisse in Shell Skripting nötig, nutzen kann sie aber jeder.

Die Session Skripte befinden sich in dem Ordner ray-scripts, entweder im Session folder oder einem Parent Ordner von diesem.
Eine Session, die sich im Ordner :
~/Ray Sessions/avec_script_de_foo/ma session

findet, kann der Skript Ordner folgende Pfade haben:

~/Ray Sessions/avec_script_de_foo/ma session/ray-scripts
~/Ray Sessions/avec_script_de_foo/ray-scripts
~/Ray Sessions/ray-scripts
~/ray-scripts

Der Vorteil, die Skripte in diesen möglichen Pfaden zu haben liegt darin, dass mehrere Sessions diese nutzen können, ohne die Skripte in den jeweiligen Ordner kopieren zu müssen. Ebenso eröffnet dies die Möglichkeit, jemandem eine nicht geskriptete Session für mögliches Teamwork einfach zu kopieren.
Es wird lediglich der Skript Ordner genutzt werden, der im Pfad dem Session Ordner am nächsten ist. Ein leerer ray-scripts innerhalb des Ordners der Session selbst wird also alle sonstigen Skripte leicht deaktivieren.

Um die Skripte zu bearbeiten, erstellen Sie zunächst eine Session aus der Vorlage mit den Basisskripten. Die Vorlage enthält Skripte, die keine besondere Aktion ausführen werden. Gehen Sie im Session Ordner in den Ordner ray-scripts. Hier finden Sie die Dateien load.sh, save.sh und close.sh. In jedem dieser Skripte bezieht sich ray_control run_step auf die gewöhnlich ausgeführte Aktion (je nach Skript: Laden, Sichern oder Schliessen der Session). Ist eines dieser Skripte für Sie ohne Nutzen, löschen sie das Skript einfach. Es ist unnötig, dies dann zu bearbeiten.

Die Skripte müssen zwingend ausführbar sein, also die entsprechenden Rechte haben, um funktionieren zu können.

Um einem Klienten eine bestimmte Aktion zuzusprechen, werden Sie vermutlich das Kommando ray_control nutzen. Geben sie in der Kommandozeile ray_control --help ein, um sich einen Überblick zu verschaffen. Mehr Informationen finden Sie unter RaySession von der Kommandozeile steuern (RaySession von der Kommandozeile kontrollieren).

Die Vorlage JACK memory configuration (JACK Konfiguration erinnern) nutzt Session Skripte, aber es sind viele Aktionen entsprechend ihren Bedürfnissen und Vorstellungen denkbar, z.B.:

  • die Reihenfolge festlegen, in der die Klienten gestartet werden sollen, sobald die Session geöffnet wird (ein Beispiel findet sich im Quellcode)

  • ein Backup der Session auf einem externen Datenträger erstellen, sobald die Session geschlossen wird

  • den Fenstern von nicht sicherbaren Klienten den Shortcut Ctrl+S senden, sobald die Session beendet wird (ein Beispiel findet sich im Quellcode)

  • Das rote Licht beim Betreten des Studios anschalten, und beim Verlassen ausschalten

  • Beim Beenden der Session die Kaffeemaschine einschalten (ein blödes Beispiel, müssen Sie doch den Filter immer noch selbst wechseln)

  • Viele, viele Fehler machen, die ihre Session abstürzen lassen. Seien Sie also entsprechend vorsichtig!

JACK Konfiguration erhalten

Dank der Session Skripte ist es möglich, die für eine zu ladende Session erstellten Jack Konfigurationen zu erinnern, bzw. wiederherzustellen. Dieses Verhalten erinnert an einige Operationen von LADISH Studios, tut dies, zumindest unserer Meinung nach, aber viel besser.

Anwendungsmöglichkeiten

Dies kann nützlich sein wenn:

  • Sie ein bestimmtes Audio Interface in der Session müssen.

  • Sie an mehreren Projekten arbeiten, die unterschliedliche Sample Rates (Signalverarbeitungsraten) nutzen (eine Session mit 44100 Hz, eine andere mit 44800 Hz)
    Sie müssen also JACK nicht selber neu konfigurieren, stoppen und wieder starten. Ausserdem verhindern Sie hierdurch, dies zu vergessen und von einigen Anwendungen entsprechend gewarnt zu werden.

  • Wenn Sie verhindern wollen, eine sehr DSP intensive Session (zB in der Phase des Mixens) mit einem zu kleinen Buffer (z.B. 128) zu laden
    Die meisten Audio Interfaces sind aber durchaus in der Lage, die Buffergrösse ohne Neustart (also hot) von Jack zu wechseln.

Anwendungsweise

Die Session Skripte Option muss aktiviert sein (dies ist die Voreinstellung)

Um Jack configuration memory (Jack Konfiguration erhalten) zu nutzen, erstellen Sie eine neue Session aus der With JACK configuration memory Vorlage. Es handelt sich de facto um eine geskriptete Session (see Session Skripte) die ein Skript startet, das zwar mit RaySession vorhanden, zu diesem aber völlig extern ist, insofern hat RaySession noch immer keine direkte Beziehung zu JACK.

Lesen Sie die Informationen im Fenster und bestätigen Sie dann. JACK wird neu gestartet und dann startet ihre Session.

Funktionsweise

Bei jedem Speichern der Session wird die aktuelle JACK Konfiguration in der Datei jack_parameters gespeichert.
Beim Öffnen der Session wird JACK neu gestartet, falls sich die gespeicherte Konfiguration von der aktuellen unterscheidet.
Wird die Session geschlossen, wird JACK abermals gestartet, diesmal mit der vorherigen Konfiguration.

PulseAudio → JACK Konfigurationen werden ebenso gespeichert und wiederhergestellt.

Wird die Session auf einen anderen Computer kopiert und dort genutzt, wird die Konfiguration von JACK nicht erinnert und beim Speichern überschrieben werden. Lediglich die gespeicherte Samplerate wird genutzt werden.

besondere Fälle


Die gespeicherte JACK Konfiguration einer Session nicht nutzen:

  • deaktivieren Sie die Session scripts Option

  • Öffnen Sie die Session


Die JACK Konfiguration einer Session ändern:

  • Starten Sie JACK mit der gewünschten Konfiguration.

  • Deaktivieren Sie die Option Session Skripte.

  • Starten Sie die Session.

  • Aktivieren Sie die Option Session Skripte wieder.

  • Speichern Sie die Session.


In einer bereits bestehenden Session JACK Konfiguration zu ermöglichen

  • Kopieren Sie den Ordner ray-scripts aus einer Session mit erhaltener JACK konfiguration in den Session Ordner.

  • Aktivieren Sie die Option Session Skripte.

  • Starten Sie die Session.

oder

  • Verschieben Sie den Session Ordner in einen Unterordner mit ray-scripts Ordner

  • Öffnen Sie die Session.

Unter der Haube

RaySession ist lediglich eine grafische Oberfläche, GUI, für ray-daemon. Wenn sie RaySession starten, öffnet sich die grafische Oberfläche und verbindet sich mit dem Dämon, und sobald sie die Anwendung schliessen, stoppt diese den Dämon. Die grafische Oberfläche und der Dämon kommunizieren über OSC (Open Sound Control) Meldungen. Dasselbe gilt für den Dämon und die NSM Klienten. Dementsprechend können sie mehrere grafische Oberflächen mit dem Daemon verbinden, auch über das Netz. Tippen Sie raysession --help für die entsprechenden Informationen.

Es können mehrere Dämonen gestartet werden. Falls Sie also RaySession starten, wenn bereits eine weitere Instanz gestartet ist, wird ein neuer Dämon gestartet werden. Trotzdem ist diese Vorgehensweise eher ungewöhnlich, die Nutzung nur eines Dämons ist zu bevorzugen. Falls ein Dämon bereits gestartet, ihm aber keine GUI zugewiesen ist, wird sich RaySession per Voreinstellung beim Start mit diesem Dämon verbinden.

RaySession von der Kommandozeile steuern

Mit dem Kommando ray_control können Sie alles tun, was Sie auch mit in GUI tun können, und ein wenig mehr. Tippen Sie ray_control --help-all in einem Terminal-Emulator, um alle Möglichkeiten kennezulernen.

Falls mehrere Dämonen gestartet sind (siehe Unter der Haube), wird ray_control den zuerst gestarteten in Betracht ziehen, ausser sie bestimmen den OSC Port mit der Option --port oder durch die Umgebungsvariable RAY_CONTROL_PORT.

Anzunehmen, ray_control wäre überflüssig, da das Kommando oscsend OSC Mitteilungen an den Dämon schicken kann, ist falsch.
Zum einen kann oscsend zwar Mitteilungen senden, aber keine Informationen auf einfache Weise empfangen (welches sind die aktiven Klienten? Was ist der ausführbare Befehl von einem bestimmenten Clienten? …​); und zum anderen, weil ray_control nach dem Ausführen der verlangten Aktion sauber beendet wird. z.B. ray_control open_session "my session" wird beendet, sobald die Session geladen ist.

Seien Sie hier noch einmal daran erinnert, einen globalen Keyboard-Shortcut für den Befehl`ray_control save` zuzuweisen (Ctrl+Meta+S). Dies wird Ihnen viel Arbeit ersparen.

Frequently Asked Questions

  • Ist die direkte Nutzung von Ardour (oder einer anderen NSM kompatiblen DAW) anstatt in RaySession trotzdem noch sinnvoll?

    Ausser für wirklich winzige Projekte, eher nein. Falls Sie Ardour nutzen, starten Sie es immer in einer RaySession. Erstens können Ihnen die automatisierten Snapshots unerwartet von grossem Nutzen sein, zweitens ist es möglich, dass Sie später noch eine weitere Anwendung nutzen wollen, auch wenn Sie dies bisher noch nicht geplant haben.

  • Can I launch an Ardour session launched normally into a RaySession session ?

    You will find in source code here a script named ardour6_from_external_to_session.sh. Before to use it, backup your ardour session directory. Download this file, set it executable and execute it with a .ardour file as argument, it will adds the ardour project to the current session, or create a session if no session is loaded.

RaySession-0.12.2/manual/de/rs_manual.css000077700000000000000000000000001417052567600235532../en/rs_manual.cssustar00rootroot00000000000000RaySession-0.12.2/manual/en/000077500000000000000000000000001417052567600155675ustar00rootroot00000000000000RaySession-0.12.2/manual/en/.directory000066400000000000000000000001531417052567600175730ustar00rootroot00000000000000[Dolphin] GroupedSorting=true SortRole=modificationtime Timestamp=2020,11,10,10,48,39 Version=4 ViewMode=1 RaySession-0.12.2/manual/en/images/000077500000000000000000000000001417052567600170345ustar00rootroot00000000000000RaySession-0.12.2/manual/en/images/.directory000066400000000000000000000000611417052567600210360ustar00rootroot00000000000000[Dolphin] Timestamp=2020,11,9,11,28,22 Version=4 RaySession-0.12.2/manual/en/images/add_application.png000066400000000000000000001750171417052567600226700ustar00rootroot00000000000000PNG  IHDR; pHYs+ IDATxwxU33Kڦ'BG)*B| D:H QR&dwgذ,!l޽3{v3o݆B!dU@!Œ!Bf$!>HB!d} B0#A!aFB!Ì!Bև B!3BY,֩P(* Pͽu6UvbYQ ז܍)6~u$&%BUkḼ"u|oƯ/B9I_ܭYRBRJJqS Y/n!Bև B!3BYf$!>HB!d}#XWRv rt97(BkذR jäFi[l6_r%,l ,:xrJlyyydr/܎P:xp-\ n(7o]֭[ *߱; `ts~ֶ üe{sԩ]فaoQQUEzvݯS:}fN%a.paܯ,U}g/QP\6n|0w>9b1߲}AcG vVOЬ *E ([>Fdee6kRN>m0_0 dddqnlA<<)vݯ;u:"_H'J uvH)]vn 3#SRdBkZ=o7ltK/[m㓜2}RJׯ_흘hŨ^>#[bAz{5W.Z˗_C/?x~R aIỸsHbu%bΐˌ׷RLPz]Tegk) 55޽ѣ4ǴTHLLuy,\Чwשּׁ7U4ߠs 8@&O6QFϟ?}zd|xWĤMz;wFh͚53e$.R4M5=xk !TUgjSS|2d!lNňƏw۵sh49rxqZsÆ Q b>޲yU8n͚Z)I'̛B=2ct)۶m7o~X,*?BѣN>>p@nAA֍fm}o,[N9SOիW(#Q(BU*U~~eJt_8BH^ǚؠ~=Xb+;qZ4ܻwsF [nޞb l4<啿 Bd%/)V0fsMpP_Zt8i℮]"xG~ݚ?"~?|0jGLKf͜ѳgE?-8|02K#G A"Pڂ9Jijjjc322pj:Wr+-[DF}wͱWYkkcaQ"h?qd !+W>ei-o⟝'MdXzdqcLSjjժo}ʕ-[<gϝ3b.B$&&f"EB2+VnݶtjժYr''GB-8qq B RFb0_bzz˲SInn|.B!0^E>;;ۼwǏ gYT*cɧ ) B!d]垑DFgi~LVnǎطg>%Dzaa[jUA"BȺ^~f܄Zvٻ{^qp^n=4iܣG@VŢ,B"?ҳWhB*6d}IFFF9BʥgmB!J B!fmBe'ީDwv-x- *-#A!aFB!Ì!BW3]N@ᑝvҰawyQ+[߸Q^=zBo7Y; Py&ϝ;g@zFB)q@B`J0O_00 cj`ԧ,\]]/\`nY&y>9)ߪU+W.znAM*\~~~111g$*Rpυ!,3Y؃Q,CIVִmD,*HUOnӺm@$tGܸqC.׬Y3;;/8s_-:ڵG }e*-aƄ\QFkG BB0 Bݕ7uՁXqV>#f\jx˵Izedg!Q.? ۪ e%h4-Ϟ=}˖WeCC/[W\)j B QVYE͛pqvػǏn޼Rw[nJlU{e+BJ0"*y{ěJj61Ō*D?El5"#1H b36лOSN7$ ~pԨ.ҳWީNNJnڴY ]-O-DNjժ Tуiyg3 v`1PO`9"6?ˉ<0@L,K*iDRv9rDbBe_;vt`B=E"Q~'Np5Gǧ{j= \Ybހј6BOrr3 H)]~}JJwEn]p!T`xVorZX:wGkw-XՇ\c Wc1򘻊˷qZ[111]DΝ!N5obڵbxevLx8h۶-h4޽fpbq&oc`׮ӧO5hРQХKkqߠ ڵ 0r;nT8F,˱ J1"<)fJ;NTsIݴ ٶ홝;Ǎkw3h?rqZ ÆK ><˫ZbRΝeH4M5=xk Bw6}{`7tرv3gV*+W.Doquqqssѫ!d|xS>>y:B ۸i9z/}z~~^~~kHPھm(0T*/.޾}zHr^608NPTg=xpC]ٱcR٧o?"tGI/^"F &Hӂ<ԩOO/̮_ŋ&N8U˖Dž͛5i6jLkO!nnnZs"=#=--#۶m7}eDGܸiٯ6>|l۶l'X.y|| diФIGUX̯ή!TUM%K;u-K>>޷nӶ]w,]z 2j#v Dž?|?@j罾קw/j8Ak}B^0ae' XKk?صV=vò\EB 3T&w)ԯ1112Wrrsu/ھ?/yALK;-iÇ[u+)viC~u@gϝS8wOLleN37mTKq @'PJ'Wn?j_\%>!`|~T!M~ "A{΋~Z4Ni>WH".==_vvv,j4,ӞXa23J50pa1xk3lmCNN X"rƖ-MzoN}8)pb(X?J *0\m8~.W>O_&wJ21V4Wd=- nW]<xm8d1cF2Sf Tt'A5TY1rT=c@)u^Jc«2c> 13t2I9%gKixx3i8J]haϜ={uͪx*& pT\} |0~QI-# 2aCҢQgt#81s!}TP(=2"YC #~n1o|W5lPT;wځ`Fʎ1U*yUDeڼUN:} c.P S[0-XYb:!TƄdrHB<x-3nm^,wߤ3]8RMtdzD"BUbbbf$ `V Z$$P 4;$ʥ>P3xT2c ܟAJ`&lLʕ+y5jOvD 51RO4'j@jlA 2 -CF" [66:iB&QJjQպwQ:ܳs 40e$fljRUܼy gg{1Ji``[(qqq/uVĆ B\ƳU(>!%M~:u0JjM ~*%5CF,OlZ.۴QQQӦMǎ vvvWt7_L;3o;={NJJʻurrVTtݻ6zAF9t0DѣI'ǿۇks'^jUƙ3faƎ]jbÌ!Tn_GRӹF](\z@s.~ʕB#n߶"h}0vl⟗|ݷӦMuvv m[]6}n  >l[n @;F'>}ϓ5׃ O y2GSDq?浿}HیPRĄ gggJfj?vhbB9s6owcc===yQx8BmRs.;wnԑ#1 Z.q+6'Mٳش4Je.VP XxNg~"/'" 6vlDĮs}5wnrr;Vql֬ibbkL?yRnFD/ _ IDAT\ jcc@jxOHH~q+ f$r' HOO3 Đ 4vǪdb^.a(1 a]vN˖tdztopo g͚wF}"88Y;wR&U'99e_>%%;11ъQ BIE\ĬDTP XKE*H!\"\P**\!%TTO*RM{[zakk[ƐD"Q@E/(TmnAA-[ڽ{wWfk=<=qU*>>AAAk8`;vmݨp!T,X " O3,+f9"œ(`Ȇ4b _ܕOqb͚e\*BѣNFG^п[Pk`FD" 2͵Ԟ k׭#ojJebGR;J^2," p 1#a$Dp`1D^>};8mgGjgg3>6||ڵ͛_d:о0O"M)y޼ХݻmM۷stty+vl߾cb%/)V0f26d g^ƔF6t5\.:=RiKIFEPʳuG",a 5>[p<';Fbr=bH~ce"u$L\\˒+W=ʴ {)K:EIE)+Yg>^JXAQ#yaWčl׮}O? TpՋ/?qFqS6iѣGi%ŠaKӂ"Cݺ~RmÇs /n]sKF SJ8MJJN޴iDRK)Oz}ZzD3L0'}1? .VO'oܸnV*3T.([Dٴ7lؿeƌϖ/_yȑ ByƇ{xx$&&Uh۶G?ߞ^'[m۽go/bgg[]wS .O~FDʫ TÈ>곽yKH*LAHNN.OA3T( hd,*GQe,Q쌈0Z\pMoIRz+[d2gy7#\Toj۵ꊵ"  `ic(@IGwp|Jߚ3kH$RW\?q>lFcNnn;g~/ĺ|^ŋ,暝ݩcMdYVTn۾%KdžQϦ:=v_޽z zD~wQb~Z^t{l:PJOƤ<,P TB2U Ǝuo;#v1 m?0455uph~ųg] ѽ{JJkC OOpss۵sGDĮ{}i{jE~"~~u_ژ\r`)2tҘR[ E?~۰#CܣGw;;q& HJJbYITfff?OPn7mjԨJ>}x{bKJm>"-;'{yp =˲?~?k˖(BEŒUB  B ӿW899999?y 2O<=_"۳gzu뚳aAݺ{ R2,{Ęnܴ)kHZ~\yVػo֍7(9g}]M4NW(ⓧN/8f՞MC=oҋd HPIHHtqsZjۆ7mt;g߸qEo9JKK{w/"~ޣ{Zhޯ_H}lxIaӦ~שS &G?6~6tm!RΝ;@VfRdִ>y˖5V^zkBX! UBԮ "hqW]5k!cRT&F<ثgS;ԨQ!Ѥ66jBaԭMؽ磉nތB  HPdggSJY/{ǍK ))Ν?-1:BU#A#.˖-eF._~}GSL;i))) Zf;~f͚֬tJի&~do:t8o߉ۻ;W,gO""v>?wŋvɲ L)L/CG9q"/Oٹ3ys~1)Z\A[10#A!6mܴ^[ߧS BHOO7OFYt:s9?=Z"ø -_ k>y"FPBWC?xУWol`AsNlvvv,|Ϧ,W{j6%<C[R\gmP'$4jԨ,=4iWB+榦Z!Bjjսw[ѴkYz*[,>th=Kuۤ]v0Ԟ7{6ftݵ_:mv5"Oq[׳!TaFʄ5k(Bj1a{S`CҢQv~/7:R%h^ 75nRK? !|R&Z *+ƴ'>?0 X!??b;c 0Ս˔`䩑%V>kjTxcZ*ˆZ91.fBRrH   rWwYQ撽[͗, 6^*wo޹`W'LUHP[;JC¯TNFj4oHfsa t/wHebŊĥCC "]%ժ鼼wD6+%̋-p!dR[ Oh hT :Ud_jJ;޿tA)Tic"R*0 +) y9eP"T%VTq k1xNt IiJKV'KNeI *kz7R hz10e-#؏FÛ57OZԸ>yӝ|M'z!3x MǮ>'oSe_^ TXbȺmW?zlS:RQ=~f<αJ: *ȯD%xH hA}TiBlˇ69eVӹf}S#'w`c۾rȖvfe|%yy@TOC0査bX*D0?!IdE^*J_grĜQNkgJV3P36nj|^#1@b4Ill8s^ ZI>*7#޲&׎T2ΟE,1.쎟uDj4iW'Z^*'v\fԲ1#Sl.n#urtJIMhBUNWny~5% hLi3Q @z4;.ǥLI?"ճMGF}s76XLtָiSݲST΅>yerL`" ot.;;KHbnݮSv-Z BJrcnzmE̊t9ڼ<^FCQAY@ lU2-Uqzos1=uZ߈YgnV9uU,'25vPkM"D`ق}*חUZn"Ȑ"5R˂32 u$[33JA!K -Vdf b4PsaX %#LH*ۅ${374 |F{Pc]DhCsc9Z0uİg 3A&mn]DFթEz‰wJ5˳qYw6w"*-usizo0pyb4J3(O)ՁsSʍ$p?Y\9iv.^z[{Ntې{֌{plcnMkJ'+ek<[QF7VR$\6mKjN)JJB9a|6g#H_n1ߥp+e0Vf鴔3hSF@)S <1(aINgKL+TiC`+eLq|3UjtY@KA!-+J^ӗcXܹK/'TrT8F=զ' `!#80<0 N ^oR.@4蝍+QJt8Rr:R0#A;#U!g$}}RST!_TNzmJQ* ,(q!ZVW\%%*lE!aFB!YPDJR"-[*rSɧS1tfړNts{{[Xբ3-&2, O:t`ggշ M6jZR_r Jv>>bڱTŒ$].QB !*Nmɂ X5>{n??wΙ3ԩSg}fzSdwy',,3 6tX@@i}u1O8)>>cKlРAoO?| ZmإK蓓'OiݦȑlٺanAA'N4uPu 3Ͽ,[VF KTb媗 :t苞%aƄ\rժFv8mA,iN 2,TOVNљiY"@ 3 rD{Oכ[nY#9C^6n8{lXpaq2dHM-bL&3 <b-ou P5M gw߲e~?.X0c?b'!K$KF^zUqW.JɱlaFVrrL_VZ~8 >+W8~"z~s G 4{,S&=sƌAFEE t钵bDc$^Ryc%T%2Jc&+޲?drR@۶j2-ifLXؠ=zT^{ӧLVSRR>3{ف]:9BE~]߸a}AcÇj**QFۣR]RB+72RnN B%SRR HBv!Jw@9y$󱱱%P[ ,:;;T W77sFRFM5STO}CBkPE~"Ç5Mrrr}Z>YHȱO׽w=z7n\?zhpp7=z(<|ܢE?Jz 7o t/S>9"&&ƊUR]֎ N,U@XęBBUS*BCC CvvW_}_Z5k֬mn۶m%#fs̑H$˥!-#pAʼn&nllZzJbE = RL7 innEr֭A~Ï?r"ׯk׮ _c:vuqq[bB!dp蠰c#"v;sKt*;V{U|BBSS\nR#a%R0 BM 8P:jԨyt۷oO4)==ŋk׮?iii JJJD%Ȉ\-CCק1ŧ}U*U``ב#G @{j;u /u *.BY3GBb~Ꚙ|uru}kSzOrr3 2jKIInT"#ie$B%rQBB)[A"Ie*=B?7dȐA}M4{.T._t{wܹ#%\ŋ2RrR9=zھhcbbx1;CBB`͚>|n,qLј1oV?q=z4xt!22R$U^t:]h;{{j5 G/7((ȷvA1߿cNXF2 jJ@ZruJiO(RBl$HDssi eF.|@)efŊS3,sO)NTTX,0q9sr_|o{=vLǏ=ZӊԾ!!۶=%"b=<<yY_T*c]>{iڲ|֯5"bVU(|rurӧ\vڵk{xejJFu2:r݂<ݭ[a=/nKBMՔB(!@ r=35>OG J-`O h#S!ˬ7/(w IDATؙvpqs˓H>,P ]]븸OK#`YbGeERȤLj{l^d2[[[VW(H$MKKlcZ[[[?>v ]z9qFc1ǵuqpxȕt#(AԒss. CD"=]Ozə3gN>ᇚ'35hm!+yR4#/obb `/YVlKfffOԹs@@@׮.ꦔ#ʂBE^G#d]VH]%,K(C$)@l9ôȏ0 B[M !O,2e$wqOHcGTLoyJ$a̍6[ ۽{ի̋y9={nذb>!dɚDщ"c8NG RK|D!_Gq= B/O,ub9XL3Ϝ}(eg4ٶy@^ÇY'910-u}11UULLu1 g͌+C)%Kf)! c(0p$,16"iNzIկ'zAO)$QC˗9ʌ7n8995R8Vx 'hԧ T&,øK\\89 V-b EO'SSDxfe ymɞ={6lاF Ӽ̢Y>|9`8fjy(?_7Q*9ST+Pevq#!56@(%(BB%@)#Sm4S#J  !m8B"TթA!}ggsF#ur23bڨQWNRT*x,+yDg ,]k:3L*f`RBЌV$zAC(Q&STyD=>IG@ P'@DJyH6LT(rةc-6N0wOF/D0BZ"A(U !+y BOD$@Kt@wLVTl޲E) KII1-7w]{VZ󥑝ʢǜuIBJ_FFD^3޴iF=wሎn!.̙Ȉ̌'NdS\Fas~RI.هS.mۺy"ݯ|u7Q ۀŠH@A%S]- 1Iugp Hku% ]:B"O9&WJPL(@I^{9ݔ6HXӿ__Xj=ڿ_"yj>8a ,}C˖}޻fYc/MaйSg|SRR`ڵkٿQ;o׫Wo؈).gѣMxϑqtJ}s8\Ҧ-pV3r!AM9&c8ˋKi%Y8Ϫ8, $ޡ; =NVF+mC"A=F+k%Q P*J% `%LN:}zqq:owVջv>{\֭ﻯ'A 40))LrWn 2M. P¢;85U1֪bQT PJBDvfpmcJ Egf0 <bhA_z7I+ZG 1 3LF=Ze4@MiX J0„R%K0x9S@oϗ׀`.km׷<Z\\ N;n}ojz˖g_~_&&Zl -Q;v|/a>>zf~rO@Zj99<0Eq5}F1;'c5t =w'|3w&MTQQvJQL/|(!@hH)) Vʗ9e""_sU % +Y!8@`EfV髍K-:G`HZ }<̕mFE@ƍCÇ{j={v@lll Yj#;2 X6AEp"c]_j5p  B蹩Sl:rȎ;NoQCx c0MPJUjjgm_qשӧ>X~~~HHȦ[VX._z魹sǍ u֭9sCr8q…&_G4ZU'%b;H|yPS@#ۄ8cc !/Dvx5֋/ID@9Jz+vR.|QKw`-9ǎV{U]G)֨PLd!Xe)%@0Ƅ0-"YrDu/PXNLkZ_~Un $Ӊ򄂂Z~Sc$ajMR.L#*}m\p!L R@)&(cL9(/G*Eā*0h.Wn=*-߸iMٯ;n^tgovNΔzl.(((O }t:fݧ`Ah?rhŲlJlV&B*_<ԟ&.;%9lyv ڣ{7Vog0ԯ@rraHX\ZVA|JhƊ"qXRBJ⋐ PL Ci$G]:LbJ[;qjcX233 lp8_^{?!$;;[# F|Mb'BFRjۋ\n^oE%K2n Æ8pFNo0n>}x"&Wg0Մ@` >zkIO2J#ih(!)!YnG SBDI[%1 I!yXA[qQ~ 22@SPKb+1; iiz$gsrZGFRJZVNZĨvDFyfJɳf϶l:7ذa˗wiۏ={׮ٷwMg0{xOMMu˒9^ &,!ޑ֯_~:V)**R9GeO0Cxe^~iTWZ1駿DE$Ak7W$mt&B/RBVIղJd BPRe\(@ReqM9UH9'2D!.5<(rVi+X,t留력 áG/҈#mV$*: !ZSixD`EPB( @ !!@o{PҗN*pJ1H8N%wj](6[,%K2% P PlRbY{۬H:LzQBZ/@C(2.RB*ʄSR@ P@S UhLdrU`$ F-a[Ֆ Z^Q Dfq%Ymkp mP_skvq7mބDiczZT,IL0Vk(qa,E+7RJ (U$P2+SgTP~,  ]53[Dc`&$ zAo2 dd y-Bd\ksD0 p;Cz/R$Tc D1)D(M !L0$ݲLD"LL0.TU@S b"(zo0S Aa yYdl+R(# =mT:=)4S7EJ"P"ٍю%;]LqaXƔR'%vJDe^4Die҅6`6wZ`06EM%k9nInJh(RJH(͓EH(=,Ƅ8dF)Mi 2dAbAb@)/24nHpAҸ[+`0 Ns{IJBUpZd(RB DW2%$])|,RJ@KNdA0(piAjR)-q"ֱ-`0EMPJHq9(%)v5"x5LZM؁:r!$,Sx;%J%D II%Jj@+_+ `Tmh!b܅H,.5$!SR"sq|9Sꇩ&1@1}TR6$ j G A# @>q!4+`0 ?[U$<.:/EEJBI!&iDJ:P;WvDrY9T (8 fBe,`Lr)d*+0IT.\:`eCwJnNHt07`ŕg0 ɭ*6 q ga|Y9bF%|B8_LdIUB ) Pr*" LeOp |6+`57Rdm{[R$:@%% s 2|?@3Ȇ };****m`c$ q aE<//(:bF#PJ+"AMyG$9ӰQ3gfJMy>$$`ᢃƍ'LzfbqqqU}6V^Pr?nŋe,3նEL0@mQp IDATnQLj۩X,Js[,qÇ8hag@ZVEB'4LNbkUWEqON3]!Frqi:XViF#2)TeI^eС[.^صk'4!!aeׯ;vtbS$ n8d(;v 8KJJ̘$;ת jHrp nr!4jS >#G@$HHHxBqҟϛs=qDBBB|۶fv1Q֯ y`ȈHaEѲ,۬)S&_rǟ~ \j5xEEٯNL1 (~8M|N۳gϋ/<_K76mZU+W|QJ+r%iӦ~QܹoøW8rȤI~_}ՙ3`'O嗋k6G`02`6~凓ׅ0ՅGSUj jgm_qשӧ>؃v߯QիJx֭[עyܯkް~U<ߺM,Ν:;~l̘#F=ڥsӦկ޹Sǖ9b2ѪUM6uעEVZvm{W /?rTHHHV~۰qOrF;naʖ~ 'zrٳgk6H !99yEE8Es\6R 2LPPPPqWVffaaa``h,,, V߷~/Z;}mvY+<9V ή^z}hQQQ(ׯ_ߺu X'OWw yyykPnUoխWit4G35gkaa {'NIN.[޶]!CjCu޼J>uy\0ƫV,wٯ޳>aÆHQ}PþyDU,_^?`՟&ШaÜ3f}oꏵZ`2v녆*wl>ZWoLݺu;u>>>}ݽkWU]ҋ/_Nqe0nHÆ5nAGڵ[DddZH `‰4XZ99##)ZV^IO'-CbT;ыY"p#VؼyJ~vYgl6Nolذ;vGSհoޛ_ >3s<(|…8{:h;΄ݫi_~2dkf{{{__VՋey?x63q%cǎٻgq𠁽865jڬZwc  zk˖ bbNW<qpRzy4yM3ks_fMژMQQgGjf{l6 4 AT卵1N3`Uc{f3 %Q3LNOeV};l` (rV)UJb{~?mʏR+jlVk)PCnY+]t:avoSi/Znҳb v PJmϛ98kX7.Q\+.*}8..n߾?YS۶0 S$ na[Ֆ Z^Q Dfq%Ymkp mP_Y*y)Ua0]0E`0L|5X &Am z#PY %SKl"ˀ*X#mY H !1J+xdENV*L BV4kڵkۢysp[l!s缙ثUM^=n=qܚ+OesSZsN͚ޡNjj|/ QO]0Bk@C [U$pܘ19wΛ[7olbV5 :o[iuC #222\-7nzگvڦ_~ =P٭Cʄbq͚]t۩6mZgee@DD; Q Hꆄx{{O|fq~}\q\&F@AV5B^^1[^q\hh=VsmSzӎh,w_}M NpV[\OeQINN*ꀗ+h* *\Zt6q/b7Ȫ9&RK z#+=r Μ9O=5:00YzC=6>\ah 83LJؘWpdTSY1$%$M{Ųu`ܒILl̕+WPJNV^RMzfbb=tȐ'A ɹz.g~rnݺBϘAMf|к/>?`0x{{عkqFΜk2222=¼װa?XҊ׼EO~rƏKMM0qǒF Wndddzzt7ͧH0BHΝǎ}z!O{:6}wwZPP8tȐ3f7_ӷS>l %Iۆ˖r7G<1xqzPLп__EQ7ؘ3g@ӽ֜+W~dCýAwyoݧ_N{ᅌ%?3w>DQ5kdޣgY9qqq-[77'Zz\x1ᾏ>>Bf9ռyg@LL"͛Oӯ'Ok[?;}̞[}r:cɧ=2D̞ZXXhte!6-66̙3-x={L虘ҥKNSA))0n=VZ5ՙU1 pkc$11VX啖̤g_޸qcƎ ///AK/Ox V^sq(,,L: z]n5v˗8y\~=???؃ؘk~>y$͗eDITb ƞINVg_,ꛯ޳gZsW^Sؘ5?MXVBb8n_ N3IAxV}DQ?*pϘVիR7p( z}ΝO:_P 11$yWrS!1˖P+9筊WnHd:pࠧ)M222-V+qM6JyTTyZ+Kd rjvڡj`aҨ eo.$9b𢢢-[:ܩC[qc5͡ʲ,UN9uE>%7N͛7+7(%%9LG_NN.#BtMzj6 =W$6Dٳc_ǎń۶o뛛WWd<ԩӤI]jOVgXi}+ӕ^I~e^|^6mڴRi}{z6h~򕲭֜Wf $\bc?=Ю]ũf1(QB  .]TbjL̶z>{e ef7sJ5͕W|ttE 8q7TzSLƞ;wޓ+&:z_lʵ0F0Աcd$'(7mT;ř˃]BCvXQٛۢyM}b谜\6[XZ^91,6+zo:r^U4**9%Ec0ZoEQ:pb05p<(3 \ր=TV0Rp&N;yd0Ve0"֚[d/(֛&?/Ymye ,$ qOHbbbRϞU^v7oձCȈonݺ_~Xhh(zV[XXhw8Zn FٳnIaahyq;yʄF8a|:uʚU>zi[-^-..66veBŷi6駔j.rZ^= M Xq"&WqIIg6j5@KNwgF[pȑ5D3"rCF#!QAl6DPFNgXL"vE%DI*o":NV}T*wAAAE}||WNUT*Ng8OAaa5> N܍`x?JweKBقɍ1pN$ɒ=āX}V\}JB5G;`$ ƝYfСCHȄOSY3UΝkSi.JQ. XP'0pwZ@钓SA)UVyw"gB }9Ϊ$$IRůI,!T ϝqS D11֪bQT PJBDvfpmcJ YN1nxVwvWYڶ`HDHSGoҤI\\d\gxW#V??nݻ?TRY.tUL;v1>>><<]ǟ6oo` "65Tڶe0w@ ,y xyEpk4Qļ},Z2@ <#Ϝiبљ3I3^y&V<_W .:zJ; %((HZb0(/^X1c~Zm[ [Hd߯\oԬ:az^OΒH^̟82/>|\[]6'VEdt2 ($ߍ3Uv!4UMVZaС[.^صk'4!!aeׯ;vtbۿrֆ`@H2];bQLJJ:wɓ'8({ZjNY@Z?ШO-s%UBB;7ntJ̙#.Z}{.TB]h /ڷ-[֯ 9rȑ9s=it; s۷Ĭ^S|_9'o޼CǎJZ0#g6˥#"C @RZ-pA6AAA쯸,???$$d-+WHOOT‹/ܹƍ%xO5ǧ˃\dY?o^JJ273f/rO>9RZ6Ndd _9ԩZgܳ\pѣn<僟xbĉOx* IDAT/"a0w@ zVf+e"{j^ #H&T̑q\``h,,, V֯_Weh4֯U``_%t:udggǷ&QQÇS{Vyy}LJJ>|AYE2u괧FJMMEØ"a0waC?!$f3jce:>;tuCð0 An$\1)Sw…|ȕƤUTq͛+m6[ ⴩SZ_}}qeĻqsT+W(P(*Fx CfVM_@aZ/\8,gff^rX w H @ѣm˲+fYVk4 |g?R67l-,,p|)$ն]!CjCu޼J>uy_bHRJϟ?|Y#IҬٯ޳>aÆHEEQՕi4Z=2?yè-5l;cASJ,YUZy2#&S1!VK)EEEEEE.LU/7 ܢ%@B7laÇ8HN7 nr@>}oe4eٲ$=X &_J/MX_Zbʼn{, hذQbbbƍs gZ秞~,# ;f=JL[߳i(xä}Ï5,˚&׮ `cdĉaaY5k~C׷lZMQk^~ VӾU'SNa]ҀA"Kr;,֛N.`0crKFn/O*|Kttt9Eh$I*JtN|poFRSQϱ.KeP b8ivz3jB( m2[w9rv|FPT^ݲi'unOA~$ڷzmMڭu˷l-WOrzZŮvګ32 Ok;omԨa S&?3Ǧ6KJJ*;Աc{t!yyyC yݷ\.Zq%4j]Y_ Bū ڵ"HmpB9MH!w`c| :ux{y7i@23kH-fee7j-ec\Ppٺ,NP|Ϟ9yTrrr=*GCx{7z)k%uƬ3bCg0wf͚m۶(H6nTΏtt_znE@@ OS*deejj yz]|`0pDTy=* ?ٻ(ήwVvKػXW,Q"h h$jhDƘ,(6l`$`Ac.l1! 1w8y晙;>>S )Gw}oVqYګ湻?xE_$8+.*"W(Xz|Y]\]\hZRlH2sve2yJJ}m\\\Ə-oNzbhڬ)eխT*e2Y1<ϑB!z-EۯIڷog?Uv*^jҖ|_8dBtOFI^rB/ ܾkҖJHt7󶟿_ݺAf$ZNE |Wm^zVmgͪli@@L&zjՆP vsulXX˗γP%OL&>?gq[f@ѣAA]v/J7 o v̬M_3|0SzEPX-={tDڶ 4hР\Ɨo_>uWԈ!!=UAe?qb! ={spzI woѼ0 3p` bCd!ޕY(FA^nn>,=j6iٻk^6$cnޡ/-%机ud6tҶvPYfRǻW(S!22rcǍ0BADO^jի&Lpd)ӦkX⒒ڵߏ|6;~<9;wyfZ,wf^0A<HyƥKݝ`ZOLq/{ <(~ǎ/ߒnJYj4;豿ǟeKH%Ͼ}NP>RNu߯1JOC_$ C?t('@Y˖-L{F[b圸c4L&[ǔ,]yI-[_y'IfBzx Y&H9b==\e2)As@%7s%_urR <'!< b<8i(R/)y|ju(d2A*/fʔΝ;oݺIEj޼F3>$BDDƍyM69$6"~k4}Ijj> \]]X;;\\\/.h4>{qqX̲Ppsu=L(WWWX%Z\\T@9NNN<ϗ>\.iZWANWۯ?k1-SxVYT!W@S#A 8¢;%{4H>nWhh rwwgYv֭CiӺw߭Zp_|QXXسGK>sz?WLI}}+W̛7? S ľ^n۴qrR&M|п5 ȤOO#mƛo֙:udgg;.v2BU-88d?Yz͚NzOtO_VLTsT|_'V+@QQQ?vˋ PVIpWPPPq::T@9tL&StxjuRd+43RF)R/ Hm|&mԾ}A¯7֭[⟛[3$4tƎ ܹK]HB/>^`RK J98iJ\a-7<W%H&nqܻ3tٛxرG\úZj>?Ks=;ET_~ŢmΝ;oo ĉƾ>&--ܹÆyYmRCB/'ծIW*T~~.NJ%+pŧ sd4J<ۻj&3{%zGqqq1 8*TUxyzPvqns\hכ\(EYc͖8I%R5YoxΟ(V[jEe6B=W0#AU;JEQ|岯T"Ҹ2is>4<xAy˵tY奧ggej *j 0#AU;Ju]RiÆ kV-6itQ*d C[Vtn~fvNW_RR0LVV}JЋ 3PɱX,bFRZZZ\\ҥK ^PPxݫW޹s @ŢL&Hf$=`*3Pya()))(( I'S ei8A$ A999fY*RUɑ!G)9Gոgf$CL&?LA]zDgr,ŃƋϚGR~Oej~fUW^y|=Q#:׬i߹}}g'۶iݯoK V=B!zdjLLΝ+SKVzZQ՘ozb''J}ꓕԪU];FF֭[78K!BUZzmr}3*/AHV(VZh4VՅkfMO:=ۖl6o$HjIrXUU}ظ'N>+!BϷ*26uJLҾĭnJڗعS'{yW_ݝswͿ"֪Ukw5i_7g<'$Iۻ{+ӧw'Sv^8wN\dd,Nڷ7[7ZE_Oܳ+~I˽A2lN'ؼicCŋ zTqFgޞ¯ޚYӦԥ۞}@I>5G~;u=[tx_zMѣ7rg|cBBBgΘgZٵ{wrkD=$BMxc|@zwM,^$H$$y/'#IB*u΅0ӯo_Zw7ȤR|T<23rrsυZ-qgFkVm ؾcDXځ7|Sr>>>7oA\_$IfZyiZ&d2D"޹sf5)';;/^U=Y Av{?77WD"QTϓ$9w*@Tvi򔩹oW,С}tn  }IN`4O1qy$xTwfڗse˥/=L&˲ 4MӴ= ;}t (**""??̙3NNR -2z(z15m$ñcG@oTq6IMMM׋*bIӕ+WT Ci=\]]&'''왒4Mۓ6I..:]QKhVT~՘?k1XťYZno۰VVT%o\F7,JBguh~zKk!BQ_R)̘A;VsT\PXX`:6zV#UY<eL&StxjuMGeYLGпBhЛ-Bm2YRhPW`6t<x+G*B۶ڵ[@@@ŕwꫯ>DEh4O}9Bωz0K`aCѱN{qܥ;/{4IO2JyOO&̸]j46+f;u*itx&=f(IT7gμqވ IDAT۷7n2jȴ?U^;w@҃!TM6.]˫%=?(Gj 0+32686`Fv&l&Rސfپoxd&ISA;͘1#fӧO%RԾJC}l$əf,!|(R(яM}ʚ77%aa%r9QQY͕޾M^ov.UkBRD3R)MAS$RTTJR&1 C$0 3#K.=fdJjz`޼SN(5ͯ[>Mk?o_B® MHաC'S6m {&SaO'Lj73w-oIJlzMCF@\4uVrvÌ!T l6{fX,EhSU]vnݺիV=Eiir//Ba>roݺp?BrjODjإK3V,T*Nd11n.UY0#A$Ν;GӴ , F#v횸"q] 諯VXT*صBCC͛O3<=={ʝ;wz֭[N|cshZՕJXZup jgFF}ԈJ"B+JZgX JRJ2??_VWfkQQ˗{%ܾ}2pYf&&&V&Nt_ #0``e#<]h˓ݹTjR7ka B&XiV(nnnNNNyyy*LJyEZQ=+ŋ.]VXPe˯ ݻw7o5<Ϗ=kVbRYR\*o~&cvjԨ1cv3gN߾}ij/h45k0iRi˖z??؀ B&,խ[GG sww?h<bX,6׏O>rdio9آ"RQRO:XwIX,ǎQ~kA֮~osssL^b FRԆ ?v޽/~geeeeenݗ_.1bxu}3(fL:veY3\ E̐ՁT*']EHTRVAZnnn zF8 (^/jlX,4MWfy\V h,tPF\.JG4ZXX\-$Pբi"ZXU*< jA4ML&1ېH$*(RAӴdllf2}+yl6SBe+Py8j;HB5A0 AFl6 `2l6{j V+EQ !TC~Ma뇕- ~5mZ;oxz `Xz=˲Eݾ}۾1fj&l6 2{O"^OLYfu``K3ߜNNNK"UYAy^6޽+*WkjYYYA,,--uxc2B={G~f)Jc}ܥ[vvη+YpQ׈ƽ5k8~mr$Jխ{]#lV۴iS%§kN߾;;g:CZ6v[NNN<ϗ\.4].W#IY+t=h=@Y›EJ'J$cN#+/2j W'Z:TY%0/AΑ; PXXԗ[,5OUխOCW|y^G#\)ba@9Y`) e exi1K1R 5y6k4,6PCnCi 9:B/>\!TܥlFT9 X+zA@.r 89PG*U֒\尿OB53P#BMtpWRY8HTih6f- Cdmj[TTZ̹aŮLCFJeJJ!T3B8+$ VDiZ x֔Mcc#NyNyr&EGdrHB) X%%?fڵ4LFF@ ԰V\ެY3Op۷o?Zppw􂂂g|=u\l,veG BF$,@FSDQ4VR JV2NV6H$ HF9s7n߾ָqQ#G`۷BC,X7 'EZ &,GG B`ݼHJXsr^k׎8BP(xnk[U7@<~I͘1#fӧO%RQ֬YfjX۳ήDNӴD"ypJ2 qQT&e4"*y^ d\8| 7"Bff37mذ!Tl,j?sfߥK?z N8Qj0:痸wn8qHbb|{:b:u[Mӿn5whРɔW]=f-__}&O9|$#mQV-N۶mOؕ|X>}y0o;zx^BڜJ=~#0wOω>|Xbbbm/\ذ!TCX8pwue/?ș&x@F"aH {m<==&'?x*77>OF0qA$IHR!M A]\۶iM䒯N8?-|^ziO?;w.33fw}w&M|qm~Xoڰ^>l11}qb B& tyZmV[PTdHR1lnP&yfV,GYѯ)Z yyy'~zcǏ1a$$_xaK{n qcGk;feeX,ǏKH~9XzzztS-9s9v|+ jIp$Ay>GwrrH$Q7o261BPf*8 p6!#}+cccJXaŊ ֭]k߯ʍ\ϿX)h4qbyvV}G;wT)9PIIIF5gY6;;͛ߍ B&<<@ǘqſU"H"ʥ~ ܛk󘑭EEE/_իK@AA@}*A۶m׿[gd<&ϓeZb<==˞}eE[;'zN 6L80*AM2I&h4-k#o^blG.^h7FcAG1c]>;wү.^^NvV07+~CCCCz!dJ9^ppHϞ=CBC:nΝ rlTF G/;w`V^k$L&d7Ke\xgη!sp= @?nd+$92}7ߜ~llQQR()'H 3eamΝ;Ϛ-]ڵ,kەXNO͝1}}Qܜ9`2 b6A&?qaCٳc"B7FWV\!_~^t-敲%A4X{ey q_4}_ k+ɡAyK /9t,2RrZ6 F)ވaBQ\\\AlxB)!/u j`#c0g#?2A(p! ҏ0L&#lOG@q\-BJ`Fv mJ•bqxrem63@tSkƍ/!T*[e#R}qJT BʕR)e wt B&XaMREK ZqPe-6EVbe[Ď<{6f$@wtE&rK!4-B j}8HDž;p4B9f$!r!{\>ҰaZj-iܸW%cKܷ? IDPp0aaaHB5yd2Fbc9R9lָ|`L<$39s'~dܹ?mo*[Zh 'EZ &,GG Bݛ[&8xONmNؓ!An*}b+ٛشYGz{d>dJjҁ;^z%ZPpI|Xbbbm/\ذ!T+_uEZ#8+x: d DFF 5%:8pDF&o?V.Wij; BJ"̟`ԩW^Y ӡ};4d+ڥlZÇ-^HT~*T"^h$%\ymi%$S$ջwӧϘ>]Vر3{ݻv=WPȸ6~u?7[?m`/6|䘘njr劣b6Pj/h<_=4tKd2f@ƍVő ܥGVn<` J]v۶m+tyݺbڵkgߋ{͚& 6oIJl˖-녅}r%Ɵ~ = v ;h.\8ߦMݻwK.l_%B*===:zԩΜ9._쨨HB5@ܪ" k@Wd=6z^b%;{mvl^vd떭ƴnݺ%zdwwf͚ᑓ-V(,,฿AsWnN077ýXחyz^ܹs|{!˲k%%%ߟe7o86*HBye 5 v{wy+pNAz~ Sl-((HN>ҫWf͛^j=R|Tj-^B'''T*>Q*$9eJ=Yq1 ˏ:l ׯ )TZ:mTqLwj⨑# <XyJ)^/ymHs'MN ңgZߨM_mZ3 -Ϟ;S żRdV7_+5YMfR)-.*5O"}~~IOT$L^AR!IH(O={jၤ*;Yʑ4KJʕ ͚͝AZ-aNR%,ץ:Fv 7nd=_2O;Oe̝0;/5{9~A֯ujZRYI ,H:TL IDAT\Wr&SْׯkZav?ox0wAUf$j'Ը8;l6R_]"arI@O Aܜ _WOZ0jY*3a:tjje'<0@պ-?f$'/j7'M_+Wкa Is ۼ$f0u}A#=gaaa#' s^o_!0#AU; 77|U,b:"OGx8.//Xu x0#AU䣇JAS W)KAZmz^| ݟg<(B5!B B!3B9f$!raח رSl+V  2Ͽe/$͙3?fm۾~3~ O_*J0 IѫVZzՄ磙HB5'9ܣw$@jsٶuW ># {׮,k@TZH, Ôk}رӔSG*((([>jԨ!C92-OaY$rh|0 Je4yLD"!Il6-$BRzAH9kVJI1aJNNNNN.[Y.[V}ˢiZ"-J$IL&@=#7o@Ç q/ dff9szӦM 3P1껿D"'2*jiгW/>1r+4x޼'ܾ}l9AcǍ_|=_+ߏ}{<ǾoߡiŊ嫾rLy۷yŋNqq1㍉'QE!/Xh~ݲaC@xx}Zdn޼p]noۣFd&++kꔘLOOE 3aC#C/SNf5kV 1GOz*Gņ6率ywv֭[32v>h F/={bqWо]7㊕drzDTԬ3۵m3f3h4O1]RmӺMVV]ƨQ͚=nj  о]NNERݗ.?kӺU.[n-vWP͵m֭Z9aD>|DNnNmڴn5n똎ed\?nIF,[>l11c_sGwHB5a~;9h+ٶu۵k_/Y74x߶@Νڷwww'J>wg.--mSN*hvm޽׬Y-v|l޼eٖ-[HuEEEСCk׮[3۴m=zؾW@~~  ]7ot:ݏ?ӧ qcGkk-{AQԝ;w*& ,===:zԩΜ9;{mB5j!!(ϯ;=¦L 4Mh }|uU\\\^^?oL9yܪ Btɱ{˼˲EUP@ݻiiyʼw0r=yR4&ĉ}weKnZOIIIF5gY6;;͛QX@aAAzZ/˅Fmtz`Vo{irϏjxhN]7冩yzj*ʅ//wNNvOsV~&qqqAc^labb✸oq)'SR۵k_/YR_pMxc´iSn2/<|$C'N vܹsǎ;I>| k~r巻v/3O_IO:}O6T𸎝:8pȑtq ~ c_vaC,Tب*&5 B"<<= Z+a3fyH}7]S{|:eqHأG>6ffsI/`ReRiQQQٙrf߭LRݜar\* 77#yD"qqq)..~#C9q]*HB5f}pᣖ>mlL/Vw6X$ۺ[ӧT=YKJL&ufl.Wh9d2=%FrKWj>P^s$ٙa{wf u۹c˭v76sIu0!B B!3B9f$!rl߶fܡcE֨Q#R@0#Aռ˗/sbAQ4 BgRtL&N2!$I$ n릭FD"JdR vo688XRW^iDW^i~~~m۶uss+WުUƍFj4'z(Bϛ`7W7a f$A@S40C x6HPH2i? >bT*! "mժ-JuGϞ+no-lܸɪի̝+iI +ADO^jի&Lp!TS8^*6 hZ0T&wH1D>a(zT*3MU*dLgDF]WuPvv'GG?& j>'5"*y^ d\8| 7"Bff37mذ!TChiaT&ɤ2DB4#CA F(84jcO$ۗ+((H,oӦ;IGp_e/ߠȸj۴m+d]$HWس71<< ~<9F,3w-M6'wg ͛7~c{_BUT1sA9qqÇKLLlӶ  jI <'JIJl#a~aro23vT bA("+=eŋ GM0fk4.3'nrD⠠+VΉx`m[> #N:/)WH$$Eq[>ѽodXV\e붴?i~w̟?isB227vO6ˇ >9&1\ذ!TCHiTzoeHiJh)|Hd>>СCo㢨?gg]FQ SQJ(尼T4L43J#-5TP TRxg>}<;w;|qqqQQæ͛. yza>ܫW/ ">|+|,ʽ{/_lWaa999Mi&&&Ks1Gy v%%%O6CƐYƏKNN6TU9@  jPdD,KeHDf/ pjѢ_,Rm @ќ9&&&+M&]p᭷EEm\L̛\jٿi~u,;s7{G\\.OIMD...*ǩن eYev[7 ĿJx#R5D`H$W<ǩDt6Ny6HHHHHHp/@ hܸqc'@7<oI1  ˲]t޽D"P^\xz+{9)v.8@<#B .rȐ!2 K*Gagpe!XZZ5J"ײ#K3Β-71Dbgߜ!Ǭf#ԡۛ"$e #%%%]9dslӜZ,;[,+;%$J-I.]4kJJJqDW!f2c"r2QX޴mٹ֫hݭE"QV ]  @ ޽;JJSh6^ߩ@g"qqqyﵞ=XV09P?nɓFm2u1o޼iڐH@)ȈWXr ;d*֗Ԗ;vRÖ}>w;@=$֞uHGu9 `BP h[b3?$Mqtj윛yv=33+44~b쏲2 [ C\QB@D[KsKm B8"icmroDDǏD ϽADIJc""3ROݞv1˟,ki"G :&[kj.ִ1 irQQ)':;;:}]6beقkgJzX`DfƜ:>Hf%E__8F_gqQO5#9ѧ;QYYY'ZiZD*glmiAOw+s^jx`e+U9lY? f>mRGy}fgm97Y&4OeM/fDF5Y|juZZڋ@]@"PqtQSjDDDDDεnOT*O8W|nΝ(11q߾5z`dǏ']O{WH$Pz2wedD2`@"ڽk6tyڇLLL4/ H<\C"C"xEo߾G #xEMHccc ]Hk۶˲f^^^͚5{wޣqswDZ2t-DH$P w߿w߿;b (H^p07mڴy'"\?v62R2tذr݌KJJ5,+51)5/MMMKJJjq ÈŒJ$Rq\m@] ֭=󼏏Ϟ=?|hǍݶ}GtΝv)S͛7 UK[j,33şL 3^Ya88t0"J}=z0))js\H۾ Zzk׈…bNhl߶յifDqnninncFPO$%%O6CƐYƏL H: /{y""yxxt!?BtqVZݾuLM*2͆ZlT*"޼P*r3f ))@gL\.OIMD...*ǩن /aMjVuHRbH*6kTPmllgR=2tذ:~qq[XXyE]5lgge300h@~ӷ3 `pYa#y߱cGVV[zzB"D vmz7[sN: Xuiq;w4qiҩS'H#}$WB 4Uel߱kA# P;v `ǝ.*H$ F5X7u䛺/[jY֭Z J24YQuX׾}{XCBu$ GAa5^'Ld*@"m۶m۶mqvvnRߗ{ΛUt033!C{D"yk޼C sswDZ2t-DH$ F"!3CfS͵->>OX!;w.b^ye{[lyAFyyy͝;oɒ/v7|AU0LM6m޼i1Mu$ I=xzH]\{/7*133+,,5Ȉׯ-Q(YU>fسg#??_R(r=V*-((ж0 cjfVTXqEEEEEEbllT*ju666VJF ]`PPn(}||{5Hm#h vvS-b[Lh7jŖ6;95xzשg=3h "84lO؂O"FwQ3+Vl;nDu붳Q/n[kkk"rrr:zX}_ݻw;@`Pn#q}R*+e/Xs#b㼼(0((*:_/&L:m5xzz?N8o|e5^|7qTl\ڵ4<}t``O>aa'Nxˆ s$ ą{ټyZS.Ͽp*dӧOgyQ~^BHOOq~cϝѣ[v$|sǎ?njz&DE>׍#` W\]r^vm萷'M/.\I`ii9z̘=wh}ԩ|͚Rݑ{z#55ld$㎀m[ÇOӣǞIȘ1}}`QZZk+Vi~5&&w]嗚Μ93wb/\м9c+y]~FXUo^OOϯ:8xڵ͞UYyM6l6??e3D۶1Pbl`AeggϘ>=<| q]P!&M #G9;9*ƣu{t)..N?@}g w9=cFEE>,;+x:^=a:O aYZwE,,, EUD,rS,ODzBQZXXfii0Lnnnk{y$/ WUݧ6vvT4vvEEŕ=WqÇNOXxd>LV<Q~~"R(YYYO_y}z/Y,GVM\ܚ7ݼuB7q 6P\"((w^׽xcȐ!?7giӦOݺu[u/DaBkbsrssd9|;bLMM}ͪz? ϻŲ}h1Gu./2ZRY %K233ǎP(I&7m޽{u9;;Y?31EzS~G,}`'/ _zl۱o={ha HJKK>ĤTP(EEEaRnKmA"zH,^reIiɼyU*U}:w֠A8BD߾}{n"\nƍ###Py|}KW/]V>&g'_9!M!"59c¸1~(eFFkGE#!3rrrzxv6JӞX,9Pٲ'<?ba*UYaQqe)ߩSF"J,^Ujueڴnx9sHb"266^nݩӧkMTJfMoݺE_|yQa—hCɭ[]V8HV-ܩ +:}f]Jo7NCDB!;d[LyֲekVL&0ntcgwFrzzz߄Sd99 0M.L2iӦڗboK5-RTr̘1bSN%/Sy!xl'^ha:vԴy&&yyzO osƒi ×~U˿ܻo)Ϸj^P_7—~UmOT2Cf:r쫥wm"`{/,o<C)JAŜڤɺ5R7}Rxn_gQцT*u8rzy;6.&h"7ǵ+Kw5|<0|Ma, jxRX,Ӿ#˲E>Ԥ2=<8yOC s$P^ay>77W_oVcW$jծն<趨jJZu$zr4HH@0+P= z@0ER!$s ݿRH PG"r;[[+Wih᙭P8kצЅIAaѵ7a{ywffn B._| 84OQ#=xUOXGDDDDDDDD RIENDB`RaySession-0.12.2/manual/en/images/add_application_filter.png000066400000000000000000000114721417052567600242270ustar00rootroot00000000000000PNG  IHDRgo pHYs+IDATxy\ILrj*(WvѲɢlK{kUZwqྰ#k@P@hʢ`D B(,cc"0d83_fL!7L 1b 5@j,cfcmER2 X,eSʪicKsll++㋲g(4" &ub 5@j F`aNW@{uޭ+/uRjبd4P:C(zz?RjH 1b 5@j wy2 bmMưaoFDGoJ#`0ojYX|Ԅ/vtp016D;:9WpjGĤ'NJrL>x^&5T*2tzwwt;Nx}Pk8~w7P7WVv!ssGΥ&.'HQ뼽wc 屲o i ӐnaZYY}M/9yxeee+B,۲u[Xr駋DñeCcА+ǎȑ#mmm=Ȩlʔ)r{>cVH#pqPL|B"e E"QXHEr8\.6 V|E|`AJwyq\s33qMMMUUuHpa!:nhh?!KͳfU$B(r{;9Yi)VcF6 [iS*vH"Yٍ^v8ڵkoR#C[[[CD?`p8\Xc.rc|ohkkbgCڔ0"@j R@ NSGܜm(y{־YqnC)5bݾm(H 1b 5@j! R@ to(PaZ&{4mgIB r%q;/ Iަ%}`?g(@ sTB]7s`LA.8/[{dՌBDdgg`0$5 CRBB޽JIF%d SV^f?w]I5*ƽPPS[M0H bLλqHPȧMMbJJjS@_1/†?o5suoiTjLA CS&gH$ rv|Kw^PSܵ[5:@8)H"455eڵBxooo/Çy"[d2J*BbuFϒb_NbfN͝' B EuN //7nrد@u(ʾ=ysI 񖖣#F*_x!}:w7P7WVvIN)ɉҊ /XWf2I ӧ[p>ѸC~_(ױ'LMM|ɴD"5()W*(0mT]|qtu=~XP@gY.no߹x"}>xwӦoVnbR2+7c۷mݹs,W/9v٧! 9O}x_Ff9> L BBCCLLL/C~4I)z_핖adW@BCK\;!TYY/ gϚп,,Y B|:PڻӦg{ؼy !w!zZKK*7d ʕEEkY#>_!)!qW#33==BT*uƌ,k\օy D'$y<ޘ1cZKP!d`hKn5=,>mj7,>twwgegxUnv!lغ}GJRPjjCqG,gLrq񥨵ߌ=zرׯ1X&nX(I$]/WXfCPmmFFEc?HNNu#[CK-olݶ#Tp_x"p@ xrQ r<}=edrC:::Bt:sl?yR!.knf[ZZN< ~_~IDxX+ŋޜ`W _ŷ!4ct RUHFF9>L&ڵAj9,)!#陙xX,\zӊ.\,8bYXHO[*uժ]q.[ ))'OJOD26nDN0'ljY闊 /]\<"r՚LT޿ИzI/;Np5us/#߱/#׭'R. f{ ">300p8H`起sz.^g檮 A&tub7oñ_֟ɳ!r v@Jnalv[t3gs0}R~ l p Ѵ7$h'kɯ״/WDz{+WK32ΡTRA򛢗BBV&#2yTEĊ}A 5|$ ngrAa xcb 5@j R@ H 1br ǰa,4eٳѣ"PR*#`«ׯ$_XPU.8Cr2MR33k}S*kgʫoC}CtyV6[!#T Eջں7,-ihh88{g_gN>31P=͚WK[̈́ T5(5x]U_`u9Y̟&"$(h̙-##Lh%zzzt@mhT* /0J|7&H:\Lԡ"%5w;u];sr$Ui555_x/>|!(]F P'KMN?Sp>wo 籒lԔ Ƨ$岲eE7n04E͚93+\ZJR Pಥ?m(%۷m%ܙ~7ʔѕ}q@ ?F"ΛKK7o/BhƷVFRӳ!TV^ `d2RRS32 ^sG=Wbkk.YՑ^?Aj5f2|bťu=]]=]݊+"B'NꑱϽ<=  & Ìh4Z{{ɭ[oݾ~iqtmb9ƌ!YԦkKW?zDP̘Nt/,ſ]RFð۶8H%PXDB$!H,Bmgnc+mێJK ͘L뿒OU|xyEEX 380ɱ`XXdiiy4.hҲаuo?;o^XHȖmkj2ӻx[oK)-^cn+OJJ޻':=-O/et/E"QQQwo<%%%u XP룢6C?W>*}K}S.F*JRe dzn$󪫫+d&LϥxxzIf.D"s\|UZ2@WЇF?~|}}}Md"!ճP(liiQYdIu^9NyАDBH, $ ѣ.gC}C챣b*lW^ܠ7YAj9DBal\7Uqףǎ'$&(C 5|Pݭω(?PPp a 5@j F65 2ddl㽺Ws($ښF|`A몼_({X,5Ȁy 1b 5?<:=ŊIENDB`RaySession-0.12.2/manual/en/images/add_application_infos.png000066400000000000000000000362001417052567600240540ustar00rootroot00000000000000PNG  IHDRep pHYs+ IDATxwx3}7dS $! 􄒠RDĎ'+.]zAA%@Bz6=;L.i {>fvΝ-߽\Ut`1ĆcyS1Q[G2 UXcST\|1"Jy٪U̬co:ȑP?b29,c233M}`)yS1cL) ƘR u`)yۧէk8WO*!QRV1v1 ܾ[z5lMcՐyaU!"4X/6|1VidP T> XE5X^jI'U)Z4X^$7 V @Fs Ղ8ȗ5^ :C[?!U?>Pg *Blo hJjHnBDh&$Bjn4"%(cUEa&Doάh* 2zWVy! fH@&@DHM Bd3kv^ 5E!"JZ_t1`yMIE"X DbLxهObijQu\Oe?F M& HDuFH/SXE}uWz兗J+ @hf0 HH@Da:Vq V64'9)Cȸzy1įV1"P#((Al5Azh Wzo+oWQԵ}_:^PjREID: ;h&1"zrt!C4WpJU4 h"R,HrX@D Bk$ AOԐ$J-[f:ڷ+o#U*:W]-h#T% I@"  PB֐"Hqe^z2 BP60_jѣPFC`4ڧM9u-5M:Φv{"))B1l$oN$"ABL-y! Q+i#W@,껞7͚ѷ|قIoo1P||NhhazNWlzݩz5Y^@[j"$@@@$|{ "!)b0=1Sƍ6GhhN]Es>) "" DAB yFD@$ELH=QGVSȞe/~F/bYfV+3-9.%o^zh3E5QqS9,HBU7Z+ A8qb0Tkޛ7JKs(-lLKv=^5G+$!H$j$ ϳA>/C"P I !dg;-\sgΘgfʺ$HLoҒ 7އ@aA @D&h4-Q 8إD)+&FVFr~KR_yaUڐHM*?âwe@DaH@X$ !JqZ흨&h jj0\Pb @++[hHw9ʋD!TDɿ+CA>*"IByXpAXD!Jj!%+6ƴiS/]2@ookddMV]6QÚf YJ%^&M⥟U/yTkc&"  (T>`!rC>@B$UuHzhaX-V[`SUk/~cƵxw7n6#$T.I5@eQHB,?MK 8(?7$$䳹 Hպej:&!rLfZyyhh>>>ڶ-++ݼe$IFcf/'NT-`0oۇX~@EDb9}tnn$::J;v8&&ZFEEHMK}uQLM5Md۱.p.طߧO/nTjuiCuzCL^*uP~B>C@ %BI(!HHUBIQ0N'CKN,yMyq} :d7VV\n=zvf]TTYT^^|9*y.5g&>|lRݦ=ʕ{_{uFppw}7^IlQo{ƌcn%%0;*-/-u^ v]Py! ˇH#̀$ " $r1KxaA%I>y41sXgyײeԴw}/1apΝW;-[J_۶mokFD6sVuӦGuܹ}v}摷/Z??ۭ:pCNvTR*8ޗW9Gh4j 4$yϪ8 @LNEë( ɿd%jʊÝRPMdHNe˗]~DrR2۽BVVo/,,C3tO>ܩ樑#Zڵ&O }_~ӜVݸ񗧞L| kU?!R Uq(LI ]J@G1$ IeRŘ($DmRꪓ= {i0|Pѣr*9, 22)ڵ˽f\l,lڼYu)ϼ 8,XU-JEHZITg|WwIEv!1 Ĭq\# HB QB :$e" GU.IM\Nk00jHnݺn߾C3nwe0 ߣsa{kBXn]2 cϳW&cAQPI 0,?S J/-wEM%.g˥#(r9A³e%ENg DREXʇT" Wi7JsHWvx3gKu$w^x?6ͽ꾝^ҤI  ],/Y aޤ$y."I*rNION%D z/U#TP t%j픎h/""۴+,,|7/|={S݇p}|}}rrrZmnp߻sΝ:HNZbeYYjML w,Zb% 2N'eM^-@"ՙ@ |GY$Q oɅRHژ[oQy^Y ]'@RF&ƍzZwXٳgsC>dmN6oΜ#GDDۚ7M7xтSQQ}||;f:رcGrѷպ( (aUݼY[m"6{i $t(I^*RP$D$A\+aQ61|AT`$3`ɒ/^>rM螽{}}}zn0~]EEE?-[wf6׭0 >˲ڷm={V^}ٕgZEqѱC{~B@β9YSr7X䜏{[Wr[3zLDu尨?"F!J*E 1J1VhȐjh4䔔TKEby(Ưk׮{?" !!0y OAX\DD#DbYP~FDIPqED\eC倨TAReeW{"[GWu:B2@Ae($ICM ,IS"A.JYJa!+崋vUՍcWB`""FrXaJaQ&DH.@"I"D*~B"!!Br:AX{X(P@Թτg]+ʋ.ZH6W)XDNCrBU!,)|D>@D@WIQ7,dQZ9(a~]~^hzĖzsTt<-H$'"_\K$ *T}BjX|kIݜ!E/([Tb!]rK$є?0P" ""@ g1#[Մ%@@ C]`]f^EU(Ro&?sJ\@$D %IJHH|E9*BDY>>R ѹg\f^5ZD@3$,t:@*p9BD ].r":H.

)-"RgD$yJeDD(*RApz,"c TL @@i ,HUO9@MԁOb\Gt&j ""b,@J +έ,ل9 OłX**}U$#M"~H(Bo8 HFV@.6C:SE>!t y" eJXS2D\ Ϡ I瀊DφKZ P AP D. JI%w-+Y@H ,%h4 &)TP1DΥƫ#4.!/ fAi $y]gH*^7: U:|%l $ 9@A9"7!H從gS Tut q( &atYzPr K%fR!5u"U^s8KkG>+J$++=*;#WLT!S%dVD+ $h4j^6wjnb0V7ptCq^Ÿ rU  @Kh2ߡ(/ EHUq[1cL) ƘR18/cJq^0Ɣ`)yS1cL) ƘR18/cJq^0Ɣ`)yS1%E6q=zt޽[mM&S_JL|%%l"a𠺪ODQ\p~pppn<6;︽޽ziWOz'd2{Kȋw~k̃{/OiݚU;wjAyuOs%t)((T-[&ڵm]ע{ngϝUmr[ZmڤrեK ""Ji^4 ZИqÒwܕ4|b-///JDjڪk `XnFQCBzݱkV5rSF-_q1Ymڵk7qSl={;b>8fljjZ޸~wޭhQ>wggG򫻴W^ƌ_PP oرZ,Ǐ3n|ii)>z=EO#<}ٿ???Dz)S`K/wqqcN+~3xnE%Vw[hhڇǏKNRG҈b<a+?ѣoZ~_o X-իV JH/ 6uJDDZom6GhK.h4ߍ#U*|~m7JMK]tڵ˂`곓 K?ppqQ-F#G&NWC{XXػG 0dXΝmdd+tM#Fq }7 1o!=Нw~࡚&.&&fU Cvx9nݺ#ٳgOڽ;0}wܹav{WgN2hp׷]&bcc7mޜ84!qh˖-țotwӜ \(Ƿiժwo^O'yeƫIM93vC%sC$_3_ ~?djZڷСC Kr8>m۴ С /o Mɓ'iΝ:@||cmǵmѣ#GoÒ'ٷo_|8e}Cff)S'*;wQCzGg ?2<ƞutAAA\\?o{7Jm r@\\\FFF~~h6m<`ARRRJJJ0†'ط (*..,,|w\.8<O?/> ۴y +VVVv?YRՎ]r۞|QǎyhS222`p  3^}p@iiw @zzV jT\\\RR&O3;''55 bc(\;>jؘgŻv^b\xb׭[/j[GFϼ>6.M*ҬY3SQS&)(('+;z>!qhaa!ȍؘUVY>uӦ{T<{ZZz7222'p8G!aa*ĉ0D޵-[><~(5.S**u=3?7u޽[Oyvǻ\aCx"ڳwBFs}Ϟ}{ͶuV]b~h4]ٟLlVq/4]{oSӅ_5qRRR|Y3O?qQ%zy?Qi!!!dJJvmEQt``L_(3f^^C7x1F,(r;~ң-]}zOD?ط}ǎHw\_ek\\ܱc禎+444T C+ayիW{nNsC?y$I}oG;m׶?vwdddb!M\ܩSw_o4V]S9QQ1L;dl jZ0Lmۼѿ jY~}z DEll쑣G/5kY{ԮݺʣjYfݼyhHHF^[T\ܹsg ͷ^^^CC_ EEE$ŷĉ] N7~@*Ź_?崉+xs _~eƊ+zϢAڥ˶yh/nB^n[nUe]\WDG:һWpQ.dJJ V+7Ujz˫ZwLcǎUtҧw]ͷU}LQ"..5[TTa/78bsءú5:ݬY;wnoX8nNN.ukaa3_{nڔG'Nhs .66-|NN;/|7222Ξ=wȑ,8>?TTfrгIN}q"->OD6n;'Oܷ -Ι3vǾKkS))Yt:]-ݍϖ|XXsFs ɘ|¢6KM7:s+~~~Y:7:{`8{ gϔUWOTܢE?kr 11_} >|$ԩK~>rc5{>}RS랚6ǾO<6[n/xUy;w?/Zt:͛Ï?u =Iq/6}]=oDMXrgUVVin~L4p`Aaƍ9r=_weݚURSO cZEqѱC]kg6jn, jlvOD>n|W~ݻ/bp[先ŊׯJ__߂XfZApl6n꠆ Y֢"&Ybq8!j Vi4՚SވR~~zTF1 7Q}srs+ddZKJJ*̭k׮{$/U`@@rrO?k0;/328,k${^0 ƘR18/cJq^0Ɣ`)yS1?ҵca}hlg3 GcJq^0Ɣ`)yS1cL) ƘR18/cJq^0ƔR4Htt<=ߧUBv=6ѬAlE'L<{i)ʋ LJOO\z oN׮]W:Q,((HV:5c ʓ)UTTTizyλZx }bbb*Ns:ȷ C-s爢h4='U^JVRyyB=Q(Q zi*Xr=nܖ͂֯]=zt_tɂys׮^0X^988>u_7nTxG]/ֵj2aG'>2x+W<$߯ߊeK/Z3wKnAV޽ܽ~.?udd;/kW{jZ <7mf h}ukVXd1z)n\n%٨(vTTԺ-'}:11Acέ۶m۶<;e^|ayl3g2'~/?lio>s߾}cƍ'"jFR j ZUV/MY^ׁw}ONNnӦM/Zϋ~ }zy=RS۵m8pt=G|Ө[Ggee>z̙3Fxs;}mjj+V{to9`3O ǣg?yh%%%78w4TՊ #N-%.,FHi"<c%I{^%&)///I7ob4p]֖-Z m~¢Z ǍMLHH9k2DW_}eݚU%%+WrǟLի KJJxy,>|y `¶ _*_}Av\r3ۛ%V6n˭V:!On^^"d*ǧs4nTH- ga0juAO(ܼ`ڵ+ U{$cRf۫-!;;QvNN-Ր$)++"uͽ*PIM'UVxIljk$f18/cJq^0Ɣ`)yS1cL) ƘR18/cJq^0Ɣ`)(/*Y/>k׶m?6;] (88Sǎ_xQppp]m`0\quU&cGQ^L?~J t m"4c;^^^ ׯ)Hzbْ#""ZlQ'e2vٮm]u$AUjh4:F5Eܩݿ 4pEU^SX,3^y[ԲNR˖oٺ588}OyUVwsʕǍ 0(AV~̝;oW6} w[GTD50L/Urd߯︇'Wd?ӧwi gyr* cWF1Vo(F^0;#Fޜ''<<^j<2A?RSK.KN^uzdU7H'd޽b=|-cWFi?N=,X.^$o}|$ZzŋP)SL7PMw׷INhϞK-[>VOSۿ}W%%*ԩh`*GA-((4WKfFW|WEQ Qf0V`"(ē]3簞 q\ߛ1Ɣ`)yS1cL) ƘR18/cJq^0Ɣ`)yS1G<5= ;cG0}]UFaQQ9}MePMh6L&"TZU2//'7ڇAʗҪ:ȥ^׳Xyw5id7UډH~^[oYl%?/Z0]v_}E l]^yKkWZb٬ޱ^#u]!y!g#<U;V>I#n`Zo0y'L"cf  r:<2VY#v˥4/Tj;6iʳ+UD$K"ٻ]vkZ?  yАѣ{:کKИaNohIR/k$';G!IR * lÇ п|&#G^پԽnO=%LDr+}۶oJ_ >c%z͚}g-\Ԛ5k^ jAYh0\3f>ڷ`¨-]'/ ~qjjڪW,[qA\Fe>5B6ܾ`SP_ӛ^v}صgݺu2;vl@e ƮI۷o} Pdy5v}mo1v`)yS1yQ\\PUa5BEEmUt 4 T1XSTT|QS}cU18/cJ'`V}IENDB`RaySession-0.12.2/manual/en/images/add_executable.png000066400000000000000000000141761417052567600225040ustar00rootroot00000000000000PNG  IHDRt^ pHYs+0IDATxw\ǟ QjqYE@Zk:UkֺhuiBYpW- XA@v q?Br1?r=s3@Z@:PF2 4e(# @AhBPF2 4A 0>,..++oM,j;5ՇL16X򥋻uVYUE?qd$  K8g!@q pH`]FcǏ:O1G[[[JEi BB14jb0ǦPrJ)qRa hNhgNO \SOxz$9|dhH0k._YFٌё;wl5c1^z[bY𸠤SWZ  {ѣ ˗-1E }4U𸠫W===n޽ivߨ(%5Aߨ>>!!|u6GX$].BT"JR,d ×.^|AD"x($T*5ƩĦbՅܵ;s"6m _~j@}歅5ƨL2٠gfe3'8~ʕȜ2Mr/9/ŧNSչ7o\4sb{Xl~%%LMoTT<?Zviɓ^A1BfVo1:l|>Rt:]D"L&'|NkܵBA*'a@R5[r8u]]124|i>SoϮɯ6e|kVyc[79u",4L0>XbrO_&Y&٧o35Ҧkj"7.YA0֟> ^`0?&ɹh g''WW>(􉴔w:}bM:u 0iɧ%Ɵ=sj0coΙ|ı_ϥw4h/ GN|zwiܚwbb"ukukq-ɿMˬv|g2gg' YzO?޽ɿ;Q# {MI:꤉..W]kuK Ι@d73qj8wqs{b^jZhhفcˣΝ? r8MfVv!lmm_6%=\K,l jjjֆG +v{6nC._XQ+DDmj/)(,,/i:"zӶ{u+(~@#zx}xDvş~9 cٳo~A!lJjGR*m8--**iSt$a xqek4FcذXlLF2 ;;;r>&drVK "d2Y^rl })5-YA)5jxi8*19C%͘;m!\.o!@]]QCNXCV[]]c DaJuFWE mS[_* ۅv[T$#D| `i Pe(~AcCV!PFv7_w2SXu ؑMQ쨐˭kAXeԙ uC@ E-OQg\go(# @AhBPF2Ѐ?"N.v28^ZVLIkx{͵Ncܧa,Lkx{扖`>?h4Քڑ?ym5vłUx7s"P\S{ 4@Ql*-+(,l%9={ނ{TP?ZW^0/#6կo_P(0 UQQqUֶ~yywZ`*9#'rӖ5W^`ܨ #R-/2|}}nq?[rGl0 svv>Z EuzhpM[䟆84M~} JM BLf-"cbro>Q`8O{wM 9b6m|>KR)gϻ񬍍iMld0l6!3 \.Ӟ20,`Nw!3z W:꯫+)yԥLf=AU >xbbD7TR/3kYuqs5b¥+x #LJ㸖b~gY9ukV:D(܃G~9fW"^b f͜>}NTc>ZN aXXeɇry^1BgVN{(,,Ƚy3&v記F%up7OoTz8q<%2 6yyTZ3jjj.׵rHDC:q%jjkMymKt hoF~q0,(ǭh3qHESaPI?LA7rol۾%:o2DO6I2= N x싗J/..nj>( t {ǝ]8mtZ JM?' FP]]}fv1ղl6 ҲŃw/*z*x.\!oܼmMQ1۶߸y˧&JNNù\n5={xPPә[jkku:=rpp0u bI7!54m$»A!TƱ2 0/>8bLnLkz|?Ru|rJSM_TIqoΞ||?l8/ ri澵 cF?5ǜ= B$3iRYAAW0l0R4j<Ux a!**+; TRZ̻-'WWEE&:P*d`t|Φ zqVLl܎ؘz&lلV{qpM7(:iUr.^9}Y ޽{n-)`ctv{r3ͧݻw_ (꼼2sUΣR_yY/MDl}w$$+ |z{9{_PO?JVuVYwtθm((gVF2ܧf oY`ml? ^i8jS:l65M=*TbևGB./ޠwqqe=7ip/(G^][tGF{[X r 3 4e(# @AhBPF2dIENDB`RaySession-0.12.2/manual/en/images/add_executable_plus.png000066400000000000000000000343501417052567600235430ustar00rootroot00000000000000PNG  IHDRRV pHYs+ IDATxw\g2`% *npuT܂8Qwݫj}7{**@ETD+ I{8B$ r>'=~9\ !v LCx3 470LCx3 470LCx3 470ސaoogh`x>/%ŋΜ=a9 jK.`z)4&2͵~fΘ~s;wT;Kj+4:Nyyz`߻w?%n{V۰a]p/_bY[7ru;۷<~REdH"*VNP !6.m;癙fϭ435z03dY?)((w:<3S/4pLQVV>oҶ-&N/׮kA_;m `w`NH$)|~ĵ޽zZ[[u=1T**++5oYqq 1 .gbl'%'c!~Y֋NrwsMK{߱C̬,kk+ss3 n߹ù1qu5.\ X rl֊K EEb BPfys<߾˭d0§z\.WQ܈mȈcdff=|!+-e>fͼtEiVTV.\LZt١L.'>Ncukq&N 4P񔡡w6`Eee֋~=ڴp@cHc7o޹{ϛ7o/] HJNءplS*]n~~? Y,#I>T >tzX\[Sp:<88tp~rSo9{hӮ]}2xА4k8pO |~v!7~ٵSR&%^*(0p2@MMs֮ZieĤ[z`ﮈWb߽wc._LI{ya. EORRR9z` s>*75!1͉ Be++=@$&$&5%rH T* r9%BP*YXT*GА*_VF$ Bakt nAm@3gZ& 470LCx3 470LCx3 {Pts-Z1㫊+/6i=W@Lh֜=-R_QLCx3 M3oB!fio`!fio`!fio`!fio`!ib\qio`!ic/XiSoF_|f\;kk@^=/^8{[1˖,邾/dw\Xlú#lݴq_D"V~ܹ7offfݺv=q/Ee2ىpvb2u_x*;1)ENy>`]#.w!{3ZP?ʽvU.)?1j세7fO%%ueZsQQqzsBG( 01E'@ Y1T񰸸bXb5,C_ EBy<޽WXF<%HNK*( Ril\H#GzGDYsfVVxDdRrJU/**+L&=466FQ^51߫Ɯ3bjFee%GUM Ml̬t=:cBH$7oGDF=4mիӦ5szbRX,H$bSb<==N6 y 1)yNh:Iml`2>߸M !}kyʶz4{Ϟ='JQ\6U*;(9%EeCqQU(9{nߞ%ASR_xV 4ڞ}^Dvp)@C8UkCBנrGĆ^e !-i45qP-D"Q___,7ק*h: aI$.22% V ǃקD6ǤJT,-zhMZoO"U0saBQZ!HK>Q&JS.kjT|.E:񭩩w|%4:ND {>]5%^[JKU>A-OqPEQT.* @CHA/fio`!fio`!i3`׹N 5"ѫWٍWx;wTXTXVZL &p8vvQA ? 470LCx3 470ӪYZZUw>ea׮XZZ~7wUP`=0Ӫ-_}S077.c̴ ,a޽БBP(&#PTd2I$R@P i#Wkȑwދì._ t7mC,_z  d#: X[[Ze%`^t#u!eee022b08_YM&N+5sD  y pss]rL&ryϞ?oW*3:,<")9ҲS'[EP]\c"=+&&3gyy4yiSH$#_,Zomm=`АyAL7k;vloycp:/C i+3]c&q=X#~1X!CN9uw޹ PI)b.p 514U̬,.gaapws=_ؘfw{ m;vlgmman씓~Z_i3`ߣcDtTLv!Xf? >]^QzX/^^Q ~ۊJ٣߻R)HX kp8#s33aZ@`JJJtu[Eh`` _p"==2t萸J6t:H*,[9s}8f8> 0d`FFFٯ%YYYRVQYRj^1 T{G acnjMŮWLT,WÛo :]\[[SS X$$Μ>]GGfqqcFj0~wuX.Ç56&*:Ǐ:aa߶}0%nȈ0P7ܺ'jjjFNB:yB(2Ϟ-^,??(l/ǀ_5_?&)/JOS*F&B h4~=JP_?C+fאP$"~H.WT|֚5? 470LCx3 470LCx3 470LCx3 470hw4Ed!]k?*u!"k9ҀV6Ypp:#A5ie%0`H7W7b/_p#.ep+{\r)6&j$ߥK{zDEXX~=t<&* {v-ڕa:yq˗-?Q#1Gߝ"®_ 5SIׯ^r7f颢oFXܽgu;z1**sb=`Ųn(du!+W9M(۷[Xr>}zMD3O Z0~/n߹szzOzetLb{/6ohuN$2fضuي.]Nq'2h`>wj˚1czLT *yV.U LLL>\rI#)9 `eeeoow=ێ9ӧϜ4h`nظ8EEPБ#.]loovJص9oTUU\ULlUxصA+33^]zꯓjZr. oFG]ɶ7q7r%%%+V/[8>.&>. u%TS ,Zkj3c31o3f"XQQ\}aXUUU؅5l6ǫY_OO,Կ ].LryECCCH~=HRlLuwjTk*Ϧ=i& EQ_\yTOE5iRCTn `r&@QS B*ŇM&m8E 8d*TM"2<w?؁!0nLCx3 470LCx3 47_mD䬧 a\\ZJWYD"WF$RD"D R!ԏ ӱ =㱆M<{; nn#wbQ1luvvZz5D" Y`$iA[npxɲ%uhRE\]O>[-ÆѣGHE>{YZOWCzdZR&rgϟ+of͜1od2^ T ?TD4d*cc2(=rڔbXOOB西Ϝn+$&ru:S'{'MMLW,؁L&?~l}\p+|&H$A~ٽ'A7P(tڊeg]8`Y[]e``@!_^Z{h:vv |%@7ɇJ^}ZdH"ƭj^=v\9={`jsľ}}@$CϞ=EyNiٴaYY/%H MlblRS#.+@Q>g-,*V@Q`bl`9Jel~}tV!,"J(FQp^YV DݹwHvvբ(1fffE%%##0#OeJ$(T&H<{njb~%|MmG7yȱc stcyG{~Mmbm#'M^^NJaXaNZڃaC\PĤkl;vڵkZKKY,6f+ ^RRۄiEѨبXg֮*-+rlޜي:3P],`5?xx¸WWTr=33Kc$ }ْRc#/ X6ob~=OS/TV;\.3Lil62Tz +?>rŋNOona5ÌԳcϞo X|*HQF~׭cQ<416Ƣ\QYb劻?yu=޽خsĐ ]qyCG~;.ZvU`@Lz+Wnj{1&)*WrLCGG s8F(* aϞ:d?_DR)k<}iCf;\.8 hƤ?޼@ VaƙLM?o۾[{ <|}}b9]7e2|ͳ6ukbblm❥]/_}ݻ9gaW "H؀"Q؅?\BPb?ə< TIw5:xq}RtמS&P B"NYcW!4z^6C|ؘJ]ׯZ;-=lkV ̜Cmmk׬zw6gOHWIu֕ڰ.DL#22…P@~~;8qEQ5iSs;Aibh4HTM g/\w? kV_( <ڳsD"Uk~?r}ߎ?(ٸi[U#< ={{U{UxdcU SZV">c6޲ ,_xŸ5~۬>mNS369Ìk\ AEee8j@WY*ژL&Hrub2$) .htU9;@WWW,m(oJ`W? 2JSFEE uO Z|Lu}0-9\^^Qy}lf .4YZ<~oF7߽ä%x_^ A?`-kA_̴Va潦 fZ+UU|+IW10ZڿS6\yw"_WVjjJGvi@i5Z{@x3 470LCx3 -=}lpH$>WUT_ i>kwg`C+d ma!fio`!f›6!*WVr}pXSL ANNUm,Ӌ͊81ˮQQ.kiix$)\4gOum,k׮4cuw$D")AtuUUبt:],+RkӮ]Aa<Ǜ\M6nA oݾMP,,W\rtqʥؘ( S~˖"zUeLTY[$%9ѽzHӧ7Wy+fΈV3i{i~}(du!+WN;wNS_OS/_J$ ||666|%%{߸q$)?̚)B/^TJrJ @É䠯A˴KǎMMLtyV?OmeeeoomێO>srrmh1 ;;)ӦnŜ=P2]XX(=fd c$˗,Zx'ljB/>s浽LgffPQQI VT; H`Q#]fj):9bCrsssr,Z菍&d2ԟ2yێ~lۖ-dnA\Cёa׮tPM[[ys Y^&]xb̕yGjd2[E[l#djo[tʾyZEOՄyօϾ-fio`!fZ+ڭDj ,#nH$>iiC-= fio`!fx}Z+l@(̪3(`+f]tl&  Z냙fio`!fioZ3m:wL$>dfe(z?~Ʀ[.QͲ!&LO HCl7o|EК=?{L\+ڭ#G#"M),{݄L޽V\KB*2|cΞ;mw~D`0ٳ͵wPkiLoܰpDJ6\ԔT&) Pj,Iu2]^Qqqc96zmmKgm(@Ϟ=~WVVVÆٲmh\.3=vR腸^X+&F_zb|\ 0`H7W ۓ_gϚUgi8VjuT?H S6ce+3tq8ORdOOw_?H4cS}vw·^|:P!k>~(n9vf2\MuɇDa֝cn8-77]eƼ[(*.Q7WML&>λ{ fio`!fZ+BL,! YXTU x_n2tҵ+*Af&/3E:T!B`io`!f›3-8F/Rc EVk;u{%^5Z(j"J470LCx3 470LCx3 470LCx3 470LCx3 47ml&161%ɭݐ/D" ϒH>~ >TBGT׊nBR)rAA>b/''⒒oeRcccPhc}2P[[KP@2KJJ@}=݆^ 6ilֶh; _ UZ!%d 8 47m9|s;%xnӾ7m8 )8x{yxy۴ˍEѠm,_/@ R5ut\.jjj庺LD($kwb]RJ̹׀td3aذ۶*(Wx;k:[m12:oԙrjc-k0l`LV:T*[׮ H$tܩM[U666\Lw|r d `&d}z^yZZٳf]20hMC1e2kuX,;ͷ"&&F-@ *R`o_+x;hݿ(W֭\ۭL^~5nx)r_r٠3r(gNGGGDu'$J NW.i.0ӟÆH҄1t{(*TWW\9d2/+kO6mݾ>n/\2m$074秅X(bI3{OwXB51)|iEEE~}X,NsCT*uْÇdee3d?_ R@(ں7oqZ[9Ht6T"'$2bqϷ@$e2H |]Ҳ¢i\#6m@3?޴u൛nS:;u;v*W`ߙ}"m7n:uX,>tI8vȅKϷ}q7̞iia3yg(*wos/(8~53f oZczzD"uP@c5IBT=="zv @@ O6mٶ>xcX EP ry*z^&T GԻ>(x2盙(:ds<EAYY9aC<|gW&XW݁TD7y<Dr>&193zDBRRE%d }^^Yov:-=LdӖmCnڲ-Ν7H.klbn*:crˤRnEEwT KJsflSSOMxTlL~w)S5DD>W,.Hd2YVKGJn˞#jX? =7[O:9*Z g:4Z=T.󝨧;ㇹ(vho3t=U*6F^LML.G]uzFP$LJNAQ&K%ΝtuUUo98ؑIhpEF菳f?ٴujjk#cU.XYYy=,<`Rݱe tN(1G6ڀԻ~o,!֝;^ VV`}q: >DxT*B D"QffOc~Ф(nݾ3xMо;.^~:G;M:y֋wG~D?o)RE#wnr' D…A#~;ꠀ/ښک3g'mgm}>HH32^^׌ƾhiiYikEd2Y.c:Z}K"8ܻJGxzix>*&Vx<> UUI34*U*H$ "ʋ ߯ol\WC=NkI?Eш>[itY%jEIEEgD$Kd2Y X5+jw{-d9"5f-iU`!ikG&-MveƮ{o|=jciDLPZ_JkOP5mcĩݱ}(LM(XbA#yۻϷ4V/?EՏk2 *As!ihijӪX*j(io`!fio`!f›q,n5FIENDB`RaySession-0.12.2/manual/en/images/audacity_executable.png000066400000000000000000000163061417052567600235540ustar00rootroot00000000000000PNG  IHDRt^ pHYs+xIDATxw\gǟKHBF !,e`߶"VQ\ Qq-lGjպp h]ԁ(+B #$1e%1?r=\~y;:ȗ 8e(#@ApPF2 8e(#hѫ|[XX\\ҖYjKW8yJpHZFڥkm;d׮ϵa0t%Z!jΜ;wD)jiibE5555558l[^dDPr"D.GTfuu&"DVa ђѠ/e0t&&I z8 q'%\Ebjo)WC8Aڵ+ݻ[Xx+/_ pv~q)I WgǎE. 7}ڔ+b٣G7Fl4ZΝYnߺ}'8pUuքǟ> &S?+C<|hck=.))%züG.GQTGG@ jBHJ֣{wCwC/X_O̘5="֘2d9%};r#8hัc&OV^^1yĨ '*KbFP60w4`Rغ}G=b6J$> p4L(Zu&qڙuѽRL&x第# X,: نXxFf&G>{>aQ#\ZuS3&&RoHS?uP6JLJ7 Zre`0q1`L˰e"bz~St:1Wĩ`1YGX,y/'I6G-5Н9c3.Y}/,^[7K:ܹǟFaz;~ܘ1'VVV vTS|g2(>{s 2D?`  ~1^Xeխv!By󦠨xX>ĮO,ITRTibhImM kI1 24dlmllmmVj/OO lܼ^Ycְ( ήwm5HKh455K`UBP0_zhhhHz`5Ї|'M–N2ʪuLev=իwfXܹk8ܵgOFF˖-x 722C{9wfH˹kiiibb1H wus _&fϘzBѲCh=Ç9sV.]$IP(Ri;"4 PTTj! v4009re9Ssws-((@Ƣ"W䆟 rƍǒpfNNfٷne8VFNbC'///]]],ݦMNOO2u ɓ@2L"{)}|FRʧVVvUyⅾGW/^pKi7n(f;|%aƍTss-+ v1L{wsNNnNb $x Q554|ݚvn)2Wm҉ؗ^Qd<4hC.KBbbQQ1L.+ W+P4С;q\qZ-EQG, ]mkk ̳eF,j@e޶n#\O= Ho^>SRmd+vedft/'Q-ҲcFMJ0dD"E@ 1a 8O]ee}}}K_S|LWVV oo?}ߌS 6}=էd$lٶb?FR"P*&%'{9fR~W22*bpy<---*l6eNh|qmPV_/gX̎Apqrq"(ׄ/&Ao0S{bw`A_VޞFF漅^ȟ6e AӧgdJ$:DbWiRRց2zj* =#s1FR~?Z59mTQQ"(dEPHEE^vC7Ǿ-Z0O*(BV/))j:$|?"/(zd֘Vdf:#*E"&5f/W[u;yX$ҤRg]PPPzux(*GtZBbR3a;{CAѿnT3ࠟ#>=W"+Hڶ:::TM2"M mmml>]#0 @бFwf?$%') !j5j%F~̝d2.>†5 RiC +mQxvP8zɾ^#U,..9t8owvSM-eG(*˛[g@ /F|y}A3|iw!_PF_2.Nam 4`h *B#&f߻hk$P\p]PH 4?F_HuFF2 8e(#1'SM>3=ˈFgJ3-s͸d|Iyj aׂF`3-@|2MSޫmڙ?8:vM5^ Յ]Tj 8BȭFPA5XX}._? ©pps)|jY!/5Dk&η~kaa!}qqq"Ɔ/(B,--=zԪ L}fXh&rDl~߀}ҏܬUn}Q6RcfZ>LT6}͛6 :@%Kp iccsAg|}ckǡwfsy֩auD&lIšpfΜyؿ0..N9m~Z)ϡUEF!BW]ZV.<|t˦Qn=6h ]]|Ϛw^MM͚FltzUUUJKCCB(2#BZ4|Ll۲:88DX+++;;;O//Laa#G|'MRؽkמ={!zyk+)ϳS|'6*#Sǁs,(&9ftwHdҶ3+sic'OŞP(e dgCQw҄ Ju"qUd/gJT˨zm[E"QhH7ؔ;ѣ@yRݻv\~y\*v[XZ>x0"2jmxXDdBI[7M|>F~GH$NÆ.?7=#A\,}Qu۷&_K3kzS}B&rG{3a;~옵f'hv-ZHBܱcP(l^C*l]h4lsƌ O>bxҜiG`}}!jmxXBdGpct>_7oe2!۰R$600P(wP</ P :Dl@ DQx 64mm sg_tbjdh[T 9}ohjjܱ[Q:lar\Q۷Tlyܶ=zܮm>̋vuXĆ܇yzx[|>m0F |SV&*\T*#===eeb2o}! FOAp>^Fhii(sss)nEX, >|нl))2zo׏?ѤR`7;G9|҄::fEQŰC>eT +LWJ#/x"~"jgΞ۞#Gqƞ:n޽{#B"ǎ۞=b>{lQQQm$=cr#0/"2Ȉ+W=]xi>GQi4*0Senݞ4at~Zn5DJP, XyҕN9H ψD*F{ ZyLH,>+3붹ٮ[4g!jM2bF$ )4X"ŴG=n( wiW}`fHw7s sۂ Ij ASA==FeHyh4*g$ ]]qUUOM 3 \|(^NHljQ̣(~^񫪪Cd2YRG:fڍUP]dH|Enc "*J9Lk$""""g 6255-uDTliFaH0 """""""Y 6^P(QlaemK++@Td$#HT1 P5kTVkӪ%?x`Wؕ-S]Q^})Cڍ8rϟ?ImٔFqJ@9h"""*:nC5abfDi"㧩% ,%TZ11 oA~YN{{>}*jת{ǜl88 @rr2ࠁvP(n,QA(֭ZGKPY' Cvӻ7fΞnA*Mci4suV9o,YB٢My '|)?RJ9ߧa֜y 뉈8Il~CҾ][gX0WʡC8u,DBY?0<̘6?fLǏj|͛ѐ\"sBXZX@ 0ؠBPCCPp0|| U!t׽af@|?ln޺<{Ϟ=ɓXl Opd6l(*WϞc- z;)UV{(?jDDDTk=BDDT۾|1оNY쭑~j-jο}a9{:vX,t{E BeX..nQftj2(T^]̟;QڶafaJH͕˃CB0f( L8^'m6l(޽{)MŻw0tJ@sc.]!QQPfM>GFvZHII)֑:\@zϱSII*UVZ@ĸ}_}6Q:RRR7nBShܨ!r9qB>|P(DvmQJe$'`hh^'KM?,35isl2h٢9ܥ|æx)U+ ̝'v؊h}΍ʕ*bMĩgyZ??3OÎ]pL< Q.V?"""*խ^z`uJ)~ߠfjBTTÄ{?zNf͞a mxQ|9$''#2* &&&*m;K ."м+jZ$$$ *VD`-C н[W߰e˖A jZrB&i!),F]_iAx$_vyPp0vރ]ݰdيiWf>{3ء=>dM Rʲ)t4rrAu1lL6#_  T3Aq=J.zȌX,\&Sުf016V4jo!99fffÃЩc{ܽR]\d )r9RDEE}PPy=:%9 5TGx˹*KF໼PjUu*5ԡ4~2Ín?jDDD%M7xdJF5ZfH$HL $H ΉC?|qncWkƋ/?DRR޼}g_(ísG;IH%c x)J, )1b##amm^={@Px>ʫnhkL^=sPzXq 4suuѲE ܺs[#mȋjUbO 9.pb0A7'2""&Gk#i0ಆ0jlt ,%`C,@#5Cs#Y|t]TT\ %%색 RRHLTS*#044D{r*]SSSwbǧ$g(HnhsMnݾѡ(Gyuqipuvƅ8q2jBZz:<~n; *sE_'362R;QfˉhdK=<#E!Ӧ:k0g M~BBBDRRPJIIAll2HP(PrEw!QOhZP?s Ә᧟Fbgo]xec( xz,޹]QCt_]e^z`Zi#iآxU?"*11BU򈎊DdDdM ϟ?GoӧcF.jֆ6Q\C4KeKrJFÚ+!~Fhݺ2Ѕ|Q3o>֭>E{~0jnQ ѡ}[D ,,gw`)i{[:sB mSf͙Pܽ'=PAp 6XUQC HNN0ixڹ vŋݴy+}R)ذqNۺzZ֟AA5zLj(C"""g&,G B:sڷCy^z^*WB=_|{1_ܺ}?3`pfZ j֨^C4Xh1:]0oL#Y&C@?xOim٤%-i5gC """=剬 5FA E8},jתZ5!A*EtL cXXH`bj(e!ttz_qhwf͞T^[oKD^zu3LZZU&GBDDDTPVVV@ȈHG}pp쩡1#EADDDDDD:' H(Sg(s)@sjPF 6@ @PAb"""""""*lQ`-Bws'n"""""}Ra "+?9伪jժ"**AAA*kת|Q%)99o޾u3(4cP#""Xh1d2Yin"_&MDF 5X"*6nݾ&*YFP#FN.깑SfffYC(P n+ annQXʐ]f 6o{CBBxY'OW ahhsUhܨL珙*n@ ɲdbYxiIDDDDDDDCsfj@mQjUt^eM7c |jU`x>ݻaa aCâbfΞ [طW6{.Mѳ;0F>r8tfDwLu34bGHxWj"""""ʜƂFN.p!f_0ݰ |x .\ @m#ŋ ~&F=>/_t=kׯ߀%,-,qL?K BT\)aHQ S1JЈSW:"!Q1"""""Ҟ8<~Tw̩+Jۻ$Hعkʲ[6)mggG {{;ar#99YeH$J9(߸yBFU*U›/)FnfEL߃DDDDDPUTtA)<"v6*l=4H#"CZVSMdfnPHKQFM]7C"{)̙СW_U@3W橼 *TP.P|JDDDDDDDF=6D"rɗ-˯Kwܶ1016e+2 Oɩ. i: ?OpˉHS.|3䂁$ """4RH$␐ HyՅY]7Pڹ" uk&gaФ """"*$Zn[96d2@ꄢa+ v~\%p)=1u33QVBa= """"""VBgXnZX\!"""""ʝ1cb19ڶzܚQoЫWL>#epV>*VF#ƏK.jժ>~Dl].]ӥLLL H WWW4nX6͚$Դ)zVZdɒR F@P gffƍk6`@iL}:>[@zt݌9sʕ+5>J!""ҵ܄Eթȑ*;~=SNC !PtniM: ffnFZ*/^$|uE]Æ}ca8x0J(pAS C!jcS"1G-`ddٳ'  5Z>ZjjբqyH}T :vꔫ2!""ҥjԩSnjp|`(^^*E"3$˞fff*eB""־FգGOx\.$%%a!8p@G#`l+ڵ9ܻwÔ_&cРh߮-RRRT355U{2& PPǏѯo_HYD:H:w8rH-,TWRVmř>7FFFj+Qp޽ ۚgI$LC*u$*8_aTVPY={d6%ϥ9322ʲʗ,,,Gm۶sS\' . 5V{x`aey*iSg4odv5VX`>fΞko<Tl@jU䄛[\ @dd$[6 ~<ҋq8y4yߔ']u_c8},]c`ǁ`mm,>: ХKd=TH$Bg77=dH۷QlY'C6nB8s,NbŊH$vTׯ@͚5ULQd8Yؖ-[ǙpLW Vpb97nǟ~4hgΞqO/\|o uѿw)_زe+_Wbu*QN>'OFKpuuU9sb%?+W)WqyeY ΝƉP~}޳NЯ_?;cuv|7dH+6`_q1~߰bǎ8)Y&N>2ldAtϜŀK]nΜ7n<>'O>B5 K|̙q8y.]VZa8탫׮aqc29|ƌ H/ 1.Ix8jի̙3WQN>V\s޸z:V4i߾=||pi\vYn* ;\=baa5kaܸHLLTn[bE9z ~p 6nR \v~y6+[L<:̘G>g!XP@}?EӦܜQ:Õ5R& *V{xcUpwwW+`gg\ !!!ʓ%Kbj,\.MѶMk4uvƠS~޳{\]c1[>Zhg禐ɒѧO_ ,]~-7ÏFbyptt̴}y?V?d -Zĵk˖.sS4o抛nb/zܷmv߿R7RRضm;4iΥ˖.h׶ ڶmΝ 1u4 mZsS:5A )׋btvsC778ci Z4o-[sur_w|EZ,M۶С=:زu?.yD pQ[YVҥQ~}_?9s;wP>QBT)}{ѥkW^.]p uƢWϞv/Y/hذ\Q.rʰ?܁ d2޾}~ GGGHR| |S utt7Xfzj4oBe}{8_9AwCሏƹuX:x~KB| IDAT޽qe'Oc2^Ͻ_ЩSg|q ^|&MбcGD"}6 ǎU}sg76>>x5޽{T"8(peݻ>|gPL}7o@]|SU)/HΝqeXYYrʸw.*T2esݻw8{ ::w˕P!""vvv077GDD}V[c-ʹ,l٢^*gDr} J9:v숣Gɓ'R(lsH_74jm*!UT%alp`({+0/Oe2 R;88 $8Xe ,i=,,Le}JJr ˳ N z111YOXYY^Wĉdd2ܺuKyrSJ۷;w¸qԩ)a"wAhh(Zj%mаa#?~Lm111Xj%Zh'O vvHIIIχMI"%%CTt9V){̚5OeKAԭ[7CQ91 P(?|K) y@ڵ_LQ5kxJ_r\u5% &cٳ'KWPVm{wqk٢%>r␜ O݇=>.]a"ʬ^#vvvW;W\P(RV'q9o̙3C9YܑU666ʰBUСN9<0bH| U7zg9CDDMiCMI~2fXLsTZYc|Ԩ7XtڹT˖`%&}qbB$K.>|xu'Ltwjwp@p/9˜&<,:tHڧܺʕ+WUPӧ+V`ƌ?Эk$''c3qyY:Ю};E׮]agg˗/!44YINN5k0t0TX?~P(?2aXp\-[6cm۷6m& D" * |>)U ϣG0nX8::b*k;DdUVzmq!Wv!""kVƅ  oo4j+ܺu+)*'Y2=>x3PFM#G_f  aϥ&NNڵmh@V))>_;133S,6<-@166Ƣcذy#u2>mn{?"""mKi~L&S~P( Mw}/_ĉ έ.ïS&c%7alJbbx 9{leY r*V&NNR0D k,^3ܢsqXd z P`ԜN]|9YQQ ǡsg7\zaaYNɉ}{ Ej,_fρ D"MnZlcƌEppqeG:u2-K~ؾ}9hbyx ?Ԛ<>#p 3}x{g^w#G 璋+~=;oGŋx%|7n*۶bpϟ=S_t).[ :͛7Rشq#vރDFD`޽}?*UqOe] //}py̙3[{r9!""Ҧznv . ӧ+t),]|Axb "ذdո~9enf57J(H-/99Y;+PfƫEQnv[2X[[#,,L퐡YgC*Mğ;H$5'*XYYA  ""Be{SSS!<<<ׄUJkwbl G@n]cccH$DFFŰBTTJ<&XZZfF[pYn26dRo% hsI$Red2YuZYY!666$ r!]066tx!2ҳAdd 9yIAϤעu;ܺ}'B!M7n3Yi *4lW 6WRe8xݻիW/_ѣظq<J Ώ_tJ}""imBDF%}Na_ybKހ:u "Jq7v8pGTT4~~C_{H1 b#<<CMI~< "a9݆ {. ODDlQݭ])sBH5p5*|/KCXERSJ,jV|-DDDDDD 6DDDDDBll?yf`$BǏ 益bADDDDDDDEPdn;Cc]4DitaAE51=u""""""&]a}8&CcDDDDDDz&qFڇY 6bADDDDDDDE """""""*lQ۽^Q*/I>xDDDDDD? 6H(,XW)^TeQq( QD*o:L+)DDDDDD ʡwR! { ),@'"%IZuD9$LJ$C8 ٍK """""Q.]TFpQ܉,DDDDDDDTd1 """""""slPW4FگaA%)q(iZCnhvXY@,)g@,O{G#%#l-лs'D56""""""47%V0wpT1ovѾ"SP(m`.)76hL   DDDDDDcAzaQ`O0 ~eX P Ҥ VU<:0 cC..jFFF(U!Gۖ,i:p(?l^Q('7D"$*!|,E"$ub&jי0r###Qw2P33,&H "Lq2۶m 9ޞI(''N>AyS_>vًS[ׯ`?`[mwC,D3g..\㞸r\]]&Xb\ ?_7,-- 6ęgq ._6lmmcNQ,ilƍeϚ=W^/{zVZv͙3ƍǡÇq)ܼuGURǎ{9oUe}SN7.4y2:u e='%г)rkC,M۶С=d2֭Àp=hWqQ 4w.]/'ٰaC4qrB͐%J@*ƍ .ΐX|&M3~DŽqFؿK!4h lٲ U_WO? B͐o탵֣m6J``hϷkԮ]{ñGG(bƊall7lP߻wm^ CҥqYؿ^^Z*1}l]Oi{l^u/ mC 11rׯ_ݻw;\ ###ɓp,Sk#R@>~RAwCሏt~~~(_x.]`U{5 Fp_?8x˖.L&-{Cvc29ޞ=6Ho>`HauHdP?|R̚=/ ""7mºuk1~4j>|@X/DGGýG3AƥKq?C+WYq1bccc( \)S~Kп`˖ͨS E|~~Í7Uv 9o\8-r{""""">Axb]ؤEpEE0w}ٰea7*lCK]wahyVv#F{n#`eeD)bc3~6C" 22Rׇ)\\.aee(吐̘1zhJ%d2 666TYDDDDDwimr={lD x,&3v,6nܐvr\yKVuRr8ƗwPRRRRdM/!!e/ FG9qhxxx9:"퉈H{l^IѧdCuA@E9|XѨ_&0 ce$( h\""""""]bAz%w-V5"""""$$&&j.ni *̹ t """"""`0 """""*xBłBIBDDDDDTcS """""K 64(!=zaADDDDDTliI}0c|]7H0 ҢeADDDDDA 60 DDDDDD`HGn埁@OsC@whѺ-^Zo+>`AA&&&\.@ PrP(Ti눈(olPP(VP(D"A\\\zji *B*AF( 5Q033˲ """""aATLMMUADDDDD 6 Xڄi """"""aAFFF^[;{, C,Pq3ss̘'TO YeuÕJFI[<4rHlqfsx߲ǏDI\UݓG˄(XWl\ذv.])/+ޟnM.չއR^^k*3kk^|y9e=JYYYn|Û4/?`̟$9# +#7*]#ܓ{Us? rQuL^hEGN}bTTTo7onfjoCӫ:53jJUϞ>mZIҵk'55[b}=zHe.͂֨JN̬Y^^g-VyswNʸJL6%u_\&m[JoE}kg޽{uD~yϖدaI̛7! 3gNSE>uQΝrJRb766f_/++m5`V?Fc 6S?&̚9KY3c+."jkk:˜Վ_7/]?4?PvNQ>)56/=+hfȆoN0]Rիwc3̐a뤼`oiosόI=5̘:9?$x~jN·7.}N s/ßZ:쌍Qٵ[>{" rS~p.yg3÷:}c렦`c5>˿;ٜnY>-s7΂; %Iw( 9̟eQ곏˞~}i)++ˀk$I~6͜9j$io7_^Q$mc2tz9jMR7wN>ͱ_4榲K|ˤ_ͺ#7i?+c3:`):䌍;~uillόͫ/=W_~6IⓏKn3`P \mͬFIOl3cfM<1g98=zVg挩7wvdmw˸Ga}kgF~:Ikֻ?єJyG>M5km{Ҧ*444ݲ7^5IfV Z}Zao7АYӛNϛ1ޔvRdȟ|GnYwƹ֧aK!rQgdߣ[l&$y'ޞCϸ2ǒ$cGߜ_wBvҷrMO47hhVio>5NaT{x+V$)J*']rs?8ƌ^d3pa93+3s/.L팩j1aA n̨Gf~}]~<=ȳɤ_̈́lSoм\-S'mgk]o:>G9&r6Qe|bݳW)_bWo3[\ڭ{zɬiV}t3ݫzv;illhj5}gV̯[b}zTK̪YO^=uԇ;:˞ˤSmuڽGv?uݥKHE?vanz̯o#YW`u߿I^]- l\oT*eά.x>ؘ=әZ) @a 6jKwDmfPX @a 6l% K`(,PX @a 6l% K`(,PX 4.7۵biL:8{g IY] T?/'7c@aي`(,PX @a 6lU2=:?]V߰+ԿJdA]6(_O٥Nzokt~]qX؊B!uY}CJu؈6l% K`θq:# @a 6lF0#Flآ}V @6VafY{o9E@6Vqz_9RVVԾ=zt_TլgϞ)/__]{󕕕@l|-z[6Vq^ :${|a3;rew3޺M7^bnzoP_ؽsN=wݞ;~s.<;I{-yxopI /6|pI>U\CCC:6[2d";u=r?QGtK.S[e;I&ҋ .Ivyלr7Tw5;|n̟??:$I2fck3v옜sY-}VƎ.%XUTT?>WƬj9sf n~ǝOccc~f\^|I'|*]v̀$oM 6,묽vƍ{6mio{~_wFGIRn3Qh\vۦgϞ9f-6mZ i:Iӊd>mtSW^! p~n`\c9*MM_ӻwK)JY6i6T*}f̘&c{j`5v}I^|& /R^MmUUU9kVJR˳/aKuuu2kzd˗r_P#l?:GBo5#6 tcnW3s֬e+[o;o5zSlݶI6xy@ QJ*++K2vfo9u^Y^^>{gK?Q^qeM6i:xo L:eVwKU*2u괥wl5kklllUa+ PX tl% K`B8!7۵bԿrƔ QꁎS-q~1+Կr]ulc@aي`(,PX @a 6lU(//OϞ=;ٳʄT*z`B`^Rh'CW[=l0<2clEz)XLzkbzqe`(,PX @a 6lUϡ֪#Glմ`F0mڿ]7I+/%^3l5\3CO<ѬNS5\v!;~nu-ƯYguM6-/b+2eʔfE[B`F [cX&Ovo̙3я_S1xt-Iҿ|6<)5/ǟ->Er̜9_~KTU̠A9~}.xP&Lxϋ/OnI={__vw=g0?xW^YVڵk+*Z80_paFVz|̯My 6,}S[>ϼyڭ&%Yo|pJR.¥]c䜳 's>ieBۖ,ҡ:$>򇦟m?l5?9뭻n |bpx'3^Ϟ=;_zyf͚M^2f̘{^UU{8pofƌ >#$Iu랆R__ߦƎc7̙3~eߌ:|?w7.^pbhO\rq,r%vҥK.m$w5H,F}}}f.ʉӧ<>̙;+[^ze>?z_2lm6װ`Afֶ2qy}9ó/ɬo|3_~YjXV 7,XlITy}n19#$/rlE]̜53[m|fԷNyzꕁ,v~ݻrղN;gy2qĦ[o%{v!x(l0<;cSj/ݻwπӧO$ĉ ϧo~^sH=faLODY^|CBDA;2lذ$9S3r% K`(,PX @aUvvt|pիWgRHfγy߫ۯ"Sݻ*mR[;3=>wxyaeGnTȢ|>qbL٥Ґ!C˳/'>SdʔwVʠA3v%ي ٫Pc9L<.% )SNR ?SLIK l@+-=˯Զ(v"X~m Uo=\! 6lU^(d/rrVDVl@~,C+6VuqZgW.]ΙUpotYYYvqY{$?sr=S*BI?`VxM~ׯ_~+dÍ}H[o婧JCCCZ$'};ݻu˵] eg/Oz2uVϹ֚ò޺림>9"'zZ\ӵǧ>'x*|k9oOZj8ѫWϜtqޟ^aW}OEEE Vi=l ?9r)yV=p1WW༳ӎ;λ]|wL<83fH`{_ɻ{Μ9 R*++ӭ[eeeZSGl*:gcY^{B$)J˳.dO}*N;-S&O[oA2{n$~9?;'?4J /SOMMMMvilҵk6xTUU˷?~ܐg=<+pݒ|i%}Aj$|ۧ~~v풋.4iLأ̴iӲ٦Kӳ*\o$ݺuQGl444wfR/W Y`~f͞3:'qZl*K^K @?rd~~-y>{GN>+_ĉ<^rI^x5jTvey#g9rqǥw7fmͽG/o/X{3a„${ٜ~s)'3,ܘ0Yk8dƌy M$̮ۮ~w]`A***3ǦgnzrN̳e?_[\3f{*{t[ow Z1mڴf,hhg˔)ow8`@0ٔ`SO=m&f ȇ>\~Vk:cW1c>xӶ.g='l8fƙg~)w߳Ct#~O^{w|moT*eu֟ڪyKf ?.3fW&ʫZn/:dHj=`lDI~_fĈ9ҳg$js9'}zn{ԑd7ׯ_TUHUU̚5+R);1c>{nݺ%I$yᇳgwZkka#XXomޚ80'p|̙3']tɝwޙfc}tL.t%}g F䒋/wsjF{of̘UW]SN]*rY攓υ?:;7׿Tʈ ~)yyֹZreWfΜ9wOM.]`JG+\˫S^Q{sfjYU9cs7f٩W}; y,kf.3gvzŗ^Ή|wˆhE ~G}mzx=A[δiӛmH38=&Me]g}ޝ[SSS緩ζr-3'RY5lMm,;C>m5eeeӧOi|YYY뛙3g-󽪪nݺgƌꪨH>}2{Μ̛7oN6xF7zyaVl [TU]]}.zYYYJRN]|uDyuJR)w}o{he3f,}ڴzs͜9s[744d>^p"ǽ8 el`Q[):W+an^U`ډ˯P {+&gl@X̚=; 2 k!9{vʖo 8lO 5K +>r#QJԘDzUR iyᥗRVV+c]V򨭭O>R0*ƤTQb%IYY*j1_X%,y}~9c(,PX @a 6l% K`(g}p0A IENDB`RaySession-0.12.2/manual/en/images/audacity_ray_hack_final.png000066400000000000000000001413441417052567600243660ustar00rootroot00000000000000PNG  IHDR0D pHYs+ IDATxwXIwIB E XO=lg^NEzPPWPJ#s{3{2Śh 4]A  1 @ a(#h  1 @ a(#h  F6JPԼy30Mץ~TR @[Eah&;''//Ow\a֯_k"~hⷊ;Dab04] A1 @ a(#h  1 @ a лEB}޶us]ӦT*;KkѢzJ֭*Z5Aǫo3bY3޽'}}֭ZMsګWtL!߳{XljbBі._o.m̙w;w*ŋxy׼c##:u@DS%6sƴy=|HhRTD"1̢Ph4jqqIt6-UT$">PѩoY3gdg7h叺%xo.[wB!XիV6k͛7rXHS,|-ȑcon{{عkW 8$Tf֫V.P(ii q._sX w!UX ~%l|/))i#ygήtt:}3fcرmKj>}J}fgN 6a8]C8nmmԗwȡ C0oB"LWKb;~FާOo( wNߺy1u^AIܬ;pqcG hajHA5jHl6lذrnݾmݤ*GӨTjaa!4nܨsNu׎y:%(8dҿd BI$paWXǷ>ZTC4sqvi޼yo_7x׷sNA-S3gLrқV]fUdD=wS?d 40~w AkڢU913WKKK[-*&dH$d[ ryac+dP(j ljU(..)F8_&`L6sV\.r)BSѲe\|BWFq[/<7 zW6 A4bA CADê#%M|~Jw`thNӵ@_VqUrJV@G޽[wC]p &&Y M ԗܼ 31 @ a(#h  1 @ a(#hF"lmmY,VA"}vjm[fegu .k۲eSM,m沿{H#h  1 @ a(#h  1 @ a?Y f.vvUd>ux6mʧZXX[+F r5uv[Ν! 6߭ e֨Q}{v?~ؔd ȈNO733P~./^i4q173رcpH( ?:fQQQuLuر,:S lp/X/I^3)@j~Gd˧H$-CT\\ف4 Ri9h4Ded&) U)XDbXX,VIIRY_g2eNQa YLT&ddrII 9w2%Wv}lvqqqR[-&)(t:]&9 Ba0D{݉#:{{@F"t5m?R˼T2H UL2 sj:m F dM׺O64Q!rQA^W.ڶ(AGG{ϮBfL&HTnX."<,,$hݺ::`jju{n##Ξ9^ # =j䈐?_om۞>uhaC#Ç{=rxѪM2QW\`_Y ۷oukCCǎs tء3O9_o7'MPQg͌sJTĵ>{#7oN|n޼ydD8~A]T'$(;FY3UձbzHnnG"ɧOrΟ  qq:uR/@~[FzuczVR)n^˹.:i?cS&[5r?dȐ{w>X8s ---'gWT:w_LfۭgLU.oߺ寿foظ b's EՠQ9z&OMLJ޽[|CFuLMM۵mb?۷o׹s'RT__kQa g͘qy_? LMMs윜)Nss|DP(='L3CB e;~B*:p7n@i#2HFi7oLLLLLJwh4C'""̬ 8'p]VVѣX,/..޿poݺÇΝ::9%ejUs3-#$&%[Riff*,W5knnޤq3gD"ڕ]P r,;3V*~FTE5 (,S@!fwў'(p1xIRIo 3tua&nTH+WN˶ݮ5ؐG\RR6,(;'[!';ndefT]ZCCΠ!6_%'T./G|P(3)dX>նdWW#GSsʔ@? kyѣFnٴ1۱cgBKJJ&M`#G\UK )_XիV6k͛7rðMƠ4E1蜜/uno߽, ;;|N?Av^(Gcwri*ULzt qSyBJ; 7+4JE~̖Lg䚹-bP|>߈kJlq9Hp;~AT']CAέ۷}:eђLwl6h*B8/yv~>NR4:ft͎:ܱCZړ'_BT{}*3a8]C8nmmԗHW*ĠcY4档MwsB!كH/,,444|:j޹ܯ}vAA59HNQX,&.Z|Ut&@jYf7[go 74Q^X1cF"w#HO9"dJ%Xn.D 1 p8dR8_?'';Ρa_e7`oe'RًSkU|)@)\.f,W_!:|$???"<,$(` ]fՁ,f䵰&'"a!!A7"9U}".ӦY٬ܹS``فNKKK?fΟPY g͘}#ʥ/߳w_aG7"z] ~vZ]2:dx{4o<7/;&ÇJrÆ KH 2߉!-$80ϧSٻFTDDx+  p <|H܇D~svd ) %|cJ& vN8>P*WYuUϚÚhUuݭ ;;*HZZZ ̨:6T*M{$IWWO=]'M0bT=k'HD"Q5d2L&㩦h4]]]@@ WQ!f 0PXX/***s1uuuryvd0򳘵h4PDܬ/nyy'"REXf1r(ߵOaUSW'*{:@"fWMT~gf0ӦM={\eW+_2QRi qϯ$RU|)*DxZgpJJJTuNnݎ@߲-%YڍuT*n~Oz8 VZuTr:o=l8Xϛxfp# !D𱮊Jts WEb?J%ۭWk8 #S:M>Py.Tl$-_"߯pgQX(DQ Enn.A%CQއ:RdZW8[mUCAˬ-|]0*zJ9 S bA~4dr(ή1\8 pr1 ? ~SG,~Q.C/I\JlP}1 ? Q0/(땬m͏3I5@R3^yҕ5 OE^ Q(bu`HJ >/A@ n̖dX<~"ÿzX@?xULihZ2LU-3)JcLB HpY,Q X2]R-A[(,Ff)3S?_˔ ޲VP 3$ɶE ["ϥHTT*8`cJ o4Dn=Ulct9My]ꁸ![J!kK-r '/$]wC[JWvE=S-egfj"015MLLa~xȂ=O8#v_M cҕ[)D^XvCKS0\cd \1Bn1\F1ZutΰlV2ٵQ$- ai)~Q-TUsqn1IJ[L1*_ŋRAL(7uItbA~ 1U4'B0zP@cf‘u3ЉU 2hzB\9daJ?M(#IVejoh+qT}9s n-3~㠔Qp(̂bA~Z+drL r8ES@m)݉]XQdFq+(L|(f4BAT¸Bu0@dɪhr$ Ɋ&Ti4Pn`bG7A*$U\AaS*b2РjK?/Et9b5 Rv}PE P(c1 HEjr{%$ 75{>İo(ڲT{YBdz&K7$WĪB\Y 4\>U#\5@"Ac[-WRXei"*<+f pWOl|Ur{Փ -Z4wpWַOm[7O?oc~|}jZDU3ZӦM0U܇ 'GV `\+>,b(>4 jX)\Nvkgδ&6}}32\G*20Z*{ƙS(3b},!+;tXi.*{[|j~!aN|@D օ Jpa8v4e~d>_af6-jԨgd+9;XO[޻߬Y3&y-+l"x}a"z~&Wd<"cp#dJ,GB% `xOs"nInT7qss%>'ڽg͚U#F4qBQQիg˦,|豭mS'?y4##sVVήU*2B~=J߼}qKB?b܄<ϟi۶ ^;s*E IDAT%%%4,\UZePesjRϞ off~-⪗קOT*tDyki1u*J-Zd.ܗh74몷[__>}NgΜ&%N>JoRSuuu-22MLM[ZW\8h1>ԩҿv!eeztW D *iؽt ~ 9)VDST(RAm ~#&z-Z 00ho߾xg*UB$+ѹs'Oa гg.//4pߣc9-,,޽6D$Kb -U8Cd"f0۶&=Od.((rjX+/4(.N^ "˺*'iSeAN{[G!#+KKɸ) #++yGV7ԕWCd2DѣF߸c6lRn߶nɩ/q N&Gܘp8nFGGڵkkP(70 FTYLT"%BL:8KlVV kkcFת,K"b8p.ӧN:d/wnݺ5vX"]z.FR hbmݥ=~z0L---S ;K R#yʐ(Sޗt"jGl+iƣ0_g5۱w:y&+W{YvYde/Yb񄉓$ɞ{׮Y}#*H,rvĐ@s-"(911))e_FF?X,=zZ >s%::aׂCBի[a5TL:+5_{wnDGD܌!ϝ=s񘛷$Il7D]v}vlIII``@ZZ ;vtsP}W/ǘVA~v2L~kڢU9:owUvU0}}=\N )L/(PM%zeHeՕ"Q>%%%=QY5D"4Q.===\^~YOOH./P(4d2 W&3J+(((3d>ubM+$hD>*hJaUzg<^1NT\,:$APs-*V*J(\Z e@qqq dM)Q(]M 4ãF5Fb;h߿tu) _Ǜ8aP(TF eh=bA CADP F0댨\ӵ@P;ͺ:ֶ-ZAjHXBӵ< Ih_Aj M h  1 @ a(#h  1 yBb*߄@P{ >@ΐH$-Xl+ ߥHT{{/p4ȈЭ[1$R$@\gZh.;3SAbbjnkkXc:~p rrr4¡^hΰl_@Vf:/vPomGAZ@q>@ a(#h  1 @ Huu#F6jnDo^xsU@10hݦ5}T*m T*uŲ]t^qSS&ajrY T|>W#;ܼ.ֶ>nÇgff5?ٳ`gg;<]_zʟe˖͚^~;sx<1WԬc!-JtgX9ُ=]ddee4jԨe?(Jjjʋ_9faaaieJaٶݫ88tMK'UmK/_u"hӦH$JMMQoA\\BP%jmӧODU&zȞݻO߾VVӧO#gu?z9:޽ӮmQFym)_'y={1x?mc/_9}ׯ7i mvʔw&ܱ Jnذw>O>,\۹s`˖kذ;zQ9|Hzz 9sD]zؤP(LK8zHQ/ppp9s͘U⨑Λwm[%Do^v- u:cnj$±J~nM48++`4i(1媵$7ߠ̏ģF:d?zHR$I9 0UTTJi԰gψZ17cng1%b*櫧̝ lHTYUJp̬7nP(m)[Cz}534$d!S(j׮ǏI$y_RRR\<=非 E.<~ㄿٸa*\d8i͛1˖.%) :xpaW._!ӦMoۮd2:vysG%''/]֭[5Hҙfrst읚ںI&o޼Q?|`!x!U?vU0 bq+Y*J&bq # $U`YgOjڿt%HTL&\a,S$*V׍aTֈzYaظqc8 `\FTdpPוK-~# `f25<4[׮=CoܸB{ I|;uP&>80JDxK'FĬ222p8ˋkδe{҂ؤh:t@ ֽ;S'O_DP?R _ )J7w;R$| $iQ"0oݲ_~FFFD݄wVO͛6N8yy-<,<ݨQcG5g׮!33#,,eell<賦MS'W\9} r%'' 75n\o yzW$mKbΠ_C>}jr޼ysܹ 7 gllܹswwN @l:LJ=zM0``r]uu٣NH$C!SnYZZr8n]:w!I -I~]xu?ΞxJ2T|` {vq8B>urԍhQ;ul?fYs1jU͞a'۵dRND"Mxvm>{N"afLpquv6e QcCBVXVvչz!|~A].Ν@|+;w"vcc--,(ܼYӦNQqe >!.?nlyztU((nD*feewQ=CJJ3gkWJ1cbutt||}7lܤy!׎:G]q˖%%.v5{p@,.9xݻrrr"#+;ݢ :8y򔘛FJ7pzr$~4lw;ubJ"=|;߱'LLM˔d1V'X,3LݺmkD l6{„ev :4::ٳgja~~&;8(tЁhr^=˟7))`4l0;;|K;wHS'Oݻ.ǡptrutr=sBe*Ko԰AW͛5{=8Gzu=## uJj\\B^?|ꏖd2MY w8kރ2<33kQFb4/ث烇u6hUIix|016.((sU99s^^>A.WT=r"8QNNn޽t sec\.pʪppeӧOٝ=wvʔ)_n-LJZnmfVZ}~ ;;͛Ϛ=(ǩS'Uy9}s)Jooo޽{ع+;;ƍĹ,_&sBBBBBBӦM7b˖Ç˗ؾ}ݺ2d!|0&L644,3"=`E_|K$HYcQQϣ 2T__?` G(:u6mںu2ٽ1f͚_B|xVaNrrdr!5t=:U0l 3g25|;q(,hnӽ{<}6w̳/{qkqcF?r'{p 9cG`$ 4qAAoJN.qRRJ/7+4.W(uy|fh4ⶻvjox̌3g5ARq'[??}Ғ%RRRRRR/Y|2:lXddq{= B,č7[UHIIҷWs0|Ç|||˄>/Yc2ɓeJ^W/k׮[nwRJG8/kllD. 2u6GYTV^sCر9R7U?А737oQs8qFw j5iݪ]+W}448쑓CGN9;w/ZdYA 9j\:hW~ēuG5rĐ!K---vX1cFHӧG e7M8}fbbBzzѵ*ӪAgڶl8~L[vؑL&<+y{{k׮&233S6hРUVϞ?#61B@[GgDΎ:iiiLvuqMLL,n;sߟBHۯX#ؿd*ؾq]t!6 狀Ϟ>}pW=t??a?}V~1N}{qРUW.1nz;dP*w?=rBX@qquuuFLsҾNҏ#E]NRfL|BPKKkӖAYbYDxHTTR"^ST*gG 0֭뙓x^x 'c8w:uʥWjz:lذΛ;#,gdd8qb͚5v•ʄx.$44dǏ=ف8$c]=zx:66v96m27L&3<}oo9s;vT2))===&&i^2*2rĈϟ*|69D&_p l\02LTFGPԝ;vԤE9uSxn^^hxT2zY?rH`0>zY bAj'.N 0C(#R;~g"h  1 @ a(#h  dۢ]kjZAδh"-]vf+ H315MgDa( #ȯ*+3]owQ F0A4 bA CADP F0A4 bA :,,,L<|Xg/c0:uOO/}aDEE1 k۶U8)eZ"F{w B!]>|Ibkےn۶*]P>Lrr[i>yRPPZli``^1 IDAT|.ܲe˂UU5$L& o~yssq+**}A"""p&ymZϚ5;::K,kqnn8wlcng^ --u ӧ:ٳ祼N153ݺu59>H*)s̉}jM="]&-Y_?aΝ#NJWX斔maaaiiثL&+ߖy4h ++^J\9g\Xgyŝ:uRGDo^v-+sM#O~ݻǷ^bH$(..y4B`bz6-<^>c/[[[@LdrIII+;Q $ +(MTjW"aff>XǏ߼usrTL&;pӧ9LثSRR^zEHҙfٽ%qS9]EXjՋ_ L"\c 8`@||BDdԤT[6y<ބB7l4k=%ibb"ӧ~GЮKvnv+^^G 6tźWV,_•K>} /]JPd={Ce RTkŻ8ϝLv<{–M,I$rdxM0ϩSP(jxJ_[j[jU(,zֿ?L޼in cǎ uQ֬^Ml޴aa\Cf:t* D"U!ߠ5A\=bwA;w?+W4mj d2ɹSpHhrѱ#Feee9svD!)TZRd 0 ,--i4%K?>?1s6ٲi =zlkԉO>ȤQ..<7vC<¯5mTOOo 0c윜)Nsss( w@ͣ0a o>L 6nHu=Ju>,[lSRcWW77oΟ;a=kUx/j՜oнGƍRAk 5Ѯ][6 J#"=Ub񎝻_o^!YYYs(U* |{-33PPhݤT"ر#qnZZX/Ç;utrK&DJII=}lm/1!Qr˖{]g66O`2YL@ `XM r~6=a29>{N:|^fX;wbr`BU[A:tЫc^={$R\W]GGZx(0tBw~RzFjܖkMJz:*''0MUGUP|S L&p8. ҳTyy~\FhXxIIɤI̛{7za&!{0?/?Դ|ك,/732R)I$+Wh4Ze5?xşUkcQ/b{ƬDÇzY~fSM|P(dҗ޺QU223ϜU~WMusc;wlɓj---6Pbp[{{wmܴf!ۧ{AAk׭/ӃVVuObRYUU"TQ ߦ^&\_<~$##  pT>۱..Ъ66͈t6::Ю][fj~[o[7iԗ411U ĘXZZRTxivNzNkkcF׼& vew)S޳wZY5 YYYQiivcll Wq/?_۷7nܸK.5 ?}ԶmۻwaP( _ *yJ?|Az|}S9̬kmڴ )((zt[c_$xk5?{NN%K/?{Ɇ v,ŅRe nhmݯVԺWԺj-ֽe+qd=1&!g]'w֮Yjhh5{"L JNJElFzZzbRxJA򕫭ٜ8a|޽'LXRR!>?w_Ma$fysn񉉽P_OSRR?]z!TSS-GohcccO ._:oWVVn߱S]]FMM=//L^ՍUUV+V,_[{ѣG .]"dԩ u}姰HOOoj "4W^]*j"8NSSUW4!mm*G&իD"!%fDV Ã߽+@ hkk744T9@ 455k&444DbMMͿpߨ.2Ý0hggw?:u55*VXXhn޿o>9O? -g%% pKE\󋋋e./]ےwϞfėL:NsQr (Q($hf+/./êKZԓTTTr>/W4^KY .OBz>211޵c&LYz rVȌ޾{B_g! On@?w, #nܹq8ESp> pp'I] 'ӧ7ǫ]nݛ7oek oȰXtysf7߭XA)?NNlI$y~*u.D[K D<ظ;W[` 1b PLM|rkVϛ;GCCCpKUuuFz;qTAA/`0\]?6~%qhO2,ZN&Xܩg}ߦ=zݳ%qE%nݞ"S( ((uB::cnjvvrIJ}L"s@2|ذ;'$2u99EY\\"z]Z!yOGGnuw9B4dꔈէDSS{]^V.Zzjkkiii.Y]uuQ+33븿 9 S@Ē^zu3 h eދdf>@݃%an UUUJSR?>!!޽}r---[!z-׆kSOBM8+[+7WWW= B%LmmQ&SDNNUEEUk'dffm۹!ŋ&s "u c' D"UW w7 1|SHȧsYQQQSc Dxzzz]egg'HLLrwsF{%T*!DG{zIijjn߹lO󥤦u;OƏsnSLLG eX YN/^ȋ Ӄ1B-| TjtLru%7nҿ~]\bbK?q/a*++ Ɵ?}(}.r8ܟI0`@p¢'ON>wIDS"͟W<_8#Nc+6oݾv P@RcCl[ZZyK^x!B] .Q& ;9\ϾSXYZ7No JUR/R B( é1"ɬd2F8sիףE$544$j+ ǫ7UW7 9˄ի-մrcmx-|Rvvv3Fğq8uRLpdL\.\% ů,F 'i3ϑx"QP(lt6;MMǏIz:`^^޿R2& `Gtj;޹{a0$Q? qRSSo vDA `A`j@@ wj55LfIIIIAa25UUʮP&ĝZjJʠAݻ+"ZuuUjj *?qgN7o!\{<&|+ wvptpA %@ J 1(bP2|S#Ԕ]N:%) wj쒒'< +0dXb]ӂ@ܩ1s]ήش cg q;@ J 1(N&';bP2 }ijԿ|wT/;wq,֙'nj ݦqXML_y^.FFƏYwflܕL&d|ϪwjЂ~+`@ܹA g㰡C7|yo޼8`in{d`?ɓ'm DׂG_̗X) ǫp8ꩪF8B444ihr[Y]]Ow3Usf BL&ٱūW7nN&W^ݫ~k[a׮ߔ(in-!mm3'O MMKG{^qn%Æ ~⥕ Q:KY ."Bx<{EիV::Zzudx#B*q+W,nsǶ;w߹jr!p !,^vHPࡃl4a8,۷ۻ;$8H!A<*fZZ Rfa|eqwyOGGmo% ##nXWRZ&^zz]!E>UUUϝ r]]\Ξ;w+,|u}}B!F zG_S IDAT`DEEGD*HTt̀oVVV=yEvM'O'\]!wUa,ֶ-N=tzZzƈϛ&[ > 8@ G<͕͙?o鳗\_f_z}%󽗈/ ;9\ϾSXYZ7No Sc0D/B@ hjjjq8Fee(3zs@]]^\Me.L&h3O^z=*:ZNmDFyy+*d枖!]U:N *++ _PS[+ ЌAvxE20hggw?`DP(^Ϙ BCUUU4sF+,,lll47߷Ot2`z2EMPSSS!^ӿ*})?vT[K_Wu@(-?yM_x́qzzFcccuux)q81WԶty\.WT*# LVd2/32t06:Ef݈D#c#o޸v ]|IOO!D65J߹->p-WBBo\.j7q8ܲ?ߍ y}>Qȳy1QGorE ^pÆmu˭q["ډnٜp7*",0##<{Fc+zkhώ|׎[3PƽmmmB޾BL>ɓf{3~@_!D$D"ϟBЏ3fyx֬0HbxoW=!FիÇaMJKL>de4gW/^!w:nDKK Q;o;eH;>|>?++!df֗Sϱdv]:r5k9Y-^pqswtv矗zz!i.Z,h ?m 'MAٵ3>!} Ftsx`2~{=vbȰ#F9ݑ(',N<]\{qYy9֍x<![UU՝L&} YyQ>D"k ]<x76w+V1|8B6!1q1XF())}4WTe,lTjkk޹cӖ-nVh{qhO)^\=,-{{y1㆏tܹ{x=D⤉._~~{s=svu7aȑ#S>K/s ~~] <[uŗ/_Jok@WS[#1XݳF1̙Rs8ҹݼP  B=w?wOŦYBzO:- |C iV#F$&&{oeiI$-,I_Pz0''g`KBBbW#&&!SYYe``5rĭp[oJoԴ(uUQQֵkqq spUzFB0,͛ط{HhxY>|_"ݫÆ),,6ѣXTĶnjo><,<$%':۷Ǐ;sPXPP(^b2B(>!f#^~!TRRk}}ә窪v8WXXԢ3W_WUWI33׭Ym߉Z4 .fE$uFۼɧW^^xҿSS\]\{왐ζG)Ra!TZZJ[[[SSg9񚚚i˗L"Fc..;lPnccEE%\tYBHGG{Ѣ_йϞIu|B?K,mx>:El99< 3g~dpHxnZ\#9䟢҉By*Z.5-_ z-n|6tttyXmmmX1 6,++b-eQUH*~!jkkڛ:ҝkO۽sGYy߁4{ #>|>|S%|󵴴_~xw:N];]7&:t F[YZ 2xo޾eNElvaa͔)ǍpþcBEEzXb߳fPWS0iP(455uvvHf#r܄aCJ&}ʥNdld-g0說b B6XV^줮zNRRf`1:DUTV;w㭭}}VV**_!*7h *(;.~~ɬۆkSOBM8 !T^Qt `n pg2u3D SS[+QO^-///(,DeMN}>| /^9r]y%0ں_С&Bi鮮.?b)sf~qӨF.pwS0Ǐ򋈈==x|VC9TjMMP(^S&K'(***bMOH13뛖H>|!iSBD"qw>=k&B͝3;>!͞53n@ }H$:;;:,-- !=o"ҿ-۷/_ZxvVNc#n޽{vp@x s122Ng=|..P"iSҧf$w77ܼ޽$54hTݨTZuu5BNRgܼ?BHKKqHQ&a\]@{܋7B =z]tP(MTOwz}c@ sBPċs +n|¬37M--E.SQQ1:z N0- &))Էއ icc,P(<ܸ֭kצ8~ȈٳfZNtL7nӧOHP@HPWjjjӤ$&%!>|~j@ ٴya7Dh `2uvtJ$%5O`dhqO:K=r($(#vŦA?QPPv+,48.6Uֿo4U5֛vDXhHP@Ok7mu˖M1ёwn:D1Æ~JDϞKGSiԘ[!T*U47Hx3$(`ɢEOdI|ڵ3~yhO9d3޸v?φܺߵ{Co;zVQ ]I_qB%e%k֮_ȘȓhTތLJN  =k\}'.˗.aх9~;tSω ?{$B(;;''iHP_ڪLzk.?EzC9;;MVý W:[r=F]]5CUUL&7UUUD̨* iiifmmhLD]MEp8fEe! `0Kli D"VVVIf9"UUUMu>N#4Pd2FUTT9}QM$bMH(//C<Q^Q!1.o/]<Hup<O"ܛإJRunC4*UEEEӫ~?9s\;JN| ?v#nNrof#hyOїW)[__/')^P(k2<˯8P]%@Thg@oTcccS'12+@Ԩ4Zaaaccy}<}*'=W$ ˬǓ@ }=wp~23߱c܍! 2>r2fcc!i@[p,Oڳ^Վ}tZSocp5бijj8~H"5t^S0:mwvN״zftc ه B|HBD @w=`?e} z7;Kʟߴ1{VoG?_<f@{(J 1(bP2d@Z:z|,f눳ށo}.;I+3im  OZ[ ` 1(bP2d@ A %@ Jfff4MjߖljTkY_"vQiB&i֯_+S4: 0*))zJ@ A %@ J 1(Nܼ.]DoMMM{)zimedx2'/Գ#kM'LZvu| wj&N;g-z;asg#L(.EPZ_ۧ;ڰ f | wjY[[auuuYL1:==!lȑ#I磪*L&dE1mUx1ёիV::Zzudxngclt܎qpG_t1VHtTı#)!CCOdAv᷈D_ތZ|o^p͟ z^k׮#={{!aR0u˗32Bqw[RkukVfBOd;nvO|!bbq!fxfmm8Cr͛`~+$0(<qE%nݞ"BBBϞ=s#ŋ`%ܲ>.Sʪ*50:dҢN:S\\`@ }K...)ؒĤ$[[[ݺ!sEy9AWUUGX,PE@d:::fk;v oxIf=X^{nذnnnA! <rQ(Ix_LPK:BK[KLMMM~Πήq5*))[4rҲ|555v9޽l!7wFP~~5BD"M4A,ZC|B D"UW w7% 3"22!ۗ/_-Y;Gʤ5ѷOs!--MQ#[Z+ lR7؅k"v5 Zv ׮[?.:2<:*ٱӵG!A7߿)^vmƌo^6CQPP@p[!{:Buu͟?{6ˍbINJ4Bhͺf}߹ӴWL$+ IDATZ v=rPpcG Z\ϾSXYZ7NZ🤭]UU'SWSkr\B<^QQ)1-@ 455EĚ \n]]h!JP(؉f1 XYY%Ix&M A~@~0G ZLdU Ay%0Xt>M4;i+RSS`ʖfNn`j 1(bP2d@ A %@ J 1(bP2d@ A %kUt z7Y8~c;V:v ĺG?y^/UwQͦv V$ #8F}1Ω}Eaý r|X;+>@UUUGN..Nkb9}r̸ yFٿ铇=iS)))ilmmV._w`ttL3k':!^r}9X miRZDM+UUTꤞIR[p85"Шԏ<^cc#B@ P(TUU]bD! " KT|Wt%9%UFOT V\($9%%9%E<2h&V=2,?DJS UUU.+g[{mu@, C <,AOb՚fk}}D"xB֯'o#"B>>z8fa,Wtt5hРK?p &^7OH(<|h0ڰ~Dڶ}D{yM?o.ۨ_O:3{֌cmm݆>Ϟ?gcqqØL&@_fCnŭ^I(nukNSP&w`2\n㙳gg͜9fB(0m۷l?qʮ;4IdrNvk\=ڿ_?_kjjfϚIP>,YRO,}|6P(|`˯[ӱvu>ʆI$l8~Fiӣ{͛}B/EELL%eh`pA]]06=k\Qb˕މK<=<Ǝ"&޽{H3lVQQ񣡷¦MJ$V^]PP(ޙ***_KJ&M_kcm/jJ``o hs^ ^pqsx%w씿 @ HߒH"!Ͽp8=.!mm;w,_*3Y3Nf=|XPPH$W,[we+s;W]@7wά9ssW_c d2ٺmGtL_|fIS޿ϣP( !4t)'yM^ZZw0qM&zM1sv~AÇ=~dqn]=GO8cMhhhر}[BbciTÿ-O&6Z˗! 7d2\]]BBB ⟗XzO{;s ?&N8}6mz3sƏk׬8 + '`m4qg͛omڼdܼ>0`@ÇJW_/^4mi% ck׌?Q [ZZ&dn%$dey/^l|*ijj:p8}{̞cn*-YkW#WwϪ*&)>oobRǧ?K-=澽puqIHHjd:7oߎ?̅B!!6tHaaQuUiƢ"585--"2J~nB n hPp$fdn><}}=.[ZZuBZziݺv5חL|BB~AB޽>upn_]&y|A=Ϝ=p\. (r_QWS344(,,좫-CjjB(++Ǐ7|Ǐ3<000@+'$lPzFB7_JjL +eV}}=s'O |>!Ct.  55P\Μ=WUUu!{>1)!TYYyUw=u1Ϟ4љ]L~;<|djkk^ivH4˖_lκ,Vnb6a]fhs@0w͛{{޳ϯd2:zzXʌ{8M%%: aX)fkkiUWԊ8?^;;9.^]͸*_V^.J*D tEaǓLc|"Z+kQ2)X̝(D-+ l6y_vm'NKKgbEol--=u@\QY9 |A,N .^tyǏ\^^^PX >c",KVŒ8$*:-ݼbO[vۯ[.Z\Q^s9\^{ߗNSQQb^4eElvEy9N#9".3 }VK23 jjWiT+˕|N\^`Eg/Y,P(d::ڨy &)z+Zۛ7o!D$ ݤ w&{-711F ;w( %!1ѴGgg',A.]Qn({wÇOһw!<!VD"kW#Pm=n!ccc :ڪgOӔT4Q?=vj~ziSBD"qq2NI$Ruu V[[[ծLLQw%jQ555ZZT*ʕމ2wȻss͞5!Ι }Lwf͘2F'|jNӆڷ7">v Dݪd0u^䏄ĤqOBCˋQVV%%%:\]]S]]f [f5Ba92/or]]\Ξ;w+,+W.]QUU?6e& oH-$UUU?~ ֩lݾ!tnɹ3h4ڣǏ^\b))G"I;vt叟g/ёuu ֬Æ`w1k KHHD2^]]_Ϟ>Y\\RYYyfЮdW4$( WM(Xn}}N$HһUuw>a8m voes\ltmmmCC Ʋkmt-,,km{zuHOOoj]Sk &|MxOT;\UU%}jSĥT*J\p<5@ hjjfDC|V6p/:8[WW'ϯ[6YQY) UUUDbMdc-\nISdnKR)JEE״ɮe%Qjj?JJDU.+" JUQQ뱺UVVjAlshqcs~l="YgimSGzP(F|<O@tIͱ˕ByHqSS7oTTTHI&+m+dyźJDQ'uMaЎ}tZS74SxZ1~qcTTT?{lʮeqFB/}BD @n[;zs~;tX]]FsDw_!~{n|L;*ə?!d@ A %@ J 1(bP2d@_*GHMbi1z^ }Vo6%ɠ"Q!ĹE6ǖニ2ܛ 'xi*޽*G8sG>J:dpMM%N26g_֪ mhڣGTT߁2ӬXN..NkH={i}Bh)))?_b9}r̸ D"͛ʮh:{O4b",|E]]B(IvUKўwƷa,ֿD33r1Al*-?-[REɎnL-C͘9)NG[[9c z;3y, P:U}|/X8B.k1***أjK/I?4Mt:mxt8`xtg7n/!2UUU%*"MU@ 0 [ "] H\LL3ah  %(9&=iF&?Qx<AdJ" =H[SSc`lc,)KNN5kW (K2yzxleŸܹwnbTj}O1 eBӦzFGތ3S:{AQa)I  TTT|6s+4ff}^^S#/_7na ̞y՛ׯKmᤃIǧ-attG~姟n۶5a~%s{2W'kƇύ}>3=0=0VmĈǏm߯?=}.~iA'~wyߩ?5{~>Ytʩ#?:Tq.; ׭Y=qkN8֩Sj~Ǎ{ oꕉo<^tt_oHI q֒٧G:t\] w}e5֐קO='ٲic}[v7ڳ{~>q!C>dY,ګN8~0@jAA>Ƌ-=zԦ=c[G=;1C<} d2bcB×,]:f(zՈr`o6x5鵸RlӦNym蘸y[)M"]j֯ 6lDԟ];iG>;<2zO?oܰϝ6gG?`Ac_zq#md;L&s{p0Df$IkO/cFDELx{y}ɲƏ| J.^v͆ _DĎ=gfJg8b[o<)ƍւyzz.KFľ?/c7q3x3fZ,`4yoݻ/w\2"mfDm۶{9zԺ6$$Do<<}͞9?+Vo˾s}/:6w[:ƍqa{Æߘ1xȰ1/t޽Jc${gΡCt0)ɶY׮q8@b=}t:uM&뾄x:q bc&䔸XɹQʫ<7.6f]3o2#"M&ӃOiؘL[СڻI}SO:tDDIOZvHQb9{6pL(((?y~nn4PT{wMN=8ww/"<=# xΝg //U,kq!TR% WTm &:L,k:zO.] >.lz(߃ې Jե;t0 EEҾ}LII  …СC&dp:--''^NΘ1كǮ ֥eSRR)/ݻ>>u ۷@PTwd25zuu_P`t^|YQ\t,0a}N^ރwߙsJs Ԏ:DGGo۴iCOLN,@Ϟ=:sŕ>ɓ F,JNyvd=\\\*}r>>ݫPK =bF:dӕVQî7~A.7w^j{ݽeu#d'˖-.f?$Z~׋~|!VSQ{..._`0-GW=]edf~w@MNIMu<\yFZU^Qx0]@K/P?x0駟~?ϯnSSO/]?mAAܲiZ2W^!vl܃k_@I7~lǏj4N7z ޳gƍٳwD~ݷOm, IDATeKX$ٵkڪd2>Z̟:Sz/ZCU*P(~ٳ+))}fϞ93o\._lTi^#[u񧽻5 wi~l7~nnwZSS Ȩim~jZ:ѯj:%w@F Swkh:~ծuqqaE$ IUTԔu$YV͍ JedbV[m>`0"98AbHR^_bqII7gDnW6dec^(Q{K=iZ}qS&UW?]@׏dC9P(Tն}m6bx<S* `Xnnn1ֆk\w:^IrE#AD" ޽kk_(jrC8FB! 1B9brgasgnfv5 ل B@_*.!~J^X-MkMPkCɰ|% @_G]5!'=bԔ(:N ylO`hhoJϝ;o4\$w.]-j._np59 a(FK/%޽o޺j jnw^zlۅOjӦ#t0d\uʣ2 hlӳl&YQQAӧ+5utߞݻ6mb@P^^nX*`t!B@S&6_FF`7ozzz\< `V*&O:e[֯?vDLXdY%ƿ>ߏd2kwY˖}%qmSbcUɧss 5JK#%%5?(0 >#F-D"H<}ڶff#C+**Ly*oXغ^xƎ}Kwm*K^^^ַ^^R^1TmۿM;sA=84Z#G>7zT``{mߟbK2Xee?_J}٫֬a2<S>GRc8rtڴ)B Iϯif#F-SɁ;V\y{λC~s"T$egN?b11ݱ#`y|\ۺy5CF3d؈ӻݻ{WYY˚lG*W ||`J ?8j=NzO'4##*~Sjsdu 0LXjlZ6 )u}j IB9P(TՍr2`~ph5CM^X\]R#FYfBFa0 r6 [=[T( z^P`FM &Pn=k jMiȽ.:^C0&D M)0GQ2 L&Fa0Dз_?a=!`B0#a F!@B! 1B9br0 !`B0#9&H?` L3S2 _?ݬer^ >p~3q@<`@\~5뺣 L$ IM9Ũ_ӗi`pޯ63qC ]2j%d2l ԝ^gs85Նs6u&N#v!cmo6ZmyyE#O_Junl /OE޸q ,VHn׳o+Y,V^= >y.f9`0z޸Q!D"p8O6 C"@ZZl&k׮wܹsnd2A鮮:tׯdnݺu]Ptܙ$d@նm[$Ϝ9cX_6mܯBQܮ]@^=rrrKT~u-rZ,//IArB& Wz5:k*Z(.-IO817?{[B-V]xm6PK$US[} e6[ΝLJܼ'-B[^AD@Q^i4+**ܹC'D$I۷k׮ ryiiFiQCvXRw%<K"IJ%d*%`0u:ݥ]wba!NE|Ier-uww!o޺e'όsf|_Dߌ C(ե =jd\\\\Bd2 zEqqAb[I$I_߶ER>>m޽Goqqq _MD"Qpp0Ll\RBBB(p¥Kze0.]D_g2aaaEwS|||F˗F[\nHHA\.{t?3m`ڔ`xxx Vt7LA(P*]:wj (:yI<93\`4XE5Z[1X_7~3`0ǰt?]B(6L'S$G9ßQM&i'M Ԫ|`~r~݀'@P+WK@V[@B! 1B[ͨqPBpB {!`#F;|…6ts?~ҤI( F~AQʕ+妥}`lvm۶780ax$}b\`8qѢE .$Id_>))d.\p:p3gV8FPV b/#FXti`օ&i-#"#cbSCF=,ϯGG2dȸq^;6:&}VZU)jwzر={FEEմk bqdT԰ N+/_xȹ?~IǪU/^;gΜK/\ذ Aݻw֭mڴ_~kN&IIݻwԒس"cǎW^m׮J T낂'N@ii˗j5mΝEY,3gAn߾};vrȐ!Ҏ; iQQxxxaaH$+uCr5vNf }Oܥ˖m%a :udb$sss=%VSRSoߞ~H$LJ*#3AlƏ ;wnZZ_ 8}4(ʬ/6n)ڵ*RuaMʨRtww 3f̨͛ϛ~:͔)۷o:¡ PS LfLL- /--@0j(kⴴ4@y3fL`` vΝ:tX`=}`Xժi:{lppp=@,GEF˓SR:vCmӦ PPPpUHT jݨo5A_UOQZZ½zG} l߾}ҥcǎe0{썉-'O~%'<Z-z#NIDATϿt[oeA~믿&:R|^bO>"QP㮩G l|[jt@&͛7o…~tI^߸R&Y\\a62L;0#Qf@A0 eMp1Ba#a F!@B! 1B9br0 !`B0#073IENDB`RaySession-0.12.2/manual/en/images/audacity_save_file.png000066400000000000000000000563641417052567600234000ustar00rootroot00000000000000PNG  IHDRn$sBIT|d IDATxw|]uofwM[: ( Ӊ] *<8( RD-t$m2?*iM׫9߽I'gܒ;)P@i{>q @a%K &.(L\P@*+O{M嶻{ :CzkPߪe6,{)3(3i u;-yi[F}Zlq Ke4̜[Qh2u\v띆o068 sgu\6%KZGC6P%K Fqמ{XaM~E9ggmiaock|sɮw P3iҤ̫maock|Z#>/~sڵ*ڵK92[lyJJJ7ݻwƌ޽z-HiijdF UQQwluܺd֭ۚ>5ҿo>~ҧO1[m۷oϟ/},^8\xA}3:559rD.}.OuuuN:444d9ofޭ[-^SZjkkSVV~|in\ +\oq2wlֹ䠏uut{ 9sg_Ѽ9|+6)?:tӭkTWWg-\o1lu.E2eJWuϢE/|1555+]qt}?e?ʃ=#G 秾!<+O=ts%y{gmM7ߜ'8.+**r~+/IyɧVkק<_l7vLG$1&MMM9crIϗrZ}t)7^wuF6Ob8gʟ"Krq\F4sv~sǝ/$9矟'IC>gԨmsʟb[[ZZ)SkWOb:tz;vtt,s`MMMߛ2nrnljJYiiԔw5W{t%O?{͝;w͛7o>wI~pyoWXȏG}*-5W2?ճgz왦gO׮]OrM_V>}R__enАt̟4wqǵƬYRRR~zyf͞C]n7k[d#s_iq_=~gsOR)))ŗ,no~Nӌo<}o,ONңGL:y7*VQ&[n-G}iihhh>ߕC'O^Op\**մSN8p@<lVEۛ2eJ~晜v)ySǀۧy?;I?/;v)mV6}YSNO?O8!Kw/ '(7]ue5cg_e0ab^瞟3O;%w9ܹs~r:uZr'On]?Uqݞ /nN->>pg޿.\ qV39g+[S]\ɓtUoYg~9srMccc^{mR8kͿ X%cwz:9Gn]cǎ=gNfGUUjKCC2.{_<Ꮼ4JKKӫWgΜ9+<޽[t)gΒ%KVַ7=έxkxwA˕Y]ܬyR_7I9hgCQQQ~|-<"ؘ3gO]r[߲nֵrcu.;߱M^}\w=B\)II&O⮫FC\ɓ[+SH q @au\6Vo{`SV/ 5խEO!=>5eU{(~qY}^dNx?/$U\.V1߳oO{ n\q/|[m~#Ȯ'7{WJK|S{GƎ]k 6o~׶{{Ct):tXg̠ۨMGU:6lrkO!)++kaҰ-wۥ: m![{C˻v!'LoM7_=|ҫgB]3jw0=9;l]#hlYV q7ݐ[}]c\. 4AfM52穬lo}# 瘣JM6iaR~}2bBXy'ݺuk>1 xfk?Eٻȣ<"K|ڙ3gn?ZjgȐԱc^?!K,i~_9:={AfҤɩ5+9bx2мLEEEF ŋdĉiڀnG{e{~n~C:vϜp\8\xgN8.'~ yW$C ŋ zd֟sN{ܲsO<PΣZaXv |OO&qyGd7'rze~)//_g? 2|k_W'y'S4ir.e2uJ;_ɓ[n9c3zԶ_7v{/.x-QL߾} Un{}sO=?n53l-krɥ?δ[V6}|ʾ읮]z88p`f>#7z[f͚>yxy?ʄ/5O{dƤCeef13-3gVk׮9g͇v^_/rMnoLΝ~f-7OCCCȣyOi~?s>=2izoRSSV#ۮO^7?{_ʗNʕUjjj};ޑo$ѣ*Yg CF6<Mb̳%IJJJr{͵ߘ$9ͯÎ<&I?p19K_9->\:w:Gm'|*gqjۻRRR v:\+h2BX{c̘yך3gNUyW;g~j>z'2a5G3jwyW_W^}-9 &.sFy\rgV#s| 蟽>GNiYpQjdfF;I2l-׍kœ=z_?# wIöQ<<߻˩_99}d.Unc}>lͳMyEy~ev̹߹ ZO/UaUiCӦw%ꔕ=1[o=2\wC^}FGεߘS޹9f-*]riz2ZMbGyD^1#?k׮9ؔ?/q~}sC?}?w~}-+宻_;߱M8&I 4eyֹsקc>*_z97'|L6U>3cƌ\+RQQ^yfԶݿ7'L̢EZ?7 jZˣ<"[ljߤ~xtRUUܟe06:4qg;wwwڪysoOYfj݂2eJzCgA={Nvavy}ƌlµ/^nn,wNdv9'L^?!/bSO{u횻/o76={H>Eskccc|0ab.\|w3r$Ken֔3~2gΜ3f,X0O4IZ~oS婧}4x7o~x 28IZV6}=dΜ΄ W^y5 ,ȓO?MK<>bxu$~y򩧗{K]СYxqƏ7mz81sfǟȀ-_9y6ir3~KҥK:uװ_{p¼6irV{~d֬Yyܲ-NSSS/^ U=hjjZ̳&J#{_߶z5ȣpS޽z?R[;/ݻwm(MM_)eJSSSvmgx27zok=˺Oǟ!W^y%'Oi~C>{} KNfΜ9^{[ݞ=޿[sVXw]]]~?/&|P.rq'fM4w>/J9SG'뮿1+M6YhM:5|%"IZa~If͚u%XekʞӆַeАe.9iOYһΛ7/翲vccFjuM6=\wC}?>xz쑒|㗛aˬlz왚,^&fVWg7{la#}]g…YpAUUU]nfV=^ݚ]uu>B ݝ7oBy8umbrM͜Yݻڑ;{O5kVJJJrO/ϬٳW >gI^}<ē:mZe?W^ۍ!4ǝԤK.󶛛]gO<>_z9555׏dѢŹ^3c_$'~c϶|GqV:M5^33HHSʯ_6ևU￵f?7}> (SMO]]r_/b6|u[ 5skR_ߐ/QkiNS]]]tkݭk)[Gv%]̯Kǎs^n%%_w?_Ν:-7;j ,\ajX_%ls.׷iӧʫ楗_^M25/8>>v)X͒n-وM6=n#' )))IU7o~gɧҡcr~o\5lؖճg^~8~B̝>~HݻwONңs7}?qb˚8̚5+ho:sЁOs^lcC紡 SYQK󍏖յKT_~%SNIL2%y.;C+]feӗ5u;$)++.{o} V${{һwt% .H݂Gߵ;{ΜlI~vvc4?Yxqʌ=jeeLv9SS__g{.39u;nIG6luƛr3MMMy⩧Хtݍ>?Gl7ftL޽[G$KV$55Ϳ+++KU[`l=o5y&Pn?9mh`M-{l]ue-6 IDAT_|}_iiitExaΝ5+[fuZң Ft ҵK,^핖sN7 [?ŏ{[պ\vɒ%Y┗Sb\x+q[-[ ja@aeeeJo}rX &.(L\P"V3zT{6hZᩧi!ScFg y͖X &.(L\P0q @a%K oA&)))i񲲲 4(}YJ[Y'wJu 62.J^{k=ҭ[׌t`޵ӎߴNw3b,Z(Z|O3wn<‹= ^{nܹ5=֡Ce8Y=+wZ^r5y/u]zqJKKԔ_|MՒuZ~4$j]n X5;k̬KH\oy%%%秲2?`:wLR̝)Sfy= 5ۍ2}ˡ;8Z[v?Y.WԔd)mqX#>/~syɧV$ڵKm:(,/$I~}3sfuz6ͤIS=kVJKK3r444dK/y]1|X/^ '6 x]cF6Ol_ .x}OOÆe Ig7uu>6l˜e~]]ҷOswsHl7vL33et1 m6[=9e9ԯ[eE9+'ÏLm%@EEE.r?x0O< /<ƎHd@9Ϥ)'wLN>WN˳=Ν:Q'Yg!w󿝣8,vlL9sow=;2m0abS$[nE._'F1|^q}>Yi%%%9Sr=oLxaG/ƛn 9Ir>6)--MUU|K$;rjz[rXh2uj|/C+SWW:dan̛?/zl~?T&d֬y.`AL޽{e;n]^1#nd %_4ݖa_^uM:tHꗿ筬<5WW4y$<%%%g߻lfC;lvNݳV[e&n~{?͵V?v[\Bq昣̣=<$_짳;g˜9sҥKd;9bMM_MM)+-MUUUn.̟N;Vۘ5kVJJJrO/o`㵮ڤ_Cۍw%'|ӼI{e{Wx|ꔗw#;v옪>}F,\ʜKC}2GYk-B0rm9꓇7OLCCC$]:tƭ1yԼ|OEԩSP|-пF ҥM?|ݺu|%}Qx$n옼kXiӧ{0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a]p |m;֓]y{u3no\P0q @aǴpn'%Gɀҿ}`?3+LݣϴiҿPX=P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @a%K &.(L\P0q @ar:pru 62/l!-Xq@8-%K &.(L\P0q @a%K &.(L\P0q @a-M7Czڴ=x[i1.R=œ @a%K &.(L\P0q @a%]޵´o9W\ˢ-p\&{=rI>0<‹=uMrYl|CYeCnʔ?o^{`kk.?u's'o7ݻwƌ޽z%IJKKV#3b%I :,|]ӧO׽С3zT68py6[ga)))ir-Mef˳lk=*_h#-]w.<;ftjjj3r\˳~fA]]t)ʗNW~y5˟q)}F-[4ײOWy .Jm*U\HmH|PijԈ֣OӾ/Rr=4z,zGi*88Hݺt֛o_٦uk5lPC i2 CVka&>5V+W0 ͙9M^}WmShuz%IM _.KԴr\jۦh{r8]7jH~MiJ*%%U$e(!!Aaau}Wlܩ$u}tH+_ۦ'{DMdN"4uEݺtSԮUW5jh-[}lŪ5 RV6n?,eLƇˌ f){Ӕ"˥֮MH֮/d=riӧ($$D2MS}Ah_G{+-n]\.ee|eff)((},-=~H, -\25>\k>5={芘h56mRuN^~Uw OCG*%%EaW_Ys^Y}/rLV~UppNv#P\V211I?2K HXX{dn烇!5½7nT}e/֮v 6ԽCt18KʿsYV^)LϔzQxCْ͜\M>K4eLM7F˗~L^׉eW6}M0N˗~'I63:uQ9`+yuw=u{ nE!!r廔Q|`@|}}`*zقrkEױC{m|Ku7<a|XV?^-[%y>3+)eWvEplNZIu7~W.pڛdЉD1%vل' uY}P=.#\^G]uWZ?NȞuVwK>N$imhzӭ7}wTʲKL RTdNef(1eggK(Iy;*4eZKg+##R,SP`bbu)%&%kSLtBBu%8q^UcåjUӿRPrgwP]-7WV(<\ݺvafIR޽5zH9sF-[4גO>ռ$I-[4׌u"1IAriSY5QJ^#G*+lL=;[_Θ}HZlSVá\:Ǟ5z=vLחnףOՈ+|~}w9޽N.ɲOWy gPXIDAT*&&Z,]ƆOK:˥11z7tU6lzX3R6} áOբi2 CsfNӽC幯q}z'JxV0 M?Fk֮;/Imh4di[4xڴs\.YVh:wXn?+N%Ij ?xM-~OmZRÆ 5dp)0dؿjæu%NY \z{$I99ɩp7؍CՏ?,a~0yyy)2"Bi'ORsO~ԨQbl ѣԺU+edfqFESrUN5"F!ʲgnhܷaM6^_ۦ'{D|J@Y<MVW,MJJ^ gr@dx)88Xiu}]ΜIխ+^)IRPP p5x =kJKKS:uJT;>&zGuܡۯNjJKK}3tP^G~عhDGi$F<Ŕq<%%EaW_SJjj[* VUaaaJN. RR)j*44D.;i/ݛuJ󬇔SO?/,#5.~_.ʧHʼ uM7i %Ihcצ͟7RTddpB?<ѣFf+~ƍwPGII 6Խr!:z옎x|{"Wаay{{+??=سՊr~VΊ)$$DdC`1#ͮo5c|~=#rUk>ow_O5u$V^?gO>Sƍ)33SzuDyq]wj]w{󖭚>kϜIiUPP:c{qYzz8tN4I:{X￳@Yvbck͚gE,O9YJnnNu^etޫqb G}RjXZ љJ"UjZ{$BBBe(%5_Kf2eX, +Ul]- F(bvEYsIߗv \>>jذAu7.Zb萻ԭkWk{]нa_/<:*TW[ב -7)/i;t\{IY%P ՟垻 ijuΑ$=4z"#kD[.ą;,??e(::JJ)))JNNVpp]|A=ב5jĔ }Z`РZ~}"#"t<>^dZ>^ݻ̙d>rDVUSDw*(aaauM5__ǎM[ܟ0 C}fMPzF6lܬTfm6пLTJjrsr}WJNN$xޢ˖ryۭ7km| Y,m|NHne֭ߨn\VZ-I}MOh\)Zav$p0 {ڰq ~崴DkK>QMuMϫeqںmE#$5 nYuUDz;pU~enkn7*LmԹsr^޻W{+bn4P7mцuӍm65BoziJ4噉5:/4i}ݵQ=o>ħtۭ7+)K4zW^V--ot߫gOw`)I{h32套_zQM7$=_5q̙31Oi;p,˫uy?w˨ayUyf,%\5 i׷i݆ڴsm-X+,,Lj~e3IRԾ]ZGް\zaj&x|dFϓOjРڷJү!ۻDrrs 6sϵZv]}zI׷̠snGPPٹ~TݰޭXppP}9X,ztT/,{N$;V0 пԩSnUT&MnRVV!lsE #@6AzkbDzbq-~}9o=CIIr\fWa?_|I͞v}[IҶ;tǟnׂ7_S~~mبhIn׌IO);;[CGԩS ֶm_*>!{?>)?? ԩ jIZRեs +T1:uUa] caZ̬ PHHRSJ QffNg,BCBU1+~#{HYR߸vns\.LӬԺN0b=hZjQ?NgѼrvVIw~-[v+-=ݶj]ﯬz7W r:u젝vf+9r}.Uj ,vu))e-pZgfV PV-uC~ZbUm5 );;4wZhb:Y4ѲR~^ ?R`YԶj]ﯴz|1- Im͞e\*IOQA~G1^^y5ǮU3#_U/m۶_vTbjֱC{}'8SLj DPSx{ʜ[%PRRS)oo&joo"#"CF75@KJ:jѢ#NS/R1I%PLTbbdۢ2dX,K*ya%cK.#\Bi闬Ui@-mS,ԮWnC޻O&O[ЬSm+ޚ1Y\Nbi;sڷfzN3M)q0 =?{ JKKWVDDK*%P r`iӓ 6s]|l{m|ӍZ6t5B#Go#fu$By<g=43ghfUmc%OIM$7lSN8ogڻwRTN2פ6@Rt \.efe{fppLT+v|Y}-lZrhTsڽg" G%˪{NNlBn觃i ɲ5KZqO¥tN9[ߴYYvXPYvbckgL>SLU˗tH\}b6CǍъO>VffuDbUƫVW3NVP`sdY|J}bVku7MS[߫GS][S^Gec%>rl6nF O1118mؼY+W}Vf EHH,550 @~JMMso N;h]ټǪ:)RSg 6%'Q֓_)Ej1өOpor2Jl#Iiii\]ye_j|~"i*##Խj˚K*_\\^*lWDQըch,((~3I;?wx9P/AJM@ULA D"<5}q{Vi- ウ|TB 9Ȅ7)VM`;Z"=E`s/vs0dI = Q NɰqBȴSPL9%pEWR;bJuJbj(uXn>D:;]*jϜ;. HӧN.--kko EfUDEFzanKkdrhH\(*.f HAAD"\.[kŋ|~Q*@PF f:M1ilD"XL.[]SejmK$Ӫ{1~.a_<d.,*#WKK0MM6; N#6ɉ؄كtvvUQYϗN) ,˯1@&Y[)<|Abdgg'ulfaqh0{DUoێ&`okS7V]jM..;|5iN//ϖVLf4@ psuKĭ|2l3bh&8͘qJzM0i?reBkA|I~߷l 3zcO^hV`{{E|u>!k|VS[aerʏ>dۧW_|*ɤRT*ͻgIiw e\L40#n$_[j]ES'OznV&g֗Zm)1o߹e }dK,.+/wwwDoR.a}rJjL̐Ʀ>!GߺcJL5 Ԯ={y$1Um:ْ.^NmVEÆƑHWw!)y/J$p\k˜8a;gΞywURIwv{owO3 ч+_װI}+X0alE3qp:NgJGH ALyZ|>Bq[@>#5+Vח폭gΝ?~┅*mm8rjk;>>h}?q A_9_~ߢ} |gصAQZjWƎ9%cnjJ|E~~ jOMK{n>9/-ĺ kr%\P͹A_~f`1M✙I$N{ZM_2D~%o;fitm;Ξ73|IۆQ Le"_\ ] R4ɺ=d2u28y;zyc??^[m2ʏ28zHSe}pRb\l,Ng21:_ƴ a0a}EbsAݶּ@,SАA EBgg,0^>A\+*({,酢oku;NccSdDgcDZ Op8a}4^- _}GX1M:ik`z㵥gN9s_~Ư2~Uo` EԿ_LN$_H2iQs#L4pP\RIP(ZmʪW6ZVޙT*1¢qʎOOR'DA=8"٭I=,T*#=v Gy7#uk_xnffV6G&h2ddfir3p9m m&?!>~@ 3~QIRSRF4p:cOSӃKA|mi\\LfV6g2`*cW^A YN5[Ӕ3' [ƢGPMRyN3v3g|xaMML6D[L4+M[Vǔ*GmV}4H$'.{p 6N@yEͤd?W"oGb'HNk3&]?|H<ᒅ vzȘ!ml̨zy߹vbƏ=oЉ~pPI|ז.YFpuud555755H$WWW,hFq:0X.l٧WTV+iBѽ RT*5߲&26\IZ\Zqhkb#_ʪj,eN8$bl!AQ#G Ӆ cC,m56ܙhmzqp:k-XʪҲay<L¸p)q`~"/&^9d¼Դ۱1l6;7LJ~n3y6BT*rh\̮NNN  iV4qӧR(uu9 ^m4wNYyyIiAU 2xA=%'?_1J1VLlٶcI/4bb)/foB,o jתi6Xn4n貲"}N>;a8,| fںܷx[XGp{nܤw|>H0jl3M`axU46ݷza|6طw Lt ;` J3Rllj\톛@(4gg,N4&YYrjE'DT\LصAUj\fk#Jګla~%үծǺ5V DZ`c-yڷw LD 9%8888k>o>UU<ݶ$a8!hoh5mtvJ0]:]YlNw[D 鵢qpBPWn[pppppz:N'FY5id'oQm޽{r… =S fpjZAU! rr-ͶE۩S}_]ll[*K5Nᔸ8; Q(U!ׯ_n[8B! bWt&I4Zfvf*v>e#D TImhpuTTT@ T*͠LkȔT}jRψ6vJdddg4or[+=bMݨڋᔐd#q #GbY1aDpʕV콋 4:VB&jrb!ZJ 3h4gprr|) ņ7^<ݺ!H)RnQڍzi88O:1jTDDDgDDDݻOE.+DEUqVFV\0Nk:tdڌLVʠSyeJM}Sv#uMvү'-~T,tI$xg0]a2ƣb!Ch4HҴND[p)|ƎnzBcw*](d"R6c[儅Zx2zشdyUcm^vW ?*WwJp#8d2YK{wUxTݿ\. jdHd"rUe T)-} B$QWyWo]g"i,fW=NrDN*ʼnܱ_J!=5qo)*'e񉉉]GgƝG+:VQDGgP% $U X Bm MH1g?o!~n3H$U'cqj5J @$+^^(b(ҋD"N tGѣL N LL&S*mNpBd3`/>q1] 2^!M"KD "p, P6 U@ejF%}&:)T&-V@ t:%ǎaYӤ򎍉>xChۋFI$ʪj<5}jҭdSԬM W6!2BAIP`_XsA$Q@!)9 |o6~e`K|?) :EVlA:p3;=u%GVF w3LIDJF~ݵ''60IW79TT=:.\TK: ĔHb>cJ3cѣbc^x{y͘>wJ"8aXw{M\OhHUuu`(,98(W$b);2< wJz,Ŕ`ˋvITLq{HP/B!&;hR>.O@Qt]sO~$'O9Й! "RHb{E;vX N=uV6k9ϛ:{=ٝB_clsU8ct>xU;&g6u66k ,H)?z)C$~mjݒg@A~3s\kBѐHfAEm1h&lkm>$meڀOE{w$rX2S_۝Z1*:tT붜>gj~:E{W&]AQ/g޼S ?yqR|Dޞət W'nHMkjwsbh^鴆FΟ1JZU'Kxsw*r SR LϋF8%C2h&x/J`;%._Pȯʷ'4djj8lL._'൥K*+.Y4ufkime2{vl}yѫոSbMIMH .6Ãf͘6%%5m8Tz1rs}C"z IġC._ؒ>xBN^ESkz^MB:2(ܯM 7@w9'G$OMc`L B&^T+{9)!mq^L~确?Zg_OBd_Ο;߷O43thSg􏪯odhIɞ<^~AaNϲ!͢P, d2rqqFh) D+מnfaQN' N^p]z5̬J'+׽=QE{?H*\eQ?ܐ~~Kk{$(@w8բ-E_~~d] -QQ ӒI5 ʓa0w\6cؠ>N>i"Ȫ;R~<}ύ'F Ԙr)ag#S4RJnCގc(#|9SKOЌD{Ҫ~}>!!**Rn wH,:{ˆa'O4`@juSpH$n~V IDAT$3+[|-6&\&ѷOB8~4v miG%߃vt&lB~ldjnF_-d7ц_jBEw~~^pJ 6q!D)77(ʚfE5JAJT*5HWX}#5BȰ\\9A^RTOӮc -#?~v߇,y+}Ƅ/{!A#+km Tѫsә@@jt(L ʅyǒ'.}썜GtN<1nhؕH }'2JW,9@JP>dfԄȬkERBG|f.) ?]X|'dz̵72%~PpYuKe>*sek)UjK]kD&YU.|CG%,|%crQ=2A'#3 kjt+%9%uhAl۹k}<f4[ ѡ95iܼJYACWV?,ǎ+D(L{ rM}10~拀UQ}xKƣC> @e{+G*Up9 ƣg<=LTǓ ۅ"Yip.Ӗ=|AҺϿ1%ї߯O9>Г?؍ͤ646-;txLAw|n⻇ϥ,Z0cg% Y_vCM\dq[~thS`|Xglu#h`_̰wAQtLl _w&ҌriTRDg?T _1d"hm{qENZ~qSss----iGE nӏ-eecF~=<~򦦦>fz;\{b|nG6M&QynHUI, kD7cټU>sj^z+i1M-n6gΔfzhψ\YvrfÑ%5~$Eضm-b)ə><,]B6t п? I-ŕ"jsm9,/wnq <F&>0mH+KRI>KLӊK;xx1/&p+7nڬP(tSMM-~uBwn&%?7ܼ{bwU:^mgSU:A<lX_h)/\?`X4,j.H&OZlܤi1J$cʪtletOԙT1s NEU*S-37?&-3oa{ϟ?WZƪʑ;}֤gL+ם`Z-+iT;c9>efXHW6;mŕKVq24J}sݣ*?sFΙ-I jAYo\1qwl˚ZNl\8%p\\n嬏?WR}g>Z>ޒ/fпRj*ؖ3l6wJpr/+((2اD& ڄx/H4K3TtMOӎ Zd=G"iHDJd'3s\ε\CWb'%(Hڷw".V#1 ǡN c %""#991 2Y8hKB![Mb"l/ ڕ+30Zq>ڴG40oÄwhpC&=xIc2;a4NA494~ { ㇱ(W<>`w^c;CizGQt.88=)ylquu4D#8164ݨ{AʚzAZ4KrV* oFcJPcAx/!$5.[(A/[M jQtb .f…Eе<wJpXp{dffwv#@L=!*DRuDL Jh~~~IƬ k sPTZ'd}H[U3c(h͟'+1Kw%/Jo{wM]ݢZ{qqALv݆8& eTj@6dxJ061S 4:݃k|f؉FxN999ֲtLE)ɉpTJH.3݋3Z-ݨڋtܹs=#EiL D>AM-]LfZ.,B&QȦ>N2츈xϧ[ ]5\Yq@.痕Qo%q/>"!IBfW1Y]mۻ Ϫϲ\+ͅ";N,jd KwRGN @rrXlx3-TZYYӾSjk\ݣ EP mH]\X#c' lmw9P)=t^>&\WW?|L/x|؀wJp d2e2yt=<P*yw6\!RکcA)c"JD  \ ?=kvfA aذMp 'biW==wQ:'vjG'G#wJH$Ȅ0*Z]Ss¥Ʀ&G+׷JH$UUfOyjԤ[ɥe&<D"DvIEQ{O,Çb%V㎋Cxw7oTTlg}ymIyuZmލCd̰P2x#X Oli?oKhT2fL--*l\@?ޘȓ ±N ްn-Bx)Q,s_]fŦ86C$'~/ ERCBRML$rgp~ &tS+y}(nqlmҨٲ{=Q N:9ci%&2xnW(*o XSsT Ry%?m?Ic# Kj Jj'0}T?3J]xOMJ"%# \G8H3%f@&ZV <"r ?/DQT;M>vhGPeVyV3΅|u[O۱Ԅ1}fMa2Uq@dOirSD"q 9vV}rˋb{SSs/o*yzd294$X.WkZ>f79ǀDkS޷E*r%(KSS2ƌϯѤFCG:ɍ;z]R80lbNzeM (6xӂ}*kX gƎ 2v ~ t#GOHJ/=tn@scϜ2p`&e_p`gqqbM?țVQ|<D{FhҎ2Jʫ},3aLT ~"IwEy2W;Vl+}9ϝ:{=/5bl\M7E3FY/ޙ%&;v)ÉM_\OKFZXʤS_qs>ݍ(Iٕu.+B}˲~?^:}eKfjSǎzMW;ʁN D=j<iи.a7 kCnu1vg5u6[&@oX3OhȑǷ8u 뛒@\l+,*1mJJjڰqRbQ$2L'@ zJk!7ސ 컻-}0l"?eUIc׎Lu u)<%(Vն=aDLDdA'.f(IԐ`ML<{%xD9tPPPBfX@&,3F[|I&Rխ| <0TJvwIe L&eBì_"WͼZ#|F%Ϛ2P ajFZs])[F@@"N Fxhi XDՉ5%!M ) $K)pJ mv:;cPvD+T D -m"Hr\z^oת:~V%Aއw5Q!蔘Lw D'],PT+װG;M4*ǧ3d074DE=Xnؔ{qws[=>fH$06Y: Dd0 U(O&P(08= &2ШdCssGTO Hbh$ q{xΞ>[-Nv~TיE3TL]s IDr3LryO z<'>>L"1XNvRc3% LbP)yC#{[=;j44ˆV0q}I$A]+6k+'<Y"ʳ3b ?}2{h$ǝZG~~¿XSS[cl x/߯iB]ŠH6.Vԯ}(*R‰;?=G8,<3o&J#{ P~^tTqqVb؎_QtJBaAaQ ~i\]]4 &a1E&ąhYu ױۥ E(VT(QI0$TkwD*'C;&\ψ\YvrfÑ%7۶E b29KGQ@b/oo QZ7,|@̬h)lPkB^T/Grm2]He 9J )kdil*Wa ouy`4 H<{z VזX$%u,Z;er9@04|"􇭧 _hP$q Q)(dR-k^z?+i!cb(KNw揫ih+jR(U:>n}өMȱ̂*cK; F&WFG8t.JME%}DĦj7 -Y yX,ө䗞 E5pZ+ύ8xvMCې@?j؁f7ϛ.fK4qѵqxX⍛nܼb1TZKKBY99vrڇy6EZ|b,>w̄)؏s_R ~))-+)-Rd2I*X9jǮ=t:[}tOѧJH$DңǪ˫[d2(؊Rdqᓷ&}&Z,5HD¬)I):qQXJ~IÏ;/O`AQ/djŪik[&9qm_Va3"6g(z#5̒_3slz5aHȾF=6OMU׮Bm rzիX*g){O$w>A$as5/}xԘ_,)hRU=7 >P 2h]cz9mERR*Sdev\ P?@JesUPhK~5 G&̝VvY^&,ӽXKֽ{5l&B!(&u`ٸ W RHR,n_bvFR'.tī{NNnTiÃhTrvWk+_~w&BAz%ą u-/="i]VJb vdއ]L6 ņYfvA[xqe{\LRPHWPY-t7Ew0Pe➣I\]ӫT/9,zu=_e ?V; cH"wq7_N1f,I;hBfҘH0Oߥ_M-_\ 3}6+/\?}B8ɠ"RPRӖLa3~2qdtjZͳ6rFyڄ6Ծ[/hICNd_p8i1,֪]L#ȿvӷ&t>>æ}̢ݬLx$ *ʪ--+T )UR`>  tE"?|vpPNa(뷞)47܃$НNMhq'8CUUU;%D"6Vo1k 0Rbөo?yͤ5wRdz%PR^grj7 ̛Ƌ*~'|+ɱb+6Ϳ=G;"Ah:Y9ؚiDЁ s11wJppplx$W2M#Ik~j߉orRGZ6-r,ńgŪ SbvK5dH$rN ~MEQҥKfYXP 'Hf¼K/%%%a9Dbyyy_c1쐥U"jZRY5^q, 77W@hK ,^u1gK^\smG$srrbkDD+(( DQA2}D"b>RTjjoijHo5j~m/ythzTJҊ*˽X<<Y&""U[ ޳gXd7لl';wνs̙sϹcqBH$b!O'4BŲh8N,+ʊ mkJ˜<7vba^Da ! ĻOnҐt>' ]5h5&N&CdA 0k杏yk?\1\1^AyD-V#Fph$h$ h " n%1^dɪU"[/Jt]vQcl֯dbvn0anf_fyAK(Sov So̤HhIdd֖痖,K1c|}};$0---,,㸚ϟ;w !iB7P(jjkkꚚ8(*!!_og\0QQ@w`$ᆸ%픍V>|sL֪5k`׭H?u DI6ng&)1ҲreА&\W_P[W'{7e䖖iuZ\N 5q}.Nߢ*T*kj}^%Q?W̛Gxhy>,, c\ZZ,<#GwH*++=,O9w<,˦bAjg'M~g[hDr%h0(`%^˭6 ^2h7^Xb>sr~;G=zdccӠɿm+`jJJDx#6m?jJNQI$Z'~ yD/uMoow(˲R?׮˯m߹k󖭭 lFwRSf?[hJo@Ql6&: 9sfr\H$̬X\UU%L۳dgg?#^^f5K(J f gf eM.J 0f?HY auBu`d B$9F`0JKKJ!ekkkPCQTRRT*DShhh^cHx R"웛]=}1c<l.}270:D t<.3 YK B(88xРAyyyÇbT*6d2egg{(7,,,!!%U*U}}}}}=$''GEEubd%".4M8QPd2Y||- ˲ ômdtBDcǎyٴ@%liIP|;M;)Xc7Ab:`+c E`,t,||| $,# Jv{$i6srr8"Ta$JMM v85E ? yQ(:)"##5Di4p\hZ C]Vs;D T(fh4fKKKKKK+//E EfY$k3ā"e?x~tXwtg˾[oNJPU]_P89RUU%ep?!6&s5tW\PPl4 \ Hi쬑8x)VJ8p`zzzzzzOD"2l0 Bcƌd:^HEؠAY=јW8%`RdQYPf*k254:;sEn6Ϝ9w^aBSSS.z׵@DP2rss>M&B`09rDxAvP?h A~^^^uu5bA0L]III~~~v]XCBzyZ DFFjk+++v{lllDDDhh(ׇq=mKiQa9o5U?SR8|6 vSO|xРA.O% /XGLZS~FI IDATM~ECRd bZjCbY@H_PkL7F1yV%Nw K 2q&-4\T #^4hA,bgk"359  Sޚ>? b4)DZ8su*`YӂlBBBB.**~>s!! 82SeaEqJA b^Zo\68^GN[ =s6[577XWj" b@s9B3~IrMu`RB ^,z;;uT TXjS̻!J}b! F>iBY]Y-ѨvRD)!F:fG!r!:'QJ{D1Q`Ů>}^C%o0r!:'B y8>sLIUre]g֓Eq[^ F>rpF9qS?/.*'&::&&J*ʪ*:[o>|hiY˽i)j!_ɹ- ct:=n8a!uB\녇5f$}j{b䂺mKX,^/>?ۋK$iSZ"Ao>e7T  ;-6(00)B}ĈaǎtHDDx4Օ3}%=^Acþd f>0@Ϋ-|析 Ebe?zk)Y HE ^qqJFHDl6{Qq1qjÇ/főHQഔںfbd2hAAMMO|.?%v5¶D" /(riWHzJy e54rsk&KBB_ċJ EQtHd8.$8xђrrJ$Z'~ dk5urf{a˽yI!r gƎ*cbϞ=WXTt-7;~be_{TCQi5$00YTV^wQ)8_ ' 򜴁̛# Jj?Ux2E MrԄ67&}/*%A 9#;mY?6cwp ׮ۼe+B蝥o>p߬e_|iRi]}CCͻtQF᷍9X,d 2Y``ZlMMQ긘Q#4MtpPPuUn+ Goh@ ,lڲb;fޫպ]\趂<$:"W1@TvѹWZd?v㸜R<'N X+Õ_SiH%R0qqm,}$5%J,{?\UUmbcbj#!#Apߐ1GRM4no}TUUGEF͋h4&922(ԆU_1޶c^D)G0B=56*c8i@4CS|}<{(l~yAqh_ 9&4TWX+JRҬn𰰆qA,:ވYNǟ;'Y9BOv,2-{&nWTrJk&aƴy*+.(yI2 >3YY] ZmrtB@맆devTV~)yOi5k{wqtTz 0~lXHHye?. u2啕: Q9H1_`Ynw䕩Ժ~sqĬ%:ɑ_hv}-7Y,Ϳom}ӧM9[[Ww-99Bٌiןrmi}Fz}nqEQ{k'%HtY>:Ivi1[f̘&CՃXPX4c9ijR1 R@**uu ϗ\K=5}ZYj555 8ۅ70 RqQS)+/0n,˲9g8y&;Lvǖ˞ȜZmO>s^Kz^yyk//D\ơ%'%{%by$##4$CǟJ$gz{w\v>'=w1  ZǏ=LuMͫ kOP`c^3a}B? ?~3rUpoW^ejZRi``@MM.l074((8Fc4 㪪k >2|b}||9;~577;ϲa||}u:jU*)...s(8n@B_{ )u~~~4MW] iMrܳ+|F8=1deZLVya1EY8 3=eaCyϽVm?[; $$XѸfϗDedW&ajyօNlcGX=z_/K'TGZP sJbS |m;v 0Gv"##Z'o5kM0m'MJJKu:rZkEϧdR֛mwͺ uɿqp̈́ >^'wcOX,VTKy6|Uu͢%oc#ÖdŲh[/~ӆz(%mPQY?nj5ne9rXvӯ;wޓBaQqĪȈ 竫kJEߊ}[;geIF46:Jc\ZVlB.ufL+Xm#gĄx_}.$bs@uB-6bXkW:uO:ϊ-A 8|cOtH66ƍ]YYl8&64ҋOe2NgZ{yn?˲&Ӆܳy5+@d9P_s2T*Uk4eKJJJJ$HX,V*]GhQSZs&+ce݇]d˺bJ/-b 3,n!j!?g_xn^w9]&ZںٴC@< _G"PZQgpvwecF 9_p6ewTNk||}h2Y6ٜS|2%v!]~7ݴ`hhl4t:F"󼪹u`hlj"XVb<6SZK¢DPNKsk6nSODGG )DEEFTVU!&]359w.0(pO¿\r孧ӛJꛌFa%dahc {\ݹ?qr]w:|c|qcG;Q9::`fgΝ HNG,{X~W2B?,Fރ`0~,]d0KJZdz \d1߬jϸu;~o8n:T%/{fSs;yVsWYӸpJ'K wDƗ8_Ç$gkuFO؉+V@yEH$:}:$P_>9gw%o L&ko,nCu!(95&NH: K )i 6gd0!`x7o9p:ζ=IM7tz.R\xAMCfֿ޸ LKxrB(\¥+8KOt0n쉧[$666o;BȅtO?!~RBJ tH:Wr!'%d@ tO B_RB&O#xC2ss@@8 I!7*CBwjժ@ z;־ _GOׄ@ = ̞᪆ @ @ B/(%@ zD)!+ J @ ^ &Bo'o R?_lJctxluô;N8u.FM;_ج_u_ K @ z#q!Zq^Вo쐄G#^|a1=UU/1玉Se2_~RB<$V{|q➮GWSUYFgjhַ54%:!*x߉/;]>7I1e"Fo/[JitPiZ{W4ׅѾ܀|\μ4*P pg =ED(_$&\cjooʍnsSRRoẴ!=9g_lziuM:W 1RO04unvVe xq9T<5.7` #}x=Ia`%EQ/^w36vb|=.`9;{qҵzRchbd92wE(:?Օn>{ꑃ>y! B?.@JB\뜡_-%Q(MIUmkhc ʗ܀1@jbOJ(hbQ(ęjUdbpRDJB8+-EDk?fVk7Ñ&n_=b|3^@o ,sEmx}xfGmCX>2P4*:5vpp.*ׅӿWq/B`b襷E|ۡ;왁bbpeN,b1~tF"@af1DUZ3\y-_uyNך9͈33} 4Louq?ph\~4OIm@jJ8!!8"肫܋5\/ujF6vn-3%Hy/B6RweilA#S:ݟLOi$H"l<4Yqkڅ]CcF'oW!^ $& R4<:Ep TH< o$сNp1"=?;QR}:y[9-?+T2å]Y&\n&0 Qd&\HH"WN$4XI ]@.B`AёR9E(X^*(_s@ xR A/g 2s Vn Jxx]7YpN4ѺIR2hyknh$)q]Yڞ,Z?Ib(3/mddGSk Wl$k+U&W72L<0*|VOc|T~p}-༖w%z(95—2Sl2#24Ϡ,!cq!nbDhl΂F F*+1k7  N3S|h0ʑ@#0)tfg]wm@oǭZ[b ,4Yze ڰv,8 MѣEXy0ec0^FVt?Ua} \ ="D5Y9 1cҵ/Ua} \^ukJu5 = ZJLonRalBG!]_BZ-pZJ!z[7@CTU \\7@hAYYYOWpUsA)Iƙ잭 _2tH&ZB`LzSB W@@ K>%Cd`=@ \\RJ?e@ Bo@ RB W@@ @] }D|&[={k.?mꔘhJJNꨄ^|~o Ji)cFZjMW $^:c2F;v̘訮-bud#DǿoꐄСC&]3a7k=w9h`rdBXJ}wμYnK&󋎊meJeڄr\,T*Dl6{Qq1.8;'744I8 h401>RiAan߾sNݕ0LRb"MSe6֛o---ѹ2ACdqM7/(tT*kjQ !J xcccZ(%ӧM^|c'N]^EEW40yɢjjr‚zu:]HH0|;WzG:~P\R՗&q!{VW8t]Y)-~jX,k޹))Fش?˹3_;vV${o-ju||?ˆߺ  J j~[mӖͿo<_{Ye+m{SPJ#lp ׮ۼe+B蝥o>p߬e_|宸cF9546Bho۱vk//u,:wYB蕗o۱ە9iwڼek na_~SV^^]Ss;w԰Y#oC|J},|U˿z٧E"L&D209i!!0 `!!`UDG՚#G1!##uӧMwV+/G]P}~𫠑@DDx|\o6 ?7?5%!]Y1?Ar ??'O4돿na^QY%=Ttt1rD }iE]a@xwfuɤ/Uv) ^b;P7>09( 5rټG*u6ٻ_p8ytccSശ-#3 =˪5k/U^fecSC&'xRr+w,xṏ?[lL6:}VjZBvsd&!I XkX @ trww|iWo1nfX|LVθ $x ͽ}=w [((,Yv/w}OSW-9Hv- $x nH|r_}} BBho钎S/.z^ IJc^5g\@ zd`@ b)y7@ ޢt@ $d@ B(%@ zD)!+ J @ ^QJ 88H"t- cC{"_[o!o1}dZ^^g~VۅMҤR>U?/]%!4r#5͉O:UF.}0s{j ӦNZҋomS~~AWW@ @ӧi4ڱcDGGum޵2X_|~kH$Ӧv[SN6M̝=gC#M cM1 :d5&NߡCBXJ}wμYnK&󋎊meJeڄr\, KDI6ŒJ v#=>.NT466UԸKqhυ߬ }}e CCCTQU""›B.I&UccT͑h4:?u&KXq_"#}pvNP_ ¢bܥn%ai*-+l|SvNniiV5. @st<Ʊ1-Ӧ}xNYyyHHh|z />'׮[/dxy¢+V dk5urf{aªm՗&q!{V"?LV[~" 9,CB(XZ#qYCw<4~XFn4'Ν_jp˯ۖ?n,/0_6?pe[544t`+V=#Zw?(.)i 2h7^Xb;>jMϿڽ7CBCծۦ-Z[['8xϿ,0W 6t]}(G ٲ`V]yV;K|Y˾BB _|~ێ}[^{yLKM ul1Bai-R,CB s-WsuWCe`y~ao/Ytȑ-oGVcP1+ڕ7RPGm41ry^ySۭgzvvjA8}p6o#}SB蓬XfoŮZs>-d2I$IÇ1 { S&_w&.6&&:Z֌9bԈ DDisSSR**bѼg)!D cˡ w5~ٻy8ytccSഃDÆk':ж4wL6Yׯ}\[wA_yïFdwl:#sz=U3Yq1ᄑd]w];vtvNFfyϾӦN)(,6uo7BOvCTVvN,Z8N7rrU>=w?}ÏU)GE> !f khhOgVT(Xݾc32[U}Nr"{Qq=bQtqE@Dg:( " ¬r'# wWwmOHtRoW`=}$pUTrMN',"ؗg?'D"B>#cز$#&Nw.8v<<Ͽp݄3g<<YYgH$JO*Uu|]W_6%%EBN癳U24$TgS_T%w֬>m_M&eeej! OW([oY"9vVqrc~]@įXW\mݬ?tB1B3 X |Rb4**N;CP^!{PcclDy@\m  1r/5vc("EdݲϫU*0MtUuͦkNguu޽;sog͜7P /.[h[7wvv&%%u媖ֈ~q]w^yuW/Zc`e+8g,Exgqj9hW޾œ&ߵg-ϼJYyX,+FB&O|^kypf?_ÇKKFoW7vz4@`Ց$v5ó Oz7XVłDt)QԸdDjQR$d2ϴZm I~/!DTd2-ZͲ D"VXS_B%|=rf/bkVꭃh4f\I?1o]ΌpD[3|X? V+ fuZd8Nt:_8!ѣjfu蚩|G8{x}lIr Fy1-w#Nax+!E_|w=Qnֺp\¬AS_B%QBBE(ei!4M?0k;<Z[RX,V*YE~@]~,v [%6V_/UUW͖ BnnnMċ]Cmb{0yY ܼn Y00+NVw[F\s~(qbх)2w1~a!"^|),!dPjimBwnhkSs FXdB\$2w+"!|Uȹb'I+F.^TvbAHD$Ћ\7ڹ={GF$>wfͼ/lCnAQq|_f;on@lH%6%]$=N OLdc{ J ^`wBS5wA8@{R5w.{ J.e7 J@ (A@PpD ! i7˾ Tr^o}}gazES6vLZZ=|h$'o|[o#m^?vYTO(w^/6:!f;zּ[8slo7zߏAIQ(%ɧ,))i 5z7(H$/mRIDATfק9yz';tx;,~faUuw罼6Jzf12jH$M7~wmyaK[t@Zjҗ_)8IyW?|dYPƛ+uӍnK7Ls_^/g&ZּZ;cWgY-+-ٻ;oN;/oIymx=EVOMMhԕ.g^7n"z~3w˲L}=qóx|c/,H7mX7z#GB29`pLY銗~ϷBf?n~{G+.*ȸYQEU#:V,/?oӇfB>ҥkڽ9Y8F=nL۫Uo#4z U*UeicE8W%;kpwՈ}ܵ'Nc }һk{sss֮^!\.T7dH>iiy !MTsKKnmXǏ3nL# \&Bή33ssܹ{Z.*,?/jR^QAq))>}E0$>rxՈb"XkhlH.;{q~?$ֱY]ػ@]Z#72 SVZBr5j_XO^][K=yѺ9֕1deenh+EV^'%0P;~9߯x;cףs&Nj* B?6UӦ^mBF8n5W:~9’gwk_Bf3EQo2r,p~/OW&SRR2LQG&L}F8ko^nɢyhK{7F=d64h)#W;[C z^[,M>>Z,Vu:b y @ r<++)YnkTJdYYmm'+g/]W_- r-7K$#V݈ռVKq:gVɤȒXǶϸvBEQ罄.GNkk[ʹ=vy/`,4655>)##p8r б̸06 <)'9Yljr3 };w4]U]iY]]w'Y3*TË˖/Z`͝III]5}+zp#xe2m];˖x[? M-K_^qQU9rtU`aW.j2_zrB<eD:K~4 }oc@%w9Vwvs~Ȯ G5/]ʒg޾gkkk=pۗ>x҄ݼݣR)+OQ{@FB&OuJ JFJįEQ*J"aL&sGX7.TJL&X9rZ{VYu\kVꭃh4fۛqdD"NefUk:r%y{8ݙ4auX} Qɧc]V+ fuZd8Nt:b3/%GVuKxRqB+D ǨD=uOPbYp &9~Icy3'z~^QCfn۱3Nu[]jJ"<(֕òlx᫰[bm@@Pf 7oB̟7~dez7X  0/eˣv'++"TKkXt:ZjjnFX 7$--U.YrS$e+`0v&Se jw_'U M NMMUՄInn4#\.tr,)))qv$L2a)lMiSRZDiZ&q3l~q BL&zIR0L&sz؄k X c-'gnYDBIOKu]R$W Zvb3==CYU*^`0xTx.˲pIIr_yQQ*RTնu%GUVwvBh.+-=tQ\l6u~_P74^7K-j9?Nch_@d6wMǔi4:t萦BȐ!)R~Ʀ !EEںP~v稺zJǗH:z8qZl_8.#= ijD0K bX. J2;!|{>"e2zj)m6[VVViIIGG:Gud4VU% 𠤳a`Ytn 28Y;~X,&Hи ¥*E[vfv\>(++nذ4BOc =.YyZ6=-#jj !>Gu'$nlIˍFc⇐mDDc"ߙ,Qu$9!\AYY|y^ox<187X,kƯL*U*|``s˲r?Khb_7@ h4h.# 2d?fTrFV7PG]ކGF#iLgZ?`w4}7(mIƔ|y DŅ-mfx}>Rt:%IJJh|]uSN9*8aHDmٺ-BʫFOrM|>\nzNI>cU9B>#cUك!ز҇g?PTXx_>q.3E>r4<"!L0.== ?oʔkrrr!aCuL$JY"я*"haǎBODyE`YZj!ZFTXw+ !~ap :|Kq}<ԓw].BJt85quvTcc_r !JKT*\~XDfo|`)]8tY|F ?kzFaC udOW% 0 !O|7k֭߷ (_GV]!pAQ#rVՄ׫j{^OM93 `͔k>[UeZ{pI=3gƝ}5-ΚVw~/4a={7}Qwykhl~ۃߝ(?y_*O>vDTUwt>8~5W"4?Q~T^HBɓ{rs4MZɄ"Jx,%"H.\xIJJʍ7LwB) 4 Ʌ޷J222p#,i7LZFPuP hZˋXjP(pww'))ꀢʷא#,]̞E`@l߱?Yftr7jȔIQ(*,B(S43Mgg^~Ǝ~JEF ,e "~y}8ڴnINNwcb3w>.]ݽCӦM͍/׬aٙLipb3gCbb"{gkȝP777ZipϳyoCD\\3fWt!#3'GG.Cw jق2{s^77Wz=II4hNNܺy >>ݴ-Z y̍Ŕ+ L͛3fkiӨaC&88Bvc=P(3j$=w#-=KՆ1HINfڌ\O|}}lʖ)(C !!:>q]Z2?|RLk=0oM&**ZX^4_J/̬,Z-_>8::p=ƥVTRl4B7~tysfQD t7'MFF:q( ygnKcav7n` >-JӻO""#-:DDFr!}+WqAȱ^ |} f;y)zժU>΂wr;NqqqTX//O_A3eҥ[ѽ+.zZ=2n޼Ejr vKݻG FC]jY0.cFdxktޙ=ԴB$oڷw3|PΙMjʪ/VImxmXZfܘQb^MtDvmL4ڵee:|=Q*|Rzt5kAS$bR{6գKdfeQˋ RҌn?~,|w]qqv{{(Utؑ~_"**MMճ^|wcЯ/ΡwуhF:^F,oN(UTO;K1jj7oƋ01\v __bbb @RKQ(,|w_Ă޷i\||Nc7yA̚3 6s7nk\EmرsJmƛ:}&b%W\a}mXj0yT^f5~trڌY|^4۷ҫgʖ)C*9Txi|}7jXM$11 O?MfF&Qԫ[TX埭$;;VK\\Uck׮ _[?evl׫sqn޼@إK$$$Pt)۵m')[,O/ϯQk׶ UV%˾z=eʔ\ܛ_ANN$%%Qߠ홳?z޺}3?|}fEDF))ؼ"~~Dݘw+}||rnkR_~ %y0x$%%MddޞBJv:م$ܾmXZm 5,Œnʫ6t۷b۶| }}}~|} x:V~@RRm;tǛa EGGϗ.P*JZZ/~c/ؾsuf{O?kۛ/,}ߨmW xɨjn޼\y Zjɨ#&**rAAqԮU˪rsۇ9ִA)l (;~UzRɛ޲'ǝpF}PO?+6_􎋋ϏW~~~DF{Xe<>>U_3ʔJ%Oc7FZW<==Łwt:*V@֭̏c)?2ނy2/W-T/..'!1u.\ iw zct˖=vu㽅79yhi{5\'k.簠|}Lߒmꚜ-:uU_ iղUsrrbά:;w &_ 4Wni0TV |re˖zj\ _͵k~ЛTxi%qrrƍ},o.)9R/8:8Щc*%nsBd˃qw;ZL RW_Oא1؟7oՕ{w(Jzaq=퍇Gvxx8.~-m~N>CʕhҸ̽< jhZӧо%rPF *W6l28{~;;QQQxzz]GK;ԫ{ݻY5w<9tAgml+II:;vGGGH:_%JйsG).KsIeJɀ,Z0WWRSRQ*j'O`Ә5sCg]HLy{'Mdܣ { &=9fгgwrZ?;%4{dwri}A&ObϮ$)o[}˫%Wɓعm k4|n׬!33[2l|}~/^=}1uLZ-}7R*zl5^1eJ$$&Vcn?oa;1m w􃏖snٻo?5kڵ 6a"͂2|P"#䇳?ri^:Z-3ӵk %mʳgnysg>*Vx_d]\V,`\oMW(UJ6}֭;2NJJ⫯O&>>l3 Ы'o1ww .Tnn0TJjZ}$^iJebF* UIND}|IHH4y>J>pwאh>wSmyrh]lOP]$w=LKoJƮ{-~J%%JxjN.$$$-WT(EJJAxzzHffhn{T*xzzo;5AΡEZ˓8{K~VΝ҅WFӓ4RySۇ%Em$Ѹv E+_:\11F_ LU r=,KNNN3ֿONNNƗE` 9絋{8̭1''{R<92:?ְf\EȽcĵKLLX*ۇ%Emyr~@!cͦS^oPZฺbRL&E!Ӹ)/!!E!} !!ʗ+G' ߼ݲyS~Zjɶ5 ǝRd헫f=ꌑoި[8PT@խcS8&5/Dؑ'3oM5ֳ5ZZV`/kd#RX#ƿǑdG(R@>f}TTk4f8;;:Ic1=gR}?@]ҭժVur|Ug] ~{ҽ]⃏XF6_ϟYrt ƫWˎ9k<:w7'1)%\2]{胃q_xx8f΢SH7:u醯/ڶ8ׯ`E s >kTp[(\{ZCSSj>w xu+8;ӱStW}cn˟1{OoWG 端ӭGoZϬSH7w a1mlv3.zO$d6zK0)l>/e*`&͛_O`thx?(h.#ڎءcvl߹^; A$%% )cbk1?K'ˎ i)csj5*-K?l:..oo{djY[3hnZua7ݳǽk4zwvTQ,|TcOTi4^ݓZf@n`jӪRFvѼy3ڴne@\F{%;y9}P1u+5eHNNtNCXgY1ϜdK0qܡJJڵkQR%8u }^ WQo\m[?p_EZ옛sfѮmkk,X2k2vK`w}'^\'Oq1۷l&6.(BX+lNzZ{rmo-h.e:b8u%))Νf,ȞQ5jCظ[0_ kÖ2?Meespp⭓*jFh [3 zzzb򂰭63ohid*c<<<4x 52>TR&kh4rZ}eΣ̎₫k̈2ScJO"o/m{@7gAK!&).Z~zE!}t"BmE !y䔗B".$! (B!BB".$! (B!BB".$! (B!BB".$! (B!BB".$! (B!BB".$! Z~{?Q%&&q)+ (A az(B{~4jԘSNRpU$<~pQC(*Vx tG=0v-åݣ ! [Ks!v!E!]H@BaPB؅B. p{Q< vڶݪ]'t*Dq$䑐(lic*Plit:HIIΝpw6-2exGr՗\FPٲTZncNɒ,d }՞6Q$''[דss'G=Q%[8-BU5ҫG7۲:5Nff&Wjz7l۱drhH@y8880d ڵn @^5YYY6y{,ʔ)͊es懳> ;;[?RIFF~j&FJJq}͍Ttv K+8?ٙtZ|QVAkVIKKryurr$33`~h]cT,=u5Pg{P(8::lVqppЯgݻrY%--4eђ2x˕cx U[n\P?+o>aa<,jsIx} Gå?.3$%%ѶM+ԫ5k<3? 羋4IQ IDATV7UZ- \~m۴F8t>ZBuym*5JVÅ߫gwjլs͙9_m;_~嵱)Q Z}̾ mӊƤ,l &6'G'rrrX&SG e_ %K8xΝpsssmL?gggrt9̚3axY0#_BՕm;v5x޽گ֙eiWDEG3f=j͙IJfg¬wns_zvJ&**3!"2ѯypSխ ag+9z\f>ޔ *_PU:L. CBF٧?YYY!RIV-8t\7k aʛo0o{fΦiF1JZxƍx{{1),x} 38a<% JDV1f,V}^}BAp}'GDDDҿ e?ʟWdr c UZZ:iiVlaP0 ouOO?oNxgݷ9/_8pM-8uJ*MP ~;;їGDp t:HLJ&,JBq㯿_Ս؉?w_FF:|lt:hԠ!Q$&&S\y22vZFקޛVƗ_ ͛<|iӼǖصG̙RT"gCX%׭k5ݲ}G:$&k9zt:sGFE.$$$kt,OuA+^щҥKsn ~~jssfi 55Դt ) *z;xIއK4a<(lJrR2HIIa aǛҢy3s^;6&֠~v0x{ *:ڠ5$ 48㍷w ƌ.**d3_S( '_~%JuתeX&&߲/ǛW 5oBy\\oVKbb4hۦ?quuE4h也3qkU*nݾwS|iǃʝkb/ӥ@nY"-2*:{Y]?!>~ W!.>o//5ˋO ""RœBV/$||-W PTL9@koL\mw @ƍLַu~ƍgٽ+͛0ID[呐S^,V~% W"UeЀ@V)U*Ъ?++Wzxyy)ԙ3PTVSkݺu#7 FkaBˋxOi( <==fgOݘm %HMM3{ɣѸV;` ;;ݝ,u+V 6.HR4x<=ILJ"''dF /tj3?,Iqr" eddQgNG\\m-W>$rccmm$'[w__III+}_GaZd3Bzr 塐@!.y= PB؅Avx=HH@BaPYܣ!E!]m3 !7 (ArR"~DGBrUagM@QZBX/11?NCWo?$ @_B<` B!{JBbOBB".$! (B!BB".lmXEį G!æ rAH 6_n.IgwנAΞ}2r !Ŀ]Ɂ3)9y;W?rpLB>>4hؐӧOӹsfcY'Fh4$''[OA.Rprr"55<jDvv6Ze;vcǎyB/L8?zxi`.5 @K~ڭ3gbq>sSP(8MN={'P;∋?t|8xȇ-FRYk4wB%>}.,T{ ri4hP1zf9r0AAAP PvPV3bHKpӦxMN5r888JRܩ3ԯWӧѾ}{uNא.<߼DǷnb׮ue޽4 nJ-xvmڵoo-MB<S>PyoB`N\^=4 'ODղgnzylS.]ضm+7o ,"s.\p>yw|iV۰}6"""8v(ׯ_4hm 11_ϝ|6B<P2cL̞mu<{ӓ899jyѢBy } bs\@gn2Fԉ4_ttl)/k/O  *oL@XXچ4 w`!D_f-۴ahsrP9S榿`^PLl %K4xd@omewKwec𜇧99:eEYB<maaa6ΝO?qm-O{oݺE P޻fKMsNBvTXVZw^}_իW#7 ԭWժc 銷7k?GժۘR !G(Wlڴ[|1c(]4]+?cdddpq]j#Ge˖$&&y [~0{ݻ̎qԮB˟ɾ{VEYB<4}NysT-F-///6x `j5T舫+E/_!)?qg8+}SyyIqя-L}q粳M(yffɛl%DQZD`K!d>$%&2|0_fNɒ%f<`gG_6*S(<̂ 9r!K!DQJ9x0۶mgP^ᅠHƌuPgn@lLlaÇs v|Crj VtiFy.K!DO̯ [+3Ev<}^MLL JbPݴ[njǥK&qɲcGx дi0>[1zJ-bܽ{תuB'PR8"<R?8|2/_rSϘ9R(=1a /G'Bb (E5nxvƵWAѠT(f͞CPrrtFC2ep`9rTgK.CFFIIIl\BҨqc HmHLLUtժUvڄt JVʺm~ K,ͅ/ !ēX777222HOO $$OOO/r4iڔ5WӾ][F%5s&֯חT*.\ gr=E+wy8~7npaҰQc9b7c̘rMDVP222xyKxyyMrrUj>j-!7)֧B<<PB؅!v!E!]H@BaPB؅!v!E!]H@BaPB؅!v!E!]P(Xb%ӦORq&8;;- rV/N:Tn׋=<[1zJ-bG^Q<1`VDx8J4 qqq (Eue._ 3f`+]a /G'Bb (E5nxvƵWAѠT(f͞CPrrtFC2ep`9rTgK.CFFIIIl\BҨqc HmHLLUtժUvڄt JVʺm~ K,ͅ/ !ēX777222HOO $$OOO/r4iڔ5WӾ][F%5s&֯חT*.\ gr=E+wy8~7npaҰQc9b7c̘rMDVP222xyKxyyMrrUj>j-!7)֧B<<PB؅!v!E!]H@Ba.WDF@:~٪.^sWZ ZrǘGR|<,:D- Wŀ~gB<Ɗ@2R2.)ŀsNYLx \=n^8QjZm7"B<}@ԤbgřF%as? plҞԄBe{+k8z*DSn䟿qJ;".x+''W4h`]ń#Ć-IMÿ,// kHP6&n @6MMO'=9w2fWC!4OD@9{ukȨt6 w .%Ơ-c4ݿ.rvO!DOD@MNZh\=P(zXBQTyjuIO+_aG<*!(Eyw3H}p֔r|=Cno%BXn_eت d%sIn)W5Nם/ !ĿM(ٙlgworYd&Ynqoe?l*_-#B]Ms;4_ axIPJڿ.GKZ !xk(B! (B!BB".$!bwzB$G(B!BB".$!PlI%x#!va׀Ҹqc7nl.QnggFe\\~uԱK_*MУGO֫g>%{΍1 zӣGO5nRiI{{{B.!{x9;ТEKuN m0L<ٮAɉkhѲNNNvprv~T*_}cQr%&OŠ|knqwwg L:u2e[qppBŊ޳6mҩs'vE@@TzuvW+W~7m8~Ӽp!&O潅 9}truu%##N.::AjJ Zgggt:j YYYFR8::j|Y]8 iii&)33h;:uRtiZlVёNSbE\bM2Z-F5 &ۛNrrkGRFRbrA]N ''gӍύBÃDQ*U&$%%ӏ?;$8bܸql{.\yyu(fΘ7?n,.\J*lٺϖ/'99l[!qvTrRremA} u 8f͚q!vű' ۳w/dڽu~7ٻ]~:̡Çٶ}UV5nzݷǎ -z'NrVX @FF)))ШQcݣ/߽k͛?@zz>}, m=s)yAe̙TwnA F>С7mBW GGGc}1r7e5,dahܔѦm[9۷o3q4oLfѩSg}AA(]fMiҸof+K?a⏨[964jԘݺ,)]Ӧ>h1YpSڵmC۶ܹKyv~ ld|:fLN\\\*.]BصsMԨQ:oȑחM+L>5jk.u+((gkbϞ1edZ<ߜWGrH IDATё6mҡC{6i̝;wXf-ΟGLxu&Oy 5hЀ;Ҥq#v~/wttdy3ڵ%<ƏݝfM nڄLxc-jիɓ'pssÃ;ww@.|`ޱcG~gmn+POΟ={пʔ)KŊYa}>tpN:ի)SFߵWlPw& /WjѽDVKȮEբh煶gL6CZfʕ,YX/^˖-[.uΟG^:upIr9QQQ\~*4K]|95V F[sxϙ{h6lrqq!55wEJlB>~q常^&EvtBVkEOf?F;^sɉxӑ!pqq!''|kkkjuT*Q$%%=sF[{i!?HxsRX>4a VK\\c1k4Qb[G(I)vfffZdi %@@ (U" @ ,0(@  "" @ ,0(@  "" @ ,0(@ 㐥޼\efLRiG߾}YliÖx 3s%~hy ̛&-RiGFprvիUO4iN*U^'!!#E~Y&dRn߹͌ӍkmmMfpvvɓ-1k&66'֩*U"%5S'OT ^ q)Z;ͱ-OߏdPߒ˨^bxzzbkzҷo_׫ϲe=f^JBwѪukwhϮ]!xzzSN߰ \ZXt:FMZߠA*vlڴҰlٺM:pe* ƍϦ[x&}\5k:muw#|^|}}S@R*g( {{{sT*.<rrrΖ򲵵5z\r Tȃ:DA|7w.Ǐ7\|大Y'JEZZ< bn {J"##ШZ"ɰUi L#)))ΖΙ/k9b8 A,Y4FA̙33g1dP\Jשsg;-&,|'NdاҧO:̡Cٲuޑ "hBBJ|vIaA;¼9b# 8_~YgC>}#Fd턄8h^޽?$haDDw`Mt]/F@@ou·a߾ݻԫW6;,SгgO4hȁ9p ;vRZ5կOXx8DEٴi3{r4cǍC&Affd L&ܨQcvCCBhmi}}}ȑ@Y,o<[; ߣlq.={(_<*T0Y态9B@s?~:@.WmP&4f( 64+^Z hԸ1nFvv6...K/\{MXl̝;wPt3lի/Fxx84\κ_~GXd1͛CϞ=ɟX`!70d'LJMp o$nh UV^zp+k+zУ{7n޼IڵٰqAAҴiS =?۷Q&~]!t.[6oB Z#F 7Z7ZnM۶~d2VYK@\xa߳yflذ!ڵ#331o:wD`ccÌ3\z-[>,Y[mҟصkQk׎3gptt$=)<:XYY2֪.}/ ?ƞxy{{ARR>ʡU-n޼ ŋIJJ|ҡcGEKtБK0zʕ+ǝ;wCHHH0ZǺڶu YYY}>\Ox43(<1#3ȁg1VVdf7#/_Se^r+WYlՊ:Ξ'u j ֭|;Æ1Al‚eȑtԙxT*|nZ-IIIu&U|||ǎ!qws~t^^12(^^ѱC{~'칳@֭-ZKWp 1EPX||siVqww/RJX|ӧkk뼺E߾}֖޽?o,m\\gNGP\9JiSg+dN;L&9u &ˬZ*gRjGGj֬)]ѭk7Ξ=k2@]N޿σR5Cy ,Z$ +9r\~ΩS9|Pٿo+UfÆrPq9۷6u ˖/'))  bŊf+ ˗/spA֭[K``)))3kL.][֌խ$hZBvg/ZF/>7#8IZj*J%cF.ׯ?^^zW,_μysYz5urX|YiMO?/" 7vvv,_S EFDl9s۷gY=`СR26}Æ˺uFugT2pw'1)WΜ>ͤIL#"nԯ ܁V̷zm3:&5lذDwv.CVVf!3%K*Ņ422߯)BBB|i ''bion%ZQjGGlILL,spttDѐ^촮n$c4^q-;;%fP(prr2[T* wyOjUJ F-UVQcZmr;bn(Ϣh4_zzz @_RP@" @ ,0(@  "" @ . 2" @ ,0(@  ""P>˕^f3|^[nv椦=jժ+ !G5r3+rԮ*i?vЇկ/W;:@&Q~}ʗ+OhN8ckkk5k3'O\6кMztfPJR:Ύe0O4iNRiGFprvի&ϩ5o #.e\,tzZH7hPlll?Ur42NGđ#/Aw0x}E 0t0Zlɶm[QT{wاruIGA̙33g1dP<׮3rp^yYx KZCٸiݺw׻믿y4]! Zx{{gC #޽{ѣ[MiVSi߾Afݗ]tڵk\p+V#-:vq&gbPN&6&'G'{wx@<^dwss3>>ά \Vɓ%cjJEsOQ$}%}v:uD`v:wb暬@\cl5\HhP(<>a7;w[kϢjר?t^˗׋V{t+ EPP^ZJ] D۶mCYu IDATp}^~,mۡr)))h4*Vh4zUŌ=T۷3v8""R8r0 q"sS*j=>>W77{FHG.3lP :+@^emU۷ocmm777GZo0zy-w']v2zkۖ^̪2UMZ04I(_<gn\;Ћ[А ]XH/ߙuuVqrrkzJ%~7Ik2?YrŀXfMt:7nܠ/|VkRT\e˖3/:TT-DFDVdPQHhwBʕ*U2+cǢY&uu~mvW^?:Z-m=r?-|Y"..'3r( z. 88ʕ+ӨqcI^̡C8Kn޼?mVJ͚5N+i '+3]xzK4j-ZNdd$,[ϜaŊRNj!v d2̩S Ͷlll&;r*4jԸd4i7;::2dPɷ}bee-{(UT+V2o8}T0yRf(|<`;߷ʕ*aFP98{ 4۷6u ˖/'))  bŊFӍ19bT2fh0@JwyzΙ3gؾ}{E\ OO+W!)1M7HOd vUP#Gr4(ΟgԩS'N"ˉb_xzy)XyX6iVmos>ZYcB iiiddcr9eʸ_,kk (j5Hב1,NGqdTPխ$8;;av=cee3 ŮRiDn `,{!F)u.:ILG,jJ ģhVK||~c0#/񎲧E_V2i]1FffY/>|D`H)n#YQP@b" @ ,B .' F,@ (w8mQ:Rvzd6a$]v&1s>̒Xb@  PMXCeE A@ XaP@`AEE A@ XaP@`AE(m wb%˾{i]@ J?6({͟ؽA _4@ x1)ڻj @ٽؔ{X'% šDk(}fc...4ڷaX[|bZ/DvmM?1<= ߽ ꛌR_>lL2nL-k99Ib}&bLФɛfG/*QH% oDӸ9Ꭽ-^ԯWdq+w/Ŝ2WJPu8QǎR$77P‡d2/fYT>ޭ+G|ۓCvN [f>ݐ|ˏた.Ύ̬,fe#;'Ǡshr/'''Gz+IA.cooOZ3%,Rd*l؀NGvNAW5rL(J>|h0d2KFP`ogGjdT* ERw,:d0N)S'j#cyؠP 4W2XEʦRxh@F6,ݫ'+W3&};?t7ܺA9Iau_m[ؾe3!;ya)Ǜ˖l"Cw2rELxN6mНx7,jle˦ma)G>k~;m7on~ܟztcgvvd8;;P^D9(Wˬe-6#p+ڷ#8pY{U+m&rmӣ1??۶ldo 晕:Zw;Vlt}zM~e_+{劬u-۷3h][c2M0X0;BvЦuKj5ncdJ%ӦLfwvmcptt46[ؼW=xyy Ğ2Β~׳GwMɦҴɛٽU+ eg6K*иo¦3~msV-Yt1nn]xxxlt>;uj IaE?msqqAP0i8Bvu q7q)ݺm7{~k҄q 8ukVyoܷ}zPjf(nnnxxxp) kܘLf~3cTBά~/>w@O|?`i:5kqttd\r={ +WM֭5r8VoL.I~OZ5ٲuuf)8z4 gg' i͈Q_0zx^*Ḱ}r9K{5kg|///ldd2fLÇYbpagI=tC_LSa}oז<SLJ5k0n$6y.GOz0k4 _y4EboostkL&+++F|:y߱N]{sr>lvvR~@RѮC'r5fϚC?ao ƚ~mڣ ПӦңWo4 3}͹stgr4/'M1GߝR;KvNeʒJ C{^ʒE?qu2VVVt> ;Ԩ^U+ƃB, J@RRb6m&7od}t:fdMvHבGQ\9ʗ++TTT w77.4(ȵkjxyyJGܺ}GHJJf( ݻ?qs/ 4 999={oۛʕ+ob@hn7oҹSGjתN#:: C~~m8uĤ$ڴnɓprtrJy* o|Ta͚u<|-[^O3o7ko7I.6lҋߦuK""R|y^XgѨڱCrzʕᥗ*E5Yj :FUifc*v<U\:Mp~ )))TTlbbbZ7}%? w~"++xyܼuѪe  w ~ NN ڴ"4,LJwUDD׺n߾"99ou)53pBy888Tk5CJflybc݋"uBB^F%99%W?xH =K=$ݜAn̜1/ />U&''y~mXz-m?y3d7w7̄N>\&7[sdw޵ 111uBBFvuucltJ7r~gff 999dA.Knzwpsq?,t WW>lt~} (]j8xu9} s-A\Pr_RcPv:mZբ~C$$ZdDr9cN(r1ё=zR޶WV"ͭhyÝ'8옒 888`cc#-%htodt}=~~۶68vҦD.?,rnK$\]\Q^'ĊU nZ1{;;OH 77JYNGLlr;gW}Aqs-/!1{ >X̣v)HbR|;s|%Æ2#>Aou6_a܄IxyyI`KDPNPj\^Gnn'wmg{ u8Tƍ͛5,-NT*ޞG;Pr9]~^4Y/<--'S#\" ד}oRnC`s.wޣGn@s'gI=~X"7u;v%4,Lٻr!=);w-onKޭiOV2ɿW@@On߾͛u6W\O%`LG}?HD$܏ʊڵjyUw,G""i߮䆲NIDQ*Wg\=˖^(<䐝wXʊ>$qMQ\9i  i@͟Oxڶf$/\fo5ef4Rjf(ʊ0nhRSScwع+twcLr"[=BBM9~LKMZZ:|5eC}̶p۷nB! z[ ^_ENl |/0m޲ӦЦuK֬a%_NNаp6𯛋) y)Li̘6n]Gw/5kT7~cI뗟!R<3?ԧnCV0>@Ov>+rqpp?rssIMMKcySbccKrrrxEc0[T6899N$owK oVuşd߽d-vےs4M7)\ZY#hZLG,L-Pe "1ƌEQ/3aH9=g) ;'^V[hSMQ16(KG:h]+],\|iXN؞Ĥ$r*,,N]^7jtys.o (0/ښ2.ewJNN%JL%3(@ '5A6,aP@`AEE A@ XaP@`AEE T}mX _A.Q+fl('-=s\z4-VV oQD$%%cǣi_3o πWkVݻޏ1YPe=)͹}Baƍ%6tᎻQQGMyR cϛݙ8B@V=:J['~O񋍍Q'D "J-&7_W0(Ea ] "< DOp" @ ,xE x& S"!f(F3 ,C2h׆/WCptO / @?55j&:;;S^=j59}4F oݪZbRg+'Aik/mտA.o>օwiάo#>!^T82 "0^LP(P,S1Aǰedfg2fXrss޽;wԩS=NǢŋoJ#ɘ:e gF./H;6~#=ϴ0yaiv1+8t$C# Yj9vg/kXr6azfm݈o*ҵo*l۴HYz~Н7fVXJʕ([փ˗l߲X`Vݞ$bak IqcǙ4&5WXvv6]L5 ;e2ydZEd/9?|X\zq9͜ȨտyK&sssΫ9x{MXY)pkkkZ6شu+Æ 6;Ɔ<w-u>5~!;g!tٛL4!||y۟# @Lx>CRbE{J~{RRR0~<ԍaooOJrdkFÐ!C^:}9%iѡ?tɤϞgڌYL4ԑkʯǎ %5._!%5F >)ر+tpI^;ՎT|"]Br>xD[YϤ֓6,$A ˗-eOq:Jx&~9Iow)0gJUVz9sƍ˱ҽ=2*_NdڌY~<ժr[2~qrtb<7q4J(?7WBƈe nxz}Re4y"::YaP[Xt)>>ElbӧOӲeKoؠwՕW_}KH׿?k׬9hIDATχ_,RcƠ:4,wSz9=2> I0y}5x^2`.nnm;6SXV[rqq)2nRR2W\eU<˖5˜Pŋnc׶yb֮]KLLl kV~Sˋ9ss)nbb"Ɍ7SN}j,Ðh:>o [=sYY7W~+\~[[Dk@˪SE=p4P0(3 d|Whr5%~}Nđ#DFDȍ7 ꕫ,XoL1o^ FoJ7z?K1oj5M4&,|_oƨ{\\MU[s.ybclٶ_ֲ3p+C?Tr-ař3u8_QllmmP$$$绷jGJQge˖?qҬz}[G捛Od2HNN6K.BY2ѐ=Fmb E x&XdeeeG)֡NcWhBt:IIIfh4'$|syyD:q;D㾂5 ^AѡM ;E2Yd:,, lut40P04abf8888xLlF0HQTKt7 xȃzߴKvvR|I@Td fSmQĪVh" >ǎ`5mc(F8bFZQc0]|H1n<(0SpͻF$SpS4h+f"ERl/dl)ːdEѦyxD"v3&Vh-fK{{>%v;B !@N.>p4ômco.?.*B!8^rYV aݷ8V}Gbbbj5L'OG<55E=8eZ0Ԗ-[l2ˈTNyxDѨSkF "D-^64%Q*OtP @Lu)D.x|Ri%t:<^/XRqqVk&D^xԘL&PՉ鹹ś6mjmm 2T& Zcƍ>zO{@OKMMO`hF@" ӱ.{#hJw |T*'=^WE4FL`icGwR9:iLx_g{͘\." azUWUePgdd_ÙߋBD?~7(,, wu_`Z}[ѵA(P p㸬B[r-vO@dd$E˭CP.΢bb.W|gقQUwa7^(ěCgYtҥK\noذ/j[5!nZ[u:0(X}44CHHC?JH  RP(dţ|Os&:N'IH#Bǀ(U*]L̥͏ft\TB\tiVVVpESYYV̙rAu4MvSd2LjnEQf}`O H'#Ik.Zv8G|x3 ;qq| j\2ae֭[dɒdhmmٳgOEEŠ: _utXQ*JR[F} A oWǟ0(^" hhhhllZ(GFFD"茊 (n㇉H$JJJJJJb?-C&>~hGfk1ホ `ժUxڠ5FCRCcccrCuE0L&iԨQnlmuySGt:|>?""B$$Ijll>{D?qƽn}Bȿoǎ{b޼EfsQa!a{~^z51J fN@gR*ddduBZ2v{IIIffD ∈󷆖6(hnoo랏D Sh7oE4-HJKKinnnf e:z HBq!>ٳѺڱc^exO,~>ꫯ}URrrr}ݴٳ,]z=z$a `Bf4nXVݟ͚5 +鏢 ފ℄X\UU͛ Ǝ]ꟃk4^/ ,,L477{<Pm0ۙ77Imx !TWx^ z|_{;)P4ݩ Xz>nMy۶-r] ddf;sΝ+T*eee , )qs#W~^..._]KDvܱ}劊n7{Jr,NG"ө iN#Ȣ^\\\MMM!wWT%_bs :l^aZ<3g~?)hkkŢׯ_]r*Xz{֭[?{^Q,7x*\$PdbqT*HtsPW O=l߾cAVdff./,\(#2G@{{=[\\eee{oܨӧOiqqIMMpp\ `k>4MP}A}jg`1l)x<oynUR򒓧]\zj؞6C'9r+k挏j0sLHNN<5 h@(`|iUz)!:> "OQh4"+}8PxdEEX,ffd9|t:ݗ_~5kHiR {nܰlKdzi6nX^~k#XM7<dX,T =O} I~Ϩ##EbB0q"~lgĉυBarrcXon0O b^8ΦvN٭IvO(P3O D-Rxd ,P"1 yӦEA9$\v0qĚSRR&O|]}=퀊zq 6"I`8L&Z ~AE_> 'NbOu:ݻ|c}/ lW$Q yѥ+Vh4'/'ppB$Z.b6_jlP}>08;N^#pÙ[A[S3LEЫ]*=zT)++miižKP7_+_zŕV1 e戈alLaB].8?Qc`0 "jMMMC" n{ԨѧODS" rƍ*.:־e74\di}}}yy-^̽OQCEM%-y ȑ>޳\QX9@;t&''G9sߞǽ۟~ 0X{ar}v~dƌ;wڷ/?L?PTKӭVSTJMkؗSNJizFFFIIɐl^fof~>a6mܸsc|+aydbv;gΏ?;v/'sܵ i,hmUUlllR\\s}=AR 6y<Rzw͍Gl+WXۿc}V[[>im۶3;;ΝFn1{~;,, Aݾa a( 1 뛪vb)ʺ VX!HzJiii7o8 ---c$>t \.)QE. y-\18[Q ҥŋ[fSO?ͶTUUٿO>9̙׮]Os / :xС8TJz}E,8"趑Fxٲe|_lYQQm/'`38ξ?k~ ,r|i/9jϜΑrf+X {ZZZ4 Arr/~p{<TVX97 ~j8l6#bqo`9p27T*0 ?~<;; &޽{޼y}S(fg- BP{ Cd_kh~[u3$MWwUP4-H.\@tSS(LJ[QndM;{n ֞TW]7nŋoԁq㫪 إ_ߺukVVV^QQQ[n]v6dE%pA;mHoŨGyDBҴN?~88n BI++Iұ755ZC닊>|Po۶mšq{7HrJ= @WbPcqinnv&>bl$ 8V;󛛛w}ȑ;v-qga~m=5v"Dhumlݳ}t7 `82NrpiQVz!.>>9%Jt8^/qXJR(ap- [jUaaaIIIQQQMMlČhw'O#Rk?wώ;>vٷd>/䕩ߙOj!GBRT*BP ]n +q[Ș5k^pԩcSS[0\hu:6m8"/w.P@p>2o:5xB.8 vp|$O%"L(p{|.py)a&GA>M.7W aN {ef5R/#(6xb/_B7r%8bT' /籶NYz C+NO!>4]3L J {R |_ 3i JɖYh1Gu[[[VZůצI#̟B:k1ꛯQ(dr/\Į{#ErrY+VQjUƍBΎ /1x*o~&z7f$o-ʊ3g2iT"*TE }N:uhBѣ9uvvSkh|RvJąHc&m|TLI0J gWVɻrYZ/i/ZwXz _UTIITv1;X%vײV$ k9}8;;tBuw$ʕ{pVJZhNN]HLLߧ}D:uNc9~+|*EPСG3޽G XRvEXxyӷO/~ZԩӦu.L4#Fq9*T(ϲ%?r>6t?ݻPT0~YlA$ *d<$aT"IǹsWd2Əø>b$HEɉF$fLBݘ>c+J.* 7Ĺ~[(=ߞ" JdrB)rO"AgL*U2qKĶ{:=2xXKxH.dbR 8ZIlKɜzA)1ɰ$A d :By-Zmy֬]O"/^EP[?NRpwsŋԩ]˴a޽+Wh4x{Nsθ8zSg0yw~-իU^ݺ9XG!2Xo 1OJ|]e܏s1N1yG!Cyanh4u2 je>11\]\juz4_?!cuZ\n1X~^Vӣ{W͝MqwsՅa_}iQ#bcc|}zdꕜ:us~ ,<йSLHDDsXÝXzd2NNhOH}k?f>ݬ%SҖYKi $- O2 IਔH~Vọg$“hJ4!O( oܠQ\vl]ꑒŋL\]]L߫mlpttqDzLƈoFX।|*~ҙ%JɃPGFE1t|= ߍcCt[ GX8پaccMB@Hh(O.ͨN1p'@}7,$UHX1%* nO݈J62wN 7Wj1 DDF2j8"L|=XDO?#11 #$ⱶV1yt0Чz5qvrb15v'NMVdWeҔٿ9Jnw9 |Aw4TB ($Nk@%Xr5}u̸o+i^X\1dkL|y붖Qi_H J cpD@A6E{dw_;;; 9QQ4O&OƹAښϳCTh^xp\#ƦY/INNNhZbb5:::"I j[5@RR+@(;ID$pXUONdg`[X$bSI:CKRKࠔLOA$bR /5P ,B^/JRMM$RRRMb29FVt:"""]o0FO'$dyp=Jbz5z/= 4;wҹsGFxA#Ro:(+WݷfeժVci=&ǩP>k׮qmV,_Ƃ8w ]0Kʕ`"##Ӭ] ]xm1>L.àÝwyq Uީ-a=w,!fLP<GכrJ< Id/@<- H]4(RϜǍ{8yT\^}r-<=WK=^k\~CpUppttRlw,\c\$1p@>܉ૄQT)._ fquqׇ={fx'',' V|5l85[ס Пu7ü/|]H<7ԟS>s&K @^kۆ[( ڴs#ؐ`8VVVzKs`"6[s)VINN;irk\|0&%V,g <~شB@$RRR,ėEx3}ҹԎO?OppiRQTXb IDgPB5w, fsh4I@Vr|K ժVcg @V1d2iQlݲ-7kvjpa/;s`0gggr9RJmmiS'>w֕ζ׍7uLˬi԰mU+طg7_ b?n,;H^=MΙ5.]>1;{)[L7۷EO%Kq:vlž;Yp$1G8/#s$Itލe,7KRRRxe |-[4g׎ 67IjUټOvځg|}]%UV%!>/" 3Nf\Zuf͜QON7&#=b},i1~?,5|ܹ Z fijɓLiШ 1|7~:sQ/+V >!:xV͚?n9FBhCӲMsib{Ù1m*~i}ڴmGƍh٢8;v`Ԙ4o?>|ݸ^D!  __6iB֭:e2k֮Cc)ʃ3n[--"hѼנ&OIB Qsn/vC}R*v8Iw#J%jZ `i@tt4'OEem[bf/ H<`0߽{32r-[Q5-6dq,e9=ztg׎mthM&.>GPhQX Pr%Ne˩W.vvvѨaC>w^BAjU $Iع쭤Mlٲ R5,Z(˗# 02KNPyVwȏ;wo1._&*Jw%>4l؀F dJq&)Ç),11s[e!vvvDFFe{5kq5m6`kkkk0Ib˶mИ|j]v.̢M'=mXZufΘjjҟf%lg B:eanV!ILL,Od22/P*4jؐ)ӦDLddI7HNWWؑQ_DD$2a_0KFJ!=+UM"::{]0*ɓgy23PEEEq ZhNիZvӪՇT6˖x1:@ȓ 4S2(QsbEybE.]龷!8*zID޽7 WC|* f͚r,>W!:u-[Ӭu׮]g𠁦nnnY|OuӾ|9KT*7oFr8} *JTTIj֬ SK.Νvv:666w/|?+[n]6xyyn %B:.%iRˬ:P!OΞ H2VPz9S&Ӯm$`&LdZ, vmLi۶ 'NZ;wQbtFŤ;XT*cǍ7H X8>vl#)9@nܸ>W4v; .5\0M ۷?J?g̨`cc3زe+vclݲG2}lzrȑRI|k;\8N1id23~8&N, #N69gibBn.GHJJʱRAT&ˑ{jJeqCA.{{{T*&͸h47iZ8u%B=x*UV!jeg(2 h_/Nx{5MBtSP%<0;;;>닧;vzu^ع @-tHUڶƆ6L4h< yѣܹkV|9֯JI` N:߀k׮E ˹u6AmqyFVZE=hӺuɃX*d B^&fggK][$'xe *T(OddNz6mZѠ{3X=xjw=s:FR2u:͚6a$$$ii׶ ,_ ֵ { 22I&^׮_O:Wei.Io\$ yH^ظX>6dV._FŊ~ӱc{֏JoWd=t؁|&#I;w1;^d26]\\.g\q!C‚ysޭ Lڵ䓮=HNNTɒ̲D^$I逳:"gѯg#%%wb0Lѯ_3۶`0a6iǏLdqZ-~VF%qpp@mf1|?;PT& 8ά^Ν:FRRRAC$H| Zt' tȐ}Ϟ;GF Xŋc}iZ~9{/|ٳhۦ5WY&XX?9++%VVJ>zęgIIIau|?i QQ>חտT.A Qlݶ1b0v=WbWeܷ(3ۧ 0y2usϟ5k0m$:vhό-.{?bAb$ӦNܺuOOO$It HV˾cvmqѶMk~K]y6cþ-[CqI0:vh\.`0pX7l,./RgA1b`1wL*T(:;$I8::d)J-11fn) <AWCXT*7jHũZw LJgH[V㈴E-A "Z͈O:r7 A@I@.M1 666ɔ=WlCVZiIA!OI@.zvA.]pjUR={OAx`AB* ((…-PAQ dKtYs̩:luߚYڮB-S]ƭ۷X| ,:.\%sJ0i׮Ux.!puq;U%44Α:p֬]*G× 9Ide`j0~XWNaooOʕէ/7oJrB4pk׭gfT̢z_vZ$IΝJXxK`&LW||}سgoqrrr0x@85kso…h׶ nc Z6Ͷ666$$ #lds|Ypz?, IDAT\mZS8;GV&vI#...ͼj5))fcD<ڪ$$&9"s'>~֟`rR @F X$@$퉎Isb9x>&o<A&=-ٲyvlvZu {޹08;;#9x`*U2mm?L:{0wŸnܸIdd$u߭cZfmmM 8xl[oooVZ?ž=jSLǎسk֭}իoؿw77o۳}{vӤqcӺRJl;mclK"$ݻf @JJ l/eڱÆ?V*7];L>>#Q =z޽Xb~Z={yQ×ΝOfp>j's9 L&cwn8ιsY×/RbSV͚9zb\ -[ѪՇi6i̩ӧ}mfƴ;tΝT*4`^æ7#I^vܹBrr2-7g?p)'ZJU]"Bf 0KwMٲeqrrIm+oǏc\v-~JT,0&J Q ǎc/ѣ;vlCo7qOFk<|E+Wb/1 t:~^zbggG@q|}o6#ܹ{Q(TV@1IĎ;8:۴i͖- U̢ER|9)S4]N:hZݿOORIIIp-ڶmC*1 f ߸^pa/bbcLoO޼U,+V .>ұBfLTYbзOom[[[]|R)DIP z6lAL20VZXuILLp!!!d2 d_T*i԰!SM#))#)9(n߹n\8y-[rQ)ʱZla ^ϗ{yz=}Ӿ}ذn-'ObƬل1m |ҙS8"ٳr>([[[vo}ׯjMi744cDD{pxtK߻%Kfҟ?tZy @" v?N>I&cժ_M2QL2vm d3a$ckۖ~gZO۶m8qdjع+[u0b(&MƢR;n<H2qqX[[dcACXX̛/-\͛^' z=iSԱ$*\,GT05lll:}[le=tО[6sQϜ/\A0h?/3{yI fQlL,ΟEBp<\ە*cgg8N17& ˆO}YC|ڇXtk~]Q*DEi̪ $)M]7%IŅt=pvv&..jU2r>K"aooJBѤiF8G~UV-N9ϫ8`;SgO0TCz!.WT<|H*U 1VA.|Tr27 h_/NIg Fcqy||ź{Ǐ-SLn4aT*v\pc숉Iw,]!i],442Kb 癭-޼+WWi:[=忮B&fڶiM֭W2s֜KW@ ȮLoh^Xbt,  =g./1A?dSc]Y O)V+\AI  P: [B 'y"#A d[ ۛ{D2yU;vn]:H",[NbA7QrODR%ѽ nn|$=fȰopsG.,QiS7M# {}JDDbER[ٻ?bmV>r,Tł~}{DӴ]x /`I:y"fϿdzʖMx$ԇP!OS奒gg'VA?Ӳ>\ gܬ wշ-Yq,ۻ'E~jժS! y) P'Oq4mmmIJJJ3ƳJeErr óGfRfI^([[[͎9:9p,m8v8Y>?۶;w j˗g[6n2}0!>fMӲy330bN( {zS$Z?[ˊU4iܐ?\./q2VX 9w8^}ޥ3qeW{>SԮUlj֬Ȇ -q!e˔fȰo̖׮]ի?Xm߁C̟;A4m[bCxժÌ|Ph32ٓ9 2۱̞;~X[[G`|1(<==Xr9wd*YGGf}6%RD.jеs' QL~3[oq!{S[,{˅ꄜ-*T[8=wy&,i 7 /~a]yLiΟ;q yX@ >`3gssgxVڵjr]C7@\|Fi ώgx6dϾQs>A SMZw(]$'N=kzKsW!IHd>#EGGg}Rj6NǨ>|G'G01q4o!; @f<,D gw#IRSs"B~ «%f̶ܝEPgsԯW?7 u"S һ\ӻq4=Ϝ^)Juߚ^A0Rǟeb*<.I^zO"337}@;yg h4fYJ,=AA^[JGQvmBBBٻk;jq5kY\^ry<=n3>>ٳ7c6e|͛7G\K5ŋ{翐 X"Uޅ 3o435Q$''[ljeeL&3kIII,QAAťMmmm-.ccXkkkbUj5))dkؐhHx2/{kIII$dte2j:{%Iij숏q4NCﯝ{ҹSGI B.x_ 3}&~?mw+J 5bŊIp':&&ϝ3aGYt!CʙgDM ~v'''.ϒK9gZʹ)B-[7kkkƍCu1\xCuA&ښ7oy <4 GڢP(x{L2#GҹSG>Ó1,\'3:Z[[3zHZ4oN#4,wsNT&3k&'Nzj|7~ T1!f __bצukƏCNy20p`\Yj Ɔ_k?n,daQ8;Vߛ7x/r{In]III!661cq{ӟl;={t3$0cLNS?n,W.nnn\+`|O~>>$%%ϖ-nF;w\W:3j$...(J&Mb?=|kz04iLڵr`̝s>u ŊE&@^}x[׮6KRRRxe |rwaᄑ̙;7&3xzzU_BWE׼Ɔ 6l݌iS9xWkW]si}Z-fL/3yTr-[`3OVپ\áo݇S|y7npHbEih4(ruSU( װHdq'NYOQ(hZ7n׮Qy+VĠsӰaCz͝;wybE~];vBHz#{3sfb>r'''~^#]>u3W?c.ӵKOJ'+-ӡcgѽ_G:dP(رCݶ}aaa 9j-M %%_ [o!Yݝ3g)ٻ dS×sRr%6;v`@ >Y^K*][\snʖ-OlZnTq 1ҬH)Ri֥[V"'K+O'_~AQSqz/GUi+;zJZժfU-ZHҥqww'(uEXѢ*Ygn߿Q+CBCٺm; Zh;>ӲE 7kʊLZ_}-ڶmC*1 $&&vŊjWƊ+iؘV?nzΝ\|( E0mj;>r0aom2-7' )S4.]xbx.l6d|GP4^ooo7jȚ5kINN`0J,yzܺu{`07Ő۷oS/͚5E.~;;;"#{u}zo ښ6u߭C#ݻ57Zjv Fll,AA2iv*]RJr ?dٲ_Xn >k*vuwwCf?mJVҬiӺWM??EXX8իURLۆ !!Y:u;igL:̞=7MWQ@Ԩ዇;/]0~;'''jfO jQd2tf65BCB͖= |!kwww(eZIgSg6XXFH賟㈈tۂ(?çrZvEBB{b!,YlIwiώOj,%K>h&6Ǐ`ԘyQ8$FIe㓐8!>ZRs;W&""xF8ygΜ%""LưGX22*c,I m2OӃ?::777?mt:=犞StYu7С}{~\FMiEA9u6w0LfgPeroͶlY{Ȉ._ =Nj\%8?$MVhpws.㿂k9xȏaܾsseSiѼ)[xU:1Y(}ɞ֗})L>IBX_ fEL< Gnݺŵkw ٸ~-1110kS8;Cll,n%oBDDBBٽg鸃 ׇ07it?~̽IHH078|cFJVvetooFq lmپ}iC~,YU+-A.ŗCs:R񧟘6e {w$11ÇG|D&LkYetײߙ:e2-7gU8::~< ɉMm/|3k؇FAV}N4]бC{n#GM ljů(K[;Y Lro;P#fC., K`uߚ9E03( 4iT*h4Vŭ[}H6g8:::Q(88ا;oZ5QQfquԏ IDAT=ml]VV#etoS{:e^r{mmm` EZө d8;;^Z4ٲFBJс4FҘEM ([EӒY{}ʶ$߽4"{ z$ TegXi 'ΊKEyFÿNYsMo1 KZӽt5Ffh4AzvBHHH f2Zo\&''_VRR}ҧxxVn !ʽENcu;WY<Y>FVSR%FAbB2DƎ6l *$M[Ʒ4N$76P؈7 kL7 ȄJo:Qz?mZ"&z&&& Af_/.Q }oź|̞)1bETXfM'=la3/n+߬XN\^gɢ/3zfjժ+wdĻ,Y%["2"];濯?zHDZsVѥsgݺ];h5"w޶% 3?J4mڄݻvmcw-ʛ=׭{iy+qDɾuyfM'((K?>oo2e23¦?>[p>ڶmSVQ}Yݷ쉌 jwQ81cLC ߱# :dp6155eɢ/iL:XcnnNش9{vm^zQߊEzdZ- sKXFe˵ת,\"o1jd(~|HOg(Zl;wHMIE"OOCpٳ7v|s-ZLWoӺUKÏO`anA~8p * )R XXX /n室C5޾CiI)?z7o֌={ӹ71q̟;G̝=IItMN]aU˫+y1&s}mjnjrwWdeW|Q/"W\ARmLQ hԨ!E΍y?_>̟;̬,.UF8;LT$))y{;DdWn-_J{11t&7߮48S[֫T*LUQ++uC{ f09w,۽#9T*7?//1ᅬdffSRRؾ۷>܉wћ[ eTڬlW]QA| ׯ]CQA8;'eB;YdUGeo\.ښ[eBwuvvFՖ%J;:: Jy>Μ&fAG^hZ4hW*eeewYfgݫNZ͆شy {būGgeg쬷'|+ ?_AZﭲ: 4o֌/.zr2gΜyLvv6NzAj̦[T q-h4dff@xh٣;o^l)!!zH Mܾ}4QQӴibcc sVnܾw^zyؔ͜611ãz&͛7v:דIJĐ8Æ!!1*ߣLOgyW$;'\~8whX^]Cu[Ll~|uW?_;o`o䖚z&KWUT_OOOgΞE]-^ѿ_qT*w>~G)h3¦Ѿ];E"#HahZ,-ٻ7[1a8Nл~˖`޼9싋11zYYkO{ښu7zreiZbcFF0]2wlztF"OfWB>!kVsgKS;v쫥DF#Xqcǟ,^ҧoFҬy3222c9-?[XX/uWӓE /7̄L&O TUT@14ZjqIݜY窱¦H|l oPTt?0y 5vջ5ӱhwv~/ɓ' XjXHHM+8BׇoI.!HENN.갲B kkkrss)--,SSStdkcÝb[qH$ۓXHP(P(deeU{011ƚ,UT]Z).6؛YVQ}r9V.RocXXX`bbbT8ߚTe?J$ZVZq_m $|) _$# <>" )5I5he(V>AA`4S Oat@urJ$zt&8( pvGF+b7Zx £AP-F1?j9ٟ"IXf /&иq#aaq˸ײAm~>}ZڵkӴk$} .k̚+ PƍBqe]$¿ƘBY1g,~wʑ#G֭[9rwG~gO+1~X.YU9U< gܩ]:wysxG.QLd>L`_7nTaYx["88u߯^-A*&zG`RX5 ˿]A0\{{;Z4oƩS?͎FשS7x饗Wn\.≏x?_Hd2LV.MLLH$܆BZ]nBAIiRSSS kaaAqq^R)Gԩ(((0EEEzBѣң{0A]R饫=*P(()))W >Gz2nKRt=^]0jH3IW\縘OOIVV^ތ[~}02XKΞ;K{T*d&LR>Mޡ6%Ƌ/ȕ+WPTzh4D$bw$;t`YgXi{DFFvjΛO7:̟^i&h4ƌ3g]'AHB;2p؏t ;~ɯMZeYZZҵKgBGFT x#hzcɖ ޤ7gggZ6 | ;#FJ1{֧/ qp?1Vf&P6a&6mB^X+:u.]deg줷ٹ}gңg/Z- 4˫Qyȩ~qF8y| ׯ]CU?YHR&L ³N 5ήݨZFLѐuuZǟgHM;2e SRRi֬n{}+#??w77$%]bA@YCHHL,׳ i5]ִkזϟffrLMMѲe 4nn޶-P6W.Pv?xfffU݄Dg[VVV&n_n0B ?? !{/p^WWW֭\'/ϟ7=" i&p5._Q#u߃U &zGgw߮`M\Jq :BdQuDxrˣ0ḹyZ=p ^K66.޽c_9S>9=TJRR3?Un;&&hP(߷ʺn֮^Izz999nmahZ,-ٻ7[eцXx錟0ɺ;vdWKG*~FuK^ IDATsfghݺڵ]rXXXPXXD*'TqqL?Çt2듙$:@AAfffL7$"IڵųWk<]ٙ\#'=7xsI<$?<$<-R# w+WI5Pܾ}{[okcÝ ﳿRB ++OS(?@ .P((r;Zkaa\.'77`^{{{ λd< K$lyO֘TO³Te?J$ZVZq׿IF+IE3_ OV+eKJSVK YZ~wUBn?xtaaacw'UTJVA< STTTA@5^ µZm(t %>6Q,][Yݷ쉌 jwQ8ۗ+QÆk}W 눍ދ3} a|v/.]~??ΙsN¡L0Nwmڴ wd-Dz_8p۶kFQa![/m۶m۶_7_ݺ];-F&r.wl^cUDH!zKonnNش9{vm^z^yMFDb&&z^ӢEsc tAx4b8@q*8'p7kkk}RhfϙK^=Qλ#pww'3+Kzxї|2kgΞc8Q 2=6mZ :5jի\pL&Ld8;~Z`ot4BCY~"H$Vrf^^?3>>l۶ADDFu?w&L_~套fJΜ=KjM䦦t=zRjbz9 h߾6]j6uC7x,Y%=srSS>peR)F}vNH[7:LiiA0@ϴ,ʺ}IL>˟DBB">>4)))$&@NԞt]{`^}Z-7+9={ (P(tОX.qfyy4_Ҕ4o\&bw$%%%h4~>}sN<\.>z~F߅Je 7qe4 ""ʆ\:wDdTT&c!z߼EÃ[8::W.I.KQQCa¸|JvGFҍ3KKiJesqv&))IoRE9++[o}F-6y y?_>̟;̬,.U#M/sOqrrI'薥MfCV@fR֝2]ҕz')7􃨈ݑ0iҤ iJ%.\pAx>4m҄=FoO'gD"oo/^c~ȑC)obbIjgΞE]-[]twEp9>d&RJJJppץïѱc?Km`ooG`nx^@YC033DEG`\]]9yTGР~}ծ]3˭HLlE.T*̙ ߅Z$::桶-B1nƍCQQu7}U_3}ڇCNN֬[kҡ}{14Zjqr̙3M70x@_ 7d"2?aGeaF󱰰_ ;!!d':&Q4kތ Xdi%]DjM=ZAL2i~ɓ* 2j󊯿!lpvEEw88yiNӧMɐԮ]~>_9=~;;[}ُ]9yu3˜5{C;#,OfDjc̰&77Wov\.֖ @.{8 66İw֖rR(( D"ή*o|Y;W8t8ᑷ/0j|e XA'UVu zjHyW_}sLD3^+ _oo"XbW%%%ddTQEEE宂U*U@RXXXzTEV\PՕztFn*' O{ DpPP򥦤zHœڷoqcf򔩺 AxD MVzjQh H؏ǟv5U?xKdff> A&Z$I뀍|zTWMVjEG'~A%AAxF @AQ"AgA%AAxF @AQ"AgxX`<9._aްZيo\"}($j_# ALV;(<ܳՂ 5 ^ Ѩ7tZm;_^ uHƍxA |2׮_lecnnN~}Y{XYYѲe , 38sW子:$/8 ky=ׯ^Y.rx,۞6Ѻu+YիXʾ۵C.?_xB۶m?n,|CնMkN߯oڎ 5 jLe*|8y(܇.͕݃  &5&&&&T*t r% VVVܾ}ܫn- JJK)--֭[ v: JJ OH$XZZRPPP~ ߟ#GOtLYH$X[[_P'B&P(g P((..FVխ[>oyziR) : PR&LW[{r4T*-Dװ{N1~XݰGHHocٲi# 2|ӦMؽk'۶n8-]+'~mFL'{~ 4CwOGQpuueǶoߎYv[4osb9'&NT*ϳ%uk ɘ6lߺCUXgAj6 X=ɉCяTNZZۯ7ograVY 7'))1yz!9o̰`Th(o |WWH$eWg3T*e3xF&L@nj7CpA0iwؾc'}5ƺvn]7:2x@yw/_ёL\]kA}ރܼn=ryNc 4=OOO5j'hP>NNN;mڴARq#%-+ܺu ]{`^}Zn~nnXj5ZZw+WӮXYYB=}8}@-6l\\\JԞ\|(7`jj t!)))$&@NԞt`ڴ4%lm߯/dggSx oAP#թ"??H^Nc)O;ɧ7v ;tFØѣ4q&NޞT4 N^^>[6mdp;nطo?a﫯ۦ z'HRT*u}Td2*73?E7@YBQ*+FJJ퓕9#'e߼=]^~%D2nrsA Fa3KHLO?Ѹq#JL4F_HaQ> ZfMugϞhV,YYX[[aaa[V;a?̭999\/T*%77GGLJh2]]ks+?dҔ-[`AmAﹺRn]:u<0n[Seڵ]rXXXPXXD*q1&0Y$ 033cz Μ=7+#J]psss>=(جy3222cL`*șG`$R)IIIdCABܩL  ::4`)(9Cms~#$7S?5qqDp.\Hd.RSSr-\d22nݺس7o˘qtt5ٜw+֭L*իzyի _];'+T @;ӥsg7l-y\tiG;iiiԪU OO~۶UNO3fffO ]PF L< o/.&%q w77=^=DPzy >gBAqq1VV`&??5V P5 2͛Бhތ? ff%Kh4ڳ>o iiiL4ԲQ#LII1rƁ8j@8yXM6a`mm͹s1vmT0o0˹p&MFRLGi{uZ ;3f|Ln^̟;:u_'}%+;K9ɨP֭߀`0;uaMjM뇏xW>X[[ۍ.^>ݫ't}{D T:)î]),,Ӄto |F`` qws]:U?p@o}|;KII 4jԐ'NР~}8w7ڴi˛xSl߾(,ի͉ekK9<թm۶ǥKؿٺO {+x-xzzRsFl77W^y?\VZ滕iut6o(ްa#;t0Xރڽ:ד9r999la+~|mظ VFxz}^zF+T]kk+222 XҤkF]F+hZ]!\66xxsMjW?>$&'׫_m\~-LFJJc│SIDAT'!W5)sz*۽D6mR6Of8p߸J]e1DE!((7 ^NNh4ƌ癙j sUj5&2prrUԩHh5eMVsw:ZFv{PRRB~~>T*랒Za8;_7T*J١Vn?[>#j*WG;L[Tbo֭[T*d&ee[ZZGa‹\rJe-YY8;9-=z RukW#7-j0XDR܅͛a9dfepzC9څQ#GN2>Ť vtt (0]tnDRTTСC0n,|ݑFYAPcT*Ik'iiJ^jܘ˗Zj͛7fh +WX7ڹ%++TʄI+VYY\p%K*ͭ,0mvrɼZyggeamm7VRѱduMNNju`AY89;-sqvSQ{ 4[VAxyurN jҲe N Բ`H}4:o_.gwKZfMlڼ޽zbWtU.g}J˯,\YegU'Z: 4o֌/.zr2gΜ1ނb8@T*|דK_7_VV8wK7v 66\v˗0zH8U~\|P(G"JuJNN7ldжm] .N?yoo$ Ν;Ѣys?`Զի FCannVm䘚Wv7.`-yXͥ05-{qYղ5΂p j"vɞ={*=O=3z4cSL3336֡ ԫW׬XZZ_{we?p3æܺ)"$f/7v[.-V.Ң-r-MQܯkeK3°l3c.08)zzɜ===SC\\ԭWwHs hǧzCZlc5v}HV5N@`ݿN{ӧ7zOޜ0iP>`رDE޼KLYӦgv?cKNO~<5mJqQ1Wd@FFz}.rHMKĉS2!@TVNB!nԈG4ԙ3+<0YVٙ9s摛gWV 4飏W所EEE|!EEE\+uаaөW>'ZeL& /]Owݝ!!r=t{pm$*vHMMt AA9hϫVd2a49v,F ѡ_~9Oqs,ؑRR,i.^߬gg hղ%,_OAILJh4ŋߏ? L&iiv*2'@He0one}jsJ pIiִ)ZYܘ:%?='Ο?Oii>| 4\Ȱh1c+KjZUnooo}+W,yQ#_g\9TggX,|*oބu ';DMBRr LX/Vxֿooo V.Wewn5̬L232y#l_] r(Jt:>dfdZ̤Vk ˣut,DK͓O2cf>?'3}nMddd"1)o&bʔxzz>0;=g./7nZP???L&d󲞅 (Dtz#o9_/^ϗn\ =k{srz |WEՓF9y$]̓O)S0 Z5kf|d]BNI̶wҶmп$%)(n2P* 4f̌L6n?P(x"r1GYGrChִUQ^=jyvQEj# ec8zCvraUTywwww^Oۭpe._NC,Kt.8;;[GmBPP -%s`^Gp0!bi٢['~t:D%&NqI%tQ^1ܒRh2KGh.hctwwgAڳҧ֭Z. e ϓr2ѤIcF#@V*Kat2 j@ 쟶)4/0wZZ:p)Ն ,^Q*XzeoffU i_Xɸ x죠Z{Qzb Lq2|9z}+ׯ]36K=E qV9\|١%|{&3n;zVˊXKX)csϡtRͺVi[`0EMY3rѳf2?J%L{`οGϞ★)-5pdz(t83OcU&$н{ Tˤ2{<-4l#? իW?>0Lu[/r )C3iVYk#i؎,t: ؤăGQ^%pi̎&66j(nS(xyy_PV >k :'6_ڬT222ӑ[Vej5Z\u* OOOv뗧(((:vFZ&''xԩCaQEEE6eesrrrګxzz0+ΞW*<=ɩ0uPgFAܑITMpp0d$@8&N]d2qj׷7roW&77n=Bawvv<`iiCn_~Js3nh$;իW֍e˿t;h4VUqTUϙI zo5DM||%i^HB!d} B0#A!aFB!Ì!Bև B!3BY,֩P(* Pͽu6UvbYQ ז܍)6~u$&%BUkḼ"u|oƯ/B9I_ܭYRBRJJqS Y/n!Bև B!3BYf$!>HB!d}#XWRv rt97(BkذR jäFi[l6_r%,l ,:xrJlyyydr/܎P:xp-\ n(7o]֭[ *߱; `ts~ֶ üe{sԩ]فaoQQUEzvݯS:}fN%a.paܯ,U}g/QP\6n|0w>9b1߲}AcG vVOЬ *E ([>Fdee6kRN>m0_0 dddqnlA<<)vݯ;u:"_H'J uvH)]vn 3#SRdBkZ=o7ltK/[m㓜2}RJׯ_흘hŨ^>#[bAz{5W.Z˗_C/?x~R aIỸsHbu%bΐˌ׷RLPz]Tegk) 55޽ѣ4ǴTHLLuy,\Чwשּׁ7U4ߠs 8@&O6QFϟ?}zd|xWĤMz;wFh͚53e$.R4M5=xk !TUgjSS|2d!lNňƏw۵sh49rxqZsÆ Q b>޲yU8n͚Z)I'̛B=2ct)۶m7o~X,*?BѣN>>p@nAA֍fm}o,[N9SOիW(#Q(BU*U~~eJt_8BH^ǚؠ~=Xb+;qZ4ܻwsF [nޞb l4<啿 Bd%/)V0fsMpP_Zt8i℮]"xG~ݚ?"~?|0jGLKf͜ѳgE?-8|02K#G A"Pڂ9Jijjjc322pj:Wr+-[DF}wͱWYkkcaQ"h?qd !+W>ei-o⟝'MdXzdqcLSjjժo}ʕ-[<gϝ3b.B$&&f"EB2+VnݶtjժYr''GB-8qq B RFb0_bzz˲SInn|.B!0^E>;;ۼwǏ gYT*cɧ ) B!d]垑DFgi~LVnǎطg>%Dzaa[jUA"BȺ^~f܄Zvٻ{^qp^n=4iܣG@VŢ,B"?ҳWhB*6d}IFFF9BʥgmB!J B!fmBe'ީDwv-x- *-#A!aFB!Ì!BW3]N@ᑝvҰawyQ+[߸Q^=zBo7Y; Py&ϝ;g@zFB)q@B`J0O_00 cj`ԧ,\]]/\`nY&y>9)ߪU+W.znAM*\~~~111g$*Rpυ!,3Y؃Q,CIVִmD,*HUOnӺm@$tGܸqC.׬Y3;;/8s_-:ڵG }e*-aƄ\QFkG BB0 Bݕ7uՁXqV>#f\jx˵Izedg!Q.? ۪ e%h4-Ϟ=}˖WeCC/[W\)j B QVYE͛pqvػǏn޼Rw[nJlU{e+BJ0"*y{ěJj61Ō*D?El5"#1H b36лOSN7$ ~pԨ.ҳWީNNJnڴY ]-O-DNjժ Tуiyg3 v`1PO`9"6?ˉ<0@L,K*iDRv9rDbBe_;vt`B=E"Q~'Np5Gǧ{j= \Ybހј6BOrr3 H)]~}JJwEn]p!T`xVorZX:wGkw-XՇ\c Wc1򘻊˷qZ[111]DΝ!N5obڵbxevLx8h۶-h4޽fpbq&oc`׮ӧO5hРQХKkqߠ ڵ 0r;nT8F,˱ J1"<)fJ;NTsIݴ ٶ홝;Ǎkw3h?rqZ ÆK ><˫ZbRΝeH4M5=xk Bw6}{`7tرv3gV*+W.Doquqqssѫ!d|xS>>y:B ۸i9z/}z~~^~~kHPھm(0T*/.޾}zHr^608NPTg=xpC]ٱcR٧o?"tGI/^"F &Hӂ<ԩOO/̮_ŋ&N8U˖Dž͛5i6jLkO!nnnZs"=#=--#۶m7}eDGܸiٯ6>|l۶l'X.y|| diФIGUX̯ή!TUM%K;u-K>>޷nӶ]w,]z 2j#v Dž?|?@j罾קw/j8Ak}B^0ae' XKk?صV=vò\EB 3T&w)ԯ1112Wrrsu/ھ?/yALK;-iÇ[u+)viC~u@gϝS8wOLleN37mTKq @'PJ'Wn?j_\%>!`|~T!M~ "A{΋~Z4Ni>WH".==_vvv,j4,ӞXa23J50pa1xk3lmCNN X"rƖ-MzoN}8)pb(X?J *0\m8~.W>O_&wJ21V4Wd=- nW]<xm8d1cF2Sf Tt'A5TY1rT=c@)u^Jc«2c> 13t2I9%gKixx3i8J]haϜ={uͪx*& pT\} |0~QI-# 2aCҢQgt#81s!}TP(=2"YC #~n1o|W5lPT;wځ`Fʎ1U*yUDeڼUN:} c.P S[0-XYb:!TƄdrHB<x-3nm^,wߤ3]8RMtdzD"BUbbbf$ `V Z$$P 4;$ʥ>P3xT2c ܟAJ`&lLʕ+y5jOvD 51RO4'j@jlA 2 -CF" [66:iB&QJjQպwQ:ܳs 40e$fljRUܼy gg{1Ji``[(qqq/uVĆ B\ƳU(>!%M~:u0JjM ~*%5CF,OlZ.۴QQQӦMǎ vvvWt7_L;3o;={NJJʻurrVTtݻ6zAF9t0DѣI'ǿۇks'^jUƙ3faƎ]jbÌ!Tn_GRӹF](\z@s.~ʕB#n߶"h}0vl⟗|ݷӦMuvv m[]6}n  >l[n @;F'>}ϓ5׃ O y2GSDq?浿}HیPRĄ gggJfj?vhbB9s6owcc===yQx8BmRs.;wnԑ#1 Z.q+6'Mٳش4Je.VP XxNg~"/'" 6vlDĮs}5wnrr;Vql֬ibbkL?yRnFD/ _ IDAT\ jcc@jxOHH~q+ f$r' HOO3 Đ 4vǪdb^.a(1 a]vN˖tdztopo g͚wF}"88Y;wR&U'99e_>%%;11ъQ BIE\ĬDTP XKE*H!\"\P**\!%TTO*RM{[zakk[ƐD"Q@E/(TmnAA-[ڽ{wWfk=<=qU*>>AAAk8`;vmݨp!T,X " O3,+f9"œ(`Ȇ4b _ܕOqb͚e\*BѣNFG^п[Pk`FD" 2͵Ԟ k׭#ojJebGR;J^2," p 1#a$Dp`1D^>};8mgGjgg3>6||ڵ͛_d:о0O"M)y޼ХݻmM۷stty+vl߾cb%/)V0f26d g^ƔF6t5\.:=RiKIFEPʳuG",a 5>[p<';Fbr=bH~ce"u$L\\˒+W=ʴ {)K:EIE)+Yg>^JXAQ#yaWčl׮}O? TpՋ/?qFqS6iѣGi%ŠaKӂ"Cݺ~RmÇs /n]sKF SJ8MJJN޴iDRK)Oz}ZzD3L0'}1? .VO'oܸnV*3T.([Dٴ7lؿeƌϖ/_yȑ ByƇ{xx$&&Uh۶G?ߞ^'[m۽go/bgg[]wS .O~FDʫ TÈ>곽yKH*LAHNN.OA3T( hd,*GQe,Q쌈0Z\pMoIRz+[d2gy7#\Toj۵ꊵ"  `ic(@IGwp|Jߚ3kH$RW\?q>lFcNnn;g~/ĺ|^ŋ,暝ݩcMdYVTn۾%KdžQϦ:=v_޽z zD~wQb~Z^t{l:PJOƤ<,P TB2U Ǝuo;#v1 m?0455uph~ųg] ѽ{JJkC OOpss۵sGDĮ{}i{jE~"~~u_ژ\r`)2tҘR[ E?~۰#CܣGw;;q& HJJbYITfff?OPn7mjԨJ>}x{bKJm>"-;'{yp =˲?~?k˖(BEŒUB  B ӿW899999?y 2O<=_"۳gzu뚳aAݺ{ R2,{Ęnܴ)kHZ~\yVػo֍7(9g}]M4NW(ⓧN/8f՞MC=oҋd HPIHHtqsZjۆ7mt;g߸qEo9JKK{w/"~ޣ{Zhޯ_H}lxIaӦ~שS &G?6~6tm!RΝ;@VfRdִ>y˖5V^zkBX! UBԮ "hqW]5k!cRT&F<ثgS;ԨQ!Ѥ66jBaԭMؽ磉nތB  HPdggSJY/{ǍK ))Ν?-1:BU#A#.˖-eF._~}GSL;i))) Zf;~f͚֬tJի&~do:t8o߉ۻ;W,gO""v>?wŋvɲ L)L/CG9q"/Oٹ3ys~1)Z\A[10#A!6mܴ^[ߧS BHOO7OFYt:s9?=Z"ø -_ k>y"FPBWC?xУWol`AsNlvvv,|Ϧ,W{j6%<C[R\gmP'$4jԨ,=4iWB+榦Z!Bjjսw[ѴkYz*[,>th=Kuۤ]v0Ԟ7{6ftݵ_:mv5"Oq[׳!TaFʄ5k(Bj1a{S`CҢQv~/7:R%h^ 75nRK? !|R&Z *+ƴ'>?0 X!??b;c 0Ս˔`䩑%V>kjTxcZ*ˆZ91.fBRrH   rWwYQ撽[͗, 6^*wo޹`W'LUHP[;JC¯TNFj4oHfsa t/wHebŊĥCC "]%ժ鼼wD6+%̋-p!dR[ Oh hT :Ud_jJ;޿tA)Tic"R*0 +) y9eP"T%VTq k1xNt IiJKV'KNeI *kz7R hz10e-#؏FÛ57OZԸ>yӝ|M'z!3x MǮ>'oSe_^ TXbȺmW?zlS:RQ=~f<αJ: *ȯD%xH hA}TiBlˇ69eVӹf}S#'w`c۾rȖvfe|%yy@TOC0査bX*D0?!IdE^*J_grĜQNkgJV3P36nj|^#1@b4Ill8s^ ZI>*7#޲&׎T2ΟE,1.쎟uDj4iW'Z^*'v\fԲ1#Sl.n#urtJIMhBUNWny~5% hLi3Q @z4;.ǥLI?"ճMGF}s76XLtָiSݲST΅>yerL`" ot.;;KHbnݮSv-Z BJrcnzmE̊t9ڼ<^FCQAY@ lU2-Uqzos1=uZ߈YgnV9uU,'25vPkM"D`ق}*חUZn"Ȑ"5R˂32 u$[33JA!K -Vdf b4PsaX %#LH*ۅ${374 |F{Pc]DhCsc9Z0uİg 3A&mn]DFթEz‰wJ5˳qYw6w"*-usizo0pyb4J3(O)ՁsSʍ$p?Y\9iv.^z[{Ntې{֌{plcnMkJ'+ek<[QF7VR$\6mKjN)JJB9a|6g#H_n1ߥp+e0Vf鴔3hSF@)S <1(aINgKL+TiC`+eLq|3UjtY@KA!-+J^ӗcXܹK/'TrT8F=զ' `!#80<0 N ^oR.@4蝍+QJt8Rr:R0#A;#U!g$}}RST!_TNzmJQ* ,(q!ZVW\%%*lE!aFB!YPDJR"-[*rSɧS1tfړNts{{[Xբ3-&2, O:t`ggշ M6jZR_r Jv>>bڱTŒ$].QB !*Nmɂ X5>{n??wΙ3ԩSg}fzSdwy',,3 6tX@@i}u1O8)>>cKlРAoO?| ZmإK蓓'OiݦȑlٺanAA'N4uPu 3Ͽ,[VF KTb媗 :t苞%aƄ\rժFv8mA,iN 2,TOVNљiY"@ 3 rD{Oכ[nY#9C^6n8{lXpaq2dHM-bL&3 <b-ou P5M gw߲e~?.X0c?b'!K$KF^zUqW.JɱlaFVrrL_VZ~8 >+W8~"z~s G 4{,S&=sƌAFEE t钵bDc$^Ryc%T%2Jc&+޲?drR@۶j2-ifLXؠ=zT^{ӧLVSRR>3{ف]:9BE~]߸a}AcÇj**QFۣR]RB+72RnN B%SRR HBv!Jw@9y$󱱱%P[ ,:;;T W77sFRFM5STO}CBkPE~"Ç5Mrrr}Z>YHȱO׽w=z7n\?zhpp7=z(<|ܢE?Jz 7o t/S>9"&&ƊUR]֎ N,U@XęBBUS*BCC CvvW_}_Z5k֬mn۶m%#fs̑H$˥!-#pAʼn&nllZzJbE = RL7 innEr֭A~Ï?r"ׯk׮ _c:vuqq[bB!dp蠰c#"v;sKt*;V{U|BBSS\nR#a%R0 BM 8P:jԨyt۷oO4)==ŋk׮?iii JJJD%Ȉ\-CCק1ŧ}U*U``ב#G @{j;u /u *.BY3GBb~Ꚙ|uru}kSzOrr3 2jKIInT"#ie$B%rQBB)[A"Ie*=B?7dȐA}M4{.T._t{wܹ#%\ŋ2RrR9=zھhcbbx1;CBB`͚>|n,qLј1oV?q=z4xt!22R$U^t:]h;{{j5 G/7((ȷvA1߿cNXF2 jJ@ZruJiO(RBl$HDssi eF.|@)efŊS3,sO)NTTX,0q9sr_|o{=vLǏ=ZӊԾ!!۶=%"b=<<yY_T*c]>{iڲ|֯5"bVU(|rurӧ\vڵk{xejJFu2:r݂<ݭ[a=/nKBMՔB(!@ r=35>OG J-`O h#S!ˬ7/(w IDATؙvpqs˓H>,P ]]븸OK#`YbGeERȤLj{l^d2[[[VW(H$MKKlcZ[[[?>v ]z9qFc1ǵuqpxȕt#(AԒss. CD"=]Ozə3gN>ᇚ'35hm!+yR4#/obb `/YVlKfffOԹs@@@׮.ꦔ#ʂBE^G#d]VH]%,K(C$)@l9ôȏ0 B[M !O,2e$wqOHcGTLoyJ$a̍6[ ۽{ի̋y9={nذb>!dɚDщ"c8NG RK|D!_Gq= B/O,ub9XL3Ϝ}(eg4ٶy@^ÇY'910-u}11UULLu1 g͌+C)%Kf)! c(0p$,16"iNzIկ'zAO)$QC˗9ʌ7n8995R8Vx 'hԧ T&,øK\\89 V-b EO'SSDxfe ymɞ={6lاF Ӽ̢Y>|9`8fjy(?_7Q*9ST+Pevq#!56@(%(BB%@)#Sm4S#J  !m8B"TթA!}ggsF#ur23bڨQWNRT*x,+yDg ,]k:3L*f`RBЌV$zAC(Q&STyD=>IG@ P'@DJyH6LT(rةc-6N0wOF/D0BZ"A(U !+y BOD$@Kt@wLVTl޲E) KII1-7w]{VZ󥑝ʢǜuIBJ_FFD^3޴iF=wሎn!.̙Ȉ̌'NdS\Fas~RI.هS.mۺy"ݯ|u7Q ۀŠH@A%S]- 1Iugp Hku% ]:B"O9&WJPL(@I^{9ݔ6HXӿ__Xj=ڿ_"yj>8a ,}C˖}޻fYc/MaйSg|SRR`ڵkٿQ;o׫Wo؈).gѣMxϑqtJ}s8\Ҧ-pV3r!AM9&c8ˋKi%Y8Ϫ8, $ޡ; =NVF+mC"A=F+k%Q P*J% `%LN:}zqq:owVջv>{\֭ﻯ'A 40))LrWn 2M. P¢;85U1֪bQT PJBDvfpmcJ Egf0 <bhA_z7I+ZG 1 3LF=Ze4@MiX J0„R%K0x9S@oϗ׀`.km׷<Z\\ N;n}ojz˖g_~_&&Zl -Q;v|/a>>zf~rO@Zj99<0Eq5}F1;'c5t =w'|3w&MTQQvJQL/|(!@hH)) Vʗ9e""_sU % +Y!8@`EfV髍K-:G`HZ }<̕mFE@ƍCÇ{j={v@lll Yj#;2 X6AEp"c]_j5p  B蹩Sl:rȎ;NoQCx c0MPJUjjgm_qשӧ>X~~~HHȦ[VX._z魹sǍ u֭9sCr8q…&_G4ZU'%b;H|yPS@#ۄ8cc !/Dvx5֋/ID@9Jz+vR.|QKw`-9ǎV{U]G)֨PLd!Xe)%@0Ƅ0-"YrDu/PXNLkZ_~Un $Ӊ򄂂Z~Sc$ajMR.L#*}m\p!L R@)&(cL9(/G*Eā*0h.Wn=*-߸iMٯ;n^tgovNΔzl.(((O }t:fݧ`Ah?rhŲlJlV&B*_<ԟ&.;%9lyv ڣ{7Vog0ԯ@rraHX\ZVA|JhƊ"qXRBJ⋐ PL Ci$G]:LbJ[;qjcX233 lp8_^{?!$;;[# F|Mb'BFRjۋ\n^oE%K2n Æ8pFNo0n>}x"&Wg0Մ@` >zkIO2J#ih(!)!YnG SBDI[%1 I!yXA[qQ~ 22@SPKb+1; iiz$gsrZGFRJZVNZĨvDFyfJɳf϶l:7ذa˗wiۏ={׮ٷwMg0{xOMMu˒9^ &,!ޑ֯_~:V)**R9GeO0Cxe^~iTWZ1駿DE$Ak7W$mt&B/RBVIղJd BPRe\(@ReqM9UH9'2D!.5<(rVi+X,t留력 áG/҈#mV$*: !ZSixD`EPB( @ !!@o{PҗN*pJ1H8N%wj](6[,%K2% P PlRbY{۬H:LzQBZ/@C(2.RB*ʄSR@ P@S UhLdrU`$ F-a[Ֆ Z^Q Dfq%Ymkp mP_skvq7mބDiczZT,IL0Vk(qa,E+7RJ (U$P2+SgTP~,  ]53[Dc`&$ zAo2 dd y-Bd\ksD0 p;Cz/R$Tc D1)D(M !L0$ݲLD"LL0.TU@S b"(zo0S Aa yYdl+R(# =mT:=)4S7EJ"P"ٍю%;]LqaXƔR'%vJDe^4Die҅6`6wZ`06EM%k9nInJh(RJH(͓EH(=,Ƅ8dF)Mi 2dAbAb@)/24nHpAҸ[+`0 Ns{IJBUpZd(RB DW2%$])|,RJ@KNdA0(piAjR)-q"ֱ-`0EMPJHq9(%)v5"x5LZM؁:r!$,Sx;%J%D II%Jj@+_+ `Tmh!b܅H,.5$!SR"sq|9Sꇩ&1@1}TR6$ j G A# @>q!4+`0 ?[U$<.:/EEJBI!&iDJ:P;WvDrY9T (8 fBe,`Lr)d*+0IT.\:`eCwJnNHt07`ŕg0 ɭ*6 q ga|Y9bF%|B8_LdIUB ) Pr*" LeOp |6+`57Rdm{[R$:@%% s 2|?@3Ȇ };****m`c$ q aE<//(:bF#PJ+"AMyG$9ӰQ3gfJMy>$$`ᢃƍ'LzfbqqqU}6V^Pr?nŋe,3նEL0@mQp IDATnQLj۩X,Js[,qÇ8hag@ZVEB'4LNbkUWEqON3]!Frqi:XViF#2)TeI^eС[.^صk'4!!aeׯ;vtbS$ n8d(;v 8KJJ̘$;ת jHrp nr!4jS >#G@$HHHxBqҟϛs=qDBBB|۶fv1Q֯ y`ȈHaEѲ,۬)S&_rǟ~ \j5xEEٯNL1 (~8M|N۳gϋ/<_K76mZU+W|QJ+r%iӦ~QܹoøW8rȤI~_}ՙ3`'O嗋k6G`02`6~凓ׅ0ՅGSUj jgm_qשӧ>؃v߯QիJx֭[עyܯkް~U<ߺM,Ν:;~l̘#F=ڥsӦկ޹Sǖ9b2ѪUM6uעEVZvm{W /?rTHHHV~۰qOrF;naʖ~ 'zrٳgk6H !99yEE8Es\6R 2LPPPPqWVffaaa``h,,, V߷~/Z;}mvY+<9V ή^z}hQQQ(ׯ_ߺu X'OWw yyykPnUoխWit4G35gkaa {'NIN.[޶]!CjCu޼J>uy\0ƫV,wٯ޳>aÆHQ}PþyDU,_^?`՟&ШaÜ3f}oꏵZ`2v녆*wl>ZWoLݺu;u>>>}ݽkWU]ҋ/_Nqe0nHÆ5nAGڵ[DddZH `‰4XZ99##)ZV^IO'-CbT;ыY"p#VؼyJ~vYgl6Nolذ;vGSհoޛ_ >3s<(|…8{:h;΄ݫi_~2dkf{{{__VՋey?x63q%cǎٻgq𠁽865jڬZwc  zk˖ bbNW<qpRzy4yM3ks_fMژMQQgGjf{l6 4 AT卵1N3`Uc{f3 %Q3LNOeV};l` (rV)UJb{~?mʏR+jlVk)PCnY+]t:avoSi/Znҳb v PJmϛ98kX7.Q\+.*}8..n߾?YS۶0 S$ na[Ֆ Z^Q Dfq%Ymkp mP_Y*y)Ua0]0E`0L|5X &Am z#PY %SKl"ˀ*X#mY H !1J+xdENV*L BV4kڵkۢysp[l!s缙ثUM^=n=qܚ+OesSZsN͚ޡNjj|/ QO]0Bk@C [U$pܘ19wΛ[7olbV5 :o[iuC #222\-7nzگvڦ_~ =P٭Cʄbq͚]t۩6mZgee@DD; Q Hꆄx{{O|fq~}\q\&F@AV5B^^1[^q\hh=VsmSzӎh,w_}M NpV[\OeQINN*ꀗ+h* *\Zt6q/b7Ȫ9&RK z#+=r Μ9O=5:00YzC=6>\ah 83LJؘWpdTSY1$%$M{Ųu`ܒILl̕+WPJNV^RMzfbb=tȐ'A ɹz.g~rnݺBϘAMf|к/>?`0x{{عkqFΜk2222=¼װa?XҊ׼EO~rƏKMM0qǒF Wndddzzt7ͧH0BHΝǎ}z!O{:6}wwZPP8tȐ3f7_ӷS>l %Iۆ˖r7G<1xqzPLп__EQ7ؘ3g@ӽ֜+W~dCýAwyoݧ_N{ᅌ%?3w>DQ5kdޣgY9qqq-[77'Zz\x1ᾏ>>Bf9ռyg@LL"͛Oӯ'Ok[?;}̞[}r:cɧ=2D̞ZXXhte!6-66̙3-x={L虘ҥKNSA))0n=VZ5ՙU1 pkc$11VX啖̤g_޸qcƎ ///AK/Ox V^sq(,,L: z]n5v˗8y\~=???؃ؘk~>y$͗eDITb ƞINVg_,ꛯ޳gZsW^Sؘ5?MXVBb8n_ N3IAxV}DQ?*pϘVիR7p( z}ΝO:_P 11$yWrS!1˖P+9筊WnHd:pࠧ)M222-V+qM6JyTTyZ+Kd rjvڡj`aҨ eo.$9b𢢢-[:ܩC[qc5͡ʲ,UN9uE>%7N͛7+7(%%9LG_NN.#BtMzj6 =W$6Dٳc_ǎń۶o뛛WWd<ԩӤI]jOVgXi}+ӕ^I~e^|^6mڴRi}{z6h~򕲭֜Wf $\bc?=Ю]ũf1(QB  .]TbjL̶z>{e ef7sJ5͕W|ttE 8q7TzSLƞ;wޓ+&:z_lʵ0F0Աcd$'(7mT;ř˃]BCvXQٛۢyM}b谜\6[XZ^91,6+zo:r^U4**9%Ec0ZoEQ:pb05p<(3 \ր=TV0Rp&N;yd0Ve0"֚[d/(֛&?/Ymye ,$ qOHbbbRϞU^v7oձCȈonݺ_~Xhh(zV[XXhw8Zn FٳnIaahyq;yʄF8a|:uʚU>zi[-^-..66veBŷi6駔j.rZ^= M Xq"&WqIIg6j5@KNwgF[pȑ5D3"rCF#!QAl6DPFNgXL"vE%DI*o":NV}T*wAAAE}||WNUT*Ng8OAaa5> N܍`x?JweKBقɍ1pN$ɒ=āX}V\}JB5G;`$ ƝYfСCHȄOSY3UΝkSi.JQ. XP'0pwZ@钓SA)UVyw"gB }9Ϊ$$IRůI,!T ϝqS D11֪bQT PJBDvfpmcJ YN1nxVwvWYڶ`HDHSGoҤI\\d\gxW#V??nݻ?TRY.tUL;v1>>><<]ǟ6oo` "65Tڶe0w@ ,y xyEpk4Qļ},Z2@ <#Ϝiبљ3I3^y&V<_W .:zJ; %((HZb0(/^X1c~Zm[ [Hd߯\oԬ:az^OΒH^̟82/>|\[]6'VEdt2 ($ߍ3Uv!4UMVZaС[.^صk'4!!aeׯ;vtbۿrֆ`@H2];bQLJJ:wɓ'8({ZjNY@Z?ШO-s%UBB;7ntJ̙#.Z}{.TB]h /ڷ-[֯ 9rȑ9s=it; s۷Ĭ^S|_9'o޼CǎJZ0#g6˥#"C @RZ-pA6AAA쯸,???$$d-+WHOOT‹/ܹƍ%xO5ǧ˃\dY?o^JJ273f/rO>9RZ6Ndd _9ԩZgܳ\pѣn<僟xbĉOx* IDAT/"a0w@ zVf+e"{j^ #H&T̑q\``h,,, V֯_Weh4֯U``_%t:udggǷ&QQÇS{Vyy}LJJ>|AYE2u괧FJMMEØ"a0waC?!$f3jce:>;tuCð0 An$\1)Sw…|ȕƤUTq͛+m6[ ⴩SZ_}}qeĻqsT+W(P(*Fx CfVM_@aZ/\8,gff^rX w H @ѣm˲+fYVk4 |g?R67l-,,p|)$ն]!CjCu޼J>uy_bHRJϟ?|Y#IҬٯ޳>aÆHEEQՕi4Z=2?yè-5l;cASJ,YUZy2#&S1!VK)EEEEEE.LU/7 ܢ%@B7laÇ8HN7 nr@>}oe4eٲ$=X &_J/MX_Zbʼn{, hذQbbbƍs gZ秞~,# ;f=JL[߳i(xä}Ï5,˚&׮ `cdĉaaY5k~C׷lZMQk^~ VӾU'SNa]ҀA"Kr;,֛N.`0crKFn/O*|Kttt9Eh$I*JtN|poFRSQϱ.KeP b8ivz3jB( m2[w9rv|FPT^ݲi'unOA~$ڷzmMڭu˷l-WOrzZŮvګ32 Ok;omԨa S&?3Ǧ6KJJ*;Աc{t!yyyC yݷ\.Zq%4j]Y_ Bū ڵ"HmpB9MH!w`c| :ux{y7i@23kH-fee7j-ec\Ppٺ,NP|Ϟ9yTrrr=*GCx{7z)k%uƬ3bCg0wf͚m۶(H6nTΏtt_znE@@ OS*deejj yz]|`0pDTy=* ?ٻ(ήwVvKػXW,Q"h h$jhDƘ,(6l`$`Ac.l1! 1w8y晙;>>S )Gw}oVqYګ湻?xE_$8+.*"W(Xz|Y]\]\hZRlH2sve2yJJ}m\\\Ə-oNzbhڬ)eխT*e2Y1<ϑB!z-EۯIڷog?Uv*^jҖ|_8dBtOFI^rB/ ܾkҖJHt7󶟿_ݺAf$ZNE |Wm^zVmgͪli@@L&zjՆP vsulXX˗γP%OL&>?gq[f@ѣAA]v/J7 o v̬M_3|0SzEPX-={tDڶ 4hР\Ɨo_>uWԈ!!=UAe?qb! ={spzI woѼ0 3p` bCd!ޕY(FA^nn>,=j6iٻk^6$cnޡ/-%机ud6tҶvPYfRǻW(S!22rcǍ0BADO^jի&Lpd)ӦkX⒒ڵߏ|6;~<9;wyfZ,wf^0A<HyƥKݝ`ZOLq/{ <(~ǎ/ߒnJYj4;豿ǟeKH%Ͼ}NP>RNu߯1JOC_$ C?t('@Y˖-L{F[b圸c4L&[ǔ,]yI-[_y'IfBzx Y&H9b==\e2)As@%7s%_urR <'!< b<8i(R/)y|ju(d2A*/fʔΝ;oݺIEj޼F3>$BDDƍyM69$6"~k4}Ijj> \]]X;;\\\/.h4>{qqX̲Ppsu=L(WWWX%Z\\T@9NNN<ϗ>\.iZWANWۯ?k1-SxVYT!W@S#A 8¢;%{4H>nWhh rwwgYv֭CiӺw߭Zp_|QXXسGK>sz?WLI}}+W̛7? S ľ^n۴qrR&M|п5 ȤOO#mƛo֙:udgg;.v2BU-88d?Yz͚NzOtO_VLTsT|_'V+@QQQ?vˋ PVIpWPPPq::T@9tL&StxjuRd+43RF)R/ Hm|&mԾ}A¯7֭[⟛[3$4tƎ ܹK]HB/>^`RK J98iJ\a-7<W%H&nqܻ3tٛxرG\úZj>?Ks=;ET_~ŢmΝ;oo ĉƾ>&--ܹÆyYmRCB/'ծIW*T~~.NJ%+pŧ sd4J<ۻj&3{%zGqqq1 8*TUxyzPvqns\hכ\(EYc͖8I%R5YoxΟ(V[jEe6B=W0#AU;JEQ|岯T"Ҹ2is>4<xAy˵tY奧ggej *j 0#AU;Ju]RiÆ kV-6itQ*d C[Vtn~fvNW_RR0LVV}JЋ 3PɱX,bFRZZZ\\ҥK ^PPxݫW޹s @ŢL&Hf$=`*3Pya()))(( I'S ei8A$ A999fY*RUɑ!G)9Gոgf$CL&?LA]zDgr,ŃƋϚGR~Oej~fUW^y|=Q#:׬i߹}}g'۶iݯoK V=B!zdjLLΝ+SKVzZQ՘ozb''J}ꓕԪU];FF֭[78K!BUZzmr}3*/AHV(VZh4VՅkfMO:=ۖl6o$HjIrXUU}ظ'N>+!BϷ*26uJLҾĭnJڗعS'{yW_ݝswͿ"֪Ukw5i_7g<'$Iۻ{+ӧw'Sv^8wN\dd,Nڷ7[7ZE_Oܳ+~I˽A2lN'ؼicCŋ zTqFgޞ¯ޚYӦԥ۞}@I>5G~;u=[tx_zMѣ7rg|cBBBgΘgZٵ{wrkD=$BMxc|@zwM,^$H$$y/'#IB*u΅0ӯo_Zw7ȤR|T<23rrsυZ-qgFkVm ؾcDXځ7|Sr>>>7oA\_$IfZyiZ&d2D"޹sf5)';;/^U=Y Av{?77WD"QTϓ$9w*@Tvi򔩹oW,С}tn  }IN`4O1qy$xTwfڗse˥/=L&˲ 4MӴ= ;}t (**""??̙3NNR -2z(z15m$ñcG@oTq6IMMM׋*bIӕ+WT Ci=\]]&'''왒4Mۓ6I..:]QKhVT~՘?k1XťYZno۰VVT%o\F7,JBguh~zKk!BQ_R)̘A;VsT\PXX`:6zV#UY<eL&StxjuMGeYLGпBhЛ-Bm2YRhPW`6t<x+G*B۶ڵ[@@@ŕwꫯ>DEh4O}9Bωz0K`aCѱN{qܥ;/{4IO2JyOO&̸]j46+f;u*itx&=f(IT7gμqވ IDAT۷7n2jȴ?U^;w@҃!TM6.]˫%=?(Gj 0+32686`Fv&l&Rސfپoxd&ISA;͘1#fӧO%RԾJC}l$əf,!|(R(яM}ʚ77%aa%r9QQY͕޾M^ov.UkBRD3R)MAS$RTTJR&1 C$0 3#K.=fdJjz`޼SN(5ͯ[>Mk?o_B® MHաC'S6m {&SaO'Lj73w-oIJlzMCF@\4uVrvÌ!T l6{fX,EhSU]vnݺիV=Eiir//Ba>roݺp?BrjODjإK3V,T*Nd11n.UY0#A$Ν;GӴ , F#v횸"q] 諯VXT*صBCC͛O3<=={ʝ;wz֭[N|cshZՕJXZup jgFF}ԈJ"B+JZgX JRJ2??_VWfkQQ˗{%ܾ}2pYf&&&V&Nt_ #0``e#<]h˓ݹTjR7ka B&XiV(nnnNNNyyy*LJyEZQ=+ŋ.]VXPe˯ ݻw7o5<Ϗ=kVbRYR\*o~&cvjԨ1cv3gN߾}ij/h45k0iRi˖z??؀ B&,խ[GG sww?h<bX,6׏O>rdio9آ"RQRO:XwIX,ǎQ~kA֮~osssL^b FRԆ ?v޽/~geeeeenݗ_.1bxu}3(fL:veY3\ E̐ՁT*']EHTRVAZnnn zF8 (^/jlX,4MWfy\V h,tPF\.JG4ZXX\-$Pբi"ZXU*< jA4ML&1ېH$*(RAӴdllf2}+yl6SBe+Py8j;HB5A0 AFl6 `2l6{j V+EQ !TC~Ma뇕- ~5mZ;oxz `Xz=˲Eݾ}۾1fj&l6 2{O"^OLYfu``K3ߜNNNK"UYAy^6޽+*WkjYYYA,,--uxc2B={G~f)Jc}ܥ[vvη+YpQ׈ƽ5k8~mr$Jխ{]#lV۴iS%§kN߾;;g:CZ6v[NNN<ϗ\.4].W#IY+t=h=@Y›EJ'J$cN#+/2j W'Z:TY%0/AΑ; PXXԗ[,5OUխOCW|y^G#\)ba@9Y`) e exi1K1R 5y6k4,6PCnCi 9:B/>\!TܥlFT9 X+zA@.r 89PG*U֒\尿OB53P#BMtpWRY8HTih6f- Cdmj[TTZ̹aŮLCFJeJJ!T3B8+$ VDiZ x֔Mcc#NyNyr&EGdrHB) X%%?fڵ4LFF@ ԰V\ެY3Op۷o?Zppw􂂂g|=u\l,veG BF$,@FSDQ4VR JV2NV6H$ HF9s7n߾ָqQ#G`۷BC,X7 'EZ &,GG B`ݼHJXsr^k׎8BP(xnk[U7@<~I͘1#fӧO%RQ֬YfjX۳ήDNӴD"ypJ2 qQT&e4"*y^ d\8| 7"Bff37mذ!Tl,j?sfߥK?z N8Qj0:痸wn8qHbb|{:b:u[Mӿn5whРɔW]=f-__}&O9|$#mQV-N۶mOؕ|X>}y0o;zx^BڜJ=~#0wOω>|Xbbbm/\ذ!TCX8pwue/?ș&x@F"aH {m<==&'?x*77>OF0qA$IHR!M A]\۶iM䒯N8?-|^ziO?;w.33fw}w&M|qm~Xoڰ^>l11}qb B& tyZmV[PTdHR1lnP&yfV,GYѯ)Z yyy'~zcǏ1a$$_xaK{n qcGk;feeX,ǏKH~9XzzztS-9s9v|+ jIp$Ay>GwrrH$Q7o261BPf*8 p6!#}+cccJXaŊ ֭]k߯ʍ\ϿX)h4qbyvV}G;wT)9PIIIF5gY6;;͛ߍ B&<<@ǘqſU"H"ʥ~ ܛk󘑭EEE/_իK@AA@}*A۶m׿[gd<&ϓeZb<==˞}eE[;'zN 6L80*AM2I&h4-k#o^blG.^h7FcAG1c]>;wү.^^NvV07+~CCCCz!dJ9^ppHϞ=CBC:nΝ rlTF G/;w`V^k$L&d7Ke\xgη!sp= @?nd+$92}7ߜ~llQQR()'H 3eamΝ;Ϛ-]ڵ,kەXNO͝1}}Qܜ9`2 b6A&?qaCٳc"B7FWV\!_~^t-敲%A4X{ey q_4}_ k+ɡAyK /9t,2RrZ6 F)ވaBQ\\\AlxB)!/u j`#c0g#?2A(p! ҏ0L&#lOG@q\-BJ`Fv mJ•bqxrem63@tSkƍ/!T*[e#R}qJT BʕR)e wt B&XaMREK ZqPe-6EVbe[Ď<{6f$@wtE&rK!4-B j}8HDž;p4B9f$!r!{\>ҰaZj-iܸW%cKܷ? IDPp0aaaHB5yd2Fbc9R9lָ|`L<$39s'~dܹ?mo*[Zh 'EZ &,GG Bݛ[&8xONmNؓ!An*}b+ٛشYGz{d>dJjҁ;^z%ZPpI|Xbbbm/\ذ!T+_uEZ#8+x: d DFF 5%:8pDF&o?V.Wij; BJ"̟`ԩW^Y ӡ};4d+ڥlZÇ-^HT~*T"^h$%\ymi%$S$ջwӧϘ>]Vر3{ݻv=WPȸ6~u?7[?m`/6|䘘njr劣b6Pj/h<_=4tKd2f@ƍVő ܥGVn<` J]v۶m+tyݺbڵkgߋ{͚& 6oIJl˖-녅}r%Ɵ~ = v ;h.\8ߦMݻwK.l_%B*===:zԩΜ9._쨨HB5@ܪ" k@Wd=6z^b%;{mvl^vd떭ƴnݺ%zdwwf͚ᑓ-V(,,฿AsWnN077ýXחyz^ܹs|{!˲k%%%ߟe7o86*HBye 5 v{wy+pNAz~ Sl-((HN>ҫWf͛^j=R|Tj-^B'''T*>Q*$9eJ=Yq1 ˏ:l ׯ )TZ:mTqLwj⨑# <XyJ)^/ymHs'MN ңgZߨM_mZ3 -Ϟ;S żRdV7_+5YMfR)-.*5O"}~~IOT$L^AR!IH(O={jၤ*;Yʑ4KJʕ ͚͝AZ-aNR%,ץ:Fv 7nd=_2O;Oe̝0;/5{9~A֯ujZRYI ,H:TL IDAT\Wr&SْׯkZav?ox0wAUf$j'Ը8;l6R_]"arI@O Aܜ _WOZ0jY*3a:tjje'<0@պ-?f$'/j7'M_+Wкa Is ۼ$f0u}A#=gaaa#' s^o_!0#AU; 77|U,b:"OGx8.//Xu x0#AU䣇JAS W)KAZmz^| ݟg<(B5!B B!3B9f$!raח رSl+V  2Ͽe/$͙3?fm۾~3~ O_*J0 IѫVZzՄ磙HB5'9ܣw$@jsٶuW ># {׮,k@TZH, Ôk}رӔSG*((([>jԨ!C92-OaY$rh|0 Je4yLD"!Il6-$BRzAH9kVJI1aJNNNNN.[Y.[V}ˢiZ"-J$IL&@=#7o@Ç q/ dff9szӦM 3P1껿D"'2*jiгW/>1r+4x޼'ܾ}l9AcǍ_|=_+ߏ}{<ǾoߡiŊ嫾rLy۷yŋNqq1㍉'QE!/Xh~ݲaC@xx}Zdn޼p]noۣFd&++kꔘLOOE 3aC#C/SNf5kV 1GOz*Gņ6率ywv֭[32v>h F/={bqWо]7㊕drzDTԬ3۵m3f3h4O1]RmӺMVV]ƨQ͚=nj  о]NNERݗ.?kӺU.[n-vWP͵m֭Z9aD>|DNnNmڴn5n똎ed\?nIF,[>l11c_sGwHB5a~;9h+ٶu۵k_/Y74x߶@Νڷwww'J>wg.--mSN*hvm޽׬Y-v|l޼eٖ-[HuEEEСCk׮[3۴m=zؾW@~~  ]7ot:ݏ?ӧ qcGkk-{AQԝ;w*& ,===:zԩΜ9;{mB5j!!(ϯ;=¦L 4Mh }|uU\\\^^?oL9yܪ Btɱ{˼˲EUP@ݻiiyʼw0r=yR4&ĉ}weKnZOIIIF5gY6;;͛QX@aAAzZ/˅Fmtz`Vo{irϏjxhN]7冩yzj*ʅ//wNNvOsV~&qqqAc^labb✸oq)'SR۵k_/YR_pMxc´iSn2/<|$C'N vܹsǎ;I>| k~r巻v/3O_IO:}O6T𸎝:8pȑtq ~ c_vaC,Tب*&5 B"<<= Z+a3fyH}7]S{|:eqHأG>6ffsI/`ReRiQQQٙrf߭LRݜar\* 77#yD"qqq)..~#C9q]*HB5f}pᣖ>mlL/Vw6X$ۺ[ӧT=YKJL&ufl.Wh9d2=%FrKWj>P^s$ٙa{wf u۹c˭v76sIu0!B B!3B9f$!rl߶fܡcE֨Q#R@0#Aռ˗/sbAQ4 BgRtL&N2!$I$ n릭FD"JdR vo688XRW^iDW^i~~~m۶uss+WުUƍFj4'z(Bϛ`7W7a f$A@S40C x6HPH2i? >bT*! "mժ-JuGϞ+no-lܸɪի̝+iI +ADO^jի&Lp!TS8^*6 hZ0T&wH1D>a(zT*3MU*dLgDF]WuPvv'GG?& j>'5"*y^ d\8| 7"Bff37mذ!TChiaT&ɤ2DB4#CA F(84jcO$ۗ+((H,oӦ;IGp_e/ߠȸj۴m+d]$HWس71<< ~<9F,3w-M6'wg ͛7~c{_BUT1sA9qqÇKLLlӶ  jI <'JIJl#a~aro23vT bA("+=eŋ GM0fk4.3'nrD⠠+VΉx`m[> #N:/)WH$$Eq[>ѽodXV\e붴?i~w̟?isB227vO6ˇ >9&1\ذ!TCHiTzoeHiJh)|Hd>>СCo㢨?gg]FQ SQJ(尼T4L43J#-5TP TRxg>}<;w;|qqqQQæ͛. yza>ܫW/ ">|+|,ʽ{/_lWaa999Mi&&&Ks1Gy v%%%O6CƐYƏKNN6TU9@  jPdD,KeHDf/ pjѢ_,Rm @ќ9&&&+M&]p᭷EEm\L̛\jٿi~u,;s7{G\\.OIMD...*ǩن eYev[7 ĿJx#R5D`H$W<ǩDt6Ny6HHHHHHp/@ hܸqc'@7<oI1  ˲]t޽D"P^\xz+{9)v.8@<#B .rȐ!2 K*Gagpe!XZZ5J"ײ#K3Β-71Dbgߜ!Ǭf#ԡۛ"$e #%%%]9dslӜZ,;[,+;%$J-I.]4kJJJqDW!f2c"r2QX޴mٹ֫hݭE"QV ]  @ ޽;JJSh6^ߩ@g"qqqyﵞ=XV09P?nɓFm2u1o޼iڐH@)ȈWXr ;d*֗Ԗ;vRÖ}>w;@=$֞uHGu9 `BP h[b3?$Mqtj윛yv=33+44~b쏲2 [ C\QB@D[KsKm B8"icmroDDǏD ϽADIJc""3ROݞv1˟,ki"G :&[kj.ִ1 irQQ)':;;:}]6beقkgJzX`DfƜ:>Hf%E__8F_gqQO5#9ѧ;QYYY'ZiZD*glmiAOw+s^jx`e+U9lY? f>mRGy}fgm97Y&4OeM/fDF5Y|juZZڋ@]@"PqtQSjDDDDDεnOT*O8W|nΝ(11q߾5z`dǏ']O{WH$Pz2wedD2`@"ڽk6tyڇLLL4/ H<\C"C"xEo߾G #xEMHccc ]Hk۶˲f^^^͚5{wޣqswDZ2t-DH$P w߿w߿;b (H^p07mڴy'"\?v62R2tذr݌KJJ5,+51)5/MMMKJJjq ÈŒJ$Rq\m@] ֭=󼏏Ϟ=?|hǍݶ}GtΝv)S͛7 UK[j,33şL 3^Ya88t0"J}=z0))js\H۾ Zzk׈…bNhl߶յifDqnninncFPO$%%O6CƐYƏL H: /{y""yxxt!?BtqVZݾuLM*2͆ZlT*"޼P*r3f ))@gL\.OIMD...*ǩن /aMjVuHRbH*6kTPmllgR=2tذ:~qq[XXyE]5lgge300h@~ӷ3 `pYa#y߱cGVV[zzB"D vmz7[sN: Xuiq;w4qiҩS'H#}$WB 4Uel߱kA# P;v `ǝ.*H$ F5X7u䛺/[jY֭Z J24YQuX׾}{XCBu$ GAa5^'Ld*@"m۶m۶mqvvnRߗ{ΛUt033!C{D"yk޼C sswDZ2t-DH$ F"!3CfS͵->>OX!;w.b^ye{[lyAFyyy͝;oɒ/v7|AU0LM6m޼i1Mu$ I=xzH]\{/7*133+,,5Ȉׯ-Q(YU>fسg#??_R(r=V*-((ж0 cjfVTXqEEEEEEbllT*ju666VJF ]`PPn(}||{5Hm#h vvS-b[Lh7jŖ6;95xzשg=3h "84lO؂O"FwQ3+Vl;nDu붳Q/n[kkk"rrr:zX}_ݻw;@`Pn#q}R*+e/Xs#b㼼(0((*:_/&L:m5xzz?N8o|e5^|7qTl\ڵ4<}t``O>aa'Nxˆ s$ ą{ټyZS.Ͽp*dӧOgyQ~^BHOOq~cϝѣ[v$|sǎ?njz&DE>׍#` W\]r^vm萷'M/.\I`ii9z̘=wh}ԩ|͚Rݑ{z#55ld$㎀m[ÇOӣǞIȘ1}}`QZZk+Vi~5&&w]嗚Μ93wb/\м9c+y]~FXUo^OOϯ:8xڵ͞UYyM6l6??e3D۶1Pbl`AeggϘ>=<| q]P!&M #G9;9*ƣu{t)..N?@}g w9=cFEE>,;+x:^=a:O aYZwE,,, EUD,rS,ODzBQZXXfii0Lnnnk{y$/ WUݧ6vvT4vvEEŕ=WqÇNOXxd>LV<Q~~"R(YYYO_y}z/Y,GVM\ܚ7ݼuB7q 6P\"((w^׽xcȐ!?7giӦOݺu[u/DaBkbsrssd9|;bLMM}ͪz? ϻŲ}h1Gu./2ZRY %K233ǎP(I&7m޽{u9;;Y?31EzS~G,}`'/ _zl۱o={ha HJKK>ĤTP(EEEaRnKmA"zH,^reIiɼyU*U}:w֠A8BD߾}{n"\nƍ###Py|}KW/]V>&g'_9!M!"59c¸1~(eFFkGE#!3rrrzxv6JӞX,9Pٲ'<?ba*UYaQqe)ߩSF"J,^Ujueڴnx9sHb"266^nݩӧkMTJfMoݺE_|yQa—hCɭ[]V8HV-ܩ +:}f]Jo7NCDB!;d[LyֲekVL&0ntcgwFrzzz߄Sd99 0M.L2iӦڗboK5-RTr̘1bSN%/Sy!xl'^ha:vԴy&&yyzO osƒi ×~U˿ܻo)Ϸj^P_7—~UmOT2Cf:r쫥wm"`{/,o<C)JAŜڤɺ5R7}Rxn_gQцT*u8rzy;6.&h"7ǵ+Kw5|<0|Ma, jxRX,Ӿ#˲E>Ԥ2=<8yOC s$P^ay>77W_oVcW$jծն<趨jJZu$zr4HH@0+P= z@0ER!$s ݿRH PG"r;[[+Wih᙭P8kצЅIAaѵ7a{ywffn B._| 84OQ#=xUOXGDDDDDDDD RIENDB`RaySession-0.12.2/manual/en/images/example_ardour_track.png000066400000000000000000001273541417052567600237510ustar00rootroot00000000000000PNG  IHDRHV pHYs+ IDATxy\Wouq!aQHp A1M $fL q#<5qIB06fDqtDpEНn}nZDxu9*޺@ @0 $%  )`@I HJ@R0 $%  )`@I HJ@r`0$%L<<<~Ĉ[?,xu=)`@ISIggP(o//)y&qGᄉa3xv|<z '%Ƀ rG!VZh>i.)s玅NNNWp8}s3I1c޽{rS .KuЏp8$I㘘5kX?999&3I]qЗ7sj**%% Zwww;;`Dp6l@dRRR]]X,NMM-++k[`رc P([ntss[vmmmmFFÖZFM:oa;_fffVWW#.\qIM g_ 4(22rڵ{BBB***Zv??p۶m &M"ӳ?߶m'|bcґ#G?\ 8p$gddm! E[[۷Ͽ! Nˤujx2YO/IaÆiZF]]]_B׫jWW~R({?ܹs&};|xx@ ~kkX,f[wwwggI Ñd.\!{]SA*T cȑ#cbb.]ڣ-+MVcƌ9{,adx2Muu[kk[nݺcK/!r? u:^Ɣmk7nܰͩS^ѣG_tɜ^4zJd2YFFe2D"ɹz*J7ߌpqqٳgNҕ+WN͛7qa~~~rrrYYYZZV@@j֝;w˩uv^7D@@@p8bqJJG}dkkhF#3STKBPu_zmVml .A_]}Btx$JCλ Bh4*J%ZM b!CjZXދ&^x25D L6 ?񂂂 (mC>^ʕ'ck̙NNN)))b}?O7oP^<{HcPiӦaq$m=B7ׁn&)1ݻvU=obqЇOH$boB<:Jbbb%/յRytԱZfxrJ`ɶL5М&x*<"Jo_UV!Ν;knۅ R+$xb''BZ'[G7(F:J7o^lH$JLLtvv*((@Ϟ=[PTTTdzm1ypNGΝ;ݻG[@@@DDN_cccoܸ1mڴԒv3{l1톹>X+7:sGG5,xˆclllll,6o%Bh̙*rjoT*e8ưn0q۶mX]\\\zzzSSGG7IIR ~~~x .׺ꊊ 9t>]J=A{"BxYጌ ʥ''5k֨T7|OJ`آBA7T*-[@I<_mooo,ooKߗ>~ĉrʵnױɕV*^lkja-} WZ1jώ.[l cM{TBՙQevڨL5aCwm}+++0 @қ}xt%7oޜ6mZ^^Bhĉr\RxqĦMܹ,sۺ;jԨж6⒔'| G7+:q<,5Yދ| (xBn+횄QzHҭ 4hPll5kL2@.kkkknF$TvQ-S#֨28$ƆYX؂ -Gƣ{h,4ኮuVe=t?x[{1aԵ^5t=z1cF]]N{w2`0XxzsQb;o4t[bn F{GQeq0^79=&[G2+z! O9!((VVV:u.O7O>}t{hV|:~{tgV?Zd{߇_{y}LΐW ]_MvvH$ Bho8<:mi@+xsngsiYdhrFF@0it7Hcl+KBMv6EU'z!~HEu%z`/.SoR~~{+3x>F[{|wKބj*9<ȈHZQrܯA>aZ;x`K ȷsR}pbÙ o7h\QQq`[nfBFAv6yfPo? ䷆*[G/ʪy4+7;p<œgZW>^۵\>oI)l}B9Z#25"F]qmȖ "a#C !d4$`mksinPK<378FUc #yB12^| $htn{`='1:O%R~;yYZBթ{A ng8d4:zvM&@ҫwwVWŵv4#liV4Hݿ&|.Fs;2t|[C{u? 44Dשrpyp_.nߒ$'q׉m5蟞Ń_ =-emlźNAۍFEm%?ZU:2"ի;ѨSi Xp_ɿkA/9͗8t>h:W:#2I g_Шr)>& /Js/~##OCʾ_/p,vueFcz6%g"sN#ݸr#}"8/x#)oޑ!w\Q_}_'[tLِ@қ <W0Ncã zR lMV1Amc+zhcFNc@F^f=`#;MH`ސqUΘ&8\k.Apye#p& )Skg+%$% s$%{}8IJ.~`ر HJ@R<5xx\@RL;qD|lggm6Dҿ.YGFFZ)XHJirrr"## @?!zʄi<},8þDX [ ϟ3gΡCۑ'GMMMKKK@@@EEūf͚ɓ't:$wy=ggXH$ڼye( "(11.33388X"p8 6ttt,X`رA([&&&fffVWW#.\qQaժUADs̝;WժTKj: ""B;w]6???%%eҥr xh-)9~xMM˩uֽ曯ڜ9s-[Ro޼yq8~?j2X?lccpZ-B%@bŊg*)A|xΜ9{Ayyy* yyyGфݎ;yoɓ+W| d+Vg^lV}㊃ ڵkז-[RRRH$999}Gee%3 \.F7 >ϮNOz=uLȑ#cbb.]Rե1cΞ=K#'N]PP e2م NJ0.yzz$~r92g|:o޼#G0f8h4/VJePPɓ'B{|wB  5{>!d4b;v]ZZp7o^zz#4頺[,#ƎҢV;::͸qJr? O:믏=ҥKtaGdqqw}7a„j77[nݺuާ¾T[[uSB!>=ztMSSSkkJRYAֿ`H0o񆫫+RZZǏl$SRRΝ;wЅ -Z^YYЍ|hoo?x  H$ڵkBԩS[limmmhh0ʕ+Ç'Ihs玃Cyy9!4a„0L윝-222֯_/pOիW$҅ rrr6n7'''%%%}' <뛜yuvvJRkmmmGsN+wvvt:|CFT=%ϟ7 wCCCL[UUUUUx:.//)ez̙3۷o`|2Bݻ{9tPKKKWWק~%lj'.^eɒ%MMMCݱcG߷c̙!Ƣ#"Ep $y^^[# ?=<-<[]AAAGV|>?&&ѣ1c;޹/?L-:lrIfGC^}=衏OZZcrxLL̚5k,hcBU^pۤ JF p8 & . )y)..[d ߵk^q$I.^);;0w\VRRRRj5D555YYYαX`˖-Òvvvlذh4Ə?xذavvv3{ƍiӦwWfeea ]V*2  ֭[ C@@@DDN۶mJӛVZEH$:w\nn.JFF7zFgΜRjjj(1OJUUU嚴b7 OU*oeمO#<\zZ!؈%Icc*=X IDAT6lc=94Muu5B Y:ζk4o߾T*B8豱 mAAANNNbǧ aMFիKKK\vZHHHttt^^^]]I=0:bĈj˗CCCB& F )y֡&UX.{`#.\O̰|>uLfz=uw&jz] e̴0#GĤ]t\boo_YY)'N]PP@ X(AQ7O# HTWW޺u֭[;::͸q㬴}||BC ŭۭƳtǎBzaB!rw)J${!JO>x$Iw&L0iŲol>>>ѣGc1O#S<2,##c2L"P&>uԖ-[Z[[])&5kVdd޽{u:.ʦ6lP("oh䲲_~^~ʕÇ$yMPsssNNƍںoߎ%sssG&ɜMZIKKI'NشiS[[۝;wpBiC>[[ېprr-iΆ|G"tvvZ92"HIlmm5 }z\.֖1dPپaggR؈D"F! &ҭX͜Q1Y×N߸^rw[D"BbYs?~ǎ;| X$IRieFh4 ow k2Z6hT* z=BәJb7sFɇBLJ͛w% 4wvv2O#H,X0k֬%KDFF2|<9) [^oI Asꫯ~СR_|222>#[ouȑ, wdg~A*.^q={ѣGӿ{X鷉'Nlll/)) :vá BÆ 3g\.b\uuu ooo ܴi{+VtÇ_xqذal+o^nB&44~bŊwyGR-Zt%xv跞Yf) #8cƌ)--ӧO37ڵkxs+tx{{r??QFzI\ti||<޻!H!_=%vvvZnn1cH|KQQy<cY-b8;;ϛ7/==m 믏=?O[ZZ;J%[c8Sz-#J N&O% ˤIzJKKJ'Onll4|87n܃LZĉӧOg1W^z{'HO#GL\n``ٳ</88o`1xX$<o߾;vdggܿ ~Аy7n0:KZZZ׿8p石m8p$I/fddt:ӧ/YiС;v`޿֭xWݻw#7X///Xb蘒t'Ղ a//;w |~ddɓ'{QaS/[o^8uf-fkkk4 }x<@` ϗH$ 1NR'zjVVɓu:I;wwH$qƴiRSSKJJpŅ ]6''$ŋ{xx899egg"וJ  N'˷mۆť㔷aժUADsϏ ;;;JeÑH$xp\[[[ -tB^Ŗl d{>\QQB!x[n]v-c )_:0|%FQT>Ԅ $J!d0HBjkkizB{3~xNR)d$l`iiiBjI0 $%  )`@oIK֭[wEМ9sN8/bǏKO>ej?~رÇ~ z9r$#@񂃃؇<1rg'vdl~KJn=>H$ ^ѣ/_駟*Ud3f̈IIIaP`Yf-Y$22/i>-<%0xyyK۷Y^dɒ~yd =>|~dd$># 7md}'ۓ"`]\.շz^?|>/rJFԩS{Y? _uΜ9˳P9!!w=d---<oСR-O?RtŌSٳ=ߋb+V6,&& Nm' }||icrͤ$[ӣp, hԜC9}l9j4st]h2rz]BB>>>ǎ+**vn2&|͵Ԃ￟Cf?~„ 4x6uJ\#Gv޽gмy>O>r-FSYYK/YX{Ŋ:n/^6l}7H }uB666S+V;**..nѢEߧ EuuuK,vjii_xgΜӟN2ŋaaaɓu:I;wwH$JLLtvv*((0)aժUADsۻ]6### `ܹZVR{ƍiӦ0j5F͵KֺeffK$a[[X,ye˖QV.\H5G*2b"""t:\.߶mI/prr.,,DwP(n*7w!>IIIuuub855}GFFFO&,,^^e߂e?E&o ƭJ& g>77(006ywYޯA455T*Zmhy knnne@/\hѢJI\t)BS:t.л&@:::޽RW\nAAABBNJo; Je\FFFjj[|||AAII'~~~{v ChhB ꊊ 9v옷wqq1GlSNYc\+)p߿o߾3f|+Wꊉ4iҵk%Ic8@5G,3"=iooo)*yȑLPRRo]];&Z OO޽#!!aҥaj2?ERtĉwﮯp^v:d6551nh }T*z뭷z?H?miiijjj+J|/<𨩩zjWW}}e2Bh4Ԟ޷oV*˗K$Ѩjq'Vcc9Ɏk׮DGG/$6lVEF<gRJZAWNGIsss}}}WW>݌KwwwPQQOUUU{{;nBIcPP#6٤d FB׫jWWWwwwwĤ[4(뫛}tz"喲oh\zuii+W<~ڨRx6ĉ+Wh4/qL2x/ƍ= qƝ?^P899 Bܥ Fsĉ{8p~p} ?RRBmdn7ggR\.`p8kII\?q肂\Ñd^KVzs5 r:] hsx<綾^rwwZֲ6#l,Ț얲oeGGT*~m[[2̻d2+H-)2e >Xv-U(St2lwDo;v)DP(iNNίT*"Fv`!' U*Ճ- z=p8@Ik>T+zD $in zsLbcc#`@CĊX,NII裏lmm5 ݮem&]5GCUXh&[jV&%%>|x[]@* Xx +_ ֚Ncŧ$4-`Qأ`y2 ^oFѲez!2 5Lj2-(suMܳg̙3+**ϼT*xƁn߾}innNKKcRK lY4w}^I HJ@R9׷ </88]nrws"xǡj QO[`ڴi}$%z饗L^rttܿ /]>( x{Z\.u c2<`<-Yڵ~ ͛7`l<{lBQQQ/bccoܸ1mڴԒɓ't:$wy=ggXH$ڼyeD"QRRR]]X,NMM-++ %$$=zb+V?F9}4I/prr.,,""""t:\.߶mB77k䘔 ;wVUT)))jZR ; BuV +KOO+544888Z Htܹܢ@j" 9u Ə?xذavvvǫśk&BDB~ziOKbbbMMsVVVAAI3g UT`?o@gwT*,QF=x𠩩͛'NofJoAx{{/]!T*-[@c <==߿{nKR޼ysj]]+RTT4nܸTCIIIjj[|||aa!v؁vd S-:p@hhBb-9hРخCKBȑ#$__ߦ&WFQ(~gRꭷުF566ݻ=͛7c="Cϝ;WUU_,_\"k&-{8uT-啑AgΟ?O?UTo6zM>o=Fl QSSwd\6mZ[[믿R#8555* !D_h4S2oƋm2D"sCݞj5}k׮=5J*?^(!Z-ì$* IDATǧ;fY[ח$ɈE >\]zBQQQbh\zuii)#z5hOOOK[[Nj0s?gφcWW+WU?~;dݺu/^ғѣG jkk߿P(,1ctuuyyy$NOvK4Bj:eO0 ~Wuܸqo߾qㆷ7L allyo˒G&]p… :x𠹺 9r͚5yyy7镽}eee``X,FFqĦMܹ,"~x w8p`۶m%%%_}՝;wҦLjժ3$_}>?o ;FZTT{ٳgc}ٱcpX5!C֭Ck׮aI;**..NROϟ߲eO?7o;vr.Q[[kOp8 ]f9glmm $C,|G+D*BP3R":G"tvv%Ύe>\QQB!x[n]vmnfB}JǚŜugy>|D_5$$&(('25֎ onn5kB`7bZMߏsqqp႟_rrQYI\ti||<I[&3f:tܜ``!4wwwf$!^T*TV-d$!$J FڳgB:J} Sa7Lv[O)|ZYb7o}'gϞy&&s率H$^{1cƐ$/5662̛7S*RƍKNN޴iS~~B 믏=?Rs;;;?v> .[YYIzQܜ(,))g>|ZoI\.\t)Aݻw<..nÆ +円`sc1gΜٷo߾} ^`K,ijj:t;BYYY?sAAMnݚ{" v]~j'Yݷ_"( *H$ZrJY#KOt>| ąSu:^!IJ2J:::c`4.}]fx9V'@ 0?@`e\n``ٳ{G6W4}$%>s~Ϟ=;wܹs'ުm M6=ǁ>8 ˆ^|ŕ+W>-^ZQNқ@gԩ^Q&((hŊÆ 3gu?9tPqqqLLLLL .} g Z_rրg5iŤT C+xk׮$I.^);;!0w\VRRRRwH$JJJũeee"h˖-D555YYYt[:N./?J'g|L͙33Kv0Ǐ;q\RR !FBJJJoNoG-s;v3fƌ ,0ɿokI&[aܸqܷo߼̓ڵkꫯ\r>$88p8&OK/u-**ʹl%LϵbbbrssNtzΝ;ӧ캭 ]w/ŋ111sٳ˭f3Mˋ݊˃߻w\ɓ÷mfZr7Ֆ8p`UUU={VXQ[[V7o|Aԟjժ۷U]]B zVgy>f͚ׯ|ʕ cp;-ů]Qݳ)Gm}ۡ)޷e˖up\zm-8p@z|I/6$ yDFIKK9sR4- Jj`0yYU*-~00HU*fsr2LRUymRT&tmdBHjj_|#A8KSn.ܭ߬e!1 C\! ֓d֭{9 68:P-$6fsn8#!tY/jZ[v0l6py۶mcǎ Ör^}Qynιxql>$<쟔s߿ zL\.^T*'NԻ9iҤ։N$%%ԸLWQ:^EI_\>J,r\Px%*VqE^Brj+\ahLSO=5gp8,YruwM/:߬˗+$$d'O$,X`ذa l &̛7bܹs7ޠ󆄄l޼+**d2Y.]6mB1ct)--a:r7==}„ 3gllly7JKkFvʟI?L̘/-Z4q#FYjjjOO ;xs}1cX۷oذG 2\QQ!H4 q>غu0#?j֭ۅ ~Ǯ]:߀AVB yBT*MJJr7<<|=`XhK/TZZ\@ &L4iҤI;wcܹ/իW~\ btվ|r~LIϞ=][n-|ѣp|WZf͚LGO<̞={hW3gШZ~O>2sΤIF׿/裏(++;t-\WW',6rIpvvv\\\PP!$>>7777..:o~OW*qqq=zݾ}WՏ?WVV~K.=裴߅>ݻ~}VZT)++ ޺u+!Ĺ@7'@#̳,Ko]LP({P(ZȟH$!!!555'wd2Y```mm= R8b\W/]຺::DX6갷Me$;y f]NVŹB !vsp&1%CRDI $% HJ@( )Q@RL6zh-kԨQmQ3}4.•jT(Lrj#>eG1a„{(l|_.6ǐ|ڴi^VR֬YC¿p^tsW'OD/r>h9S4{½.ܖ۷^z-]Nٸqƍ7lذl2Nׂо )yOJNNϜ9lX[}C& '&'' 9.m=+r0~aȐ!=нW$ )~sYaXu~uS6Uܮp[͛2.#lmU,붩VnV0bbb:tK.0=h]FV__?+TR-]tSRRX tAkq?m+}SA /g}gyb 4D ovaaSRR._E2 S[[n:ݞ0ydZSS~zZI``E>LqFppaZw}'O1b?O:˒%K˜G}t &M2G]vy<&qZ׮]w?{XM˯pu;vlRR`v_Dan5)S!l4k98qju86m}6L+WVV-[vڵ={jO?ĉ]cRSS5Mzzݮsxi>l=^}՟'N|w[޽{h嗴p]]]UU`r';;-#\w.TsC<px>$$dʔ))))FqǏiݻw'%%-_ht:ݙ3gΝK=x޽{ !eeeӧO_hQuu588NRܿnnSO=E?JJJoN5^|ի ]TTqcL_oT+"lzuPa @W|_VUR t.]pRXXi IDAT@~HX__cǎ͙3RUUNd̙3[l2d!$<<\s;a„g~ \.!tYTVVzXM(JBȀh1պ-aYM5rS-rݖtcРA&e3y۪l}B,GR(n7p/򠹍OG6lgϞD1[FVi[v =%poz>##cz> OOBHffUΟ?o>Ν;lٲnݺ9WB8zꪪƍ7Ғ_uΟ??~xBȐ!C}Y^j?3Bq… {=BHVV믿aW駟2eJxxۭVt.^fMUUonV+,ݜl5zϞ=+VU՛7on;vx_۪<n庺'|r۶mkj݋jnw;!.\p)n[FVi[vIHHh<.]jP v:˲хD" hhh.oT*& a@,JjD^jj_|#T*-&֭[o*)JISԺd2n' u[ò6rS-qFZqL*FIKK9s7^tF0+Wxj.-.[m|tSr8tPS glMCٶmرcsrrV+VH!.SZͦESDanyXFg7Ƴ¯:}cǎ566gg-")^TTTYY@ӧ/ZG7oޒ%KիWFFFzzzddŋO8Cnݺ_~26y  '|2((0 ÿfFӝ9sfܹݻ{˗B4 *++ׯ_ihhh64o3,:f*ٯz@@q%''RRRT:ڵktsypGOQF6uɻv:{lDDDSgxr/ mWϟ>}:˲tD"tbРA ~zLLR$҉AAAΨ.]tz-hZU*s1cf x<zJ3flٲRR}{YbEmmZ޼ys*sΡCV^}ΝJ:ѣ^ee7j;wnٲeݺus8W^333WZu})^:{f y.]@s 4te饹- JjhO,T*[< T*ґ)))^BBp8e&00`08QT6e./h4 -BO l.3j>s.\sq{=;exHDI ->j(e\rQⅤֱcǎ;(7 HJ@( )Q@RDI < :<)00_\ch.$%0L>}ka4ܹjh  h4Zо!)h6aKVl6о!)h4Mw/BD)V]tV7*I YhhΝ;{!|KRM<ٛnM>í;M8ŋ'NII-oFQXXsN~"0^8Q&YVծY& 8nӦMmT9 I 0#FXvҥKwM3c&%% k׮%#""Ν[SS#y˖-7o~Fa{9w)++zСCO:j'M[o qbn'VVV_mFB)**bYGcJ f0޽{ BO?Dq\VV_V( /t)h4^KMMu\?]nBXlYaaaTTT``޽{G HVXQ__3X,6wܚ%>C'Np̙3O-[{5k|_~RƌC/_駟~O<!aɒ%G-aÆ BoJ?qDzM6ݾ}[V/[ڵk={j~'}=z?'NBF=a„ڜGydZ6%%Vk׮7oZNII|rbbbzzzVV>eʔȷ~pt.ËhxOIIq>@?d !^0K.L&0<mNݻwnnnII !d2ڵk\@JNzǞ~_ݻTԫW;wرc̘13fX`hLNNo~sܹ)Sӧ?~߾}ׯ~BB/H^z%z/s?˗W\I;Nm۶aÆO?^;z(-odddD/**曡ӧO_hQ]]#<2o޼%K0 ӫWŋ8qbCݺukqqq~d2!$,,l .4 O>$0 ÿfFӝ9sfܹ-|III˗/'h4:UVV=9޼ysժU_~ӧv{FFFRR;Cϐ^ziܸq1naG޽K[xql<_qǿu떰|+ehsoǎV⏊QFj4BlIyyyqqhbccѵkWq\VV%:̚5KR)os%%%544)={>|V'k_}x N+((Jvv믿qb!7UNvu8w3ã\~!꫉39fa:T%<}6447ƹ؎9"Ɇ Bt.]py"##++++++0`ƍ?Ø1c|'x"&&N"1bС/pFԫWCի[n+W,MEӧQH$.._h47n8r]ロk׮ݻw!矝멬t)pԩݻw\iӦfcǎ~ _}c)  (HCu.s*JZ}]MT:T*R)=m,HBBBjjj||OCxSRZ6 eJ瓞+BJJ yBp8.u{T*2 wƲ",j4uwYD" oD}HFVK깠]knmii)9^S~q˕p8gDccu~YW]]ݬfYvߩcƌ)**Z=܅ w{e/xqvBaiv@`L 4n5jW\ q)))-} ofm hұcǎ;(<4o[@{qܢEZc᛫Yh =0 qիHzjoZ/dѢYKMM]zŋ?-wʕΏPmk$k\WWof3 FV7kF\ BT__|Wh- HR+B˯Lhk DI $% HJ@(>%8BDD"]",X1j}ĸ ˲VU.l/ER`aeh9R__Rju82L.xouh4Ѐ,I t(}n =a E```P*r8,;xou h4j$%-0D"R]]VX,͝Q.0\.jΝ;m[gzІm-h ;_ٛEͅ:u!a 4{@G#:$x0 Y\S \1Ȳl\\Ļ}5Њ=aYV<+_fh4J$FC/'eVԂ:4..ޥݻ~fkRiBBBNNj'Κ5rzo߾6l0`fC***f͚E~V^^ޙ3gvKaÆߟ^mtAGwܹhpq\Ǿʆaqƍ3eYTZYYb T7nȋ/ҹsg_&v~d^~߻fFD2rȳg޼y"˝4Uo!e_NILL<~۽ԗ )r8޶N*l6áV 0  WWW'HT*`JfvՅµurGSڹ0l6L~a F_R pBV}HHH ^KMMu>Xq譤w޹%%%Իwk׮7$)l6[```DDDxxxccT*ZRs]t &tܹSNc@P}O? E޽0$I^^^߾}R)qz*H\;X,eee|\[*++XaǕ+W~aZ2LR~-=s\h_4pp'J 8,++y۵貲2T*t s >}˗,Yo߾y_lK_3 ӳg'NOZ~ٳ) 3aO?4?1$$.zşyg*++8.(((*****FBONN>{J!kBHϞ=%K={6˲?͕w-֭[yyy $%0jfl6ݮP(Yj`2nIDqM-cFRўTT*ied2F"J1UL&,=MУG|ԩݺu޽;qÇ jFiij-))QT "22RX+WpW__OӦxZT*/f0wji[㸦M%7|$N߀XLWWW']AOO lN~L˲ZҌD0BCVz}xx8RzjAAɓiP__O+2h|Fşq)fX!]v7nǯ_Jj*/ׯb~~Cׯ߸q'|GO8QXXطoΝ;g|\Vʥ{1͡FbZ5M .tޝ8}ӧ-[Fߢ1}M{ gſvN[paHUUվ}fΜY\\L~yˢ׷o?uԩSRSS{C{}mhho"##5M^^CBO 4 lr5.iJS=B Ngw^=ݺu'kd(-- ޺uKכfJJJ<ڵ͛7 CNgJ]v-**O>EEE\ь?B׻VPOd2م ӣGEfd2_w> T*L& ~IIIuW;P^^Ngr TQQa2냂h2_~z&ax4gffCBrssKVVV^zW^J ='+((t:.66~a6Vk}}}S' Vhסh4eJeyyT*UT%Q*eee ð,͍4h7 q8*g3~J>bw_O&''666}w&M{R<}4 Njm6ۭ[ɓ÷mfZ#""RSSgϞM/'>õkE޽{ʕtћ6mr)W^?AWnVǯoܸM㏈ؾ}hǎ3f !$33]ԗLBBBsw r;eV(J@-:CV744зYdbzqbq.O~8:eX ?o}MϒK]b ?vT*N;cv\. +Kr>V.C1e^zA⃧]L&n2G@@qt4f.eh FhcN>ɓtcJ+\ڐ/3Z.X:XUUj8@Cf3[-T*?(!>[Ѥ͜9STfh4.3l6.ڥ@@@@ccǿaÆ3f_R"8嬴[nZ\˿;t`t\$Gvnw'@X,It_n=|1jZynqg4u)kX,zyqΙ치nwyץ瑹tt=+,CfڷDVkyy+e0Va(z=٦a ] W7/{a+pI﹌ݾe~a_^]fVl-6ܹs^a[֟~IQ6 $%ѣG!g6l(Zl63HJOO-<;ٛe7$%\|)>_IPlnǾz?"@x/Slw `ۍF=~Yf3}ڃl6` @"ѻbWA^FJ-k}I t42>:%XV'H˲VU.N{^:p8d2\.H"p8F^ w86嗽I t(eYzG<>DaF^]]p)HJCaF. |NZ,ΨVܹ!= p{gzІm-h ;_ٛEͅ:u!a 4{@0:萰saL \PPP[/BP$&&=^^dk[Pw LB~< !UUU9s&<"8߂e铜k׮gFDD4+1^W߀={6..nȐ!BH^^Nh4AUTTL☘?`ddddeee~~~~~~ee%0 k4\.]VJ0WAAA~!:;?KNNW_}W_|J>裗/_YeekצLB 4i7| 66Vt؂aZ?W_}U"X~Ww{b6/^h۝TWWٳgŊjz̈́ÇY'^X|^8p@AAAjjٳkkkZh\\܋/X]]hnܸqBHffロo>s8p`ՍVgٵk_lկzY\\444 KOޝDqqfe]@!5@c&4IA[6H>O>y;N&%J2''g˖-/_ޱcwrw`` ++)dp @i{5han:ĆǍ 餤椤${y ;BMMME4;#Zlʫl/ A7 !>x"s)F"T!ax^+"%IQt0a8X;wƾCKמ^S#BFt/^jscǎxbҤI[n(JR_~`ׯ6mZ~~~SSSYYSHRrssCCCϟ?_QQxM6zjXѮ[.&&z{{se*..aL4ᵵ `<(*11 ''d2B-[f0o@BotRBBŠ+F`8|02o@BBBzzdzUss3wVCR ga#E655͘1NIId{i\CCC !ϟ?'Y@P^w駟 !~Nrp/WaH'!$%%e]]]ΖER嵴g>~X4Wi6ۉD iDI EQqqq_fÆ ;w?͛w5o޼ӧOB* BHIIIZZڞ={!j)mgN6-;;B:tHSZ-xs!Nb³X,iiiwILޮc?}͞=&662 `۶m3 L}BffA??5kر?###55ʕ+.ƍ̠\aB f+..hʕ+aaagϞ=}e6n_oڴiѢEf\###kkk?y@KK 3Ŝ9sb˥{y,!޽Dt\\ܮ]=\ZZʴlLψF¼왝=ytDbIDAT۷ >ח,Dw!={ɓ!!!~mVV4BHMMڵkGx-ݻ\pVkDDDcccOO!ѣGSL믿"##333CCC-t-BFcuu5!uҤIvwdH,_<##'ӧO### \o{$''8L[4 0D Ya0::jgddL:5$$)U[[ItDd>3}}} F׳!h4VUUBZ[[1xWTT,ZիW=„w]6((H544444hZpSccctt4 !TXY: .FD83t:]@@D90y$.\pՂΦ&va!7 jڒ={t:ooﲲO25*++/^x^sPae0$a%5551!ÇY@t"Ç?JfB9Dzd߾}y1BHGG˗8j.?0===00&I_g̵ܹ F{*!!afGrRi0(Jwa j5{Q FhTϜa^϶7(G引fBpd>>>pJbw%݈{3N^^oV]]-q0T^x/$+ݸ!4͎;o.Z>rƍGUg ]|ydota uIl6s!DxC !G 8l^C ZVRHl6sU*Z^\ҍH7>}zҥYC`OJҍ ge˖577LUV1_rׯqO_}J ~b4Fwikk+,,(FlNIIdǐ<&ݻwϩ\|f 1u# ZBԩS]DQ"΍X)'9RF-GW 0m?Y)an) }g6waӣY)ubif`00'`HFUP(e~|QGB <06~N[ I $%[@RnI $%[@RnI $%[W?0L&b(jK4ML&OOO#06M.{zzd\jj󎷷ER6iB<pEQj:00P#)EyzzNtKR|r{M%7a_MrR2X& $%.d$EQHJFה1BHKZf)))#OOO*|x``%e-o̞=&662 `۶m3 ̾v.^x9BH~~~tttKKKXXXqq3gM]^^.Hppp{{{ww0lͦh6lذso޼9;;{޼yN"4f͚;vgddpM kHHNNqqq!99^[[k0!<`ri4˗gddh4&F7d#ENpEDD4440)ˣGLȬPmZ322N2ް+%oZ;w۷m6[ppp`` !M, [Y1s̬3-BGhŋׯ;zxۻs΅ fff޺uKwvvVVV2@.7+>>Oyy%K?E3gSSYUU^?}t{nD644dddqmmmDDsILLLGG\.Zw=qDlll}}}PPNkhhhhhj#VJެ'O^~=//… W^-((ljjb.}moo>|gZ={fpҍB=_ց=,9쐰R_ĝf`򰃰R w%Eyxx*e 10pp HJ- )p HJ- )p HJ- )p HJ-L|j~IENDB`RaySession-0.12.2/manual/en/images/example_new_session.png000066400000000000000000000415011417052567600236120ustar00rootroot00000000000000PNG  IHDR4.!sBIT|d IDATxutTG$wCZ@{).݊kq š$ƈ%479;wݙw#@ yzW@ |;AfC@ 0BP"̆@`6!E  !(lAfC@ 0@ HJJ`kgՆqidoL(H g5 *YƊG5ߤh4(ƝhbbcMSTXgnt.;;c]\z9!J? ן,77W\]]8} "MiDE,N3B رs&M1[%W\ԩly&E ș3QyYruiryVs vvvԪYKAw3HisA$K(P ?N?ܹsdGPdd2z},[]rx9V4߹s7~/9RB@DeT*bS)c ɴbՕPlݎ^s 6… UYj }(%JGPσ=RŐI\\/_!nՒ 9},5m6͘sY3سwkBRq%>ztJ:h43oB?蚂k0KKKwB2&LFr9FF h4ܹk,F>%ӯooe/2u:ϜEԪU+WҨa\F *Y3p1VIH'=1 !(d9},J0w ._”㱵e̸ |WݺtG.XL<IXx9gbeeprr$C y kkkX!.^D52y-ZAP`ccC*U7!vo+Z4klތUkr}@"1xBpNNhؠ+Wu` ?ӦЬekիUᗟ۲g>|/_usnnnL0[ndr׫cߨ j 5<=quqaђ{0h@?Ν?o.(8y ݑF"n޽իѿooüQc  acLFT<2d0yxx珇`r4':иiDí?Rޔ(BP2yxnݾË/p|y7nt\V%o\qϜ9_<&&aCsu}WoÍg58JүOoN9C&ѣIt(Z0/JLL 111iFI8x5Wy&zʳgϹ} 4=} (En]rA(=Fv1j]RIBYlEuȓ;7Ǎf Ʀr@׬giωAѱor$IK?^O! 4 .^EѹSG*z={qQ*V(ϰ!dټzʨ9S&ZjIF x:aG3 ȟl="#S&[,^<9m,4 ztG.s=Fhw]͛͛ѦUKN:MDD?=dp͸1xqSY2g&cF#~duxGeQTۡՆ%ԷEPj(JцjVZYYhIqJښ4S.cooOLLGn*++dryj5VVV&:'ptt$&&&Isrۥrʜ=w>t%%*V>%طJE"H$ Kd7iZk@cJST$%ZLN%"E Yj +V%XLZ"|UB/&ɿdj~iA @.Ckx\d  NdHRK:>~H{'Zd2JBL65JU-K\l\zWG! ARVz_*2@VT(~?_&\@~ *jW!& )XXZ|mj LO **V`]D(2Tjup;;;cYPJPh\?xG\QByjլAbEQTϜ9Vgk뽓SNTZsSp!^o楕lY2t@uUdJ89>z\Jȕ˓ə3,bUfCҿoonݾ$Ix{yq|,ŊEcee|у{ӭoRP7@~o/6l܌L&"Ul-ZRT(J(Lu+"5 111%6^ݓ&K7sR(ŷ[?8i NEn"XYY~Z[[[ƌAn=~ޫ[B*r7I&:::wVQ(Fz>!!rKKK"## Vd2lH✩29&}_9|=FR;wnd̖M뱳%""#ۧ'=2bkgG=vȑ#;Ǐe)ԪۀЭkg,dݘ>% R|[RDz۳.9~Z|yp]T*eJѿ6 ?x>{9gΗ/.^2Y,,,Ȟ-wW9;ӻҖN+͚6fyHҷ;yG~#<~<}ׁ\.slXCӺe J/fݻoCv?xyd_#hڢ9g痶?PlYJӻ_x  Vغ\=c>77n? *+DZ͵7^̗7w`],_!fr}TI|36wC# ÆcWWW}NNXXX@kyx899^F |y 奟2VPݻ~æ~@$[{*ʕ+Ҭ{C2 oo//Yʃٰq7#{l<~mZwѺ/ƒ%sfj֨;w{Y2g&{lT(_[ZgϞsmw=6ca!gΞsԯW?~ɓ ӧ?/|̛3+WrI#@흭\s>0>:{l+W&8$y䩑@~oc̛7oT;)T{vz97´R,\HHfɂʊ;oϞ=ԯ_\tXlml׷xѷO//\d&$_<899}|JPhvK*/gaJ"ۡ Ļ{'"29_zEll,>ƆY/^Ph#ڹ# F>vvvdΔn⌭m1%41oF&i/F^Ɉ/9&62d@uZbæaq!~'=n߾c^`0i }cv2hױ3}2|蛀B.rt(<xUtt!l_{֥9{.TT mX/]2Z&I06!j֠IFDEE!I?f<~0aCTd$q4KKK/[LDDo޼M ^g葸8Zf<ō0eʗ2gΞc<,,,i4U 7_@Rr%~:WTJcǧaa&tpuu%L5>ۈ1٩Or( Hr;d2◮ @ltlkm҂ $ښ kW1h Q&X#Pr޼yh=2c{rd2 5y CBDfZ_$IiXJ:#˰kbuivm g4kG+n0|Q1XX~]/J∍Ij* ![֬8y=Y{ |!d2Kÿd$@Cēё7o>j }=/mc/dI;YJ$It#&ЏIRqd{/aGϟOu6-H?|az1/|n@E!E  !(lAfC@ 0BP"̆@`6!E  !(lAfC@ 0BP0}]ܹkၵ&=Ś ŋE+^n\.aa\v=&'Cҩ'{lF*֭Y/#rd 4m܈R%}ٽÇ ,eyg9I+LvS H]y"""RZ4ӌ=TW].h`KVPL*͢%K%1ɺ=DK{)geeD\FcW5QQQIQw/~s}__LZ i԰~qJaMlX=vPZU @~oC[71fq͙2iBzaw$ܶOٷ{֭fɝg̛- ''' Cd][vSCowo+Z6eM9^=RF5F ưmFˤ P6-ץsGņukؿg+7ۼa͚6al۲P,^8q5l`oiiɨٻ{'o17!r=Om@& NcItwwD睝;z$#FV?aCƕ ;yy#2*R%} ŋsDynٺ1lDÅ2Qlg]3 F uQfIPP xbԮ[:Ҵy+ ]TT #'cƬ9TYPDq7kxrժVCTU/΁Su7bpNVQ܏4jڜ5j36}5jeݳA:o 5jեZ:ҭKDez,[ΉS@& Bs}KtLj̙(VΟh",'Og)\RI9{\KgϞ3zxf!2eڴW\\]`{E29 **۶gn,Ztܕvٱc_h;77Wpvr4|mt>...!OjgmmͰ!ȓ;7>$..t:8;;SVM*Uzkva|2m M A%]J2]PP0+Uގk׮ńqc rT e\\NPp0nfyI >~E 3ix>{ƕ׸&姈V,](mpp0.Fann?~\i{;;7k$IrFiM1x2N9qL?x[7oMSxi#gϟ6Iz=wCTRREΞM<(\VV@rܹs^ρS6ٳg7ggɒ93* ׮=NNN˗/y6=~$9gxx M7dF$~37$!iܨA 9΁T*ɜ)!Yȕ4V_zŠ!8R޼vsԯ[h'NRnm.\dM4Braii[ #{v,ODD\~^}QLiڷ9wN!S'O$TEP̠!!6t0^ZÞ}ٸy˧6[e6f͘P^hjT-Xk6BBCa՚u,[nthJRQgۊݮqqqF;,j;;[ڰ$7V(8::avCRaooOVkN.@tt4i϶999 Ku]KZֆP-@ IDATV\Dm,̆x9P  !(lAfC@ 0BP"̆@`6!E  Q[n*Ly?SuB-qiwo8JUerׅ]ɺ8JniNcҐG)ٝ3)!E  !(lA \|9  BP"̆@`6$Uָ%=@ H!( (S ] BFZﰱI)vQXZZ%yڰWB,,,2NӹS'_n&˱NnB O6?qa<={)Z(k׭g\x-Zr*Zje~g0Bc8q;ws-[KK+&M‰8z ,bŋvSϰpb\]]Yj56|] 1=r(Μ=ǡGع/ (`cѣ'[ne\KٜW'ZM*U^qqq_eWЪe _N1s&7ndiӆk1cF-J~},^8%K|ɉ7o7ѳv-SNnj3۷ÇNXx16nD&1cFZhmڴ K,\V#ۋҥ ٳ|if̛*+MJZѬi|HM(T0$ =zHɒQ gϞ%yjfɒDEEq(U!Çx ׯ_'$$,Y) ׁuq:BBB qqq@0͛(vAFS[nMӧOhӺ}G(+WWW4l!C2d(W֭9}{2m46nL…صk#FϿʡC ;~~Fa~88?O _;fH}g ׳|Jlق+GI2ޝ;wѽ;2eb9yğsrDit:˖-e4oނ%KQ>tÇQD ̙Ǐtx ݹ{!/_$vqS' ?ڕ&.C/v޽:cvFIT5kV<==xa9xj ffߐ_BkmZ @+G =Sٰ~'L`IIϖ-+ΛOhh ׯٳ3Oc8ڲtϟG^(Q‡2e2Z ҭ[w^ȩSرDΚ9#Gq)É{n@ H,wig{] jզ}ԯW78 G輥%r4  jBCCN_J06teF UVNstXZZѭ{w/^b1nƤm(-pj?ufӶ'_1n/Ť9i") l(lAfC@ 0BP"̆@`6. Jŋ. 63gO#x7563PT)Hޫ@披 OB!O0blmm~fzWC 0+&l#l(@*i3 Db-E  !(lAfCYVi@`6,(jR%}*c"*U2S YӧP w򲷷% Ϙ#с2Z-RJG Ε+QŊPm6|$&i^fmmM͓۟WϕL+%Mq ~11ܹsŊr]hԠ[0wuq"My͓=ӢF:x"4nޚCL&ןaɞ-gҔ/#f#fڤ ;p /}څ@p?5Mv%8$N]問E "&6$󱵱!"2^$#\11tTheeITM4I HɬdX[[jٟз?VYР^]#AIeç ~+TP]1kX.k֠W߁YL|{T*ƌs.aT*(rnr$ښ$-SƚȨI"{P&h8!* RITTTddwB%I.+u̶>S9 PUܵYs"IC$00˖Jɨ1X<>%J`mc55QT)2Eʊ;v2k\M.;RNmcbP8y*GOTP>%֥f𑣔*àP* fΞþSVW&AGp o ߗ" ѬOHD<8n4b٢L9PƏ ׮"+@ ЧWw,z&N%iKpїcǏӢYSd26iĪ5HÕd ,Zd9nL4]ФQC,,-q'M&44~vLUEV1c\8ELi-B~a}ŋW8::T*:}2MIpp?,*SʳL<ՐE4mԐX#";~"rgg'ƎɈQcU}`ؐAxxx$3,^,b"%\|K(rJ/JDDy$.kPT(r?yYitٛw… Ҿc7om޵S&UիΜ=Gƌ̙pvvŅK}=uޞIS!I$ 88ӨY 4nB!C_ q>Bmi'9.s3wM[qvvb,YZRQSNu@eˊCqߕe뎷ÈXo%K?zN;a&{%}J3^"22 >}WH\l_S2g@Br\t[[;g;wɜ9V^^/cŪ@F3fE Cz:+UD kN>b'{?.s.\… ѹC\KWR.M y\\\t( t:"##5 K8clW)T`6dyrÇ!%gg'a,vǏՆ//eKr=uaŪ5|W ?SLs~0.NիagkhaaNc%j$Gڣ7Çb08YB3G}99:”6 yOt:"#u Agg'\ɐpdr.Cj$ruu!<"`gx LQ}wK6شe+UБFS}+*>ϞMbA F.`"4& _hB2d`IHV-qHD.OO*WlA%]2>)¥]Qҧ g8S܏2Tm3r~,CCxe6yeJ<~q$IL6ҪE3V]l|''GõEѼiclHD)_dj 1MLiP޽ǂKnR!!X[]]]$W_dgҳ[rE2p_@2^aܻ?&rf<~ҥsG,mllpqI~]EjxxxC8::RV (!p$IB.ӸQadJ0:q9sNw$syzҲETR_K 刍'z]HMr ++TNJC]wjVUiؠk@V&NNoHFGɟuj iҨϞ@"$,e-nՂVSFu^zŠ!ޭ vds&Q%KC_?i%dɜO0>}Yp$ܹ{vR=ʕ 5Wc;p… ݝdhڄcvlـOI}}-Ybkc|\\zIbڕlZLEOv;w.֬XʚKyh֤1˗,jJ|ISد[7e׶MIT9y lelX]6ӥSoĨq+Zְe6svvGBDJEhhhSivԭS`ooOTTTJ.prr$LFLcLB_qpp ..$RJ=w>Wvlmm5yI5Q*]>bXgccڂP6ٵD)ݝuSZ-,,,dd2 O&P(p7Ker{| irmmmNvm·zjkw)Q*f1 037BCCS+IqCt:KCz}b9IN蒣l(QʕeUfxx|*LfdL$I%:HLҒsT]>S'N| §Y0k'O>e#ۯ_ڶzʄoti^ce*^ǗDJ9{BzW@P₟zW++t)oc"~$9tBL@tt4]6bDEbEyNBP@xX.z*W+aZmw5狜ڐ(Q,]Mj9$yoc!(fAB׃$A Y\ <lAfC@ 0BP"̆@`6!E  !(lAfC@ 0BP/j+;LC)oz$@%`Jŋn%>63gOmᴽm,].I|XMF)ŷK*@@ WWN>Ő'Pe+^~nkkvxI|>I AIDI3+̟dZ3 A|=tLmC!(lAIL A@`6:tB|FcZJ nO' m,ɨU5U%{<~{~'*%=GJ7W^MSٳ͵{{yj#GlmmvY|6tvrfXZXj:ݻryryFTPq'ݺuJʆc///-]J~,S2CPۋ%˖sy ?۷0dpdmf?5} U*WlPVq( Twچ._EV3}4bbc2dHǏG@@ d͚ŋS6lؐ(ML9c#F䒯ٯ!aհP~ss&![Q6Qc{*')k5 3G%P(8::u`.d._A&!>X7[,W݋W welll(V/^4:WR%|}}0ADDD0`@/[ƅ?Q6 ٳo?͛6 FӪF2vJL nz>#PTԭ[ yI}63gdܸqg޻^⷟&^7N;7޻?żٱs}{phhG$r96NyXXXIDATcǨQٲf1͚%Ky|D%=LZl۶'OrOZ4uTs\T*<|}{)ZvŊc䈑O4XeMmbI;~C` lظA/I˓6ZpmƎis\@dd$#Z&..Icn&ÚK+lظO_Ac#"~MreʜӉ@ ML/|ʦId26$E'x12JEJ*qy~fjogs'ٷd2CO-44Ԑ^&@XX8&@’z) 퉈LqKj)Sl焈 MHDpppzW?A$ڳ/Յkx0<(422ȨD:†"OǴ6.m%"%=O'-m( .GcicAb6_FtD~i@>=t hVOj|XE;w,ڱCav?UE"唐fz`&c}\|v4? FPAb FPAb _^ɯIENDB`RaySession-0.12.2/manual/en/images/example_patchbay.png000066400000000000000000003735031417052567600230630ustar00rootroot00000000000000PNG  IHDR3= pHYs+ IDATxwxTU8sL&3ɤ^nP~W@,"ʪJQcQ $LʤLzaHcd~y|{9Ix瞃; -Y]k.c`JJK=݅#9)],`<70 G`<717qBP(gr`qh0[C:̜1#5%e`l +D"P{{@Ooh4B$Ɏǎٻ1k׬>qʁ65ӧOCyv]]]gk׬.,Z|PZ[A 8eKGEG#jy( IA QT>gXJ%I<O 5iD$1 =k֎1w?p9N\Ii /a0l6[.;17͜lG}_Jn8xPTe+*+}I]]ݚu!Z~7͟7+L&BH}iOZKdn^}BSNǎ9cӾصjD^[h=줉Lfm " KNN'N㏹Ycv}豁^5\bn0D~QѶ!$E"ՓlX'de!ZZ[m;{&/ &9$$xgZZZ7fRBVmw fϚ:q7+{̌Kjeܹ&N?^['&de>r姟z駞jhh,+/UUJ0awz@Sw㶁0Z(}L&Ddfj *NІI;U( jϝ3;#=SΙS__Jᬙ3V\颢"\.a3g@:|l6!bcrys" @ Y,_r^ddZ¶]]SsiB~bʷ؂2 {MJJD;vxe˳g:zX?q2=-=+k_8w|RR/o۾d.\`…z~0 F%KUTzHϙ5SUUU]f„C/YS*6mZmˋ: y8+fs?2 L\c1 >Q ɚ03˙zp0jvCDg\.KPFa8Kޒ$I:.}W y%ijڝSS]=n5k"9_巵;Yɷ_h+|JT">χoXJJ+BAp}{ӟ8>y7m /<Ī+-\`[oRվ317ˤҶ}h "~`(i'Ir\f&GV#bcb^}eO>]ZV. 2 7m ÎRS.Y\[[{aGG) TvY,Ǽ{l6J(]!T^'t{nsQñ|왳BP(L>І00 9}j=vĢ Of )ʑGma+g^f-7>۶c,C5cǎm=#K/RAB(9%Z@cndPpʕ#G.Z`;*2 !t^qLvfFB/uG^cs3^JJJxXXDxH'fdd ^o?n\FF}sFV}VV^zO!ɧ9/Zh2| 9 WY]zL椉Byg5sƮvWf7!+V0{g}̌W6y:αZ*~+PzZ+/#.6{1A![VgC1!Zm{{BhO?L~pʔɓ FMmmq5/[tƴiٳoofF{3r>No֍ܴqk[hZ{ӦN]pa~ԔPKK+BjՉ^żd"իENz{JwQ@PPT\lZΥ˗u:]Td$u[ O4J" ì3B?ٓƸؘ«W7oyc͞9s̙AXl~ݭϯ[5~ܦW6uͰU*Ѩ=mmmݮB?q2 `т6n=C=EGEݿ|yYyy}}CxxX=4uIx-jK>?Vs6VUװs07ddv< 54sQ$ ~ l7p7bA^$ykz#q-}8NP(39u@0sƌA4apfΘ24[FWe'\S塼œJOƠF!H8z؞*v'O^hCϮY3}4Кg9yVXv«׮ u `s|2g(<::-fhb4!{Oޏ=iB oێTϏuk1L=,kҤ?gͲ.Cޖa,)-}?Ǿ` Xt4#?ޢP(<[6T(8|ٲm~RWWfs?Vy|G1a{b [lzMGg'W%I27/Ï>ScO̜1}i_eZE"Qh}v &%''mx'O}\׬1 tv>r>X17鼼\pL&JQ(4*з9 EC#ZfMMu5a~~¤ĤgΘL&'kHIIXB-+ ϿF'&ě搐൫iiiƛI OZ)Wȷm߁=k&BɓެS332 .]꫕ysN8?x}{m'uȑK~ɧzysq@&L0H0$Vb1ȫۭOgcnχ.5k勊jubB‚yN>mK3Ѻ7j?~8aCH*MOO{~ݳuW *l#/׶1.#s;!RiuuoeO:{K.a=jm''%"ӕ+WIzFz:BhW '{r@ FooNTTbPP8S0 L.J%WF~3>7oObhg j{a&VLs%%%|+1ණ͞93;{3X,;7]]* !DB7s8^Oyg9gEGG'%&Θ>㶼VmooGݷϖh%E"ѷ992YdzZaqzh C[A F >/::I$ DuRickkBPB /u?`DDXYY.ްwju bPTkpf̘˅Ӳ#ëXgmmBU(V588x2wΜW g͜_̷Z.eNr1 9cB#f !=SRZZ:e/7[,clբS{K.ϛ;!Tx莗 @ <ˋ4?!R謩)kkkv橝gDZ]r q A~~®.d0uuuij\ɬl5h4Yb ?aض/^ҳ@ 5{vJ}ΎzgRݎ,wC/9vxe22W\aۮ9uBx?j[olA ={&%%D;w gfd3g=zV85~/;w>Zmd2.XhB^mX2npLNq\謨(T(:߿:Ao`cN?W><<*z`V^^^GשTq\Tfp8^A#ɺ{#ps̜ F}E|Wq۶MH \9Tzw*>^Z$B%%}C(nGsr[lkccOmm T*&`2РbnF^kD8LeЭFh4F` 2B66VWT~ͤvI"i^^^AABr&&&Z&|!IRtg t3d_66u"8178ZR0z7CIۋvIcFddTڦjCCC  2  `Xa:1<_PtM4-lx^͝7}'> b]d}-[6Y,7:fܜ CZ.BUvСk^uvΜ>}٠ w+A8 ~y0qʸqxt<ͶII?uꗾN(:L= tEWBW,]V~zey575Ϯm!xӲ3q mT zfC\.KPafV$ɞӕt7軺T 9)U*oQm$F*<_*\vѹl Xl.LJT* qD[~( z\1P$)A0A=Ks1׻i4'R*!BbA[oc/jŊ0A/\x߷Gc'N||M?:6jŊE ֛j}+QQkSgΘd>@cn\bnvLE׮8pX쀀8חaT C;37Gf;VE$)4z__NY/: Q;#--..VT:slRuIM/8~ҲrPxP(ؼiSX}vYbŒŋ~\FF:ͮ{90<6K wHjO*0h FDggkkkTd4:`brr`LIIuS1 kJWIJrP(rʑG-\0s [XpkiHfFB/` ɤ,mlrfVa`O?lhRg2O\N6Hmu! 5kB[Z"#CBC%5c! p2eӧu=jX̟'}ɧ7䘭iЯ&B}~ð^XYUՀswRqRVvYUL,1cqTTѨ/.?u皚R'nkkkͿXPse ]Hd2'MO*$$!4k PuM-BhBVc䗳gƾeխZ*~uϿo"bc{ZBY +9\.q|Y ðL//VCCeggk.P bqI%55oL0|C!^ -,PsƼ)'3k! _tivǧg0|>?=-_h1~w ϭi׶ljokMh))>շ?!+kܹVuێb17p>_&먫}RX.>b)u: Z իyc IDAT_U*UZǣw#1FQT`ܳ'q11iWnƊ=s3 8!ױ[_.kMl|m뚛awTJQzں]_}5Ndž cX>!^5i7zFҥgqԔWW n'Cg)qWA[2iTܑaacҒˮ=w.\`Zvvss3k:sR!~0 .jS @BK#׀;221::l6dmCikpcsSFG 9yΜӲɧN6h :f4;:q"17p8PѨ0,!!388`^Ɠ8;UNib΃0g?d0 4IuC%& S/f2ؖԲq$bc^- epM!I=O U*eWf5@ \&,,d4ףI R\r΅wDhpkٜ0AW_hVuʹ^x0 NFUUmp8p9'WZ#|eB_=0v@ \?ˋ%wO3RS'b*.7$gz|ف n_6a锦q=kpc+PQ(P 4[, Ǘ ,>ϝ:AqUOwPPss} c"a+]𰧞ZxԙZVqd2Y΀~s>qTHHX,޷Ç>Tƍxw Cݛ'IR.;lNttr``XZڤЫWLw!-))-uGw$Ow 4Bq놆XB3ښ`_m۶6!!>((pR)Bꫜ |{jL&G~Pu[nٲ%F_c[B ӧ3f,z5yϏHPP8I--u= 500b>i d[$p{yy\B努h"BBPgg'J&&SߢөssGE%&geM//ZWW1#船Jr,Kժ;#TDRrphv|nX,8~vn币vcr偞$ǧ! 쾛&vߓ ,)7~VkѣR=aN"QhJ%Ѣx$o%u:}KKkV>^^m[{{{+>,"J,/ R1 uR.C,{nN+--%<11w:::'6&F,檪Vi.atTTpppyEE[[K* FGA( C)@#idI1yuG},^@,ߵkLv{[ڲeb^~c[}+9Ig4Oge͊IhۛFؒ3V?q``kg͘?ޱ|0MMoٵkN<骘{̙K.yvMPBHtg{{s|}V0töQ^^K6W#m޽?U?Iz $$Ç:Юwҥ_'Ouqgp17J =ٶں:PHP!=D"aXϿb !amvOn+ Z{$m۶8cfZ޿Z[;}l T*{V8Jš8NiiZ-!!QUg(!IR.=Mh%A+7E>}jXlX,&ɨR)5.^;ԸZ,KOMXP+s17B$jElP\󭘘hAIi^ڰɓOZtӧL

>\($ x„̶6T*Em갰zyq17a?`TToJ2s 4_Qp:ݮ5T(;%I'>?tFل*.=cC77BC$[l *Xa!/T.T|(/#364HbW_PQQl=$R)U*eu5'DJYuu׃"%:6L:F"#lPmYұ9lu?7z7|k$7 SCpeA׳yVӡ PZjT*m4}U8hMCd@|Tvjmb& ԅœ$Sq !<֞ko?,[×.% :̞ͦ* *Sˆs#0OB3 F8oZT2Ns|'E˖-0aBH.G!IS\.%&*1!%T8Z8EC Ǝ~0yK.Ԥ-\t0w8a1Çk{rG$I55 ⴴIBʕMc5Fs5ky˖g޶cǶ;Hܵ{@`2T2+V=a^%+ql G8NgJAaZZa#摰zzJ]OauvJϞ=<>004; mmMNTp|//o^;Ķ0ƖxA.]^hVj5]]C$]BMڒ'slI?xfիy)}hm0R,v0ܓv1緷Kd: !n y1a#ƙpP_ϰ R #0 kiT%l 4y147W*ť t 3-Dh[ ?&;HJ!p"“صDVSHC^^,(hKxB6[gQ`@.Ԥ-R4#93[.)"4.J&k+,6!Ptp8\@&ksI+`$PVVUQE J$Mw\lxx}6@ZWWf/YFU.# E¶詣:44:118!$Fx~s Fb]x|A/&3ŶvL&&deM>o|劧:h8 K;TjA0Dz !_/bqT*iooQ$Ip=/0FbmZj`o NĎŗ_~7CDkk RI-, I$wtiX#1Fs9wBDx80dCw$ wB$I6L&~0@`4j5Bq ìV+ñFA Je2v#@/T AL@`0::Z<7`lhTR$00$ AUyy0LlFhm`۞3ky흳+LVW_?~8ɧ;yBoL&!ͷ}?44#O>>mZZZ`x:EҢIUU8.Xss-,DMMPddT*hBacވ^N3n h4'UU[by?xs<2ٖ7zoK$F*|y۶P(uvv~wL&w7DE%0Jհ|||}}6N׵3,PөIb=)v#7yϼ,3oL*?V[[wǪT*շ}4qbvԸجBw]PPЭ+hwR=Pka|?¢1 I$0I$၁%at:=n粘۵cT￯ɓ'9u VՅMۆq[V 8BG `2Y"*+'Y,MU{{أѨ.Ϗ$ H:sA펑%//_ * 9΃<<~8\YY4i#bbR. F 2JUT:8N $IR"`1&&Y Zܱ%ׯtAC&D?m'N]6 r1掋Kg9u˼#B fsst'JH=v#7FYl6 hӿ&oBpc^m?假mT{PDwuɪJhHr٤tpJ]}0f۵l#$;::=r)f$o[T(,,B66Vv<)>8NP( p1s 6npQ|`0iiBM>.jښ8. wGP$qBxmZzWUhllshl:Y^^R)Q(dȪkV]]rH*F$17fÆpSiޜnGb p7բpq^2ƍ!dNiggVrU5ĹlGQs#Μ孷^/))hZ:1+kܥKW)i_G>j„Nv/oJHH7x55[9Ι.9{<0>>rzV* L/>_$P 1 3tmmmmM E]K $.w XjvK=ojwiki~7UUն[01ٳg_'IJZ, j{޸qDZSbcc>n,Ip/))+))yյ:[P޸ 0ਨ$__>BTPVvEox3-- -- !h$I+ SN*5-}xD>l:.+ 1 BP& !R]]Pt8stNT8/D8$ ryT*ikkC:)zmhIIi04$'% VU)RZ씪aC BbX^2|Ҥ I۶D%O><77ϙ |P(w,hbù^ׯ_G >Hlr@O3HLU;u0AYz;F"5 eEEgjZ:}INJ*.mlIe{I:N!.]\%;v||Hdg M&lhhD-Yࡇg?:kRNRqi4$ͅeI++KX,X&L^t7G= Fs69ܚsrN__`nifee:d0XYYf` ^UѺ0N--rAAa"QphhdHHVniknnXzicH I7N% wGs%O\ǒG~~yCEE@GEDD$K$H{@q]p 8ȏ` 땕2nĈb\UU*m~rCEGEWTB{d0쩧Vvtt8LcA4=00488R,CjDRL0 j)H/x̟?~8Xl[ZRi?{g&GYS6d,dW%AQY %AA v/!`w!%@3dgߺ{z~TҙL23ɬ=3Oou[{N2zwwb{ǾsU߹|t}w4.Zf=4KvbnC&c~O c;Q.":4R,-;fAI_w52駟XSiUQl("b)+))٪ ptgT @ ð{nSނ}>֭:p?O2d2556|_袋j ^r7޼cms~f߾l\.kk|>IWVUUC}>nᒯ}{{_y9}K9?~أuWO>G=u)f2l*j2قA@ 3 VT%&/_`7g'' ׻b޼yW^qO?=\^Ɵ}~k%tXtG.[O7+.wT* ,664 Dknqn6O;f Ks9 g\aqtΨcpg8<ͥ' CcVT%_ZuK].MVڲ,َ,-[MN;}^oii BK,5XvP*W]yV睷cGˡÇ.YR]]evO$< wnRD^9lyvL?(`Y6;"BijZpJf(V"8^,j,[4oٲe8_2ǎ7xe%KKJƶGND#Q?qQ8t:孷.<8uXCxPe.YM4:p`Ǟ=B>D9o޲\aK@ f"ZݷG zvݳg>hǎd2JḶ^hQkk[k[̛;<nbK zmijft0H&R(j~B] f@ قaaAېch*LvСhlSPr566j5}ζw㥗Yx1'~.W8h4uuɀx}vZ]x;oYcgK}]ݖ7ߘn+Z_Q1G",6sm@ gVk(+C;ߟؚv}mm{{hy?n۶mO?l&J_.]6fǵZm>llh8x`MI7a1!8C"=ATZZm2z?0CQt@ Ĩ$3d3l >MrW*l6;A54 42b+faxك¨'LVj-/)9a @ aaDSG'J٬X"yĨB\.d2Tz8'iʦ7?NȚ];:Z( aYq%%vl.u8~"1~\,ˊDdrR꓍d2:kQ=n>MTFMܤB y3{ʦ-; Ɇiuqzh<n 82"NFV>/ 烯D~wgß^|f /8n;/NM0Œf+8ج{;" \8>q3": % M|`B $hfY Ɋ"m*vvm_D!xڃ\W(NئT(y1ŦB~^)M,{d*961{'a$Ij4_|y F&vuz]uZQҺ\=^ HbKHdm @:ȸOZWk*jv?aRYlm/|*fX*5rNT(:=70̰{?'~{L]d2vFf,-Kz{鏙C iT4=IrL&JqoM*WȩTBXJ6t+y+deS[-6 cKr<@d6E%{ςAX,_XYYK@4 3 aTG_ap߉$|- d2Js>qhOGqU6e2@pR'a:N.soqxT(V̊4qec[- YC_s͕jGFj{!|WQolP^@ 084i4pxIG"1(Z}Y\"V&ITP~RNHtؤRt+/B޾ )z?{pՕW^D"ظտOR|B 9 K d[M1 ôuAe$`Dy0nNZ Cvvv=ȣE?RZ B?GYV_n ^H$ַ9{9>wF$9^z u*Xe*DÅ<%i}9Qtq.0O$b2HRl}y#l^.pW.@0`7X(&4_W?d=>ΜE+ݵkWcG+7$I ޺E$2q9n |>Mdd9&I滻*Z1*!"K$2WҚL6sbc_С&jӈ`Yq=7+H @ &\.H@.WξYFP[E>>o{ݿoެ~{Ǻ߬[g<EɧDϟw~XbywwW駟X,J%Psi[,X,LW(ȹE"P(b8-Zkמ`#<1\$I7de%fsZV;tۅ@ YN.`E"ݧ6s I's\>qMtl6H$7\X|[_lO#?Xr}Fw:\;wٶ{^X_d4(%Kڵ!w& %t=c\%K_yeuytQxѐZRixNׅ "bHƓH=ll.df[eGNXe@ xγ"#sի&IW?˿L&LJb{juw8S6) Cooߨ=vGPHCVRkU6JߙN'.@NR$drazz66WYYkf%5s47ð~r\pu ø\:p.X0߾Ӕ^?]g bZBdb)S55MqLlZ@ 8r MS<GyydHp@MfԞM{F`ÇrIdFeѢw=Fa7glѱpN'f6?4M9]fjM N$bmVtM@Ė7ߘnM&ɔ\C_0oޒ)ٍ("=jĬ}M], "W\β,AE-^ܼi°8d(y55O>̐uO9(_r0FC6[ZUhhB ,! Xj! ѣ{U*^ 8/PXo ^U*Ν7h[َKi H$D .]0_wH-g_[I뼑|+_o?#mm\˅usmA hq,9$nEVƆ[@ .+xlޏJdJe$:4#pe2L1qP_jD=(?4&KtZZv /fFsnˎ1-, D!ZJz^!'G$9xsA0 SUUM D"LU\d2P(y<{|޼ ~aOAlhl:![<֜5~=Ql6A# au]lPlI1e;;t&jT3QApBH(a>/B!'I&IV#t B~BכcUy-kn¡Cƿ/.euEFK+z'O06[JGsfN Apښa&nE xA4CS,eMIS"DbQ>Ow1E0 >N8HzD1+d2'[kk痗.^" wvc{fܹgmkaXqC7_ܧ{SˊVv{ˎY.۷Ǫ~-GN,1d@T__{8+-1Dm옻6Tכ4 X6Mbc%R1A12q"M4M"I`YZy RaT@֩YN IDATU]TZZtv !aѽnwM\yy2kz\7Q靝݅!]T=gyv 1J5u5c}qI&ErMɈ3%9s ª9sD6 q^>~V+|qO_kk/˲; /&A/M  MS}}mA9mh4s?reS/&Bu&:dNxvޗJf]czp&"ssl?\zlvc9gQl0 rBԴvy<(dp 峔X7o!<}DX X&XrF@fA /`ᘟ/愹 vZx<^c&PHELZmScm~TVVڬֶ6?4pα۫;s`]>Hd%%vɪVU*]mX__˲l[[R,K1jn8.?@sp8-[MX,ێxOCej>&rySP( )J!v-K,Bۼ9͖ŋ><eY.Waȑ]p 3 w80 ˲<OT<^8c.+1 iZ&ƛo~'0. m8kp BH$K$rL.(b@ $cxIIiIɱ44Ʋa8Ͳ,qO!CR^t>!=gz)&Ts5kbfY͞61u4ptZJ3oRQ,l&J&9mS$PEQ˲\n@i|q>/Daʊ%KIr)ƍ`0g{{{o6x}ĵu8xƟ~隯_fk>>yܼy^G~lO?,r~y8J|-MM޾{Ϟp?J@L  "X&K%Bb D8ӄ.8XŰSehi$_$I\.t:MQ/._ybW_}%2[ni5 mq%Ixn7gfpAjn~fM( jkޘn+c'I9G3Xz=E&0h 8)xY0d$xee%p뗮i|\(mڳwGd2O>t_?_ nܞciz6R8S˵|g}[> =SHp#bT&SdJL)+%@ N' ]r,FIT"O&t"N*E|nSH? 6nܼq!l?%8lяn`V馟l-[^?h<[Qqݶv}c(j͍@&Ao$+F[mX,בɤۮѶ}o910 khhx<2T*%].Wgyyy<x|>Naƒ=Xַ$ kB#;:.xÏ@&UWUפ2FR<ѣPɧΟ7W,;/0@܁*B-)R\ Å.Ɖ brt"K$bd4Jө|>{ڛX,kj,Ysd26!Ə5J䤵"*"+V,ᲅ_hѮ]{o| Ba4EAk0Aa@Too7PYYVju:**T&PaNg0e)2 (e2Y<¯j:J N wϝ0nP(5fHU]{͗{K꧝1aF:=@}tF FpLP \V("fY aYa8 MQd*x$&|ReYvҥ+w(^vg,{J۷r}>t:Mw_Sm7p˲?AT<}>Hoo_sϫ}@I^޵kO]] 7 H8qZ[ۖ,i~M17Pl.H$NAZshm(לѱlB!ೌt:y.F_VVc4 r:Inf+ E. BCabF0x<-rADt:=$W`woݻ57ں5 z "MVU,?Rad WZyQZ@ c +,}8o7zyŸGw10\PT:JVR9Vm ->6O1IE"h4EMYlٗ:;wwg؄d">p_ɤ\0IUU/]|7xOpuk6j4}b1|m^b`85$ͮ[w'O=ns8fd-+;|ӉS"8@$4v{UII`sPZEVwuuI$\jd2(*) Lx$ AJxkYr=r~S͛{U7'~o{uu߻?i}yOꖵwf9aRBҪT:J#p/$aYө)qd`4FCXxBD%4 ?K޽zMbO[. .Xnݝjn$y~C[Up饫d2,X0Cسg1iĸZgb.tC|ò7xJJVkeii\ru{s_KZ磱Xͯ_4Mg2?=k|o|ۅu}!~ym߾6-+2ǕJFc J,2 0\O(M" }/LY@oϟT7_tjp2P}Ç&bY3Vx4Mcw}s`0$s67U0 ;X,,=7Z;j4͹e`BL y.j-X:t5 sWD"e].W6FE.|>>J*JTiaR6a MS-O%g/IFY"VZVkP(8Ixx|Y1 cY, PH7ؓM>ݹb)X|>WOOk$<خ,v{_~ySggBdYt?uwƚkѩjјLd ǫ~g <3ΖEg#OO1⁦)/-*)ε+zzaTJpJIR[Pz>F].W.F<OKJJd2</ @L6TZD7)B>l6MQP( |>Oy c8dҁ7'"-))n4l&$~ _@(_;>, umm4M2!3+j;pɲ`Z|dPswuuzKKEDՍ2hD$Iy>Ot.fD$I ($Ine2fLx.d2^_ח:,ƲL2s|P.WR(:N B |>߀?0)'e>O7[,eFcRaV,J%x"f)tɫSW]ŋ5PGG`\;gNM02  \~ iyg#vo\.wvڽ{FC$hmm㎻O/n.D w[h|hEW4bn+&4w4;Q TUU<JC6ioruWTj4ƹsR`ЃM\.'JYT Ifr$ed&,0Z_Rb5b;a`)*L,N'X<A\.;0aNd@ IRT*\x>K$I|r\*sxNT0 /;wٺuڵbk(kll;(Z⋗]v?2²p ^x}+}y'ŋ~z1RCv*l6ru)K40 4MBd2))D"\6@.60HqXLQT<(PrH@1x_כM&Ng$b\f `(|w`\%2 T*:=G,;bD"J2J&SbaX! Ex<^20,p'$i!y|>g\.24ia(iK[غug RUO<̬SIisp) H3lY1E 2T{6l.++\ .[Ty^J$y<< ''I EGd>/ )Qi5e D H$6&UcaL&T*RiR>_  3b\M$&0 HdR\&Sdr\%KBQ!;  E0 I\&MӉT*$SD6!h_V/?_|+׿OvHsCUs>`enlOؐ'1':w~s|>}b)XKJ&=:~ ='9F,_$>Eb GJ@ ƃT*7m&UPqWxXN3l2D"ɤO-:?h4lܸ;ScDqRۊ=ٷ_?0̏~t#\jM7dÆ?o6Wtt7޹eۅQWhwqm]{éHp5W#/VVD"9BO9EQ]GF٪ZCCwz2ӔB[R\ͥVk\bY`a }Zn3 À(7+j@(wz^r\V( ZTEpҀaǼ$IӉx<h2smej8Uscر?xDvˊNpÄh#]C#+V,~nbX*Ba*œy& +r'H$ -Zkמ`#<>\ep82reP E"Za66[u,z>kJ#aVk* Y t:w_Smbh4pu+~{`ɒEvFNw& %t=c\%K_yeuy9󾾈b&Mwu9j0X-rZVkkk^?P@ TnV " d2>0v,k-YrT0dRNgk0-)/ , wἇ\Ru*VI$QZs 'l2łh8 %"L58S7  }X$03 ("=2Zk2 ˿L&LJ8>i{juw8S6) é$<q__Ča:D"d7K h&Iuݎx<<ۦWbARTj$Ɂ.7(&pe~CQښF HmLgQ>_VZFW(\b" 46݂ˌah4 C!o43/eSz΀+e ɻV0짟\x\lݺ;OMM6[xT*>^:{Ϟ}05i;p&=vGV:U3'*dl6[e. ~+H0L[zY .Wo fYh/PtJ%._PWW׫zRXooYU-%j^5iz.K7,p9O XQ_0 XdF??wڬ92c47l{dnd-Z{3Y(0,wxq{&=ϖ ve5{ư!9N"mk޾_5L6b)XJi~+a!8GDv{R&Jt:rz<\)- EX0D%%ŋWd 6 twB3ۖP5t%:I,p,ˤRID"1.Y(qwǂA=Dl<*Xsk-X\pCQiQn7uvv,^p, EGq1IHvBQx;o~k{َKi H$D .]0_wH-g_[I>7x\H$RC=ε_Xw`?'{jJ4X,$H ED"Zvl,aZSƲ=Uv/o{3s957tB3jD h#qZN6@"nuv8zzFJFĦPh9wX2F,* JXʝ nwSMcK_Ys8@:NҲeyᅗ&7Bo2Or1bsqH$j zI16 1 LFcH4"E/KN^^߶euz3E8B^ea3s8ZC54*zza6[EeeP((TaF7E(c0 >֪F`C!_&Hj^.WvzόK7Mv-;]dN(?㭪8z8Ŷ!T"J\=BV*Vq/ ;6$T"'D"L38J .l}Gbv ߯(gpO/L[^w ewnt`O?! t[5!f :V`R.D.?J[S3W7u8J`3gD"iwx:]h0 8a6-0 hP,fb9@22O}JB gRg-;l,}"|С#"'ܶmn: Dh4Ľ%BPd \%+R%Wxwa\.et6ft*Mg\.;2|v8'7 ( $̐7Z,ufY;o7iX>:2wyQewn1ꫯڸv?W_y睿JŏNgT᰿#>Q"C.WVU5t&]]TڹJeYH.-UHm4ZpDzg\>ZMMK`Y#^0rt՛Li'(W{\E!F/pz YvȜKR,Wc\H r\ 4t(QlP@yR\&SJ\%D"RSXγ˲\6ϑd$(2ϓd>?B$E ð,3iT`Ozg?5mY,fѰew9)y\DDKˮ ٳT7-o<4^^Vxw_VfӞ=XݿO~V W66e2bl?  %<eYpt~4?T s>O@sySVv㲻x=p;9PcNZe0].؊E!S HD=8.E"X̽"D$DbTNY8aPM XcpaYRc8z_j5w׿=8(h4궶[87q.jieַZSc2Vbq>HTVQth4z\a{zZ;E"qee}IðD"q|f0< fGL6{FQrubaPYY[bn$UU, l)G E$͎rf鑷Zl,-:]D>82gY.q|دn~b F##tF a2T&DN)a|䗐>_H<a88cP(L@ ǃb(E*B= o1ARP 7L_v## ø C_`y<|pp8ѫѨ#=G9JAT~<rLooՃV-';#"p䥗ϪTXl㲻""3W8qoqcYN|h8t?o<.BH$ɔ2B*Jb4Y`Ѡ\8D#)j-B89rem|RCtWeݮj$"OKyii];  y.x.IT*Zj \ɆRzp"D VV֙LvNm'M&Dͥ|ܱd2aR"IѽHl8Utw8:Z  C}}d\3-]JT`mpA ]wRgҳ~jiD"RT"!cɳTP>82gM( jxc@ )D"9uϊ=3=%<OT.`,.M&D"*-#ac;lM{NDd%uu$wzz{PlnVUZZt<aXIA ɶȱ<n0x>߀RQWwA6q8\}\uXR^^k6x8I89I<^lɲeYŒxlfڡ@vf:Ph鰔a(LH:vX~i BCJ[ IH8^[-ٖ-Z7,ˎcDzs>?9#_]}{)Pۓe8`0TT1 8/|7͛B>n4բ~h4711 ]wa0'Nz]wc;ohkkݻwRι<(k @ sQ 4 pWl~ll\$zZm/_ p_fÇ|sW(IQ={ჿhl*QkjjjJVs, +HTRi4z:ۇ^gMjx<~6ZGG9@PӵD">>kjP(rY|>/ͭNމČefBaZV|> R'r}?pȧO<BOMvヌ0Z~_/7T l6{y/m.b"n]oWl˕tP %AzRuY>6RnZRRYYqt ]]۳eX?ٛx?bacc'kj:V$F#it\d\Z1 wm.0H )*p&gD֚:V*8|Ӛ dU:X,<zFsQmUY3,6Jbihv'^6}qQ}h68<^e}N,65uj6ۀi,4A/&'D"_!LBP ~`LD"xL&rYn{uuJ@4Z''l6Wi!rRNNz^>Af'ɧ & Ļ \ w?EAخ />bqOھ}]kebth]/5-Y!A c3PQ(lvKPvP(CjM u(H$\JFCV@&56q8l6k8~FEIjN&Sffb##vǕ[PJeT@"XfFqjuX,G$ͧg,}5㯾Wox:ɕWnǦa ߼yc2r9ׯo}#D[{䪫>. 2ĿEϹFkCqu=Xlw}gEE%[2>>Ħ d2yݺO8"h .LΘͽFI.״_  BA.꺆=BMƉ (*ryH 8d2Y&j2LΘCqBd*Ec /w_x=[o;n{ߧ{Bc&U}K۶m۷D"?CRc2\u 4|rkXprVX,SO=N<' ?7s5Y{g{~o||B gpO~s?~%|7–t:54t뫪ė]a7_A hZJ ÜNȈ0Fv&Hčƞ|gAT&X,p m%IJRGPrzddXJ&2LlhB}γb1b`q@$vݻo}?8xWT f?ܾ{ wOO],:Ei-VDbW)DbY!Ȫo D"-@0==3o}ߖs7t}WWGeeŞ=-OENH(1ڥReuu]q" dqqeA e T;\5^665uh4@29cLNzszADQ_#ܻDs>_׷L&c@.578ϧ?{n޲e3yog2[oC}ԔD"g}D"ʋ~JxÇ?DD't ]]/ó-x 2RKsoכ=&]^ ܺ7?rfm9p0]px{}C`^Pm۶k0 ð,eL*H&gdr&b%USS'ږFGCC`TE fL&mG׳Xd2a47oLa=>I[,Y!! 2,:B,:նTW,~^q)t{dZ__cǎwwTTx4JL_@PGff 2 ?xFG(t8>yM )#ͽ]ozlG̫Z5BY׼ĐV{NA56 $Ă28`f&C@ 09==U 㼆tZ&'Z[7IʪӧB[BP(z]uu87-djBs*t:^_S#%=a/dr+t6.8P(J5$QrȿazpBH>_aL&311Op8߹C墹/oO\ ,SPw( EQ2Bi4Jg0l62lZ ih@sOM/EF\_߸i[, ^6E,*d25 [}h`|,Wkeydl>K>w6vx+ȒSFQiSȧ\4]qck|E\8 A>_(D"HT'55mn}ttx.ځ75uD͛?wX0%d2U]APfLPXRI?PU%V t:Fx!@uum[oԩs[ek6|8YQܯ# nww=|7~rb,!G};o3)W>oʊGo^ѓOq8K29Wzju ZⰥiǦ2%7l`O6䈱Xdx4@} lnjӹ3J#Xd9 PhF 3O"@h?<'~ҫiǦܠ4w) IDATI0lmm!b> _ bZ" h\C 4mzf'Ntmy~N#\Jv_Rsq'~DPh%ՒHdd:ymffbmm55u2lu`i`Zm J$K8\< W׷Q@`dI(JJd2Dǣ`,/΄Ur+^6XFG?a3,ǫH>"Mr>թT*wðh4ɤ2{y nPVÏr[OjBA G?p)qTWI$? ذĉDDZ1} 6tgo川yNs-di9+Vz +0lddxddjٹ}jj|hh~`pر_R`_j. J RA1i.j&@*)ZN<GuFcMMMo Rb)`lmIuuJD"ML^ɲewdH nPV4;v\f 7\Fgdyuuu9ve[lÏMo9S(o~_aPv.Nd6@ E(i6ܿcؤ^JwH*Xn\9ɓ۷TWK.k7 uu 2Y= y/6 ^f"u:- F$RnKJiBaM6ZIUU:ݙa^gqC;7Hs>𣧟~r``(_'OZH\- Qtuu[He6)@|6R ;zɱߕU:]&S|̹&͜:I{e55u-,'JZ Tj%zCΪZ@PҟJ%;Lv8ps:-SY'6orY溨fSob]~d*A''æ4Ckp*ؓɤ7B] [ׅdi 8NPږ*1emQg :Ή )g3&J4|B8_ׂ7yA{bݞpu_$^ڂ'`ЙL sk.½EJPn71),,t:58xr||uN*+]]]]```MnV7s8t:iKD%5u$yrrferAI"CBL=@UUVDPPO~tERiai.@r\ϖL&S*9Gd]Kb9~MT~0L&6njj2o4=zS\-s{[wJ$׿~D_}wK>dc..d J?.olTZssWUUm&;͹M"/+=ЂAG"_7*0 6bvJRvqr҃hccH$?G(F\UUaY4:ȿQaCř  6R~J`ٸp]cc_zn~pv_`ee^x<;vرgl!VgAn}oȈG,`OqrU-H.s*>$ֶ-vTќx}s{}>):lFL2ҟHKS@ N  5XD&E3|>K"vDZsd2Eo kRЩ&')ѺZv/憺qt}wּҏ )+Fena"yB}VuUD#GU]-ݸﻻϗJ%O>ٹMkK$s(cZTڀ $*EQf89&猒z}Lv.J!du@`rpdѻ*"Cï8>+{ ,jWz Yk%AK=Nnii/ Y1)zN9WR6O}~58Eg44ivuYN ,j^K x`XZmwN}2==5Z,9}Xk斖'N#JM?N EADlelv||FJ"BڟHi*KU&|64qۍ55A].aV5@n$ |V5Jwl2_^S}Y4"n>jfcҥM1W,zL*<>6|囕JwA )[}Wɲ>'^Gsɤ/ z MbwgWPV ݨϪ-pF^nAB['Ujj߽EXx`h68xuͮ3==e2tmmNtJ2^O&%V.")XanCuuLֶDNE(͵l6=8xXYB.~"ߔU廱,#;7!]{.D zeeE088v8)$H3 $bBN*EA57I&~u ]Cl&Kp] ЙT:*_CDG>-ݨ*a@R cLk=gq2Epd'ߑ5R13mmI1:#4^n݆SvY&(ITU1 s8D`:];JBt:`B?HEI-AL|`83H$Ąf/M1;8~,? ]pI(=:3SO-|ngny% /ߜܰM7t~u*rו\%k?ݷsSTF&xY;~& gq,,ZR5[, `i4Mt:kf&fGȞHT`@Q$X<"%Riz6\CX־;J+*v :66ja\iкuMT*UW|YXecr她% dg_>p$N @M'YmU{^bu8_yHR]/`Y[O߀@xp qe޷d*ZN-m(%U£hϗ_ޑ DC)p#;~Z8XuumnJ$p8PaL Eщ m-a'20 f1&L[,}9mnnR>gddxݺ L&; *. LR*[sYq~']]ok+;5O9wl)H3V)I6 L&p!HsⱤwļ:MG>$%_{> e1W%/c dӤʪ}asߨvݚ5mQRRfWlL&4XV %7*8Y,NP(CGM,͢( a;/|Akf*rYC![&=>>r'L47w)d2 kdDB48Y!}}sYмP8HgqP!E rN-i`Ļ8IhD%#)HXZ㙰HԹ.PqE@ pEj4ș D-ĉuvnW*A1kL|hyCssɓKMh0,`Q?,`tt:1fG ōpXDEb(,. jȄE^Q\v/cjuR4׽o\AD&X۰] "`&`qs謚seE28q㎎ q}s,rZk_d⥢J,P\oxJDQ].ؘ`׬X,khaXn7d t:+ =3TWiulN\[Ÿ\O<T*W^;-daRQl6 B,dNNN4GET$~M嫹u+=@VJ)/ or>P r/C釿7<Ls=o$g-FvKؓ j>{D|מ{d #,! jk¢v=p`"0}p"zSÓ?~mok.={(T2NGơCV$3'OܦT6f2Y0ir+*adľ"DQBj0,kdyS*xZ@>Ph­`%T23 >5΁LX7# A*t |f[rTH6["/m.oii޾}uD >o>xZ}5 P(NDV*pDn\M΋s֠{?ŹGn{^X' Zc; lzI$fzz>خӵNNzZZ6tF.W#(I] 3  R髫%DòAM,1O$PC'N@Kyf7ZQN$(2ьaY7xï~۱ =}\ISD q[ JHj{l\WtkmͣG-Ϸt@fS.f nZchEݐb[Z68q FF҆Ųа6r0c0,4B@Кi4&cPjEQR43'(t:crrj``55m`0蓓cfs/}ILyGlv2|ꩽoL B.w lWW' k~z[wf~m:っuk&@ RY䥫ZcX?*L08e2[[|YGBU*=N$61*r.l^EQ].kр$Yo'Lp<:]ǫ4:dmw:-9KBi$8o~C\y'xlzzZ v7oL&S}\9.׷΁>)UW}~9}1)SͽMg\iq!l]s,]QSFYR&\%{N4Cllix|7Ǎƞ5`"_B܊zD &\RnbLAN? 0K_ضmkmx߾= }{gTj,#Zɜ٣8cJ5z7t}WWGeeŞ=-\"8f)Oߚ Trkkbq6996_uDiOO,J75u0t:C1bSv(! uB]A.>y\n,#nb AH$N}{K/BRl6L08k5~z*e1.Nsm 9Oǻ{z @) NgTUUd n9ܕU"DI$RU)}(+4@P;(:`.4:TZ6Rg 9&8^XD(\.B!gv[lr9?L&{wݻosH$/HW^yWU <|'Hض]]/ó-x VTyim:Ǥkχ;jՁnH `Lȅpx ~\},Рhn7ΛǫhZPŰx@g8CLAuͮFP aKz;ݵH$~=;vǣ3wtL_@PGff ^23`4y߉B/beEim:־jbjnY>-MM'N|;NmMs_ߧ%:Y rycccc.H]V H$' d ΘLVSSFVkq%En!믝=̋8 \`O>_aL&311Op8߹C!)iuL Ӧ&~/ ALP1 6z҂Lt%l.a½G nҲJ\64pv-D"m۶xAYSSNɵZ&0 [nW.ܗ EY8Zo IDATǫ$*jn@7_nP(zN$vB4LCy9<~=Dqi>_׷(j % L_cc*UА'?ys*#}̅LAKӀ@ de<NLxrT0T08xމlR%ӓ.m3HmL"Q >22 Q2::<2b/*x8C<$J?^zҁ,OPX,JBDv$#AElDܰs5qP:ty_6t'{7 0,;0pr9 o5<@$|P]]G8xkLsy# oT5HjCp4!N;~i@ʍ OEH$Jn%WL&nR٨Tj,ҝ Fb!2oHDDQNx<:We>RmM' bPh%E:?pC[o/~oy[E_Kܠ4\Zacf ~L׾RP8>> C_X6t8q2믿Vnr8s8Gy_ 5 irr' DR(+*pM$Vk_HnѡQՒ\ VGG@*r?\nCG~z!|>B cnP(XlTX aAқ}h449魪HΉ(B&S Iy޼BBh&"P`xxDlDYWWP:$Ikr+&SOn)ߟ{`Uhnx?/u].w"xh"T nwaP'O<ȑ ur?&4 @ TTE:ߗ?VT(2 MXRHϦi*L8^(JV${7(+=eXL `2,+  J$wuǑ#}wsvuu֯s%=֢)H!qdikۢR9t:5::Phr6 kb9qD}9(j}}#K&( (ĄwdVICCP(8P4d|c6}xfl^Q\Ub>ȃ, $ڃ I$bM𶶖W_!B W?t:],9yGYkYk"æR@^:!dE\VAo6'&FA'l(j8<`0dؘDAu<f3C&SNJ$@ e…Аdr9+劭ki5[6OKT`L&#&|M645^}%Wop6}a?зTj"h/38z_ @ --lPw 0+gCG6IRD4Rj%z~xEEDueHn {TzSS'FxnyB.YnvGl|4x=4j4} v~uC>/]h4z6\Rrcǎ/y%⦈T*r;v\ܰws`!ql#::S\b,N]rGvl*k cE_l@Q?\J@.E<G,j+*DL&i (I&SՐǫllle0~D0J1 Knk0'æ|tFSSJA Y9uK e%.ǁz sSFvnAݻoX qeccD"Ns&I$UUb@41)@ HMFYFRꔙLf T*v(̇Ng  x,ҁbO=8QB& wߟJlJJ].cwIWz NXv?S5!rәtL$)}08tuvB38x2I& -OæJQuum*ZəQU%5( p6xAi0')n nȅ@+Dbdǎ y"1φB2-بf{>rl+V@T&ST*N\>  t:S$"&ծcHl$"Qm"0{KZL`(v` d2傂rvٺ>:TڷAVcd,vEă&MCek7z8ZWlFc/G]ܡA TRc2Y33aj[?KvyGxxne)A\-qCqfM&`2:]Lq:-@ `VP[ewɮX^r-ɱe7_[喻R@ W*d29tm%Ph\L&:vLfn944Y,n4ۍV<< U(Ι"dtd20e_Eعk8w.QoO`@in.H@ H"׉ iݺrfzڟ͞QZƚCTML&; \f +EI*é,G=gњg-d͙Fgu108CX4 s靝?P\Qs/xZC HB"r _ɤX,n"1l\qAp 8Vh4F08vHd`XD"ONzGGEk2,¥0͵Y:dӦ.'P\8eMVzK&M ra0X zNN^S(H''\nEuuaZm L%8R(TNgf2I2 \it^O@ Ybm۶6NAsPl6 sX,&999YAEsF\Y&}]Ws+=@Rp1 RPx~1 sͺv ˤ)G3 ͧR^k||NkV7hT*A2By D";V(KPMc8L%Vz bO=o͛7 G}h4EO?h8ٳobbA`ЅO>s<Ѓ믻\ɝwSYYֺw fd`D.JJ-a3\lf&dh4j:X(őJqɷ`>3RXhxxӵQ(ԑ4\+Q|Q,YQ>J, ]qȧ=]Ǜ+ }σ>rٸqJp~;w^mX,-5 ( D(PLy,];Jkн,1 1H탉DtL&C"41.Ph@FFlICm<f3 Y,Je 4˟YEwXR4Jd!h`[L:%s%AYgv~# "v=t:8Bf41, ```oկ~y;v|a߾goߚVQ#t(A5}k R)I}Ϛ͖ BY>Y[־%[6ʝGZ֟o+@ K ïoPi.a R[ q⚧799}]ٿbh|5ơG6Y@ + 552D`t1o TjLv2p8LL8<]UU HD8BX$OMzBR >55.SWt&Lill^cvRqZnEH#3s'Q](m_} >կtۿ?t+MOO yd2r_; tG&''W]ŤL55g^]@ KBihгLfFå\BKP\.!8p`X&R0ǡPh%a52YC6|^Xf,LnllәޑROpōpMMiz:Jm{vm7oٲ<3쭷ޡkwujr"ϾN"^yE_U%N>v|tp3a¾&]^^#1,v;\VVUT*4$@Vkj)d/6 bA^ }^s{fr p`'$b 6tZs3Eso_b^e0O?b[x饿Kvܵw~\L&qܮT*bTj O,6@sK$>7oټy yЅ{("ͽNTbf47É#klN4xƓdʲJEz{sv(ZUB8z^vJՖ0,!b6Wp", E}X,+NIf;:|f`*HHD\FE{ڗZ%rBcY 8c)p1q,Y|7ovH$wܹ' xÏ>`۶mg݋-p|muݶ`|a2|>cߞkZL&jk`pk| ,sxI:9c'waFY0$.IJO@hS1zяϲw#*0,v7 ObJHd^G*udpl<?io U`@+j.rhgnfHr:pGXϐÙ+8| Nn  BK4qh{?t:3߽W8k˖o͚UƍPsYh|s^}… >ݻr[n^hj-h;VV>oBN B_E=sw^ݰo'0Hs"*s,jɔ6[5ʼnFCnw$Bfa9Hk%v{:|ífT`feaHә~ϠUԦRù0S&|_8\ GΒcxpZvc0>Xy+HBbn:TJve_p8~g}E2w?^y5Ne5?9sr tz0ux\g`b^uwݿo߁ٳ믺2)e'"ܣ HB!]256 a!mxdX1}[hH$ofwqd7a& T ~$htuDtcFCryZ Bd` lTPSYY/Sc!ZQg2Cğj]_ڸjЈr)éBdYRCB S (a{0K]M/B6{L> =^(О$R$)(ITНz&SN}nwٲ!4 hq꿜6[$>.9sh4bضmze=ofOя!M޴cPl\|ɥS݄;Ed IDATM`B^ R 7_>l66t6[ "~?0Vk R fs%Ee f fAWuô X/U9dPL&Ec+%_:)*=;d_=*֮]鴷zdZ)gؾ}gضm'{FLJ&1 |62 bT ӛ-8jKMrAz{;}>ר1\.&qǑJVk%DmA((tvg2Ew DX,HXX.WLlhi9;QZ|=N3}a$AFwDZs g.p_~u޹.]dΜ{N}e9,Xfͯn ޠEwU^pA*z+p8>lS1!X쭷}_wwwtw  0?(N JsEW<!\x֭r鿁@g4@X,Oܰ)J %/e۞~zN͕k[|ZZjj;~LWD&Sr5 \6+ {~W~TJ1)r"mA,!~;7l6(+A髬c0X fsAd]ԻM#PWV 6rJ ۋ?_6UߑsWW`yLxɩrY( UֱQfP7vPnKF>_X^^KHJ%UEe{,í%Bf"lVbPoL&T*cnwA`%%:{( Ô/9PUU(9KGgwY4wx&'oT8\ p`'$bـut~׾n30:bD4Kp$!eфgXdJ7 8Aϼp8==]U^^rkV\L(v\7|Gl"0,te:]igo,灁a++/z`0R{Ŗ7\YixoOLQ:!ݓAD!3à M7]ᰟ~c~ͩpN*RuBi)N8 )aw#RTpǺAQ d2ّj U媔+0eEi{R!uu mj\ƽcRbΜ2* :MA]Rb#n@TY9tuтAP³۵RJ$==Y3KRJ(8i\.ԃb` H]}7mz㡇_}H7o\fmw6]s||mow͡ō(L.#hH$ӟ(ӎV)4FS8pq (grwFZ~WD"cO{/^h۶nGݶ`|a2|>cD?J&;?ګ}}m>߂ >޼yNéhhiBLr(=\BJכY9tD"Vh{X0%PjFcd2nwS`gn3,--vtxl|hԣc`pX\kOQԁ~Jhhiqi+쭷ޥך^䃝-."k/^2e7lz݊3<~?ܦ1L=gDj)1 ) V n,A⣩M`}3/_-[G5kV7Bs9gEN+.ϭzM .vsͫoyu[[HAA_|r*N5$^'qzz{;Dz'jn>H0͕*NH BL猤DDh4 Tte{i*6]\ZoKM缹m~po] ՘8v3pв)P`_GBY, _'JR1?{wGQT]m-]a9j:d˖k~9s4wAڵax?q SmVzzڽ^Xlzo jId2|pYJd*xOrLGښ ζQ$@|wO&SX,{^Z N&~+6;93h4Pȧm3)>" r|0A#ӑ6Z(4\ {p*YaԐ0EA kRaL˖q546iS}]]fs7}"I-K+E"0aD4ZfxKm*lwsfUUI4rFhf՘,7ryI2xH$)+S6ɡLD_RbɞT31)N2 2BYB(I#(Ad~xd$IRV]t*FL EMC7`PR#8Lƃ3lB)2 H$j k~,hˬUkhl\t ؒq^ݻw95͕W\`&ӌb89ЉܥR%E1ZE|s9\.uج7L58oӕ2P] ͕Z[ d'T%! GM;;}JV72вt?ۧ @H$?ޮ]{͛ ~˽}9¨H57K6Nu+&%{ ,v:K%p # $0'p :Кd%@]q8Kv=w%s޻o_0;d˖sf/X`͚_mݺ-yy|V]xT_K+p|y2NÌBf2CD"}.Wpă`XKZ#Iwuu E"Ie,Qx#MiiyI--{I>dK5 mmx|\lh6Weמj)Ǒqz~oܼ^Ozժs _@~áPDTͮ]{@$ARfpS( VB][SINd23+bC7 a!N\~Mͼ9s ]FQ^WWw]}3$I67Ap#R^^'$N灜J&Sy6Kݍ7ͶjX,V P頗 T ڐr(wbJ ͂,B9箬k3=,g$`6͕d`&ɯF}7k+WZ{;~qpÕW^\xQy;BcN 4Ttr.W3\6ʑioVWf4b{rTZTLKjHQ $wKh{eϻ޻>͛`X q͚QtxT*q<3U㬕uPvO1wH$d2=WWwd\T*իox /p]vڦN}:k^n'e0μiL0nd2-%Z2)_HΧCQϒ,R 0#]$3) 3\U^^'YS Rxd79xXNE2꫿_mʳ|HDT_Kg2$q꧝6wM^XhɤH5gd-J8N(fO많#X0:U"$8`S1IePFt3n@mԧ5(:]dggk[k1r6:;}힂s5ZE~O~G5ãOBh6X,V8hz9ͥ {ZLU3~2e <\aiuXwq87T*~͛?এ/׭o(*=y흝]]CR IDAT|m2$KJΥ3\:?c9N"Z擛IQ P{ n6?B ƍ8p Gtfǔo/ 8Hn Cfs,J !D.WèVz(%/N67(OIjxU*\ !r5>ٜz6]pRTL$b>_lc 6VZjkmuʽ^K,ht;2:!p0lS]CW#$H݅= (z}<w>6aD"SO=vp8r}zS^l4 /m(>(o.Al6W('N\ lZRCQdGwMrޜGN`כ I͇u<**\~ .D[(T*Fyv:JוI~hKђ?/[ ;VX>ꜿvH2{tBQҸYw󆊩oG4 m-xuT"w=ᆛkj*W?(O> `PV}֭[@ I`pg]z FŚ^V"L"#<_f2GqOL7ôBՖ͕< puBחU(]#uGJM&t8R!I77w#An%`jZ.Ny< (kk6W46͛LQF9 `2.ܹ/]:PEEl߾s6sb=?ok嵇>/x… #ki94r噗\ra0r9==4K饿ܹkr,LGeA'+Xl <5͹% z͛l޼V߽7G?^VNTbYIG߳Z-r'hn"VK%' I62HZQ1K(r5 X,| =ABJ%1"v{P({}jN+0:q@< {J͠ɔ.Wc]i혩?5k΍fwau랾k.p8T*>҅) 3yv-kܝ3W^_P(| Wm7xoAbcyӒbܧ>">k0000BJ>_HQTWkIà EYK^otQK9,ia **fxW/N \.O.z[`۶w_֚&lEs:< CƍdL?bBXRbZ+|EQ]]~y\jRlZ.J%ZZGe0*ަ{9^U>_ rl5R" %TfIqd*7ʽަ\ykS.WڃL_H$贅S.2V+Z tB!r(ɤ?EcH}-_gpl6;H+Rt<?E ôBH"c :ȶ6ڴ{oAkjm&D$TVb8==mm-MBJ&S'іw-I*)1C֫պdJ y}3Ό][R̼KnLI}>Ar =ta( E$ͫ?ʹEۿlNJ'kMlH$|饿}?]ry\5hbm۶;8~$*n޼͚'xYue\|Hx&<3MMeN//}ɧ=Џ~tdpepe$IF10&Om) :ަZbp8iiiktLYU5Et=#zdfdKHdprBҥRqPAE'H0ثRi4CY$Po*u|# Ld2Ts<^nT`0tKٗJ:Yb8^vOlD[[B2m=ɔ8 8}F 3ʩ&7~[hH$ofwqo2|ͷ5PBׯf:_+gM^hEG>;+W.^pm@ 3z?t@G,wnJg%/e۞~zN͕k[|ZZjj;~f] 39ƈ^tx\/cnkmu% lZZKQqd21Kg Úb++gŲD"t'FE7R) Ŷgq8.p(' [eevǑ+,)1LmmUZֻکnIʩn°F7mMT_ر[(Г)ݐ;-)"=ee&Pt6K?܃B`,_~{;:7p[u8 V644>K*jG'ZsO˗drvkGiS݊aGyN RlWB K{<8X,\כFa!%{><4P405TWrP04J[/͙LiBl6WٜL&v7v ue,:v H䕕QC>:hbX(k|a0=NE6η٪JYyKUe|q2nƋx{7]7EeN'IsW8gUS*JoX&S]wNKҚFp㵡onm' mιaN0WA"s`04Hpr`^Sm0X<@__kw4BQb lzc!bV&$=Gw%%zesG50,Դ @PMetS,T:4c)+l =fǰ&xGiqKNqQjӺv=wƛt}֛otuo\rY m6kGGW:TN/\,GEMSO=~~;A("i&uÆzݍ7^+"R˯z@;˗ӧV_/um6<7Yn @TVVn0fvo[kS$i$Z-( twyM#  tؗH>MrbNq%%2;ANX,Rb` 6OkV(&=|]JZчB}}7hP..Pyd]K{j[5Ig.~Hs7rY[n˽v ;w /[{,l탹_mÆ'_xowQ O۵kK-\>Qr[D0-w'zW^cH"I @;%h4=2{]~X ӫ8fwcu7_wݏ{ea]] $IfnWpAQNWכe2% I9::Z , jUp8rZPv7ȇ,N(IMM Z镔-J}e1 EI<>v71f-/ml<IQñUUxd'ݠvG[֬;wf*&GsOh#<6:԰y`?6rݺ's ;;;sW]\ w96jչUk>tL/EQT~E#Hqڐ>.Z+]WSk7mz#J=̺[n[2ExBLe4Z4p9n)l* zMȘR hyyFSJdKˡQ}|  9 >*h4 )RJK.WlSBOOJɔ!?Z&N\߻wkl>Ӆryr%^.;v^Xdj190%E/~i^)3gVWW7yZ0%w}qnQ?E\aim+T*<_N00.|{^xڵOK1Lw|`1<L&:;}]]ٞX,Zk`4xCЌ@TS3O 񦦽ꊊY(vw} lӂ{Pts^S8wKe(ԗ) sE,sv7E74잩1,u."}$buÄ^^y執ݶ-a#?b_ӵ߅2W׌EQh*@6Ktvutx'sDRZѐ4 :]V HwqFTN56*ps8 2,I77Z2t[[VU^^-m8bVkϼ 'jKZv>EZ?ܕno11Lw>;l_YeCprxK@S{{NJˇ?8AQ ǃj9pB!E]E!ȑX/4B&SVHp_GGkOO vDZc Sm(nW,t% ퟭP1,pnz^o2t p[+5in.] tw:RTj\9I{?f a\.f8.B" G("B(? [NNXc IG,],ժOG! 'Wq0 ws嗮Zu͟P]h;\>߽ Xk7û "Vs>qLD"!m0HZQ) t:ttj[OQ`` 88VSs'#ǾtzJ>_XS3D2-qs8U hF 2NU9P--;. r&nl;gΒw9 \._ B@,8r,(nGEQ[If)f)RfI2 8XOQ~r:Eѻl7p6s.uKE>Y: tq,\xL&}5F}ٷmaC[f*Yswn}>H&r*°̺uOp5\p^8Q*U]/ZTٸ֛?hsko,{ Bjg2u Ee}p8vwRYb~ i?odկ~4661O?97;5Hggg?cq{~xH$r9p$wi|wH& iM/ofc믿A~'~In} T*Fc,)ѱXA`@= LAzT.) D"!8m ðc&d*'ɬuxn`)--ǰñg^sZkTt8ɣ'6D(LTV몪fB %D"HdbL ~(H.ebH*Hd"R ZXO@iӿ7mQrٳ0o{>RQa^Qs%uttQp.͛=u EQS*!!(K|E'Hsnx ݃ s`0Od<'| 3W;l_Ywz 3e)jZTD"1]E? JbTdrwwuNBh4Zj.XLu:R mon03TC +,e2^GypO$ ZlhmmB\TjPaBt$E@4(NN2J8 z@+3xuV}A 4Jo??ڵ% IDAT޽ow`>䧟~>j3 a(F 7`E02OujޝVL%BTRijL IPO tL?Ezdpk {&D3͇ bzRKDSӡ{ġZՖө9H$z--i,^\^RZjS;s޲tY1XV}p{ȜkQ*}}m۞?(rHt;|((*I55ϛ7!ͽX,_QQ(U*s[sJ<yHTPƍ-Y?L˭?|D"^͛_1Bgvx<) qCTДTH$ a:M|%0{EQkx.Rljb{b3)JT0HQp:mHsRTq؉ahEE+eȳxs8Ouxgo^znw8NQԟo߶m.[.߿r۶=]w\v٥dR,oj?ۍF#afef+Ogw$rq<6U_w˖WyO뮼-f_|k+[yͯի/δ3tLs )p fp%sk8px"T,DR@ C)(nqx)-?.KJ*U*mgM7^D"im|.ϘK.[ Gkt's8<{XyE"im< M,T. %LX,jm`:տ+j~386AEEݒ%+`00|>o{ b$InٜiD"O?$IHb3'm4E H_̆өj>^]}w9|I~)7_Iy01n0e8ON:'L4 !(//mo廊4koD"ڵܲUVfv[S7db؛mp%\lTgg${)h}a\ ,daMsɒyV=p/D|>S|D0\+4}>o XMiII+iH{VTY]ݤTl6Soo[2yv6PӗW40:' Il:VgXMvtcżJSD")i98hu:p6T*yŋ/ll\t/+*,YuyB'p I IDQ AQbABE/x<^<AgSS#jyyT*eopku4{UU=tZ򪫮غ kZoEߜer'뚦9#)|W/]X"oڴg:G/r\.Xd I DJ4Dsy.{r*q\&Sk4e2 HlW*Qdb%Q sA-DYl6y K0W"WW7FQLh4eR=>K}8T*eN+O/Z8t]tRš9['{xnK̹ƔuF8;6n, '8>V*JN,1z(}s\qd2{j5xɔpp0x¦EwZI$&ۏNjfA J1@H*gn7 n~[ۑ;0a5G<}}$Yl61r<6K ØLzE%x< %x"O$x<'T*IQEQ4M S) Y7AE.;w-򦍩[oZmV/-$|(Bo_z˖ML-[6=AW29ghf)Y>Q"0!'|>}*2si`n-d}vwf]BHlfslpl6 6lѰ P  ) .WTT%$^p4I3Ajjjm1 nV(44MgD$64,DnW*UUW7R]htUZm9p880`M/sR *p8d4ӚNSՍIgQBxBLzدNRX$H$X2H$d|C7lXtvtޢL2uȖL"@Sq`AӀq(3X 7}4 o p{-7?edv>0(8=7j?G=4(,}aM3" AIqn"b !C B((C`Aa$AF8F0+޼& '[s`EsQv(lp*$q-7ိh2=rOX̟L&Ux<H<ǣxlz'͑2Z.W(H&Vn7\2 IB,q8$E]yAB#9:֔Vө'f +ڪT*v${B(*u:T*Ib"'f)\a8 P(rكAo }̲ [hRY 3>wEttt)2ER"fDBT9.)ןyp&ر>S03ruלbw?Jwy_?(\SRJ*U "T*tڜN90F\'**jKJ*FCmN5X,Op8v$GDc">_ z[[gTVRCGTV8IQdɣ68U^#q=z<.s嵕 ˎyf28x%%˗_yd454>MvzPxv3G5˗n9s7 p "(`M&s..nE0?e޼f!I{yfE bQ__CCP(8j5WϬbz7_\zaX,X,Jb0?t~p:|>P+-.+cNln3MMFcW.mml\b΁c`EEZ]HZZ^f IvY^)G4N]fso JF&S8θT|.8}3.5:9FSpG>(ion^\_H.W)$U@ 22iꌢhf<EQîI8 vv{eC-uםX[~X?Ɉ(8Zkhs bKRÍ oLIq8 AH$b2Ϡz]y>:]EEE=d73G,/$Iv$hm=W$/0d5;! u$nm=HLw8 /+Q*D"n6Y,Ƽx11.rF0&mx# 6nO?߱ n57/ bL(/:L:.uw!j啕 $N==m&S$I)jFcЙA: }"KnAp8rx''<^*U4FC&Sn_j4e2 M>sptǕk閖BJ]vу?/+ޮӖǞ{zޫX~}Dװ٬}|񧣺ͮ Npn+W^tȱ˗wر7?PUvKii֭O3/d=.d;ᄏ[[2ot{10oHH$#<]f"4M{<}#9P쾪 .Xt]wǙJh4^G~9gA"@,|/D)TIQ@}>" !T*K&6Kis\ Aʊ:E~_Wױ$Ɇ:]e*jm=_Ȕ4i: nALir}Uuby]|6L&O r֞'+HKht%8N46.r`ggW}Kl"G|闟~; VpY(++rB߸ܣx@  ,YIg.WєTJl6fth>yr?˔J+ٝL(IӔijjtUKr:S]`hbL`+Wéc.l,Xܗ\ϿiС#޺A.93uW^_sOwƺ-]C3. 0 0EX7\~؉ nz31mLǏpuX,4>nN8N\68.e$c3uyѰDP}EKJ*kHM``>^u NEQtvou7o$r8lYSԴ Hqb_sRJlٚÇwfϨH[Z] rʕW8vgv7f {K./P=WS\²P- S@Q.0x IDAT(K_zo5T*J%&Tw]w0BLÄ73QhH|&y_eLݙEqJJ*52 ls:fܭj5Dλ|w%x=A6[QQUUW7^n7;p88!e.7CQXW9@"9wVPl; pDG8 7vݐyu%GV5ꫯ{,`6}4u0 #[>߷.RՙXD3l6% GE4Ť`aCQS@t:JStd*NQTiLҩT2'd2L& %%ee5$Ɂx].Dj**qL&s1@ jl\D,v$T_VO>{o#U*>1kX,+/Jxx}5 %:]Fg0tM,P.g86:ʼnjUU.'ˉ HuuBc--N"Vt(Á,B(k|=N0L=;,XTjDo?/t:e4v$RJLUUU_UUH$A}>wR@*b6n>WZ8{rEktAsKpOp :L .XUU vEHBa:5\qB-/)rh4b4X.PhF.NfsO(VWWTp> Pzxb b\o IN2k@$Mii\k}I&~Q^^WSӼtr}cFc؃ LTJJRS*u̢T"DP0bx(X~]54,,)otv0'whVjq*ٌ&S$ |QuuT\иӒdVV֗)jo?z4JeIMM3z}#O==u\pJBQ, VqV@B::y9ܼqaY˕ EA659uqk?1ǻ;o\bbjR455lv  d%u뮟?ڵ|?X'DB`Xv1q:cXkkGcc޽bB!X Yd{3Wp[w[.=08VeRIr X,A$#R\^ߨR4󹺺NNR8ԴD$b'iLJME ʪ`;Sðd2n 3Drbf9\}9vxys!7_ ùϳl6;HsӫW/=,'IO?YRǤR*dN]z}+. ݼvcwq+ of\d1, =01?2ыé'h[=a\T<~U*AQ(ƱM"P(?J.|LP)%MP(e\ f3䥖T@DMEf,%phjZ狙ʼ; +*RMFcf=;$LOlJ ]KĪ"߾}(%**jJJ[xr8d6h4͍ߖHę 7\v{_kn:M}vkݻ_it8,X,RBTj++x<x&kEl67:k:p.Դ ::UC,UU5`[eAJz}#Ifs3B8ZIo0= $I: Ah@0r?ϯPOz/ٻw?@w@߰aƍx>DyG3p 8zo5Cò{nFQEY-v6kkxwG1}Xl\#kR%A4 )*r KT3e)u:=åiBBh2U@+%C%au2)g`{..W7 Vh잺 EQ}}FcwIIEyyFSє|vݜ˪NrH$kFm{.=PuUkϟbRi?zD"TWW]i'\RZ,I@Ȓ:G"f6Pp83enrəE)9gAQT,+B L<8huyLʪ52ߙi 'ǣg5t:q(/)2F"IpDJDEEJUx{{ۦ¹|v)<)**JEQbn$W'&V1d2)r vM]{yUU%.q<sih{g_aCZ(3ׂb8pL%uL]]~pyP/K\鉽Ri:z#gh\.8KB+?R)\ 1-j8yeMQ4 \.Oee9M k>pMHDP0-r`0A /^gϾ=]]R3U2x<^4:+ӱ,c9~DH$Fp t?XbL&/jo({$IM[nilGy,9,q}K,&r>*,8oSs3ɔhC"fureb\&SJ$ @̘oh}nx HLs8<2y4$qX,K$ǜγ_ŲEF8֮=jPRYYGH$;L#IN*o0IZ^DBrZTT:ZGӴv^=`Gx9|:<ԳzK/=g;p(Oz z]楛6 Bv{G8pK/y晭_|Ͽ|_\.nw ?~ /'Iw ^"tzSO<@l#~w~.[v^_u?Mׯ+=\|Epxn!5W8Θe2W¤ {)~ ;[25@ eb\(r8\h MS>t^TRJ$*\BӔf4;=JWW7Apv8R}EE-MV!AQT/khXm6C1f7{f{遉x[[s|D.e"^%`0a(F#D,SYFmx/AX$_4-9&_!d:J\r}>e%IvIINWbqhwEuu  -EY,gR<@ UVѼ NWURR!\Eq b\, RT)*h0i`2T:Mt)c&_|h4֮kySF<w8iΞ$C*rMYF(1~$~AgSPz2T<ް^yҥ_V{lZjUW]ukQsO TQk"9276eKK$MvuL& BP|c>!)=>uy|) V-T@JY}&Sos1(ںAޖTOܼxCy ZZZPh( X&͐cm& Ixoo=Zdf(y<+`8A$$IPC #`d6K,~s,:Sǜ_~UHtu߿o;;w^f?R)c _bY<8~@E }Q4Nype_aO'/eq\8+SYm,2.03r?ܱq=Eg69>'`'L&>'> s2a RR-W(LИ1{m6S:=%iY,v}LNS==Fcg.qA5;(|aee=H#*J6dc5 t:x\7AE.;w-icۭVj_v-7;d.//(JW.xF޲e-[6=Aa&r$!GiH!j9,?.11 cY~7]dn}9ݛ3wY Y,a9\p<6a84Eѡ?^ zc)7"B*q.ՐҪ^W[ۑ\TWhdk<ڒ!ZmJ0U9s0E%u:=-OĀnذtLbcFd2p8Lhb}}ܰ?/xO?e'^UW]<3|z1. Nsm ƶgk/+//ąìn`_L"xMR !q H$$$pM(* zP(@8F?7D2FPdl1 ~:E L156.pĉy)bY,^<ռ𫫛\~:m-#_AFX&_g__v4(uA;ct S%/`@RnvÆ\.@CO= E^xv/ܵkn`p( :c<.]EQOl? Ks_P}rF{ ׋ m <H_APEQ0Řq@Q pH0  q0B8|~mH$bH4"h8 p8Ggw TRuJ @*ٌVO0 j g’&0rBLBє3Gt T '׭=܋4M5Ƭ]np(gD'?:y7x+ߏlٷGbQ$ >RxT* @ $l6{8i#}/o`BҔ/uo IDAT>y.菳5kkq;y^rE5װz}0H4Ӟ1$x< x"O$x4bfzhS.$2cE׬X I&T8$sra*4XhsDpªU}>GX'b#[MSĤ(i)fT*NEd:JRL{*L$bnP$\#IE4v瞶P(_ tOO؝Z*dno?K8NB\ !TtJn0to&LǺu>(@ F3Fo|m~sG^TPgO]PY]X%K/+2^X,X,|/]~exO>˾~ol63s)\w5矿}wޗy/F'{XB#R%-u ZAt$Y55ju)ntvs 0=W,3jQ|Yy<+O>{Wk'IV ؽ{ό+… x`O>{^uڵxd2Ɉ'qEU?z@[}tYK%M5Mss%qOwwӟbǷKt:Dn}:Hp=͖'x]w R޽7o>D{}iO?Ɍj8NDRH&˄B1AD"pX'|R¼E1@,D"H$pN-FvnG((HHZ[;_$4m{zZr!,/+/===my JK1 BFcW.$ɮt)r/RddOD"a2n07((;wv-fͪW_pٲvg۶=KϫJn'۷?-IS#`V]]3jU7c':]J?;9"o6$ɵ^T ۶=7 7\P("vQEQU&:kjϟ7o^3BW1{&,yu߯(GQ*|ieB"@,|!iH&.uy.fzMrt;;˭66.DxP!*NP4p8̃&'Pt^{H d "6'+AAi,r܎NPo\hQx<ۭӕ펕+/8xp$ٳgU?sSSc[[n--/L&{g\d1L Baݾik^^UU Lfg08gJE#!Lbt́2IR37tj}ǒc=ay ;>jϙ{z%HQ)\;`AE zUD/*^łr"-4A$l6e{9,K!l2O>a̙3gRX*h-I9 ln[NkOT^X8B^Vv灒@d~hl(+#| ;H( JH$WmޑĩcfLh`/p-0ZbzM: [l{_mWqsMVxS%,BWv?<2oܵkߢo?Zc ǟi'0OYNhn\. BN-P8==-//7֟z{]`t/DbT"I$2H"I\0!QTqxNr9<',Jmj\#VZPtÇ-[Z|eel*UJzzA Xۓ%ڴ!A8y{S[ypȎS .dM3s"7 MO(⋧ǝ:uʺu_VjU}!//7;;rhǖBFGt3Lx9ǒhV^s睷kFRǟuW^ZmZ/޶p\W}^zq8V*+W_6-Xp^p8CC[9>^]UóT*xv9Bx@(H$DH(q8nKZZ|Ns[Z|-B&Sy`^YyjLM.I<\MQPӓ%I[TQd/i݅\pٝc~8λ ]=Ǝd|'Czu r~wܹh4ϛw۷~_qiӦ9r4,!C`r&>m˓e/*W(.Q K_&9N:|6vʕ/?*I\nk!Vsǎ.17{;qi7Rɒ%x<^ pr8IrHM. |>'ry<p8v ^S~ <> "yJ?TI.4#\^o"J$B⫫QD"<O]]çXzɬ&>() *-̕Ȭi 4wWviӦުH$rgz睵\.p!?ҥOo߾WW/`ܸ1%%{?qfζO<WP8z jԉr @y@ : |}f̸]rul3T! B"D$B*cn+OoY( ^+ B@ki.T> Df d#VUuj/Dee &Y'QjjVjj`46L 'l^&--chjA.  Ǎ$IP>h5^(+ .8ff ̕,4w,_v}G~qs:/f[c k43\Fo766ƒs+LzY766edæ_~ْS0d]]eNo759gt|MDBQc^vǘ˜"p4D" #h. !ZgBX$ffBZ֖\'(/(,͆É5'bHjk}K%P,v%࣭K(5UT`8blnљYJ]_4B܋V {yY4Tyş /."8Mѿm8h12nSkmLݩ E݉wf;sà}ǢE“kyfИsOQ''| IbKo_s_IH$)'I.EEjk{;Aم8vd:%33$IR__ݓ1MN't`&VӮ]yxYg漫lY?xC0Lh%cs/=`#'9JV tEʾߙI 3'af߀(n.3 E"Qq$ BYX s,Ϳt_!.='P!@uuPջ$ZmСg p8xƺ8$)P(4h'H.P*C*lII6s+Fl-ORqy}_֏9't@Ka{ڵ[={xvɕK*s ?+,`f7+sFniӄu5o.\xOs1==WbIϖC/_qw@w$t !txܵk&K >_U= M4 Uţ T}}UUՑ/.rٍP+I57̹'5OOx<~FFnFFL@h`r8Nbvp"$|>Oya)}Ѥfe !IU@ffr ޿Q "cMj+U@cs[c(/ZX`c7fyX ]HO?xG6κ|L(f;R$Iff RZÜ^0x3B@h}a;V9q#yyhkYu j=K\ڃQYi:bbNzVH+Wb٨qw6d747?oen' Zv3?SO`5wOp:]FZZFJݎP"\^^? > hR \)IE"ivvoix,Xޭ5O|_ry?KxrnCv/#yv-_IjC{#.}7]ywh`L0Ns1ٝ ʣ#kh4j;NX%Yrt̉e݋0h@wx̴lZz͆&}#+?NmsbRMQQdj:ᒽ!.#%%!0/Hɒd98O>`T`t,,++i鋡dwrq޾,=dѡ݅ahQE"tLRCY\uQ^^qVVAp@eSqM*%7z<`儇x"P+%OOeh DHR$I7>VQ/}g`U#gN<<нH<թ:]N&75FMYd2E^,P0RSPwj+Z뫍Ɔ@fe$tkpӖrs1\pC\\M7>ܱF ,1bM7ͶZm*`h+[VGQ/[bH$X,Gq|s% X4w]vT죖CrsҎ)ÓIFI &5%%CЉpssh4'6 &5?8}USSn4{PNQyyC9뮮>t !*& ͔|7⪚N,ZϾ/=p\xtvm8qF~JK %Ebų6c/_e2Bw}Ljn< ؈dssUc%w9o*Z򅾹vnEf&a3'6sG ) \V4TBr;[,M&SiKy 켼b !L55eV뉳 77XQe0Td<ՕOK$[Ϊs 6>RhMV}{iy]} Yh4:oޜ3/⋯&O>79ԩc)]Ѹ\p8?Lܓ нa +3 rZ$Q(MJS(4$I~hlZ-P(ؓ삌<.1nnԔy<Ğ#JfȐsWUmi9кdFZZ6Bhlln֟wKԖl&} }KzPee%%Dig6z;`r"G=uB>ceV2XEEp8D Æ ?V./8xDs'J0L,H0s&OeqN9 Hɔ FTd*X{tyndl6s_r"RR2rrT*-B8 Ԕ=q8Ehm:cm:}X,DB姞%i(  }K᲻2#zqD -[ f3F{sssj5=O?O;ĸqcKJk3--uŊUuʔ fͺX7L,8vNI& wqƪT_^,\.O"+*\-R` !\vjvs1BQVVAVV>/dj/@q`0taL17l]Jo\z%}{bA.j^'+MZRӦK'Ǝ1&zlLI,[awg1iXHXy%B DbP"KbH$\.1VtNuCoBjuJff~JJIn54T75Ѻ6"553'z?{P,--ޚgaI&b:K(5UT`ݿwkbm0ѕG()1@>>lg)LYXS$gߛm{pp\%-P|j 8m^q-$wx~IO ujQg B: ox>v6iDLE"ѹs>xVM&z<ի_$Iͦjmw`u.fqƮY>ׇ4Ăgk(b!!Ip8\p6\.p8ޖ_ N\%I  U 5{B´,djjJ{.K p8P]],;a%[ST\G_etL _mР=[nax.ih1AcȔkn"8T&k~S` tx@Qbgsvا4>uZn324b@_e~M ,<o4&33{ӣgIɾomc {}_{wJz[?"]wݧVnOKK/C'dBhl㏛q3=ؓtammŏ&iOjnӁjWmƌ"_N|ƸV!D@ {B@ [@ !PҲҲ!F#&SCcc8 =TS uu#ŏM`25,I14W\q$Tpѕ@љm7(X.ѕ=Dרnk9(H#!L,mz9rwMdĶhŵ?%i8 .*ȭZB^'HM tu!62Lv;F {_o()plnd$1v|ᓻ S4i"YXѻ<̧'ׅjWuG1F))LQEa)p4 áh4"pO$Vgt$Gҥfd͆:ݵC(2L`L54 =ʹy[$BRs$[7:GEg8; Ɩn1?D":rؼ+tH*S6VdKPQڬMStH1fذh4zfxTv)a>}HVBz}}ffǫmWaҤwyG]74sJ$7.X8k˖N&1;b,%%]P4A8nhknZhwp99iiv;z 6o KS}}@0 FCo{j|5@a!T&E2jk8qD,υDW`nVvi_7漢 `覢hDSbtaJ>Cȑ#>;{ܽ\e {Az}rYMMI|n+pu͚ }g}ٓVtZmP( }>d25햁_JK)pf}N$ 2B$BRѧ]eI>cM.#N Ժ6 3_NW&Z=|]yJym8kȾ .;=CNh~`ϯ?ܧ$}-AGSOZ\`/..\Vs'a&]Z1$愴pZj itw?dRcʚgsmPT5yFjjH$"I}Y`EQt5$r5BGk4]p82]7HTU]9Ꝇ\.OҪթjV&S!p41-&֌ J`P(Fuueu=#s22BK^_dOo 7q&g%>ߖų`{N?,9nmb{FhoؚVLxd_"zK9>_K?g?{ڧy۞O*4$ٹkAanNgnw!T_ I|^(D? W9н8}MpSiogꚞ4^\\hB٪i_ziMiiY"ށnO>N~˟XzfoٳFZ.=ģ@ݞj\P_< Ȣ]l㧟~0w@`]wMsQӾkUÆ ?V./k&ZVR \seqqBO=lojNNQS$Y[1v:6djt8I/ +:h4֖ӹzH$)(!Ihm֧]eIbb :yyGXWtɋCologx84֙MRpm&7EQ}umR -jL |ERQ<9=5w^b>tI,_IjV nl|E=Z.i+g 3Mp3]53&0Np4wwiqYN\]]CO畤Bee1t03oޜ>x׮=cǎ7o΢EKҎqhSgB\v%w}j^{C?s.=_]]e4X'R)op4?~mݲb*鴋?FwSݒ*\TjrUovf3l&40)LMA\.[U_>_}t6ogfAYMuuZ,DNωlMk7x~?_P 7\y?_WZZPkVReffݻ!8p…t3㲚uiӦdR@tvx_ }=ZwȐZ%%x`D"z}.5j$| ["Fp½=Jpe2BV( Z$Pb1Z&r٘#\./; ==$U_=wP\XxH$DBG?k8K1%Qnf8H5{;xT*Ag@aFi9t3K$Slݺ`HW5wsE~ u4jt!ecáVXsۗe@H3疧^n4:kUWiˍF;.YӬ񳄴1֠~ %%m~7NZʮ1=I<zЧxT.*RD"Je< a Hf3:vtzcp8C TWWpQIyf3֖E"}r:Pn t n/~%3&40Vp w}y&MKPGC_I"ǒ4d&M@״Z9̒}CYYVWrѣڹs71}t֠1TTTsϝJ-1M/vHC|`0$/ Ó"|P("T,J2Hm}q8V˰ddegpphSSO%id2eAp@6qW׶anك:̉047ۖ+=r{ u4VMT$FBJp;|믣q` & o.^f`_-]ذal6&.)w [nBG\hR/*Tܱ8PPf͋M wrwp[*x!Adffgrp8T[[P{R!\^nnN1L z=͒hXˁwbĆ$$PpѳAd++hcٳk5uNN6]V\W:8n9;w;vl1a?}tJr:1x,XVNgL 9EQ*N3vw}n_X7x [n+Ǟ-^(nWV<oKK |'W:Rɒ%x<^ p8A$rNx<.W!-\n C^x~mi|A H]]P} (5537$~/(Q[9+)]@w;YUTCNc>?K EӦM CMMt/:oܫ>Pwwy1cF^Xb57Kl3aN^ ^$pV'']@QP7`ƌKoڕ+WN:hZHl]0>Lf#LoP(@0[@0~/|AvvAFFAp(*j0T=OH#I ΐJhYώT,}DN0][͕ D@ףܹw+y鍲;O. ?8|}>v4SQQy 4fYT$eaɪl.NOo759gt|MHBQc c1EQLD"HP4 CH8 á`% 23H99E))p8X[{d(H]LեP ,]'ZA%ew*gC*Cv`37$DshÝZPFZN/tecaI&N8,$1}%۷q}ܯ$AP)+OM!]AUQdso1`L$I0;V$!xw]D=Dïf]\;33 d?.[2ڽ8M.BϱXmkԳ \ nj5bTU#D"i4+(j "b K(5UT`ݿwj4',,=M+eH*?{LژC'CfOWZq:ь1m/?vW緺to|>NȐs&cqe%%7mڼdɃ?s‡齋/w%sr |!EEjN.,̇xSg5y{~zeמE~zB%>dDe`nrr$_ *UhTVVJ9ժ^{;V>YgfգfLHrݕesoSʆϘp]L !IAFV\fCCBZmz^^P((Vb]Y"68 ́_}xOBmi奔~lΦ0Nnq@C sH"Cb+kWxy;٨qw6d747t-'' Dպ63+>TZhR67ʃA66 # In 4[?m\=I (Zwm['PrmC{n@Q~Ca] B';tG in8&Ayt",ݰl̉G `BsA)l6!`KCCms>DۡRiI XSSmoFm^/VNۧQۮ?vTB@_쪫o3iM_hFmvn!ܶ7V?ڃanNuH|C1eebI,L&fme CQAE.]Ix( 5546N)fETbLKsMMiқ)D\ﭓ5O|E?v݁߾;@4֙MRpm&7EQdz'}sgڵ٧T[*3.E)o۶]MV: z̉Vd &]KU!!5675SOODjjVvvP(A$,%Qf?M=`n}c%F,X BG}' ?OMThpďlbX$Y,헹EFKbI s575]`99mciyܽ IDATCIpMNѤxnlnXngB''##7+cM&^_y,,}M(7pJ@;bqe}g}ٮ<}mmc ǟ*--݊lv>1^|dB}#F s=+cnK,>1W]5;Vr?R)>+_He3FknӐ 0ʙvU9٣S*5*NjڤM&h3dgdd 5z}U0ؒYXrs2\pCDs 6>Rh |>z޼ۮ_ks ,XP47o̙Wt 'ߖ嘷ȑgN+MrýȤiVs0 aW&^ӂ$*V)X nbi6].{bR<+ %% p8XWw6aS ]\t/NwzKpcfST!8r׮[(3.[j)Ě-**7!!6lsvH_juyy)\jnpУI%B#` LTjjRr(*lnv:m $IfedI |z}eSS}wQbSO=.He+lqzonnZϟi77nؒLKK]bb2Y.Vs4;$_͸qcU*/TTTgNP(RR&SH6c6@ 7vnxXE\lY *t$$%4 `o6!`y}BqMOݾ}ǴiS~zTմ``С241cFoC6 ޸K s572U Fo,I&T%%7mڼdɃ6 T!)e2D"JAaviv&BP(`0h074ԲɶY;Id/7U0\v]MccSccq_m8^t:Wɓ/HOO[j9Ij|>:2H$Bo`~KgN[P+`㘅O`э;nձ:ery"X(DH,?.CQQ:\.x@)J$lvPm:`aD$P+d [@&|>:rĈ&!D:?M~^}  䥗V\5={M~i>i6U _gf/Tm/+yCU^LyX+2ˀqУwgt/Oǩ$ry<BP,KBP( $IƌBFnvnq||%$iiii"B^_n0Դ,,@Ýt2'qyܵH4C4jv#[X$l6ǎ&M(I}H$:wÇϟ?jdRǻz+$7XcٴZͶmFl67n5kNq};n}*&;cyRUGU#ǩwL=ӽ2wCQu}w$>E@l Dq8\. |Z[y<>] c!z D"--mi|ޖ [ fHrqlnhjZ1ƔkMuZ\-{]F.ki8O_<;6i1!4w?V[J4>|Kv.ٿR^o u}j't=trnL& F]㏛q3=ؓtammŏ&0`0m,Q:Z R# ôYZ"Z0lZW{L)Fq4W~_o.۠J~p1%a0Uj_~#B]1ۋcPF]F$C3 áP( C ~CxlB S6Io67E KB?ST̟Ц)b~Tiv'nM˃RN7fU6Myác_)vyb*Ԓp(ҧ9J;H1&??3F,ZX$:+bſzl86/6DL&s|$/bP$m,R:г?ߗ׾riÔiVsSj>_C_;dxb1xj=X?⟿=?WOo&`:=.Pj (Ea0h0FQGFQ`  P(óyH$2&MKW(4!amn 4+ KC?R!EQphjr{oYxԙg7ԘuGkxΝ:l×9wVnk1>wsӣpN>Tie-Qo?O8CnZWS^ 컋R ̓ݱqctM q4 }:2|N c3n|nxygO,Xnxᒫ\yyGa@a|%#tʻfBEE+St0kY"tT{>ҟRt:;NsÛv:=D;ts+Hxh4`خm6K:.CMHvۚ OrzA?m+j<_9&Ohĝ3^ BR螥^nhRdd[98=G]]1;rny'9htL:>[]b7 xG^o0ݩf 7mڼlRŦT*^yD  o{9W`!3n_1;7EOmkMXB r"D"ѝw5jh P護ޭԩSnf'MuKv=ݬg_~ٗ=9:]VTjWHd2LM]e01~nYڑϿ̫̗ϚP-!ƀGe5s/ jWM4ͺiX?te_ݳ MN. * ժK.7ߛLv%>t@w*y`oIjq$IZE!J<%N/P(V**NMDt'rX KӶXkߺom|`̤8 I.w/G鏻~9j3Jq PemBta(!p_WgQFnb| 9gtMM;t\td _79н8hnH-6snF@ @ulmy 濫ԤG{ ~vzN6btΚ뻞 gaCxZSo(<3͍6XZ_zvFq*=c Yib6k?0v٫V-))w79 X>Dsr@{n^hk h;^L)`.{ ˷hZmi{=Q$$T* 7NIԽk=oYf5R ժZáP `֬t9MMMihh<Ώ/{0X,[^!]cm[vaeaa rȅ"aC5?{WFB $ػt߶2N E\A@uKny_WL+X٢N{_'sI=( @AH-N| f]CQ Pt(t n`jcyVлN?@{N]=tZDFϘ1}Ȑ|(*6r..hC_zi8{,!r?Zm 1'{Ȅĸ"BH"Qd \)(b)@VƐl,,g ᨵavCט&gOj)c7/5݌ P ŕb]/e7 Ы!+?<2oܵkߢmҴbV{~~.pFpn[*x<ϝ ;}snVgҤMV[dLو,jQEqCe* *xAYG(mwfte!:&m'>7{IZҧOD"@ JD)*WK˹y@}IUuYŮpCs8iP{X.pKqFDXXyE\'v>T$ry^---w\C@ӽF{nD"t˙3gϞ='f^C)`…B >˼F}B0 S,@  E7@ DB>_(x<8 ,k5`VLsblgrayFRYRzLl,V{!ڔi*m8x5_~MNN.L8n˗1bcք\_j[qj3ZyMH Vd2UVVLFh2ʫ+*+p>BmUbhqnԼ15zUUUo_je)eVbel)eXj2fh0LfsMxmX,;B0Bp@DcKFAVa7rq]cƏ{ {li~!ݻuvqIu1qlY@:Bىjf\ʿ8Хn]rvG.KۄHBmƶ?п_Ltʴt $&'&&Vڙ}mOly\Eӕ:p^F+vGS&sv/aH#}jES2Bu ,K/^VTTl+ݵk…{oyVVرrgwi\6*ە17B!Pga['G^^^/j7o_jNW+;qgo0,?Z%%%3<===<}z/_^*]!B- &XVFk4 l=pF7{ 9o+.]>}*0#{7Ț4iaTVV7Kӳ]IIjH!axO.3k<7Btv#pjKmBJVlPJ ]RRRYJ\|fl H&NoŊ5Çck6:{nnlJ;cY:]P(%xŊ5i-x·17B.͌wsv/#UepvBk!e4?`9T=jV5ח;={O?d2_޿ӧi3((pٲjf{&Or%!Gk3nm]BɀCPJG}x{o#G_R___.>hє,{_kuS5qc[m cn\_'bfj3 CRcXRJ C:Tȼ2j!:i M[.nٲgھ7;v gY_>ed6+x<Xb TK{.@)ev?cn͌ƛ/dl1}0}=;?ʇk2U*WNJ Kuryϟf*|܃7,WB54oQZX\YY-WT[훟&={־}Q ~P(//>Z|ɓ':uko }!i|MFT6YU{~H*RRJGNv>TJKYۿ9׳~<Ss mǞb;zP.G!^BPaEmwww//OF{ct~YW{ ۿuЇcn68q~ԔӇSCe!?']EX @䉏 v͟sS=FStkdyNc&<¨M@Rs~=1s77<9\Xo.Ѯ}{{+!,x{{-\P(4 "O#M4^ՉD•+7~qw%'O>wTSUUUQ-eΜ|}ez}yuuuFrnqnX^\sko.W`{cn"4pXڔ{xwpl PQ^g IDATPwɒZ/҈7m_<{9jb/}`5\e)ݰr7'Vx!e)L/&''&N7sxyyN>孷t%3g?~٬lVn6iXJխ/u`,%{^~Os_ώ0vZ_8|~PWB!RJsbww7J]weffi:J'U]JXn}Gs;]9/0@8cS+v` !ܞ]I'3"cc? @!$+8.7k!aj{0FY05%"aH^jʡg5BS2 ?~ѣ'(2M)t>>hKT9/2 \wA+/?ؽ~n`YR[d\<\#Bo}U\ʋ"3-UWe|>{x `TWbPۅٚL=sӕ^VBVdS ut%wpd2Yii]vOoF/g\B&NlI |MF_aw"7VopO#ԩSR?oTUa_ dhWu'#r‘+=bg}i] s%oV{?=qɿuZnÓ.0Dbsss+s#-Ɉ97UP Zu9Kx@fBu C 88hĈ{***?xo^UU-ZP+yV}̴Ñ  _Bﰰ!s:tĉ3dJqls#B~ g!PEnLh4l'oyzH1FȵX"ޭەݻ ns734w˜!B}4(=q,cn\ OIǖduBm293'ٽ0Fȅ4we. Bcn\O%wc]~B! cn\O'bo"erCyi:BØ!i2"d:E>ɏ*H|=*>zw!rsќ)8!+ЀhgwQ0FxpN;0TaO߻J_R ['{+!K5{ZYyOlؚ xbNo'}%_/sϿ{VrG SUT* Gc1S}aTA&tmyOzM౹V𞤱񘘞!r-)ia79 OE"`i J~=Lf;ΗU3ptܳ?2TC!>Ͻ3~⏷=H*489T%O}r CG=;icdxs&(G_ ku@s4{o\&BBW %Rψ;.Ho,'0DV^VUYަKQE2\>Ƙ!WD)]O=w:CG&M@YJ f]%t@B*,lr ~P<} t ]t+Nƚ|!FC7U"T\! xf K=ߐh6Y}ĿnL%]bZ~|]UyVYyg0C/:q*C"e0F6{wn?!M=F)&?^=3=qTýW?\QV..Zoyؕ 4r|Pas#dVyuzLd_-qgVL[%؄_r~/P:ugxDeAM?TsGӢ rLTul%m+Tl\wE:ydՂ !G$M9`湄VYƵyPʸ>?/pS!Z~+k@[\^!/s2Y@"@!~*0-keA>:$IyNّWjr$7` !WawW @!?umǤ1=H=pT,0?N:> q\|men<7B.*Jwv/BuX7,ZE%?5\\rA{mJԓڷ}_=eruK8ϝ3l \B&N^o#"~߽ٽ@,.~P㉥*hmMyOeyuUwi MK䤋r ZMsss[ֵF!,{(jNP\9!Swұ%Y#P[xgRUpSG17B.Nw}(UepvB j`̍ӣn,gBȡ¸^4:5K#D,u"a@/sO#wկvحϐ@H%}#r禮Ȏ9+BSXX?!a!#d"KM=0(O']_`kra#[KxpZ;6či\g;_||زuA]M>i- 4c! K"jsިa̍c4{R N 'z_YM3 (P 5Ya'{*  @kǦkE8!D]Zk|ǰV?֎dQS㿮 GN?JGo(\nB/a!\7xkFS?NN r&F#?K_APmJ`) t*}h7_o!//>gZ{TUxʼ#|K}^)q ]_XtYI!>l?]qֆV2oRX;uk6J) /~aMa.)ﰘ4L͎?,K)j2Z ;lΛ^}l={-n F!8.gØ!u7wa{# y^bPMLMP\); f= | [psi '^;-_֯pF!j!a̍ӰPaS9dzʾoOT3[ֹB!!>oV1rRW[BÔ*N O-.H=Ms;)q0cz<3aB5 v1Jawnqn!P 񆔴Yр6~\+!bJM :\Mvsp%GNJ%`Ȯ]̵,~w >+'jU:BR;?Ce6qտ;CR_uH[kz>Diw#m!P]iqbva q[#r\doj96s#t{:=B&SmϽ;廃AM^]?Yi/7]Ő/Xڷ~aj2 !z]gxDeAM?>E]߁o_lWBRsW^T3?7][\ena[jfu5RB6\ٽhpC 7C]7q䌬#!H=urRMXh]!2d)+;;Ӂ<܄"~eu !r"s#Xy uzܭNڬ.R¦jطP7ؚ*Jc[B!ׄ17BwWc!j0FAeRUB!17Brv#k+w9!PB!j]Fȵ0ulIVg}!:r!JiP B!Z0FU0*E܍ !B:r J'bev18ǰ,%_"jewOV7ͭkB5 9RDD,{C Y+8jke`̴yL߰|O\߮wL]VRi0k 7w7Ȣ<k6LBjO7ȵC6$b)=/y:{ҭ+K!?q*hU*B!ny;sHI>n 0ۍQ*E w_unJ}5b cj C4'U"xU5C!$05-yWl1[ Kj,7%:uy!Z!Z6m%ږܦ 8 ձQ9*ELT!!dP~mϽ;廃AM;_]  }Re[hӊmw?>k6Y^eu5_=BօsHF+ouBڞz76Sr:1wQǖtH'MnI ܞ8-P"ԩͦf@BdrR]nm/7_h["CcvnBiܼv:rM[򕺫.P)n-lTmVWFc5T FB syM*#t-A*EKnBsZ'д#趨TJ^ pn^8jnkQst]Bud87.:)W|~\\lP`)))׺,Lr#Bpn^9vn^bb+H$Ǝ6 +** 00(>>'%%u Wؾ`tֱ%Y#P¹yNBy}N<)==}ǩ]G pwp6`#NN<2UepvBÈ%ZE}}Cνc 瞟lr^-œ'Oi˖¢"B`dJJY{TE`h_f]eӦ)]}:Lr ʴNB&ZZY3-a7,߳㯭|(5)o{ӯ/U J*}a]h׊ b\$3?}z ah[q1aE1wH7oX% j$B-ns7z+|{Br5ٿ7 e-l%^bPceZT6YT9%^q9{ZxT.Zqo8pDi2L=nxj2c(K|VxNUΕB{FB_*Bw87q{jPJkW#3zh{n^_j~x<Z&7/c̍(B} w5%P@IWQP.Z{9l€Pߢ\-`kOqSt{j2YpOeʹOu}ÕBHoV}܃ws?p8gԄG_U "]`[jrb"fF' _Ӆ9ڵooow!k! [p>=b49ܲ`Jɡ3uXl0*޹w<##R6{Դ[H$nnnF+q~駼{ǎ׷짟zw_MلxQ#ʴ.An 玥My|~;}W幹(ZP" r4@kڋL\Pv(>HEJKv5[ wK,ۣ~;|ˋ>6otTlן`^8~Τ~K=a k1w_VW[7!Ppnpr;0 nfڧrASe>Y:U(dYX`æ\'O#܍*+*.[Z\\<Z"t,%{^/=y]!z-?x~NXܣoęi{w.\sܗٯMW-z:B{_)(p7xܶ!5M=[,Bx 0>l{aAIDATϩ.<|+ByEW]ڲu48c{1|imnjBj/'D~kk@? 깜M1źE;rN+nQظr-sru ɪ[BrʬkEzRo(pfk3MW.{is!9Pݛ!RZr@r̶j*B>RT*}^TENf^իgQqbyᇭVm?.o&-Ѐ,eZ aÖc7ᓷJV-wϧTָK_٪R, J=˲ ;7jVUWh6T`>|r]_ <^߄gϝ-"3p{?LvQ*Zu&B!pn^ Ə;)&%')AeN<2UepvBc¹y-7Ѕbny)OO/JiEEEAaAfV6@QEX6G!887EVaY6MHS(QEؖ}2GBӊCW T2ByM_Z\b%BQEDl##by<&Zql|WSqpȸ܅v*~^:UǰVVS0,nMqocsGY/zDCQ * X H{@?zK~:̢G/2 r4]+lKM΋KkUzMz!y~=UE2xɼ r43猸wTm2>>:G!ܼto΢#SH7s70сӟg{;է@)PҙsG;?"翽v955s4{o\,KT={9jb/}`5pwlR?!g' 줵V+;xl ǿ;gEO!Buܼs:ꝊJ:݈u}}^nuͪ%t]v0-'NiL=Bүjz8qkfzK< GT@B9с?( z>czr-=7BG87Y8zQJ1F )(N ?M>IoXMгBXx!BB0\!>P 0BHYC V!X֚BJ0L^\C.rw4 ~j#dZ2li֑RiU*p +51<}t*}q!0l|O`he]B!/~p!z!{Ƚ="߰ ,׎R^Tly!0htlqv!@'czd^-H9r>0[c߸c!P[٨QcrS#d"y2nFwl8 RMƕ{Wo[IV-Z{ImsGӢ rLTul% !ynBJ 7%^ڳWoEffKnfd8wEY.62qUwCMKVz!C$%rj_Y*.VЦlb|d:um?Dx<7PR^ZU]ي;eh_! Rri"s䤋<)كnnQ%|MF[kRRUgw+1ũQkphl-.[P MCl1WQj K!C.x<*n9a^0 GEr伻;{=E̜; yc̐n*J/~?_5~E9 !mt9uQr7:bawϡd]$҂2sg0WWZE"pXڔ{xwP \F`)9wĹci߬C(ۋiY.][^ͅpwlR?!gS]/Lh0g/?gZR?pT̞) tظb9R46~$"Bcϩeh\+>{I+%t=%0-'Nij9 Jy+<{,h0@t+N"x4N}k{ʭG!rA,[oណkIJ0r[MDQq, ]ʁ0_ _x;~mLn[Fm2O55Ps_<۳Q*E0GWZXYYh[ w_unJ}5!ĶSc]p.z@5O)ex נ`5H' CBHݑR zB_|*#{@m7 !B5\sw9u'v 鬳m%R)"nQ埼 W}I|*{j+/0 t΅ cC>_촢WZ0W==I>2ORʕYm4*ʛ?ۿ0c,54>B!볟S҃GRB\B5omG̩@fsX3s=osmeI\L7ga2MnInZuy˴pcz' sbnS!j_G/tN] y&?ƹU}wnh3 ZLkp[H`U(& F!P\;: 9% [;aPLk:p&MN B5}~ϩ&f.p-FhEF^_m:#gޙ9bcu ONh{ BיYs]ݜ:f.zn\-ghew].3}Si&ΡM$ޱ0 B!\͘):hub0ܵ !rv:IsRU  1H ~~a7B!(Uepv)s\0ݺ,Y&UnƝBV;N!9O[ҤQo+7 B!PV(<]'l՞}#!B2ts1wnn.@ݯ=׉\K# B6R?ƹy-Ԓ\}MJ&['|9p#Bȉpn^oی-nߵ€!BsxOn?EBv6+F!BȹXM&sY׉\K#-*17B!PąRܼi<\!B# [#B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B?m\8fIENDB`RaySession-0.12.2/manual/en/images/example_session_launched.png000066400000000000000000000473301417052567600246120ustar00rootroot00000000000000PNG  IHDR1s+H pHYs+ IDATxw\H@D{ ֽ{]u֪j{o[½ NDف0HH~_|%On}z\Rc@t)&~s8Ph98貳zYD"h4@`&bcn\4P $bEDlHJR8t|Bәy Nc+~lVn]WJe[L`p8ڵ]_L&3sU;nvsuMLJ:w{-RRR~5;{ӓ;?W4=mʤ$e߹bxӖ-[0]EQ$7{C;u:vhׯON+JܵqӖjUN6:J$CFܿow&AE)S'T O?WϿ';wr'L[\ѭ[L|[8wzfϝqcF6mRNÆ'tfϜұs7b/Ub .mW'rO|˭_G<|TFаi23խrz}Z^n؃Yj4=k߮mݺt^0oN]۷m8xJNNYF5[jvqvf:J\.%e3f͹z?Wvi='O>ytGG]۷6=}lwQwˣ={j&&%~й[VV͙ݹ[` .o޲iO#"N>r;vhwʗߴaݿd\Kϕot]LJ7ftݣ GG >f7oݪQ:4iʕkoWrVrMß<ѻ}˗yxߺu[$-[KM5I|.R];ʬTzo^*U}7y)&&6HOO[8 --ݬ<==],1;w.YҷO@@7owsu}Znf⋗.GG'ORSSLV{p޽ygݵz`  WPhڤ$%jݪŷ*4m"S(*Vܸi Ma'HWwC4EQ7n*|D *IrQ}-o [tst*SFrߞ; nrlQӸ>5iKZmu:JM2Ν۪Mi4Bx^6o5NԕyG;J˦Mi԰AvvvhhT.1DRTL(3)۷7m޵74EZ|Śu0nG1 ;wٽg_vmWX}'H$!sݝ\yTԗ/_}PDdima^X"SEiSgΆw܉yzASO@7nճKW(rA7n4[ZU@dpPӧE>se~~~4~%K@ GRL&srrذ'Rg%_|_5@"ts3ߺ7t\.éRcl޲@?y<޽ktۨ7^x9l`UnϺއf\/-\.D h4׮`v5QuEϼ7o#""{A+QOU+_ 9z O{mM;ulۦ\.+dd{{yY|+X~~m}ߟKLLksOfdYgU^}ؐAz䔔S3'sYYWZ ,֨^-1)yXi͞պUKx9w~Go/^=w~n]f:=_M 9r0itEK?O~e-vcb/]Qv\;99}C$V]߉% K':z=xH"3dQ"xX$RN3h JU98ĢkktrrjzŐ3;uMJJruu{μ*"qwwWTX>B_?KB>@&!ØCB0B,1b99a!Xc!rs!ØCB@CESt4Ms  V!Td8\R|8+@|Ď*B8$!،Cp0B,1b99a!Xc!rs!0D}nFDQY!:@2WؿRSVTӦܼu[~!L\h-tnJߝv\׺qA"9I>(;G$R+pp%'.?/ !լkVn<=xvlZdT*}RSS x] T41]] fq!"m,dH^'l|csƌ3>vrrtC~~}{wEPh)ne8̸F<z``]6P|ɒϜCݿ?rijۖM @4yqq޾c眹UAoۺ߿TZ9::j25*x<1@3%J(y[ʘt'On"myox8x\eLΡrWsY=6'Jo߾.91zO[}F&=V """r|.]Կ_ӈ My /ծ]s;uhR-[+GMD W_EE>Oe0MW뀝q!ޤyl8jg^BkԨKW*V&W^KII)Y7/ӽWuAyz r&!Ap 8? O>[u-RJl||BBRV~].}_{;DAL+UC!ry2D8+JHH(SM@>7ӽW`APt$2336|%sKLˬSw@dխ&6Xc(_wcc6۷T7Ő֦a[n/zV9M6Ҡ#BՇGվiYU/0 ;M$}qUqO/6+Ӱu˗.Ϝtϴ0Ů3",QRNq}zښ##,p8F5Hb&>sz l}yw)!}J qq,꠯O:7{h BCg 9o?V,b9$[7eJز-<~{.* |>[!*d ׬d6i(h6ǣ=(H$ΟKشFj`_nӫWQ͟3eگI IAgkSόNk%ϒ5$44M& povnI)?}4M~zU?Kzy)<|T% 4 99y߁C%J+Ws^T-/_T* h ߗ ~MӴi= }r5IĂy R2Rwqq|A;˭bQ#0 (8xyA36*`3l7F̍8pciiaT @hir3I=BLi -~J,Q"'_k< EQti 4VP[Tӣj9窕+xyZf'O# stY߾}شY $K^tƊ흐~O~3Q;˭*U8mdwDXyE"ϳ S6yVc˔ )hɻP (|v@QML6rp6ɬV5C/gBt) w10狗 !ggjU*߻ i' IDAT5{U$YV~[bVpe3A~c6c0ץׯ2f܂9VY! õk7Rw?s-2[crfhgBPemQAD|}$ٳGݻr8ۅ J.-"""T*oϟPP|9.tfOOO___bwZP(򊉉,L4Wпo,Xhd5HXOє&='n)P@394i88q@@SB h(+rD.[w?g8hC;.\Եs'c̍;:))zu]r׺!m}2jլ1fpg.lSg6n`ȠDGaӖ&#Iv͚.]kmbӃnۦUn]vO9!99nZ2L,mߵg}uL~1ԭ[zߵwvNlȅ/n԰^Ԯ5nACG)<=W}_#=]ƘQ#${뼼&-φ,[b<~|ґ{2_I{g2dur`u!.UkNڷ3Ԛ-ze[P(OTB< \.֬+=-} $Ifff>k3~Ѯ]{PT=w{aFe<{މ&8q-͛ߤq/՘( b̠r Ll9SB0:I=2ide|ŝ2 #%i9O&M xbZw?^ǎ{pdV-WjE ?}kܸvx\.봥q%PHO>:rJp߾y?<r޿T)i0x$kլѽK}Se_G|mZ>jwʮ^yur--ۘ5|~s7n?lNl5e߾s[n3rM8Ϟd.3NGC~aaqfL h.c8Qw&Yn]= TE=yԤM׫Su LNЮӦ7殃1G,,.r#//]]f붭W0aBv֮Yx"cm۵;t#o߾aӷodddLLLÆ O8^v/_b_1gi@̡66(F @m=&OD4E/:={Λ1"чKINdX@i MZ}*[I$ݾs .Ԭ٪p8waDZ5jywF90.A:DG;4߫ Adr(55ՕY̘@ؤbb kn6i4pȴ4gRRptZxsDmt}}} }IDd*5֯s$c'ejV8,&fg %EeAbVnygp7qhxDZj=v5mNNOF 2}?+KTN]$[i?888@ժU{ dJ~pmݒω]v k>y h4 M,5mr4Ֆ|9]]ל~tz@{T*LSq*U uIfO͛99:س`X~cvv6TɔJL@r32>קQQoRT*HdkƧ nndc^o ɂI#&6GFn,t۵CZm[Xs!{?>6uБ1#O1(e2ˈaoNBbZ-sqQ5ZdmgKNNds2WӃyzǩgυO2Ibaa<h N8<^xݹs1c fet0`ȑgNs_[Vc0<)m&Qƙalн>M,ͮjyy\*1с 8$EBXS~DƍL45!Yߗ,lP 4<<wn曲W^985DBīW"#"ZsZ2uʚ5kJ`f&3~!+ߙ&󿁦 p( z 4&E1MP4@$w=٤)N u[xиxSjތy^:LZ*KݺsvoSt5HN"Nc>AM)322 K8r@f]%K֯ẂfPRիml N1,D$??qܘ .jWQÆ k7n*פq#fwww&&&WnL!36"6.JL#}6Ƶ(k;LޠresiUC.\y9[-ʽ mnj``\bbĉT}YfddÇ ~Q???ZT&;߿;럐7oLđÇ Y._:O֏(&4 cg~.yVprp8$u5VE'OHLܼuJ2毵rkpqqh2cz}Q2KZZ:˕H$*v[˗y<}\ETR~׮<{P*+Ϝ1eXhIccARԠ3M#ԉh0prrh4w鎲3 $,5kc{/hP¹Ժi׮ ʤӦ_p>>$臈HY\nla9 <0E8#a2% Yg1ӺdgSnMMfqJɌz}2Na|Yb-V}칿͜1*ij[Q֦ 2 J8_C?6C(̒K4e0\A[*Ml« ̮; 5_ڨA{v|漪1**_3F)&G)b.V͹9ę9'4WQX`-^ir_ѣ=ؾ bd2zY4Ahc҈MCmآWLљeKdWc.oWN:' 8sv`0Xnę97!M)e%h>ʻO VDSiOw\컼'-V ooEfC,Y9mF2)heXnZcÿ}EGۀ_&3::ڬ3 )*Vc.#AΜai`hhetƛn АmU!uF[b"h|sƠ>/ӽW`4MT /xdE4|ΦESV$v|5CFFGi$a~ ʃ͘J4m ?V+DpC2qqwEPEDqNdCb!ØCB>}BEL<B0B,1b99a!X WA p8G''77wX j:11!=-o`!D OO񇃥RG\\hkwN+Bp|JP( IR)Qܰ5Pp8jvtr*!==CNNN 6E"@FFF*ŧ")1)5O_b!rWL@fff&''')5?B7m޾}{3g湄j5j}oǔS]z{oFFFZކUVZ`pssgqRgXwHT($I7wƜ@k~. ?R2 tjZ*@FFFB|7$s8GGGPk4g;JI2wL3mJ$}*.c{ƌȬBANrWWoMOO~ղ邃ߩS']QN:۷/66tFN$SU) Wp8GGG`qƼcΉoГ92 g_~{ }{.Y83<"TAٲpV}V۞c޼y3CݴiǏ5#,b /BGGGGGGbc,Θw̩tg&@3ƽ>ߥϴ=#mܤC<<=f T0~~bcclU-JOO-acѣGݻ7<<<߻wQMyYI7nsE`0bc]w̽p U{&?M@9F\JSyBCC,Yڠa+/۹1vjٲefV3gvt] 2yOjɛ7Q2Q([Ϟ=3ʤϝ;/8(PcUqINN,Z˗IInyUF^)lkZ5Ygo%9){'NY[h{߾}\,;.)1Fq8N:lժD&";n߾e*sttdQ//=y+V|j\.OV*-_m/ 7 J\n\DPPPHHyU>vl\EFF烃\X$rqq<*`|(*5Ueq|5v Г!q.䙕:mOE[Gʕݻ'5j*ԽG>}6ijuXXW>5M.X|I&Ԋy^$eBe-7nwܹsݺu+L̉DҥKDJ[g))) :/_=}s @,{zz{N B//ج{l|KF޿-W|ͥRwBΝ{eA:8h4jkuL;Q֖֨Pdϟϟ?)쮮/\rf_i'L I233saׯ]vJѽۋ/6r(e{{{޳w 'NEy7iܨhc Gx&M̜5;,,Sv%H>BdbbS-~I͝;CǎEh4 :z̘;3Zjsf1LX{$''K9 AAGGJ%7fSNY+ v(W.!!յ[ڷS*f '{ʤS>b͛^ҢEKzZݵk6mq=zũ*ܵeVڷYM3333=<=&NPdoOk:rK)zErUN'`e rÆ>zk=k׬ٺmի'Lо]k,^A$:vXv<8b۷oXw~Ӱa'׮]˗?g~s...cǍ[n%͛'b`&##cСh4G1bd@@EQ:vtQ#z}% ѣ1c>`|*UJL5t% `۷o8pЯ x-[az//gζhԩS;wR|ILybݔ޿OO %%uqLFFzxxxXX> jzaޥٙy}6fdׯ)+WmW\1}ZH.W^ZugΜڵ1};111J8Wڵ-ZTz+؟ ;w:lXڵr UcNnnnW^ݧώ;:}6v+N'mQ_X@mmyrss+d{x|P4'Ng)^xݹs1c `N;8|t0bHOO3O2_{cn֬Anځޢҭ{3~ cA%iDQb6=66bŊbظsvvqH:#9[ p69wH$(17_⅍zqvvc2̪au@č׻u2dnݺwmǎs-?23E"i:&&&)UL\2e޾}[|ܾ7e^*rpPk4 W^EFDdip]Z=e5k֔}z&3~!+T@PAk|N:+͚98%6&3ٳgC vuu]l.]H䀁fzʗ7 p8f۷ߗY'ESFo޼i: }5ʕQ Ǐ6'&$;6f7eKʻwnxWkJvF: rIDAT/^ ,L Ο?_%@Nk.11q UTپ}u׬Q322CÆ?|䨟FQ*ƍ_zOHH`m޴ #&EڭW'Zs\.7_%K >222:w^p>=-m 2,;;25˗/_AjJrmڡ}!C/W޽{<>|:t\ݻw (۠A`۵ow T*^j+Wӷ/EQr.lLLL iǸظoG:xƌ+߿G\P֏)ʒ%H=t.b=7lؐ}ڽ[W B.[ٙ 5{$)t:sAL&hԅA2Lכ.b=rTU~X,V*yp8̷FkL9::Vwtѣ  +UaÆ֭[$ >ߩPX;宪M4-S3U0 ?恽 o)NJϞE&%*x~ng^!L%px6bСaMS,Uq`0$&&4ߛ)ZDӴ/:F/|jO+T1@ PbD/]2\LxE!!![5jٳgϟ?ܹϟ3Fʔ)ԴisY<nreZW^I-RS/l\ZrCw8;[R{ " <" 2\.:|tڬ,RLV5no޼xUkԮ.::._(. ooĽ;y͛_ll|ѨQy>=r'4`8׬mURHb4T1IUr:-5[6[iT9+;O `drR.}&wi5gZBE`0@P1+Kj0 :8@2I>h@5["QL|"mƙ˜CAJKt\~krDw\g.&rl&Oc!T!0"ϏU&~OJ#Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rs!ØCB0B,1b99a!Xc!rsIaFu]/0 &s*.@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q2's@q ϲfc߶{l~^l%7ۜuWPf:kfmf<_ )o@q2#P{IENDB`RaySession-0.12.2/manual/en/images/example_session_ready.png000066400000000000000000000760741417052567600241420ustar00rootroot00000000000000PNG  IHDR1s+H pHYs+ IDATxwXͦ'H^{׳gg{穈wD鄄)X1$!ELffgg7}g웪@_he] C $sd@s!r9QA2@ 9HD9( C QݾQ0p]RzAب-[oٶ)ϝ3՟GF-Z4-=K(]`Æ S6>*Rcխ?geե^^+Wse]"DoİC&͊^2U~ҢJ x2"Hx_V֭x<^}F#t8o(a|OqV\.Wz̔ >L0LYN3 FcJHZzgn;v5z˘X*`u-x<Gn7n޲9ǹNn~4[%2W=5kNGIF3Fi4|?/_:ISEFEGGFu>ӫN~iJK~ۻޠW)s~]ꕛhɢ> >2;;{/Zhjl֯޾s7l֌ )%1՝4g''uuEO?iҸ1]&ý{ެT(+F֥?4͚u&V2/\iߖmɢ7ngE"E NɓUlgϟ<}V^ȨU5&tаAng{ɍ 3ݻ"n]:? 3S֧Wϥvٻkґ\._^u]]\Nqpuu]l o޼"uz ̜=i]!/\ /y=]]]=UV ,d0mЭgÆ,^g~Fq颅W]߱s^ĜpNweIժVݾu'4|Cms۶?x zCeS&Mѻobbrri <==0``{ i4ܰsfM>0ť0 [ے-[V*yxxܽwW֯dCh>juLؽgX[F#G<H$^={t3''cl܃q}kgNfެiӴ:.==~wݫW.jƍ[֩Mkתu]/^8سk5b{ |$ կW/4$HOK{ PKLy(هm꫔ԈW 77yd"r ''"<77R'O={xWTݻܞGF6i܈|$~";;<[J5p-^0u7`4&' (o޼Xp[B}[kX")Fk+_ ݳCCb1; AА;wZVvm 8|Cą۵W>>԰g322P(tvvԨ.]ߠ~=ݻu~5־}z}(Nhj~;u;wS Ug&}NLLJHx1Gh4nn"GU%P^47kJ߼~ct__PշnߡAA\rbRݻĘavF1S,^vՈ֯;:G [m٣{NL&p8lHXkQ*s~>7[cvRt93~6m$6B޹sSv6ѣ{֭Zs׮o۲IRx#'MּYÆg޻ժ^<;'2yss3fϙ6$H=k\zmeF 77h4T=wQGE8~^o1♳̟7҅sJb͝>Oݺunja0Hge͜=@,xC4֯aJfY.#׫[GϿrssM=V03l;vhOa/cb-)͞kޯs lΥt:}a3Op8W>s^#/!;w}W_c)d/MQ ;c \Ba2N99oH]]]T*K`SLjU*egg1B|>[:qtߞ<}(I2ljϧ3EXNOzCyǕ˳lY~jo蝙/|7s,ҵPOg{,^JӚw~V!It:էh4Zzs B.-c0^_P F;FhF(}O1y ϞGk*.*+HR5},?E9;nhsR beg8v@dT􂅋˺8RVD9CP|| eEFr>@_IG $sd@s!r9QA2@ 9HD9( C $sd@saɤ4  Hhu:$q .@4Fp:Vkh,&i(`L G UQn4@ 344@s!r9QA2@ 9HD9( c9`012 !/Bzg48Nfjn4/>sfݽw_~!/:ud;Fu'r*# Zw>*@&t3F0:9hЙLSE% -Ȱ?: Xr@ x3I?`.tcw\F-u᣸ K2Id6WTs(V&oΤqcggOw:D@,8}ؐ˺ ҡ='nLJ+3` ۞8 88`ʉS10pojתI:7l%QQ5^%&&uA; ɟ铹kYQz+`&kE]l~8{:̝8uN,-f5?.Z LL>I\k㦿lX1rrr,]UC>߻WOZݶ"0.u:wXZԴ4׭kJ%ܩc:uGF2Tb[hP!';';'T ֥K&ILII Ú4iܡύ7{xdghu: \]\%&RpwҥshH_RR2۵kg.[jN:TVE*-CFO ڨ{ϓׄ~25hIa鬧+=NM9"[2wj^L!] $sfa`&VQv܆#"=<<N͛BsF|f|td2t:}v?ضMժU.*d]QvN se׮Qgٲ&pVk٦cͳE%sRu`nբ fR%W-߽wqвEs??_q_8JrD1:nǶ-ժU]hɕz6jի?gU|aعLi6O&O*.N$81^y3qT^s&eee;@$Y"ŔaCl1^[Ϊˆ lJ'N~:l̦}w28]1<ЄtF[FLJV3);#ԱҺU˱cGϘ1iÇT*$&&J$oׯѽۏmۼ|,޷iׂZH`4y S?yܺUjU+Tp1 >(=zxɏ?Աۿ as@$`2ii?{[hB=bݻ 1/ZPH`Pǔ( ZK$ 4K[ʤt惧]JZw$>Rl:NjY?q9ƍIV-79oݹuOXð9^j!M /cb,]fkW^kذoKmU!;w6OIIaI,m|ZD)̐׀N0ZzA18:Lx|ؤqT[Ogj>5̡Zhvڍի +Oܼy+++BC rqqqdfff޽{/u+FUH$Fgtׯb1a2`yΧϞ;zԼ_ܿyf|>鳟%"BS]5Wt 7[i})Bj0 (Qt.BЪ P~s'NkEC, ;;`(o5O`:<ŪN4hSYɧ#vX,߇>ṷ[F-eh4j4 /ASg 00LMZc/eGr\T[h)' f9DEjZa kQǎ:a^.^Ppzk&MIIC^ViH&2Ԑw! ɉOT*˺ Dq@j" '7 +-@ 9HD9( C $sd@s!r9QA2@ 9HD9(甇98W-+|e(sO>0 aQ1. lPY[~ ha ai|4or_lŵJZR322˶_bǏq:âb^{e]D!v0 ð00F@= zg)ux|^si+%##R GuXdkh4ooSz$h4$ʗ_2ec]>iQͦ޵a`M5tƊ  ĕZxJ}Ո aǮ=;w)r9=M6aa"߷jl=zr%r|*ժ oǫ,Bc5إU+3+V Jt P,B=y/-74M+ 7T$IbU~x?y91L.>z׷J.^*vV:~L&+vq>t0A~]@=|na ﭶ2M%cbbrjZZI _\L7pخ47i%-+43hА`ZOm"x -l7ؑIÇo~N$$I$I$$$@>MP``6(ˤq> >4 h4I IFO#AY)y̼Q#5W[~*x9:<=ŵk,̹ԮYkxSrsɚܺƙ08]vΉ!}|sH,**`-lUZf=j庺~sϙA ٔo%A $I]X7H0#`Gpu+Mr )l#YfTk#AzKZ5=~ܺ噳Z|z IDATr'm߻!<O vg:ޤ͚~Tӯ7l|juI..o3i҅oܔAF[w s?sVbj2¢~T?flea-[ ۛF,\.bŊ\.7&&FPb? qqTZNg|"77Jfsyzz&''kZ6啒)I,(4WP6lZf5ЄM<A|@Iii@q$>q@@Hsc->jdcmRU83k!GW]ݳIN]n"ksxe;& nS כ4~ N_f-75bFx\3lݾ3$aCpoXkڴe-]O;wпO/޲mTryF B!ݳqZMb iܸaݺ:}qe+Z4ok L?bu 5U\&MG4m[̘6JP\Xfys>c'?hܨKZ!0L(q9l777*+O@ܪՅK))i*֭;Zy$ܸu;1)^ɑxzffsڵ5OiIɴ8ð1Y?7n޲ϥ4I7l3ڵj=0qtYY S VE$֝7ydtL :}tZjc''g''/cƌ)֙G򴙙5qcN?+ڵk?ݝ ~Kv)J=۫wo6ݰas,^1v9$ IťSfV[7Q7]۹;ާz#R S(0t4PaU._խSSv} U*iR(E"Gww7hC/†ZG߯O6!&} S>js>N>;rЇk:";--4_X,3A&r9v*t,Z )11n/>ԉۧ>Y ,6Lܿ7o޼pTj50۷11yZ-h4t:I iDT*g.E\>4:W ~M4bױGJ E& M-4ApgCOt?ox6ąpΝV-[PI<<2/jĕ+?mS!_|}^QJ3v4eZzzAYsRtijڳgׯW?66ĉcƎ=q򔿿Z2LXqϞC Ƞw`vĉ W#.8W.}sF¬ $I $z-I 4ʬ1J@YG95Zi4LgU}M Ιߤ;a)hڶ9G}y]8_O޿|":.pv^fiViX5c`X7lr]bҡ}ͳgwޣb^|cv{r}~[6Tl ^zbH-n:7o쓧>}Uf,Zj5C{ڲmGNnϢ`ͺt[w[xƎ0tƍ޸~`ةCjAoݾ~HZ5kΛ;kX|ԱI ah0PM3A&0pvvV+ļlU&ao.J[g^W.}&KK.2͹rr >U11!Y]l KUB A[o!?#1È?aXqe e]R[$I999VcZD3a0qb4g1l7.kVm Zg,mYPZ$IZljql)F0;2&I4+{?5Ȝ0`58"_0:I5Y5N+՝GəeZ-Vy /ٳٟ@!1X{"1@$ 43#457`K2΂m(_"sqeF8F+5aX(25`݈3O9/@ lIT`ؔݧ$ŦSJ^iS❖\x2EVYo⠳w)sZL6Z̪u#HCENKMbbս(jMbbEgp)-lʜ2#FH,BIiMG0- $@B7TPc=*]*E wwwUâb^{ņ$ɂ(ul`SY4M4 z |T*?{NIyuY`WH4ƲU hN)gfTET{e]D!at^r:Dcd@s!r·Ԥ+@2Ysd@s!r9QA2@ 9aF99;{x<PTRiFnNb!)1m,bqZZjRbUQ@|h4__ˤq8K$^>6AQfh::9;uA !77eF%%|P*ي,_?OOI43;֗H&r bNh4r!$'7e˵!see Yzkw2Y:d"PD"Q*iޱhgi4F#e8W^ؘ,H,YáJp>?|SN͙3'<<\ X+F{󌴛R.P{$d!8}}|"?˵QhVYZu6Z :tСCDS*k֬9ƍ%ɞ={p 嚒(JT*3ӽ #=F999Jp k4dHt 4[l^% Jelll^{@y<}hnn'kծuĦ :th=7EMDGGéȦ3QlJ3b1ي,OjhlEhfdXMX93Ji.8BÇ\B#QXʕ"?+RwV}UۚO(/^~enr0[4yJTjGh4Z=wVcb^ݳ{T`0NNNs;vl_vg.FF$e25u_hdn"qU;fWT*/_Z&c<.xtE lU8[84i4 ;yi8>E6[>$44==ѣG\.E_)A7hV-[J|#RRR~% ]]ǿ5 rȔeJ$^de˖*I /]ԧO˭X"ˍQ(bϯB\ܫ,`9UV/_0===lxrȝ۷eWTf~h?{vi_=fLe{{{8xhigϞ]ŋj٢tez2VZ͛ **Oq\*ѳ?tEw]Ѯ]{s5jIc8С,\t#)`2 `aǏzJhhhHpIPpL8lTpssӧo]d2E91 ۯ,3Ǝc7ok~ʕARݻSCrvr;n\y<^vB$rkߡC]ׯmF{zM6nI+V$z\.VӱL[i=<<2l8+8T*&:Nǎ3//nڸq]6l6mZ.]6mܸbr{]?vlܸ{ٺ!C<8666%%ygϞiذћ7oF~ sLmܸ޽;s/v (1G?yXV7nܸAAAAtի&7 ?qҤ'/]<,35ղ!ӫWKٳ[,=v_^ NΫWںeׅڵ?zUZu/O>wRE9:, cYzt=act;Q\._pQ=*UԼy  ":Y(i3335jxN~gWWW]v<9\P(4mR4!!Jٳzf 6}gO.,?i4\.ϖ̑$`w˳*UTTRRRRS0Lxp~^^7Ty&Q|>ðoiCJ5k7o~{~qȐ ?.aa"d6kiOqУGOLֶMǙ|PRSRJPȯ^=j۪ի-VԻv*ÆH.dSTj4%%&h !0 {14#cE-pF&YJ.=|pu+='n"v&^\\|$9@5'JOVV={nwzcccO8>f'OUj,sI;wٴl IDATdЌ ʭluA ''֭[[6HKKZ%1]]](#tY-rrrR(TɵkZj) CnNDжm[Z}bFȜC\rrZnذJ~^D^OTx# #^RP 0q];o ѣRIMnvڵ>5zw55…M5>}ɜ9s찰ꧥY-֭[r3aY3#". 2dl6{)v6m.^t…iiZ2cyyrϯBU fjjjDDĈ#lEψ#.]TS j:==bf\.&Ml۾=8$x)2M\թߘ:JM3?}󅹆ٺPIS]T]sSvlժݻ˗} D"Qn...<qP~ ÄBZ* B`rDnي&d2Y54z{[6"(X,Vz ] NNN5B:ujذaEʿF[nرcAV!?\lvW *XTE4Y*!?o*vݫW^q%?(/YڑO;SI̴>PahJ$Iu1E$iXNG-ȹ{  VZO^ X,Vjcb^$===,,lÆ /bxÆ goWEstiLV;|)'=z"hN;~u_2,))v:"TvDcK.mݺ5jp$~>uֈG#>E2=wܹsuEuVnLQ$ٿo_@"99YWۚiilmF㸟_Oٳ'99y֭Gټys"={?\$]h/YXA4PFc8I1 $;ggg}.WecSy̗9ڮAjƗ9" "%A.=zF2Y,SRQL&㹉܄"LYhU""":v8a„˗/_t)..qwwTRHHH֭/]d?|#2Pr^X8I޹Z}*՛{`0\Jd8:QTP@,6[$D"6d@id2L.+ CBBZlgݻwW^up\^ɉiDQVH%G 0nǎ;v>[xǛ|~!KmziW#Tg1 >!BqV_v99OݳnyyߙydB٠\.l}n-H+(uF_;/Yyyt9DZXZ zm/8s!RCaG:$2| _1.DZlN :]O9Q0,eų"L((ӥ~U14( C $sd@s!r9QA2@ 9HD9( C $sd@s!rN) `@f% @ Cќ=x<T*4#7'Ϊ s=*_<+8NXhkg6Z}8z^6Y!h4De8 %/__Kjp=FvtDhu5ty ?NΞN@Tf+||<=%l+;֗H \n^V_ko[@|~XlM(r8&:VLYf߷nǴWRR˗/^^u5LJJHw f)UŶVw*ׯ_xpw8kZjX  8Q2tLg8$N4z{ħbE"LV:L.W\&[}Z@,O81888""b߾}qqqQR1cDDD]>N_@Zjrj W\cllE|7޵kO1bqJr2xy{Sf7ӱ2X$|h$ ?'esj𜞫r'QrD"Q*iޱhgi4F#e8W^ؘ,H,YáJG͗p>?|SN͙3'<<\ X_{E33;ln&! (ERf61yeg>7}̜0if*D$9q>9ރ_䔔#?zs+riIaECF75kٳgϞrZZZV\uիW;k5P?|фڤdBH]m-˲;\gZH5i|*ID$YGX9H~<heKNI9t@׍ zHN`dٳgϘ1ƅ̘1Z&Mp^X__m7yDHe93N`7*QeH*˪(T3\i3L?x4 p[( /;^kv}Ŋsp[s]bnZ[55Պ HX, 0 cXR*RS]6wb_2wcRjN?7D$IUd"J$17Ef> U=܎kTWwŋ׭[WPP/((XnݢEz"ݴ*sTWWW9*ruUUyyygB:sqxG̪J*kddQ:tV6f̘9~<Vo9m8hlÑ_ѷ)'7oe,9v{J(*9y?TUU5yR1gfugjƎ*--$Ghp58Ien„ ֭3˻9X=lڸ0cofm-Ϝy?>|_}`4~_ge&)99nwVUU|&Sey;wt:B/{.Yq\ ?޷|G|ͷB<V\\!!a]&kxW׮}o͉h1@PCCÀM:uݺ\0h,BȈ#^{}d6[aÇ,;o;NmϷlm4njksJήfWq zc1H,I-fwQK_ZB"$H$Y%DU.adMS{%&]sbiiiݬY^zi{P($С~vsMF\zÇ Bc. ?lll,q~ _В%iiiV+.4$ؿooM9BlB=HEU![|{O=drrSO?SQ^ hLqv>Xpabb/Nesl2,y!VV<" bHQbJ*DQEMdX;JQ8i=O6m!$'''''G-Ӧ8p@{;Kp\~P0(3<(ɓ';wa=y"@GTUrvy әUZZgUQQ5o`0xvm6|~dd$0%%%ǏC!BȾ}}>eKW^= uzYsmw5t~ zcp\ѬJREK,(*,K$H(iQ08 V?55mԨћ7m=zk?ҧ:33S;zv,mR=јQZ$AP=B^-q\LLts]qq_v[\tBlqmivڕݟgcǎ뒶5W__CK.䒵k{FUXX駟̛?Ӎ>ef\]WW }ͷ|&i~k΢ӍOyEe':UdYbeE%",^OU X2r?bӦMc>hÆG{o[̝7'ܷ)S.]Nt%*> 8qbȑskΜΞ?a/{cƌ^YJ8\tڟ(?ݮqf+uv@^^ނ "##  2qĿo=YC555C_~wm۷m F貥KW,_nX<vx*JHȸk~ LГ9\[sZ&I7UY*mi%Q%E,+$˒vD,YiSN%BTr1dUOtSIIފ-`pZ^{mƍ7L| :}k_}+j#G\K[|Fy'***˖yEQQQ/9o~8A˕ַS\]NY]]?]3gN^^^O&;~ mn&\qofvN<`.5V{YLiz($IJ`8Ek>E J$Id9N!v)>_Nl md\k:j6'111(vָ0aVй#/9)ڳX,Æ_}]"6m9ҫ6lؚ5kL~9v杽SF19?6hv8f{}[o)l]gM46Mg<񆂢$IEIeQd* ! Q%EUrT[72љ 3 ^}!$յ?xm!DUUW' / ?vECk5/hǺ)Y[[ZWsUV-[|uƈ TQʀY!TUMbIe!(ʪ*!U) 0C0& UQQ>bĥ$ݲX,ݳ5k֬_~ذ:t׬Yߓ t !dRL<0uW%P( z"˲${dId!^"1a6J*a%BܪZ(!N^Ht'˿z2 ~qMMuٶ9qiGo'I_vmee5k6lꫯ_M>s_$Q 9󅧶-27TUfBNUOMMMlur4s̖$!$ MHr JI(GUD9WI)a OB19@! &02\PU{u@]KKOsXj| B 9""g\nu(??ʔ)-ھ};򊊊 !YYY999'Nxlf-WI(RNnjVBHo LN]쒔 It;o:>fqbZ$ajR{x8T&I*cUY5ȿ'*dOY7mVf3OP0t\.0''g„ ڵUG[Y^^S;Q+dca[oV]UWX}Vg##'~*y\bx .i;OZ8s) =[B,L$a U'w q%:oG|=Z;;##_}}Y?;\VVVccc8sZѴwE0`˲ h,˒$@lllQQQ?_'2<2`@b㴻ih^SS]Q^ٝ=:Μ^/++Aq( AEQ$M&dyh4,+b0E1 B!UU۬^VVEQݾx=o޼^IDAT^xZBj+_4 6!YñcǾ;N;@L۫*+ !If!$t4s d tӎϱ,J B()A7Ny=a * q:8^Dzl6۠ TW_m@ p8zQǏ\ z|---?UZZZZZ}ڴiӟ۷WE}wt}itz6wPFen&1b0ĠTb#u^ϰ$"d DeEQA+m3F}j 8&fPMНINNINI9ab,\4h++{zCYf͞={(weʕ[n]zXvm/^S:MiiiMJN&ֲ, `EV=Uin Ck]%h e'˲²LKGx>Uޏu>ShgJR쯼+Ezj1+WSR77w3fqa3f̸sss{/VI&-\W+iMD#******h4BdYp.2c""xAj]f14DN0DN撲U,Q-J-aBHuQ@7F=_A.hB B{fWX1wܮQ[[;w+VE\SS(JʀTŢ߰X,)REz;>qTUCrFYGf,?ȣ_455fz|Ӧ͞;n2+~O@`Ν0_aq\v::l' erlos^t>v͸;v枓sfsllZ}L+45y:יNϴ566ʲFaK[_zr*WaxgY6663L[v0/njn"sGg[Z||hI_#G0cfyӧXKJJ֯nڼ) 0LRrr,-3L=BZZZ?(**JIIqqq;v~V~}pqy~͟7Bxvm6,FQ常8^^oRRRqqqddduu$I+if-ˮ];&N:@TC AzU޺ukxuܹ,X`^LKKݻݯ-?=K'nC>ȟKKKDGG?lQ@ ܸ ɞhll|xٲ=@ C _>)S^ F#ݬxlZ β]__t:?߲h43/qN_Y5fq_|qsssii'X6Fi2jjjx8N􄄄ݻwEQ?β!C tqaSD !>O;Lц }xU>oy-s;vߵ>VxfpW~~'n݇, ̨^믿#7v$IrTUUujr{.!!?=HEU![|Pߠ|{w?0)c?裏f} }e?HWA(,vСCfY6""`0<0w} -($;wj4 <8qjfWWW'rVڻ=5&ڹÅ;kemu7LAׇөtڙtp*w؏;v Yf=S}x` `6wݧjeeUY9B9"J:ά><<!Ġ7B /`e Ô? !|K-5ztxߨ̹}t:w5Mwܬ͝IaFQQz}SSn޶X,N`0Bs$,$I`fu6<W\1~`( !))s1ckA޹#G[0O>i09p~ձcǺAB>90{>}Zܮ/w]'2gkt:]s~NNΎ;Fۚ%>ڵ頻Ͽګ~ɼ/X@fn,_=BH]]k֛oMtO?3iCI ٮ2(b)++3LF\TTqZtGfWEJTTTKKK0$*BDDD?jO?[/Bc}ĉk汿%!bSSӨQM[ZZgμ`0u]~ fy~5l͛?_6`'#. W].WZZ:qCsgJ-`6CzkX&N' wf n߶mm`P]t-Ѷ'꫉WOZ$ykopFqֵNNkjjH|FFe]fXF=x`p%5jfddz`6z=$u1ocn͍7>?>_K;ooWСW_s˗yx|X۷kv޽{fA^0L@`0,0I:n 9""g\nu(??ʔ)-ھ};򊊊 !YYY999'Nx}ݜtpŴ˶^o}}FQphmB, NSe턆6fMF'B(\.uZn`3a„ v#nj,/(Gr1}흅SfNq˲z^_$%%^Q`0qvENӮieY,˱eeeZXx3q%:oG|=?9h9ӪjWj1 #˲EQeACr#]e h˸\2Z.($@#r{<Ù7-g?:R(jsґSl7tYjte !FYoiȩ1;zJlL$IZ״SQ}kbG@,V s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(92CrP!s@9d(9ʹ~g*:EVXKqp)†A%~&JԐ TUr,P@QEVBj0: P!s@n*q'IENDB`RaySession-0.12.2/manual/en/images/flags/000077500000000000000000000000001417052567600201305ustar00rootroot00000000000000RaySession-0.12.2/manual/en/images/flags/de.jpeg000066400000000000000000000015771417052567600214010ustar00rootroot00000000000000JFIFC       C <d Tf!Qcd ?ʠ['Runw|>u?N9]>u?N9]>u?N9]>u?N9]>u?N9]>u?N9]>u?N9]>u?N9]>u?N9]>u?N9]>u?N9]>u?N9]>u?q$ i%c;HFa7(آV3\0\0RJwbf f IXQrrI+݊.Q.Q)%c;E33$gv(F`F`((آV3\0\0RJwbf f IXQrrT"Ɔ@^gvL^gr.+# qVmϯpq9vƩ㸘̢ߞaB# -fH ;{8aifi,qSܞ.&;f !^Zjz\7u8I;:QֲޞG+,UqM.\g+^2= #v$)@=0=1w7 Q^Ƿbq)3OS>kr!lH(NCLQ=@D:`{?ޣ`Ջ_JW:c<(}@\a_\Dt_Mh/I=ȷ_=r}5r uސyq|~ɶ/kغ5ỒFgI+#%of3MԃFIy֓%(ؤrL4bDrʯ cS=1",Z*+E2Cd!c,:- k[VRg$zov$O'f,'lIr&D\vUvjJT E;;Xr @D*NW2^T`c'#7;aM;sxϵ0s*>#Zߛ;zv0twj߂{~uk6}w+ox n䜠a}#"?_J"'+?z':"bis>~ܮj9q5 >Z8Fo:ǤqEQZ"Y풭`:C%i "!cs!&sw7j) uMUHοj0cj}X1;9d"5j*UQ9U9SӮޠ9Dk[ UUDDDJUU_"|USt-#zDr߿tu;q#"#^q+<Zc\9@l讵Wb2Jp&eNó/eG1]#zeV~0c #]j[T><`QH$ 3s'D۪[PA2\N=e>Fz0k):3em Ezqt.2pqyl٣t^kN=[X7M8Sagfc(qNIgj--{$yUU#&SMG+ :sGUQ%~9EUr ̎M?B1M̖zd"lzaԬ(L5Z^EgLz#㟇 =mY'缥NV;*Zcj1<[d aKYF(XDR :z>N]4L>u]̵]3܀MIHʎM'gmȗ'6zZRZt}:D6*݌yZkFw %Mމʡ.^o~Sf $岂A2.,wL]6OOGX-ZZf;,RG+aM&YF!9Vkij-(/YI',?LQtcЬlxR%$ ^#х%Z@M)oWN}'V_e?.ڛ/k(,(dU*}zϤ2%~AƲ!tC)9 7NxI*N.q#jMV3+$*Dd#Q3a[u Uo7nT"*ajTEEKk>Jy=wx5:yy@*rO)ph{;nP.7ךQ0pP]^G+*MwYQx"VLƏ)irW?ء9HN+)|:1/Pt$].\}@^DhW.I/J`n|n\i><ǘ75b%!cl m/ۮlȭ?my:ZPqb$Bu>t8#|ۄ[#-) WaS5=qɑnN(B X%T2A?xe9Q]WBSGEl?4Ⱦj"*J1k^YRHO :TdGlVW8^Ağbdl",+iZ[pd^Ƈ ۥKu!.JyF(FSf e1fWP)T]5j*g-2Aj]b&H axB 3v]جc"Z2KU-}"@"h(G@F=r l;`+x֩xgTk6ċf`fIf֘rpOqX%0^4!|pFsʏ\?R~ LbJ WP)1}eR'ϚH; eY6C:ßu*ȑG0 )ڭq##0-nQ_ůڀj=# wkp"= ߥ{X˿Oھv SCq__?g?g"@!dG) S%1LQ) `2P.q hI{#FTzGޱ:E#Se@Qs%J%ϺoUr7Y/AqܦuDV6.>F QeP}^}xR]|LaڗͥYHT}tjVrR2Z([\ƙGH\쮃Vs[jeoIY|y` NsM$jnzŠ*8odGͨk aRJ:$&*)eN\F-|fVV֓;#g] fvvvUYzw{$=Jj7W!,YxvBƆ3g 1Ixڿ]ۗ"yOUu]ccoNWf;(0pEk#}K__ߠ@"Zpqfff*P/5j㫯^JR|;wvvyVڵ}ſEQ$IG٣{^=d^RݫG;Rfyzx׭k6ЋbJJj/O¢sϋ(BvmCoެĤ$"ԯ_j߾[cUׄPyN:uÇc~ڶM-mV~uFL&[ᳮ߸ak̚6-#3U;::~~01D4s==֭x|i&8T7GNMM]jEP``zzGzzqc_}9--3#3s_|θd7fOѽ[~yyyӦNۧVd*o7={t9czvvBNNNwj*mExTLk``'˖|yqDԱCڵk!!NNNk֮ʐ+Vzzxdee +ٱC+((գ;)]|ŐqM6׆޷qܹӯo:AA|a0k`h빻ˡ:xu뚔HFI>{_>}찡CWc/?tWܼuKHH7MCD-Z42`L̕ڜɓ.^Q0qڴXKbco?1~paC;thԴiO?]}]f \_n|wܾ}zoCbRqOLL$/]" "{'Z5JzPդ% Q;$&.(us:Y&2c;vM0~mqӧ˗?p055Up{ϯ{\p/DذaSNg...z~z&ziiiGPTvvaC_}n]T{ҵnjiZAb"ɓN۾Ǐq¢1o""Ny'N" 3zDgoϵlق32-^dR-Q^^9̚.ʕK?\pm`[ƍ>]LZQU{{{GGFsxTWWW^o|?\&XĄ3 Ըq~~C_NNt7-04IavvN%6@A ܩ/MOO Vx4r-33x@ 4Co^G'-`b8!s9b8!s9b8pO\.FNNU]gLNv_ $6|TƭWu2X_.D H BɣLYͼ+f'ݻVxTSٳrQ^UPwHA(~$@$ 4S;$S)51BjVR'(hGfz&j֨vz=yyy w,sKkոm$dщ*=гOV Fn]Ty|jH}Ǹbכ ŜPe# :AruEN(?J}=*Rq<~?(9n_(]15)pWV,[JDtgZX#Al+`Fsj̎+{s \t8FEf._yezΝL2@11[9Ѩo֬Q#%xr=O(L,7rK,5ڋ/1gO5D3[X9jww9W٨^Y<1wFfa^ȘȈ1)JBD|!Hc%d;5mS_Fѫl(3%Eu7Qy}-d77Ϝ+sǝQM^UfOZ*?qԉKu:]QQ^YPPhvm__oļmnIkM5jؼQQ;G :uP1ԲsHr{G%qFF]+)n  uJ[oT̉tqSqRɲfͩ:?Ro呻6zv__OM"R(ܴI}Rbbr2݈e?=t8FR DD&k4j6~k,[t;;;\FZ4o6lȿ'L\N,JUBڿISܽ[~5+WݷAf/ԤT*|}X]>\wq"{W7km ֥O8qԔ .X4kƴw쌻z}BlzuW._{b{ϋ>scٙ)  U TJ74XnR /[Fh֦U}{;.=#AߍVv2erQ( bqϟ^w_Y&<<|A"#.YV㗁m駉6mņG#۷oeV7nܸwW`11d2h܉#AdDL0IqFD"c&"ٕUWg8AefDԵ0a~Lvh8Lyn,էqjSgDQݣ눈9z,1)Μ=w%jfͷi+yҺU &"꽔TA<<<{yyIK31F!: 11^;rXHN\%F9p.]뛖V:\4exO#Riep\vmA(]Y >[8Lw[-[ݻNW$8ŋA(,,"LĤ|c2:rt!+qW[h(7sNuvvqvvtXٳVZqwwwpp &M jjNjd}xi]QQC^{MRlrk/қcȘ`1*eF%+]Kƹ*>-j4GR)QA,#Cє1\hfyo^ׯeaa!ej4=I#1)רLxoCaAAwݖV"t=r~۶O 1}Q}o'%5'7=7Wk}2&Kyh/##x/OO/OO__3gdeLſ#zh|jq)Hd"EELKMQƒٽo:e |"rpPuQGO ݷ |ׇ5la)Dtuj\I7o]ѩSsss̝Yv-i۷7rg>fe!]`Jz)D*~B#AO$2A꾉(LLH:BɣMS˫Ys}~l[>Ef7~#.!_qBl{ҿ=ݳjVS&A'N^nɓujٜd2ZPPP vY2''Ϸ5D:snۦuՅ&lYPhڴii ΝIH.+KHgLܼ?1DtرN;HTV^;11CBimDRrrpR'nPYRc7Az ;uqUFG㹒t]wTz4eZ{) GͥΘi7޼Y󸸸6~„jӦMi7#GJII(~̚v^Udڜ^4icTH,1FdRT<)A%:Am* 9 ϜQIoI3=Q{е_{a>>Dt% +..XegTn"))ye§5Fpo?{ iݦO\zGs >UT׬zs[Z5oJ>Hd{nu|qW(q}?q5⭒uOܘ]V ъU|';އM6iDӍipAEG-]bO/o N:tCElcO?o_pRtvq^;wW?>Wg+Whjſ/͎g{^=),]rrr _߷o}yyyD4wΜwvvh4R7&&sEEYY~~zjxsǐ2%Jd$Z6 |+fϘMnnnƐ-M3rqq)***}5=++xyDP899i.ڨu6n^ nys>OL>KznHrU_T$ 6 \]]DV- e1A nZu{7hP~Ի4h މx':P;sϿ6?Bŷ1Uqf1A'b1uqx[(:K?l̕qU;ldm*ͯ>@N.) 0Uob1D2RӦ嗌M|({@p[u~5iQCk&!6.scN!w4Ju.1߉3<4 +[Bf6SEKHH0) b;xJ3 0bLmVC7HJ=iaX,]5$TD&C#c==*miiШ}zi{5>)$>B 8<^]]< saʧRwqq144ڌA%LNbstѣL$?g#T@ϟ?::6NCABY,=*butu2jӧM^QQ!m?~< 6&f株H+v%((CÙ"y0\__%p**jjmmmc WVV Bٲekzz͛7l6@WWuӦMΝcX2Iߢm[ZZ|d2{>''ׯkHfK 3Z^ҷ~>"폂 ɖV֍ k \,kdl>ͭTuuo655ujL֯_?6$عp*,]0%|nbrmlx\]]׭[ Μ9sp*=k Ǯ7f l D@{GG5O᳧ErN*|ELeO*0 oo_]p Ŷ47QȬ47DXa{GW|p8KKRƋ!ɺJ/,p8 ѣ7nӢ!X7=zB?j̃5wwPG[[$1H  "hhd,H֞7j?x`GAp䘚oh=>`bj*ۖ-[ P3͛7ukC2jWT,7ZT k9nܸ%K"'OLk$Ǜ%$ĿP~A1uڴ/V4s6R0 A{V̭'O$ kɏ7x9:UyPTWWW777GFF^pA:vQ7k?CNꐮ7o.l|~?ˤd5*z`i,**BZ<<=}||lw2HT"O//OO_2j+W\OO(**J}paXة6egg+,c&ݹᡡ`8NZj*zof_ii2d2&Oz\,y0M&1r`Z^ mmmnnn1 Sz5"(V6$$IKKszpy9sfϙ3y}[[[:|DIy%keD:֬]kUC6!MMM^^=d(*))p8#Gʕ޷bbrrr--e[[7WX|Wll̊+.܊]bbZd.HүVpayr*/iii...Ñfoo訡P(4UN@Czzz4 W333fffHb9#{A:mfRmO݁AoTddC;hw)/emmlruuPH/))˖-742|bE)R&MrwT@(~<9H$"H׭h66w<ӌy!-k׬A2eDگzOOCCC[XP,]jcm)|YfYH` 7NNN"(33377`mcFw{7ӓD$=/~~79yW(̆ ܾm{zzɮ]7ma8 0&&& /egepTѓaadmr˃Jƫvtt }] ߢvA=r9/_ G&b/[_؁b;;;7=nw˖-477]ׯ7n DALl;M^xѣ9:sQ8%[X$%sb?{488,Cޫ`&}| Zv-I$ה***@ <-*zҥ[xɰ0H޾zjO//?_6P(,(ȗï+ Ƌ;JڈTcbbEW=&x64fzyz/G899khh-lMpHHIIIee%" Ů[sg"~X$b͚I9?wƍ׮YSRRpu?y`B$?)**ݮ]>ƍgO ,ét TRR`nN5:* q**e\`p8d)b()))))os}}[1ïtŋ;vXl'NIlٯyחdϙ3d͛7CJ~~INEĉ??г{ sfl"(4ts`3qE93?YK1b*[SS=gN.h4ODɺ/<޽{H˔)S.] MPPPg?eׯ]etg _d~8Fwu9*++;99]]fL_byeeTʕwr99n𕑑r aٳ^zxɒw;g" `nad!ӥ3gmݺm֬Yee/&L@;{=s@rXg\\ )S\5tÑ}ݽi4Zfy%7jN 駟J4 `ie~Cbʪ؜h4| ?e<"dkkmllL&͛7bi݅|~CXzJΉ'U ٵkٕyyyt:=.>aE/_)y)ʼnbPA[ {^VD" P|DM_&m622*//?~~^vj"H.~T iq˖/azee[{7Ο?q{'jkjΜ=p BҸX ?P==̇5} ^H3Rrssg~<]J]nBoc.HKj{gUUUdy_Μ>29:';;+U+W,={΍7> x %ԩظihhАtC4JqQZZ3sHq۶n-++{嶭[555f͚%-OT٩Fhwww]]P=^TUU}ssH( edCTQQ,+tu ;_]]_UU&{|(Fd29 i$$ nx/KKWL&P[hkk 8r`@{{QQQSN۽{,_?GKKK0aB_}{=v466~Z9+++*220(($4sҗ-ٳ ?W=6maa>w\ٵkgssH$ڱc'@ 茊ZH {ݻ-ݐؘX@UU@sAx0lllRQF&&m#ӃN>_NmGGGciu̙3?ܯo}ұĀ^ ;ena~>j&'ܹc*D\ssSϻLnii4J `V`0BþH$%%kxUuuBSS@ Ye!M1C}!'=),B$%%Hr2qĨ(%=(o_U{m }Qlb EDDȡ<)8s\[[[mү6{Jv|>C#p8:H$~)@ ]3b{*CgkkWVr!,ox[(ŋ!)l>R4jH}<x+޳gϐVb w 0L`_#6v5sy R%ECCyAEEm[GV?9SS0Udm-2%==cͩiii:sss:⒖o 1'ZQWWw왑 Eqpx PWW!D$~Sp8NV(Q "s;oRjP8NOOJNH$|8(Ćɠkjk%j4Zcc#ee'Og"p [8z4L(ٳH$˟?!_ͥk.|Q#gd8yz'WA]v\$q Ǐ% #廲\bH$Cã0I>z#",qْ̬XSv:}Sg'ǐx|޽.\.O*v~Wo"Ǐ$/]rHc.?p,=c捧ӏ?)+p˖Y[a ؤRi߄qLvkkc0@ 1<=wɱ;H$SSmI{/Y/h36rrq͛[x:z=v|ݚՔoG Ql*Hd٫x@ gan20pvr(*.hmGĺ{{pg'G Dq1n%ϛ;-_$>+;?hANN}.ng` T& &ojjZ___VVxgΝR7iNv+Jb{`0RDtx?yRCCC:EEŪNϲr?"W~Rעy/_*wXHG"̜ VVVvqA97nܻ tܝZw|*~e %997c;ӧqcc箴3阱I$&{=w]l՚A˖UTT[㯻`5J())Ae` 5) 7|kdM##zz_U;L] HhXprogwqKxYYه۱-ѓ'wjQ^˺z-ˮU+ Toܺ}G؂y13B⃇'>yz'WwY >`PJfcTtȼ0bxH"xᣇj,)!]:wنCD"-[Z*_oM `p8l@UuU3SSY[J$7n3[M7,_/9H<|1L9L%@"\*L"ޯ/xoGp8ܸcee+N!Z YöwDKOTB7m(--D7o͆8c{Rii@ <}Qѱ1ї2UWאEqee噙N8sƚuo.ZVӦ-fʩ4nb[&пIJJx[sѣG[6oDpZ tJvlKXdw x{!WK-W 3O2[J! UJH$RʦnFd@Ԇ=@$ B'lCR[黩 Hd2JouؘL&Ji|ׯTVkV -=5@Eup8~v  05@  KL  05@  `j@ SB?7t.c2s?"ůOH$.Z{vUu쇬XD\cg;wҭ&5XwҾ}-M"HMmh`MkF;puqС}sɗfT*(QϏ8¹\#qjHD"XDge0 崊UQT(--- ZY FS!x{E- ߸9|F&PbnvډDw^7g{9} .]?2Gw+WMR;uH8TU]d C Byo  :vdJV:0eVn.}z&6]Tڭȅb1 0RT*I[Ϟkժ5\nzZJI o`ٽwcc*{>tB׷D"yYLܒJ1ײdQ(NNb4p(D:gXD"!~r!{I._36~)ͥO>g͖BJM۴yD"hkkntwܽsNk)C} x€~}\NlQ>Rti|]nT*bbpa  X__Oj޾5bD:zqܫM[3@c<^ 5r͂;na dԴMIdú$,Fʂi׶U.Q _lBff Y,WogWAfΘ` -_;/4,:*v1DI[{yx oD6l|u<}/]j+a32?{.A.NOyzϚ3o]z suEC;"& ӧ&L7j̸Q#7kf Ty SfƟy᢫oz5~o&zxϝ t]jMQq/w2gɓ 7owF 撏m` sH$3wAGV\+7Oahݵrr<8|ONWީںsgzxaz7Ooútl?d1ckkӣ{wO^CzU};ro^CO^4^a.^zQw;;@k?}ӻzܳGwX,֚7lJtq:,gÃ͆KKukWXF46GJؿ?~?TVVZjPPRn bRW ysRL 5[{[~BTƓ)bqccͰ>ABCB1XMfUTT|ʟO\Ϟ?d^|u-+Eɋr-+B#g' ?J`w~ĻL}YY٨")h5k),,x<&M ^#y|t⼌%LAt:/(A0>g'L}UVO=kBVn]7t!67o׷O~AANu@ {4yᢗ#,[ƌz-["|@ 8:أ kY--?' #O*<TjڣObGFjJcPejllHO$o߾MܲPZZ`9hFǎ;+T8zXg'8{n[с7oO;u*d^TUvGطJ&߈?{)'O4EU۷GIMz {SUqE 3ϝR<~$`_yzz _s?}<-x+e~9v7U%i s5<_r׎m555t:'s-JG͛z{mؔy]@yyExTtHDJΞ8zXzcF5i:HZnɫVau?Uh=RU#SM ^cG0SD"7ҤM|kyP(\..i*4*JM 'nH@ @0`95oT\O[0?)zzzlmK(J~}\۵m+_޹s'OAadvQ/M0A)Ǐ<_ .r\S^&ˢ95L:~D =@G\ :9:`Ծ]?YvmI>0bxukCfN ycTxu.'jJ-|}}71k޽z̦O =oo')e&&pR~qlP.(Tl#&IfL1< &E"Gy fo4*3٫QHPeCRoQ5BQep8n𠁽zPЫWϵWHI/|=#dβB=rNH$W9fB#sɚ9ʛ07wwsٳo?E?B̴J4dki}#gǮݣF70`jODӂ}<$Ҫ5 CfEo߮uk]=jœ討:Ν;J80D2=6ʑlKJt'&[7ee:|DGsEbP |s̚-551!i7%nJGB `阀Z U¨G%0~,Lcw@_b墅\Ĥx|޽.\afYϞ=<ؘ?LVXWW QrS{:dkY%7ϫYՎ!3qgn}GSF@ɤ͛m[6E'G.?mhpF?*љ #cg#G_gdz =tXsf$%DʞrW_w41ih!+JHϞBX[wͼxQ.8zQLaP_˗geyz / pt94pYVV%F {ٹS;wc:/lmli/]^a޾~T2)I$%W9m6={tw2d֯):ܻw߮15录H$UUUL(-ڴnu"H,˞ɣQKLMѻ\.Nn*<ާw7oP L㣪7 sv޼u˪U+#'}4*ؐ0?2h|&aTZZ]]`Cf-Z4`JN~F<a Ƭ߸N}c)-Ecp$ Dy1 )56$L .HG0 PQyL]]]UUа@NU5--V\;Y;8nޜYq1[pUDjanOӛ53-*z5DQfp URL8\T,:ȩżKKj3j$S_?hT*mme%SH$b eǑRH( fSf$%%5i˦ӧlC2?4K$>^rǖ7|> aʓ5 ؐԷUQr%d2+*D"JhukXu+R\gg'@vmv 8Ҷu렑_/j1&6Ijʤ4n&SQɇc0k!ꂂH ҨTHhURATRTTjpDPy]aaW&dM^އfLȼNH$bX,Kwڷob|a7oO F3 Un2et!5I㣌z_}Ԩ޿@UU]LX,[ؼa݆^=yx=v.#C>/޿oٲw LRF/[:;dYSZ(d9rZ[}a)Ӧ~صɔMN?Ge-[,DpȉS]%Jã.*ee/Yѫp2%5fM[1I IDAT^v㺵ӧOgϞoBMoQѱ1ї2UWאEqZNنGO<~QX(*@yԉc9oIX~CF76c9@`b=xpڄ}^={(߷a4MJ lܼ>39xZZ `Qu.!ty YUU jva2@I D"M&'DZ9fˇ7A ufCj|RS/]G :]Yڡ6 +U/FӅB6vLCCÔGSiR~-3ymlݲǷIkJS%IS? ?H(I8pPMCL?hSFg؈ykOA m=k&dQRT>-Xyf9D$/e *@O.T2SXGP2;rU/eA ꑧn61 drYyYL(cZj>a1RR»{EQыѮ&OжMHU2GW^seet:}޽8`0644NӧWT<c[oND<~R0PaP(QaH$O>[𤠲B̝=aD")+/_u- //8?" KܫgO:vʟKC ֭]ծ];HT]U;5f'U*AΞ>g{/Y]7ۀ#<22/,[wXܿ__U7?^Yv5E޾&9{vs]wWWttU2""&~ -v6#dZDtÛD&m"0ۗɓ 7owFy(5onqukV_gP7OC^Wn4SMHuC N*Nj\U(dמY9FD#ZԴ3U!9^4dݿХsg==FV繫2"We̚tPrCCT*E#4irvrαhiiy_ <(*ggOJEiYY٨DG?(-+{YfyBnܢT^lvR㪒_-}?V/u9lvڙ3Ə544.dPLRNN8#.3/&5*ˈ74>q8lB f?l6᳔ӥ1%T\#oPRfL-X\[[+;2:" BAAÖ}lvb 1]UwAb}v"D==FyEEyyEN66g1]?}Cf[ +W)ĺ CR1 q`M;w~&fL /ɾtCLBT',t7v Xf'>骂@ Z]Pxy~+|@JjCϝT_U]mbnD!3WTxRVMYFM099Л|+466644}9EWEKǍEi SBya 4fw7W<|PNUVU ʪ\UԺwAYT"̼pD"KǢ𹹷#Bܽw_z_8ZXTa5tAX~GIMz {DYBaӪkj>ՅGD}ٵ[>w(G;`o*W ALH h;H$*[9ekYMdғ{ &qiNKRQc?/yxUVP,jĐd==PX٨uBQPQE=YQe骒20VV6UKU. o/s]Uӌi._Q̬PXF*0D>iц,HxU%C by߯Y3hWS&Op9<߹c>}CHݧ1qߥ[".*<obWThsJPTȈa7DY򣁖'5@  `j@ @0`SL  05@  `j@ @0`SmdcL7[gT.ii`Kd V|}<:vPXX$+fkڵk EAML:k \]WF__ӆS&7kf*+ܲyC-?YZ8|U+Ý2xϠ3igM+ߡ>ӧ;/Yጌx<caaLؼJ?%,̞HR( 7mڴU(7pͪhTj6hz`p8/֛1p53}/ Np;#u喖iZ ow^HukW~Eo17q}m_.Ө>^wCpgdY,4~&5 ӧN)0`8yvl~(ȅ'OPKжa>}Zz9ME"9NOED;.fѻ ]  ݸnmрiP|$$dt_oڶiecOFܩnhlhۦM:p$Lɬcc.F ROw`?DXZSSC&2EeΟkϾN;qh߯OuƟb\j5zK$$prSioKZF7Oo'GNIڥ#|нuk}Yu:pȒޘѣFCj@CID=;}<?fCc͉$IU3f6]w++vwuiݺuMu3̌ :v-fDM e`eK}Pد_TUhbb x|GԴӎ =073k׮7Pwnw~T*=9aXB~~u.VVVL&S__D"z͛m۴x_^Qjl+|&U?xXΝeee6]f\x1#Ϟ==j}пG2sƬ=I Q+-=r_ê-XB:o6dWhysf m+h Q*޸[]U-}]Ti/OԴӞiϠ-,[xɚ{ltz* `fLUC׿H%T*Œ?] /DֹDApvrd? eVV1L@ Z,??m_f͜1i3GԤY3S!oު@ڦzI"F>ؑyavȌ}zw14" -ɹMyyFod }}}g'9mǏ552r+V?8l4HRFw,Vyy Ȓ+P޽{E#[4'Ɂ05@~:xYSSCAXYiK՗._YtZusr<=x}[8z zzl}豪_|u;%W0._f 8ݐH$id7>ȚU+c'Lz򕏷TwBfL[SYUed޻`m9D #HǏ Cfy+gaa.1,CևʝنT S<$ɘ-Q$i=$)ajb+ Y S(atiCG\Y*(WUWZI )~ee?g>i1637}&ǾoϿ$'O?;׼@ Bӫ ȯL  05@  `j@ @0`SL  05@  `j@ @0`S@Cjӻ?"cV6_.rAM?hgg5r D⢅i)wlomecäW 9w(ph`cFh*M7ȿ A:WIxB*"[[HD:r*"TkD" ʋ*o1ZTN;x+بJ$-Jx<Aa0555tWc٢E`'J+lN,-[-˳L"Zpʟ 543}P2cӻׅK7llflI\ DL;)qO$3:(ПH"=x0n2TާwA7'TJR$&mM?{n< vqtv>~RC'zx{ڪU kބ6{&T*e}R5M2Ǜ' wgAs-051ٰn-Iq1* tϫ ܹ{ w7]TcF<{:-ݻ3v > |d}XRYYiժUC}CI ]7&.Ύgϟ/,,xZV\kmaaQvN=wy1sPhnff 5B$WM@O14խ۰WYCٗ_"ll60W_*]E$W_~XJ%!)JtTD6mD"D"VVqن"(tPoWoc=jĈFQcMuuWejbyLCtڝ=JR$iDTǏvv"Si$ 6칠cɂH`[\$Έihhس1Gb :o_@w^=EE hlUVT)(v+ʶK/;~sk⦬C( j|f-gx< h*rI.)̷CyU˖;w*/H'; :էOfKROmڼES𐿉mعscO;p0zq,k2K"(iJ~Tڵwd/=yT9淲Ã/p8 ss魯N4/9eęX5+/ɹn`LJ4<(Pa-íZloWZ#䒸I[h ֒I$[T*Ů;w.\Dʊ+WTP6o%칠@45X[w])z*{ּEf'q;qPYYիK(mB} rrᑣ]]šRT"ܼk̬Y֭P[[{ofX,>w>@P v JKLM۵m pqvu+SHMAQ6kBtGeex<^s ߝ&O '[qG:esw|>N#r*uquq>yqQ3^J>|5JKKfp8&hw 8D,**>OIJHb5.׈yI mR H3FNuulΒ|2N9kǶ8 ?766ʊ*ʦ3<^&ruq}.BH6(tYKڸ0$\ Jlt$3,t7v 2X{tN8ڷk0dJ> Jft:D"544P *gϟoU AU|#,||6??WggՊ*ʦԤ-NNg /UUB*B'Uf-ULۡ5Aن輄hDEuuYfiʪ*psmR[VP_WpuqGE"+*^x JbX,K$ a2/\sewZVvKKн r! >| FYtz @ S$ϛ> y;Ri:a-]Rd MMM `Xnhlme5r.AԠKcq@U{- ;#GwWn{y̶7nvDMmѫzSicnj޸)QD"_?W*LNԱޮ^jiikǶ:9hw@yyExTtHDJΞ8tDdْa8.++ZF9B^˒cU=RV6)p2%5fM?U 4 0Z@ɣjtIM>S՛+T*=x(y}j^i邰5A>~$`_yzz ЅBz9i#G/nh5)dzXYQW1I&)r':L:e`P]SӨRMLMMFɒI0J ,FjJYQl81#nj/T%R/tReJ-5ɻT P,ݣ甩әLO+5 L}}"]^X,Dui TfL tzٛ(QIk+";GyY@5(+TBL4U TGKM`.)5S| -СD"yCp)'zzWUV͜=gǢ;^^|嫄~V6[۩crϤC'e( J; _dWUU~;zzzRZJQU@/hj@ ?k@ @0`SL  05@  `j@ @0`SL  05@  `j@ @0`SL  05@  `j@ @0`SL  05@  `j@ @0`SL  ?!5t~v CV,[򳣀@~8?!5I$cc?Jp8 N?%pwc0ڗCkhp8>C$BRJ 嘽D HQ0c*@m A{e 2("B0+3 01须 iRUNU텞 jk?tE #\:u2!t:ɔۃ'OjѢyTbIڶi)Ik+lCCHv:]V`?D7B׷D"yYLܒJSgd Jܽw豈P*"H#=~ @_OL&JM۔$HжgKGGx|z/^ovúʻ<>.N!3>{]ty͘17173[ձSGs痭XEPΞ0D"/] ~rl:{}PS9t1Gm48܄S"8}wJ$y<ؖP?qXT*ĤgHΝv>9xG5HSDXHMMMLM>v#Y|ꚘUA\u2q}'O*VTT`q͛[x~T;{ݚվuuu!o):v{gϗ*A52xop83B^;aPbBy^Əm¢nKJ{Y(o߾"ȿ. &'>%%]QY9rBĽd2Yii)«Wjnܳ?Wן:? R%_VT*XZ 6^PPh7J%ZS1x'}ler\.*@^Xrj Cg߾}.h~cDm1H4tpi?x_R)ލ(O8-4?`=xÆ&&&5H5!RfUj~╔o,-o﷚UU7 &j `0 U"Kѣ׾@uUufH,0]U1aȲƾ ajb+* އ'R<4-`JPx}q\RT*Z:𮹵gG'ȨŴ+f =}欁>¥}{h>xT&i@>>v(N%>c yP)ٷkeХ^LїsL&QYYYQQakcsNS}B=w;]!%j5\ʼ,ȡ75GGX>Ujzђ?,<W[99ڦ͛ϝsAXawNLض󊋅s,q}EoYh'8xu  =tK"lsCTT\7IGdrL1w^w-Cw䩦M۳k\&c0cOٽ'12beW̙M<-=c﾿vmOdL3"r64a|V֕ݾ"dfxSu C ngoaL@O(h-.  #v-VCAAA7n|n&H H uy 65} -keF,XVt6핍M˖or+++ x{{[ f^? 8ɩ/P(]~j͛{yy 8Psۻo߾gr:t,hߝF4p#1 sǷs. u۴iF yggggħG._4p\V 4oaPPKRs۷9ۻw#te!tK{ظ?~ Ϗ߲uk۬6QQ۵snCk"񴫛C9;wXRRΝ,_GM6=~?ر$kkkP(?n;=zb$ٽ'18xA͛c.FPm_3Tf͚阗m/R8#>1I'NS(2B ;zp8Ri4J~~qfff?v`A0a[|ZPEBN8Μ5+8(铧3O-Z8xp̦w;ZYYޓu..ڭM1b o_611rr|'T׮ݖ.[sǎӧ+eaLYrST̛JL&qHTfM+WN>s[Υ, YK _W?% cϟӱJ{]dsLLl{ .^̸)&$vuYw}9+rV֟.nɩե˚#׮#>{xxgK:~7lllO;nܹ3bM8;;Zhaiez8JOK#L\b޼Vz&ikk{k3>wϞ@(#tB!aL&S{v 2d5:"X\TdgoO|zx-_gg߬n;wrǓz .]JN>R T=BIxq„ .@yy\.'\.B(rw3SR_hQQ6Ĭ]I3}H5vژ1)JXXe˦L<|/ ^9슋`ݺ׮_5qSSSF(NjD:|ɓ']Ȱݷ˗0;;;ssn]oGǏm!юﱣG|||_պ{G7ϒB(--mРkW | ]ڵkډ| ݽSbcc`0 fl\LoQg yĄq_6 =ֶMcnj!r[FGG8y<}dСyyyТeˑ#Gi tԭ{^ӧy\;b떭VLz*,J7n,qؼys+k }8}۶VMLtn߾L[Zj5q~i儣;72r F KH*H<}ҼysRv222ś[B4MTUaԸXCxV DD[ml޼qȸkjj(d oP8#1sBamm-JKKK×/_P(33ѣG/^4j3g4,T*3,Y^/|.|7A=z,**<*}||;gV,p9O<ٴ@sIӦ7G E!!wܹuW77ᣡCM֬45 DRqlfT*B9lb0Mظc[v̘}񊕫`Sj5no߈ BqF|JN!16kj{z dFkkk ^3gΞ9ӱcǨ蜜QȄf0HZrF, []YHx9ږ<}|}LRƏGDo+W^)4ipAFF)qTVbp:v0׭[w6%J;8ӴY3͚7 7nҬ)QG xOҠI\M7~]ZZZضm[/oo` e鉊oJR3q!kɹsð &7"ׯ_YP`jf񣼼)S^O ՕxxFm,,,%]ѪU6mywwoW?RG;\.w)<Դ{ǎ#jѳXX5P^==n}]|W^eX,Q-ZT3ft)#C*z{o#J1ִ+$;oddDGyImiiaؘ1c\BDLj6b_v->>pZ"*0!^={?;w8r䰧gqF|t\8i҇,O!gΘ:"b! vS|,==8Ϙ>mÆ S))g JRϞ9#6lؚPPPTV&;и1.Y'K:@|oeeZ>wѣի~?|Cff&>..2rʹii4k-h5R/qsi@4 P(;Mڔv6md^΢P(qqо}m۷JNV(ʋ^M2(JF:;;;;;7(=mZ,Q o~ؿ8#>U}BKegNiSYW^^ؘLVى2MFX܉PX`kk{lt:JJ PT L&VbX\) Ap2[UT;oܸѮ];d2ӎhdULLLlH$ұ%Sۍ6f vT~(,,ZSW# UZ]sIxo]Jzc iZS%u 6IDATARP(tB9Y\n>"(6CulF L^|A >6_4TmDv> oLħI I A4T?v O<#τ@ |* gjHX I I I I I I íP(-oO#ozȈ#˩zD"^HGCTiݪe^~~KC_lceem濷jճ]t)(,,,/ﹴ餣M(#&lv((xfJT]X '?<.ЀQ_Vs|;Qߩʠ$ t7 @@5OpP z >ppr8to"i@|h4Sv5 ZnPQ^~?)wrtŚƍs8[n}\a7ȠwN|!P͚2觟z*|y#{&}GP~& Ǩl M(u??*XZZٳgUz8p_R(~v{1aVG|rb4{'- 2/g KJ̬߽{/h~ UlɲE#Wֻ{, ZkCR,k0.#^1_ccȈ5AAA  +,,=ztyy9۷Ok/Yr5úÝN_0h~7_{CjzkVp?v$s(0[`(W8FFFt:];9a,c$7GҀKk֔)ΝT*I4iˋݾ}aô4:*jӦMϟ׌{{^,<$XWψῐJM4qǍկoJcc ѩ`Bs|>߄ڹgo@gNڻWOJUTT?vÇ :WKxIvIΠkFd)fXTT8֭@UZZ L&3:*ٳvu*;S\\e0o-Vը ,.)T{{'LQ:PrrrZ4kv2qxfvҰAKînټٳgD"KKAr5g&M?yR*BPYTQT033+,|݂9I7nb WY I=߼yYf,,|`Bo`...W^^~]9snKHUa0n:~԰.g], Ue#?Am٩嬫Ær9wz2{9D$߿`sVjVV;uM(#ud9?7m߾@]PwVZaFѼ}}|6nڤSݻ֭ xhv9);_{sfvBI'N^XRRr3gkۆ̌bXLL8B׀KÆ@}> RGpgro޼Q=6#dRhFӟ|4ie۷R}dzVcb͙}>\^(~}ԺR9ery ݐN/^VacY^=gfQI i(ݯ{#F, (ab>affR^XL:!4HRMyw&O#H%b=B!'j\SK6s޹ainh.8\Χ7 H\qLH'JE FPU@A5Oȟ4$X I I I I I I I I %ỳIENDB`RaySession-0.12.2/manual/en/images/network_session_template.png000066400000000000000000001777571417052567600247210ustar00rootroot00000000000000PNG  IHDR; pHYs+ IDATxwtU;e{IJ A HSzG  bA"ED $0l3?|$$,73o7GE4n!BnE!B B B!#BF$!r?HB!~ B0"A!aDB!È!BVZFJZz(-+reYcMi Ÿ?QUDFDVSB=??F"S}YӦ)ɗrrjUSM7ovU#FRb8*@u~S1A$]biݪ!rʟ P(JL=(ʮwVA=b0"AB@}_!fa( :sIh9XX0 m`JzaD ,C czIgl#!2 sdX,vNlXNB^SNIzaD >2t3W$x8p AA(o <}۶k'Jئ}]4h4:tСCtttx~e㏷ a^$*xp 4 c ifbL&Lpy,,T*%T!"(jiÇ|R~~~xDĥKgNUZ0Lppp/aðow D0,,;;{׊;dUQE7~Ŋύ3gE jLZr^Ñ3A C ~wŜ9g<(>>}ΝsW>g϶lݭ@ݎ(//Vo @hU; BD*h ;v[/\п_QQQpp=6nd%oG7BBB*zzzv|M7q ,HJL`1cΜ6,ZӣF$xzz sf:m?+5ꫯ^ZuAO5rDJJ+hւG0"A=( 8_///[ΡsZNq0^2PU]jMɡi_VѣGɈSd2َ8Zrݺ˗/)~q5>O?ȑ#wq>IIIǏ[3^}etrr BVO@ST=__ArFZ-Jygh3ވaniR@QPaIqQ֔S{}-5HVӷ:c222=T_hlT48ӧV:}9oGvϏ_??h2n;oRrrs"T} CjU[.q999iiimF$@@ ι#_yŨiK*ddF0y Շ~#cm*l-))IMڣ{˗K?ն!C`0wyֿp͛Fz*,^ݫ|:o`ذ]bDRrm9 /.}z}B+"<ȝV_;^#k@GpZjFFFll+ݴqٳg>s\AKxxD#"#ѝ:unx+)]dRllhhܼ4h0ԵkW L2/4}fϚ۲u۫ÊU{U/cǎ9|萸9hnݻTynr_Om6m޲uK;v[ؤI"Rp8Ąjf+]Vf3.iC;SRad|v镜jT! (8vhrLӉGq\dwf,cVVVF|K;-{ĉ-//"A~gBJJJ^=Atz9-5KBN|BcNw5ƥ:Hztޫ&ĺJu:e20ڶs_-:$$ӏI$߷ozbBȻsfpslfGqwc+Wv"jpRs\\"^One\C]nmrr,N:/O: a呣4zBN!E׋3˗t8l&Ab"_p_Ic'_6A֭>   n۶Wb6x?-D= tQ3 xJBrF"2SbwrRRdx!,P{BH~ņfaaʤIsϋ/%#kOɂ4޲ ^UVRJ5σ.;5 Ҫ77cR/pR\\B7޴X,s^C(2J2P V\4 " Q+F׀k&4 j׷݇^ӍDW:vA=j<"'4|MxM7>?a^|,4M?vj!r{j3qJ۾#N|ݣgoENNN=}||^yUH$N`nW82B!ȫum\^}CBjB!T)HB!~Ԧ6lM@O*=ݪmQY9q=!~![&eBG0"A="4ۨw0W\qc6Iewk9אq.oC™HO!TKhBճK}>"Yf͹FZN{-#% uC59 =G%EiZFZYY!A!k( ӄ%2N<}$S Mڧ8ғh ޣ߫HSFu(¢뭜\ryjʪJqVשBj֬JJLLtwC`$ FswCz49ғO2 I>STrA围?Ջ ^,+՛2fp4 Tƍ/+0"=8w7!T 낟$=ZlV#*53+N: ]i+fe)GP@g J*oc^t1cz뇆+WTo3^a^NJNNvws!0+RT3&3 PC~I鹅Y[nrO\*ͷ9Y+LXW*U~, ҫW~3%UƏb ƌ3"HB5Oִzu~"q0\.( hP?3ޙ3VkB'@BI$BTk3 TCj-f3 !vn4vN:mٲYVՂ!Cid?^K=p`?!$&&f_ !YYYNܰa[چ ByY-Iq2 J#[ʃB@YfEE:NI4 ]ɠ/q-[_1Ͽ{K,=y+x|)))}TPX|||$ɬwfvtj*~w̙o>EQ}\&{7Ӧկ`cʕG z08~bҤ+a\sf#G0Vm8!T,f&IJ*@# (fh)J6](B}cddd>4=%]ט.۴) WoĈ]^ܽ[WH$,o0LF4vAǏ׬YI;:K/O>9sygwERݻw\l6[H2"B q,˨(m뺷Kā5$3+j2 S<Ͽ֛Jط#Gܩׄ8xϽ RS: m[ti+v@cnj5gΜ4pϐܼ%ѸY5Z=F&,48̔o&R:W>TQtt3g}-$)]L˧lzԩV8Off,xItVo>Ri*h4R@d2aBc.wpHPLX?z6߬V1KýO;wn22Ayz aMlv#G9 v(ؤsg( RSWN@ HPHBUk,&0އ{h9{D"INI Ie^ \FA7+dt9)';GRUP!ÈU5\C|뙛x$6nڼv#+;[Y>@RҿT*ի0LV:...[.1x94MfegeݸQ-Vs4Mff&˲2iӦnԮ]V-yr;f5# +D_n]*HqE jF$FZ7֌[nzDݪu={&֊;݇V4dXZZXҹS9ᄃR*We+WWION#G] e¯ܳ\.F$E oק(F敔+Eկ_nXV1ÈGF$VmڼeOn+(J&{[.Xs4ir[DP(v{i=Q*F[_}nHoάWnjm&NWT}_/ƲΞ;׳狥#=_Bo0=G5jݺx60,s_fy'O6oЪ³=.׋/R|w#HP6n_bY6==ח_Z;,|fn^k33+K|avG=H֭%݇/ZuƮ11`4CŒ5h'ۈ;?G^9m]+_-v_tyȐfTTx3XMvt;tn+B$|j釕{wv_ _ !o>K 0 aw8L&]XnB8MNpp'Jr8$X,t8NS0 !+''V. !T#p=TmYWZN﮴$ iLE\9@); 6r|ܸ1?T\V+qeYe8#(((**ɓ}(JQUPv, IDATPp)Ag(8j B5#T%yKcbzUiMGzR7`T_?ִ鱿c>%N'wq1ٹL8HPP#o<_Z-7 =]A a:^>ZD"J(B&ɜkNidRafrA2&9jE"R)+I%6]#U+BG<ψ1"AUus*"[54]CwQ~޼l4ܦMspֆrv(I5JTd瀑*ٜo 1B\kعGw#0Ce2/tֹ'B6 d-BP X ]TRh3;%r0i *2ZwP(:tзK/%44vDpСywI;6-G<_8p#4 @W*N'nY#PZ6uSN0ɛd2^.,]*izH(6|QTFa˲{۴1s(B!СO<˓ϫw찕^xSPjRT3d2˲EBhJ*JшH$% !DPxzzj ;e߸p#K,1r5y>8i0_i,⇕G߳'.ngXXc%s0̺u?O+|λ.zQu9qIIM͚ԯoP(-[tbzp0"AՎBt:vnIAyY >tw% ,(V²,#;>Lnn.q ,htgp1cEQ1 UR)0<Ϟ=kQm.&V CF\숍Z%Rd`IƏxᦦSPLS0Lƍz梟)Fedd,+Ž*x-vR:>gy֬YÊ˗/)BDszmoܸ1?BQϞ==.\pL|yJocc/\qgMÈ!TKhSΙ3gX%pg2y^j4 !<䄆i>_q߀@Sj*,.5kJ*[ b"##7n7%##]lʕ giXƈ!T!%%%DPp6lح[FEE={l6={nv<8eiӦ3kNSqo^X_q!~ke[z˿˛;a}AhY]Vp^B׬C ~D 8ĉGpgs;<<$4p|$TDfhD gG GKґGVz윜kr K$!*==3%ﶬ}[=@ž%:NR1 j !ۛb4N'M0`aF\.j6nze.]Bj&l6vvTFB!S,UTTej˲eE[X]:vrOPCFGu⯿/\t!͛9⇕%[&,d=_)[.[<摼(YiS.` ThQT,ZVyW %ZVihT=ʍ<5 f* J8.\R$IH#`9/އ{ @Qlt%%%6@Lq: l6P\\lZ G !t#AUuwy긏7o]z;;UҼy?}Լ_~Y?-!nFFql'Jt: ul22?n۶uЮ]_/c.Jo2tVoZB(`!frlj<ѝXVLfXSJ{br e!Z6 J#H'Zm _reGܻgMl(2R,ܶus˖-~ۺ9~kr8u4MAAйS;~mN ƏO\Ǎ/&eӆ{;=XXN+?o}{ߝ3t}FOk x8N*l61R,l6TZ!h>@8akں7įAC g}H%ޝo[a n/9$((跭mm-6xyy=/^Au͵w]vӥ3%_~ٹsM%xT*.^tȑ7%#P0"Azڅ I1]$?qҥgL #Ç EOOς#JhST:. 0̙gΞޭϿҼy3FsG  sR ,MFK^hhdDkcƉ%bM}^;B #T{"PP>2xg|\T\<.5O8IJ>̪W?vޱ#WM7vEWw?׋KT*Me˶qc__w{nñxvmW uCJZJz9׮]8N%Sv1K5!THP *5+0EEO~[͒:PR\|E5(ڵe.߶eS{m׻O_>{sCffTTTΝ'O Ӧ.f1C~^ z^RےI:_WbM\5BU3[Qٽ{Ue'OXRRŋРA}a2L.ӻWOׯ&,ͶEӦNj5*alvޭfzqo1m⢤dĊi+>R4'^̬1*nx{/^M]h~:;B#AϽ ˗/)JP\tiʴ&jݪE 4hfJ٬R.)}?{)&}1;[3gϖ~zmoG\p|-K,Vf֮['0&/ p>emmZ7oi3}d/Tm=W͇t7BnJ{覊W{wΜy}TC;g>Ue-[]T*#2͵6#E2u8>],q2҅=]YUGQh,;'pJ{@T}_!fa( :sIh9XX0[ m`zJ{d4o… lѢEVV0LuıX,(|YΑuE٪JkH>N4qބ{GRTTT[UYM 5% rxp r$L1bbw:9b;A yM=6^V:9&Aч k֌1w^^Q46 vYt'}3>qc{|`0Nt?yȸ\$K!H93+Ok C)7n>BaDDVrjQyTxG1vvM;@(Jdj44;MZՍ` )1L΢罃Xr`6 B5Yf**11 U%>̯8+?0x6fugjEp\*(pHJe !E 54s 3<|uu(q^PM7~\!B9(FM<<<l˗|g,DF6299o0"A5E7~Ŋύ3gE jLZr^Ñ3E'`v8v:q+W;wرc٣imx}*#Ͳo\H@@#G۴yXݴyС=B&MJolȑ ^{L{nN&#={ 襗^9ڽG{Y՘ODGG'$$ 2w9g<(>>}ΝsW۰!TK8 xnMl­. pq"J9§6~~~*V^^}ɧsر&_~. 4Md2&˰ZEi-^2f cc':y[/gΜb%oG7B 5ꫯ^ZW4xQ#GmG @HQII~qq~qqNiZ \^XQf˼|[Ih8\k>K@~~ɧ9zѣqq;Ο?h̜ !^j5!G {.;;[EDDGqgA$%%?nҤɥ Oګ7>WPXP A=ۓ**AS<MQ|}A5jT*yax#:*KEAi$⌴TXW˿]>k,J%VovY://--sf8ew֬byNvfdddT,`HM u8.'''--ݕG$)WEF6 kX A=fK]vRP@W^1nڤJ2,951LCHXJ2[u:]rrr=/ZTf͚u>}n޲Zjj.Wݲ=+EYYYG;Ѓ#"<Dgr +G6mREUl[?CCCjzD{{yK$(wHBJEIWfx9lp9r36}_ǎZU2w^n۶Ui[HH@CQqWXܘ1c_}[ B[*wN۝sr&EQ>׮ URd2!pVNQV5 bsiV(fj*j p[Rt8VP(x/{:jِC۴y2R8~SNnذ|jqwEh C4UP/4-vq4mvdF|ꩧ>"HZo=|H¾SLb][n;>ÁArbx|o¾;{1ZXxwMطoC$/׭[wÆ{H$MV lڸ%$$d^Q|NeկkիVxŹs?Zq m۶MM(*j!`6yٳ 4^&M~~DD;w}qq; 33sϞx0 gϝZ>#B ))iq˖}[:">}ƫNNNvc0!Tfiڨ3횔'E@pWnm\gܞ3@*jolݼfN-Oۺu܋/onNX%#3: /7׵c0Fb  gΜ_ 9ç6A`0RS@ݺu9IKK+,,toj0"ξpBo5yHpp#^KV].{|\9T`Zrr{:?C 72 4C!=f:tG۴ٶfR\\ *N!Bqqq@@;? 7'HVd21Dެ\TDĉ`kTЃ'"<}h9}nqСVZɲlׯ_r3>S5\./;%<<{ oϜټyǏ=zԍ§6wQŲOmzǴzmcC D+dG`;@ @ AD_@ǎ}N8QTtGz .rd2Y-ɓ'9%oW 6`N'?a2ero z` D;vCAtk#"iҤqVӗ/'BUg===["NiJu?"РɥgiRy~^MS瑌yJR3suWIQQ5 eEby+}o) V"1wydjպuv hRDd۶'j{7o)IyFDҺUiS׋cDЃcU iya'^'R {FFCZ7k|XRXwaQlmߙ]nXPBl0@vwk(``*eK;1^`A9{杙eV ަ(Md!L&3$8Rzaaam^^ZZ )M4IHHa0Æx t]Cڶ555]t[ nQwjTUJ+*<@dp9LFZR0512TWQ մ 2[EKfMuv6g\eeSA 80''GUU5&&fuU2PAPƌxbII騑#~vH HRKSYS/%6&Tծ:$JFMBJ$^H`$)R{ ܻ]XzՆTUU e",' 79v?g6ib֪er IeW$IUGM/B=}oRifffVG(D$-F MMM#,Q\v}͚/^JNNNJNNNNNNJ.-+ý !1d䗕jH2K Gא$IX\"*AT5{ 6!E?^rE6o  =r7K߲m{@ƍ7}:k~r-ɵ* A$%%%%%ÎVyy~vntW~kiiӨQQ;<8&&v: G Ҳ2ߩcbcWZٹSڷ۴~]|BoQQQG 'ضmwj7"R)ݽ~ݚC}JIm240ؼiCRr䂂ZMԁ R~bDCSCCS畏 ȷ*,,\vÇY,ҥ_4tA,999yyy`d$VDEEE:  o#yꕻpWWO8yꔿ M>~~rt`0$IC&oZZS9i4Z#ccSˣw5???*Y f& I^& 4 3g8x({Fݻ"Iii雷oSlYYJ~M5ï|a)k״ow괇k.ܬ #3iҸŪ9۰'(+SOE"сΞ;_ga4޴aX,!5053ӽv aG ǵQcㆎA?kŚ;wwPUUuw2{Leёijj.D"QJJJLL LLL ޽{7zsN6wJVf^cF  o#i٢uk ((h u^~}رgweԴW322D.8kkkhт`$AӨ(jkƍ45>~DWRRhT\!~8ncmm``PPz@]]#66VMMEeaUZ׍%eNNp]P)M4IMKFh\GG8!>AVgѴ NȈee勖,J_QtjFF>'U8}Ç_Ϝ5'8$Dhx>}<=.4Atu_#a2xGf};f 8p}X 8:88:8@II 4dhRR2lڸ[ .^ 3yƍeCKJJ֭p:;k;vL]{`ڶic6:>5H\7Ϊ=h|ۖ:::G߶}9 㟛 C.**ܵ;p;.];:ٳl*'Omٺ;.Rbgե^|J@@auH.bUd3"E* _emm""":M >:ψន&yoܴV^}8a۰=~@_E^~1uԩm۶IIɍ7jdl ;thRԶMx0`l߶E Ņݻ/,^Sϩz{Mʺwヤ # l`0.[^E'2}ǎƏq c;BhXٳuttod'm۶6tH$:saVV|%~ffE^=opϠw&"giɺ]˦Zvj3b;͂j?{ۛɯNw=܆ ~#._1,[~n0Μ1~3f -Z<Q2tΝ:ٵm{ݺQ/WVliTT6m <C].eyxVdff6o.KS3gXcϤ ݼukk8а0]]{ ذq igΞS4gmtq{ieij$-VEHD5) ySm+Wl߶*yiullhظ,&&ÇСCǗ/_ϭZͭꅆfV-xJO< 353SWSH,,,*}5ԳU! JKKo؄pf3 5aN?6d 062Zhݺ5]v7n@.LMM223̲w@(uͪUիV(+8x칪{H$s5uOLf}Ϝ>ii٬Cz֭]s!g':D"ׯ͙=K T]m"66=EM PSd3sD39,VoࠁfSMMСiӦMw3bHv;wT((<+(Vc_YHN KTΌ)+&Zh 7m0>_XXH$~3fDDS\aaaaaa9X,CN3̒cX8lVG[CBIttt<}$SRRPzƶ_-j&;ð!߿A  4MfI35gフL[۶'9g|B[p~Μ5;>>o4Ș7A>8IQ#,-wG!%jgMWZLf>}wٝoeAA޽qmղꕪ#͛Xbׇ1 3vܞݻeklβ#"ݽz_(R[WX9u /^qӨ '֜fsox}VQQǍnpȓQfffN>wBHhn~9J崳q;Aϝ;F~@`I>!a!._100--OܾDЬ3.E> p_hpwwNdw|]zzx<k* Ok555333(++5: QONaиq# "=ܩQaÆGk/88dA7]~}> dD5B5dddlٺJ@yZZ+WrʷW/'_ryTӧO˫}}ΙSiÇǧQ]tn{c9@g=<=gud?jiӦkkkא>uTe>}Gb̙GϞƍ1ܳMVN F!u9==ӘL&hhhعkݺ;٣Cǎ* Ì:wо]JJ UrwHH޾ccFggn1>cFz]ݵNvq177ܽjꦦ&-vqVQVVP9kOR)F}91^~M5þzݻsh}=}##AqIɡ#G޳gg?߽\͙;ζjClRٳg&o>8.y=z*//O dff*JwqgncccxѣKo߾?:wǏsww?r0$IJ988@RR␡C?x 66k='O%7vLoE5ZJ֬9|ëW&nei _G/\ؿ_nݺHDqq[lB+yevv.:w@~TSׯ׬[_ >Ҧuk[۶kW=Iv;9G}}=">!a!$$KsvlbnԬEf͎;323GQ Ӧ4PTww{ZXXL:ޯ_Cdg1Oނ 233O:^i $UӫzQGG'#=]4##]Թ|B"PQkii 8ɉJMM/^uuuHOKy! pڵ҉̙s .f/OAAA|;$---99R'j$8uS+%|uy|2/Fkoؤ%:O$Z z9:WڅX,޸i;4Ytْ{O@oUeuoPVVx"RõCXz0[<ˡܕTdƥjc[z͟#}J}c~} e˖wNNޱs!122ԉv֬Y%Esǎu7|ʕ_5ztDDX,׿?N}W7'=NnНY9ϧO\.IeeeA/w̝ۮ}p>yJMVTTDEEgd*33swal6gy666Tk4LdܘN kA֕WVXpjIoRW$;ۓ۠ee7n\}Tغm'`ՊS#KdAn=zV֭Z*za=[?W"t {yap{}5fQVVVPPyR++Y<`~{il>_p*pX,VN GRTUUW4A+_Q=}bȠ~$ԫM7*nE3|^3bQ99zL,?~6J԰PXPPlii)|ܲ+3-㛝m5," BHAixяӧ[mAG$&&ZAAZ  aF|iiiUͼyFeցW[K'ihj\rExTUt⅜l'O)))eR23_0͍$cǎeee+T#AYL 'UGHL,{,_!I 0rٵ,׿ii 7Ν;h4ee\HOO葝u|&MF/_bC(کQ z'O'&&}oƌkHR>f!Obff6̝7&22  ROr %Ae}%Oݳ{Unnn8vq'''ysWY,{U.]p.^7~+H]& /ٰquRSSSSS9aFiS[."QQa!͞=k $&Np/,z6l~F79GV-###'A~vvvOUu!Aum[٤gdTH*$ /G_Ḿ^Jjj0,$4l:M|6ՋKK+S𕕙 Fnnn`?Օz(O>1dP B\^XT!yKh DŽQ|זT50 IB#GǏPO%IA=|  ѣg7jYsn\J7C޿9bk)%cg%QTW1j+o߮:C+ 4 ?]jfv''NzuwOJI+md93ȁլBv9bzqryI IJpj@F O:SYYyv@S$G<&!1iÃ

~WRr$o/W$AYqc-Y &r\w'N-ZLy]]T߽SVV&;3O<|806o9z,tk7O 3iӆf'%'Ϛ5'#3v~7f||U^"9;ǎMWCft;;w9bOWVV6e^"zmmۮ\tttsBĤǏikk9+WRAkʊ円[x A-Z7v&y{M6n===CSS>n###G^jjj/_3 EN0f&x@ r_YxtDyGE> wFKȘ:ͯBj#Zy&11IF &)k ᣷}3ε ֶ{O1s!TC~~5k\z;:hh0p#z:8=w~o޼.nnCG򕫾>«4&My<ޠA<ֽgYYYPS?9d۷˪#: 5۵o.z{Nrry zk} N˛7oiر&rt2mzzz`c- svquvq533ה%%\:thW-06n̘GX];98:w=?/{"8ncc=r犕uz&ZEGGkii߷۶ IR0])6]mM+))?GO4^=ks5ER |Oɥspofa=˻ٳ  L&s];8ӯs'{۶m}X[+#ԅkժ咥z9:pq\\2mCCG5eN:>jڤ $߀A=z:dfe:::P Hg_TUU{dXA~A?T#zdjbÆݹkPhIFFFQQ~II 5rܹy%߿cllDѳ%4'y])x5N>mڙ3gUUTLM˨ZVPh҂BEh71x)8\.tՋdbH(*.gccmnn)))q۵\jPhO[v]jj<񢸸B.GD@~AAԺb2EEE _I{q۷_ $ xn$0ƍqK'%%EEE>pЩS?1+KYm|x $*-? ^ME(ϿefMccc@UUuY&M>~p%%޻w-Z40Lv;F[G;;;;##U胻U[|ƫ U,'ojfZ.4s| ~3gM5rĖmoܸicc]mT׬y[BehhlZ٩ZY~Z>]t;AAUEe}̬033PEE[.7^th.g׮ϧ~®\<33B۷˩rB!ՠzՊؿ/ijhTTTgd>;oOL7dEU[|;cE7FAnN<^i/?|>p@Kܻw_QTo~ZhJUTTp&NxR ruutn޺z_ n]ع*WB¤9rÝM) OQ?R6~0+K$SVZ;UOG__?N[FqP_C? uL.~*P,BaGuAþӶ,--}6l Z(LMMϷl֌fQ?tܫg](Zz0;[ф^<@@́aѴ۰oJjI"hdl,dd? o޾mggg-`qZzzzzFqqqQ E455 BӧO@WW5j4wm@(&'n1PO+v)11)66rsrFyOl۴ǧNeݓK/(ؽ{Q#UUUS+%k::FV`BBHƍʊU wFu/А}PuElcc#]rl67doK٩VvA@t: F :t ՗x~8ό=rh>|'cbRbnn;[6LW/ JIM*xBYC:IAwnߺ%##3!!TG?}K"(utII =K'Oaف]^UZZzN'E@ܛ7~ӧM1Ҭ')...+++--5{AF6kZz: gK/do޾]|iyK/;]Q!Y~uDvb9S͞3z%22_N=ݲuMoua0<|9AX,s33YVΝ;AwG9q6S+%kZX W]ME(:qCë/9{ fՠO>QHlٺa%fgggW׿KrgՒD=<|䨢߹tܙ\!Cݬ,-ߖS!v9suVnfgg3YwP=~AԤfuI~nd\+~[i淍G䷆79GV-#t&1L]]PVŲ_2JJJ(3,b|~~~~5Migk;uZ՗8ZVVViUql'77W6Nd*++(:3NW?gNLEW N FSUUǹ* *$^?NQTHn^^\>Oggg4YZjX&UUÇS$.ȲC,݀]dj˦ٔJ_PA~"kkk#RA']׆$ɯ~ˣF%ȳh۷EEEJJJsξ|\yyzmJP[h1jȑGW srWW56x~ $e?VW NT*$jPƏ*lݢh#qqqԦxYqSdlkRQΡ{u fs~FRW~/[|V;g'N`0̥"5k+FZnMݬ)--}lG:Ev5 dӛzR 2VVVyyy]*eWH$qqq /_#lvNNNQ ?UHHӧQZC])w㸭-$uRB7h4rDQAMC'hѣFt}7i6l1vvv=z4iw8}R2v-hS9]bڻeG"UЈ8%OR Mڹs;w8tpFFDRq߿Q֊ C F||/A~kIL8^XmPg}k wkâ}I cuVf%/jKsyD6Q= +dX4M6#"XAD\R'[E賊ךQ} XzZGrQwԾ:y% tA R h.4m&ǪG/DZz"R hW5V>W[|w\PՑ=W, AV.v[iUPТ2}RiKk: ? 0$p,/xCQQq}}=]  ﯑륧kiiiki۰ƍy!?u.*뤨100HOOWUU u)uVnÓ=z4idŊ^޺M߽Sgͬ,\\\b8 0_CiժDEE={Jܹy`7b㪔 GrcO%BBBe?h4.+[ᔗ癏pJ5W\\\9D:f&g]QRR*..KС[nܼ);RE-Zݽa&x)#Э[WKKKT#A~#;wymbQvFNHZn;ŗQOPA`&i`wNn=rڶi}¹kW.ܝ7qv--Ǐ޺q]G[܆ p҅7e˖.pqW8x1kɓ8@=_rw|'$oukV2{Miㆪ=~\WWwAU7;rʥ wO0q)Nn\9c# jfV;۶eee)**[ 6mܰ`{wۉ&xyG?4^htÇ!'.,,GDjii|}uz ں]v g?F4**//ٳ粎Tڙ uuhk&qFFWj3Pݸy5}X6k391)1''.\8S.NNn۷mо=lڼ?gdenشNR>(ZZALyE$ _fs""":DGG_z 9ZZ:ڕj_hkkWVPPg t\ڶ2dp KTаysg[XXsʴi0o&aPk~~gϚϙ#wrrrq1k0 UYYY?|P*-7SRRҏ~M7DEEp153SWSH,,,7;CZhhXƍmmСCn Xl`h@ey+ىj01iܥKw $4lԈl6444jY<=<;lmӧMUV\qyyYY98;(+Sy$ɕצOMM:BT*JUG xN=MNNOCuURRB};\Mw:'Cp]]] /0o/8„ @]lU$;;{ΜK-$HRǻ~ƙ3g$'Nnۺ%+3oƬ{:?Nr8 7Q۶-[*Yp`k3Gw4wM?\ZR\ur1Gm޲6{_zdy+- ***bX .D|]_<}d!!>TˑFqy‚꩒Rii|s IX첲ʯebF#Hl֖L$3g|k$L֪|JxDkjjyyv9tɤ:=v\YBx\.ˣ͹d>JoU*$DRiDRQQqVU*-#3S箲?~=vg0ܻF A"%0 p̙***E֭KJx/7cƠAr&|ٲy+ɓcǎpً-9k@ x֯;}4ڶmm׬YbΙM rtt3wa<%ӧOmټ!A٣GS8pY `Ԩޓ&8bumHɭ3T;U"W2dKJsr_(g]ͭ&ϯ:owHUO`vvl4EDvu4… 4&pݻumU jc2={rrrء}jj#G׬^ɾ ?>ٹCv6mBxrݺu߯1c ;ǿ7vD//'=͛7 Zi'x[:/0K .ۭ[wkר.wR@WWO~rTQ˗/_zY,^/=rظQ򛈍"7c ۿ#9zs?9AJpe˗D|JJJ+WxmD"_SR4˭aQFC=ZZZ SM۷_B||vN.W& @ H$iii"aB5@_ a5zup\ 06nܨdihh`/H 8Ʀ=77NEEɑ$&M8;;6p*,JL&SYYY%j׾CT{*48s3̬ ss#IرcYY  R F>}LML[lphٲU+F-[d0ZK=V\TCtO$I4ƍb3%%%))Ѹػ(-wf ]:bb;%&V {ƒfO,QcIDD;*e۔6Hk}7sΝwn1 }y6,O??CskܸqllwA@FR\.~2}M5m` #|Q{&ɜG*AF˃`!GtNGgf~0˺0//N.t:}nnL&Dl MEznU 2@Iy|"履|><#WK*O_&LKO>Črssw[׮ݺv7dIիefeǎ]I\&kޢyDĹrw/ o lP( 1>#GwbVe7vBKΝׯ_,#&ʌ@ te5P(|FZ aZa]`&J# F#Bf͚C ~q%X Rt v3r7Lȹ6۵;{攭-B%2"^=/P۶mN8r`D^=ժU۶ Q"-\Zۯ.?ѫﴩSz;szn]>y#Q"';\nݡ'>ۣGFvխSOxDؙѣFUcG5kzؑ3%4aeƏ[귒 <=|."m6l!'>>c4 k޸aKؙ;[foʿSؙd׻xAVVV !ܩ'_~= ~7 ~aeKE|TW]?׻h^}ի׾7 ~ǃ=y/W,[:};w֯_/$xkܽ{"..nI X#8\.#x<g===mmmY-7#F+;ٷE;}iM4ٲyÇEС XbW_,C45x[tٻ -5gnBBBab6>ٰbHt:ݾn׿sٳf233 vV[Nˈ&M +1)1?_!puR(Dn^]ѻ\7nb"UZ=c׳gXXh1)EEE]\PnnIRA h:y{=EbJnذaΝ^}9sܴIK!2zU;匼FGbkk;fCL:%6`OHmjkD"++C,i2e bZj9h/VkBlTd;;EoT?~x )ϥ˗͝խ[)Ӧ!v޳g>ylɑ gΞSXڈTؘ:o7uڌdݻefeedd  <ƌ=$a0Ae}[ x&?,Zp.&x1k +W<ݻw^J3!޼7ێPS4 H(4 z!׫'ձC{GGGPׯS4/U&{Zfr>W`@ǻ|eCГӧN{$!0 EQE3\#999!o'_X,f{z4T& l1=&ӋD^6j_޳a၁<!ԧqq;ZX BR~4n.ZfJ>)eD 6QV׬Q B˖<|pի/_ݼnl^1r`3wſ 5Mӗ.]߰n]ؙS$ =~5%L9}*PsƟ < bԥZj٦jE"L^q<(h<)( eGfJ̝.]<_PP,\Ǐ;==mѱ7n,姝v\|gO_Ϟnڼe#j:~֜忔y￯_bP@ flJ7{&Ӓ #ծJ(~|;ҁ YQ5{7`TjK$v֖iZm.j8rJbmllH,9 0TP* B*jJ*瞔É}q,Dr7b6L8C p8F|wzw3å^u-sx[[#Z𑦭γ6}۫I>'o:u{;uQO *׆aRaV*a&/?0(}Kv]LmdHGBfE󶷂࿣WcPr}s@$IMҝt~*[t90>jBFK6R;iGBWH Ϝ XOQ| rدV[<b $ e]uۡG7nʏܒ]n2 zr׆{3lA ;v:t٫!/[tR6uZjc^=W[8\a&X9ApQa[`tZ_K-'<VBQa?= DֺB C/ܿ~h#|d04U|"Ik6`W2{'aҒ];0L}~9\8"AIPmA8wܩZFԸu5Go.{i}轶BKםۺۗx9-q/WD9]x}轍gmVs|qяg>Q(%$ۀQE iƉ~R3z ,ƭ >ޒFNp\s%l_7k=/VVd4e/1(v@F⮞JMjֆp6i 6ͽA0 CQ5MvcNjpܝ/8>m .f⓸E#! [#r}2GJH{ I4{~_^Y_R9/fJ+ 6NV.~E]l־{o2/3@׽۟8!hS]Q˫I^RLM ^:}W&~ʝe*i5] 8\jTKvFN]MjF'EOP^VEs4E2q괤xK +B(35Qc٨ 3QRYp،%%jEnnFʩʹ+U*?U/6gnuSb/-|Р+D\N;lΕ 7Hxp+RQ߾8N^J£9M[9cFg#>k6Eȕ;OeyqTUG=la&p27ӵf\i`aSr=gOFGTӵ{*wtB*ވ;W~tw?6 !}MFawԻ%gܰSo%-zn|!Dާild콹meV!/,VV;.5= y:Znn_VsZ<ϯӆn׼c/}J>geǯsV+r2/3rίf,E sGB&uvo>{~lNt}zȆc'~|`70xbw~ܸf ?Fų$>ljeP_wQlX0]pV÷l[>Ty3-Cj(0f'2ίU/Y6*ZEUYB-]\֌0Lb+HVϪ!ʋ-dB\_$jźXJVf4uEFmi/K6RR\R٫[@U;>^=/J֚!۶_Gܽ{rsswUzBOěK\\E" UƌӲ_VXܪUKPwPXwTf͆ :}Uxd,2F t%4Cc/bBh$I2"0bXՖeB˔3nBYu0tEUފ!c! 5<3,0J=p.q  j4M#^vڵ^-VNQTrT8N?z`dDx.]ͽϜ =s*Ё}uxvhdD0 `> agFYNw;99 8䥶mۜ =q3~z"fϚٵkf;sڷG"6lV>zb \fBy˦gO_XvT*E9;;9tCE>DwXdiל E DF>sm۶A <("{.E]7v Bߟ7l'Oua8.Yۯ+BO}տJY=`ۣǬ_x=׹E_ Gbҁ4rQQBX[ٳ+>>lXxh-rP$d+_|%+r|ŲgκsnBݻjƍ8t̙=}[l ۴npHiՊ}%KMv2?E ϜaͭZ/RAP(c+ч1ܵ'99\]][jӯhJ͙5s))|>_" !Lzo .}-ٻ ^=}|7ow%ֵkxDDEUpɋD]\5GGGs'5{wssYW11?hӦMY0UC\vRԥ+ZޱCLJn433JۢEsPN\NIMip5kzzsF ocnk߾X,Fq+~-8fo>_ŞcauEeffD"BQXXH䫴qcǸ8 ܢ-oeJʕ!RA!jnn^lHEDXXdz΋/H,Fx=hh4vvv$I4=udswmcGc)rYWT,:2uzS\nN._n0:v`0 ˔Mj4l嬬,ǥR)EWiiE8k.&%oX`5)51Ə;̩пc&$G7v{ܼykorr~!;+|%uhb"Ixk_VJJPHF ޽L&exx5N& N?|8 =|劇9srrb=k4\]wČ1R%>p8ݻwv=!2%%>B5e[zI4=Gcpصgy*0aa')/( !4g?t>`bC,\.W<[l#Hs|7os3!Ge0:l=qkcٻ.]ܿ7ndO;o%_~^\~ǎݲEŋ6}f]:wh4VVV=paYṹ]ZR'??ow\M1h~Y2Vyyy}7E iDO9."m U;a&4M_\X,V(% Q*U%WTR}x<I$IBT*}Zo0|B<ZV(R[[j 0RYjl#ԟbuiV*x/0yyy^2L%[z/EQTtN͇1>dx4MKR; #5jԺukKGZkO߄ ++ALLA2@)` /);nxUV r8ckFF%CCCVZ}D_ߞ^sKEK~!XaAnJRqg9o P9;F%'[\lqUm QbA̚Ogfh\Uzmy)Ʉ AM5_tP(ܸiϿ,>m*[!!B{Y|ydd$TtRR/|3,冹\.A\E$t:>A-[rtp@%H0IKKu-lT:aB PYJ;klKSJWH:ȌɹrkdɂT%755zF彶q|Mt!TXXr=z888y㹹!ۂ]\q.rر^kkT*-VzLl w w8z2 _F h/\hxxx,d$@X!6VsHQyBk .Q(pDPar!Gkđ Ba:::w-7u6zիW)IQ?ìYV0M.o׮mϚ=XS|>ߜ*8UئOo^{y%P=j Æ-?qҤQ#G3AFt B  O X[´6 j9ze$ V.%:LxF> E, Qi Tj={._bWYpymbA\r?Sɖwڅ2!Bt.ͭן[ Z޽{.ؓ'O&L)o{hɷ6&kDp>rnk A?9R4??r&2y׫G'O>Sʪөk~b[gB||:RTaaaYB鼼bH:u`Ӕ!C޻gׁ6Pa _>~xŖ H ݺv/[ۯ+mmm5`AFo(*--o'I:oH`yGt2S}$>RQ!HUרpԩ㸭;Ɔ {{{X\NLFD«_%Bo:Fcgo'_3}̫efdyyEfNN{`"IC ._󽽽6mzdG~)XZNHxrsssvvF%''Z6*Gt|aCwZzlj ܹիWlF"JJH$jժqwnݧm\.o={  mmmssrGcccӫ/0uի[!??_.C)BH$3ŗb%EݧԨ(RQ_ ᑝ3!C2 k׮lwwL F ծݲC5[lUF Xܸq;֮][V $Yv޽޽{gff֬YJog疝PN 8sh=z˗/E"Ff s˗/fXll EQEuFA;=++?6|eyxxbe%;o^ƍccc^j #T:/FQ6j!))˫i5 ]ff.B+܂ƍ[7j5_2tͻ=[^Frs& !4k ߷5x[x9 BBiԯ7^f͚k/_t'RRRӧN<ҥme=EBBffzj4C?!{2<2@iTPjq2[ |Rig'&IR̲t:2W$8! Jmmh$W\}ZDzतݺrZm4˖D"(pulyzzzΝJ%I?rÇͧC*5 @۴qcSaΜ>m` #TBRYhXu IDAT\}A(J6fe JepT8k4dfd2).WTj [ !ad2#,ahJ-> #T:Bg6P "bB Yls!'&.y,aP~~A b*ݝ;Z-+F{[7^0 ϟsC`B QTAJ-{~k 1 yXv"@Ft$j4It7oYAF f^7oH&XE ,2Xd$>>gΆ<{ܹ@GDL8)Q>~СC 'O|%o߾l;.]rz-[d2~j*ύ>>>ϟa"6^`:Y*6HӧիWWSvQwѺM^+Г]tҹeK}?!|G.]0 ^{t׫\.ƕ+Wo׶{m۵fpaիאʤڷkۦuZZڸBvvv׬7on/:N xR6SYzGڶiݪe JdTcF?aBaEˇO4iO>Tl|{\b;W^h"VJHxNQFvrr.F./?T*Pǎ_$''_B)ݻw=BC3 CQ+5@u9==]Tzzz L֮M4ݴi#[yƍ_|I"T;zIPЄɓ-1c1-;Ƒ*X,[-[Ɣu򫥧߼qSPܺ}",]3IbVֽ쁓SVf<3#C.3d&$8BnlyFzFqrrh4&8K2FʣV#HHNN͵lT*mK._Q7>رEKFcccӫ/0uի[h>utr0OKK5jdš5kJ$pZ'''a2O :a]vdgfZ*Xmڴi6mr?}HѨ!? \hz˅ [iH$gΜ)/^SӜ8;XYY%''?~xܸ! Əpq>5~~~u2z(]vwlTGj$IprrrJ߷5x[x9 BBgݳg~~n͛Eo͝6uҥhš'NݳGdeeM:ǟ~^p!BH2XO6u qѣ  G3\̞2ˇF$b_w3P;wKܻYb?ޯ_?vw_Eo߾BrZm4!Z0LT*KGRN}ɤò1 z}_vڵkNLLLLL,N=a}$Ft^^^e?aRGQU üWleg_P~.` ,HUG<XRdKKK+9sU #Tɓ'O^+P5jԺukKGd$ˠiWum!hbh(HCu,# AAcǍtAF !Wg{P$i&#FSIS$0XnnVx\[UV>}aÆ6 wTr, B,x<!+T4E14͐$Pڦk.r寇Unݺmڼe]m4hv>>)MںukpqF7 X0M!bEn"/ px4bPY3aBPf;7==!$ 7n/O6웨=*z ABHV@kJuݻ7l3E+x< C5'% 0eV QQݿ0iiindd`%%WFD3pgap"n-8>Ml:*,,\by=.]ٳ˩S;u|zB3fΌz3W˶Pz={޸{K;k}zG]N :Ubߨ~u>*#'A,M1UVZ=uhs9A2,'a%rZm4]J4MjggT*Iudccc0؞@:uQO 3G2H&pA *W}2K6o0 {t!hΟ?t l0~܍7rJMGB Ô5OP+)VP #T_.p98Np'p' лndSG< Pe #T !{;V gE:.wٳiP #TaZ6h֤VVz b(+alFr ̵Y=k"JF,H"'pm@(#AF˃ ,2Xd$,,,LL FU,& 5D111!HUiטF <Tݏ; SĞ!yE9_Y:R&YY #^:u6Nh1 \fR\EPݵ}V6h@&1 R5M~8VZK/t C&H+>>@F*-e2 9y\>3L!B\.G$,LHB -wagw ZDoKMϘ斑n+֨QcU{O􎬭eR Mںu+Iƍ5k#PUT*aL&@8CB$dԬƐML[ףKv.]Q[3СCB!:ty˟'C5j5{af08tBh4$Y&M&9a% DK$F0LjX9ab-[9:8 ^$DE]dw äݺu fg/Sq.G^CRσ c3e2 ))8 R^qA..!WWw\|[d2{E_{D{wi,{( '- SAcODA"2:,-R@*(MG0nm|߯qyr{s=<<</>~'O`A H6mޒ~:9ٳ8s`` `Rrʩ۾s^z>s6>~/ 0 -#G>ȓII=6d[c¯Ft4״U#G,Y-\}رŅ!HVkdȓ- %W pp q sn%,LAkF[zc.+a6C rqqqNN\ڵkwڥsj &fdaQa_x~qry)^6999 ^  ̘!|d|~x˖$I@^^ܹszDv]*83fL𒷷O?7onoO'*Vk{oA=N}}} j5~„C1IoM4Lwؼy˲4Moڴg^$'n׮ @QTnn.j*-ThhL&̼Խ{wx۷m2Xꫯ2w]\\yڹ\eKU*t}ӧ //ĉuzR*CCCM&SaaaDDWG{t:[=\kq)S&ONYf5qcǷ8Pzh2ͺsGBQ/|ڷ/EQ`hٴV  2L`4:r`W^yM6noooFm+$~!;y7nطoK0̜9s{LVTXhkKi-KΚ]TTTXXآEPֵ,ROiaAd2gܟ] Q#%%j&5Z}VkAA{JKK[&hhh6knJƢ"ci)0 Ų,ð i4'kJKJo߾nݺ_r\"BUoooe  ē'tq{)r$~{=( w۲H$@VN0 ~Æ*Ύ+ƏWyz|!!%qq GDG,sΒ?SC]cX*kL%% `Rhh4|gwvvw^VV֤I@Dl䤤$r ##ݻnݚ5{-sH$T )ɣF5Č|T3r*tڭJΜ9ݺu;GmIaa m60F:pаƏت!uW0b٭Vywm+,LHH3g,yw挕V$I\0}ݧ-%fΘ矝=w^ys疔[vթҌFcrraZm~]TT,+߳2rss-[2NG͜1.\ c7Fc1B2NFxc s"eۚxSs5N53.Uѳ:$NQL~(Nݥ gxL...&>suuUT&)8;ܲ2\˲R="m7E"@ P(56rEWwbj A0,#taWk+VP^/ᕈd"W+jUQ(K7_WXG$L&rt//]?޾g{.#@#GܹLwSRY߿{X˻xB||CjDPpv{ٹRO>~?mb-o ^~}%Kohnkގi҃QK5pN߿!vrڽ5Wa"##E"qv휜۶mӨoM߽ǩ fկ`P*4jujǟ5)UJOg< ڵkg0J;wڭ[=fhWkrcܻÇI ЧOT߿a4d=A]~}ʔӧSq֬oMp GUHj:hh}ᄆzyyIR`???L"Je2Y֭bGxxxSߩS'//::K=\Zξ ~~~͚5{:*kP AAANNNF$9;;!|>2>>>4M4eJnܸqc;nذQ;)R楑#G{ZNy=SSo4Mӿrp!ssSRRАⒸ#YݹsgIIqpppaa>Pk߾}@@^^"zyyT*k[?$$D z// ]zM,L&ۀ!C>;__=z/ ؿo٠ЁD0~|DDDTTߠ`V}$5͚5H$ӦM 3 SNqqq˖- gfm۶%I[nՅ[PőΜ9,''')9Y]p񷔔Tjf楑#G-Z#~x_NvvaawzZڿ92NFxc>>  BT*XTT\RRP(ryQQ^'IRV$juaahT*:N&QeZsFF wsuu3Z8nWWWjo8Sukڗi2e`0LUn;׫,MV 7m*e٣G8;L$5OHZ-0:N dtz$i[6LP C;+#ϯˈT&k5E>TTAP$Q Xl :VPojYztدN6Ba"A{r:vKĮ]T*UpPpACD?L#Pߎ$U*f!80 i4UbY6--`2fKng}!I@A P؈" BOGR/P*.\q[#=%0 ԔpGlm+ PDPQ#)?RTBgG!a BME2z8!vB BO .!j&;w3 iHm\`p` r  pV8߱s# \Jea X֟ћ*JoB!Hz*|- ` t5q=I (+ßܝ<.4"˲fexzQ9i1jtpnf0,Pֱ=vD3,_8;oܴ9TZbRi|0006l8fX>Ϝ=3@ +O'|W...sSہ6޽'K=u)/WWG}+~WԲU͛6U>~5駟#7ϝHLL92fŶ.>vXLGՆ}$5gNڵ[PP`=SV9sXr-z kTN_]>F#  ' v|^6/ӾYײ>4sLP-˼mp\C>O$̘9Y"Mk׮3g% pswIod6.Z0QPh Ur͟'OW^y?6|a:?RtyƎ  dgߞ8a;vM]5#@tLiƍsMGՆto@mrb@ɢKBCA,˹.ulas?9Z/,'f/ĉo-XކvЪU~ w~𡨨|bO0e怀p¸q}eiNO;կ_իݻw9[9Օih۶_haPpUǏ{OV|q|L$~]~}ʔɛ7o)Hf͚=qxǎoDPQ/ѡ,;$pEld2vi6i#[3~&VF@ 5>30~iO?gEEEja9sTZTXhkKi}ÏT*}_zѐҬuJJm P),,((2 77HdVV֖- ''iۮ̼ 8@AA-N!juvmZ+--ulUHB l6X Eq,o뼽8}p2mt~5AO8XUQΜ9Ӻu#G$* ;U(7>fzb@ -)6oڔZXgW*Ro˫,zmkZ h߾C@@&Np';PBCBKfYvΝ%%FvxrEj2x<؜eInQa\ݴiLlI$^j-kٸGOTSmAz{u{ -m+w޽u֬ٳmC"زBjj7GcFÇ;w0#GN28 x*5eV=zܪ+~~Q}wfz>sza{͙3z8KHHCbGL?>"""*oPpcDjpA'&d") -*3zR1f30 f3 c%j4W>s6~;v|k:sƌ6mڜ=w>99aaիbSi'N& B0؝;M-Dſv꼼RO9;p177|bEZzs{]]hڙ3g~܉7ϟ?.3BuŰLlfeeed=9sf |VEl[vxܹƩ!_{F3<۩cJ1Bxu.祗t6I/_69cmݚE#|js(}Um~/\ZmnU ٙ Iy\nYY05J$4M?e 2ݻvWWWV[y@ HJe]p$?Te]TV7^QaW{^zVӈzjIeRڱ x7{줨KAVxzcb\ȥTp h`d5b!PN>bXUThj\^!h4*v(qFcIII2 SZZZq*˨|rj[f gbQ=7$vRO?̥˗k]DB!1!rB=aS>B 1h@{9?pmn'NDB)rZ|r k.00l2]z5??ުeKJeoiѢD"rJV\w vu6DXhH+5oDün5Pzz_r < B<zժQFUL&Vz>|{Λ7$} N>ž}m-[fv.^h@¸mZoϞ;(+SgϞ=oĽ? ''e_ž}"?FcQ%2 jx yYl1UΊO>)..?~dm[>x >>j֮p32;A-Y+.e>af;WoŠmϝ2vdR AO h4VJ, ])t:{ A"|K}DB?]`4,XjrN: 2G;v숉.H\]]7mܸe˖Ff=./[bŠ$cFTH|}|?)o,koM7~fݰ)T:̙5SPt.a={;>z4]Z*;1e٘7xբ闯,z$#rxX{PTd"hY-rݧ#K }j)77{pzTҥL$Xކa"A!OXΚ5kֻ%/5@ƥKNNN=ŋQQQ' \_op|=lAďz,Wϝ`P|śb&T=k0s_,kΒ1',"WSU=N?J[_n^~5o/Otx!PGۿ-;v(**cB{Ϟ,iݺ5A\.wС-[*yu}'...Ycc4N7]˖t2t$XМwgv޶H$ZeY$ \kDww7HJIR? ~~wa BFQO?̼ZrVݼiwޝ3gNa~as=ånT\I]˲W|kV~w ˆ9*揬W|^Ìg7~Ywf9x+>޵c;I{iB5>L,a Bdu&K|ըSzJ5jUuWlE!i*I$vt!D]""ʟvyY9Z>˲U^ ;L$!K3 e&HҶX ^*8Bނ^*8B9&B9&B9&B9&B9&B9&B9&B9&B9"MIENDB`RaySession-0.12.2/manual/en/images/options_du_demon.png000066400000000000000000001330501417052567600231110ustar00rootroot00000000000000PNG  IHDR.-)sBIT|d IDATxwxU)$4 XHQbWQ v@_Tvӳc!KvMHLs_ɔ3g&gw=3R]  Ʈ   >"8AA&B  D BGUm d<.c_0-k#p= ¯zm۞"0jm{6Ʈ I ִ5vtmi* Dp.M7qAAA   4"8AA&B  D™C%>?C.\JSLĀƮ LT۩SGi 贈kĉ;lq"e j)squ!L5=Ne*.yiAdN.>}Zl鷼qM76N bbbcctFQ.|VkcWh4~IÆr٥0sK5ql6qE}j]Z{}my<-J6j>cDsdhabI.Rv^bBG5D1-OU> B;PpQ:'[cϛ́SQZYvCOeF#*h4t:q:VJ%SRrbXzl6S\\\4 -2~ݺ 7'-=+33uR0 ໮\:C$L&S6@m`tcwn*j:BV'ֽ*'#IF /5 0?$x_Pu \P2"5z8=n7=A5s3|>o>q\}ըՓoyIȲ4{-3/p혫 WѲE eli׮-zg~dw6zYCOR$/[s?cu2\p~eޝ/}Kx㵙D3뽷Y7ʿ( z꩔=ucN^ƢżܹR'N;9y*|S]sYsh>=G KJxͷeXN^Fm:u@pF+1WWrх}Yb)?OL̕ï൙/l1R_Q޵cf͗I^Xi3z۫$&6cG7_ro 䂵`uO뱦Wn$`t 5_r_c2Bs/d7-{"IG}uw.3w=lo:BƪKsscd>X+}wZd^;WLJ}t̿Dψ* yAZf:nkF 4Z7@<͋gϲ[_ɧ~'""w~^/DVQFFR?61t`K.#--} b./<Ǥ;i=sn 1 IdDeee51;||.Z$IpdffqI/V<@[hѢ9GѣF3=ZJKKQ\3*n.;NΝ,/OnjKV+lQu<})++cdegO%YVR2VaCp/XNJL䬳0y n쵌3|j4W^}y4`];~Ey Q\\M7^=5coBo{յ}׬9g|̞{Yjuжl9VQ^MwI$ ~?gimVwp_g mrkd4NŤ e}5L)}N:K,=t7  #ܽAKV≮Z^`S0=:`ѪwF;[,_vaH[ˁ/dB j29]^~Y˔GSe}p1~wl6;_}-C %K1t %x:x.`77oNVغO./23b2ȳ(.)G0rp}6^4=J^rT*))7hsWR_Ź{)f-ǎ`_aILl5mj FI^.]:ӬYCבgT@oV,~oHJLTօIIt؁6жM11عS-?Y(m;Acbe<‹/}C.΍}SܔśrVN |2)6$;,9Ҹo f-9Z$'C& dfk/1x<PV23$:*2xa҉׭GqNѵL)?f߿޽XP;v8wM;n obѢ%,\.WeL{ ?_rssy7پc+WQRR-}𣏕/Zdd߁Rsrֻ\.T*U``ɲLTT9ۜLt3n믿1d f)C⍷> )) }%Զx4?Ob`m/;MEPwVM܎KV."I(vu$>1:2gzweǝ >Hp^Ϋ?|,j66֪x>cbn7+W2x@RRSYoJgh'n}ZOssэjp̛%_|5c[o!p8f-YK=ҋ=v?m?/F7jOjՅf*o^rE8NvVP,Yu7`2j6jRjFצj+yyyỴ̄MUTV] d:b];-rIŤЫPhtN^u={Ed/ Bi{򰙕`\?ZeٚҺU+嶸l1WHIMcX,w?d2.b˖+W[oVC~QQQ`4vhժ~NNyRozmwIxxxj5_7mÆAVl۾s;]#nz ZFe֕GzO|jF^h=j_9֭l2s-Y]KMǯIm/X[9|d℻AfY[~zgkR=b/\f*zDj%R(pupMK5=Agm9Y\6f{hn9'WHT6A{9\eQMH  ITxq+|\\&?>iOLb2Y_]bߒGfF& &33X֭ߠ,o,N~fa1||2j~͓KQT1i51;ճYDFDRPPW ;n###p6l~_W~!S'?Ɗe),*S8ޙ_ ӹ;'vSTT3/y}O2bpdIҭ[WeaEr2nklj:~MBm{_taж2i<q t< =>%rwܦpoQ-Ug$v{9ߠ@kXUu>dY&|0 MFrsW=?`УV)hĹ+Ԧ-fZf^eñlbQV,f3jk*X xvA sAH o#eF瞽̳s1Z&OZ .b@ gScZKu=z/_SݫWu7pK}ŋHJJ"))Y+Ir:wTmq,[Yn/. ))!MVtT]ƕïCj|q7Ҷ;wo>7, }U˖:~ci| +-߲i#[6md9b=`K/2ez|5f$4I=n&%%ȡC6|sFV-_V`;u-U_5kZ-n@ $IމXp7^=}ᑇS_>hˉ ,,,cN87_ 1W1zڝH#* g^90߼e l ܨH݋`A|e]-IMKѣʲ֭[,N'NW_{J$a)((eFCYYYfWQnB~AA'SHv;׋JBRp8nc0()) .Xz=܍F#5ֽpe ~%ÆWf*R 4ŗ/1Wsu70x,~!ӧ>'L`00pPVh4*'s7AC`'7)`YZ~.c?`iiz^yUʔǟR^|_֬eࡌ5/ǐR 2U 4W K wU*录ʵhPUbcYaC+Wͷߑr5h4FYS}%5-{&[cLܳ0IlٲWfT>QQQfv3q31x^ڵkj]\voUyyDGE_h l6>#~Y:,eT'}٨-©l8xU\.V$+xN?ɰ ;_`!}l'iʿE0j:/k~0%]h4b0joڵk/:::F`iӚ;}*EʲkUf`0"2^3Xj#G\I֭eL?sk99+Wo%,rcÇ&;Q9l9NMMcJztЫ ԗY>rU L 7~W%K2zHذ!>Ms~jǏ>RaC|ʐF![M$I!՗h<_:?h0AQQ1JʁybA@6֔2j,%Kr]w*1kco׎Oaa[n=贉23x)<>u2==[k IDATd||dffa<zXFˁyx7Yp⳹s# O?B֭3c0Ll߱ʶo./ ftBAh s^c~z8&"Y<JK|<JguQjZپc':xpݾ8xЯ2t:5I)dYKN5 qڽDV9.jo.hm߁^sNT2NX+Q{aa Z8\NYYHDΝ1 T*ٷ?6ȈH"##PT\.dY&>>T Ohݪ@{^L&ڶthOgǎ8,!A.!>CEdD$j5,SVVFjJ*gV"jr#I^GFD]VZktP|CJ|<{6^\s-yR\Ah4 sÆeJ`7GD\Bez=:Vŝ_Pf߾xHl֌fF‘$쥸Fp0^\l,:G`쳺(cVF#"''ڷkG\lSN̻j2h4=z dYFzIJJD%vEii)-Z4'>.0KzƆ\GDrVδl͗R8v8iiZut8#Vk 6}*ΡPXXHttm۴!22L23˳QTTJ"##|yyϊU"00tz6Qi֬:VTVGΝ&=##` +-))X)R>XLtQQJƋ?\qq1N-cIȠfz+j4` ZPo6<VirlRpthUʲ}皑ɕӀJʔڢ" my9np勄7%%E)Iq{qq=LI[2С}{ )At =Æfoז."++II"0*))%==EaawK˖-p8ᮔЬYqqZ9xpA&* ;\~*7O$%@ϧ?wtk_4K'&&H28|,v'n78jJjrr++{ ;CVۺ}.e"E8縵(GFDkfrQUx^\.YY4oDCR#GXP럕5&vmrʪuOfvZ޽Ww(Va."'jm6n2|)D͓j58N z_JˑGku΂ phy/ۗ L)9v8ڶex^RSHL -++#.6(b>R;Fbb"[pGxxTEE8p͓h—3pTw8 _pݤRU(,..vd EEE8x-ӪUys9zxmkr}jՊDqC0??lߗpͭQOIYB[p*Cv>Zj vݤAt`IA9uJ=n7k~ܲicMJJ">.M7WYw 7pk${& ӞMV,Y]v_ Z~\l,?+Gn; ] ( Dff[Sy8^(z|ܹvW xP=}.8ACQXX,OJJI{ v:tIݏ^;nGV*,}!I'׍eϞdegѶMv QQ݋UVW[NDDDٰq#}>>N#sA&(**s{b?2x~@YתeKRںu+ߟtkW)S$,3UʲF,jf3EEEJDB~AAH~ZiU֙FPY1Ld$`/}]jQTxHNt=VuS rU{سDF_ҥK{L0|y+Dp.]9|8֭gJp>p>bI^?UVnݚcUWߧm۷3yr * ixNnq7 _F%x NBZ6p߾}x|j5*k|[y9~IuӃ^gsхzرs'O>ٳ4j5w0ooyM rsyxI$%&b4y7|̘<-Z4GUp-ˀy/_-o.3OӻW/,Z}0e9z^_NG$1nM|~91t`>T*}acݫWC?F Mȑ#95ش'=Aطo?Wd \su ^k|O\UTR<;CNN T*V+^$IKzx^xq:Ly|lJ.чmih5zr<:xN !Cq\to=N}΂"I Aj4w#G_7^g{pwkn."^~i: _1s5q$&& ;7rsHHH`o2ុ1M8#=Hd_NGVk qD+i߾=ڶQ ==޽{+~>w^H9AXf--7Ml޺}.Ì5nݺzpbM7k.v jDGGs{3pT*)))ʱ322XVL&68.w>Á96 l6gս~ۭ||L&oDϹ B3jHXN7ߪլcعsW. nZ?>dLpÆࡃa2%X1ddf(US/<jWx\qe;1 RĀ3Iddf.]vi3bۈ >4*S5<>~:s1o\3f  e6O1~zWfpQZ \3Fv饗8V^QQFUyjQ} nl6dAR!8"p f}s&C}غORSӔ/auϿaHl ֬]Km8p,>>NWz\o0 j$7 (履tu;ΩyJ۶IdDo&2JK}3 :0Xkر _3F?Ah*fUWF`0.OA+((Pޣb4 FQW9G= "8;를QF`U/Yﺓfj]+h߮_}9" =v{i+dffcSx|d{?2[k7w}'ʊeKlX,>s> N@޽"22xS>u9ï䞻$=#6_Ce9ʲ).*b֭7X/>e2 ^/!y*f K/_ckU[op'p >ЯS)z_jI0™tJVUpNؘh6il y*<KK2ٕ4u0JKE.߿N#22\Ԫh'M_lLtuiit֍T׽{wrCsM/Vyg^2>y/..ގs*t8dee,^ijeve7@FF_`^™bz7[lBVuwjZ\beee&/TvrzdnfF]vjJ*:YL NdYWvz=Q̝70ngMii)l޲Uy, UrWN%o]U>Fڑe#2"td2|*\..ɫ0Lt? _ t"233^yyHϬ1 @RRGq5`У?ڶmMYǏc4Xdn27fRK= PW<33,6.G=c˶Xh4e%T756mZuoUe  {رc :P`z WW.T*YFVP՜wyDFDpy瑙T Oz%%5L$dCj9Kg,lٲӉ^%5-LLf{)A-u˟b1޽EE"e˟`X23/--f3sR~NWڶi͆8 z32;+Ǝ*c*摓Knnڷcԩ))jҹ;wfcrV.v,¦)ڦ$IUƢȲ AAvS[0֕*Q4kdr IDAT@~=AA8ST ν^/^WAMxmն7ȑ#|x8BY/i`h}>iQUzdfemsr&f(RJRCZHtt%Jeܲ2$(VzcuZT !66VIΡķ˅ޠ?r*GFd48N8H^=8YH܉ ˅dRVVFDD8v ğnS^JwjvSIIi\VP5]Ap"嫯5峇pR\TG]ޓr(,(坊y-j kL ۶ 9+1Jwr\i} N+``Afl-:&:sr:hu:e:o8y-.[׳i۶_p~q6¢*׃4 -Z %5mZgp:)--eU1jT\e 1J  $v=iHV:N SAN7U>IzE^]xVdd$a=zys2/IMM!"2ȨJCNXV m(IHSNDDc2 y}:`Hh4jT*ǃZ.fMõtͧTWhZy'Sf qÆ-3;厺ugϝ#?/΅OP\r 'N;S~=p ǟ>Bȉ'iԨ!AAL ..-h4̦y~SVg,+tqt[!WQ=a<[PPP*wEkd⯿)Fcu5xzyqE2,[Ѱars8w<暍 o ::RPP`6Ib2Gvtt$//$JV +ۛIIY܍'jOƄ /OOsfK[ljKǐDDE++9jM&V &y%iZg#JD?os觍6ι37IZ0Uc!7V-89䶢 KQVUV]]6/k>r2g#d%f4ٹ;M䯿.LY&&&'O<pSs({%kwy-SH-YGu3iC8wp Y!ĿKsɤeWԖaRs2yٚJ]՜=Mq#ȏ?V^ש]~+ WeIDw7-0n d»8Lط?P4k^B9ܞ@6{*ouu2~qY{gbb67U挲?/ @c9m7 >>>gd+LfEۗ:ujьYםV?K,k(K`` MGzfǟ\wy%;w>Gyo cȰ7>lMp6}ߢqF3gxz$''b*ԩ=w7f붊=Ṻqrri&zǎZqŵmӆ2j6  :m3 ۩rf*wp^_ks%8lMg$05LjG /({}64sqxyyr߽+qTaqwwӫRr8X@ŋlptk<^%1O9pQ {z@VDMZSDf*%8iDGn6O>ɄH 7ӳWo쪛N炯]oߎ3gY_O34M OҥKV̴) Dudsx8Ιk{_2kG4.ƌ[ooΈh۶-&LCN,\ ٙwnj&}; H|^2>rիyn̮Z(OIyx4 ? ^{\fY&DZiI?&O⥋vS;Nȃ>@nn.a7=lٙ#`2_0}RdܔRRRm}V۫Sǎ2}CRvmFy̾RMr1{$ HLLd/g,ݻn3ux{peѾ}0xK+XxIL`"~ ((˖O?Sxs7nŋ8z qjyox95MJw߱dWxԨʕ9uQ1yyy k߬^%KٹkJkӱsx꩞cvIvv6ÆvZtLjj*~~~F4Z-r8::V>oohh(_/_AMT*oY/*,xcxܒE_ڕϐP\\\hґ\:bk*Б|f~4_)S,?$++*{="˾bDRѹSGfΚmXj1FҭSJ^/KpDV3u$eprrb9fX룻v0ӗ  wwwm=st=ʫC0Lxx(uv}a /rݸ1_/[mۉ;ӓ'MࡇѼCtԅ\̾U%ݘV[gn;ZlIO^9U5zE'99d\=ߢc0܈Kmecyy~"*Ip퉹&;#  ''gQ5ksEn g>mvv6f ~jՒ3g# cr%^~zrR"͚5SYr]yZhذNݷ߮RM*d:Ipp0e˾ ?/߮ߠ/HNNɥvmN/| +Ξ.\'OJpp.]JÃg+̛S !{gK/5|v ?GZ}=[:,FT7Ti()VEyRPٸOs9__#pu-ڶa!$]N")1onOH0CbbY^IIIԸ6"燏=B%9q=,ÆmwJ51 ooKŚϦMg)\5c?~]eO0oo>>>\*V+zك|}}ֵ ڶQw5._K*^÷ҩcG·="|J6Wd:ii饞Z\>j4yi`^kV⣙J} !== gO].E ??"7+/lܴ VɅ!;%%s9tƌWxKxu ­qP;p55zSXRpP[eWDIw[.BKMM?N!$}\̺h8991y҇מ:7kGe71j^'b zu jF3Bx?NgO d^/q< ®:r>zUZ>{p>>@(kӦM< onݺu§ҍb?p*fh zQ *5 5k,)Jzؽ?Ϟ*W6So+Km∋g@~qO/j4j׮@Ff&ӳTgϝ#.pKJ 2ڗ섄8qbY+WrwJj5AA@麕WiKv B!Jٷ?#Gf!|g))t.w\WՒE$%]&%%L3>>ig0oRSSb^6Px1}w4F[‹ gw ##l9Z;9|0}v&==lxk0o"o%'7?L B6k˗9s/8-%3BMŽa ?cwضz ,fSv[ys?eʶ'NrooHBB<Ͽ]doFƿ>ӦLoM&V\ܭc=v.@V3N\(L&F͔IһSFe⇓z?gQӛ-ؿo?Q|lAQcls+$$\d1j;Ijj*:m#pRu>cfҟ7 *ͧzr^Ԡ]:t⾚3b͟Y5graD+v< ҉M5sqqݍR7t:ִEV`'6W{jHII-C]\\h4V/IM0AFFy:N^/Wylzqssh4ZTZHjjjVUګ,+5jg"MHOOz>J"%MF\ϙ+윜rAZZz/V]hтצ Cs!ĿVYŤ[Orڼ3-qi++K!的˾$UUwYݗ8Col̽ J`.▐9BjIUK*(dcL !e$8BT[* sǁUB!S$B!D!B!UB!BT !BQEHp.B!D!!nD < ޚ.*b)/''.jou1,\qӸLMMBg|פ?5j|aB!?…8t\ymѢE9B!BT !BQEȴ!-Rcn ^_%BQ!0/Vn !nt:cOpСJ.Bd`r]R=LkB!\!B*Bs!B!s. 6ANˉCQ{' !>$8BTKH-YGPTvkB$\B Z7(w`y8 ~09~(sfU!M !X?/ @S_p[{I5l_">!\T~};&˗/Wƍ1v}~`%6oMa qqq^quុuJO*,]{b4oHٮ3<=_-d2Ds!uSZ Bڵl x˂V-_pDm\z*Д h֬ +6777{QVZMNNέ.A$8B*XbdddT8}gggmGGG233͎iM~~:0}+#|:RT*Ȱ9zRմ4e$ɉDGngͪn7_.`Sz"@6mضe3 :D9ٙ&ϾưՅ>1vmPm-7݌xM圊5@˖eF"q`_oc{۠vnذ!1vh4iըΧfGT۶l&WFf?]v-Yv 7 DZ3:o׮!fZjYf]:w-T/O>WTq, obMl ߄7Zdkf֯[Ktv:u제g}4y7nvb9r>)׋ IDATDElch|2%Ξ϶d\!%Z|A/_">> YN V5!۱uv{5RV-hJŬ 2u:Z-juaxc[ʨV:e{IJ`g8991c>6cүQ+s)va#է/.Q y{hΜ9d⹁/ dSz6nD|BÆN ؙT0 |9^~UΜ9/W\ۋٳf2nۏ'_~gjk???f'M!z\\\Ѯ6jJMUVkP\\\hґ\::N?AԾ6;w!++ɜO>k{=4o:u!77///rrrʬ?gODDF>e=VTq}z"1)_y(2pELJS户#4n܈q1Xm||a7R pɓ9r(CVޟ07GJ϶d\!ׇ }=wMnN||<NbϞX:؝nvv6f\0LF jֲZ jw,[5999|~VZ4l؀~zq/lْ| !99j9V\ޮ(۷kү n׮-[nSINNd2#ׅ ݷ|lӖmcr_DEGc2,5=6'`Uʴ+WҞW*56_P@qR"<\]]1 dff]Dl)O_fk3cr%^~zrR"͚5+}Ν?Oݹ{1L$$\,gPP {/d2QPP裏W϶d\!/\u*322ԩSf%&&`ƷW,%.4+#[1LJt3)韛|11lyGh4Ҡ<%֬Zɏ?G3gYI2>.Ա#gϝE7ZU8Mbl)/zv̶]JLjmMrO6+嵿?IeOJLۛؽ  2۷qf/XH~~]u)OQ}ΖTq#"_`ěEly{ .]DzzzL:+z=f}̱ --lybb"j/// - ΅ %--lޠl[tqPvWY˲z\qttTFakgZ^o@V3❑oN3 ̜5 ?cQL`" j3OtѓW 'YիKMMFz??m)ZX`<-#o)әo0T)Q d<,.-笱էJn1YӦ̞5.\@דp1j>XUЧwo.G6J 劆?&D%}dZBT"كzťRӎSHw'g]$$Ӡa%0yhp]Z[#..sԟCyΜaC(7FvKOOOu!;&N;Q= |9ee{Ν  WpqqaϞX֭K)e۷Q; oH[ HV@\ lKh4w߽J}۶mklп__=ӧ(yf2KNj= 9qvץ>aseէUk =vĤ$<=ݻѮ?mmTfԭ[(;&'''N>^yku #BQI&c>J}T[iݻk+IKKŅf+S]b'ض%^ϥ$+-{Fƿ>ӦLoM&V\ܭ3r&}0=1HOOɉq'pq>_ZMFz|8y]?=dfd#|qO჉{g4dggӭSlդg / ܹ5'h2ʶmYvP?`pvrbلo٪jj[휚_|g t2DFFq-mL6Qdee="C ?%:2ty{hhp]|lAQc Xes`o[T4}[}{^̥D<==9t{'??0ьPx/^$++j i\|///>3W=S&ӳGwTj5NblTrCqSx(1ԠV󬟟3ֺmX'~C\ u9jr6="JĬ!O=3>WXhQ`q*zMc///ӕ5KrwwGՐj*rA~~5]u:1j 55լ* //Re,R.iq=zeVEBիv h>...h4RSj5^djZWE\Yl"J*9r]ԏ)2ӷ>:N^YV5ɑY109.)/ߢE |%8B4738}<Y4]wƵE7.}u}JBۂs"!`|-y~#qP ̅B !%UA.sc((l&pp\!-#RTO`w_%?EB!BT !BQEHp.B!D!B!UB!BT !BQEHp.B!D!B!U~~|B:uK޳{bҥtԁ?[_MkδhGGG.Y@:uҹʹS@v툢E.￑3^z\%b捴k׶ڶiÌݤRo f͚B\ ΅ھ`MR1e$~W޽Nrr2{W/2yv*CBټ)g U=Mƾ; Yf6,~NY;fs-?UziԨ I"أ*_|n&;#GK/e8__ߛX 4 ݤ !u٣;j5,3SWF# >/XH ۸fS=y8uꔲ]Ֆ:v?pv777/ŅRU*fLBEe,+ח}ShxNG^~>7:88Dff+rr2/4Թ:leEӑk?x}p˝ӑG^^^(ZN#==jyh[[e*ٷXZ :::V. q+ȹB\ݺeqFWѽ[7T*{Y-^bΝ:g -[>̖Ɓ}tY״io"|S۷pʾ`-]̒E_3:nu!쌎b÷kE'TAÆL7lؐёڴyQCmk5%l÷lټ=f[oVMŦnN^}e0OOĶ-Dl_i| }J~kVi#۶ӵKgmlWql޸v\t [6o2kDz5i 7n`5sJ:~R,%_߾@vFG۵lv K9;lݲ[зOo-LƏ[̝ ;# iߞ5숊`ۖ̈́*9999L!ёDl9Q]m,ĭ$B\Y.NQ6%ߟٕڹ~̚|ƣ=ٖݻccz?M^Q#V}4m*{b.#{'[!<#""ԥ+tcټ=Me_(?Zo1c,:t̎b|ɧmBn=xEs__!v=B:2d2e~:vJϧS=mR*UaU**S&;&CѳݻuñtWX{Wйkwh݆ӧەFYu2ǡf͚sDc=J޽iB:v&l&O;e$buv݇!ڶ2i4jժ@Zhذ'¥Z-z4۟NbSP쉥nݺ4oo߾}ڱf-Uw\qq (ܳGwWXWn0N?=nnn<%nۮVGEGӽ[W%_(\ ӿ_፣%۶"뫴uDEE3hЋԨ)k ΅:L&Ə{/X=^^^j0~l6Jh]IsK̮#*x{&N|ё=jW#GqFEĶ-o kO:-n 4lؐMaoș?$--M?o{7[luxg:tĕ+W5j4OϖMlټڵldFƿ>{bp63fت_ecEWPbvd5^Oմ~F#۶G' |e{w{Xj5˖.apRn4L>}zbۖ̈́o 3T?!:W;"NG\\HHHĶl۲; if qBhde9gLmC8deU3be{s/h3QTѝݺ)Y6q|kZKI899jq)EKj5^^^dff{ kwwwZ ))VTTx{{LQ(C))xyýWTxyylR%yyy=iTm*+Zt::^oV}RԾ_ѾxѣGT>WqnnnFSpww/gHT/b0۶׏-7%-Zp#v/s΅Rnv p탋qmޙܿbsWa2۸C_)=zj4FT3\rb2Lh4*7ZRPPP*06LeSg) eU?v233-Z֯_sa02eÎ䘭.DU'ZJ?!7\^CQ۹‡>=w{ jgٷXBT9 !%UA.sc((l&pp\(N<ɳ ŨfOãSW/\QmTVhw"/J5[Q\ OB !BQEHp.B!D!B!UB!BT !BQEHp.B!D!B!UB!BT"!Du^ŋ|lƂT2!: ΅㿢R>Łϳxr'BT ΅m;08~8ݻus江,&'BX"s΅u|cZMR~*CF iժ%ju_jՒ:^j_m__J)%)5kVZzK,ﯴF\!,0oݔaC0OxURO?gf=<<>>L:&NC kMOPP Z-[={Ѧm{.^-`֬iґ1cpp(Ls˃}{m:vB6f:|2 *k4K|ӻ>ތ5SanBGs!T*·n[©-:H?(/^jU׫GnN. IDAT.%ҬY3Mh4Ü8qBr8::@,_,6_P@斿X| Q9x<=<_'Nڵ  *uxV ʕ}jբa| ϏeyΟGw߽L&.ZmM7 kUuꔾ֚+Wq:vZQ.UˇNٙk&)2v哛ӧOe֭t&!D&K) !uK)ew_w}7?#W燏=Bv%ӕ+z HIM5{ ) '1),$|-1>>Ty| TÏ,mR?y]b4yc0s;L:+z=f}̱-`HQ?774|}}9{\cUЌ7{C]h׶Եch4\7(=^ɯĊBgΜ~'$8Bx0^9DDFѵkn-YZ^O^2j:n`0esI̝gW^>>0/WN^PՌxg$-((`UZ>{pK>[0˗'22o wGO'~Y39~r!SS!Ȋ˗ͶjCmZ СCM?I'W( ĉx΍s^* //O-F!-bi988EFF hq >UՐjEӡjqss`0ڧV`H) '''IMM%//OٮhZ.VŅk#Bk`r]R?}i^֢E |e\Q-%\}q+7 Z%[SV}qKL&z})'yk_233%Y ̡pjLE.''Չ2랗Gj`^!\Q-}l/<<ݻu+y ,zjUU;BMs!Dd,(`ҥ`RUF88H`.░\QmTVc8 W !OB!UB!BT !BQEHp.B!D!B!UB!BT !BQEHp.B!D!!BTOCܠ\N҂ roPB$8BTKH-YGPTvkB$\B ZՒ6AsQ8jK!( !X?/ @c߯&-[sI ɉ.55̙3rQN1[mr+|SCA\\MewL /_EB32r.uwjC OJ{q~ݻweK[N  YfvӨQrcIPP; Z>߭.BRus !Ŀĕ~i=ގC1V8@zNnIHF!??8gggKFvv6`j\4޿__bNmw{E>pMd Q,THKUb*H^ "QH T'\MHlz$?blɦ<i3ҥK7;O0z(_;z=̘FAq=T]\t;s&?mw;880}TLF~GfxԴ4zlll:e2nGnn.L6ǏK@@[[;vFD0L4mvzyy`\Pmf׸׳}͛wߟcߢSNLFnݾYo_~W_RY?mϳBEs!uĉNHH`}|j>ؽ0NhΝ;#0LoE=-00UkXz?ۇ>ЧoG<̗&22 5?ض}* ?:P78ﻏ+VOAAz}ݷ'NSn۶PJ>_@խkq_]gz#M0LJMIOkGƍMDxFА9JpP_gҦIHHՕ^|'''"((F'hؠ\[.ׯ_et ,Khׇ+i/۶m'-[(lݺMIw97Z`!&9Bj ?{;5Rhdv쌠SO1olnNFFZ>YCzz:^rju/x_xrGg%pz$$ޝ^OAA˓=ӹSGe٥˗Ko1h>x0#ؾc'W Q?w|파&;;01|jvFDگI3$%&᡼}/!$8Bj:{=#;|{ U2ZWWWܶ|SQPPlb}ai߱Y @rr2krJ é%??3~$Xh!2^ajƎ@5kC9x0͛5 ~Ν+~o~Bq/HZB"~~~ԫWOyCsE+ǐ⣻ѫgOeV7n̡A`@n08x{{{Kyq𿔾}2h@\\t@a~|O\] sorEܸvW¨#}8;;Un; p=1) w7Rᥗ^P{jΝ;_^W !=!#BQú{=ZݶN_,^#YYYj֭`¤I̝.}{G NjٹcL78y4%͛7w!!|nOkG͸u{2Kչ|Jϟޘ(s2+W1m&%%N7fgf&N'3{LOFFL>۷o3rpѽÆ!!1777N8cq+W}iS"33Md6BYT]Oa4/2&?ӾS('OX/~VB#_#:* Źa2KMGX=v2kΞ=3ɥ붱ݝ۷o/Z^h,~gggF{{{t:eΙVqws#'7bnNVCJJY{jJ)FCzz!Wo'=n7*cUjՊgVx}9B-YNGWj;0L&AwJJJV"//b`E9@VVVvI~'77lsKF2ݡ%ee`0p aYd\QHp.[J\>?RnD⊑U{2!l !T PPIm=VM`c _4* !sHp.RT*;7*1)nB+ !BCs!B!j ΅B!%$8B!\!BZBs!B!j ΅B!%$8B!!B=9;Clf_&iHT{0!l !|H>JvfXN!N! "[ xҁ9@aGB!##B

*>'ZGR6{;;:v@gzŦ/9vvvL0Аtn&ߟvA^^}{V˻ٿo_,\T#mB\!͍ݻѪe 燷wah'r)v$%%L/E|M42[Db0J-/- 5ZFՒa\`ggGVV xmPuU*.:ie;;;QnyfffFSSSTDR%ʹ(Ҿ4nbmooO^^FBVqpp ++ *;;;j٨w5k^\S'OFyY]yyyՒ 9B*SǗKVذ!wߝÉS'Q{2fwvxzx7\ALeKpw/qnԨ/- G^ݺJ3G0p싍f_ܾ-[Kn㏼º /^"߿Աݻuo ;hִR>|Pt:!]9>9K/[]ךAQBQuadeeHRR 4$(( ߣGNJ"?,mAvVuʭ{ʴt 2ё90m=q ͅ ?кuRu\~-ӹs'lll G͛4y՟d2QPP'ж?qvvz;wkXD3"АN<+ 4ŋ &_~CFL&Fo=AP`}!|#W\X֦Mk\EɁl͛ ѰA i޼c̬T_ILL$%%oooHII7%EڵkǞ(1]pQG>{6>tܺulm[h S6!Js!¯׮SիWy?9tM>^sNfGИ [hdv쌠SO1olnhdQf;TQdgg3pƾ9>^Έ|||IO0NLLDV+-%O9v8xGG0qd¿XzɩSߡR1 JY~~>6;%^vIbbٲ$\t:-7V)OHH(3$oo uÇ5,^EO bc`^\x <٣;;uTxu1[6jh66|l A1XTR!Di !D??Hdي`'Z”"E|E>rS}ǃ6":&ẐO9+-[ԩì7o&ԓO> sެT B$E!j@~~>} oܠ[Xw |j3GzA<Ը1/^ڵk\ FPtvvV,.(([[[p71) w7W߸K+@kp 7h4ʜ؞tɬ]xSt܉Xz KM:y6jD&N#GҰA:w:u`oo_uzzYV!7WEy`%;-]ú(^_5k?+\K iO> ܹÇW;3JzF.:qqq y&'LbҤ vwa\Q8ME JOa4hj5R}IDAT;rIe g%.<mPWBkB6dt:lm5ͧ]ZŅ\-ZGGR*~̼]j''[LQTTVy}Ijj툫+dffZ%訤 dooN#55lrk"\]]h4YVbj B N{gz/ov9}jՊgVx}9B-YNWϝZvO`Sd[4 C8+oyyyVGh0/Hb4˝d2ySQ;w^T~I6)k" hBs!TXGp'W4˹B!, !T )Ljh ̅Be$8BmT*TB"!B!j ΅B!%$ER*j]^eL#(Bh& \r3:)joTB!b"B!D-!B!!B)ui`㿺Ip.cAA'/dZVZUj} ΅>>>5V_N= ΅6oY{\ O9S[~C2J=999fǼ5䐟jeE#-=@Tt4)kkζXVqtp 3+Ja4-^ Fǎ8~<ё{ܩ#ݺve :eqiӚ;ٲ+b#֥Tu e7Btƍ}?>Z=~wfۨQ#F0~Rm,=666̘>}|&K6cxɶX?uI~~~f6\\t{썉bϮ 6\|ifc彧spp`)طݻvM4nRKo Q{vƨl"h!/Y*WDT !D5| WϞ,|o&|*%)9^|b%/_d21md0h45f4 -f\߷N#K,zoo19sڗ-oϘθ rJ՟b0 a7Rװ.~999 }}͡OX-ycoA\|cg\+vvvl|!DDF-_#M_@ =<ٮ=xzz`\;3gҸt5Ο'>>͍wgQϛ31|(j53ߙ;3pDRVctRkO@@-[K 7bpuq!<|=.]bL7ƍ߰GәmǘtZoQ% '3ad\\t| :uHLllhO 3IMK~ays,'Oߏ[=ů ÇH0 cFVU5忧2xu ֝l}7K?XB^ahNtJ^^zpVckMqM ˇZQ92r.53gAD+Q#9q=Kpppnp0II-oO *:Fy‘#G  sYڴ~7oTlիFHH/mw(_~AfeWHJJ*899o<\^Wy&u黒rrrX%'rfii4lCD7on.?4y՟d2QPP'ж?qvvp+= ҋ/Drr2Ye9 Q 6h7.@֭8 ܾ}Bv +fZZ:.@PPc,- ,$5-M\ 'Oޘ:%=ݮ7*;?k"]BCX>\I}ٶm;lfÆp%uߒ*Y *GF΅lxS7OyyIÆ y{T4 7n&e3˓=+i._.{*^ӹ_/dwNNxzyիVG Fװ0z>'''eTұwԑ#Ft+$֫O*`\|Y.7w7?!!By>>g~j-֡BUjYq~cАy}`"wG}NXY*ܼ>/F#G2[~yF# Aic8}=-Z\]%|%}{&ӓbk$%%Ƿiكwz ,TJ11 Oog ΅fMߟ> Gͫ`0=0uD9v\%rΩ%))|S?^6+y0b0\]\\L& 6sNfxyz*kZ\]]s-[зoz=ӛ>j2mooϜ2|(Μ9 Uߌg؈6YGs6{ɤ}FQIQ΢b=ό8 ?/ZȀWtrKFV3v,Z>+WbҤ̞5B}a,yEH?铓0[R,ߺ2LNNÓ)I5˱/W^*^?|/oF 99Ǡ-_ͮV< ,哴!|+Zi|=Ln*}LL, ťpO()Ww{HAA2V43dBVӯoRSčquNZ-\rr 󁻆u)a4{{;lmm@|oIzzőGiؠYpTNS٥S .]̀W_ G$_8G( qqlQakks.C\x77rڵk\ FP4gggh4űcǭW:נ>yh?k}R""Q1 {jΝ;Gw9i֬R ϛWDOF΅|QT@kiy96jj֬XiSg7)))t:>_5k?lcj K}ŋܱ?q[[e2rf͝ChH[gq[L8S&1qBꀁ"_>o`"&N̼sL/Tj5.]b6._ٳxWOTj5[lG)Dٞ >}RSѠae &3{LOFFL>s/j232qpp9sջy>9slh?1B>\ٽ'R2+?.{c!2*W=Ud媏>m Qdffø ojVZѣfV~i.]Jtnr WWDO[ji)'OmX0[nO)h4˜[ښ5RSS4qEWTxxx^j=v2kΞ=3ɕ*puu%?? [booolllpwwJݍ|ed,0kqVZks[jcYQո[*鰵Րjv͹RHIIT}Pk>yL?ONx~*sm8;;c4>[{GGG4MALs#uΝedff|Bu?KWjՊgJ,EF΅&O/??3c%`7Lfїǀ Vʲ)((P?L&z>`/fh4[6(+lWk>yL?Y[2FE{~( Te/"vY",\!HfҤ dgVaf?HZVmHkUCrJJ_[+BTZՕ ܋!^bRRʅc4+TB!B !BQKHZZV&!5FB!_\IZB!%$8B!\!BZBs!B!j ΅B!%$8B!\!BZBs!B!j ΅B!% IENDB`RaySession-0.12.2/manual/en/images/patchbay_CV.png000066400000000000000000000321741417052567600217340ustar00rootroot00000000000000PNG  IHDR5M pHYs+ IDATxwxUϝQ/.-n;qSHwzH!!K $.KYXva_P^elH;ݎ;ݱǶeIV}2eYl'=z;wttv.yXjD]?~T>xxkhyEuWƍ׵<<P.̌\k,KB|P($ LMIu U+BGKN"h EfeeyڣEny-I0 4{I= "I3 4G f!0hF0@ E$`VJh fHbHcB @hgl9UqL&c `8b9{G%JP(,E$)BCizSrJVָZ6ðƆƄq(qxclA~g+.\ih[ZZr?Bℇ⾏0PH$EQ BT:v'"*FKxE_3Ð@B 4 @ j ЖBԹ<q'#=ðK+U$9sTpl>QRH$Z+Vu1 {Cr|ݭRS9Wxhܤį=pVm}%u5[]s+rhaKKMckAZjxb߫4MLsfk&Lh:qDNǞΞ5juRR"9~q{2 0@QVG1Md㾁Yt]&J]G1HRG@ss&rHQtdDDNNΜٳv^4Sz-SNM<9D4Lb4Z }_P0m4Xr6_342"1d ==}jֶ >yyijege9Τq74ibqA/eBDH(Zϒt}9۷N40lLpcĮH `dR m?erX,sn6ݛAVț??11 {ԷhhhvyD{|TI.L&! Bnl6%Gu9.n?r(k h:!>!0wk Gqթ: H&J}AaR  k  8`l=f>cgON"D" p P]]:*뿜p:-)eee)+WIxbEVE"QEEoA[,V_bثu| p!B3q0Ѻt'7vZ `~ 2;NX0zߩ))! i=8bP3fr.=~QuII111)/kJLttvv6wzjH$dBzM  bOI>_A@҇pD! BrxQiZ0HDQEQ8N$Acah JDsZoBa]+!$DRwRqRUUPp806Ֆ3a|XXXqہROIQJ`堩^=7%}U%C'y\u- %ܵpaqSee00P(T*&J[lE`K0֞sҴ$%%wj'Xm2s! @^1gz{=B+ 7$Msջ+$& IՇaT*lnCI ymWWQqnh2EECBBbEM3rĕo֎+ #O"$9_`{h@1kC&K;65*J XVPaAJc0IDR'I$ H$лWa?KSS`HINNMIDQ&ѣ/2ǰȩ>yTf"#"dU8A"h=eB3fLk'DqqqJt8^mBDri U!!vA"VU(mmm>NQj/:^F@kXZ cǎ͟?}ڴĄ&ji4Ebk[1crLi ?96G&)SΝ?oQQFe:}Z66&fiNfZ.^tӘ˗-qq'JJ@gn>cɢE/]+.K/mi,Mhƍg7ZJJZǏQ]],>ĘYL SPT(n! CF~Xsf9???+++%%9>5KtKkKyyBT`8zp%\|^ߏ8ygΞ4q⬙3j;V(T,vk!A W\=_EsO*r<::d2Y,DP(FVE4B5< SNk)BI`Zv#& 4:$7p< E]QQQFQPxtt@ 52q $@<^< zFtXK46&'NprQ8ru?wyظZZZ?BWu9VtO?L.s&=ڌ٫4Ms޻qk-s:^X>b"#I"T,Zoí|eai>C9']* RY~\d/Yx.fFFFJ$J%O>c4̼ys? saΟ?}ڽ'Xcf2ݽj&%%TIfٜblege](:ZX[%wGJuuÇ/΍F@+  Z'vu! Cnemxs9{5 Vh44p!F8^iZժ[/c6o|L mm11 EWV^Q_PW^NJJ[/Ngʧp[Uk[,_uqn•n[?蚜NeeСìFFF&noٳfVkiI?rWX$FȄ Bm+[ZRk42FH4F#hD@5L4F5Z4Bqh46ƪX4KKl82H!6[HJKK3f BhP_˃|*`X>3)' E;lURS_L?TI.WYT744!Ι3=8vط~!0;E$ `v~Wt:-@'@`j^ikurMHӓ3oY|ĉPQQW8o%7{a;( Gӥ\~qly p+xll,wۚZ:r9c H%$&}`VY!I Ă0H#L!H#(,Z&K0&0)(\$c(H% p2@lڸɱ_mt@ˑ0c;Fhaa 2t: G."&&-p:r(|ISss`lW;}o'Q?9$ !yA;h PT)(BaH&&mc{Wcd PD;iHB搄]K {Ϟŋ8}{R?!&&=hhlp.MM螁oA1ϝ;?y$7wαٳgs;ui:"BB`vPa 0 ᄃp(EAQRM$jq %]Q7ppH)aC ld; PmljP^ή(j}>鋨etw0 AnsLofvbN\va=2,Ak0DЈp?Y8|!puSr\t޳ڒғ7!7cO;:.N|c]Q))8t.BKkWN䬙7@)3O?~Ą.[E|)Ţq/v1<6A/c8&m0ғ'}} 偩;sHOd[n muTԲK;;;Ngم En[ ߼P*7=Fnnnn6 I&ʤRгO?ugZmȈɓ&NcQTtlJ0`+pX}22 g=PFefFoo}N+**NH$qM@N顇۾cmk`ɢEK-{kmk{og a áÇYeq8sAanƖg:tM]wOMI勯jkoc:: tG|: O>mk̞5qQӪfnG%%f1reHd濎hU(!JV顯?ƌ C3ܴ.-;\ʟ=<}W-!-B\52ۗe˖pEH*/rmǎ7}͛XjŃ>1AcN~pv҆XP{[T8Ώ>t׮=^T-[f] 0R"CKð09\Ԡw^O/CCmT2~|#l~ ,JrY@g#3 shEvmbZf:5N%cNm|! )CeY{#Cңaj/ +%!& Fg'$K-: {U$JDp9P$e1SJ`m밚}m$RH"4u[IlijikpQU~`, X,K-[7oN_#Jq0=j!5!!>::p47xɜ2k$=mIjbpۺ٦ֿdϿy/@|ۦ^(Ϗr!ҿ~soIPgg>튇~+eņ!ʡ)o/|+׽ə맿̞[>[ƺu7$ Mq}Tu=ص*6}XgOW_?:;vcmINvu1 ''6&&w7۠Cd`6mLnl3ϪʛUQ^×vȞ%GjTQ oDԁ He?*R8UXS? S&{ۿ|uȖ߮8]\Xӱ?'&W~.XvҭŻ.1u["9M6f+"G x4o 'ğ'*jŝ;֗e觉_?]XXuם)//߳gxJBO~7zC30^"IDAToެ6|}|aKS[2DC&ݜql9!%'8kb7sT&zmG@]e;/3~Ejڻ:W:E_YE.^iMuf< /}u d_7-q–n׸׵iw@MMP(jě6m /˗]~0ZZ9ĉ{׿̜9sϞX1M28gzzʎf=O䭚(lV祳΅'} U1dq(} 剃n^8nlNRal&ĩhul{*mFm8qF?x,<b1ښt기o~ HrWPTT;GڞS\UQq*>|j6[ꨑϰF761ñ)Gm??DbB(TPƧLy4>VʉKߕ]. L414ÝڭN|yO;Gʶsk󷟺RoθWw OO쿮nwVCjq(Kw̙SqDGBI*hTl"_kkك '뽶oLz 3?xњIgGe'$eQU!NGozy\:أ@b=u&L;f5ͼޛ_{ꫢrж8>jnM'!V;G/1lo~ð~̀bյ=M!~G}lL]񚙋ɕEk'OsBZRF@8$8|R SqT=$͖_9dEɾRw ??>w0:^u z)"&4s\|IrAce\a:MѦn[Rr`Кjq4;utg[8ry+G}:\_aghs._ȦMh$I7F-H/C :LD,&EblaaXLbxXfqit6aV;*;g c74QQQ6?:>+>/Qo5>" NV_ǎLkA72}Pղu52RoǮq3l6#%''KLLCegggggSwIpa^RRX,JKKq\q9_hAjjúugL\4x l>qt왕UMW5{7}=^1;;wU0>b+om%g߾ {ûWe˖l;v쬪ri:? w VXr0kT}*1 ե0RLL(cp!T*FcKK<į.ۼmm}Sp2t'Fh_ltiU r1w3gζwxFs&Mʙ:5W(|6Y'NOk*Aj۵k72ТZ4>9x G: #CFj*S.]̼0Y)ڠ OE "xux Oڟ8NR0 tʪ^] 63f>MӴVEQTnj[v|o_r6lXz ^k¨Q2MX>~|m4i3 kA B駟/sʸpΜ9w̹48'&&T*FWχ0Lmmde Ag8aĄΝ;^nw)M>Ыí[?*'2e2WÏi?+h'OJH$_ ʵZmXXʕ,]D3+oz>dJ%wӧ8t5kVG wkon(8RoN9}ֳ.\ӿ?-[jÖ_V{7 !|5&F}+mhS ³Fe-Qp_z?NYnB(==-:Z-|onXΘ1}̘Qo< K1-P(/p/_V9]'ޜ~oMrH/-=Sj֓ahh/3bR>q[1lχ:7K/_ʍ SGJJN>Ц~wCeggK>JN&\z>lmmKII.**ǭȨ-?{&_>q Ex=z>,,<&֭[!pp_ ^&$/]x̘llld&<<<'gBFFi!wݵ[iNOOݸ~.]M6>| Ww=gά+:Z]TT###222,_ЃwtuW7TA9||+V,g`1Gn۶B7}Ž{9#֯_s[6vۚe˖DEEmr٦M̟?W pqo5+n^ZZhJB D"abbP(hlX,NJJ C$<7=='Oi8ΚᑵkOk-O[A?`邟4TtCi#WSFx]HgadHMJȷx^kyjKAG :?X$IENDB`RaySession-0.12.2/manual/en/images/patchbay_a2j.png000066400000000000000000000260551417052567600221010ustar00rootroot00000000000000PNG  IHDR!C pHYs+ IDATxwXߙe K[:RD `A-XK\crorIL3cƒ^ wve{ð "p><<3gs杳sp^@ xyL?^݂AjAtg hF`(;+A(9^u΁L˕>ZH-/KΡ+1$WuZZ@WҤɞY kFj1YLt.mLkCۖ&Qfqq1]Y}DOoH0x9&QNb3#UہGE LanaLƏ@X0)**2usdbh ThaAjAt1qI!IKOokпV1#^tceȦ]2 b|Ǫ͂ArAtgP iӸ 00zxE} haA\9ZT$RiCCCAAA D=E<+H0τ.///++UU tsw477OIIMHLy^#L;0l`PPhHȄ SRRƜMKORqww{歲}X,)SΙ}FV8cMXh7fZݝdzTgryDx|'ݖNLa! ͛L0iCΏ˿XSubAV!QO䓕,7*qF7ƌ8`0XŠ'L8#JrUD 0Sf^ݧ8N~N3#Eb %ۨV=w%k7n߁8ۻ~NNN((M7{>. ERrrG c~ wҟh1c͛xSk}Ż fhQ@ HJN^rqw:O>8x`9g_z헝; O(t\.OrrJQQ1== ,fPTㄭYy(-5b-Kxxx@ ̌ r<'7/qcFĐfׯYlCwmP to~3A{̛Pl:tɦFoez6 'l}ts%^^T&3%[ɑ2pF}}}Qq\.TUWe7J%~V6CqXlqOL7o^UVޥ`/SH|y|T Qˇꚛgss_ac ի{#?A7(++{6jXX67qazt̹\@PU]M;py2=_8۩6,T_`9.H---s `jH$ڊbEMdvܩ/#"?"u_NZ]'d^9yڒ>!se2/xj Aʞ\ K^]ed2[vĈа˯2h7[0H-toII)@R 8;;UTT<5T&#yzz`f\ٻ!!!޽sƐs*;==q||3`c"#lv}}=9觛9:4*U>:2E&55טǾ (0%Cc ׹\nIIg~2zqt⒒S9\G?eb0///OaL*U~y_pqi77[`lSCOp |Zs j^tr+NP```@q Rb'O*.)1>P(^\{1<4LT3|B2#ʼnL02|TXQq۷;Lcy.$7ϞgȦ Xn]tiԩZa&vmӚ=OFR*=v=]t[JesNNN3gLKi鏟4 &2a֬ǎtJG9i$Űa4i%gD[YY-7.`L?~ҥqqqgcM#^m7A#??Rg}}0``ZUTTDǰ~}  H$Z%L:u7o:qt7888@eefC,&@ ꒵{uӦLy7]]]gfew) &GM5s+$$$?qa#2#6thhHȈÏ;~&&c!:605)S[[D*5rW(zժ=z`aFINNqtt2W,O>sz0bۿ";𐐰3fddd:99BBB ꚑ_qS@&_BPx{XZZr8Z-J]\ܹ[T\3% Y!0KKK .ΎdzQ*7Ũe@0D"Ex^0D@A  `6  m.iD7R <-A- >1AVP cX-] H( P @1@.ݜ*D m wh]aۚ.:pGa=%T*.5KdZ8/DW"=C0&ј_nK@G 0pdہ^1 1Y/0v":YTuu{ݡ#c@́l>aؒ's@R\w6jrY& 2`wrmMſL/猞D?Ğ[9g-Lh2rfmXJ [,eE|;Y3-Kc3NK03ct#y?os^>thgR03E=֐0=~p(?盛nnߨfcK j>{ku;m FN_7ںyTjhMSFO| +?cVn6,D\n6Mi=^<`ԄɰֶN<;oڴq/YGn.x8/O˒ܴ䬛 ١*Ȯtr*/gzR!e#)7,Cl|gy=źU{tMi51 6:E:s4whzRw#w}{:r@ꤌI|LՆIA.,)JEg &?kpIAMzrAS @){0o&±D Mhe1P}V'VQOJՆns-:YTQ6!LUj5}(C]4&3˧^>.VMB0$eB%NMk&\94b\^C|@/A˘\zEZ?uBHObmtGt gWγk T{fvե}`TȕR2-3w k0 r26۴}1ǯNJ Zl8m?6ZY o#V3Bʆ i}DJT494,VMB0@L@B\F-@Ve=,#9>~iѺy \=e.hU{1hrρ[ I g,ʀiưs6 kׅ^W /T4 8Ȟ,O['Lm̎O|^ 72y 2 @ uiҕi1-!O.SNb1KFfe  N`T%扄) Cxvd9sa-\2îzE>(+^v?$R2K_oJ'Z֘uCTGdou>=iN Ú{G~d[~b,|R^ -o]H}usQ^S4ȩ)ߜ{o˜v:YTM Z>?CDKLK0@LA[`=}{^W-S9adU|=+ d1 烖:- yGg%qr}zPkH˪_Ƭp@M>f>'rգ箊HnKq6#ks A\-ЧNl~`@jrɕ^zVl,ܼEBIqn;Ja<0Yf5Zݐp82e ã>vN{mɫ@zML!Q9ɫ8;= q P,9>L'׶Q Oe~h֘PV"R3b- v͋@t /G|ϋv鰙/MDһWvzJ c a:=6"1/M 9/D!:c]2S! :9{?4ޏ@:l~0T1TKa9>Lg>#ësfG :maHaс`8c0&TK/{>ofJa|n *qPa: 5Z^z/v58Ӂ\'B\/*?N*4/YVÌ61 `X/ kNme}FraBlByad=E͝1Teњq֜ڂ;k凓w|~:?pޖc Ҩ5BRcj*l%1Ge:%I2dNxV+?||jfM ֹuUMAWP%ڙ6ebvNoOH4M?=wee/? geu_;}h|QW-*yU`:l9/ &3mPJ|Gk*aoZyAƬxܐȾ+7Dmq1_3K;4AaUZX䱞7 3Šcd_`nh:F?wϵbm5'76Vk0 ]].+*bcRrKzLLSkaH?{Zf'W)wn>]tZZQ"7d >z@@!Z\t䪏&gUlZ[X'2Z{͙e$V6\F,YG/GT,('-9Წl-@RSE[ݽm,"YnF=5`@"TjjfjV T/ֱ:u܌2,qgJj@ ^"v~q\j4[cl QV2ynގV@RW&LH0ZzXłFSikF}4dRj ܡ0Se*Iz3h%{\{~33ƊO(&Es8+v{u_1xQM7\8-]7VozN/];gȾ% ?piw&ZL}gYoMi 61O-͒>:^aļOW恵3Ȥ f4Z9Z2;8܏T5sðMWFٶ8vc*!fâߞ iVe䮌#?L-}kw>)LZvIEX!jaIqٟK.EsGO<"F}s{ v"@|h3{2aP b%hptXevjB.Vl};[k84A${~vjȤ +Z˄|òu\X;Y|zy \d!CFٸmaqnUn̯\%|hY]Bxo^?-؞%-|+ҧLxwd׍2uհʜj;ܿ|Ry0ke#Os=P³#J}xf!BO%]PhMq#$o?~^SVWm;WRoPcf7~*^EASecL&MSF݋HU^\52;$aB.3;dVT8#Tmu}iA5TZ0x^[]{5Xr|=^l @C;tg/'B"ܣǜ1)pܴA# $}=rņWZPC퍻.mKq.^\KXl3[; ^Luw#i?nt_y66L6G/n_J'_0c2j* lxO$ZS*Ti52nGvDĭ N-|3ri R<w70͏~-{:}&t'ͳݿzߩ($onޒ,K׍ $~L^TJ?$qҼ!}+Kc>vkaK֎㘳TJT"'T[N ۺ0'WiT8!=5-%ge:g]hs^>/YlJn}\ f8,1 ;םa~ ߌ\N/KpUeG=ybB+rҖecֵ@!WLpXBrCԨ %4?iq!N_2""*>4t>ak7sU.mtNEqWߺ(lbh9+xE O9qjȾC}"&1߾@?pUF%uKtYcckAgCuiTT X mX .QT !ZʀPkʊj2?պjџ_hmR?kX0FX:o_JW0L@A>Aeџ,k=V*zػzړq(zz;@M"򝦽55?- C[ 4]%b̭Ww*qyq-U&_*19ñi88خVt_c9;[{}]^\ sd`ިΨL@g=<-BOr0]M(ʂJo?K+y\BCe \k^^\r#B ј m~qqU0mÐ| 2 Zb< '[ O,=yTLcZːQ}@+iIx XSKw|~ʱ]xdbG1 \zJâ!.ʭzT @ {Tv8R xvtJ fLJ0s^ g$k\)Ez;Qm-Bn A/DrC=9J>aZ2{GfLܕjUJ*Jx-*}P CB8bO G' zUI^Nmim1J햿?湇EE~f4/Ih`E#{65`X/Hvxgl^I#T:rH"-\$‘}TY={9FL iTi[ 8&_ wQYa\1nfpyq]iA-XaVL(TֈRa޵)wr-n}?\|IeNR4hd}5/AZI  ]ڲg~Y e5A}0^zM]Wo1ܝ0g Qs7/e_ `0_ a83ɥ5IfwFdbӧۘWN>ڶHPӐ`&xz2IWcr& L/7.OEL6LWv|v=4~VHKjۆL^J՚[^TKa+phco~:}>^Gu`ӕ%Y+7|ὼꖝ1)+6D8v=:^].S))wr~rh0 27:b夗&>3ksWE|j5lxtQ6TɧrtV zSN<(۾xmF,5r?+weDT \ϣ\*K߁ވ rǯZarԁg !$"YLyèTT_<{g2Ea,muUz'7[q(4`s=}XlVTY*P_8Ӗgo%+JZ?wɭiO  4i;LݿQB7,ܙE]ȮACBͺnͨI3sJЬo&I 4U1,8_!S^8|WZL6|HdUɺ4KF~vj1L&B @) ?]0Z :##$ޞE|\Ú1QF :GK0hV?! !5.~!]=+͋ӌ 2a Y,/KüL-KZuxѕΥxY0&'G G5YM,tRFG ۶_Y0YjI Pz2^3&{CY:!KBE2-L;4t%M>c>>6- 1OfݓK @ @4?D³7IENDB`RaySession-0.12.2/manual/en/images/patchbay_base.png000066400000000000000000001326771417052567600223470ustar00rootroot00000000000000PNG  IHDRj pHYs+ IDATxw|Te8 !BI =+몋u U,]uW^ *wWH(^^C'|>Μ9}d[B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!⌊w]Ŭٷ;DnxBh;S!q /,w!6: B[@Q8!/!Bu4p8NGZ:U*UYii~^^*(SwIҲґ#FtvB%V &7~x@1͛6o^rU[,?omΟlE͟?uªޕ/?ȑON!PaDrrmnֻb*o7-;B換rJ"8BHB@ vF,!Ӧ->SL*|ͫ;yԓO=t:cgD"lkG!z h @mnu:= l=k׭;4sm=ޭqXWn_Ϲ^*uӍ79B~7[,S&O~hrgᄋyI|-[JNɲehTնZ {_7.ڵ(jgzj_2dX|>߲?߸isg5B!)>Djsrz}vNV1̝*gĈHt\I 465'lnlO<46 gd/ƦůZ8to>h>p)LV[mKJO4itq۪nݸg}wyG?oƕlظC<#?\SS{̙NkBSp  ,55-J7 zԔmٲiO >{v\E#G3caÆ@^?lPP^^Ï?ie/Y}ᕗb}#GlFQTqѨSB˰^^4. ȥ J[7޸~aJN4z<+W BpQ{rc%I[\ь8&B#BUVVSFo~zqQqpՇVV{V*UFRC>/;{L&(o0?/oI۶moSNM0;G"wy}رɓ&=p}c=A!#BmD"{G[zMqq簏+*nfye +WjK?xtq󋞛^6mӦֲͭe붢QE%%c~V|T(θ喙3f>\z>"e݅Yo;}l/맕y} ,?nu[Njr$S[%Rs~TB.ip?ZR+VkGVPn횫^BΠLTN>]iӧx#֑ܱZ\.W#Ał>"yCf>K ^l`0!POG4yކ@0XQQi0\\2 fff464; B!ڂhZ[f;{nu@HvN6RQYnnqnw!P m/ic ٺ}~$ne}+""B=G4?낂:(7Wtv)F-0 sL&lv{0h]>%\9i竔Jtp B G4|yEy1c/X6nOg4:Xȿ=RRR?ob1|9 avq_m޺}_T,~Ŵԏ?tͺuͫ;gx޿G!;>D`0WYn1?zn0H3z49v@^n =Go=uZ]T.ZS?x _5rYVVV[A xثG;H$žicDr'x\^bJRxzZ>ܴys 446ݻ7 n޼.u}ͺu&ef|4w4}-~a?ou6mv?ۇ'M/ɓ'Mrw߾w׭D!:GTJUvNvff`Ol1|Z:|MfθMdbW68>M7_Y'ɓ'MXS[wo֬ B7pvVưnlX%GmΝ_Fz?W_:l9s6vJD!G4\m􅊊UV8ys) (jڴiî] 5Cddf]*X iz ۿwEkl^7t#5xF׻o;~3hŪU\ u}3o^lm[g`Wq1=G!c0}D |yy# _7~#<..ʒcƕ;~Xw;we/znW|>_by<^ɲhԨ{6?/er<`?irr ۙD^d2߄BBv`OL0A TTV?~8ٳKL+V]\t7 3g(ʢQ]<{c$o<1GhKKxXS&M9cƾ-# ;zݸ;o= Ϛ9=Ey`(##h>R:u6lܤVkk?FeRC|>_!27`!9>"<@ VV _Xo1yF̋^#!QUX8TTٳ/ĻD!Q>#KRRf*L(0jNew~( yj{/>}á=>̓h4[!PBuMO4(79YIQFj-F{vC,a -[~B904aFQ;P(DQBp:ԐiarY(|l EE#y<թ !qfuk;t uP(2dXff6ˋDuuMM5Vazxӗ̹oA?`MM;~xizBhXRRRj;/?ߺu{FF^_ 6{qEaW_ =B1'OW]10!k +\^N|tjj.44TG^=m ?࣊ʡC R{`0g-߿Rx׏=fS￿TV_6lش|nmK/&B!LQeN̙#Vk{KgsGHzA.TXС#`X\.B] g^#I_0!>N#G^gcu}Sc:{˄Cm cO塨O#HB"dԩ3_g#tx{766% ENN /hqqRRR[eZ Bip8tT.TDQ[QJe#Gf*l}DRƎ @>k5 v}W<%N^|w}?z-znٲ/VO/xK~zH P?!l6oڼyUm]`۶;=6ԩS`c :xW^`#G?q;#ԫ0}DWVJJЁ;S| C!ٰau~}p??aA{痱 AʕW\ݽI))&EQ]XPvU7to6[v! G4U*Hp4TPk2#P5}ڴvjI^yu'Oz򩧝Ng@ H$6kk"S0}DW,=zJ8ڳgc8 B(I(^Bvk.@s84Mu sx㍷kk^~Ç/NB;91N@:[;v+ Q(NTFv:As8wv[AA?xݪ _v@Q7xo# q|2e>( !{{wމI&[N-:eˢѨVmcn\(޵k[!PxcK]|Ar\*Ud$H$}ٝ/jvŸU z/-+#~}߯͟_Q^NQF.Vmǎ/0bH$:ؓY{]w'zZ 32SccW^-:7sm|O+۶%%'O4mr 7nٳ~7JJ6lxG~葇=}L/B= GԞ1|ԩGYڕ(HdJF E& s |7 áp8P4!a&=tOl\>bDDґռ b;vv:op۷eBqeTPT4ꉅUUW>rrM<saC ~qIӧ<lٺ+.uG'>6iz}T__ّiҲ4>_tfr^ >4Q {krPtȴsRڷ_4ʤ|Cd2EQe~F0?/oI۶moSNM0;G"wy}رɓ&=p}cW}LQRSDI55`;4U nih1~o(FӞ=nO?]]֞5nwԍPI| >[ou*jN{ΝyAUil.˯/6o5Es>.vͷ%V\YX8LVWW/#/znzٴM6Z˖ۊF}'qWWRP8[fΘ?p)\8ԺIn%> ^*EQiiG IHH~<3}ۯ3@K>fCۓoքގ2hкkB5g϶8׿S/Z{|ނMYGK '+rGoگE*p8ν 99j4Q_G D*ȌƆVsG\5rdY(8ujmm%;?P{*p=]JHǍKJJr\BP @G*߁~e~.Žl_0l*B#jEj BHCCm(S2:䕎-֚>5sG_K1A{]>V(:BVI>_8vl\ǎVu-}˱'bP 2`0z@ 9z%+HkAjUVU_MEEgov#"ng'PEtJ)! |>_T~^R6 ϟo+!CϞ=k4-0}D-B MsJJJѣ{;fefƫjPpE0SN=gN'4kBn;lliD\V;vlMPVVʞ ]cptqNe6o'N)'ٲZСK?"++ku+/T(^^ 推D4(LT\}#`4ENռiӦv546VWd Tl+M8qX,|ټ'֬][S[;xР_=MY~سw_{o^KN>ݹ7P_D !CTTw8!+BydedR(q%%/<Ν{~sbE<`dg xW^Vp]ep{;f4=}nPñ% Prf32!ԗ&N **+?}٥S|V..B3gJeѨQ.z17||ѣ_\%K^o)&͜1c߁eԩJJnh$ҥ=1>B0M!P__XB'x<. @mhzŊ}/q,((5r䑣G/yeί^V6a]4/'7Xd_=2&?gVVV-N0dz<=㖛#ǟ~wPÆqҠAyyEc7HW@5sm}yy3f2e䆆?_Б[E"BK d2ۼag/a#j`0#Bh믟>edw`Ent!`(d2p#B%@xB=+zj&LQK\.?[B6" A- "W BGԒP\.9!B%BT*w,!wDE! kA]C>+S N;tqoGY\YS`BZpzޮe=t yz#ڂ#j$')&wD!gS Nۓ7mp#ja"(:9YpB(Φ^'H(dB蚃#j)Rz )Bӥܱ´s_22ZFW<@8"(꺺xGf3SOq ^k"!0km>~#n{ráx&qJ{3>@g4vX8kԒ%b@QTB)ik%"Ql$j}#B>u)wD;QKH8 DIud .DB]v:EQW^3c/&D&"~uNyLQ+|>D"(bi4(WԚL !t 7SgMn%}x|KBEaZFc҄;0}DzRL"Z\Z#B(*,T*{|n/}(x&>}^/|Ar8P,''%%'%IbT*OOB-5uu(摨0}D,Zm\=RE"=)Bv{/>}á=>̓h4޴yH$<WbDMhRT*BQYy,~£NQ꺺J1##W u !L,EQÆ,[…rah0Fv:]P(Bt:c!M P(Fx< W}>Ou4Me 24/oDVV'^(pꏢѨN&'WL>_h2;.P"Ϸ Se*oS\y̙syyyyg4i 544dŋ1Y ௪(/ 7gwG{ya¡SF樷Rj:܏rkk/8VR689Yf256#tIIjXyB'|VPUTTZ:o>lJśo~1'Ozj7aæsm^z镶Myݳ!&Sj>|\Z`DqmG:êӥ*e04d*.\B%~3Q$8pl6 9V~8tX,.C5>@hر=6qqcLٽ{+`$juN *U*]MLA`0{|UE4D!޲Ά1!PgoR]]P(.6lɓ_ J` j]0RB&'BB:tĮM%%c B}BE Z\vSﺼbHOhRzL0}Dm2hV(4`256-A!Y0Z};>/~yٲ/Vk[]~ɒE"ᕅ#6r!YY=U&JHl KbqrqDxQ(,#HjPϛ5xG0)Ć}p tj~<3՗~u! lذeb/MzU]GOhvmnf$B18s>\M65t55B(A 3-Bl6[7 a[ 7x.==嗟;|nԩ2L$;_G" >~o)kjΫպsuD#jfLKPVnCj_Bh@B~\.X4M}܄E$z.hlzpX !J8>X,*j5B,Zo46;4JL99r|ĈBS]]`i.p\.W('%I%X,MJh4)ZmjaXc2565X,+kF#7))WJ>x<`0T}Zm!G(Ñ\4?om~StMZ4(鴝?hl'Vt<5Gt&SSj`RknR*Rr;4P'#wu{3R{;{^^N׽3gϞ;9zD"9cNqg6_`Z 0( tC=!VOUG:?mml ^4M{[R3gl߾#Bpܸ͊)'B GtK2@^sd )B$?Q&4MzP6lr]HΝl6KNcK\RϮ( BHl:>=Q!PoKIQtǼyO5ף.۝nVUuVM(Bі+baj51LTIa&9`0Tb_RB(Q] لg6;I9sHCCZ*A?0/%$L1Lb1L)65ޡ!P]1jք}uۑ[(~OOμFb25 960 z}Zj0SP]1j>ڂeBޡJh'p|>LQ0}D~Bpa&ScJJZ7B(A`CZSYڔ Gr>[,|)%$F.6j=B@R$ށ [QG͆!:]zcc !$ l&J'KC%x(>@bLQ0}D0QIKW(46 Jקcuk{uGRR2ÉDII_y:`h [~&%Y|C!#j!"ۘP0}D ].D"ujP:.!B@G"0G9C=@,_z^K*M !P7%%%"Bר>q:mOPǶ1p q=Q;0}Df46RӥON[(T<?!24p8pXh&&P?#4) i44aϘLMF !4P)Zo670 #@4#j19Fglh4Tj8N|cC!5z}!PG4/z_>0t!X 4MxBbD"u8 0}D]V˗HQ!B 8z} ,#xx/LQ^qh4b9Bo`!:T@tZ@Bl6sBa rHQBh@h#w\uP׼2 :6P,*BjS aL&iwP_uzR(=c46aBTV9 J%$=ר}>n1 a{=D"mB?3}VXF9LQ\@/+|{` mBVRRrr#BQRRie["j 3n#@B/%%T>UߨP#.FT*-e45B;sNڴh誸 x0KNVة3%R*5B^NT>|lnj񹝙JmmmCa>`54:dj"!L CڔDA rU c  `ɇvfff~Bu";Rn h4b8nl0Q&B;M!$6d*^:33͍ĺQ Һ_QZ qO;K#]@0QB.T~qypvP?#%X#pؖ3&S!Կ:lnbڔH$ddǁ}i]ȭ}D=hlT(z}eH$lYT*Lt:m!Msj=Dck+ u ôu׹s־ 0q Bo@veII^ti>"P?Vik2ǒE. L 8rTQG8;z'2.,|#Q0wt!t(ZM f=,';`0pO:&ᅅ-$X6}D=q>6_dϰcb##JVs4a C ,wl}D=h<8_K-K{h4)U wt!t(mz4.&BX.WvzGJS厀9H$Tj\WATBn!^NPga#a1=}FT &ScZZ^~q!zOjj&EQyfff;Wu_Uh4)zRB1IIR$nB2h2{>-զT0LJJJDbںR*DB(iaS.P(" PU\Tq&'K$6E 4M+JB "nfffzyOpt^ M\&aݦpH))tlp\)vS(Jqypb1$zDg~Ƶ׿w_3O_Z5wP~OsSL??4ʪ? V04ovA߬YSYU][[ܹ׍g9zyZ`4(?/o:TӽwugΜ!rGH^o[AIK^4Z<@Pa%QtTBRб~dXr_ `0t:8tz>\.g(jo?T8l؅(67P4jD"v `P?Yn*Pn2S;wt8cF{ aC6#Gnݺ#Ν'@RkVB>-tm ^KOIɴ -*N,|>!YM EAluJOBv](fg{UW(rO)jms-z~ܸAy'M|w;vT&B^oӧM6lԩShwZ Blbb2d2+ x=F;薐M`csTz |N]&SDbgjZ-BZd2a7%2x1 p:-mNy'Bsr9}H<0.NMM =P(("lظ?́MFZ$>N ,Wbx;{3bn>jԨSNzĉ?~/_KPz)xmcBJN:ᅅ_K4hRkk+шe(e!tP*5E[&x*&\[},ˍR;o0gvO,䦆65;~P(\.nw!ERٻ=? IDATx+"H*}>b5?y7T(n{yWWYzp.Ώ"$ԟ1 c\\JQL֓}!T`Atgz~CbiddIAJ!e+䲒ojY fLX8ee|W_74Fc,wlK86Ll:.[62D"<Ɩ?n3ut.n8VU&S[Bנd>~Rզ.-ç3Lj%sS4r/8NUQ^QG765;GWc̸h4Z__i&C_%yrzhmD! 5e@.W "J]h9~`WOeONȖėnjqw CSk.K.k>6$+g.(2d4My1h6v;$>_B(I$Rn'tR᝞4#}g._|\z r3֡ں5= 6 ;[lj)w~И؂eSzEvMj E.dJ)q!PB\t~0Ͽ;^naǣQz6WŖ퇚9iE1{ώZ Q%Z؝ܑԪ%TUUV9N[Q \}( \v\-MB!zX, TRؖç\0ip]pEi|.u\%6= >򿧓_b(QpEQ!(fJ6 rZ54T/kGki&- l-EXeO#!Q>8n: E"qB 9 C 552'PWxۣ@ F)iᴸ°"0dqӑHJ@J ˍD;!P h!DN?F(%"VAQ/!} [ 1nLDoB$'_XQQNԯj5(JF{BaǓ]BQMQ4ER >_t+yv^C HhS8}isF*fqU^Q$)++Ksyy/<(777 o.V#T@KQHHB(!E"aPpTx@0}}98V;x r$\7\ۗT*Eq87͟r\FP(اEeee)|Rye GѰBB10 C.#9Y hXB(D`0 7.p#jUw^wjLT3TK$I}6?/!7l\~{| O=gaK^QUsaSL Sy^xiqeUݸN?}o&LxOh4)z 6l~P(<|˯vLxB=$%%G"a*>rr=J>1;fl~^jzX,2*;63wqr$ز"ے\$`d!B7%C' /@0lޛmIeuSʝt;μgΜ^TdׂȲ߱ 6oؐ qСcFzSwӊKJ|'{]8kVر+'O4fcǎǫvZe'Bt^񔗕7649i&5ed#JaJe~Xl%k֬ݷo?`M7n<|0 ՚ҝ-˲^oQos!|AJ[{S! G{1(ˈeYY+**of{lB0loKNŏ8ǟ(**:tW,yywsjjjf͚e4B~\xſ^4{#_@Q P;jljehll$+,>h@>&, VfeM H4-Mڠq뾓άLMfdBBCcZ2x͛ϙ5v 4Pb#h3Pmؼe-ssU*U]]](갵#Fdfflظ!bB߭^;ynhh\<碊ʪ}Ͼp5W_mZ>0 zmW|,KPHTr\ fә_o_HMM5|k A"O0,#G"~bJ655E*!YiB("BdI1m?t_ST4b1/_Biiy4N8 R;"?lݶ}ذBrwMMMQUU]YUՋO|jNF,(A"lkl8]UI4EQE!AEQee RQS'=0ft\vpEaϞ#G5j\qe'O.Ew-rڵkk-{PQxgѬ O/$|(JdlAL}]]}]]ǂy‹ I aXeDY jkk!PBh˽^,˸0˲< ,V#4"\c';iԨq啕'z~v 9e>F!O?W 2qQ'cOQ, ؼSx$>%#,Dk= !ai 3dȐ4Z f,#--ɓo@ Ge4*nSS]Sӷ ?bDyfol9١HowdZA&+.{3|xμ9k4h4hYL׮ èTjIjMm!jefdID][EIԨ5VRB!TU EFebXa(4=B?#PǙPPc9thС! >{~/%I$)zAn0λ+>}z@0X]U-uk+RS j]m!Ĝ L,*L$ niѪ^$It;}!Y7h4z5xw@0PqdXR)f˲,`aXfiiur\@( Jht/(2/;\Zv'9c/^DQܹkjU;M wEcTlO6DO!,d#*!C!M fdBH+>[{Ai7ܰG񪫮˯z'xm۶"_n@ ֤zr:iL_:!==v8M:шo8%5X|fmC B!QT*(Z,<ǵ1KNVd?3˕UT8i!9߹n ´Iէe!DӴhhpI $t:aV~͖-[)q 7GHZXVzNg :afZ\`@ s\ B=pڦ.at"&(S4M~##vN0 Bpx M$7Kz.|XfQE )IREQOQ˲zے0biӊB|b --|bC|٧^[oݣ]}7`./vgY>/{aÆ.䒭۶9.!7믿FTW~WBn55ii)O='Ӆ0wxͷAA&́s\_/ǚ# seeeWe0 h! Ͳ$ޏa h#Nah<_M/`LVɪ)_!nwz]~'N=d5O{}s؉k4/]vGzlޢE ~+XyCÉ(J=$EQO=Λuu'OTTT<|Jɓg $́sԎ#G{CJ 8Ns'zQkVSet:$I~_VԄKx<C,++eGi@rkZ4}nwm^SSӉҋ/SSSq&N5r.t58+,_㍣Geւ/xB ӻo F3Fh4@8].jK{7?bI;|xwQ^lر x?1jH!QQ4fsŒb2Yh26[x/Ɯ$Iܿi=zba,s3g*MuܷheRRRg]]=g+[(O=iӊv !,*k;{[oq8 {>㫯ǖ-_΀%e]\>F1Tij*t0L; #Fv3!EuB`65^Z>`tuuua(I jŽn9]t-xߺm{CC(|ϯ{:4fICƎ{长rرcnʪ wݗQFN:?ؼys.c]$ h5-fsٜҲV=}f۶ ôo߾cskjjVSOO駟B'3<=$K$mdggi'&G1G68*MEnœht'0S\.Ǟ=C^(3gݱfGnZ^TJjZlzcƌIMMݳgϜ9sDQl!NwAۍ]A~OӴjB! `F#*]ycƬfe8j %E',n;(SOh2dDfP9B一 |~> s}Ǖ`˱^lC 8Ro>]̱94?^&J%IR?bq\m|4xk}ȝ,˪*u]eM&liU[bɈJZ4jl/F$cT(stA2ai=rd>EG1j!m#W:n"T*PMM q#Fp\eǎzeYjjjd2@@e;1L}EÑrB!))LTJx<.v|>Oxۃ\3 ˲lxaXTVjjfРL%%^n[֝B!7̟߭ 7\a~nK6rr-\xhke"avV7\,ޫO$I(.st!Ql0mEgg9rR1\ IDATz]t:=gf=pV~?0E Te].WMM .iRRjuFFB`Y6 4@RFbI3Sp(Imvr!T(TjFT+JBV ˪J˪Xi6RÒw!#?= Da`\"VVV2~E}$iNkݺ eee$wBlҎ:_MQTż| љF;xQpd[mmUB{|> $IRT B!e%Iy8+EQ È(^X8 ġSh6-Khi$BSS񸺸y*V֨պJT)05B($ BHIjN{-!I 编%Ie9%&+ iW}4ue6ooIɁ}Na@$|nG\;Hٲkի,[,fvQ郱 qUTzMyEWV*BVU(X&"By8, CȲv@0d5S  ⛚&?>JZ7FkDZfE/G yz Nf P( q ~{y璦&ۚ5?4;$|lO;>!r,+;.eKjJʠLEdJjȐ၀*VC P$vϧEQt:84(˲(JVxDQ i@ dJ1Zg! .s&ޠFY@dz<.:q\  |]" Ao?r|mrJ2^> FvGvݼ"xBj^oMzdtFp($V9STqh:q`"J(Jx4!OXVLx,Bǫux0Q8ZR&\hިzVkjJwA^7^,:,,Iӽڛ8h׵~'ۊǶ w(ƒ;40e,˲BPTFRiU*J;\|h|>wTSR2N76] E(>8g 0|DćPHTlZHrB/htFh(*|=G?3Jc4ZL&h a;>sCQ1{v啿<tM gvrbR$X n)6M@%I$^Py^C$̡(!$b#(6fbH6kM&k~P;ztO/;L` V `UWT5K_ BVo2YF ^z,˲t+ )6LFhL1M,B^vz.i aɒ{O2cHJ_>YjwT)r FP-?y !DQ!kEPa*Bhhp O% t8  yP8!q0W?EQzlN1-EC$IrNuYaX9dJ1Z>ojunu[18$5D;vAd#tȍ7.6mN[>I'((ijGTF4Ͳ"efhN kĴ̴,,֠I!$< Ch1-K^or8[O]k`0ͩKNghF^r^㺛h`;8DԂ䔏[F⌣dee]r~tb`ŊV;%,˽~{Ȟ8qBۼ^*XVP( BR(,R(,Pj>N h 8bE'%efsɔ#?@x>tڝΦo)jbI5RF3M3 ^@_ 3rւ:MixVS>d'jp:]A0S\SBVt3^K ^j &7F$>Ѩ 'И>w60 ?ua`p^ut a RR*UJFR+JRPFfJ[D͚21+$"˨Tj%lNjW>l c~i)bI5 r\岻\6+ĂbAElr<+I(>[u3mZm\[[g4?]v?cxh4,_&رc#RVVK/7!Czw}|xcgmݺmݺ VE@ /u4cFƐ)*@PT 8RQ4e(/@ '0@-KaR4J>lCX,4ъEQd䜘="VúHǘc=Q[[`/`a[ho _V[[;~{~[xiJG{7x}]] / p]z鼕+W/ݬAcN2-*)qLET +UB)UfYVk4F eQ̓<Lbf! P*&Sd1, nnot:c丢T,4%U7" nor~9xk09J`;B$|n5kGl\P0ᢋf zJrӧkjkk6:عs7ޘ8qB]]HKK5>jw:eh6t(,ɓGˏ=!sO+RRiT*ZRP pP(q`0qktfi$0@ah)&Uį0lZhZ5S,4^Nј+`C{x@I!$I%%KnLE˴W,'՟ q63+mDl8://;-KgpXL&ٜ7b$;63Zٜj6(Jv@gҲaò333Ϝ0 p8?E 28##nܸ|F-|HŔ&۔)#ψ<3⨊ZCx9jzuPJJƠA4 <GUUٙ3 gAJUjg(jFg6hL4bѥ$ƅy{7VA;Ͷѵ,8&^Jm0 hh-u;6u.^o4SF *@suisωu0}Y" P\>v?~{tO?|us=hhojj}( ˯Μ9SSsWZ]] ϟ{gDxO?ym6{jϾܴiKvyE:Bp8j4:h0fɔ2\.{mmU]]u]Ax\= bJFVkJd!$In؁<%YDm;1yV޾^(YyWmߕfh fѢP(𗁐ypJEQ N[25T%$Qgǎ];wZ~X,.+r-<&?p߆  r{x5.q /R) u|u˖=P(8S*g !dedYJh*V֨VOQtI箫dZ,04MTZFVb0XxIx7 ^ q< gRXT4uϞ}v Ǝ'ۿW5تCbgR70bv8ةzCӌV z`0tưN(ny:fjl1v7\vsN={Auu5gP/H!! IB6 l6[GaI~L -NErB›o6Ͽ}ΞHQEA(-AKNB x<'dm] I==B[ayRz`A_qB!B\3ePP"w+Y wy9,WW׼;~*o96qT A/{#sϝv=%%7.--OEZ^5RjNnޜ vv;8.&#aYh1,!8q@ VII!;2ɴ#H~+𫪪~罶*][[_X89F$!!$I,#I!$!Ahhq@2P˺=PTZ,qsRiڄ8B("`/ĉmáq?ܡ5ط;kȤshv=$tfSSQqR(,-/9RT*-2_-@@~ ! f3%D $y.v$s$|Gba[˧vGLxuMI !~B$!H ݉l^0,ð4MS(a?2 MQ M0 !1!( \B bPxggg߿ nw0 P(ZЄ?P;vAKzGؙċ?Zj/H4EQE4P({M f8mBPgDe`[bB@H f%lNiB(iê H>a e Kܤ^{('.ӳqe KK,K-2j=tup8M&В$CM&nz:|G] ~O(9Bp?mI2M3&bd2YEn=WkBH*-m''Οq $Eǔٳ}>+x4@Ch طkXЌ_]uv|e$][[?u]NBU&{`ή]|-~{K/X,oȒ6Zs^ f /q8lG"EA-YI!@'qݿo{}{y =ɘZx?R jWS*} --W^+++vǪU/Z-[͝{Eѹ#o߹z}7>~aXt&Q=es8l>;VIrSQi')3KhC"}b1vK>p8Ww?ouZWaε)ia4Ng4-FIֵfs\vd$I. DAԋ KX1bS*`׮=KޯZ+*LNhh:^3tz֠TZ"Yng85 M tS>esLx $"X!mbtdYT,+I1ttJO$H0M3jV3FΠT*5 Psm^sNC d" c&u@$M$D3RZZ~w^~& #fذR]ܻ;;UaUt:j͛gs/B`;@]̝;_ظqu :(Y* Äs^+*FhJZU(4ס',K`syT8u0) {D$|LXw!Hd%$IxLfIeڮ]{W^lك+.O5",3MEQ&Zy-IB( g8y>5"$IN B2<򱺺s $ZTu7m6l${Q& iSL2GZ2q,\ɒ$J,I(DQBC8 ,uH zOGЉL*]@#ПtGڦw}s$|- 2V $v$%$|D;ېVt3 9ې@ P>eK˧^=dwt!^'$D}dGl)7F)HTxiӦtK$O.3&kݾc[$cz8*ؑxddU&E -8_tG8 k&)ekפ3QC @ $9[J͟Q?@#Ў5Ie2yM ZeK 3reljZBlZ&@ l)ozȜV   m@dEC#@]k9:u(Z?T @ B5D>VNSۄN9X;I5'r:D#o0yzzΜ=v(I6-y @ BNА0*UUT.Q-lT*E ht޼ ǝ9s'O|5W(9ڵx'H Z!woc49y6rѬQã U썞nZBQ,mvHQl,뾂F()Ы~E!K © .,//O 6{y/$~f& D>+H IDATVl7yѢ-;JHe Mm-E&_,a'ߺuD^V\4 XSTcYEazѯn2xxm?^~x-K/7G)e:UQqbRAיL6dGЊ@ES$S!^{9uX.6(|2Bmb^zsBR (Tjmc IysF UgSTcP} QBhIӻ~Q@֠S )$3+G]t!!W^*.~Յ-z:Aw>YԬv8r/.gɁ3yC#@hEx|Ş!9YS/kN̯?<%3ͩvD^lwG#[?n?;wn8۷Y9)Z>jeJv2ACLӝ+HlIakԸ֕5,e|ϴY/ Ps=n۷=xig߻Ww|/= PB; ! E |uuuh'F '>_k7 R[k*+>k, `7_,Nϻjʕ<9/?-|WdI~kB2CQ!^heL,kЌG㲌2NAƲ,#Ek~aGiVfRu@2Boݿ_ۛ$R\zɼ#G.*X-噟3 "\Qhoz,kQ޽L9~ ]{ճ/}5kׅys/lܸ)6};&k@/#R:[g`r>ċQ7='mg׎a`Cizf TğS< ^?@VCvvV";JK&=~<\`nAҷ)E~DIW_4oUcsOPY'T>au^owߵ)!\8~aTѨjf|޿Pu]wͽxΏ6eYj}~~ƌ9x$=QBPCT]]GЊ޹\^eM\# =P:* /gMIͺBf*j^Zm~N^7--  KʚYfc yH~ juuu Ϝ[9b_~e >)S!BFӾD~D}1;;;vBBD"ߝhvĠAe z BrBkb>[cp>03#sƍ틙fnhlX4baxG8qb]}(?zQ>Ө&V1;;{̘ >VỌ iX6Q6hmB {3s񫯼2'gةS=8:wBr6n4w͘Q0q}xA\}5@|L)F>buS"‹AFK$!z==&';7= kL ĖsƐd̜yG8l9ro,@{~붭@h'Ѿ01==֎TuMR֮IOg@ (k֭5r䤂W^Tvݏ@> /AYgOqLŚs˄%N/ }ScFep<^SUUoUUUUVU|/cؠ'3Odd6"Sssf+ۇw2 =uT{2NDΛ1g^=v}illlllĔ(>N؃cB9xoG@ $6mr\W,Z4q„[>yk@Ɂ֮; @ tT#`_>N]payy;W}t-0gذٳ/\_|%%3@ ,u ^>^zɼY82M!,ЩS /d2߰!~(TWWrs-x%#E_uua Ge^{Nd55w._r8? @H"$IDb0-\Q\TGߣ-54(|at/Hmٯ/ꪲҲ@0o @?XA!'+++;r(B]:Øa •fy_XZ/JDzUݻosze* {h9|.ܵ+]#+Hxu䔏 {cKCx|# ,nظŋY*^R>@}}=@H*vQۆ'doEr ǝ>]?ߣwy&Bb_os! P{2BFI>dP-IOOEGf'?_g(Ziަ7ۯp[[QjoM?rzޅW<:Ò'NеW_=Zv]{7bƍbӧXG@ $r#(4M2B+^We7z"+5BXYZ?xxRŜDQ=wu?nwmjb}?@ t7.%yɜȒ {Քt[/Z4yMcf>s=?x99$;c~ЯՏq4_ĉƝ8pܳϜ;wٳ#r#SJ~6ݚ/3|i C|o2]HDw=7lȹ6%4"\QÉ8 Lj]*:]c'Ny^zOD=u"+˪v'1ƈL&F *H& UR@4&4!je 2AtxJ'2+-mN),*ӧcs^\*.ot i߾ݴZ-&A@MOJJ*.)q:Oyt߰EMkA}tr}x]LB)0p"ӛݾџ.bbSrKBqm̹T_^:ZqJ<&^מ?;!76njgV߆#:j熋 6s|ADǍ|q+0sјx]ue` &qWڥ71ʘ`e~y#4mSj/c/;RS/~衸YYٗcMovmIJ:yu&GDDQu=A{5cמ݉]2ȿ###w:p~M ,ڵGhƤ1trԻs.X̵1H`"1FLp"0FL`1t9dnur ԵT 鈢+2Q_毘`RDDjKQLR`hCt Ֆ~5u7~^gyK.{e?{Z {1"Qq;^Gj#H`tT=F*nR#ո<#7'v層.H`t%5UzSLB\.n܍ 2OJ\㷇W'Rm)U +vx>/О9m9q(nw/OLxmwwT8]?Nsͪ%%8x0#3GӢ(~盷lֵ"#}gUnݒϜy6J ="TVXYV[y52,8D]^ZyUMhkAZZ#i9$Bb|| .2 bK6x:qС=ޣ\.'#G.$rfk0Dg2VKwU^Me09˞-- =j΄O@cKWX;unٺu]=VsΫ q# @sU!:!fuvg{ VWXB;NΟ|NP]4X:uj㎒?Q>|ԲZQ>@s-/-%.+ui->ڟy -[_[phh e]Q9,:7%: E+֨pjGh>Kt ~R% TY*k[#Njp<|cQZڳK5_B*+{ǫ^ޠv!Jͩ2RUϦ3sQozx ^mԄkmV!pҖfvs&~uX姘)ciM>?fcO]uOOO {ΚuY]q.r&;Rx\.완z˷q! [ZJF4_(MDڇ'0sts,BOh݋Ӎ#|LقmXHx`Zd#~dHІTj-UV&tEi/B ,ح)fO2"߱K15!jQ[c>JGWVrfc_.}pg )rs˵~2y֗ņ\! Ҫ fwg^;ibxb:Hc+%i},S4 X[!EN@QԮ/6ZCɉ>c-52 +)mG~L;-_~v||򐂬U;'F7ϙyۺ<1ehxO}bmҪgIA.;98W>W7u SfM]vMq.xPF u> _)Cm( {imaq؃}=3߷ WU1ʘ`e! +VB kEy6tx>rN F9O;Wxp_K%+h֮M'L5DD&USm -+۷#kX8p֯YKjh/ξVE{Ôc/x|Wf{g-ۨn{YH {1sJID}*xlΔ҈[R q9ŻS^.-ؿ3M}t Vx5KxNޝuT0R>o촒~|O7>QDo`bF}r9qƈ7^X핹yaQGIWu(:j|lGEyvSJsM]}s=I>6Ѧ5 JC&Nq{OLںDRUG;J?ETlh^ؾCs?"g.GSzW{ex Q2, ?2&XMMѯ󒷾#"u=oۿ3EJDiE{2z{{"=7>"Rɻ۹vq<;!L m2 s޳|q"I+i; 0RnG2#Š%6"J>×fuH_G`MdNҌNZ%Vyl-iQQI >w9"`$gmxdҝ{ t<:%Fy=Yꯋ ,v؝$H&B#D$ a*0b$z'"MpYD0Nq|{8m[[/3hDoK`z@Ǻ\.Sc\Oߟ>"GU1JK)X1hʄ4Axwן]76]>N_XSWX} <#E 2w8y6*6'0ݚC ;Y募_}BafzlҐleT7~u/=}s㔌X{X޶_N*/E/|muц)QLX{pVw^Z{@Zb^)*Y6ƙKaBTD]n][y%.{@46661Q^;OZfVef#}uhK~yS/}]LȌgfm^}ͥl_wOCZ1j)TrS%l=z*cuNx-c~@Tcuo}Sc&uCX.nsxfIOmha1n?/c&5sJA&\4&:^W]Yc4CÃ?>_i?m,#?!LA4*J|1;Mw "4mqhB*y2~*?WFUlk=͡SiFwɄ4U5ogi1S3ue^i)oZh.Q49ψӉi!oC}wo>ٵW{H$r>f>]S/<5l( 6 &9 EгϞ#:j6z 8c >2ͷ ;OHl9toOu E>u_Ct\>XkbmXc֘}Sa0CuP=o+F$5ED=ufEm#?^ntrHx`t_Bמ犌z3s>"Zdb s%|/'⊶ͤ^WEHmx34,nŬ󌈈 l:hYs-c\%'7 u.Pykcp}\ R@ȉ{gD\Pw߃J(B! tcD[|6_,V9H"Mt*3~p|odnS9J-R(u;3n\K71=%?huAezCTՖM1 r [w#F3G2yy{O5pՉ%co[R,kgh|nYV\JgIq;tw[7WѯB)T!IMGn:9*ի߾yH\/0ϾPdTZm"h/ղ#\>Yf\Sg"mHd[gWekG|l\;^k4#Q:7Zk@x-f$DT&\.RAźJ<$G`G[kjv/hQ(͈ QyBJSseJ3sQozx ^mԄkmV!pҖfyf̙Yօbb⧌%s6?u!<==ûg+$};kBg},;wnǹșH=rlβgwT/G_g^ NZjQܳ]$}x ?0WXH0ϲ.+ֽx?m^_?@5g|ot1Xi#_4/%O 6ZL`7"&^r,DXYn[R.=ϟeEc1bbjBv^wF:(**i<wB)9w\-ӛn} `vxf~y?_і!=&X)rʯ+bD$ o$"'u(KjUJx}gkRe w:jS=|/[je WRP)tŻێױ:v[uybr9&^7'-;]{E?꽣' Z'hu+Uϓ\ ?w"?s6q|Lo0̛3\N䡌7fK?}$KH SP\ \zfoۙY!F!r^hrXQRc~eHDSG:גJ>k*S ɳFT;jH#N3?#k4ZUaA0;7_eYk{`Y6~imօb"dޭwnsiv#"Jrǫ;6ۿ3e#7}~4"CDΟxԢe~a==LkjlS]"ȄU;^wg9L[5>;+߾ L; qҨ\.q==' 2>'>i{skcuo^1iGZ"ڴPAViph#sVc?]<2i뺣IU*Qyc.K΍Gd.R͵=u)wDܴH';w3"Qxxb!0T[Hm) V 9.k=H/0&0clfo@1*/0$ڱK=/b?T^}xy5we%&뎎x>&X֬b0myƈyFUjgOlK J\`yt`DĨ}}J a\NQjegTSe˾X篼<"B~A.%ϝE x8\)}+NZRIISw[z?^Y6G.06^'55j#F Jw%uoñk&E"թ'sROdlvQzJ gܱo?/Oo\cF*k_rt K!1TY;0Ͼ^#B6`X'sFTUJ5L;Hf@dV`po%ѭwtB\@Wg^󈮹U\ʳ}[[/3hDoK`z@Ǻ\.Sc\Oߟ>"GQ{{xCdR VxM{ zϮ./P)dr+~,ܾFܑ"|Tn͡_Nr؝,ϯHvZB!0HGIF=6iwJ{_ϓֽxySJ5 [+۶I%.0%<*X kJ=KkOHKt+YZ]9}8s~F.%1#wR+JBjA4*Jv rڝ qAae[4!JLonrnJ+_Ѫm6~P)j UdBuʚZ24kt/b 蚩OKy?b%"alm Cꉿ}]lZd'\VĈEn,ۙ]D#Ӻ{W$ubMUV6A&]Q[t)A>lAJ&ε^Wm뺵LqUg.-׆eᏤӹXTpYZf1.6E,,PAe|zL>઀ .˕>&$h7u&ֆ'1_ZxM4CM[>rJ'ddE&+k{h=p.|߫ ^EjG\/z~?J \IENDB`RaySession-0.12.2/manual/en/images/patchbay_start.png000066400000000000000000001077031417052567600225620ustar00rootroot00000000000000PNG  IHDRHD pHYs+ IDATxwxEwVjuݖرwBI$$|G -;!GK!WHN/{lue?Nb;X? fvFvB!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B ѮB[v-ѮBwѮBut+nN:*t}vB]B!:"!؇ !Pg-!B蚀/B(p8pZU*qr[Q!-(\Rtqkc!vu@EM\\Era^a+V6gV7or0҂-X0vX0s%&$,\0'R:B/B( $-Ӧffe@qQ/kHw|JBn{zÎ;90`?niB- 0 rH4|0a!'LBB)2t6.SO=j|Xl2B`joat?e{7>>t:|˚5fpfrKnnO>Oiiǟ?h r?0g@ Øѣ;G.3 wrQxlٳ~[ghy>04?~xރϛW^^q̙5BVmvFɒgIJJRWc=pO>oM6+zxNSO>hvf?v{Ą޽ztv e; =ۧ7yՑ#GV\p|Iyylڼ20o@8!P_PWk[V^oRiY|&Nӻc9p8+Wz^ݲel!Cbqs4/v]!:l-@ 2麉6euו>R0aoT2CNgffLF?n]@>}rGe&K9u#fΘg5cG{:|IPpX;~ !Z/B]wȟqӦ& 7wlqQqmf;끹sx5pWӧw\\\YY٧}&4p ?7q 66Yʦ[YSvӧ?Y@ |MS&Ov\, vE7Biͷ>{ɗTJu;.\0tKeeeƈD[h4b824I(JRi]4B.(l<㩔Jep,Bu":TeU7˖ y-B!EE@0|P?C\ }7E%C?v8juL6h^w:wr:_} yܳ9ٗ(: 2 T"$a p8uuzXg釀B(L"#F⒒OCrƌeW40o gΜQ*y< lF~Ͽk#1FMx/˯Z!t\.}>-))`-SngZ\yϜ)++OOOk~9K>|h~~0|N|ϝ}믾¾uA!^'B=MsWo9ٓ'4f, 'D" %^|>_&9ƍ0b3' a,r fsݡr(r5!-v5cF?Y^_ߊy:``4^y}p%pfj0Eu%?._OˍF#!B(R"=VBEvB!Bhh4ѮBWQQ*t "B(j4MNW[KEvK}Á/B=%ЫzEWlhW!hrs&"K_P;[88,#'jTI7C8/B5f_>Kst? Fa_P;k|m_Q¼4Sډu/a>lE!BlE5">_x<>r<s<"p!BPk`CPIJL!H~|pDjW 6F_p8D"Hdb\$b|@ $0:!8 2L `&0@ KTF?>zK64?1={JRL Vٳgwu`) | 1 Z&SJrX&0L(c<ltnvyny^3vD,^( Oy0]!}R*{|m~NMm֍7ޘl ٳg)JJJRSL߿M~@ .uF]](#)rR+| :Z_o-Nq:DHnuiOpŽ<ԛo#+"m"B}=[y<ޮݻwQT\R__O(J"gdO?~wu@ ⫯Z/BYL4..)66Qp(lu*`viB[i!NLzeAXjzBaZCA->\.z}NC^^. @unon6/ræMF)h,+/?yԹsޛMX,+^ڢ(*!>>U CzXk6,h]4{=i)/غuysv;EQ˖}z,`HLL[n~f歩) +Wn݆M?L0\Mݎ!Ԏ.o|3+뺉%O}>{0 +VJ$fͺ?QRZ:. _ TDMll2Ms*F/ ⋯sss>^rB?_/;pRx睷=6x+<#&N|jٳ\,m֬c_Y /JIi=>:p#z'N&&$?n?=4O 9R%=b |#aQo %ҷ"ط(ꌌ<Ԕj~& Ä d.{\gѢǦN)!!5'/}~ϻ\pr^`  \.d27a!9;D"ammÇ h4Ç5G~.py޹>ߖm[499?^]RZVQQܹÆo ]4.xlA9ٟ~qzǟ̺uAsssΜ9Qo0FU"mNmmH=9o[BTD@,}ii٬v0 k[߃A& 2LpݺM[/~}pٿLgvmwsVXն~z<phNFrm6m2}N7OS\\i&v!Cn4X~`N7`)(l6.7'S@4M>{}~((8yDڻWvrzLMIU#{Q$0Lg.!qq)=E"1Bx|>_y<<p\B("bB(X 63 {))ɯܑ#ϯ: Ø&8 if@wLϬwo//!ѩrW)hls=Сiii3gL=j~رcUUUƍe lݶz'L處ջwcP_K\0u`@]^P@?و`z"v64L>_0NWY^~鬿rViD"DbH,?B8&hqc)&`gaa*% f|0 TWUTy@a,i̋ݳ2ry~}2J .wљ!{/uuzCEA@s%W8.0(7J+%F,;g;d|2v"E"mټyyysffso+y3fرNX\.?*V*H%Р@iN}0mNE N>}R%SUURQQd<_.W)q Z&Sq81avn:vv;e\߾nO~}{"6^,jjj"{ThNl0M/%PK:;v]ާPi6-1<`PT{cBP*NaY|\.WPv{y쫫V^a䏗~OQp`PgӳSd-)9rumaT%Չ118vh-6s]ūV)/LHgΞ-lq~R:rOQlcA㵽`6\4~~nJ@!T7~Uk5jZt|cF~hރ☘Ͽq`Τ1>Jko[ޒ $PDQTRRZjjq8%%g,6 ɱI (!@`X &j5^յ|/>(!nӧOei#*N6GN  -^==St.ё~QEş}yV{*(HLL|Ӎ)))@jÆZ弨Q22r|/+;U D$'$hR$9nuz}bWPԅ.l(O׭۸dkn)%S<EhxR>~R2-w="tZNm]Pgo+:4}E.Sp(N޽||K邏v33(*һIIb ^_U :޵2B~͟tb{䑅_k IDAT!Zf.<BéٸʚȚ{Z |[-߭cݤE 7ǟ# MOcOweWHIɌM`:]^_ݵZCOFTaԋPg t<@Z{_KlY>(gQ ;;`Nƨ7bmziVU嵵s+--U.ژ@ ѣT*%%gjkb<_JJJ`[JuNvqߎ<^#lo,o[vi 'LG 'hr\ 6^0L_H 8Ż"0 bv <C! "&\)$ Eq~_UUIuuq cDVydUפ9"T8J*o7Z|?t$Ά_tu"32rE"q /)9o2F=&FL**Ԕw›:-Ѯ}NPو`V_@|~aCs8dp8 dB˜vG#mMLLڊ$H$l:NGyyamm5tk\z?KUoG ?ff[o>vYBih}b ;pGQSO<^\\0pazz)/?o+{jh!wd" C,jnbB,=7~P]Ej41髱ߝ?wNQT[QQ;[YL$+\P^^%-:̚_VG .`AF?aM  ~$vc0&7W* v !EA)M [,a!֯pBYx1.Ow{P_6#r\aIJ>.wu%ݵFe62MszTqLUUIMM.;B㶡C(%K*,,n5{S]/W -{)JB V:uuz=Àl*/(+/o΋?\aa5&ddDWVT :==KK 6jR08px͋/ !='V`Vv݆0~+**޶}{wi:ٯ*)I@L;ii E<œ!M3š-Wݗ:u}) |;  x<aP]ԩҌ^BZÚA"gdp<^Vvn.!ԍ5Ʌu`>Mc_ |,=zdp$H>ɤ111Ǝ0t:7n\ZZDFQ&3>>(E%%%2 heZm.G! ߎC#gΜqÇ7~t*+å:; /z]EEm64r?/Bu94ry<s<.G<C4åiái(á9!NBQixB(,krVtB(RR+Z~U*P(l.FP#ʢp%'ƦPZmy8Bsi@ DP  EBx<.r !\_s 0@  2  ЏD{!8nI7ǻ0mV߳>WXXV^:0-֥u4MKJHH VLM|@[YY\_̾!u4MDH,bH#j:N|>|^y^@~ @88fτ$waÆ  =dߝX,:rhY[QQeXZQܘ1wݵ.| |#vW9_g^s/!,r9KKϚLNo(b1VU!B(rD.ɅBqL/p>8ntx<.s:B(e?.[[!>>;Q{3WXպwGD$g ÁodZd񵬫 :3P(ee窫\`奥Hdb kf_4͕RB,K$Ҙ! nj5;v;>Z[i\borvݞF6J%4MցdqFOHCӴe4Pf[iE |%^DPnBdQm[ ψZ0[].l/]e-*d2LJB.0L鬷mVR_ouDݺq~fǎ**11qժod_e R2tɒŋ߹s]{`Ȑ7<_%naw&***} \cǎSkf-9ӃGK; T* :s.z*XEE'{y9:--KP꒺YkS].o%rR'cblB͵Vf3NXz[49sn˖mRwq/ooci&Oa[.lÆM3f70iӦ-lJ?/RKύ9|4hС _ &fXFH]ɾ}f={g,i RD X,V8zMLL|o6   77g߿={=\/?y֍7GVVvc |բ6,Aש^B&K$BzmYYj4Y E@Pj+s5tɉjoGMT*|>X,I__o'#2"e>KN$IsKt:]^ހ[o l޼z}3OHۜO}or. _tUt`p4|aUee/-TƧph,L"XNPe2EQ՘Lz~ίuQ%uvDt2MVM&VQF2nݺFQ_a0 6t߾ClܸɼǎW^vٮo߬Y3}v%o| Wz]GNT`V.56t{*DHd4 եnwdx<~zz\ O7]j+kT~}jsĮI pJ4LOhK(J.W*U@аa7k fgoJ"x<)wzQ޽sGb* I4NxZ](f;uBjp_)&&jϞ4M_ȑ#zeUU5*^3 ~__} {\VjӿIi}#S471Q.uVV{WJrM&E6LA3~\.6n\bes{fe-\0-=-X0vX0s%&$,\0'R:rx<~llJ/+9aH FcT\΀{'/~n>TYYN> %O> |gy^TZ,K~d]r_zUrBforl6$nNUVZt.v csOٛ94v&'$$TAWUUl4ֶ<FpE&11ABZO|JBn{zÎ;90ƏiZP~ҸPBrDÇcr8a§JIۇN:Ӌbd2u#5jub||Ld&:NhZ͝|*x|hphi.C4phK4Eq.i؎0!B`GWi7y?#>aƋ2gdrTLƎfk|״t/F^i^7wؾf/;ZxXPGOV(bٙVPc4:%B/EP(D<xx|s8d ;\ mc OUBZNWYY9F?񫯾F <`6[nĵ߈]SQ/\Ԥ;m!Jbɒ :V,\llZgݢVVz!$!!5--á=wiY1܅Q/XP\TDUGeGR  Z-7֙.ɧsy޽r>_jjh_y}I^;d6}S8a<l޲%&F4zԨAMHHݫN+**ڹkQ&N!rٞ}?:r0 %voڼ{7 ]D"KR\.zz}e]]q33BD&%H$ |}14P]4\.r9nzl{;`B͛6ovU S80mVcrNݗp ?_Js7/b\U11v}yvtVk6׵PӣG/2ΰoCg8 )))5Ǐ=zlnZzfB[JMfy8!++OƎP{ ;:Xr%6}l&X\) jaLB\^\\R||@ "z}:]e]nFOZ|P"I$2T.bb/vN᰹\NgeBq?ۛѵc+oQo019Da XjCH( T*$)+%fl6Lz^)hf..>U_ok=ZɨW&7v/k=:#=|ѕ{-`bX@JJʤ&dI]WVVvHomR` ʤv:=d2!dqvz6ӧONvѣld)N9b3|~f:=vlQ{ϡC4 ": ) E,a`XWw`"ǗɔRR.WJ >_@ pf9vynm9sӨwpst7mD垢Ѯŵ(BQoӗB]i.cG^x EBsKi4lv^H f&$h!^kvԓOB>Yԩ.OR&Lhwa0JimÏwy#ML3p`9E[m3yv/_Oqqqeee~x/<6ld)6o?dOڵO&Jd`M7M]{ڳG!SeXR( #G4YoJ.n^[ϗH$FBqqr]`V[5Bőɔ ZJ͞T}>ѨZVf3w٩-9s|n!mz#oӎ]mT5`0 v@0 ^<=WG$J*U8uuUxJJʆc__ajr\^.m2`΅qqI|>ak @ W$ccxL nl0 jz .Ǯw6 ގ/SÆ  >{K;vEFMOϑTn)-=׺U-PkŐ\ m 0(11d\Ma^:9KEq ZV' Bᰅn3uo;<^ R(Z<og_n[lُ˖Nrybabї3 Ѯj=ztCѸn/JP%Dbx\zhԵ:HNPr5EQ tFhu> ajݢ7bjb-FKK3!DR:нTTBӴ E1 Rf3{Hͮ}xAcL& mVHHtC?f*7\V'Q0AA[Zzff4TZm _ȌMZjU,P{*UZG\bj9Bd2ZTĈ NgTg0l7AiVTD2^Z< |[7[?{55ZL8 ϲ?e2% z>6$''{gϞ޻RS_zYϾw.~bl[JJ{n/yDR[4UW |e2eBBj||2/`꒚ns+pO[[oVWv \ m۶ؑP*9ڗX,M jk >-R">>%..y<CTk4Ek9h22$PZqKxk]Be2гϾPSo{ I'Oa[. |555}䑇{lW_};w/ 8}̇V[}M7^%!Rw~b1Fv}hu샯-c\WYh4JJZEQw-`\&B)c d7[.TJZmlbJշONWXX\2{HII9{lm.)PPB^XvM|jj j~E!kbO-F},\Ϟ=+ب)HO8A*aBʪ8qL&aAZqqr{l|JRr|:]V[a4vkƵeطgffvNv0صkY~7\.w΃, $&&~oP~Ν=;=- ={fΘ~woܼ~T*^y䤤Ͽr~=Ν={%?בem-Ǎ6uʻߨ*URyXLC \IqqIg(?ٚlf7 :$TH *ݩx";Ά"'z6TAQ@i'(EZBO%=lH}gfyv g<W^y"##r+7˲! \qPp<!3EEKgovkJUXZnP/{}wl6o߹R”~}*rnii ^za;v:}F훑zVNLHX6nJ{7l$Jv-rԩ_xb@H1ժj󕉧dԬ N 7ʪ{Q$t:]bL(ee&S%6]q(>ЀM|O0rfgt萜TZZBP՚L0d XJ]ee={0-6pFGGs5{<^߯j++ =#w8deLImɢkm~b\T*cjJ+KYPYYf05A(7)+8`e^zϜ!8!#m6KL[ l޲%K׮)N}m8˯lj4NҲ=7t={x~s۶y'Nػw_>111/4?8A/Ш _wN{>Ҽ_)G &t b86lj? -b,7J=Œ%kkP|j jX> ^(+^رL7R z}ciII?ڶmҒҏ?~wZ7_-///,,{zcGg4VtO{쫥u,1bdn9BT%Ur*&F)+b1&fxCTi6-Vxw3V~mv@)hӽzjc=y˖ 9r|S;?/ ޷OX-ߕu8q :tEEeBڭ[ץ_/}ԛoi=\ZZʿ5j~ԩ5th4:BFj&$Hڊbp8FcX^)B%j;:xXMg6o|Fc6C,:Η_^Rl6WN)};lڴe׮=bl,Y+in~ J Eu竽ˁړ\3w3bvK$?^\\|iF bHt!K(T%0[\.GeejXfjomF <҉5jҲ S;vl\\\|>rEy} ++yqcիC):>|˄;5 wjyB /)0NKz*++++uǷU*$%z})z* #|M[h.) FkO#Jh }YUU:Gu:לݕuyŋ溓o}i֢֑#' !}N)uVkp:6f3&_R7 Y3g|1PFXwy8`@fV3!$kRٷO翴kDoV| /bΝkmf0L:[FbOOsKh!!`T7ɨD%t"ۭCɤo…-ZٷV|#@:a FZXXlي YN󲲊- (Ji 磁@wz.z=x\юbA$/??+IF ׮oJ3gh4~9>ӯoϟk9`Æ pmd17pK ڟVY[Ua.>>IBb4WV7ZmP( VkPju1B?0O.YG^2}78jpGj{饅-4LP j4q2N9\dr6QT  \,jI|)"/!Lg]Ϟ!|FRiքBxW/5lY!0CQQ@#ei4qR3˜z!0@(2P( B@ E"BH$bX$bH$jRzl6v:Nn96]4%z}RBj;< :zjkN%7Z$d++JұRBb-@ y].gz^v;nIJbc(Rd4JMpEp?a7.S/j5Ե_J)4,K)e)ܰ~/> |@2.##!Rjh@-^_j4p7!G|B!=zth4~+s>p=%!HccccjnbUUU:5B#OIiYiX7o;޷zq͞|\B&drv,_ yd\ *EJ _[!ҽ{+eYa,tZz !jbC-КJz}N!#H$ f0LV4J hWU5(\v=^1[y8?aL_C3fL/,,ھ}l6a~׿a4ߵ۷իۺu{vm֭eӦ-蘘ELJ.W(e Jp:6l6Y,&d7ȹsUm j- !T:z1(t SO?"C6dյ)=( cLEEɸՌK)~jZvZmVM?h3TYǹ'_iCӋK{~O?ω'$įX/=׍o7w|U|pŔҖ!4J"J "8t_zvaZ6ft+.^Qqb\ Xx,3/7nlFFz؛ݼȄ!-,ٗrfOδ)}nlIΟ/\v=w- {_I./m EB?nlNNΩS_,[R IDAT聎5k)~ܢ\[~'s˗\ֿ 9Z\R2f̘K,ǫT`@ 1bM6;_^>(?ڶ0"vBGK-^gvfG;@kiSa˲y{n{bTjA|B>K48e59BjztrK;˞x#R,t_v^bw2OGq%y,i:ήfR)JfJ$Rɷ߭,))7vgxt \.sy}Db#>wvw*%9`}[P]g? eeeأN}k+vಁ,U4SVP&f)W$ɹ=|_} :kZ $*:ެxkaE!P8y[Bn@O攥%{x0֝2LjJINwBa6&# Km=SBU}! !Bp)J.m{af͜y˨Q;vZfMM|BWe=B7݄r[82VTk^k34Ւ<OP 2ʝ:N:?c bH%gy_~?ˊoNve=|>A <BJ222!J*aVvaBHRbҮݻMVjwN}~NzzzyE`~`MnK^sMNNU[lFϭlX2f_B`:s씻JI鐟_PtN{sA2ӏ=]ppϔ))r4rYOl|z!1Q!٬:qrСuÏefrAdX1_d2QJCBf?jBZʷ+o/r[0Fh[ uKHBjmi:ɨ<7m@)J֭ۮs`0 eD zw$tܓ"Bjמ=fwܑ޻}r}˲˖}]:w:tHRb?:}Lۋj{e`:yTXZgnB[ ĉ1GOz_ޣP('tލ̬߭x<|~78_ `w/BVr߰aæMRS<#QJmv{iiY~A~___B!,fd䄻!8j[/B!&bz|#P(ѣ{bB\ZZZv !B06 R9~=R })3۶+D!FԬ06O<977wˊCOIaԨsO?++/0-ɜrKfT^y 4[3{\}<3+|MF!"4""&0*;&OZ [8(e8{`xm7.f߱ ׬]{wd8]p7! ?.V "#&qcsrrN: p|b?Y[~ۻOU/9|:ȑ3f/\bXV{<̕C]5[C!ZL0NoKPED & {tt2eRڙ9ŇaӦNue\?ERٳ+**0"j m W!M' ԣ{w]\\½yXIŽ?e[9|:+c)M\vv5+JTj6=W"JneIIɸc ?cƣ_^r;5[D!ZZ8iʝ3iRHKg7%$$Q SwxǚJl<2Kar<;;YJ6Ij[p8W_vcZ~7+**"B-tҜʂ&Ͼ_  nC?SyÄZw^80qm۝$S 6-F&u~\u9{)#5rmۃa[`= B {#a aaYJ)9cy` =}Z6)Kˊo*+. GuvPjd9'/_F|Zf@⟿}\4Yot#7*#cH6-..x6C3Q\-I; ˯yС~ԩCϞ=&N T"y/;J) iϕEABņ|jT;snoR^\KlZtC@.meG ^zKT>!@@ `bj6dqr;pС@}6RW+Fg߈oҲ BR߭:vvyU]؁k+wS`Zs^^QvXzuq?!+8l]wt}>N# s ʧn]gU1~5$Bɑs0ePNM5jKƗN%tDخ<}p㣺e$ur7%#'Fۨ}nFtwO~ Lu˼K3oѴuvh)Zoxuf/JN%.6b;I-̙S+%C~~A9R֣v3f̭ HO?zt•@bB=S __&B>.R8/D˥wG;jKXiFٗ[g?>Yr^sZsR>Ǘʪo]=y<FS>}qs'<>C:ht߸gEUQ,#)Ot»5:RZk-qTj9dIbsYRTZa/Oo-x6CeN6th~z8|cHjl2[,/Fc2(!!5k!DQjە B|R{s֨3FLH}uն=uXZzvo9zCY5O l{=Uf[`M+kkzg1l;uߌuԏ«}mݾ-S>Xfmq(UUU׌w([n#B<=ds\" !0 L !ȥzBBrJUuRRP"3* BH@^Tb dv*1CHwtưk~;&wL]t}5kWh¢m߹U5E! "7o\ WH ד! x\Y~t5_,9Qֽ.A|k2-RB!p.@!y wԤhPȌw@+ãZ,sWf z!:YjꑇG BA~)e<|$.A76~[N9b0  B ÄN=,qKM>W{  %b70[kr\^;Fw7ì".QsBrg?[?auާge%w،7.) <7Z~Ν5٦gϝ c޻wQ\\w߾ܼee˾y.;:$)1k֞>SHk.Yz}(\MB!zGj%=Jy|*Ti MZ+N{-wHZј&g!cǬqq0XGL/oo'ssnj=u}{B&NЭ{7ʲ3V|] Ba׀nQu7G{hըRe˛ ݓ<5:wkSnd\|r߰aæMRS<#QJmv{iiY~AxE!xU]65}^?9;MqߦIJlvNNvO'D!x&4g)܍.!B2pLn~~[("~!Bѱ(ELşBu+8UpPtڈ !jI݄V!oD{/8/B5~eͪm8Tw5BTnbxS/U+k)x|# ApO0"~\Kk-ۅe.{1Fei<{|\~_@(ٛٿ.=weg%RыXax/6ߜ)BmN*};(5 :'Yt?e)a'~tP(XCb$wzaզh$M}#+:a!Pp=!V}ό{Z]*Âǖ-KE~|b𸞻6ɂ9YM\\#hf& z)1 尹 C ²QB@M٩gG CXn^}ȥ:s9Kh4J\mh3aȳMmXR V}Jo])) j` F\6.tY|R7G(p7!P:a/!,z,-4zgЖޘ JN%.642Fd nomnB!.4Tyw !c{Θ;Ǘh9Ki%q(Em)46GwT!PDR:z8l|)Ӈ͜u+~/ɯT̘3aظ;7d8Ю#'o\VT[g8ܨӷ9{~;ٳʞ-'` DUh]/ߴ[]=u_bKvlɉLZI?a(ЁòRs@BcUhO9]qSt\ձ[ұ?r R-kB~o*QNdm--0Ow PQl*56sܔ7f]V/w>[ۗUza,&0l'WT;3 !?mƬ:`_k'טY/M*ɯ?c`,XBBvǽ$pa$gBJP0!6VXRpB#s#/sqgas sZ[N%.69dI2GY;^v㬕pC_ E#1s;};ܸ1wkSrGߝUV\|.0g+jܞ~!TL6>Q7O}#+&5k!Pc.F3 {͒0^g}_N.KK *@&ȕQ*;C0 =0\~zC3źDd/=o22rN3 yl_$FUSQSa8oN~ͭPFqm5~:ۥhS% -WFqyN.~[ B[]!r:Jl֗VZzB YrzjܗoqÐZZ=meb(f_Z\sT;sno^\zSglZyZLxp>-qGDL@ `bj6do/\?tsPjd~_ass7RW֏BE`Wyڈ V-~U !reO *G_>r;䵥},!}772W^aZ>ㅇ|_NחVK"P}r{nOܷW/SJmWRr/!L㙷-ȮE,[:2ISg .tZeяO(N.۩}۷|7ؤKT*nO%rߋgϕGfjx%j]̩x+[U@C;7&o;999-M|S;=#;/U=\ >ѳ7!fW)y,~hӏ:ynG$ZL}m#ø3kCZ>6W=ux; VDخ<}pڬ[e$ur7%#'Fۨ}nFvwO~ v6yӗ0fޢim;f`Sۗ߀KSzW[B(JJBKhaj,VWC)^,mKDXֺ`4Z,k4jjs_zH"Zf[9@&(mf᩻yƦގge.KSFLo*RT=˾!rwνo eXJud_oK<;d u^~)Ҥ/?PV}}zxɣ)6틍S̘;IA?=3&.b/e)1L!}|򇔥ޭQZoE!FO⺲iu;+` V#ycn v1zFu1jsj㯪ኲXf֖To^Nͻn(,7g=cĄ+o:pw\z=;ԷuJlnMmsOVؿt|[\]k=]ӓ<}c۩G!"CG{ύmI=n ؎UgFEIDAT .Z5+`"r+s^K&x$saNq%! \xI)#` n_B 4t@Y0H$"lDP$pjY'B!>ɒm@sS/ ؎U{9MeEor.!@.r3LH,0˾-'.l R_veh sNuKPT7^Qbr\&]jPȰ]C @CO?p #B'99{Q Zylª1uuae70|+_MѯH,ԗTyB jn8S ѾM0ȤKT*}vXݥF{i٭yɝ/6fy!B,3"T:pF#צtk1گVʆV~K.]eU UtI ;wBEʬ}=^J652K\Co}4wu8Wy8!P+ xߞs+o |M{)s,~٦p7!jJ23}FP6mV|M.M wZN;uC!e 7[uRVB)**Hulں{g<6AenF!t}ξaMED>!̍Л"HA!AVƊ Wt`*st晍!B ) < MMJؐ<-0{ia /&N᰹mfgp+!@)YWVެvHy\!$.Iv,&{hy7B!nTh$N,=:l~/.so}ר.-0*ceN?,B=sX\"_kbo?}+k"fٿtR޷R#9ۡsœES|O _<ڽ,FrGV-B!DNm!Z^>v{RZkgƈGǽgv.QacϖE?>1x\]j.R#YC9'KAF;L@FRZc67aH!!CX;J(htru:;l{h!aͫTR#}.ecPFQjEeȳMmXR V}Jo]M((2, my`B!ZVa 9TbBBl^|a)Q,|\_f6ы;]>M/?A~;|6Qs[EIuRدx`ǙҦ?B-jS~g؞U_\tOxHʗ) f~1O6:~[{/vۣs?3~ʣ#[vj|ۛj2rEԩ#YR撿W-mRia+C?%g۽JiB2Z9\6xr fN?Woohwol?8B&ך/ciZ|YWXl. RǗS-|֟Y;j8(zqk./ڽ9FW(P XV@=1>5UڴV?yhϹ-k/ontwg_ϕg0;7S6%^})KK6?y͡=[Nwoޛ ]%L ~x|{@N>c$w;:V$~C;/yw_FohZ!i3'}C1wˏ/!BOZs7J)^ٮ2}Iڭ.XJUľ9sCCΎǃ pyGs[RQRrlQsnO߲pyٜu`ǙS5F?=.[@(QD%6ڡ6=u_d){l-3UW `tʿ nua N?{.]!B„׋AJ->v*Q2GY;! ]^2!!D#% qXU^|koHC(6o^)= 76: ! ǃޔqs?S|7iwu0Ck$5ƲgX\o !$d.>$*!@~+ Lhcis3PHėTY)5peƬO~[k\`!B|1ah\Zheb8spm#nu\a\"WFY 0DBrs{;+fh9'u*~3Gϗ<./C D1ÐNܼ wBUS{|[dV(m5gv)nICis/@8y`mb`ȭO=[F˛u /FV;(ۥwӥ);o ^BU uhhW"\NHR4ůz4Z޳Bʨ>,U6)]?}<׋G>>Q՛;z/0o-K>yy/K%R@(xO=7x'|d)6+)9ˊnv[dWD\w?⤩3G}.2ZeяO(N.۩оa;enߒ7̊b.Q󫸭V?b}/9V?Wٛ֫OWu1_lyB!ZJrrrN\sI٩ZɕrU405nQFEH+m>1' ә)^,mKDXֺ`4Z,k4jjs_zH"Zf[9@&(mfZSz!BeDNoy4F]Niu_Y0ks/wVW}UkEYj,3_wB!F @;賻̾-) snՕ6B!Ԓ|iN K;g7a pDxB!tc{ oWB]EJr-dEEEal B!Pov$cE!:JINwPCh!B|ݛY:("`E!7*,{?aa !B-K(!B7p|Y B!Z ݀ZX,j44*i5qR3B/\+Eh7!B>f-[ub!D @db!D @dbIX#͛*Z荈x/,,K-aH#uwGi] gG%uA9U"p;M(B QVVJy#@db!D @d b''NBӵss܊*Խ[>WZF)DO Auox^a>ڊeY" 4(TPPNBx8'^x~ȒE_Ι"r|dR@pUU}zGNx7:s0E.f[˲**??loR\^PPPfF1Le>`Y5tT0LIIIoIIMֵk\\'+ |#:F(H7W' IƗ\t:Z8d&"3zԞ-l˦G7'"??۶>>5ܰnml̎]|D[_{TfsC VUx2쮸}fg[}5Ğ;rhstZ eee ? qFzB{<~⤫K&Mԯ/T^y;X/9--ݐghڤ؜Ѿ}{[KW\uqvW/ --ǧ7~H%>3w}Ml[m۶>-\.Lg:NT"׷o8*Bj~X%"+WW_b媩oMQDwkS 򜕈lX,D(֭#]a唛)5mbddfVffFf :7]ruՏ??a_SO:ݴI>ڤ/\d#:_ۧkPj>bXh-%o:]rr%_/" 8NKMK9)9?0qٳ}ZRV{ncnj1\|y֨}~b쮸 v-''|kP{ro}i! d2aV|BB~}5j(|lذaJLlڤI݅)rLf0qF:77ӳ{ghqz !>rd##MTNFqDFrdRkWKwffִoΌӦQQQѨck O?^byff^߼e#;e˶aÆL*Yyyy**a.+ScGt ,YUWySO[NNNZƔo2~jD"qss3Lw"øZ,aB*JP[?mڷkw;JRt:$-eVVp /y Lf"C A =}5kgbGWkڶt@4 1ڊah@dw#vqq~^^?M.Cwbc۷?vNjxxxyz=Ҽ .degժ;!D @db!D @d{cxe'4טL;^;W ⠖AYw WPVIO#;4֨🕕! A 21"C A ]qۯG Pxad1 C9`@@]'.C󜐒oenax*]#"v=Ff˗,oذᣭbvԺt~hL3G98 &!p?TrKP@I@s|)*2jD,QkX'BRZJ-Skd*MA~Q^.7-G3;{j=]]=]*eNg銌DThdU3TF10ƿ8t4n?[PQ!=۵o NW>==}#˲J'G W2J%٦(;BeyvXJDGY'Yǽ}?n >~D5 +ˈcoLy_Zao&zj*(xi䈩oMy]q͚5suux2 JR!swڧwzj 5-a#G*+X~ <ϻ8џ΍5Zںy۶T #fglgX,~* kY|N{n%bvIjTtYl&*(m'J=V@]+S :tرAh(7W7Ow霖n34m\lNOh߾DeVSA%>ڤwgyfg쮌L":|?so[qG~Y oެ{bNKD,zyyj^#kQQ_|Y~zS:<./v6Jo:u* _'R=h9ô?z,;Gy׋?Uu b!w|}|;gԷm#9*HrIIIYw鑟o2'FNޫוWt\Z2.IIMpz(%]\*Vvf3U!EEE+L}dť>K?` \ y…;tԴ \Oysת75a4;g+!SulF'7.s?c,D )H$!a'v2qm⋛j55h௿ҥKF#˲񼔧G욾Wnވa6?P1 CvCD dX$O<۴iTŋmڴqrr*..NMMtNNNN@-[DRV+~f1,  5Nk-L'|Vjs eYDb.8"8 \vv77f'o]x)@D^^^;P,cvޫE'xj;OfZnӦM.]6oӬY'O*-[_ E[#QQQhƗ#z\Dw!*3vT0/0PחC1\Yp쮬o[dn?} gMݺĿXԺY Ha/ʲ_1b"*-WrLD"_B%%%~ C=nEZ Dҝb?3o;Aj5;`pww͜xK5kǏ1rTFf&t7v̨1cSRRZh\INkC{8JGlqXqȑ*jy|:32~O:m`8uthXMр~}vD?Ҽ#6neL]`0xzz;V+//o_N:eMef,a7j(ܚ,ˮ}~+kFy̐Ω$cV 1RK4RVHjD5RF[t)ٹԜIttrUsٹ\cN)X" jRoDh>`ߞ~^X?LZ0ͼyl|k}&FX,:nsoL iW[2yDgȉ)w6HO/׀HMWtfsF G爈a0Z]6'Nlnpppsqssʄ\.T*uv WSTJ2W-^Yesss+$H\]\暺h1<9c[,TgZu ubX|YXXhabTP`UUָrWM IDAT=՚`gj.us^*#.19:"E9IN/C A 21"C A 21pAñ,ԲZ#pMIzZlyՌ4;/ ((())ch4 RAqb!D @db!D Ãe~wSr'.}#G ~{0Nr].w~Dо@pu"#O<5wV(w٬lao1rKIIM5KJ:;Ͳ=!%NNNg&"Q(EEEeU*lX,hL&Su/B9rdDĐ#F$'ߺhR&*Jq\Zm/z#41rOB_6Iֵmzmccvشa]̈́?r-{|c(X˲ qcnjR Ì;o0Qhh}w;~SfϞ ->޽훪 ]q}/ޚmzv8kϛ˲,}ɼ{?] )J+qVJLR޾G)??<пߘ1cիGDRtO<؎Xq+>>>Q۷ k׭ lذA```;~i&^^^gHH(}ªxRhDJOKh4~u9r8&&A!Z͛5|bj ofhX,ǽ>i;.'|rssz}~_t)Ghƍ6UY=<(DQ/tqvy~ 6mڣGw,ww7\.j99VcYviUͽtb%'O2l= "ڵ[TdR{<˲WW86b𠴴].]ӷo_n=AG<1r e/߼y_-e%?Yc4Y%lYǽLJDf=ߛP(ޛ9+;;}X?LZaxL믿F>ڹ3ի7LN>x@ՍNLV=ALh׶͉'*\J0FE2L8TfVɤz}^޶z"z}[~u)om[^76.vglLuk*(ebǎ] O=ݥhւR}Q]Nٳgf.MNN***nؠdD"u?~̼s)wKs4P(_Cn]_zK/?Wu[-3 ݳgȑ(>>aܸ1Z"J#@LFD{Ff˕WoLㄦwUlءCDTRRb6}5jԡÓDh""]ݭ>lXfMGcǎ.Q(r~7_~z){͝3gQݺu=zPj'Oj콞βZ.3aƍ1j#ߘS'n#֬Y7mž7~kg$ADOwoO/6슍߉rDxߤi;ݷo ۻo0}W\|ppЍ_e֝N9W^WT:}ǎسwߎG}T>lCm:yȦM-aE@@6lXUq*,,9}BjJJJhul⒗g6ʋ/E s\@D|}S;cvDe27~b*emg+7~rՏr|Hk׮nzۣYtyƍ ev 6z #"|tY9u5Rj>~`}oq%''۷"?[mQgQibҥDd2֮]Sa޽{]FD^ u.{9ίXpΦM-KHHbqFdĀ,\PGk"4hCHPZ,({J饷 ɶZe*}}|m|*/\vmͧOX,U)]h]Xiw$Ӟ}PZ, ~NJ:sW὏OFz,##Ӄ^?a¶mQO3{]xG\222_>F6v!C""g0uNDVݶXV+N{Ni^>rt9>>>>m޽ۣ?^a [Ve/[gh40V\F%:{t}g L~=P=lAlZSS='{s3OڶuA͛O>A8Iॗ=jwС#GaیۯܤiӮ]Uc7oܑd2ِ!Cׯ_v#H*<6j11ѣFN?`+9sF*6hЀL&ӡCnnDd0=<xҭ~ J<\XXcׯi?ӶmQAR͛;799[~`A,nذM6Dq܌Ӿr#OnzŖ,^G'>_XPk V#ð|̙ѹs;w.a7 niֲuڶ9qDes D|`o׻=jVIR{(˲nnn:P{~~~gz*$Ɍuuuevl63@-x[   ^_;^gX'-4o:Ng),,rZWQ3>1A_xNꚜuuu5!,FtP8b!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D @db!D 8 v/X:]9slvZ#pVSjApǝ>娿?x`h@db!D @db!De٠-{oONJy#e˖ׯ_HK#p|8&N ti)^ @db!D @db96;u )}v]}% vuu5rhCW!H$qRrԴ5k&J [prrbMh4 ۲JRt%VRzxP&J;ojffe q!/O<䫯cvQNBrOk3fFѬ_n_Q۴iэ7.&:zl-TXZ I# ;//ˋ㸐Ǝ5flJJJ-+I$liߞ6mggwPK-a#GKΜ=3z(]]]?<(''?.>Mn޼)a%{Gmz};`k6+mW1//(,44fglJJ ?CaBqJj}`0ǟjղǟ.^TE6lH.X,V5''rss5MnnP\XTɼyL#V322x{?1##Gxm^bx{ےA7`#zFT: S: 6gvVu խ:V&<4jHRIDD+.>Wܸqgyz٥1|ذf͚Vk˗/ݸq#22RVo߾...UPzGܣG&MtqqSޚh>`ߞ~^HL|rRؽ C"C A 21" 6L^^5W~_|%%%jոIlAoJJ7yO:稓 0F 21"C A 21"Y R5dJJJy~ j};;t5 X6M>\]?d pܺ$R0Fq\vW܍񯾲`;c~F)((8~T*eLS*jOTT撒2,d2-899VDz줉'OϯAACmx~@Y3)OOOZÊ~5jܹn2<9)yiŽßz*ev9)ۢ.Zq\۶m>5S*j?s듅G>š2/ \\^@ZZPrP"edfF|.Dt cyOMMqubl]uEmN8Q*بU*'Jӕ4(OR)3/RXXh6Uw20nnz}^b'''\W3gC-1 |1w.l A1ba {;rؽp1<0\1 M A 21"C A 21"C A 21"ĆAܲe~}t֭a[ uO?qDJr1eGz!^^^w 5%vܿߟ~\٨QCT*'OOj-2šwSht,s|{ai>+{=A Pr?bӯjjIRb0Z/B()))0Zm20 hL&Sb\nZVk-4lp萈u7ئ,Rw);;{q5Rde%lZhyT*lj*$|U,;ibɓ&Y-***S,JryrDb{7iI, YtC9'"mm!;oNBݻu=jL)L5W_ߺmٿwwx0azDk</$2oyɭU'!>jۖMDM7q;ZR"̚ޞ_6߿wK??G ρoܸѦ bDG 3z{owܷ'a/lm<us|\O@@?ܾm˞7ߘ, 8;k}];Ojqqq/S7oژ+|96雯--jggU+~Z؝>JrvdBgga3oq;cc7[GD?|,fGTQBlߎJwٷgwLM /Z~O<]x9d8==}=˾滥ve# ^9b[S^8:߀'wdXxV&rms>xoUT_-Y$W(ިyso&NbYf}0kSߟ5i3.]DDk~i+Vrqv^0ɩGh/_ѣΛ?x̗_yrt:<~z),,|/o狊*Bryq+WK/?BƈyoVȸؘڦoٲU56Pz}Z>>ѩS|N!fJ^W\\-T۷ Y?0BCcvƦ<Z..ÇVsss+{O@@@fVL6b?FnV{ ɤWo{^ZVjdigΘ>o'nܸyRP %|"jJ/_>s֬3b#/\oZHT%%ʯwҲr~G&l6k )x]L& ?_Q{xDJ9maarڮ-..&J˻~`^9oPw7ǏzQ q555S.`إH,--y%<^ wq@MBC32߸Ѕ꧕3z#Fj\\/q\ck+7o@ غm?,Yn휹@&W=|R񴕥%S_OXoۺejGL1N'V&&"N |!`2\ /ҁ¢BzѳgԴŁVY#Bᡰ99/i<㗚޻W۶Ͽ{r#--,<#ZZZ(xh,J!&۶mK"8HaթSǜ+T*uk{WWgg瘙hF\|7QB\\.'H$bs8+!j,,,Vr1@RG{^?zx@"OMPvyyϟ78d2srƍC$=J̎:xxO ú?nZ~C݉Wml ӧ}y=FJJf,W&NO\1+_2|=mE8SSӧ)O=BY[Yڱmauu5LcY2g\y"?&:Z,}r윜}{wӨ4+t󏡡dq t4#33ӧOD[m'v*rs>|g ;v޹s{eEB˃,XL&[jͦCǎM"222FaIҍFN"=zvzقC_6=5`Xl߾?WSS?URRde!KvTŁ7nJMM5km߶?x<޵dQ`?X,.&Z( ?~/ںaB,D" ¦LRMMMԛ25oh!l3ں:5bbG!!_3~iL F +d2e2@"l3Dt:xJ\PQQР@:b***ԗ󊒩THԤKuL<+Aūn]BKʦWe$I.WM5YD񏁢y2L u;v|@ h|3?vk h d^E ˛wFyZׄ zgt8S'># &LMY?޲u[H|xmѶ;vbD"!>@-I" 1Bb3 !gBH0#a F!=kdq* !J\0ے xEE-T>BOVֶ:H](h4U1Bb3 !gBH0#a F!=@BzbG^lU&NV-jA[+{{P]۶m ,E ܳgw)kǎҘ^^^t:Knݺ=wxLB7nLK8}LKԅtq@B!9nQKcნ p|#Z:ccデV\,u>{-̛1T~Xa-e0Vau|WsfnT+mw믿׫hD"1!611H$K644Wƻ2kKظh3Ba0*yh4B%=?ܼqs֬ٗ.^] B1264ɬQL644*Ǯ\*.JHyh9`bjZ--400Mu TUU@S[9k M322SQܹQKB\vxz99eci^^^)qqW]_AAlU`vN~gիפg()Tj#Y9 1:t t9=#{#Fl''ظ׮ YJPtϬ윸KQ߼ytu~Çoݶm]>oɓ'=wfMb3fee ;L+ؐ)z*.>aҤɗ/''%]իSnܼ5~xEc%^NNut8ܹs::\x)%5-3+;.'ɯx LMKRo7r֯`Kq9W iW]۴iJfq;\]]5֥^!A]NN6l~il뎭y6*`(00+;'&66+;KۈܹȨĤ)".Z4f?i..:E-AρX*޺uK/[n "JNܻQG fggill $iQ744|7gN^^ޚի8W^D"ٹc]ݼusY`iig]véoDmr{߼y=0idزuҐ%~oDtkD!Svo1}y{:eIر.s܁%B^Lnoo?x댙3OyjRF=<WXX˯~:hEB.#aÆx{)>.nDEPp%rh䗨 ;4p+-[. ;. ݜ7jhה[n޼Lب(!C\]7n ]l8}d2y))ݧ7yΝ.^19#=]G%8;;K'pswOKM}y}Tj޽2H XZZ2L@`emO&ziioZÇm۶xV0xӧOccbryuu9ωBɓ'YYY">>u~oݺU__iTpM;;;Ep?z!Cn>oG Q\T{E ϝJׯ_W0 "g'n>loo߮]{}{.jkkcX[XY[IҨÇ{FՄԔ"S'O@IIyyaJeuyĮե>]] +N:;9}_.ݙ1cg.'%D*ڊ*+uwpXыSN.# hk֮uuuϟ? W/g2d "G]7/*2\;w^~F}30/n/YYYO\sl^+atkS^^x,ɄB!X"P~DVRc E*Ca]9W%H%kH@YXQKmmH$20ԗN߽{u6T*u6EEJ. xڵ""Ο:}fڵϟ?{RD,+Hʫg}7K}H---͗/_AoG 'Ι3u6 lm- t䯿$kDwE ~?(++1cݹ}z=BXٯ߄ ==܉!C܈mll'N𦕮^6=#<<@(*V:[jxʪHptSE~4͉5@ P9Öd2ZQc `nj@JFM6ǏN755 ?~|ilٺm47n{'O<{uСϟoJgi//ۉ'O/Gߴ.! 6_v޽;AE}vekkb|ryΝ}||I$ L&`gMu { 7777wwqvv֌e2ٟҨT㹱q]]q{ذa,֫MEEEZZ+_xDGWVT2̌ GGgggP(5*e$w~'NK[nĉG8-]ٔS &:ejjj ӗXɒHI'W>sSߨouڴ/^xiȒ.Ŀŋ8+GaSSロbt:F;~e?E#FݧOt}rZ/ -7~=Ke@ԇ455sNxgmmc``_9ub݆#G?wؘ)Ur 2^CG˗/_~;iPcF7=mEDP="#b4Nߒ%۶m0aL&嗣_|[5R'uճǵk״U''dW@X$IӯplJT*f&G,lI"8P(Tl5kt8NEEE㣭n] BQ6`XjcEPX,oJ-b[7o4((--%i 1zC[YC"\neeƓS{8H$z?A<;A;KDuuu07μ)K$R d2YYY2ryyyJtpt$gپӝJUnJȨ+))6VRM"7=J9TWW]V)%VYPE;rL%*=1}|>C'>&?M5tt ko ML*+\momȻӨ Cކ}t#֨x J (݊.!}>u!@Bz!ڶ GV$-逸N>|ElB迫JTA RX.?mBc{!gBH0#a F!=@BzX,[7~{!(YXZTUzZnnc׮;`IDATrB迨Jk Z"g1Bb3 !gBH0#a F!=@Bz! 1BYsܡn껽4XHf!>[}"l͝;Q/Vsl4'B}:akfYS0TJw{!iQnK<,q~H*j]l\&/kjjaADUwSI_pAYYU໻yz/ YA[:B z8Y''kX;ϟ;7hqI߮_.>6}6iЯLzz˻%4cNƏS{p9OO}(gЖtŋ~q?nڲz ###K Dd6e'L&k T*Up2<\cqcǴkN%XGt:Pw d722P(: ࡰ@۶mǍP}d^ eL&SN700P@"LMMTڠmLI[zA"X˧h C=]㼨L(r U662hmQ(+t[[kks4h`rR_@#/Lb|7#G(=vh1?ugϜ?g; gLuo66 #-,,N?RQT@7!Kcc<`1.^87lW*677?|`tŨK"/r9qlԥi)]~K#S.To{)'X6>6o萚DPV\1{߻&>6/G_Kg( 100X|YK9@&'ujۥKx㠰j ?a{v<i``aqq1Q{vd^O<)5rLtTfzj6m4#Qwsf<qTSkA^1*׮"bĹVZ)[[[G]0eؘI 633#^8/J gN&'ߏhY3rH$KI W;гgK~TrR¾=^NL8!CM迢yS>,3݄㆏YQYr7m ];Gݽw/>!aW.]n] 4poƌPVV6q„M6zl6˛D"mۺЍfΞs5'ISx%%ض}w;8O+((ҥKء~?GWR2cl-UJp۷m]rUfV١L?o')Khei~GU| ?NP' ::>ۧϭ[R)JR?}㦥KF|8vSxף1qeee3gLoݦWCkjjz; Y[[Kɯ7dNWeT*uт-[,X.011H$[7oB7v2yҌY5caaJ3frkcb:udff *kz!yyyI$p8t:} ayQ>}zwh}}=ͮ#Ai{ ,[r=ɓظxEu\aw ?q"D"\09%y]ЇZ[O6n ]!T\] 4mӦ-ӧ2ZT%"oGhE\TT|mPx]HHuPrAUUUYY>>އ޹k7ښy ,IHH$lȶ|)S q555S.`إH,--Kx.y<K<Ҳ=+ӧݺusu}Ca7llE@"P)%"WpT$A.((T<67 ؾx1p*qǥZ^!A x5ԥefff EۼO˗/Ϝ5kƌ /@"h,{Ď~ܴyq6۶w+;wK$by>(P ͍ґΙ;O%=22j9W0s@?|pll@.r+KK'5-=5-w^۷my_Bc \.WnmmUV^Rz1h=nii^N+,-,-:&V*@Bbpaڵ%rmVG v>DUv?'x۹8']NVlooO{mR)!==]vg&9f脤$%6+bBٕ׼<9S\/!QcB'L8NЯ|dݻo@Ѿfq!!!qtSSR6HZzЯ|FFFQHS^6f( 'L YۼO(!@*)(bxgee+h۵k 2,%5`0D"\.'D GhEܨ%K/ YSdظ)'}3Օ[iڵXlll|?XX\~ow,-)Y"?__=y'D"mەw*yР9gxfff׮^#UJX$dͪ2il{ı1f!LD3wB8h+vV,_- MLL?rظN;9}Jlhh0ugϞkGm'$=**bvV-[ 2,.&J>}l}P^^q^'[׮;wnP|~y*GEnj3z%,SӸVdwz*--eٻv𤋮;w~=#dJ-w|ϣ sڵk:2m[sے؟ͺ#HlD"IPlX,n tzEEB;T*DyKWNgXJ /Vd2"o͘bjjj};,SF{mhhHRL&ʞJ/t`0&&& DF"Hr*{zut}400 *&L&jbtϣ|E3H$DMyc{NNNnѝV򮾥Sg[}gAA.k*RiSF{WDR%hn0MlnE&_LM̺:mCCMGBھ9M#DRA[{'T&=;^]]<\=>y涚3vy9GƟ^C!%IzޞrJ5īl29P(]NNιV|x~ÉS[}PH꿩.x? JƆЇ#Bb3 !gBH0#a F!=@Bz!@,h4B!bq_jH$gun~B)ĭjtk+rѣ B!vp! 1Bb3 !gBH0#a F!=k[%!dR7ϘLq>xHuN }Һ9||Z_WRpkO1QxL&r0#Pj$ c F!@ЧzGMa !gBH5>qr9nOƇW!g"F蓦mvm\qi \#4ޣG=n􀀀[GہL&mذaNNN %`07Ņb֭[[W7sƍ%Ke~vСCO<)۷kٳKnnW.,,|y+K#FY7oE b>mou_4iRffիTAD"1F'FFFUUU/9:8l޼yڵQD F+}AKRT|T*NV=X;h+Ma F/V'ɔD"*gnD"={,<<ŋDΣG$&%>}zɓ.[ߎ~ҤI( \iӦ޽{dgg/[\*jQQǍR -*,,77˗@yyyrrʕ+`@+VRd eǎ eŊC\]kkk W,_v#{!]b~!C֮YӮm[ED"ٻo77O۷oO6 Jdnj3jhO[6oV)[nW^Xu=}|} wwwmUH${{{6>յp?o ]j7ŋǍORݼyU<֬YcccӫW/}=}|Fyݷ` }"ܱƑHӧO߿ʊH? ڴiSRRbժv|}}333וW:v6mL@ Xuaaarr2TVV޿uڪ&rLcߺ5 80///''^|Dtvv.,*رc}}=O>EEEfffNhll,7^k|qk!e{]fڝv^jΝƏԩUTj~~aaa;v kׯI'|~]EYYD"P(jJx(hII nEUUU/_6mYqq.ݻ؇y B&n CaaN$˗-:x74K.fgg3YYYssswޭ؛7ozyz8qB%LjL0p8&&&ٳg믿ؾ?,,Lp[}Қͽz444 d2ccJ`2Æ Sd6a2g͜M\0bĈv7 ;t|ra2X>kj\vws#32:vI<1ukv1OOn]uMJ8S_ߢQQd>a_8wzg""Zgݍة.p\77Q]hkL<<VbH}]:we}>M~dw-\`&akװ_+^ݻ&yd2u:q.[RRbi d2JK,|FXZa@Rt:a^/rrt>w[-Nl+O///''w9q ǾFucXڵk)?xy:N;qTn]I7@yG,|;9/x@|\w\&sڽ tzС}ob.{/E'N8#E u֠qsj13|MFS hrʰ 1`0TpP(^T-ڗSCx\.˕ٲUxW"s2"(++jFcw |X e@ 4R.@ 1@87Fs;xKo Nt[p$@E G\ojh&zD, |YM$j٢@ [JK5)O,x-F=<=SR_DBa/ HA@  r`#F 1@8 G@ 9bp0՚q<44kB$''r\6͓t xšIrRRm mh!/@ k@1bp0#A@  r`#F 1x v[M0f ;TP#`a"}ƭXEmF@ep/1x!.4&ciISbДtǧ h<>\'`py 嗖E\L"psvrwqrsfq%reIHYR /W@&ӰrK 1۵#rX M3u $/%Fڤ)1Ҙh4.Fcc:th N`%RZ-W*^gp0\2F}J&_jD`<`7ŏ=x#/PirKg0`0ajAnHx&LL/#kiX# 026mf"G@ ^ftB[&ұV|D勄:+=%lF 0~Oevngk7jܸyWvmF$v)G֭Lf ?~qQQ[6 _5l۵ k֬OY7jd~ݻlz⡜C1q p8< pp ZVV;p*@M=ZJ8kFğײeACfff)1 6=gj| 0l1 LII-(, |8e5,Nᯡ߭NIIp*dnXɩ]NU}Eӑlj=_ >a? ˅]Gܙӓ&~m*V5....]X x8rtl"8r.qDl4-Y|߯\dΞ=iN7i׿^LsN>k0֭7|ɨGڷob#GƱc>q ] Ê˾Eد c26ozugb7w[o[+)irؑCG{C'|+V~>Et:S֬^nd 7`L&6>sƵÆN閷G5p"hْ_Ot۶l~aNN.HH?`aC'OF7heEAퟄ5F**i...`MaxL^눘Fݸq~9cũ .Q{xxPǎt&?LNNN~n߾d2D"r_z޿~ׄxS|> )LTbT*=<+z[gϝy~s0 KIIm"gb3g nMi5ڷStZ]^,<< d9G8+7e})?A~AP_9ADTnڼYۉRLȈhݺUz@R@ǎ/fȶ`cgΞ7袢g2=ݩS&rya&d"fl"srsƌo}խ4hH0᫯L#FV?~}~~~jqOOOootB̊־TDc0fSHkI]qGԓ".V q|@~/|H''t_GpȐj&G9ӖD"j˵Эk+7V|`1BPܹ{wάO(ŋ-[xAzNcn2ȺHiQ6-rjpPEIo Z]M xXGBkB“38T*n>&nj`Ы  }fNV9Βeϝ;}ԉRW~Gqĉm""[M֬9wVyVF3 Aڽgw 'L\U6uISN9c)|Z:'ɹwı׮/vED er rr4aX8h4uad`E}9y㈔c6fP b0 M` 7>GoW<""U֊aBPVSK ,K [L{\]]K!X,A԰r4`*a2ŕjnM0 suu1 dh啈Dj,D G~^|]p6EF^<~>>F1'))Syy<cǎ۷?t萇G ܹfuvǏkDϬX GUCΚh"EݼP `Ep0f\n0""{oc&(**zkjVuBxu&Zm1𯉧M.zMe 567}001bth,(.Cj<3'' Hf rTun/@zW,br-{B<}|A?m|Xg3\NъJիWL\./..rEEE2,%%0 _ @VM/LjߗYQK0a# V?YJyyyq #F o;䰔ZYWG^_MR1s [q^=RiP:[OʺM=1Ye6ϴ1 3<}nfM G@ v0 ?9& YI8g#F 1a24z=YgxX>-@ èq㝝I5h4ˎ'O%$F`jXQ)/UHή8d0-c#T,qƬ,&Ņ9*UIT Yut`8F@#^q{tt7/]S2F 2/^С;lӦ  K1MYQ ͇î Ld0f|6o0䖔a{II AAZ=p@^lS`gD\GEBafM<^~~^Owm[7'bTzضuڵ<|ؾ][ÇTXjnULtt\\i3*`8gէ5RI  jH{5UTTD`奥cfb1`L *e0JL {š1 ?ncG><8**rįgΘFJi^^^ցoojvwwr{PjO-.VWv!|d*T( )/ j FSPP2[R^䊾wyDt2X,^oY+'t ,!Fh4j} ݝܴ_ј_*ǹ\.mjOYPB^i- NgE1LrgϚ@`.X)Yt:+O;-[m۲Y,޵h4 1rQ㋊9}:N߭9sF9czNZ-͞5g7sgnօ ;vnժkA6ްnmL\mZ[R͘>->.h47 .Y޲%ùqs;F``6kvJRT] @o#8nlWRҰ#rױ#="'NG#^j~+ɝ9{vF3&k8r`:.b o -paQNFqgcnݸ6tpY~>"hْ_Ot۶l~𡏏O֭tULL[^n{[-[c.T*%Iɭ[{F*k'OW/kbXL "dz/Hk#&=@[&x&'|Fa+T֭[߯WT*5t؁:%c/Ob-\0v.7/J(MT*_;<*srsƌodi^+W|;-[Fօܾue۵ 23ű1y2ٖPTnnniiOM+w H"VI9Sf=5UymfzK oH`kpD"iZ5ڷV-4q&d0 hݺyp(9z^X_z58((66|bDB!i[NNnrrr5:R48ܼu;>>NקgdLo1[[Wfo,⽇ (7&pc&bk0{[}K3{KL83hdߥ  '˯2c>9}Zp8K-?w|fVS'J5{;7n_Ag88/^;wus~~Rkw,\08_wk5k/JJJ{"h ٜ5&N#Z~^] <߉и|:'qy 3x| Qȓ+rJUͅqᩋՅ UB]TQ0-}}U}X5hܤ-[4mkIDDD5g@ Xbjr`0/<72~*J\.b|brq]d2ɧ^`b088RV#kqqqU;԰ZrlE =f,։e@|>Dp\>ǧsyLTxQ̓+r2'wWY";s\UBST.TY8 0+3ush&KT FDDy~mքZV)~Xx\n^ZZZZ~UPVVVVVfNB0LXSRjJK5ĻN2 \YF3('kx%%8kVA> x~# CEprlHxwkЪ0Q*ia@yְ5o#n@ 6cLC 1@8 Gߣ{7XතÚYm/yV!@|W GԮ%[@ -5~CmX`0pĎ-vphZeuh4Zpl^q6]26AA 9b;5w쐐 ?[PPxyymaGf?|pojŮԆ#[Θ1Ib=ݚ&{nQQL&#,,ܺu{tǏݫNe2YK-Rbւju ÇG2dp'MJf[;wmPD-A ;dѢ))]b:vVU̙ >>>B06.!:&_}9+ 6<[wY~>PjիOٻMD!wM?wBl\B=BCDG={[n=zXjįSz&88&.={tn id۠ ZjDyV F[۵kKt:ݮ];vPM9ڶ&Jw@zCvM:%IMoo/ul[ktt<l5x Ph^{%T#h4ZPAAK5ky2PX!Ils 4LOO7 ˄Rm[@Vw=zL/i#!!# \ SO dnn"D^^#UbB!vSo=ݩml/;aNGDpp0yOٖ\! Y@@&ϯ%77QCPh^deg`_Bmп8!W\+Xn\.WV8YFh4/^5!44$i$B6U_ jA#b;2u%}л)))/$zd:{$NxfzzS}3g HB϶ѽ$44/7bĤuMP zU؈֭%"9'#㙏w.1#WZMUݛyT۸q#RfsM2ڷ/..4psVVPڣ{:`X1|>C{dq<&&:& Nb{aaaddP>yIiPP6/VTdGZťgbN:{VmF`0bccb<=aefzh٢H(/(lZlأ_II|>?.6K|}3L&eO6*J* -)))++N:>.`4 ?v5kDͩ gmbD"IzY罻=<<͝[9N?v8QHGeRS"pM_X0^TTJݫW||̞5G.W|8d _xfFZbEr`hӦMt.-3 zE"Qr9آTڹs'HRW6eKJL&k [9|9z^&5km.P(-YܹSGiS'5TiؠU+6[&s炂Ç^R,vDfMBd2.^VTx\iS˅Bm[78,33000̺]\\vѸqcL6x_E㩯ɑ#{zzɓ"Z+++ѽkff氡A-ww;U*…,u߸~]N_ 40!>.)_-ww4a/jV M6G} 7nޚ5{ԩS֬]yGٹSN]*g̞3=~jŷ0?0},@*}dzL% >6wͿ8m^V322ZmuZcǵZ3g`|gΐ%dee/Jɏ.H0̆ ٻd={ɃfMN|;wA4>p@^7sHNJ>x`E( * ^X(tusskסN#S|~doU=9lvrR24jSRRm2^IХsƍ 8\]]7l^#%Rt2-[ضm;aC.ZRK˿ݼykA7ؽGJ}Ï&"b˶mdSO:'!- \!+ %55 [;v$SXI4 ?.,z; _Tj7nT*ٻKІS*ܻw x?mv5kױ_/ONNWTTDֲy[oۼdլY$+_~DF{ň>$FQJκmѢymJpPosRMuvr^={m1y={ٚ5kFp8  MiiFq&BLF#uɺn]5k־};-0P>2()ow,@ &5"H$-[$At둘v#ݼy|^D*ݵ{$%'/]($᜹gYY{99\.gr|~njt۶o9}~ܴ:yXyy`hHXfo3b~:C\ѤZ{ KHII˿vA<{oGP@y'4mڤΝ7aخK5z ,L2pǏj4&N6R4y!! [V~<+++;9_^/M6u1Tж"p8YAAA?~ŋt##={?`2L7L:j˯K/,,*/O2p3fζj.NwqqQTZ60̼]rMQ=@n^ /++ҹS=?+2ugXlX٨j.o FDDy~%qքM[)+Y^^ʠAErEN+,|i''-6l7y &<>km5UiNa~2{};M[j5lGTLe0,:l-/W&""yvaaQ/>pjyT"16CWWW\~ŃQD"і?fgeW^-i&_~1xbwh7 r-/F>򲦨>֜ZiM$@ 9bp0#y8=x{DT`0 w/_`8  OJ“ Ǿ{<=Z9<o|3gi6}iKOp_B+4lxpS|8dp~S7o9=ݳkimD8 8k_g<oƴ~k!5γ?%W.66td-޻WϜܜ ;v0y2y-m\\ {Rð:tӧ;𥥥Jօjȑ|>ɓ653R $(0Nd]tᇩt:='7tASS~1Ѥ6[]degڻ<&7͚6"X۔O/jU*8>,?eKOJ#6&d4)FP[񾾾mxlc2[j+22 qK E-.:Ӻ˱0{;2 a2EFᴼX6]1s-:A$~4lh``F)//ݫ'y]8N2=L&s999eeez)Fо]\lT*yyYY9y7(ƶo0T"yb2R|{vlҤIAAX,֢<.w̝Kl􃫫E-"#d#qK;v쐙A^Ǝ1MyxksB F`@OG4ΥP M6 ²?/..w OFЉ8q3a˗.¦Mqsxį963&KWU%dF!!F2ӦM6℄֍3mۨiS'yUmwҩCvGӶm$%&_1QHW_~'h|5ee:n:[ IDAT`T*h %_U;v%~)ӧud͛o-oq3[&67?vE L&ӆkWXVWo)}Bb}oДR޴I)ejz a q 4kR͚55cy7(6ĿŎ $$ۊS&OJ>5%TD۵9kAWVm)K#G}aFFF|\,y,Qbc /ڱC77o]Ff,((h(\0ޢ-FBrrrT.gdXSVU)ov)l&vF!/rrH/[RRr-qYYّmX UMm~N *5%#y\RRr4|>_$o߮Xz8Vt:חFؠ{9b5 !o2ۊAEEEoUJ]"|sIG̣AAFQV5n$|>}-\?IU6έ H$*ljKBA JB׭[oaRjjjt.=ݼu6h@F3U4B!RW+33s;u8oVJ{J`^"RdΝ6U۫OIM ױcWcq&LDҙ=AH D [ݻdOya᧪)/_lyMze}oK%H%d>Mt6ݰ{@ @(t89efV1jOC{ΝmV],--miZvMIIITobqPP`ii,?P|/))DdYW(;5Y J,š6irY *-mT:YTJ8o"=Q?b$IMK1b&S svvIwww qI/}'lq \h^)cO O2RȦj{UFq_]BJ ̬ǏyRYܸQ"pUfm1̷cRR^=yb4e)l[\t@mnTHD"'$wl `Y %ؽgV-,*jݪa"O''Avmةj۷o쯤d lѺu@? =vGEENyǾh4KQQQb& ju`aM sp\n{8Y0^ZZڏwo9֯9[>ya;۟=w|n" q;a6~h+wA} @ i#F 1@88b''@ zaP.ؾA+Q&vwAAǍ]dќٳb`̙1s]3kؘt铏G3O۸~ysjϿ߾mk|||is4na_GQ{  a( (,^ Khnvhu׽7p J,P{+O<~>ZD25ͼK/*i2Ր܋qqƍկW__Je9IZT!7O#たorv5ͣ4&L ޣ{~^~ŋRR ={toذAT:8Us tsrrD͚6~m$G5=;'ge*SV!+Wӧl-''TСJoe.ܰaj_30||pRwSٳF ݻwHxz[nn>>/RSus^va͚r\t>{Js{{ P3BnnUsP}33NVToju_ esUP( ݂d2:5l ##>J_֮UťsPOϧOR? fyrb ѻftSw,-8fOslmSR͏7V:7vLzzFZVX3k֌RMUTћb<+w֭9;N:|z97׾@ ض///Q}8b(l\2-X,֯о]zFFߨ>!ATQRԃst>77/"?Pի:t4heK |.Lƍd[nk-}ɜ ҹ===ztޣWo*Q@@IgY*Sh殮ӧ2,6⼟lkfG?_~---՛\ow͖p8JdBC9uM<ݽoTzdӧNX,uj ڵгWթ_GMo$+9qwwpQnnuC}uT>/R3k51]^ݫlZ BHrRݻ uR#ر?7l$x޽z*r*[ۣ">] ĵkVtKn 9Nr~+/FVlOl <ݽH$F8N-͏8ѪeK%zWӛ7i* Pyt]llwFa1 :w9~uXLtFׯW/33S.|z9XXXizނGŤq׬Go6w\oAnj%QJeU ]&=*HoSb6eɳZ`0{}Ae\k׊y}А#9yٵbU>fuƒSIҌZj5 |5![-#9N~tuҁtGg̩{>Mo$+ϭ7Ճ9@t^z #/_B WӻG_uz F_>%Q!WI<CU͇F&}ܯL5G|-o/SO9ŪQz\Y NdeիB̾6,D#/VVlQ\.گ]M=㓔/Lqjjs PTnEi/RS_eeQ#wGőuy*!t/^z7vX,{ŴLmyYYaQ]T>8U'+**޻?ռCY+S\lE &zWdnC9G0 e嚗@hV+ *R+s@cii`0O_lr͹\FXiiiweeeVVV%%%]|J2:UJjy"uტP(ޛQp Sf2 cVhߛ];=T @)-- J=eeeHRiXZ#k?!*)y+yu wZrd2VӻR:u*ejj@ >mꮿwS]^O)KJJ]0q-xl[q[0i;|2׾Ӏ_ |ZwnnA>|ji0h@ @3b! f4C 1h@ @3b! f4C 1h@ @3b! f4C 1h@ @3+ O_<a}Uhcrssn^ëWw}E=ݿm&O:m@ (++rTg-[U0ϗH$*Js9!Ȇ: \.\TP-,,JJJ Ud2---b*CASxsĭ[:q@ Tsv>s*˫.!eGڻS'P]\\6_wܙ ̘MY~k;{hHѣBN?6~܏cGܿ¹3#G W߱}CN:ۼ!9urߞ]SkeKWX/!Ĥgu '\|+SL:-zY};;E 8n͛6;?/Yta? WT66քRWp 打1৹ ,;99ܿԔH Ѡ~[9UҦM^={ꗛU~-ֽf_8h/ ψڶnMX[B-_Qse,6kMmZgf**,r]LVUV&MjTrB+ӬBWPPPձ*8*޾s'%%U[%\Mظ׮\zjΚΞ;wܹLxF|I9⒒;wN}T$xLwuܼ<{{{ͭ읝L\ .@CvQW&d2Hjת5S*7giI}YzVTTLi׮ztvvo0_$JIIYzͿKwc>y3gD>sv%<?n,!b\{ڝ:R8::rܧϞ|ovƍQKqqzgiY&!a!|mUV%x{{{{'$$h65ԩnn55kKv:o/ 9bקk~Y[XTTFӦB,\._x1n)ӦN4q!t!2lԳGwR{qOswܹfժǏ>}F|2T^=>x+W=zaDr֭KՍٱs/kVq9kki6X777H$w޽Q,Э[$<!t_,5zFV P(Ԕ@ P)EE%666D.k`ggWXXH-S V(/(мX DZcKKKBT*}xq>!*J߰Q ֐WaJ'iBջ !L f4C 1h@ @3b!Tc2^^<>D|Lb8%9Evn+5YVfy{{'''rSMM|DalL#>h@ @3b! f4C ٧Ϟ;b*SVZTpp+ޫi3xssaþg0&/|*>@b+Y귴;ؿ{*E5[YwhrM_T--^bdinI !/^6ujlջp,6@ڵ999}JKKߵ ؁z۶mx51qyΟ8q2jqbf5jt|BBttf zk ش/#-.Zt؋q'Nhh1e˖k.]o'cN]ML1r_p!v}BpUAV\YiAg\|JηgTI Yj7R!ݻ{svv>sj/_d1Y:LV%g5k֬S+rB#ϯR wtr .\@.kUb^z ㏂BHvv6URP5geeeU^trƍޥP(˯_C_zFl ..Ś G|8Ξd2ʁ]Py)|ٯJ]ao5Q`GٰaCCuaff֠AC2E.XR=jKJsg3ٳgΟH$׮]px *_P%K/\8>!X\RRIɃ~^d"#ԓTPP˚57mʒˏ=ZMmۖ.[yuׯ]{s3^qW^5_Z gOJ(*B@ ZsF/߭[z}կ<"?_u233TwMŲw A Cxq?k|ͧqid}QQa%D"yVFyy(LQ(@l"u]1cFE Ą\n>k1b!TX";:UZWKNIc>&q89%D*TdU91h@ @3b!CD"q= PA,?doZk}`="Xh VTIK9b! f4C 1h@ @3b! f4C 1h@ @3b! f4C 1h@ @3nd2y<޿OD"INNVTRɇbo/WYrsr?OOrR҇TS<>QX9991h@ @3b! f4C B9::X,d~K8N*ti ߤ{׎U؀B`"cN* 񛯇h.ׯ!l̟=-2"z3᪓SJ"#ϝ?_TTܡ}fM]]]\OsX7]NWϯeǎ(..&th^RrFj֬؋y<ׯoJr;wZj#ɮ]kתռys>wkzS5OO6[G^ZݽԶM*U\MvmjGJζ~z<9s:H6NH$;; gI$ٳg1NS ,4;~BTj6eyyy|> U8thmmp=vvv^u_mFR?q27ܽh\T:}:##Sw5tF9slzFQs,))kTZhcigg2=00 ??Rxvh͚58|8;;1SϤQ4oР~jZ큥(JwwyyyǎJWsrr!g{+//Wor^O(((Ь=åv]-_I=?wV"ϝޕ`>s6==]JJ}'-Zr1ұ#~7>VRRBYrE׮]>"\' !NNNA!eeeϟ=rN,%\Mv!$%'ܧe{_j՚U+<8׳=C,BN?ÇϘ5֭ۄ_0ihkټys|UBM޽V\ed<9V7u񴲲5{D*=pjǺ݄d3vٻs߄GGn"W\5di3nܼIR j%ɁvѪU},_+Ρڄf^f[jue)S͘}={m߱'OnBllHp҄mw$\J}zZbfIGpP3fw4x@b^/qdDɘ9c:!ҲMbc !nߡButt|!UOxz H RE5gysR{U^SAqR-[EOrЁعTbӢE 6D3kvN !W&^ܻws7nڜekϟ<|ԃ܂g'g;;4?rZj4wU+=gæM%׮enݵs~{{;WWPO333ՕUs< y"@NN !bKK .#u"|2ٛ^?mڴ6>4Rɑx葫BOիW޼ysC׹\ӧk*'7 <籫k\%(i&>lԨaF0C".X(zڔ('sFV-o~m_GvBllDx-u={s\=zMZufhLnnn))$0I x۵]2\N)))A2U\.Sfo>`T*qBaeW?V>.յ)ʡ SOVQm0pժU=rĒ G^5dz&O*3Z\ vJQ*kmm}l۲9^d2r9s>;hnko]\$~{x.]uQ#oM\<}l'UGr칉5iܘd=~P ;8A=T*K >5 5jHoܨѭw!'cN5i8SÇ 쒟Ԩ^rVJ-wqqYZ|.)_]0#GToGИTxx\خm[;[[fQ`0BC5>d&9# e)b… ](By%K^T(<}=Kߛ?+ӹϟ7bo֕x5oܱss.]:ggeۭ^V؁.Yܮm[B{1Ng^_R u-33];TJey|܄KJ^z%!~Y BPL4y֌D(ع`ֿ ,fqQgJKK'L_"H%gT%` :r8fwݲuhSS| ];[Yܽ{IYU+|P('}FqLU~}5;mwT^C`Eqq.^tΝ`kpu@Ə[?7P.))תe )^W7'B۲y#,--,.[Ya!'NBlllv%;|D{nZ& 7oݷ]"Q>%Qdii99c~w#B0_$)u.tȅ ꏁCrrrZxP kd2Bu P(B[\"0cannC%򨧖L&ЧfClllJJJΠգUT*dC㩷fff﬈3kfBaqq愕x)((ЬVXTTld*Lw'/..u6ы($\ԹKxL;Iecmm~E@O0-5: կW0#3ͭfDxוVWI "iC>JKK5$ WVfz75ai/(Jͯ(JRPR[T*muIPb)E1Z4Cr '5A]xLhd֭[',,W([Aw5eeeZǼ :ݨ# wXC-4C S?xWk*wڙeƏ0~\S51M4ճ{ ?Te}zi3I {srrv)JL|?n‡d<=ƔI,^d[͚554{Vy绺} !͚-[sVGu;v4`!gß띝ҦMBRp߾/gg'BO=?ߴ4G7:uֳG̞5Wyy"Pr՛޽zB:o7rT tYR:dچ~u׮]>{qC/n*~Aڥ3ɴVT%RT5>]3>Iơ!!gg "O6UZR"BƏ;oPToKeeew8st.X[ۨoCgoo=uJoKҒ!(#n_[\\M7Rg%899:rD}!Bℐ,*S;޽y !$22rMAsrsV^C),*?sЀ{?KnܼI:{X&]o ֒7KC;kToyd M6sn?Ю]11ͮ:dQӢyFW>n*w2 ӃЛ ^kzӇ }M۷?tH FF >zT\\"*J6Az\$ʛ7![7ꂙ ]]]BC/iH|G ϧb˷/XhݻmٺdLR4MbxTJuwwۿo!cpJv%u<=R*L&M宷NW~jjFaC$OW}m7gܽ{wfM._ЩS׫׫gN+^+{5I&&Ι=tl~՚5^^u5m@T7nUNǎwBCC֬EsmT~I9>R 6GjРIVmCWBAL&;s̼ E&+JνߦLpr\,ї]oZ LhL&3Py#uy~jӦ >xضmWWwT*CCNf%ee3gϙ1=_bXir'TAf7DkӇ?~Uժ9'%%^l׮m&M.^E|Sgۻx=]{ @p5檴 8/ r߾}{ϞW(;::RO.x-k\.V(433~ޡC{n*wuj5XocfCONJvoܨ!`p8 sJ<sBb/^fȐ7o?q3gUdDUZ !999Tjv333HZXXWG&OH2xP8J{b6m}ku!55--娑#=5nfֺ}2qPPݻ'OٻxE O IDATۉb+:Zo~ %%%[a_DVV'N7m?Ǐ?}t)q.=|0+;DO}tm.%R͕H$|>oɕ=J|7_{⤉|=NCb7sk6O޺sTmݺ%;t`TzBH=wݻwoZtI+LB0s,5R"W¾-|xDxxF &p'YYQ7xX,P(zS x<.Njcm-W(4'mr׭Sou͆d2mmme2twC&Jκrg2666acm-++3Y%'^Di5СCoal{>vbx5B0U"h^$7nzKo6tRY[%sϿ:f^[R7)JI^齿zwprfԈZ7RW( ?FVf_o~pQN:b n f4C 1h@ @3b! f4C 1h@ @3b! f4C 1h@ @3b! f4C 1h@ @3b! f4C 1hf@ҤqcSg@<1W&jPW][_.b[[a&l6u#LKKwgip,Kws& `h-Mr333m9zڥK||©g w~jw جiӹ?qb%%''ܹsCmܰ$wֲe KK _זŃ rii/GSPP@2xЀ_Œi>zD9] offFY\?a͛7=rDY3l++w=FG+-e0G2ݠȄgᇏtÝZfǎ}-[;~}v]{|С]X,!b5Iff,6b1CCw)8t};~ݻBڴiݫgQC;?ppѢT%3^:nݺmq˖߿ҥ!aO9;ڲs׈v,Zգwt#_&S ygNGFDW'$8C=ءc_zE9!B۷߯P(o޺UZ5BHpPPD{5WLmo~TJtEgϟGFFԫR222֞=ws>Ƙjj"2":qB9+W(V^SVVFIOPswHI~6D"cBQXP~LM;8888;;9Q1orsrZ.ZܯoԢDK߹{ Ly<^`@Fʢۯ۷;uVIQVʊzP(Y۫T*{RRRV^m m۷٫g_׮Љz0LM?[ngddR-w)4$D(B|gdש[ڊҰa:{̩S]jROk֬i|qإZ51R=2oܼe^G\6֖<^fffYYWݺ)݇XſSTT\ f4C 1h@ @C|ҘLW>OwC>ObvR BF!||ꤥgʢ!Uxݾb# NV+>OT*L0@ @;b/[gk*14C ._©T0g41[ mRZZ:zkLԤLe>nkаa :=z%͚65!ڵ?5E۸\n-۷kgccC?b_Έ$^6yҤիW7oBwǺu<۳g&O6 0 `̙Ϟ?Zʸq""#-,-}4_.5sss 7cL) `0\niii3LKKKXkųg>r(Lb.#W( Vvf9T}{>w|>_"hHS_#@R*W.BlUryqq ={e˖߿*qÆSOڵ!CX^^.L0 66V !JhѢ&MX_|yi Bﮝ#GFEW^8vlFF!$ z4BH^^ٳg]\]ONiղett4fX˗/?~8ŊءCiiEi\y1Ck/{Ϟ;Ξ5˭fMB\_:t y_M9yD.]..~~~111m۶ݻw^:ۿZ&$$uÆ O>V^@Cf0B0 0}_B_03:?>o_36bogx3f=z֬Y΍7o,(88$4[nn~&/_D'*`ڵkڵרQ#;;۱jUBȱ}||UF  OHIII5jԠ |8{,!ݻիW7kʖ-[T*Rrkꄐ֭[?~ʕ+ӧOS%۶mYXT^VVUӦM333AxoT<˜8\nsOũf^r3VXշ3lvjjb\\XX–XAqppppppvvdR]$U}ܵrEѻkrbQ{Rlk++jĉ噯^ⴴ!_=N85kP0э2.((X~;L洩S/]ǺuQQԤ!СCƍ|2Ͽt!D$%''\Pׯ_ ڶm*RЮ !*4"VJ<##cذaZ=z4~gg˖ Y~0 S_͍5 X+JWTTD]vU|ݷ;zdLLddU@sז-kמ6mu0T>ehz{{{BBa`@x 77688x?իT*H$,T**?x'3gpuu-((=qQ_19ϯTƇC !+$Ĩ4$C 1 ;t|hbFB2w9VZ,0**_|є*w]%|Œ{)) d)@ S)J= 0,&zh#Uph@ @3b! f4C 1h?>7 ?IENDB`RaySession-0.12.2/manual/en/images/properties_ray_hack.png000066400000000000000000001452601417052567600236070ustar00rootroot00000000000000PNG  IHDR0D pHYs+ IDATxgTK7 Bj]DA굡`BbV.6wD,((N @ j܄D';;;;]\ |kWAo1 H+CA@ P Fie(#2AZ  bAV1 H+#6C( |P j; k,!Z"k<UQLM ["-P7`>CkWAvMUQ( EE drkA4F P Fie(#2AZ  bAVւXAAf܎4h=w\=mmmzZ[w`D"~433SmN:jh0Tȩ;v'k ȯ ?fXŋdUUN;Ξ;ڝ4 No!=hkiyYå-^0s/RV\yڵ[a!/'u@H :yy+^%$`)rrr\.WS(Jrrjtf%n-pJX:Hpߞzڽ'5,]xe'ORPPlpG"Fq8׌Bksf;~R@< Ϙ>ntWo\jbl Z7o̞53*","֕KD鶶6a!׮DG;;9bA׻vx;*\SS];+.D݌{䐼xRWWx»ѷo\z7c]EO8Q‰Dwnv];,Ʀ筛#cc:D|S[70)G4Yk:f񓊋'MkvQ8M=UUN8n3O۾cNߵc fNKz:77O$a+Weddu볲Ο=084 g?H$:9:| [:vu_'wuڥu155qvv-*)+ax<_4Pv7l`0ٽe;wğNԮޛn}mKAf=bEEa6y':r`?8.aJJj[}}], B@ x,;//Undhȭt{Xle%%==ݼ<-MfoTv~l3vEe&DG151'Ggqu>Ю?я"MQd2~aaVf>?~t;:Z(VUU {?{G4,MMl8w˗Q`0 _xD0t:}r,=??}%W.ZAw꒠Vf@R7nXg833ap8#F {'1 >t{|*G_xhú5D"1'糺NHWmR*R*A~[Y,և~GwJC}7Fd_oۺy% oϮflKþ|{3NFDD~ə6u1BhAX7ݼyKN {,t^*i'`2Qל>>dy;O4U^޼E:_S&*''8N4vÇkg-4P'O ELKKKBD*//a|ɇ½/ó)*:6tȷrOƚ<NN޲y"8iU.#G<ӧxхΜ:vу˗5PNaaU^K`Ǐc+Ξ;ׯ -jC` SSААLls#(G[M-S vӡa.B~u͛6m}zo}ζmN:'ۅ ȯ`ֱHcWEW0AUUf2éxP( Hn/_q8ZEE=ptp1}ڸ M&B$UTTL8WUU9Vݻ'Nmi.-uge P(.6Z6V! KJJ$dysΞ=cex:@   9| gqM_A -nP~nA -mA@a /K'/Y:lٽǯ A!e@Q  9M P~@Nfٵk YUUi@ ,7_A uFD&AZJQq@ P Fie(#2AZ  bAV1 H+gMxsss*,A씔Fkbs3"Y_ _`0-,R޾B~vhJ( _ChA@ P Fie(#2AZzg 5"O" ML/?hGعYR_@P&PAߗ< O"q8a|$A>##==(:pXZ(#"|C0[#K >ںxЂ 4Fں̧NҹtzhH^w1nXk6e$sVW.]kWcQX(*))3ݽp-1v <-bSM yyyt"kۢ_/.}޴a}c8 p}@ o;X=dţ9sKx2]UU߆rrrr%p8 Bp8*ZYY@xr#Gn,e**gsݷ?ϗFpPkקNLVP(e2lt.B9xǏܹ{ڵX?xH xyWSSC&׮ZZvݸ~HTTTLN~xjN3K;vx~>{S'O>sVQ66=xVSS#H[m>h@͵>~̆oܸ._<=ᢟ" 8@Įd@s̞ViQ\6EpN\.m ۭ̟h޵dmwpЦ Gta(S3 dghw3gIIMӧݻCnO? ]t^nhsKˮ=zX9:rطE5\`s烂Cp8]PX8{<-a2H;u99-Ϟ9!>`0ٽe;wS7oN6, ZxƎXVVsU@s*55pmmP(Β@(1dğ7]NɃy|~Vŋ E?oӦ}vmmzb$i׮=Q3Bnr\@իT.''NGG151'Ggqp]~~TjiiiUUU}5q:u yӧVD ~*Qϣrr>@JjjYKWWW|>}zvtP(†5 X Jiji6p@grQ>ݎ\hQDDD媫 tuuǏ*k#vt}F-544 D jjj20.:} ߧ6"d,ab|~% "GD14''ǀc~y֜sgώ ]'Nk&s>Q3fL_pP8>Eb<HdIu:]tD.䔕dRT<.G >>_RRRQQa``ЩS'kknݺxb۶m344双ܴi8qԩSՕ###/_^UUEp&W?/4(--`hg` QZZJWCP)pSZVvUF3o>w-u:'k?|H_j{WN=qT5/\x1~Gr>zQn)''ԧbSzru3bKyyWr4f^zU|ԩS,Y2o޼ZXX={/^}v$ >{޽wjhOEBw&2IឡCx|Rk OccǏ_W1۷g͚D"FFF'Mfdf~midm @WSSVRܼjخ˓mڴ!HuAaxɍ >511ek x<^EEJpkj8pvr* -!qJDa,Y2s̒G߿ 6$&&|44#֭d+9WMܹjNDd/_t_?k"Ϟ;vdksΜٗ\z,nm޴mڴ9p`9E ̒< uVTTzaC͟7'@EE%>.I& ..# x~aM6Y^~Q?~  b%v ͫWSSSPP0tKggΝwܙ5kVzzU@fcc㔔Ν;jkkYfͲk|7MX[[7WRPP h4@ H+//b$xriiai&ѳ**6p ) Ba2Krrr,KtcFe(<ZUU% <O˗/ݺu1$''[YYYXXx@hyEEEFFF8Nי!չUaUBb%\֖/_0\.PAD(J$d2y.^0(^~uut%kX[[[UU%_4Uo.^Vws4 ?O(I@ZZ,Q455WZ]_~*J"h4;!à^^^~/)>~+5]議֮ $hŚ5kh,m& nj3|KKKkWXb5:ik4G_#S]^ 6|4 "crrrwn… #G$3f(,, !׮]oӧO 6lu?n q8lQ}P u)_H"WVV2ioߞ}4|VV@qxU 'C&O$~ fcff]A?yJJJk1p111u>n>L&388xȑo;"(@Td(%4 Xlh4$y_iDʓxD"uKNN'NXvm^.]*, { -wPAٳg߼yxbWWWcccY6ߵkWϞ=*!bݻC y<FCItB-,,u3g4P(ܻwo\\܅ \n||B9y$F9sfۦ}޽{ϟ?Cqqqiiiǎ'NػwoGԷ-R|>&<<\(b7nx*Ga@AV3p8ܠA TV՜)~ǯӢڈ~tuZ]#4p;=ݦLn{fd zΩS Ւp RQ O'Oy /]vx񢍪j/VVuu)/NfygJKq8@a@rx@"=̼]USC"H$/l1b <־JH gN~5[[5D"@8x("2 dj|>hǏֵ򕫰˗/_>t@SS3*"`ڌp__`,HG|$m>m9{/#0;vة޼~:U=8F|ooQft33 6Zz+W/!Gy<^EyRM\{ްq:DZn]HH43sse_'Ֆ-[d2_tuumnjf&''y5kL&@شiAj8ª+zkЫweWڹ#**J O>=t;vvϞgCQѬ˗cox66^y۵[?hPuml딴P Y\aa6m7~*++]NwlyBB٩Ǔ^[h~!,`"@"H"!3+k]V9 KiәRmm퐠lHK.nV{ΜJOOUC!ShRCJx5}4PYGE IDATǺ)))щ}ڵ/_`kkk̟r3@$D"xޥ M7ϙ3s#>݈֭khhn, @Ϟ6#G g3gZng'طfΜwعm XYY߯/USSp8O<ҹŋBCC|auݻwϵࠪ|TT̛HU ƴi=۶amtf2.]lڴtϟI$]v}{~ 27o2rMBa>YFn~~A~SϰX,(**}ee,AR4?kn'1PRRٯ_?꫆Hzz3g|SӃ`S%%%WZZAJKKe,-55L&`[o. l6SCC;wlm~U,ãG۶m ;w |>׷_y***ӦOhL&IFf!}۷{]moY@p x66?[vÙ\n{EGs,.; 22JzS׮^x N_|6??USS+~N@,\0)+;,Rxܷ#{"?C(g#232J%4 /y֭ۈ$⧏ Pϯo+VRy≢/Z]xZNΧ)'-\heADh۶mˇ ةS:B=ai$o{į_>ŭ0íX,4ְCBnf2y.Y^^C(9 G+W1#FW@~}ET-^\R"a}eeTLV]^ic3q$7~0PƢ6l#?__p()'z%%%wZZZB ޿t]]#G|*#ϐfGt#=O͡ &wX&NuvlF"?ybdh8xZZZiSdDIIvbixjj  ég'Gl<cbWjM4I… E:]Jp86lEQrV9(**9K|y߾}@ ~ڵĄ]w7pǏs7wXž~&YEU+*ڴiRg?e޽{ۆ Amm?,V^YY}kr֚,ѣW~F,^d>'1OΙ5},>z`~},^}UkVZ8δ3jjj:yw+++9?6%V(/(.4$87?~  bE[acǺzzRVR!^¢:!`ksΜٗ\7$ ݖ.ٳwlޜ}6GXTmǏ'.\8?\cN'ؾ=88H nϚ=tc\]x\JJ5^жUF Kܖ ۷UU`zT]O7m~USܢc\ f5>> mZUp8UU )P)2\ZV&:OzWY2]W6en⨯㕕Y[[?]_TUUh@EE2s׮CHTUU-))8ejjjl6[zEt @PQQW@ 5)4@bȼ93 ڶ>\ҫOɪ/+??Dz/-KbÙa5;mls+O&kjàb~gMB&Ǯb;wU^C^_@5@ %aYY3>}>x:@ (..a /),(2/_%iB0??LQQ;%!rVS#^0^qq{L{ ɔy1+PIiTDII|-=5~EFEv]JHLz, jkkp8_ZR|fח3 #ZpEE>B[0F=bDݻ+= 732TD*#4s?(s]ffpG龰H5@/uuMh4 ))**zQǠ@BIM3DyJaUމ{!Ks|$Y;#G AV1 H+CA@lؕZںC;m]݊:&mźfjfnnjnA?FeEeJ֮ECT A M 2AZ  bAV1 H+CA@ y%^^q133.z#YuSMTQIMJ/ȰZOƈ FCQJkĮN-vi[  bAV1 H+CA@ Hu#F)dE#/\r칖ϯbA.:uDR \nSK Hk<{YPPuFQePWGA[biiwǍ{"w.6>MeV\lQOO]vPUUBvv_uvvx[^߿c2;066b!;;[|_&޽|y@ EEŞ=mTjAaAbBñE  ===??+]vČo1==6bcE)4u[^99|"J17`2KD;Ν쌌t6|QRΝ|ZTmLRRREEEuhKۛӦO4i29czNNwsÇ% -ҵsO"m>`ׯ8՜e˗gee-]byٲkٻu_1\+Xt{w_DoNƋrXfkkpG'~=wc%gdy ZZZd2{x,9bxYYؿӏu 'Ocf͘_@& ۷KI}a󶚚gkA_'7z߿H$Z<@&$pT*Rur2_G>OP9Q,Cڵkbb"ws9rZb_c\] W <[(%Kn߶M. L1ѣ^X"H?_ѣ\rΛ7K׮# yVwViii^^?.);r.Z}Hidddhh)Jꥋ(@2jxm7n [+**  ڵ,B~XxkoF={x/SԚ6B  pT*ͮp8 "n-~M2( @&׭Nح׮^677;6DG FtvrݫGoڕKanF:&MY*hսDMXkW"%N6H,fHCCN>|8IOy ڴ bzNX N$KK  ?: ؙ;v/N<?~??, @UU];544u7x`oӧ055sWQQQFOݷo_eeel[nUUORǶfώ~×ebƆGD}zIvv,Yk:됗yÇEFDhjj>ݻSN[θzJii)gϝݾYYYһԢ鉉 ߿ᘛ[`d[G 8޽{m۾cXWvijjarr?ޢ,.ِC/]Fq㆙}m߾=°[4k)'}`[~555CxzyFG+22[[>lF[g_hR! %''?,'B"0ά#~^6UnƏ[摗=?}LLLaʵU7ĸ4ˮ_'q̛1{ޗ_hTzP0cFlX5u9?{CJKˤW9:؟;w; =zXan+Ĵk|]]]N>쪪+*@/[guۧw^^~9А[/޽xg6'Mzҍmw(~kw+[aaw?z/oBCGé>]XXxΝvb2??Yf?|x„ t5:;짭\tiݭ?xhu#p8| -mm)T HXT*L$vٽa&EEFH9BѦM.j<,//ONNfXDp8\pP(P(vvnz@"ݺuÚܯ?BB?|EEE؉jFF:խ(/Ғl;P(n`3.ԗvm{156( B!xp,ۀ CzFll܀_J@ܩSn^x[B!tWɓ&hjhr8Pv|d4==]-MN_c2K@KSL2khh jjox(`TTTƉ sZs}c NXm8??IpO>emm}ٳg{{lٲޥnٲ _6@OOt@$GyI~Ǚӧؗ@ x#0p{ܿײe:tpa];ӧOk׬ٷw-[|Fr߄YRmuuuC[r+W=D555׭;zݻwGq8ܨQUUUMq1_B߼eK:uYyyDoX]x F۶}i~T^^afjҧmI/<{b,8$ /2iĤC>%%%t:÷qYYYfV4U oTC_-.PjiL&F~|o9˝pD /__'k[fVZ FsN4vL8 |>TWtiϞ= HOOvꠁQZZwF@.(--MOO<>Mi7`@m-7)_q 6nXr3; [B7o*n!H#/^,GnթS?Y"RVV`h̜5KYYA(;995ȯC(fddoNzUiYN-2EE2!s={xېY]nׯoaaQAA!XGN9xњ+*+c}8zujvWYw Ǎ *((`ۑQ'M%37/9?7D?\O>-LKKKFFF'MlRm>;}欹ǏIٽkS ˨W~.00PCCk׮KGGmv1M2#@QI_~XVV @ RRR>4cL!CD"\fm#9 ''* طwo{-=&$$Xt(_~ȑ㪫+6sYD"ZpMnbb1rP(*VQQ. „M-#͎@ 8 u{4@m{| |0_mmǏAǏ}D=]]BYY ?|V[H{'޻G"̟suEEŽ]CCo[fWVWs\]紡 7ڹ}XW,,,ZsU+WÙ6}8M9sf_rUucƌ1hg~h,8qbӦMB .hS>511}ibqxD:&&m;tuX,Bs?nܛ7K,%Hiii&7CoUTTP&L'NގC N:Y!5Ё`ZC翭3P Fibc 1 MBo( H+CA@ P Fie(#2AZlxVkU+SSRe|@lrr Z"4?-m]ss󔖹{ M40W}.  bAV1 H+CA@ P Fie(#COOOKSW-?nBBB޽*++-[b]t.[PPGr$'.))kkBZ[^߿c2[u%??@}zP(한ZTaKKZ*]EYYׯ㪅1_|k,6VN͟?ndA[[Kb޽+.|ZRSڵk"q$mm{UUU%%%7AVV=T*FKM馀UW>}J4irm*Xge:t2jԞݻ%JջZvQi^rXz.]۵kWíy$tuui4ZZZ"KJJر+((t]]QYY>''a"dXXJMM%V)))|>Bh@fY7DWSֽ[t֪@׮]g̘9n#>>Gӛ2eꀁttuRSR\۾ϟHs?G8 o?aɷfΚmjjzhϝYvGo'{ݫOj@jս/oI%pǓ䪪* #&8JJzf% lg\<jۑdpU2d2,-++#H.^ y3//ZZD" rg̘D"̙sݽ{jkDx˨#|?;wv횘=|n4;FFFX;Ԇ8;am<$Zxɓ㝌%DӧXʕ˗#5&--%%ɓ'N<G_%:~X Namٳ!C^rYGxѣG))+HיYĔ\h'/OEEŊ: Q 'N01<"D"NzMWc٦L2v8 H"`}'Mm>}t"-;;{mS&Os7l1~Gz*v6bH77 xDD^^/D8z󦢢ӧۤέL&f2e-C=>rQg5^}pq8E =|\F'{ƍ 7ơ;'ͻQx  ܩ&,f൫QNXbpPัco qNt 89:-]`|cGBCn BWWWbwnG8.\<[*-----A>TR\${N'x<^BBB6mE99aÆX}`e:yc26|8H .K=Ǹގ5z8h  @<te֭ϫ~@|\\||ܺ[..111!!njOd2q2YaAwmx_X s^W{bD"1OcoGGbbƆG i2;v|qQQիWΞ98nY~~]Z#ݻ[ܱӧS'OLbckKP4Z3442thFFaa'P#G888:looߦfff} ;vD=>|8::eZ2By"JQӇ >̶jd„!WvUN&BBǏ_vZ]mvƻv?;b?/@"ؾ} q̙Ϳ,]dϠsfT5g.]4miӧ+o橩)*wwxrbvvW%R5knՔ&%&^oٳg"".D"ûbOϞ,&3-=],]S766nݶ]"C.FD P9s,kk޽{e;q횕% XZZV+uvr7{x|sm-?~o޾#DGm`oo;$T*Ut qd242O?poظ9Tꅋc._>~>qҤА`3x1466ٽ{|>RN&LZ[[{mP8dP`55C| -_.zbVVqrt2d(3xO"***~˚lYbW,+%%E,GEE*w1 ;3a„*uE"\.H$ .**Jzjjj{\foo_^^A߿7ŪTqK3JGDF% ꣻ C($ B`2*HLJJ|K?y[ܺ}*8(7srJJrJ3g8||pkn˯ZʦX,nnn̻;DGJH;߅("G<^^^b/>B5p*J/ Dy<12EVVP@*DFE744̘1}?UW_hbr]_Wnll8r䰷__/Z觟~Xx"v7oěuy@"Ǝ(Ϟ=p"2}.,{℉⪫[׬\|:tSPWW׿"yPVZjll]tY~Lz\A<^[|ΫuKܺ}`~T㷝Ç s Lew333TM#"FIe=}՗jdbfn^_X۷mc+VPH:&oryy:;!f2#=wbR}{ >3ZyW"ʈWu彴9s7R WzmOdggF'rщbhtud2[gŷoY;wYv&NU::tǟ|T*mlllhi_d2y]-c'Nݸq`$jz`[~:nhF֮Y^zVX,/P#G>bDTdbomlb֖xy"z|࡞TI)k֮KHLػg|~~xfcqJ t:&knnNJLH$t:ɓDžFn޼d2<͛I@ lڸqʕG7HQޥ ((;R0T"i{; M߻?++_7vzΤ. ݻv킧wuӳg.]t/=1)T-sss*%]] |\8֭r>kZWO? \.JRL&{ӧs7ݙKMM;r/7w]w?Aա93DtKΝ;gjj驣 &Ns֭ׯ7ԩ?066Q顜8q<;;7k Lf40H"R_ɓݻv-XئލQ7oPFHpׇ[ZZ~ggeD9ϕ+l6O>&Y+ǎgNKKuwwѣ'Z~pq|޽kg>y &&&UUU'NXaad2y&M;-GD\si[AۿO? //B! 8@X~y'7&88D9…54S&&6Ga!AiiYN΋Ĥ9«1\-W,]Me5:&vCSS>+3 33_п̙_roouԩS2ٕ+WXR'Nw_`+Hҍ?pe4ŦƆȈ&eee#as}`޴])Jss3|?>V\:mt-.Zp ܳ{7NH$Bp?`/ϰ}6iu4pHc}5ldĉgΜV)S(lܰ֓H$OWL_*ZxF:M\qHhhhP  ۻD&764Xv<}T.Y|ԩ77ctBT:zԨ^?~Le>zǏFl2FXDQ.#.UG@ z 1@$g-Zχ@ C,Ռ1X 7/A O}]}n^N $\.[d M AB@ z 1@$g#i?gҦr# ϔW_mF;>R_<7*r<7]MrF #AB@ z 1@$g#AB@ z 1@虶#&nnnL&]A ϟius++/lxxnm_[[CL0TTT@1b3HB !F =@ b3mx!Hp8vS#֦&'i*= q9vScj0')*P;)H;5lNn|g'9>q݁;7 ѹABܩANb3HB !F =t :5HBϠyį077 O>˓dk[7Wggc2yvofjzσǎ[uqqvtphhhxg66V 7gߺfoggooKPܼf"˫gVf<D쑙uK")=\d2\qUUϞ+{agϜܦ&{wn`e˖fg`ѿΝnGW4l6_~QрrrrK$anт}obXnݺ_FO4ĩӸV,_jcm}޽&{;ҕk~i7/>d26o\?~Twyo03.FlZcd2ƶ~jP+Xg:,H;9H_f U"D"0 St@PBccJqcG[RRĻ -VF h4H$RLӥRXZ0*^J&Y__ߪ8ffA Sw sCjq_FQ:Bi/>۽8|Ubxxq۶lx}c뙳?讣 *3+[tDgň_ ˕/J'"/D;J5pX,V+..4mb".sё@ \ $\޽ðys$_ ٹckƏ A#Gnܰ-B/mu .^$iϮ/F?w洃}K>틸(Jk 2}جR$Z2H$< sZn}hEݝh̞5]^=gϚ/$/8vKr"tŪU~#F kke\920b g?68׿Y<xЂٳfzyS<{̞5s߁YYyAB3g-X+:ⲥKpljjzcmmUZZjnfa. Ca痘dkcp3+k@~*( IDATX?ȋ&NP:l萋eee5H+P[[wk|Ա w~7380{,OϞ=gϚ9wrPׯ߸~Ӗ_~?oζ>w~_η/(TJJ=JJ{|l`bb5-_ ZdW⿚1 g&r GwY,w>.\lH>2Iw ݿM# H֬ #6Ҿ?755#+fiixʞV!*@ `}GͶoND"@8zebbzr^ &+'N@ 9}FQg@~3g~}af׭"Q<}6=ڐ>37fڟd2ٲfϚoo2Y` ??tx7N;*7hI$qْEuutjB⑿V)]&ڳoėioC\yh3##Z_0 :Q]]4ARkjjt@RlP(Tta&-P(L&O>,dhh:%3bD@ bʤz7֩ :F5FF^$׉z2}33K#~sڟ)D"XhI&\.miGdb\][D"Qk L]Dպ:st_iiH 5?$.onbndLA@SCPq`h6M&.$ uЁܠkgwjP?D'&H=SSWW3כoǫ B !Ԥ^ߎtjjkiioJBt6wvRSSmL.B3HB !F =@ b3HBϠkԯoG:5Bamjr"ݙABܩ@yEENn+_ASLMy$%^Es;-H;5lNn|g' wnеA@sS.:$g#AB@ z q'';@tj#A_[7Wggwm|Wqf<8zxL>-ú8;:8444<|T3 ss+oVdP(|~En^>x@TCC㝜..ΆħOKfKJ˪L&͵gʦvq10ܸ|_@ W^g7n<<գGE={h7 i/!&>xhAٷnX,n/\LӧLpi\MMy+/{^SS]Ii~xd`0NN_q''Ӭ/kz12l>z!NwKJN6\ngk/=o+ l6;h섆o NXZZ7vԘ%%@"$ L2919YEtzSSz`455IR/XX9@h"H=:.Jbr"aT*QK0 c2Zk s3@O>QV^jܥ+̱Ϟ <~E E,/Zvq}V|YAň3gϫ_Pb:066>|p_?i s3{;;s/cEgO1љA1dr *>K[<|eKDGF}z >BXh+-_4r䦍7o U^8ӻ`6o!;wl_vqcq7uq~B$D"谐Μvpo^ӧ}S;e@ T\Uf@]ěRUU3K s|\ {51-E̞5]^=gϚ/$/(++ߞQA#) u-[ tȈm;v6q~T  Ѿ~&N h8Pd\ 6f(\:DB`tt_@`(7n#Dk~AYY3Oo^))R+!W ~wLRي<߾ؠq˟e;|(34dsqv}'_%ѱq##0Lu;/3+k߁g쁧xy=k245?\uП_|ytI'gᇏfT"ɬ—Ο>0Yjkkl@xx>cG7m_߻_wP [.?Tl{Y<={zz=knffDZA1Wdаа>>6+3ղr##c|F^QQ@ڪq //ջ(Wwf);;;YD"=yĤ}_%#b"bzʪԴt 5g/?{V< _7o>Nxj1~}soݾ5:6.7u߯X,?vڝB ]ޭJzuM ϔX535-//Ǘ/gbhHfr]O>+/]S4US3vqQI wR"(9HJ|BVof}5ҕ}zT]]ӷ+BdffMhSa! !~=lkk斛 uuVVxzBBC߾}bM<)&.dii`d=*(a+HJJ rѽk.ڽe0tvvOZKLmmlek+]UɓQTxuvx Ln2HD {:ʉ03+{ɢoctB׷ Ml_tH$Gc9i?#G^\lիdr9Ɍ<} w&O,6;&&62*Z bbzr^ &+'N@ 9}ѡ͜NkS_ND vkCjUkdV=k]df A/?_͘ |GNsFyky9鳋7s<^^^W#:ĝ̥<322Zea6H"*|H$r\E0.P *tgQƎY 'rd\ d2kjjy1Z%H@ h.? 0=㚺,H$ -eSȤz3ϻodE"AYvB. kkӥR\. BMp8 &T,{xtꚗw$W-!ZRa-S}@ݷw7Lnlh`X[xBt :5HہKBǁAl6LB}LD_hOP?DM_C =Sat :9(4@"@$ĝZ Lx;x<^]$ĝ~;:ۑNMm0--7 ?NjjJ `y@BA?wE@ z 1@$g#AB@ z 1@$g#yf"[um5cӳ=s1O!w(fw 6d`X+g7D 04Aꪋ f @tNmWa-Z~r gXXXۻ;.&jERh{ͭj-\gꞿo><.#LCnGwඅ)'/_D̽{b2 .,3Sӈ a^޴FusssqqƗG bXyfҲc:.4p B1?B537k 9׭Y}ԩc'%%jPKKK o-۳Gn\bM;l6k%mhl|n3ލ'OmiDo{662zc:5T*Ub<{<ysh88gd\ŵ/I 40̀ǡomee/jjjR.B݂`l(:L&u9.f;ꅼz99}d3/uC^ӏukDEsvv޳ketd_G7.\=*#z׮۷/׻@>}n̔Jwrr>6=0h?O,-D"H$T:gO T6,ZᣍT[[7llF 3;wlǻ!2yU-]o2eǢG=rԘ_nnBM2 R>xzq ÀB'"L4ycǗ|¦F  ͭAԿ_7#J2x~K.qf?68׿Y<Ν-L7sj,0 ll?xq?0 ~ySBbq ne}} 6ʕxm\%%N8 9sf$0gl:HP> jt^aD"M<+Fsf!C3zҔG= *Pܭ۶oٺ5`dPܥyH$ҢFEE00"2Rodמ#fLf\rjE}7d`OLJ7f4n|!⼼2sKjlly5 Zhիpx4G 6*hSBBB{yy͝=;xM7+W D"Mh 8qr-w?a!ϼslmm>4xfnysIIIȠi3ToXerT#tT:{A"zU\\Z߾}R\ x<&).Tڷo|ӱ' wyL&S,dׯ |Ϟ= FwwHE"HJN+++'GǣG&<S.K8Cѻw/:dHRROzyyH$OϞii*%&&@[yyy~8lmlnfe Pk/d[`cc5-=ɉݾ}v XT8&6V.D"xrLncm?ۧ"X\\8!* WzX]]d2 WLMMU~9_/~z\fU.⥟fuu妥/v>L:dƟnjj$?yR\@*0113z ]&\T*g/3dΛ1-e;&e)-WVVl DȨ膆3/^Õ)WUWK_RgjjSht<^^^"]qhޔŲFߜ׬ZA">;*h$@ξ%?a˧N|UHHLӻ[ ]ٳgϊ?:H$G鏟<)(;}aؗ3'$&zzzi_$\MdwH$_;>ϹnnnnnW3+D"?i)ZGEX,Vڵk `hhe666|[|>5SLKthZ$%%73]vђڪs% fmm-XQAAxΌk\]=<w #^=^KǏNĤ$g''EܜJt4SRFh>E#88L&ORi4rZ.d8ccc2yFYYZ>zHe:g\fogwpGBb}jj=~q1<,|>STǎێsglm[*b?b".M64ryWWА󤦦Y[Y%%'gD Vd֬8ᣈ a!A4X~ޱё1Q!1F}k׽}6&6D"V*[B7dhhX]]҆khX]SaXƦ۶?y'"ak(HT4Tħr\V `܎0 |p8f흧۷޹swķnƈD7[9$~ґVAARdӽP\{hL8ʯ;rB:cg2LtX,ni^c.Ԏ`2KKKbGnyZKR]TXoD2L99:'i4qϛ6$N9GS,E"QKsEz򲶶^wW[yB\{ٜFSZI~5DdžۻD&764Xv<}T.:3s&O/;xߡcRq3 jy&T)z80h4SSS3٭F(^%N_I#}x 5(]T@ b3HB !F =@ b3mϟL/x^#uswwG wG}ܜ6iܜ:@ #F =@ b3HB !F =@ b3HBϴ: Ioe i6i6>565@PTCCMZDB*@ :-M Mm 1@$g#AB@ z 1@$gwj8l6JU2 &X%Ɇ`iiAPwÃa ~vdN} qJڵ[XאJBL(T fXmЎ@"dr;xABܩ e*JRDAS !1e~eDz"@ PVBU0DR5aaX&seR7. N@ pBPbW(HFF"Q1a"~C `a׈[YQa8D9+Fd2 L({{''8qĘ5tp{QEea.ΎF2@ ޽{F`лv!>7L|/.װ7Tj7W*F `ee|" hT;ܜD" RgG ˿[[[4MňI3qvr͒ں(#:>H;5bqH$244+URb-p ϯd2d 73oIRkkK'G7kam;uܥSnn/`xWGϯPchhqL  D"SI9H$*:f*\ޭ['OH$/c@!=:D!+Nss;H[Jt✛_#hTϞn#:9(4РZP]#`X0@غFKRi@Q9'@.?yH#vdHlnnKd"D"hƦF**f< Fet:bLJrED"^QQXFQ#p"Q@M/Nwv5B''{NCCcSSs .d b|A.T**Hpa&1dDڞxoZ{UVTX.LM&1N;=<>411jhh|\d`v kZM7+oZ+BPt1F@b1z,#B!JLkj;w}MfD$qR(R^zihTn66VϞv}'W(Ecc#S1 +PH[Ftnfq3EiRa MtvRi]]qu !166ō/8H$4Mzll_FxIY)R(d\$2@0L"044Td./㛙 8x X$jx-?% -iK#,fL611~SI `@$I$MHJK }d0/K?X{ Gtbnn+Q\R͵ gCv4{f a=<ͥeeUUոL@^ݮ]\+HBh4ҖFhll,,|ؽ{fT&W1eD's=G//όTCC%rqH$L&ʐd|XL dVbF&RrpH$u -aHB!+"ԈSӪToffizĈ7FGQtNU(r\*˒JG~[hT #AB@ z 1@$g#AB@ z 1@$g#AB@ z 1@$g#AB@ z 1@w>bH[)j=,h_ C9VPa|ɹ~9; Mh ]TAo3ƈ߬+S 5Q@೙YϞ=F_=kooow6Z-J}0`Ȑ!^[d2---ݬ@tX:7jicc_\.P(T#DsbF!*ݎdڷ@RDb;~RMLLBaSSӻ+{eJ_ւǏtQIIIU\Kbun߾/1"??_ (6 t4~gD"i#DJPvbw0H$ZPiɎ'Čaa0@ h?^D"Q9CffD\.W?jJ"H*++5zR)&ikkے^z*TVVV1`Om[mOHd*GZѾth!Htww711@pΝV?nggr՞={VWW?yv@ y&ݻwKKK] *,xݻwlmm@.߻wOwۧP(!''G%mmme2L.**z888rDr֭:e;4 ð|)//ǫMMMw(,>hRѣG0pݻh$"أG.B0;;[*ZZZD#D@$E"͛7տr \.ɩ˫vwwojj255U4?D*//snACbwqbTNhnllP\rzNs8P]]#tz޽KJJlmm1 klljhhPnL"fnn.SRRdٳ{7m=D 3Dz\.ѣG.]rsswxo\\\=z3T*G555[ 444]t I.]vtt 5k^p!}>_aaaYYKH;q.**:w\kk@ X~L&)qݺuk}}}TGGGYYY]]]Hܮ iD$Û5@]lb9s AK.]t)n2X>LDUUF)X,>r^>bŊW^]PP{L, %b]q8 >ȔJzRnB ;jZl6`P J,rquNgQQH$bYjRjH$#ge6m6[`GW$++^x8B!RRRp|z,v'nP(˝N'>ŶX,~-K!+pˆ'n!;CCC!p8pKjآU*8ވ5@$d2|q\oooFFָ r.\OCŇ`@1 388i{`r_X dggiTutt`ɒ%8 x <c@JswԩE[d2uvvz<\@P3LE;zWD(v z!ճJJJnŁoK"Nz l㸈3^9~e㘁ԔETDqn7b#/ d+ vq6юG4=09/{ސk+ ^?fr^a/O]|x3 SVVVYYyaVkwww"/BH$h[ pa|]#(\łJjKTۍ؈!KxKu&'>B`GT^C###EEE<!DD3x"SSSrD8Nӑ$IQ`JYBp‰e^73TRBF |DDz_EA}`0H$\)9]{L?bƍ~'`Z6l`vFHKJJ >mz^ !IJlCCCIW˖-S.\j֭zEuuuغ\JI]]] _5k |>EQʤ^J555>`FqժU$Ix^M6|>epe[[[/_/z}}}k׮x< qDD+eZm6ۆ \.WCCån!҈$I7ke˖aK.ݼy3n !DӴVkI#J*cXrE|(ԥmqcieeKsIŀ/4{8 xPa&dN%pb;< (|VHz9n< 1򩬬t\===|>F.[ \.f2D\5Ҕ"VAm7#6[\G4(C2E,)v3#v\xjф)e D%,{Ggq\S7|ax*RRRv;0xj(MKS*b+Ŀ' pm Ľ==r&Lr:{Οx=$DNNNNNLtHf3;F!l}$C$Qxz;w.Ap]]]Ν'S >={LQL#@A @  1$bH0` @A $h"agpzzg$0` ^T鍶1KħdEE=='L g&BqkJ%m1???fDW޴iS9/^\XX̌ɤ)))8F&?k&r"PaO/sAe=r8~j;fgg< \ SSS& yW\\rcX>xtq}W644nPFFƢE\.Wjj5kv{pUUU###.**ŵ,\%K;vtG"Je~~~}})((X|ySM&R#"##a4՚n69#I20.y<Ç h4Bd2Dٌ+Vhii1 |>f 233vJKMM8.8 f(kjjL&Suuu8BYֆaD"/^rJJJb#G^@ 8.~hll\n]ooNCCeq @@,ry !0 @ X|yccbIMMs\4M9r˗geeegg?~v+ʕ+W"JJJ.^\xZ6//ĉnܹs`a* r$xN\JT*MyewАZƟ+jV?6`0\~Q*X 9'/^8NPpt:D"˲XVF'JVD" L&LFBp:AR!Ӎߏ8GPFFnQr(`@1 388Vm6˲iiiE .6g2N8[\ӉFdgggnG[^P(… 8MJCsG_}cFRY,\8H n7 $"PSN-Zhݺu&@:&)g۽^L&STFl6d>|ANx<</b E<ɔ. m6^ "dd&d@ _\\miR,jsrrl6Z ~7|8>~. "B$|>?x'Pܻx<]]].i4ϲl`h8ۍ( k`e 144-L&S]2 |=<^^'}0LWWWOOOYYYee3gmwwwL&\.W*C(fee`ڰ|ǣT*%4bX~٬Rd2YVlC)p}O'((-"CCCk֬6"cgΜ Yz{{{CNG ȜիW٦زhpB^sмjr98y _FFFq/X*To`HII 9a###x3;; ło"|>hī&u4Ljv F8.dJMMg|>?Е3 $==!Dt^^dJKKx`08ΐ-mZZZH!d =%gz^*|>C#L&See%£:r\+WzG\QQiZK[rz}yy9B vժU^㸱# FplܸY,n^t͛p? VZqFo4v{ UVVĆԐ6 v_Xmhh`Y7nd]paddD&]q @|IIBx<|>;0nMeBZV*^~^醆|X CUNj劓'OF{7=#èG|kiee[ې-M$5/ |/E$G1&0&s#"g|.FE|>˖3 S\\:::"&xxRZrl="NV5M}}}[K, |9 xҋ k>oĔ ,1$<@aBVXaZ/\0CeT'=՟4D3:4rLp9TVX >|rxE!g|.FE&#6|.+++U#q,l=EQEEE!zzz E` !a#>cR\]R8B':`ޞEEEyyt9=O&|>dNǦEEEX,שFFF@VJKK3&)|Ǐr掱'NL1ޞ!g#@p"ʇaӧOK8q,wONKKK` HXuf6ZdG~{egn8e*b0%5 @A @  1$T&(":jKɤ)iS#ghָ6 @A @  1$bH0`SGLdyy1p8ۧ8Qݨ ĔJeyEE{[T2ЄD*( X tC0F  1$bHi &f~%^ z.ӿefP}Kڿ> "vJ{ S6DayK4$=b0p}h4,?wXQ%Bҟ>}NH %-qg[Z&!1H ;_UUU;P{[5@\|tvv/h4wyG [S-=1Cv?sO=FIv=8=ϧ(r7tcBO>λo/@"B*:NE$n$k@$7xCFF+jc7w1<O=^rՎ;ꪭ=zՎ#C1kNN.ѣuyy4O]V3S \T*ʌl(PFFu~m[s禩~@ slxŗB>R{HU3rᆯfYR^fT:.V1^>/]wFS_"x<BY^/!99!gg{w~YbX,S5W_{i6n~}s;ܙi:77wz 2ZF?pH$ W\=d 'G׿>;oxJ"ҋ vM[ꎽ[oH$zT{{C?66ھ?ъ()b'Onuuuw~5G֑t]riiiVadFcOi:55lę^ X֩$aƦ96pxU񤔬3ԉ(*Y5(b`0G@|Ga1 0mt/ߛyˊvMԽnB1F^Cl}$>KEA 1NZ_3  1$bH0` @A @  1$Xk$\88@Yil]jj,*QV[\1MIbun]Y"r H /XBTu7=qo$hdU<^-Ó cHIM q OקD4$m8I+Uy4͛LYQ߆6M"A=QTYڸp^i&EnE|4$w Nǣys? #㊌D̆#1$XM$\H#^ `N*'}%mG $]WyRx<<|vEiۦI'lv\|etTw9rƲ vIYxQ㣋ڲho/h\.ׅghsZfffEEEmm*MlF<~ϣb/S*3lή$$m FLՎt:}%K˛ώʏASߓgJ~!\VlڣPw(NMgϟcW_{}b=Ct *2S;9nVwst$s GfI(d8AdxwieCqZ*/\vt!}>BhbP0?l4MQǓߩS%J)zBP,vzRRRHl!(MBr~BힳM|V D|k%b7._{{LJ-[zIKMm ˗U99$Aݞ|+b>Gsq-.-!IP׹n2u ~Ώ"_ jMuEQkW>rj})R)_ x{ߟz} _@(hk3983M@zŋlccd*//Ayޓ'O@"ٳ###jzҥG#8S?'H"2s_sv_Ѻ/>|8 ?s[vͪM$IX.yN:s?n#JK!& yFD< _Q^v^o)L&>Ȳl^^nIS?lg![^sO>r"}|xFd?{lO=pTZZsԾq __/|է ׬8|ǡ1xgۖ́dC }_WS3bO˲G$SSS"JB2l5554M4 =T* `RMMQ&psM-??JeqCTr%K28mݼS1kjNo =`ZM!1>>Kh6}>_YYYooX,ƫ;N^hNtNZcƳ7~++|c-nڸ9G߾Sψⓧ Ƭ):i;<41᭦BHӽG?ptt4{T#$)(|q4Mee=7A)q|>O* + g6)RBGǣ#%^sBf*?/xqig9nW +WT!$ɗ@_!$o ]8{p"15%%ŁSu54M"qI_ħNH$}uE74h"J1p,Nt/xEg[fg D +J_0b8F.kRIQ===SN0:Sc{D""I[SC|/??h|u&Qi~/u:NA֎g099d2YVV˲CCCQ6Z쮝X8أ?}|j}y$E_n{ѡo;GO߿Թs1)V\qhVWWx7 5Lfm ec$O/s~II㪫q(5A' fHKKlyYo; HtLv$z#􌌡e{rrr*++immĕ|o߾}?~m}[oݱs7 kC>8n6B^qSO=zjPxvbY6j-7L}Vںu]B&СCyy?0BuvM4IQ?(ڽ{͛nP$ڽka#ĂGbe˖}TSXX^z-[^}{ccw܁zkE /7>ذaÍ7nr3O?ҥK"nzŊ}Ѷmۮe˖m۶-ڦ ˓[m۴yVcNPFFƓO<=[n}?[x4HOٳ}ǎG^jUڵwꫯI` M$n zW^;;;BaAA^Dw@EEENNBkX,WqA&RbDܴV=tBfG4o>~}}}^~>Bh===>ܰavdj3 ]fȈL&]"X,OMah_ 8_<88cWzdϞ_7rKII#{4=88TBZ֣uu\s޽{KRT*8Nnn63? !FcGQB(C|>un SSRGFGv;[z^z Lb@,17!㱱W}7HCǎ"nfz 7$om~%^_W^{5!HΞmkGGY%'?P$E4Ya?/[VJqH?wrݷܼ^f(d2=Ok()zʺu˛'.iK,2M bǎ{.qf987L?K#{ rd@ zׅBT*(c ]Cxn71<y L't<pnHWVfAL ~YK˗HŒD$9AP$#b8#܈ L!DIy,pt,1bH0` @A @  1$bH:HWJIENDB`RaySession-0.12.2/manual/en/images/ray_hack_launch.png000066400000000000000000000476621417052567600226740ustar00rootroot00000000000000PNG  IHDRjx pHYs+ IDATxwXYOZ *D J.{`]DPHQP:B !c4wu><<;{$f!w@ P>"t>"t>"tx<ԔJh7RWW.Ĵw@ uuuS3wT#RVVF@GGGGGu $"o[ȸK[5{]*&.X.j?"_< O"q8AA#V^@Hd # xʈiE1Fiiiق7G$$}Si4𯿥e gϜ2S2=N?cƨ|L4ܯW"MWxh8 EEE1'7G-;McGLNI63АLС?jmݻweee,eee}޼q'D=ķq ~_s[155e4h l~466Κ=W2+ue#v x<' FTjmmm x**ERdx4 i4ryy&,d2YKKyV@FőJoۺEo$,1q-/2|@/+/߼ekF{QEE͛{2p8!w.L^nw6lĪ>zGm¬d6uYxaݼykIdJ&s>P(C }߼y ?qسgW^6 5m466u6ǿa޽6mXO$tzZۅ}vܡ'4MQdܹφ FRO9{JYY_z*Dڶ}ǽavÆ.Y]n tivRn7>G 풺:S}=S G>7]5<{GgxB͝C\=-Z}N:vԝ0~;Z@8dk;݃=|ı3ggd 4pߞ!w?n,ڽ{[Aw^Y8p8***Kpy.^ ᴵӣ{ѩ`2xxB LJH$5u/fΟ.WWW߿wm;>TPPo߽;w.^+C<^~Y\r |0ٳXtlmK'HwGʖlarn(32 1񥜜PCn"!G(+)M0JVVV7ϟ\{. //E_{{;PPP U i/QU8hϟDE zo^RRRURWWRUUUZ-ge˗/?f>X`Axxy???}}}]]]qƅ8#K̿2ihh JKJY oL5r0lCf0W fX,g  l6;,e"ry1&d.ιrJ*ǡIE˒***jjj{aii٧OW^͝;rB͛7 &L2EMMMII)""bٲe4MUUqY~Zt*++55M uȂlR(*PYUuU`^an9q<{j ƳX?f-_CNrYxK\z300{4:i>}ߛ}d8>Qb1DStusA G 'T]]]iiʍ7DwM2eѢEs̱ 533{.\pǎ65j߾}SXXҺ ^|0qxl(ap<*j<>~1X<D͜9]QD"E&NPsr|gqDѩg`*)*@aaQzzrsv|>It<,߱cG)%*J[=>b bϟ<LP8lv#8;a#sKJJƎ[ZZ*&FFFы-1cFEEӧO8ɓ#ƍ y<޿-I׭mh`/[J?p׮D44#"~[vMD*:~3gϵPUY],޲yӡG;vxj@ 2+Vn.ۧLEE#5#G;gVqIrbBbl61x|tӂl޼|9/?~h}]ݛdXRR2bĈ~4Ǯ]>|8s̬+W4c##={jkk{.p2ڿ"(Fzt:b5$JJJ?iSǎ*ƺ#P( d '䔔X,p!VxxJ}}PU\X_O~ڧOe'--իWBPp80AKT *j.ۜ4`p8 Z^-D H.#od2y׮\  dMMMWW̦mGԹh XT[ ?KLY455W\K R$4Mr{㿅GExz 6Y,̙3easܹ{vwwo|rMM-#A>t>_B@yMMMCCɔ\1˗/+((=zxxxܼyQQQ#Gܱc/_:uCC2R g-`kbzyyI"_>Jo>>|%%%˗񇅅oգGp8ٰaÉetx F݁ jj33Mǖ|M/khhtRnn,,,,,,@rbb"@;te)tLLL?@ Z:R#pqqqRL&3$$Z߿'"#"DFRUZ͈gCѐ8"m|KYYEL$nZZWf|ru 0`ŲgdX-bw7R#~D  ΋n}v…^^^FFFd߽{w$X}ʒqɒ%\.FX~۶mϟo9@ طo_BB˗9NbbB9s F1cFycccT*@ ~O7oǏ8Nsz__ߐFXr F$//С-[г D"DjÑ>"_ W^}ܹiӦ-r/^Ϸp/4S72LR'Mk5GqwwRPPyDȀ:cǎ'1BKK`(++>x𠴴iӦMF$i4Zffٳmll444JJJsrrH$kG[ˆ@ m)cccs=~˗?~,//޽ |p8*STG@@ ~ -,pvvvvvvRs54[8</'''Qoe751fmm% & ۻgdɓdZ(|aΞ=|͚6CݻM\ֳdb[ f+**&ݺj hYbnCqzzo)(,lq ]v EA1,㋫V(:yb¹sS0+*޼y#+---yy <3ݻ[Vd;wӧܚut:]__SN$99Nc=Ŧbb _\m[A/^,1Fi"H&[~mcQ^^I 鲄G.2Y2ÑFq8/!zz&ZZ؟$33ӧFD"~2Pr5޼!Ϟw?͛VkW&@&׬^`J<<nj7O^Vļطׯ_>rfdxXII3 ]py+? `Ϯ#C9/&R2mٳ"CD0vսG{wÆ+WpTڵ$ѣ&&&7nZrը#VXY\RO$?ajjrk}|co8pMH$҆ z315X뛚[n#<o5@GGgLL^L\v-$7ofgfVX>p`G.]|D jϟ>|ݿ?AXV6ڵ\lmeNO{tήVJ⠠:6k+;cn../JKڼyqOZ[[{-{%Kyljjr¢ uttb|>@ s6W:Xl)SUU->#ZuqvdVRT<os gPSWg(ל fF֘722ڶm;D.K{h+TjQqh.ZZZ6^\\UTT&O8YOo:'&"~,++۾}7!(Sh( ! ˗EG|{#G snn'&YXT8w1j55)<_tA|t~^^nml w(\?CUeF#3*&L`ora2ڸigO`ҤPUU%~y2Cݰ8⽕ :.%%Çŋ=_;kc>3cHH?p?LE:9?}\5@V؄yɝ۷Hgߖzjii@gS'O&`0"z27UU T f7֩A{5())9;;= 0N8MMCJ666l9rTj5t왉@ |{...ufr{0猌Yf={Γ'O 5,i**P]S۱c@ w^WUU=~xojWbUU5W/ɬmn~:ӀѶ㢅 -";|fxn hV\vͪ+͞:mzccÇlQTmm-6Yl{L&AT9==##}蝐s?{+"zJ%EňEC---ڪY׮ߐ ŋ?n8[|Itt]]ݫWmw7O \| |zv|D ~WUU\(#JJJV-@PVVildI TUU4W@̐aiȜY3;u>Xb͠ATp6|yZZWE$͞'1^?[]VV/!Ey2YS[oDeZ 0RG)ln:U]J$Ŭ]-|>9qlUUU2fTSSrj///o_`DŽUTxHIz;@ (..6%[߼+y'+&sMB~)SӘLI+3%ZƊT"z/bܸ1O #"#~w,o MrJj/))ijj KkkC ~QQFEf09ٵ b΍tƈB2#z~/֭?M#nUQR$*luf?"QA(¹ϟwϟ%[BB~#hLINNQI(<*_"  ^H%SZU0,"ѹAkGGGjin@ SS#eߑ IDAT4?# Snf;_CmMmzƻ_ G lm _#t>"t>"t>"t>"t>"t>"tG Hoe(`㞵^0&&Tw@uͽʺ]_oGCCzg1-tLLL?H{5/BK[48ηFC?B7o}?e>"t>"t>"t>"t>"e MKIT+^w+Gj=hTjiiYrJ inl۱ADY2tIpcnjy]VVħ+mMlݺرcEE^@۹sgKiiдԊ 铨3Lɂ̌>~'Ѳ0L&W[C߾} /?۷|>tzVT*$6mm=@@VVVqq1sffw|nG=fjjKz@~~ׯ_)fLf Ӽ.;;K<OHWT4ׯXacHe\v`7oi&NgLoM&MHQWCee%JJJbڬ8nǍ!̠K6oV?N&^cDb^{QLm{k޽+++SVVnXˎSACFz ]\OBjd0*j͚՘Bqc'N?t 7wla6o`o'Yֶmۇ&&&銽Ǐ2sǏMZZZzz gjfvׯ;Ǐ] >.]k{VbbI$;n`/],77g"..K.[fMHH0V} zp?^PP:J,^GAnaD"1 0 ?˄ㄹ.?Әaq},p={0Yuuލe˖飖< zzzK\GUUUaoҾ02ElZZ%d2٠KlolllW=Խ8~X޳~K!H½x<^L˅Tjmm0~jZyTԞJ4B#-_ߥL$? UH$+WC-**~䉖iihhܻfc3$: +<,}#Gx<ޱzꕜ}= Vݰ@$\.+%9Y(/ޱ}PL>Ә5WcD"<<21Q4轢E۶p8:^SS#]+((H[ܹϲT n"ܼuh43X"rSFBKHG p8*RWW/p8 "$mp'O:uP dkDF444 Ƒ#+bٔ~۱.)''7rc,kAPYYyߥK`QD"1(dY|+CRx'QxǍ,0G߳{~Æ̟ڹcڴݺuAdDddhQVRR6S__'ql[`wB'1`K= {(jq&==^ ¥+C\dX[[WYUE$`[n߸b;d0 yҹAׯ8mǍ^K8 N FucM8?nLkO?wAoڏj ?^1fy<|DCCtugr$טquS&OZlxc Da}1!cgqT Cr&G"j0;w,Y͛dSSOyKu]Jd(33sjjjrrrRmLLM ~m;dg߽{k";wnĉC-Z{.1FDD;ȑᢃF>>++3ׯWWSqzee%k.^jڱӹEhjj17>|hlda#dm[6ǭK/n߱s/zijjgb2}}c %ŪJHx1|ĈWh۷ot3>h.]/avv3gzO4Ǐp/^`@@cc׬s&""Դdɒ#FZv/\r69颯o3hXbD"aGY,8nߢ⮆999E7o~}Xjc23{Ꙛ-7gr4* @`ei:{μ &suknmGF*]N/^2!\_? lX;6.n uttv={<_)a㰿)'I}`Ub#Ν?@YYx:::5ZZuG|G @`klk| KiknFF>}^%y83:dHԣDž|ʎO:dȫ70#={(,*~hm_ ^/_'55q'Mfs+yL+w!SWWGKSz{JԬH fiI)CU\^^}ry-gkjjceR_^p:X۸dqqqn8w克}nݺgdlݺƍ^6kii٭[ Htuu;{ ܺussZ( 4tJJJ۽{[v}[n =]4 46 h#F._ ן8yѣ#8nhN== _tf,:uqS3Oٳ{s} o|'((HCCW^աCl :uԽ{i&HNJ`̲g'tɁ#GO1ep"{nǎsG-huҥئ;!C+7ڳ!!!^::ċB"ڃSM366'BQPPRi55@ жoC  &{Щ1buқ6MMM?W'uD]oH|JII8;9vdvڼ$q9kWQPPع{Ohcׯ[QWW^bu-7lش{׎cp8ܳgн>QZZbkV\liE;VgvS49ٞ,9qxttZӧOo޼O'$b<[-KCl?upS,޹s.ŢP(GI&WWWoӰK.kiimڼ)..ÇI||޽֝9s^ ]\e9V555[l%%avv#FPPb'OSgdDK]uڟ]qcǾ}hbjdd|7^MM EAaqׯ]=ũ35u|=kl<TSSzF7Gr!5[=@ -@ O'PW[S\TA ~ m_nDGgdv35݁ ?EmMmzFkjXjjee5֗["}@ HOQ //_o%TW^xVO\bǷ2OӪFA@ @ @ @ @ @ HǛPi_@ fgjU111TRTA =Z:#ҡhHW h2>"t>"t>"t>"t>"t>"t>"tڰ>\WWWKSuR:::o޼8p`JJJmm-ucǎbt:8NIIϟMKKKKO> Z[=ճyqqQIIhJ]]]vvqn<>//۷z@ZZ0޽{WVV~Jz033*(ffffPZZ)ׯ_uuu;齈h4SSӗ/_v+Ki0EOOOKKK4EWWsbGz@}}}JJhDc藛KRi4ZFLXjUYiٹsge1n'uymRڵ{`݋F$~pts^;wn4} ZGGFeff6VJJJ=b,]AAo߾jj굵:L&ba)/_UTT;Ӎx<^yy询A}XtprB@}zի3ƎscZ]]ɓ 6NׯvbpW/_H.gy RcccN8~AfgQo9aÆm޲Nk^~=$$$_&'+*ٳw>)){>tΝcǏO0ݻw0fXYDsҜ%K_ǟ={FhI_b6}%K;uT\m7~t鲵k߻o6666ClȸHc N6+W0pAjjj,=ܾ{fN>{O 5M6ٳlR_GI FY,[@QQQUEU,Q,bll<{|,V~b9::u31Yb9;~<;;lb{Vbb`IK|}sssTUU{M4IEeL3ʹ3fzwĉ/_tvqӻDh.Wzzqꢢ۷o>꣪E>/_rrt,L&<O&eBNNH$bYp8J`VWW'vSSSQ}# b+Hvd`d2L`2+H$+WC-**~䉖H,9H$?a֬{vyzy>z;Q^x_G%k$CCC,q]])pb,\8yDIуAUVVDc)ׯ]Pk<{Ϝ9}i8~DқS'OP`0~/^>|ׄIIGr;pa) JJBɘL߁ GX.'NH_X,&L?!,_r3m'O(M7bTlo`]W77z.//u"%9YLBޥϝk.\L&dVU GE½an..k׬;gv+/p 8N~7mtws cnjmm!̞v[Z   ٣fommu?nQ.NXbHp1c }aT8;9,^l55'Os{w?\xMA@hQӻ|J˗/_n۶]tWeeeee%TTTX, q8?yb޸\7o:vmɍ9*X 8h3KQDbP-Yz1{䝆mڸ6hϞ[m;wNsV=ĄĄ6}NMa2q2YaݣǏZ.;GKKȇ'|jjGH$O>;w60;wlܼeҍw r$טqΗ.]^l)DD>t;A~<=JJK\[PS'On߉}ջCEwlۺfL񊊊233Ϝ=QOONNN7ee!ئC^^^Nvݻw<=ΝܹE%lMM~,Buuu#гg lH.]?qbʕ32s۲V153Ḟ:gll,L'!!MG'Ǘ/_TWիbO<8 Q={v`mo7zS=7pA^Ϛ5v޳br̟7TZĂyԩӦN&{Ҋ._&tܙB`\oƍ˖-nSMb=kSv)v n ___/֮l+2c^4*EByhf?r`aؠltS9ܼy Xՙ=_/_t ,**fUp9%}2޾\W_qquu%=kooG D1ϝ KbwvA.( >|;ϟ4qbLt;v1Kyy{GD>x$˗/a^^wB^h`lvCAGe]S]]bNrժ~Zp۲V1b0d-K$ݳqf:>-8ӷ/F{9ÉmBp{Ƃ-6\ s}}@ rf l11PYYyő#Gb22d~II &F f >t(Gfy{;::G`W z b%VUJbD!66Ǜ7m,ioS޾|Zl"wy޳f5wp yKM{;cPe0_P'}}p8MMM4l72?***> <;|(6UPX(PWSx/UZZ&՛PYU<.k{3 y &wc1#"OtRY] OdVThi5 Xn]iiի^HHHjӲVw##F._/Չg@^'xň#={y\eY ӧ^555V-6ZZZ%'vP##m۶Iļy;ԋE#UZRhs=s$F'Vmv68pk Wx|Wמ2ΒJ :oB᪑ #fV2EWB< ]555\-?dΝ@rW϶蘧1Os`޼VH30 .] 4 9. D®P 5%U8@ #oܸuȦ&Oχ2lm0;9y<nhi⫿DraPSr媦I eϤz*gd߷on$вd w~xuSh4GG3 "ÅYBBΝPc޽3c>߳GwI I&7n4if9_w>Z@AA455>{r(yY]$%R]d`hTUUܱcuŽF}}ph> >P^^P-moǬ"n=7QqNN***нFXzaaq7cEE:enld${|bc 쿯eҒoFvǎԒR.&N1 @x<]ſ9:uqS3OO^~{@pw}ihhK8xzx޹"+77k׮nٺkt3jb+W.$ڵ[tH$;$Ag!"A;|G}T[@#>|h{8KݡCI'nk̢NQ'O:>qpRլj, 3~"̬gOs`0V]Z*ؔw1MqZZ-}/AH /l0K4\b0XL)P):!ߠf:E6QBqGBhqw}݉Ĥ]7H$L#8 ;TǏr[۹?INNqαc%{ݽ;) _s0v a8ǽAlS\c덍MK sKe$;.lڴ Gӕ.=mVP{"2?D1;jbb"9J`?wīUkkGotg%_|Խ}_0ڴ/h4S4}~ST!/_N8SSSG*~'nm*wO&mݶ'mO ooᄒ>mZڭ_&Yyy#WΜ ˣNΫWڴl xN\\.+K.,; âo:]yw0 ۲eoaԽ&.]CEEEqU% bb|s.E͋%+rFGmlkZ) 2j:G%'$Y8QQQW. i6NU[[xe8~j}WW;ve=  ds>xEjy=9~ ޸K H$'^iZ3~\Q4''.6+ֿ=~W_5x#<|WX >G1 z;*!(fs=7L Uxi#{z]na+X >G@hmV|[}I`'əyo2<\2s` #ɱy#}cΠIENDB`RaySession-0.12.2/manual/en/images/ray_hack_non_saveable.png000066400000000000000000000212031417052567600240350ustar00rootroot00000000000000PNG  IHDR`{ pHYs+ IDATxCIThdvgI63Iԉ7nPoCMzzCF3Mի_WU"@ oT$@tHRp"@%ZIfk@ ;ZO6IH?"-'h@ A*@ :T$@tHR"#HE~?ѾZ,fŢ}(aMӭgg6[ [* FA*! h_''cS.4My-~ fZWs3\c'$AQ5 TCRu830 Cn6^Tk5v~N ֋8鎁`@+a$iaaH&{Jo-Uȵt]PT&'hErVg]F0oo0w'GH$a, {>6qBj2*+eF- cv2%IﯮjujyxEiBu8@.WX,I&wv5 o #ճG׷8aws 4vm6iS.n9_~l6)j66vwgl.OfBQUթbtt|B;z-+!&c/H\;,J4CB COo+UeށF|O G8;RR*WVQS^|f>eEJe,cTU=::v\m@Q@ I`)fh$ɲ,/ è}^nS6k2}Vk\X C՜NgkL rVʫT*,zrNp:F\x^(|6Ȋn8^yt(pY(J?h-¡}?8TUqQl2A#7$vR{zaTUDšYKZ%ϰ!4M"R@uQD/@#]QVz=r^)NחLv qA$$ iYG} mebSCC''@| s]>S6 $ ð-MI}s'HD붰~.Aw(5]*"E獯ee9jC%(KWyaX߯Z45 5p0Lelv8Z\kcHE#$*PTV@Ql>QTf34 YB0࿿0W*UR{nl&''jZ2&&~@&N\3S^$yӆe$I-LBDI2>i%򅑑b(`cs{b|?˲N[!WS)I%{v{<\kyh$Ym. $l6(10 Z 0"wu qUB:`cK b'4"x|bᏅ{dE :mVe) c:\B H?~ǠHR"#HE"DGD  @ A*@ :T$@tHR"#HE"DGD  @ A*@ :"qaMCipTaR⛧W9dsJ.vp8Tj”ӫͲ^#R̦ p@ .y9i|۾m*?;; `Yɓ'-k`~7:5? 1 Usݏ=z ]vw nFmkCCC&q:0 HZm D$Lakp4ͳA{a J-:5TUA^qөT.bVƀdr\tzjwf^?~~JC*_%Fu$I D(wp8Td]\5 aA\XЅ $K%Q 1 0sKX p>^A,--uAZCI˲Bm X,P._) ] =Z>7h6T!p PTVWW/ N :;;[*N4 OZT>|xF:t:xqUU֊",kccT*qA|>i$IfU(ǡXi?Z{'bhdcYӧ>= |j_ ?99@arl~Xp?==0,|ayyt޿ӧO/^0laaapppoo0@n͛7,OMMhÄ۷oyF۫ <~pT*އ7oT6ؘz=+aqoVDsN\~=apf3EQ?3aHdccP%sIћ4M߽{Ǐ|p8|pppCt疏|>o6-K\Q=~q$IVl4AڪT* 0 399 pi^ z1 o޳믿.lci ^Wikܲd(EQ et:m6nXfY VU;%Dzq$IҬL& ᄶZ>p$Af(rPY2^r\VC% C. bV.FBm8иZn{G}Ue(AFɲLtmĶêQ"Dr\v[r:k- lICCCp~^W! lEO'~|>_V,DnJfEpF \xAmh=bHgp_[Sab9DT*EӴ$I`BӺ;Nmm^ 4ƸDmEQp1mĶzaJ: }문:/W-q4M7ͫԀ^2'_hGW@+Qw/@t"#HE"DGD  @ A*@ :T$@tHR"# ڽZ⛠W9dsJm4=#Mv.L@ 8:,kE?*lWpYM=N`^P(_Wd2?{L0a}}}m^~kH",>yiq|7Srhh'r:jRo0 \*oNdcl6Q{ya;(C|oQ㖖t,|%$^"L&ܜ>5Bt`7@iaT-zUrsǏÏ?iPmc0l||T*Iݕ&IaA[tJy!0ƼP[ ZO f5]?-խW,aټ_sٽ q0̐_?[PUUEQ00CiX( Hd{{jn`p8<5iI0 Y~aa0&AxT*P7 )RVU#9== bO2 |>mn$pxH$J...q4FJf\__!!p鈸:"1 UUM$[[[~^Uw?Y\\!="P aL&ꋎFfŋ ͽ|RUW^5 FzCЛ7oA333bcxDQjvJ%UUa4gl6S?c6;;D666XM$KKKbd2=|T*h{Ǐ\Uՙu _~띛QONN`55ed޾}|4^]]e0 aA0Lc'&&677cO_jjmA t\Q-<>> ԭt: |>oXzzZpp]UU].F#L&EQ EQVZZ,<.0h4.@UUVAq5Z<@ţ@ pvv(n'tiE:4  8onnjxzeYLK?\O>L&ͦIfYӏr'Ijm6<ϻ\.X|>;24'}>_&Z)u(^4Cl.2P݂ uXIߟNP(h@AF?/+(>\.;ծی<{[N߶,yh+###=* 0 0ŢPj$9W(Jh 9tP0N58bv,{vv8M.˰`Ȯ4 h0dIi{(N@*ں۶Ѷ9Y p ' M i"akkKDj{)0@dZ;$ ." ܾ4p|| )#RmU2]sa4"V*J$߿dbt:^R^gYaxtkvB!醆{z~:K~{/,,2 e Y -$I^E9MCCC?~# .rV$kst:t:'Y1L& Bj|>/ }}}PM(_30\, ex rPY2vHZX fV#H[/-bfA_ivH ,vtB<χFax@v Ȇ @@\.@o qZ2woxVk4Lư\/<V_Yd2h6DB:>}+TUf8tG AO.a65ĭY,r9k0+ sss ,//GID֖pH$8ommn*bϞ=eYQeEQXXXOr9CYI4{b"[*Y 666$I'oAXYY$48m4b1T*޽{$ZTŅB^?}Tru{2`|~޻wӧfP(jm?>>N$)tl1J,'EY\\Tegg'?}TE2?Qk;66rAi:Lj볐+, N[$$XӸK^X1"o,2:}q{<\mDbʠ!ǕeK#nqW pצ2ؐD"1Eŝaм Hwf&#GPĜחWF,vt>>*PQVM}\vMNv8pso͛6ڍ}h47sYͨG?E]6#ݣRffVRPT6uJ>&`I߰nG:::*6n]QQai3gֽyk2B}-N˖޽^ 624ع{䈆5 @EYykYYΜ5W GA6qO !"" H$<kt]]I'xPYY9:SW4 L&SԳ"aCp8yyyl(J[[[chkiyjBbem[Hnϝc'`JfXmۿg>'>~AX 2/ l,/e:B6G.'W&&׮\ 9v䰼RZ-c##̌JJTAAam11QT~\.7r)1|pK$  9t߶L8<=^xiOڰiKsKʪǏK}D\];Y˖-t^]]c^,&{O654,l& 566lcǝ\\=͝U32OU"xq+%u\b?(x]QQA˖,a4eeX%%ڨQ'Op|rN.\`e9Kp ܼv_|e)W.٠R(uuضQPߘ{'Go,,._\WNu̩ϥ=?pPKˡ /j$RfGs;w1w-]NK/f25 #cȔH2dHeeŐo,֮[㽽1W% 9raavv;3)t zQѻ1ս{N6WnٴH$xRCCg_cclmFmް>3+[РN+Xwfp@^{&[lp:Yv˓{Pe+-GiGGfɓб;o]4773p8Q1niiTFffSRSo߹cf6PP4-V,6_L8#K+Q2s'yBZ[[lvEe%dd}(b=++2rsW,[B__)w?HvD"YZhѣm Irrr--Ч}xDSxqqSRHcllm 27/,,4HKKwwsSUU 0Liii*)gJS ZZضހK™Y9eewnjl9ͤ`eQVVZ[<D"}c1d*2z簈N6{ƴUcI∐!d(G$nݲYOOL&'$.=}mjj\CKS33+ K9v DE655h.>sou`^EEE&ϝ;!@\|!CB SOQN>e)' kq(6,kbшZ45oݬd+׳sn;-?OI-~rnp#rN6XT\Kԙŋ^xPPPv  kWnimUTPzܹ\c'vmOLJ\ > 8#Gb4=LV$B& //OњEKp8%@$44tD"Q(3O\HTQQV<Un9ECRIgRUUᶶ /vUhL&+**(665ϓjF$֕LqePW"kLb{5tuBbX,*?alࣛrR`RZv%]b2ۙY}ETUUO?J{NR?ϒ3}!>zA(SA@ A@ A@ A@ A@ A@ A{d"8VIIOܒ֠HeۚڂnUhjmGۥBkQeM`0L_1+N@jY/2GGGGYM|}!>"xdy~Lf{iii4-M3OzOr=^K~}LL۟>+{Y^m`,Vg|3c##ccC`o\~PPؿ2?ˊjוUQ 2|`UUrAWSVVnkue͛6ڍ}h47sY!C:X%¹ͨG}ߘ+Yfu{T*lيU ӦNL55֭1QGGQeUΘdi߾Qp9zz%vpݓOM3w vqH$Ҟ];h4_M_$HeG]]I'xPYYD"fi>B!ڋ!GJW4 L&S4r츓g^~޼s*WzFS]Zxq+%u\b?(x]ѷ!ߴX죢$dϴ.HOprxZZt#CwsEb?yy'}.XY]n^BM'O={Vlt)E F/37:XQQ5 FDdr>nCdTtuu5$J)++--?00KJJ Z-- qs.46._6uJK<o6J]]=mddppxQcᨑ#Fx\++KJN˿h&$&Yno7E}w!IQQVM}166ƶ @kkjbbbm=TԸ쐮ηIKKwwsSUU -Liii`ijj3/[4 m}=<)+{sVcc#,ENN[X{o, &657^sLlEyǏ{; @6ZUTTd28<ܹ<~;\]\Ξ;v6oxT %**: ;>>Sׯ[Ccbq'.>aȐ!a!AMMMUU逸(Nٲyɓ@ٺXlmF-X>hijnߺYQQlqWgv[0m[6ݰwGrl2YD-?>ykGkjWyߥ1qìn7!{̀319rdNNN/FӃp8%@$N&@PUUp8UUf8a[.vKW!H %DK$UTT$WVVnl{vmPT*@hjjVmmk FZGGG.B|Qʠl5s8$<Op1JUUŲl6p`Qq7 f .ە8JUJK r@Y}ETUUO?J{NR?yv_!d$L7ʞ?whrrD#C ^> d2hCrTۓ^jYA6 Ŀz-_!d41н@He^Ћ8tzk+_HeQl1@Ӵ4gee^bA(SdffpIG| })m@ vB  }D  }D  }D  }D  }D  }D  }D H>{DNo@ǖ8b@ "G-#)$m<j->ZsxA%#ZNo4̻q$7k1qߓ*κ to"FGG q1WLGAAa)]pG^bzĵ+c]\{$O4:.Hχ6aϺ4>lLaؾSxhijFExϖz>Uennޯ)IREm|TUU=ԩTzTѣI$$Vd$-\=aRZZz)NtuuxJW~Gqbf6x FUUQq%_04ɟFya]" :::wcG>OH_kyyy K,ibbsbK,</)+)(**~Duuus!X'x<x$IzyBH$vFfVGGG{{ F\0QT!<DۏD" aUEExWPE)~#<ߕ"6i>&&&b 66'6`j\b+| 1*YRۚJz9L&0h4~ˋ^D"O#DzeFF9?:㡃̞mo}kltxf7cTDXh[IK,,7oSt:QZQ99C QJJ4M~MJL jnnY߰|#.6ZK%ギ$9'xhyJMwrL;?|?SGG';3BoL kkkY^ac3\WWb}>W/_1Y΍1cFL? ]8w&,$(1>n7ͨTo/O B7ȈkW.`;2<4",4"<1|()6,$F`1vv\T*VMS7&2|S:zs 6a7ceVRbH2,$(0̈́ y󦍋}\|#fbݶ߷FJJV~#[q1Q!7LMM9uъ "";X[[@ikkdn#Fܽp̚3{ڌg𽞮.D"p~5ó|vvv._g~~<<[ZZoXGkIrr[6oeͺQw_VVw۲u򕫶lބtr1ggHH0++,%/\`?q݂EF&ή/_ٿoOÇή&M;{tbCCWwo/ɷoJ79~X ϧٖCÆUTTcZcm="3;jjjt:Bijjy:7W .aC6cm=;tRS<}ruuuZZ\.Ν;#3gZJ&dz ~d@Zz>ܹсNx<RԬÇX/_ "CKMM{\]\RS ˳Jv6ۗN߿FϘ1ʞx<&ɔr #;;; 8/]bҥ ()R^x EEMMzzz0nCdT4e|+LDiΎ[II!Q]c6Ornʪd2((RtwwK__\0EVƌnin1ۗ>|xWioou832l |c*+sFԴ x }.8;9{KbaUU|isKǎuHȸn}NX鳧  Ԭaw5 TnE -6-:vuq ׯ_jZzaQȑ}Q+6lQWWommDڷqj1ߦxUUլ?/kWGGݘB565˺^CC44{{%T96):]t){hWH\WWr"cb͛j>.M]]￾vE,F۬܉5EEt~|(mnٴH$xRCCSWW=DYYnm`^dE2z1DkNcnkk55 E+a?fΘ{_}Cþ}ݿϷF77a2opWSSy\BbDO3ro^YY&٩zԩS&L=c>FMozvj0g,e%IxmX6=#)>q446]p)BPP;s/4mmBqjCCCeU%6Xlk Up8/]|)S;21$VFKKƣGFs?:+;Յى i322͝ )d2pwSYb$g3'e^x<>?{2x)55ӧ$%GeHS3O"ĉX/JJΝ3p8܏榤b`vv9SnpܒDݘ`myvv6ϟ?ЉD0DBւ>Yd16NR)|kk x<^EEEJ| ǣ0*̜>}@t[@)IKKwwsþc,,_qkk^7^WɔR^eNm-,㸱|'QVC\]\H|ii}鵵j͌,77crI YHVJYgڪ&"=]gϞIGY1mc#ķ3)&ƙYUETdxXHЈ3x/]>F]eq_1Qase:rܸ4pА'OZ[[Em23|itqr7mm"Bo'h`F5vcbr3)M-߾}G׎9|]`SlǎKJwXnYJ͘~}VTTl[$Ǧ$ߴ3Zzvc$%_#F?z8BN #y7i ( q a!AK/.((`|-0p֬zyzH0۩g.pH̲b=G :vHdԻGmmm)i+Uo߾cee)y Qf?/KM=B.Z3&66=#3<48<4x{sorRb`+/y0YJ{$\8wF#nLL߽rbȑ9]tv̫'*[PVVfٯ^usVTT$Hj"H+vp855V =j[["SSUmlj\4Y4͚FfL"H]U>Jrc|i ( $B4669}2 z\||WAUUN`*+Dc#*** BuUUTɛ6cί\xX1p8UU6-$mb[[*t[d2,sB!^e%%Vg><(8s'JP0V#07nZ(֞R )V%LLy<,ϧQle1BtH!ORf-k֞bX]=hkk.M%DPX,`%s8iQlll6[\.W>cb=V䋜54Ķ&~b2]M=Wg3J__ 2wHHZ Eq%8.bD >FF'%ɽnoRG ݐTUUOMk;W@``Wf򝝝[%-AdePZ}6p$Go6C|%`M]^A]]SO $1ka%*~qF $!$g3L @#@#@#@#@#@=}|]_e@|5ozo}834JF`˴*,,ᄃB<{i IENDB`RaySession-0.12.2/manual/en/images/ray_hack_test_zone.png000066400000000000000000000123051417052567600234160ustar00rootroot00000000000000PNG  IHDRQ5Ĕ pHYs+wIDATxyxSU]4IӴI(i+.Pu6q,2"0:> 2" (8R6@iAn$mhY66MܓsIܵ:)B@`B0ByEdZZX, PoX,eee ð71mpZQKC$ӆ )+-e'oV#ŘۖNuc!!8`8" G@w]݆gT]Zj}9e@ $ GAVCWֳ輤h5o-$Bw*՗d1B#GčM{i/\.]1"C()*RfOb;# v9ctB#22.b2o1|npMZ`<˕/|Vk G#V}qX ?_EH$2|>EQV||ۄ?8oBu||wmbM6"##[ZZnwHdkk-DTܧÓl,_Kbcc7[@:w칓&MZd-[}Bxo|<ԏϞ`|`w{`++k\llX,Go DDDb]1|iʕ0Q}]3gL'ٰac1stVER76oI6/ǹٳfƾ{1Ye?=~РA>| 4MϚ555C>w{st:ݳZ$H&Ot:7a%k֮ Z@!V2yraѩh4i;UUWWsGQT}}} QT=xժ6}g)a?[QQ?uvV^n^MM-77T*[c Ϟ;&BQr<_\;yi$sZs`۞%ߡBQQqFQ*k]M9N 6#?t}+.^^_^^[[ۼ47hnި#7%̜9C!W,]zBT*j47' j]n5 >juvDDKd2ǫTm>ޯ_%ϽiEQ"H$RiS{oqQQi:>>{QS;>bs/]Ӣ MtttQaѱ'/\v͔ɓӦNDl}˳@<~cǎ/v2LBp{V,y%';?=p,**ڠ 1/>XuCKQTLLb\R`m56tz$zu Db0nfcw{%ȩ~^{(\FO2nt)bN6uwۋߖ^eI{;ϑHv0e׼}7(LF07},OG _F!!!8`8" GB0B#BqpD!!!8$ISޮHmjn45flTTTk[ c|ѣOSc\|Bkh2w]4,;jkI|3fF+- B>s9Fx> NA]9kf[VID0ɏVJ%}B`td\-Ѽ@UOh0t84(B8"/f49*Zj-SjD%c44s> N!2Qh^'#XL&YknNsDpD!![絺m` Cmao`{!9"/!nadx`NGl6_ }j:s ]rLLht\Udd 2oN'N0qJINV[UWjzjAMT2$///0_߱]v`b3+Wm˫׮(). B P*S&ߧhdDvAzŸd..)LrJb ͙9Aii|< JÑJ:sLSSSZZJQTTd6YP(*))vZ\\СCsss$;?`҆q$l ̛vc;N}xsƣyw|~I|~h7%xB8dlĄ@C`P 6811ҥ|/A+:&g\.WBB|rҀS=XV;ww8pjTƖ@ttkVݰTy{MN[ڪg۴=S.v  333+++GZPPPYYYQQAQԸqT*U]]]RRRuu˗juM&j׮]doS&NvS=~'زiJ~]YhaGNoޜ}Я_A^52YoΝ/MMI~see?V\\nj B+0 rVݰݳgrGzƢ~-y睵u' O1 47͞&)0 /zlV_lB J%H"## ::zԨQYYY4M|TJĕ+Wl6ba?~5BAQL&tU+: X,-/;[|}ÆW]vJdrCJM00{OlhFs;lN1|x/i {Z,$$aZ|/=hqj ð#J>oڗ+w g߁cV.dwIqfP핞 BѧP#GFhqDps5թ))@rp8W\>f3nFՊNimm$EϷ~iGSSPjP(li$__Gs}ݟn/:uͭᄎzK/fbG-qfIStuM͇>{&5Fϟ///xt:]nn.g'::o߾.;*iO;.zs4 {ݻq>}˞>tgΝ Nccӫ׼l6/uZNJe_effnm8WhxMҷnJ'Ϛ2uOC{y`I,h4ׂ!JF:ǾJvL@ I99q>U?؛R fϟ?٘uRבYo/y(***n{w A11&&slwNҎI. cb_ָs2u&1 c2q?PV]0AV*@ Ara#tuʥs.e xwh:p"Sͽ@4ǒ1X@!8!B? B71Ԅ.{n&)^(4!8B8Fud\X" \U%Durip 2uh0DE zp8~n7F8v&p}.}tB vϷ56[2 Xr#Maǫuq ޮHup?dɬ1\b4N<ا)‘ ɫu&~V'pm } µ~Ov BqpD!!!8G"bUBr#IA )].'D!of3y#By?5X1IENDB`RaySession-0.12.2/manual/en/images/raysession.svg000066400000000000000000000153541417052567600217640ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/manual/en/images/session_bottom_line.png000066400000000000000000000133221417052567600236210ustar00rootroot00000000000000PNG  IHDR+ pHYs+IDATxyX3 =PQ[jUkZ{o֥UQT\RwZpiںW "b"( X\Ȏ@ sIgf̙7ѻ/]96/s<<ܒ!2 g:hrf5*>eIxxxҵpL;iEQ)4M}͘}uLg Ϛyhy36ohY mY3cϟ 6jC5:GiS __'GGv{Q㝡#xi+(p@ j7ր3# YDv 4kTzo۱͠?;zlܽۃaPRR׿X,"/&=;t^h)g7{?S>1q;myϽY8yeeo-]y߯O}X׹. ^~}Ǘv>Ա#xyvpTCgNj{v:9:q4>pBQWY%[q ޑ!^yFprrwI @x4MWWWϝ;+a+ƍR餉vٲ)Zn77'fB|?FE+m1lw[/\ЩÇ@ ǎ~N7znް{wsstٹeff@׬ ݺ닗B! wBnn>dd޿rZA3Wf?{2]%2ltNW^K_W[!ev7=TZ+|]֮)G~啞=¢wxwZhI]JK\:Dîݙ\S~@igdQ4x6666wϙ=S"6ҳ55b4M;v{988XZZ@Ϟ='MH$:EQOQQQVV, Ν{i! A"@]MQ>hg34 +qT*8;;eܿϽ,,*jpviSߨS߹'g=/ii5փk0$`ЃSR ؟s;?rp~lFO_N^ד5HHL߯7Pegg+YֲC atu4<Åظwѣqz ;40D*+Vkh4m_((.;w?z5gLr횗码oMڵkgaa877IX#[ۣ}X*LPt5MŽ;bxG:xt:aCG- .((o4 6+**Z$72򇈽zꝑq9s'p\.]KGzc揫׶l~M=Cmmmbҍ Vg6oXknnnck]OrrԻW;zxڱ]&ywyhKK3}ƓJ7eLttLtCMMMuu5 YvT*e:kĈ2QS bLAIȜ1t|H(rabp<=`hjX5BQVJ߷o~LK|¢"R)@98d\ Bh8%;Wױkkkڀe333=>d{a<\Mp1%-}˷GUa!knA BΎQ(dcL&kuGr&BHDӴ]L^coǧk܅nƍp OE\E 3hȰ u>l!j" 0[֫ Ĕ[ XQlFbͶږ0hGkeVk]蒭4ƮBHII#˵qB0A㌄aa3O|w;{=bXSR֬ݸ*,Kv4btcb4ΉϞMO9tFՓ' B0pus`!-6uzWQO(a&|r;򣹹9;)]siKK8#s ̭`U8?$Ƙ]ZrV5Ѻ4W k]6hvJǓ>ӿї*1hRBJ-#Izt6̡_D 7ո1}I+;lW.VV;3 ڃ8V-y{<<<<:e`.O Mԥ ӻqpL3sSj=?/𡭊J"#EZtN+Kh+G.Fki-q[ 2&wtx49o :;;[ ͅNLf,Bb`LeDuM JHDU?SUY\T\A}XԽg2,@KiY4M%CLun+ *++SSR -}XԽ}1^{I 0iZD!bfއ^kwm!$ɣއ)*vm}4s"%k A, [2rhfŦ᝙3xsrKBBH(h"p!˱5[,1ċY!АE1 q!DB@!(~BȓQŒCy89ØCy89ØCy89c{߅)#YTb_^$fbұxE AξoJ2g_|ul6_!nL !b4/EݲYwf?Mk(H"_᥸PCCER9MQkKk @R2);'Vp :Xӫ&Q:lG(UYW+r {ssl\!x`%DИ% h:v"kc[tPW8,; J Z7;Jo*U^.\cX~DRnTV#f0kjq'@E?(=k bA[eun^q|cWiTcjǫ^cվӛ7@P5ͅTyŗ_ܭ۵Z L&{ ôcb&MLJJT#\J)@i?4'=Q11Jn-599:zr!fϚ1a½A-fieYRSذwxSR$:2bjuD[[{wO0v?vKXkDZ\] ' VFM?I}+RiXuHNfk7Au w@̧3Lp9BbΚ9cS5sg3i 88h'JKpTqM&N1BRn>5>,dے$w}oc.^@Ys)X`[VV6j xN"tvv*ԔUOmmmMMNHd2?ԔK߯#>yeSe54h+Hܴ2bǶ\u梐L~o^܍cĮEJYTW|1Fatz+-{^Q#ݜ{Dyi˗R9rys#"n%||}EQhizʴVvy>=^Vc ,J,*pQ(||X,N[ /Yp{^d'3a})W_!H͟'82ޜJƲ2eV=3W^^)$$ š͛:}ZBMMm|\lGGGYYee)ɻv~r}h4ͷ|NٸrH:r9xт7fב޳ʋ.9ZMsuwP[=] Ւ3Ey/J]]y/Y0~+ #l6'pcLV#G;zS'3*+8צljqP( WTTVZs;;/[Zk*u F/͇2p_@Ol弖r$]!ƹķp|?ys5+09\~lYUUTzXc<ѝ92'XR[MτYXtɢk26wvw?QzD=ܽ-w󼹩yN#oYxF|!ljDQBpz|[4DLw WA(:ҰsImGǪ>ɵbb&RbySNkѣêscEUU4MB̙bL6uu޶uKCCÅ !?|СUOmƳg&M(8t}7Y jk:'J,"kG|#,Ǖ 5k1}Z'O@[[ۼ4Msw^ڊeN#2G})I1&7`]NZi] ka=Q(r̪O?ڛ\#>X7ϸ !vGFF}`pID"TyaO#N]]]6p7Aiq^4h]lEgHlѷf66N$=05>>...nʇ>۷L&9vh}e~Gt#cNٌ`W@2ċd+-WM]}d7!JZ@&Y:P? M$!0Bc!0Bc!0BZi~FIENDB`RaySession-0.12.2/manual/en/images/snapshots.png000066400000000000000000000604611417052567600215730ustar00rootroot00000000000000PNG  IHDRRXA pHYs+ IDATxwTY^H^ko v{EpU>ZVwA4A}U\B |c: ٽ7o޼Inf&HBvBH/BB0`BV!À !d0Z! F+ah2 BB0`BV!àW嗆}z{wUj3gL1;u F z¹}68t`NGaiiy2 C 07I]֯]Y~h.]8c>?oܾ};/>G~?XvmM5MLy\nVuP-:esFZ6+jKK QF(5D'j:X\'u;cX$P;Zʿz|W?66T*V666}MtيflKXp8շ"d2Νڷk`Z5?~/ɈB puX,ڣ:f$"Mf:f{|\G޽ڵj hmeb1=~"E tpJϞXr57BY0ϿH$b2Vws/9FHrڸ{PvV/_ΝH$ٙL"i݊b]zmRU˖K/R\3gLfՊ6[XظWb]Wpè_IukVnՒF_zm @Zpܻtnf݆wԎ䨑>cFP(@"ǏSL)*+c7oŦ-rW,[Ҳe2QٕDee7D:UzFƭ{v8x֭r|U=vqW_ݔ/ef_z圹 >zԨ/iii֯y3e2u_xͺ +Q^^>ea>n!  7[bULL= r ji^<9M7sIOMаvtl=boqqHsf6d-UD(d2F!}>}`0\NvvΆ0h@rܞ}i4kgLvFW1jtvvΈaC׭Y5hpťƏSf ϾKJJ޶ySACOrvjd7jŋm<|Ddtv8v¤O>7n9'Nr8x% L 䋴jղwrSHD B]E Y3iiiKHN@ю9ܽ[Ad2Gs_tyFpOoCBt *7}m;f͙ 3gLWNnGqi{715jԨSÇ ccCrKJKʇQ~W$%'xvviVDyJJ >W_ofMd4fZZZ;PPPٳ5A׋A'èT'55-:&rrA(`S;]z~dgl'KR(RNngG?A8Tzzn]W\UPP(JOU^񓧊Xg#LH/,,4U))_[ZZdff322?@"y,ء$;'eD}sss[J*N[h7o6t5+Sx=bI0*AN֭@Ԕc#i?\q##%4ppxX,ڷ P *}AaX-2Dwֵk"רa߸Q/^~wO2ᘛ).u7:^ݺ򱶶b0RRRǏCb6EݍS6qppVxZ j[J')űq&&PPX75t8&C<=7w\hÆՓL!?~%$vQ^VNP|?ra7ǎrv)ݹy<=Rt:F+((:uj+mtpvSS>}zgĆKw 644mRaT$qcb@DHFݍݫ'q fX,&.(,dd2yZT!/W-"VVV7cEd2EKV,_\XX`0Xx&++k% JKEc'LD-^bـIkׇ4`cb6oݦOsr-YxL*32b =wb%\UkRU4uddW_xϥ0Ie2+t7n;QwԮ=}Kࡅ]+,**-)`q%!1qŲ%7zu7GnUꤖ(^r8'N=v\l {7 T %G`M8pKʟzΙrn_lMA~ z]Pi|dbb"^m&&RLp33~~P~{^&LLL4ZzZ266& //_㕗b)o_ ԤH"b1״vZf3?_X7rd2D$s9b1 E:sүSKJJngXl#@πkz1h@r}QRv$i41O^H"|aAhp8RB/ hP5ӻS~vGa_5# [b,Ht⒒ߵT}L!d0Z! F+ah_3/kEVڵjs~9h_~ߵjJZu}zҙ Gҿ?w*6^ѤֆH- TG%|*ԔS-9d)U@Tj[P S1㥦tzՎRQ=RKe8LV3=+USuܛJ9WcWYXASX*gt:Nk*2 :n۱+<"rAd2 t#XROܛݻu]0ϟBy;o͘97K;m.=fZYZ2|19..̌;vUS(C״iT*;arffTrss07P([$~Ȧ6RTC4knnv5(rII鸉nj4ΪSjG*R|y^V@p=R_|u2N.XH}j~.6RߏݫgSgu9B cn+ɤRi" ΕETjϹ=Gh3_iADm-͑ؽ얖HfddZYy#߁ȽIo.m(&toI՘+y"++یo2axVHhXIIQ3gL?tkAJ阦oN UEՒsU{P~ZAneER5{S*ȧё"AuVT-m<Д SmKMDݽuMV6ӣO*1M#|T\ hZD5猪՗0gv_NBCzA|DשSۭkxDe5Tۙئ hVzc>]]\ڴi]~{2afT\ {{+Offf÷㬩cu4eRl\+UUsU* c;u$~@Nչ׬ZѽDZ?N9sG YL;_};*7v˗z{{I䋗42,[7efe[j߹m+2mD2F0fTǏ]]&Nibb|/!H8Κ:/f\+Ql#儿M)+T@uռjsU%al?o/2r'ꮞ?^c xbKmMżd28//G,Ng'[/]yaSSӼ<Ϋf /ChBb:Jq1}){\vRh_AP]DmQ9WhX>,L/Ytqff~vGB;Ac+mLL%bIi@}Gxs6. ~<<DV!À !d0Z! F+ah2 BB0`BV!À !d0Z! F+ah2 1P<q‚XIPa6윑*0t* y233׫SY/UW |uhU]%߄`BV!À !d0Z! F[pWߪTEvx޽w a0XUV?<鬦h4Z͕I/^R~\N ];]҃?#9X}T=|`Y{dffVƼ ؘWVV}SS͛Gމ.)jۦ͸ Y<>~6wdw ?zdyyEg vmBZ:utudf_t1g9-ׇ]`0k߮L*}[ oysFP9/^-XruaPKN ٽNؽ7n qG cy6l[ t΢2XqsBbniib2O9{0iS&ur(Jsl{OΓ'P(oGE!y̚)ڷFlSgN9W<}̹ `֭Z-6pظn>hD9 UR{"1qڌ\6oyh跬˳/_2cf^^剣NKO'b֮pu;cd4hDbInݱS]-MϜ;t#D"YYZHv&& H+->lVx';w:ybhh]=:;A$t'7o֤uCF,//716y߬)) 6ػs`p{;#Fzv ߱u16mٶCiTJ?oOvnQÇڵuxo\Q#r1XN@ess²MMM{:ۉ'4aG=~2s'5me7%%%*Ѫh=z1 GZjgBpqv?۷<Wɀ{ +A"p¥}Dj-Z4oԾ݂%>~dnn֥[ffVFFYYٗ._ռJ=Bg?AyyCG8#:ԄfDգ 5rVv^d!Qqb IDATùPT[[="ԪYRiTt NgZzUXX(dr_oOŧzA`SR>}ljjJ+=#ի<-9h@<(d2qGaa]:T*xİ!vpVEGl﵊Ĥ> 8^\R3>B`Pp-/pGB̹ 'Oѿc}[hcblCA֯ 8~L!=w} /_8~8[vD"YzB-_F9.;U\T\ZZtj}=O8z/!q}:MS;I.O|]:a:=o UC=_x>^q*jڴ+XFx<^Æ$&~sѱN:GJ\n˖-=zTPP /tჇzl\uNoݲUlD"qta_#-=-= 4$!!ӧO+| D)<ʨ;{UiEaÆYYY@6_*,*'OI uUZhܸɎ;){yU;$$$L:˻vT\nzr {׷ǏU3f0z.=pzYf ǎ-//g2YN>qGEEi\~Sh 28==l#2\H4m ..Nr\V\zL&) %%lHd?sqq]v?9R^ݽ[l{{ΝUz~{cb55p uA&BaU8NIID"WI$`б첲2XTrKJJ۶m pW׎K$#}|$w߾ .TK7n5kM:ue:h UQV'b+h_ݻܽ{ϗH1qҤA7~i,,,N8yV84hp#"]];ʛѣGxDdppHYgmw+L>cϞyψJaϟ*mEaAmVZR9#GEĆލׯ?9{v! 'O[:j[o޼t#M6N  M4|py#m۶z/B֨Qsa7cb͟O"`5 l61aaDd QF͚55Uvrr &ouR*2*..nƍU6nk-MQ)T&FQܹz{urxw#3:t7vLNN6L޲u[DDK=;u7ɓ!uҹ__c_|à }PC۴iJuLSYY6K)WWɿ:|PWɓ&-YiӦAA}#*ԬYy7n2ݺåsjjcׯ[eY,P$Sn׮]^:8;^ߺm;QmȎ.ݻu֭{>@QΛw-_zU~iԸO*ڤ奥%yyyvߎK{ RȚJ[),P ߪ\􉍉511qppxIڵ퓓;99ՋBzkԯ_CPZZziy ii'77ӧO'zy{@˖x<^Dh*ZZ*YRZJӕP(Tdɒ!C6oB>W^!z󈈈>}<_֬Y3"yzyݹ}[ d΋D"Dpɓ'O>XaaaAԹpqxرZjծSfZ7`iiC׿ cb""cc͛[.//TZ(be"0DO#{DZ|9ZR !NUΎ3>.L&_~dҤ߳gŋ-, jfA!Hpiӧ?v+0zYY. 5jr9))|C׬Y;?%k+_뤧Yݾ>//M7jdqvv@"Mc\xPVV& -,,bT*3_vTݲeR[oj׮ݞ={?|p H$Ϙf:񲳲R L6mjqq>[ FFF>yarrr}c ccVd>|@P;4h(CKU}EC|qF<8:/-0p`z?֭ 5k"N+5 T!FFF"T26bKΝs}zyvZNNNnaa?Xd'/^z뻻@ݻ\.)S^Bd 88A㓒o޼5{6qrj샇?HJ:|fL&{yy[ZZHq'&& ͕}}}T*9r}? 'GD 9ii7n|9l u^zO),*q>z4y.]Ofjj{mD2o-[#J=Ҽys{7999"2(1۷k<ĉQZZp;wd2eS';{v /_" lk_xի'L[&ITvS*J$98o㦍 L\,Mxxxnݺu'LoСC.]VZ*Κ6uGmѢE2K\RD=W[Nm[BBUt:$??_$)JśbCB<ܻC*jbb"uKuqccc}֨h\.W,9.Grss+ybTxD{XGSvRiqG|ŠD"Q:(++TiEf PXLrU9bX5nՎwKii?$nP5GDc  'P:tЩS=BCUeB4 !d0Z! όV:Brxl2 BB0`BV!À !d hjjڶm;;"_*2;(N8 B0heffޮ}7TRЭSu?z03+ofLteK[luС{JJ Q8uF$%%韍!XR[nM6UVjg;''nGܹ3''H4.ɬN>r6nٲ9֭j86sJu~@OO9}<ܾ`Bjg,..&B=KX\N&ޝ4i2dddL>T@E!U<~(f%%ɱ ;\` .YXiAP( mllʹ<^--mVbR}EݹCTxj7|cGHOxŸY-EUOVgINOK#Ɋ~~,-,--}|FI/E<}5WɤVZpwh6`0׭XQ޾|P_hH+>BUvM vOSf8]v 6|1ӰaCMK/Zj{;ve!Tyqli~Gܼuի7z1PHPH$+^xN&gh_VڹkIQQ8|!#+ոq /mظQB̟:hivQviݦbс/YRn#*$[n.⎋}Μ>XH"~T)%)dyWQ?~撥K?{!T)>L&۴ieO JݸiU&޽G .\CߚOJ%RTq>~~III11SMױ;wZkWpBk>A iӦSC Vn=wbB'2Le>A-֭߰u++k`0ff{=Y%JYVZZjyyBH;ÈV}>AU5kb09SMoР!NU'NNx81~wo~> 0he>t٣1qq/_M^pt@AA5;tXtY^=FP%wC;9+'XV—.]V;鮊 J$:`jjj.UJJJpZ>vcTڽ[|:>#.V,UOP-!`g! !d0Z! F+ah2 BB0`BV!À !d0Z! F+a7G+OÎV8 Bp>A &Z||8 B2 D?0'2h " ;AO!dV8 B0D0BB0`BV!À !d I]@+ Y9V!À !d0Z! F+ah2 BZLg۠5VR$NT:KԦe&߹!v22l6@S[}d ĵvDm& G*BIbN^=GUE+*E"}/<Ɲ݇,?7$҈YfD+3x@"vqrb#?Q؉!2hȵϦN?W1iV5fHd +]{nwi!TѿjVyC?*by$wO!gѪNNm<'ײ08=BhqJE%дה(/-3]fYoBE0ջ[96[M%ʟ߾7蓞STeiԢݾ_gB&K*Crhcc뵷BӳڵyҔx|\T\TcjU\ +yIAL*d/BPl|/a\"OWQf4!B03Ah2 BB0`Bw==BȀB0`BV!À !dG!BٹK5iҤ=zSں4mUiۻgϞff;wXpt#")J՛b2Y;wۯ_ƍ|Ǔݻw>66LXnvt ұռ+V^]\] tzUe`0ll*OG׮\mպk`PR^{9rS֮]{JҪ bkqV5j8 ___6;(Wݺ;00w޽zw]}I}N1#G1`wmڸq6nYn]=SRRJbKH$SPӊfD"LTd2ʤR)ah];w>}>~8'>>^ׯ,\> N'H"t:L(Ba0Ŋd2BP(DE\.PiH$ 3f<{ 6lx_XXwҥ7L|ٲ 0 ##F=eʔ[7oR(/\ 22F]rg^AA:JVT*ߩs盷/yJe2Y6oyo[ݷ?$4^B´Gyw_hjj*'݉ٷ?,tVx^^^Akz'ꮵ%D@@"X,899|x#(ͭ|UDe6lvT(//u[NcPUv"`-[WC}K^3--588}rA{2D3t:gGW#Yh1-[EDt٣c[Gy;<2xP.;v˗<<<|>Qo늝߶m[G5kmٺ=U7d^ʥClN: k֮{bk^ư0X7ӏvtuquPVV6g?POOӧ:L?~ڴZҹK|aD#T*gsuqqq@"m,߹۔_'^Ύ5kΘ>eiijwY^x<^Zj|Y[[ST7633S"a5-5^yFN0[Oϙo'ܾ5|pM={ܹ]fMQ~Ç@ii)qGHOK͵p866>}?Zl""" 7h_ߊjVVM-_rvvv-ZܷoL&H${ԩ3;~Z߾}du лwZjխ[7~kGW?FGG@RRRYYٳg$Iyy䉓P^^~qwܥKjjj~^H$JOOoE$; IDATGyFӐ6idS/_D`*h4kשsriiŏ~yV|R /\pww߲u[FFR %0+db¼a5DZ̙}߽}#p8d Ξ9;mǎyyy^W{ޤf`0+WڶmNV.xzzϝ{ں@~)==L&/]xٕ+VtÇׯ_E{IT~% ''GqpbBz ;7Kl>OP,---ZL/}I&@?۷  % ) H$yHs F$J`p 5PhE*=+kҤiDDD"!}1B /p8A\\qrv1§{B=^Qe7nңgɓ&*6r۵k7}4D;w P(j`W^{kr,e2YFFH$JNNҥŋ_ۻ7**JMo `na+H9c8^zZtIll|>|@4РAr{Kz9s/8n%CvJ[U(T֭[x\Vf͚=y> h4b&>}QJ2(722DQRX,tܹssrr?TAAAVV⽛ۻwo5*ݻg6Ç/^8qHI&GDD1ҥwl6dAA7&:ݮ}= >(HwȈ zETe2ZZ[ÿoXl6fg|AT*`9*$$z?w޴SQBdgg'ݿ;f ѓSV: 8u񓧱qgϝ?~؝۷`cǍ y#8$!1nH$y:,<"28$w&''GDFwr&Z&?wӥKjn"={֌~7CBBÆ1ﻐ49~اO_ϳ~C+/#ʃ;9EݹCRRRn߉ ݻ?dDp[6o~~sEDqℑFƎgmck~~3ѣe ٳmmm+wVZٻwظA'N?B?OJ*^2ljj*<3>_PPP^&&&bXzuHh{qyB?ݿ9Z(!d0B0`BV!À !d0Z! F+ah2 BB0{ٛ4iҠA7o$''Wߊ6m|VbYT޾F͚qӸq6yuݻuՒKOL&͛7/r| Dݑ̼]v$Ⴧ֭۲e+@pnTջv4$!!A1u"23mZZZeddUogV'H̾YuUeA_L=hߤ!ǩ>`֭4iZvL&s&Nl׮ T~Q333FpȄ6kwEbd~ܱ֭[ӦMoЧe>`ZZψ\L>=99Y'8`E'&9HvK$#}|$w߾ ."2G7*#G~op\6vǏ  ܥ+O㎭4':>}n߉Z`!hsPq8ՠyէ*4ՠu!*p܄ 6L58kؠ7cbw -ޣ%Ko߉ϯAPjgg簰P<.,4F5k$QwN4222Ov* @ȎU RLJgd" W4<Ϝ>Թۆ A뜃22ҿTr|'OTTqtaнGׯ_G~{.]֭[`Xng֮YݹbwMOO[ZZggo/Jwv$Q.Ck>{}m,wL;QLY?Ek!*MVVqMhBxB0`BV!À !d0Z! F+ah2 BB0藃4j@gŲ79~#I P&nˏX&Xժ٤9H=B3Am}Btȱ?NRTM*~ӷoptuUO@Pl+tۧw/}6Тy_~iXU^5eUbq>kյbj৬Ui֭'uUgΝڷkTHѴH$Q=+$HL]4`(Ng+d՚$SLfٚԮ Դ!j;fڵ<}VTT//422R[(eSg?Wyg2%p6^fi4ڕJec:gnGypӆu>:}͐)խ;c fxĎmll,F?xpuyy4`ܘ1ee"cc~?rl9..̌;v@RmذaCX\XP8ђ>X[۳ҕ>Ç2O._*//l5kP(䒒R,I"6l:`ђtPY?rX*0933SS&1􍛷FDޞL.ڷ>m;vGDj@ ._;ᯏ\|aҔio8?>I+bBm+(*Z/Z+rE9Qm-G(SP9%@ȉIG4$1_>ϓ3<^cE"G6 `5g9q?kϽW:;aa <"21)YXpDQVڝ*n%rcdhx.!A/&X[ʖ#p&il; W& ?al@,G2[$DrO!#CCw/_ŋnx𯯷O>x݋Ԉ(]8`F %.ߞ_Ez{kE y%55ωD"BsWy>"xTRRJCc@ *-{aeKw16=mo a0֮wa2FFF8N_OolAv:-[kϾΌ\qn9X%SbRRӎikk:eM@u>9%U\:sivGLh˧OmB!p\6 ڵG#G55p8ސ1G;;-[zmmmݐDWT_\6`ml4>F bi9bvmC ـ~}'=)--?bNmـ_ӱ._AD)GrNO!151ѦѦpxg{nCz &I3+;[f+ha'Ob& ODXq@([ldd$.NzMsb6ml&UIi:o_ӆ:] ӱqn$W[uqDSSeB?J!Kg:rZiStW%NM{ԴY^^1n䤔%ewڽgOMHYOj-^PSSjyL?751/x񖫉3uu/FZZk&\ћw5e˖. ;w}xp%#3F)0FDp2/Sd3@@ Vw ZA T+;j@zcE }ǍEi>73+@c0>y|T6SC/zCq[ǎ[`0=o'Nȸ'7Hh_T_dP(d c0T-Jgѐ dtzu~/^ƺvr|b5P @!] ZA \oQ0%Y?34?ط@T/PȺv *:1nTfʊԴޗ}Z {ZAСC %goZ[ $C-,Xl Z:>Dgʞ4p&N "c_}ںҲ$pzzC-qZLK @MMmHȒ%K:@ccck3aٳ%$KҦL&ELt4= >ÇZ9lnf61r~u...vGN#5 7e~عwdn_g`@W`e\}+j1.jjj!|||:`0i{رxjaع5\1ݎH xm(OovגRW*r-o3ZI~ZfKKK.'9!Hrp P 9jD_~%1779r̙էNZhZhᑑo3n꟱gs vs.^(WU6  XbOӦ:|'mf&9f(MسqgD"l&&k0 [hysv%0xg2T+ ~@(UjaX[[+]XPXN"ZZZoܼyҥn7]vm VYٓ~fb U^.GGnܼ3mmml&lXN]`-kkt8,4U+L_bhѳZv}8w6_e+V30ܰ~+~`Q,U fw(H$˗DKKe À? Ağs X~DaoHdr7UTV "חnFfZ %%eÀ3q l6@cc6Gh3+.)511640v`|Q0Zv]eEMM>~BR`65t:]$IK G=f͚#G|އf6em/2h`Ue܆,Nח-'Hn[WTV ,&),q8@[[hރ6% _1v<*u˖-[\[*@n^Lz677W2lj'cbt,RR-s_2`dqR)¢Gy ]hej þof39r:ϤF,,xt5CJ GppDSJJdƝ=}۶aÆ!B Ι١fqqqXXXPPJ@S?T[Izd_+ukkbr܆͗\usl9[q[mmmIDx(:Ked.ZH$::[oOfׯB_Ss#oQI.^XUU^C𸼈Ç H,//wss( bc㬬v=ˠL$0 oW|'OE6d,~80x՞Q---;v ]'8̩h'Xpq/y|~%N+׷oxXhK D|wk7 Q F~'S[hmmmcP[1fe(7?MgPUY7{l6[\AmmkooW IHTgX#p8oih3ƌ>5-Un4$D5P0 knnu>0ZRJg@l+ )a2W--KBaԬ|7 D5ĻGeVw "ބR[>[  Q9`J.P *>!]W0@ TD%t%(,040p IDATOy𧯧尻x(\QDh!d6E#Cq[1}o5Ey> '} FCT+ E"R?ACQG`4 *^Ɨ @@ Vw ZA T+;j@zP H[VIENDB`RaySession-0.12.2/manual/en/images/video/000077500000000000000000000000001417052567600201425ustar00rootroot00000000000000RaySession-0.12.2/manual/en/images/video/fast_new_plugin.mp4000066400000000000000000001760561417052567600237670ustar00rootroot00000000000000 ftypisomisomiso2avc1mp41freeCmdatEH, #x264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=2 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=6 psy=1 psy_rd=1,00:0,00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=4 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=30 rc=crf mbtree=1 crf=23,0 qcomp=0,60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1,40 aq=1:1,00pse Zd"q 1DXYDR(k^ig kaSv$ dO$>Th `POO>{" HAU,UTl-n# m =oA&!?>RwQ|-XR 0R l)~(R3#o΂2ox#eZNcҞT"`տ2k"#JL~3뺕PI"&HVe+yC~ .0X\;߄H 1-j9B'Y7~9jl9}|H/lp'Kc8>r Gmy eqLX̣ӧYXB"T'RM( z_{&Fr%bF!47iMԼdV.ғ1Y 'o%M֋2g XCh@G&xt 6q397Ӿ_)AoK5*D>CZQ9Sm1s,KSn,'!0DZÍ H!|]ȼB'`WE85n cm1a|vdI ɫB_gE;go_ޒ4uA+A1]hTpuZMm|ԭ?4?L"#`T 8E0clP Yho.t:[[PwU=\Gas6+{# D~+9[l>ȑkD&a@3V_Wgŷ^2= ))9Cc`pΩn}p?U+ RM5ϡ߅I#P;ٳp1E*:I>NՐ5lH J,Ҹx64Fw_ퟭVpyWDTY.ӫzƈ/t2-1jXF&=Z$.NSbyqE!;VRi'HDdjuC?X&wHy;L;ybOQ5'zwh<-+~ɒlxH`?4Y-6?dj92]#6q죈ZhwPU=[G1),$(s+A'jT Eo!O萾{S򸜔[N+\^= 5[cҴm`՘}q#)SDixb)%$tZJʽ\fP",F({buoT AN>#Yx"yK6!_w=g֝Dxg͢n ]-ONi2! CH0=!c|b6 `: Nu~TqD(ڕ6A0(ʻFE`aLӵSwŲr+*\R2Rcӫ]82+!<ߖi.54c`#A[[]'d`N>ڹm.s6ɒIMy<Ij"aIG6jσF~YPZ$bK-vxա4dp8E.$ǦOEa, ihb?ӫhuPl$7A: Jao,w?~Sv 195/IBRO.(@x2{K_Y¥V &g{~tuOF:pO WFlnЦ{Yor 31#^,Z_0hx<LݶC)Sjd@hJ5D\? Gהa[X:L*dM9ySЙ48rQF-dt"pN0?Ls oC,ѷ4/iuPib Ӻ^o&UIsc D X+T8E. 0I)[kj^.هΛbO`ʰ c$TJXp:8:̰Wrs֐e(SX`D) ʻ=5a &{;Q/Zp{}a?3Jq=GѫP՞tHHgzOpm Ӿ$n[(Ӝă) ]ՊJV b[v!2x<}gRGI[z:D ҔN|{< \KݽiTWwMLP)vRC,;Pr:! 0x՟[Ħ4RHE;}4!Hl[cťtl4ڇDz']y/jFbDN f$ "?*ߪLGpMb۞u{l z)%-ˌTˇU!*"x;R4ҟUQj\LIXyẖ4 Sg ͵׵hg7]1}phpcn'w6Bt‘7Jn'UUx FZ!t#~ R)#tjCVMUbD] "2J8LX+r2 .{UTЌ⊴$Ѐ"z̓aE0=Ji GJ%[`w^{f 0Nee)bJVV)v&ܶ(@XIU'XwtX)-JʐV&A9 u{R(exC<2`$P @4X>d'Eǜ:+PV2EM=jjMa<ĺt3"Z^Ljop!v+yG&?}QB$?վ9c7ѹ~`IdƐ(?%q1LDb)*j"CZ$1Uvxgn) >:- n`zC>cFou/cdͮF2/dAai7XܜFoz~5ND  `xԟSWRZ5cQޯ :.fՐ x[>&V"b(o8TzR8V2lU XR#d w 1DL:zTOה] \Sxmxyp 8ʱn,&aS{ ?Y4)Ab[*n7+ì`A}t W]آ v/ĢH Un~TǾKXUTq>:2Bլa5NpBa3_ނ߰ޅy$L$(6RUG$O'z@UFыc힏9yۛ]q/AՖL?UUǚR/hc4 l?vC^ޤ)w JK]®S~%u rMcHkRAԙ4\A(ؗSMeDNbaV';ة~~U#WjO (jQ7q@I'wЂ"jT'ް-!qzR')%o&Q`51SүTnSbJFV1/04T̲pt&=@RefXlnadGltb 8'Ҁץ?// 㟑\6M#ίP&QUpp]%T˓rUk`we@3vҋaAWvT{n+LeUNCld{ɥ&#&G&o+\/HRU&M2@⳽;pVI˻O Ekڊ6"Gf]vkf0b^a&_;0clQzH5ʍ3T?"Uk_{ta%?OYj `WHB)z`Vqb=A6T1#B& Q[N-̿},ɤa'aS_+eIB< 1$W"Q-!o2 <xGB=<HU WB/})c,,31>+uHKf@ l`zGSşWZ$ 0%Jͤ&nEtj>rUX5Q_ NL`j60.| GW5# 7TfD BV'kx`%rI[܏zŝ2h{BD뤓dC:TV0 t8ܟ1qϲnTt5TqO[pۗ>#õC$ݪJv $Yi'1l(du@~iz&t*}$O0| TlGxo Q3%֝]B)B#JX(͈d/ec4q uF'q1:FpoYЕm*_L]i\DB4U,wKȴY۰xgvo%ɅmQ  4nO4ˌ(i)"PZ2~ʎ@`5ɉC,`I^iORMVAR!AfCA ϕpE0dC }PT7s ʒC=GlSʞNB(R/&>pfj#tO4(2Q:P.ըO@dD<HqM&L9IHh-VPs/M,Ȗ/:T#Q:n듉ѡ:'Rm6iVŗ!@÷kZ4MNXr赊 |aG`gBRM)9YJ|>0>!Ž*w3^NUgfYnJnf E> 1_j }"Ţcʊ*vw6x}]fZa$t0zK|gPIj/ns4lfs E.bFN$yL$R2SB:~hc8(jٖ")XpHe'@v5fHlUbfͯ:`^OK{8[Wq/rɪ]U9g}K\:-R뽓z"Urs녗: ~xX ^o4|\uSlCV_a|G( d沆Pg%)VH8[?(}!-G06<%Ϟꇨ"G1\ 6VRd1@y5 D0TڹG!w`@ bO;0eQy(FG:~X\)6\t 3"4;%y=ZzP qgjqcg]&2q?}E?CYnMB֩ 긕*2OJ%{XĐ:<M6MX~Y k0-Cݳ9k Eї#42s|\dh\ʶzJޥFpɑm>R9 T-4<1Wfx s4?Cxg'+h&\;sR>rBDnM>N 7~nܼ[ީòy[p!?8.&/\sexNUvkD:pf@!>1 W*tcӯmaoڄ f 7iLKP61 ^tՂ4S6dD?-WUB3; B8։ M2ƻ~yR;d庱@YlrSHTSW((O[n^IXhp=@( aRʕ`9#^ _u}h.|[gVzOOl/"j#,qpXcOo}LmQ [g/U&(;b/$*R)ԀpU8hzLKGf%RgρNآ0ppbs"MFWadyJ50FŨ_zG6ȥo+4^x$ic%&4R9 "Rͨ':V:k\bv{BpLYkrM52~QH- n\Qµcշ?S]Af..y|n*C4T5A+:Z_*qKӷoj/ kNgSgseG4muTWķ#7cRnoeeMF *;j- ewivXP !ط{۝yLcLY@.7+^QC LzJI/`Eq5I$6^`&`4(ʣI{_XFjRZLg!+ivǑpq?L8l2yi7 pwK2}>ۡDC $PŦM.2r_P9$Bvgۣ}.+ɫ|%d73w-ЖZdJ:.hy;?b@>(KtI{<[N5GBKM^R<.{d? $[iaOvǐMjK< =c;[R@?0?.nsgID;vcW[TϤSVno^ByHF_Mz,]tB-':`c)KEJpDT):N":` LhcGGgJg$cs>%讍wffkN{O>|mmmϵ$qQۭ.)/WrSFa/ud谾Cje@"U!q37! (ճ9vNM~QcVKJQdI^Yh*=m;(hG5nQZP>&^#eQ`LVts-|cOcx=58u%7f [1h`^2O H5*^j yL4u o+m0d|&fIQkи;$X4!w59X&QT%_9J榡ߚfAW1aϜw=eA|YT9Hz滶Veׯ>ƥ yA+X (/f&:/T0EJ꛳i"iy}ӧZJīd,N'^dE= i*ar4U>01=hY%Hk & dd{#`hC 5!mY){b2pFAcij0״Hm]/ mq`u]iȒۡ-R uBH9m `kV>Vf-y7#b^Uzߟ^h D)q.N˖$/o%\CJT4:Χ6XEPOT\%}#XŎG=Z/d)_~5r @+/$-0CUҾq,L*!d hFRCN=@>:Zx\E1Pw̮g02AKւ#+ߧֶG8p}_+mƂbO2D,-P vwO_W>90"bDR=#sh Ly#ܽ]QJ6qޜ-8x[[!1KpFNFUwA \}GdH&bR7 qkQWVI'HUSHC?|BbIH##dV*FaK:l4jWM8ϙ>s( a>YYriSu~9$PcƦ Չe8z@rҞ40([ˤp/P9\P~x]Nl_^6cGd],I7,՝%~$[X( `/[3?KՅ:6rF=%+=M:cubӴC1uPHj%0\cAp-4q+isjuM{oѴσnVʵ~6|k'$XpΫ Mc{C)2Q,=32<+}d!~ X~ܱk+~Tz =yϒ$)FN BܸMkHq~ 'Ra80jؖ8?!UM]D19@gpzƚH>f\mre-GyKe^KPSp_(WvH:i10h ݰk ls-|#Az; ev2M8$ yQ2xgC6-lm1@dm-w9scz;ՍeFpˢ!㟲+~h̵=x#2Q7TGNwB۪ځ ښ3CxcxQH,Sގy%auiSRLl=ӏ;c[b# Q0fV7RKlA%O!d]yૢ SmZ~J)8?Ip|u|^@-]2gbdc j(CzB4nhM7d?o1s)X4ds) /YOlN|=#g7eR0%+kzFRL,0+MRC<슽FZ{k`dhh^҇Xj.S: GDkH*\5 ~y0l8D+DC16nA`FԐN'/ ɹWiC/GpRNa}!3 $9)8zCMގ',Bjc=TUY]S^ÂE t43J5Kkzj*U=LckzL^|Χ45Ά&erD'I.4HL-^>u1e% h=+Lu%gPd_ J+AeGq-Tc,pRn>4}9SuhÇb0%yeYBiD%x*R=I/!KFiҁU"XSODe֟P:q|h*sD[^2P6S# #:jVbRECa(UۀB3l0_RW{0[ 1;OnhhQ[~>V>)hM.7I}E〩Ve\:FQ|٠DF]˒k/'>FKIr*D&rYc.z(de,Q}؁H3m&9g<ӭB<^!㖳5{@wȪi SU Le-3KȝI ۸qWo L1=`H7[Q5[DQGtӓC ӨE٢kqٺApLZ+S,@&NG$ jZ<^ /oL+T8Q ]fAɰTT璒n[M~ϿUC^1}gm@uZā._+~0o:9c=Ѕ4fNeNFjQjsb$ͮTql8~_T1yWXNAU<H'g_~IڃVN)pD.JklEc RJ N|V9{b&byQ܀ !ō\ݓ>nYʻV&m uHw3S%;K|V=n;,PFHwه&TE^cʖX T=v/{v#4C\HP j }&\L&$FqD2\uΦPɿP.݇ݧ! 4:[HC--Aj&>r52j[eR[&1lapoClwSI;R&L}d{"Ut2sm>t%;KAH{fE?emZޕi;V/qȌF^c ]#-"X{j*fi N /_5k/鳫؍Y-EwwBl4,͛K~wYw*H E"SWh̑0mjiM , nPBlbKQvxRN55/›bd!V81nľ9`}@8Sυ ծ#J躞 a)Lruo #Y-7Z9f:h[_< @(owl i]8S{78!#P1b//gӰ/)"[_ )8Dzg Ыp+/q#+}z Ԉ2oD#Zwp'8} GA{NCsh,r(ޑZ7uTE$8տh%qI3Ug1v"BUwڠXďX'`U᥅%wG@:7_\ G;x;;$J&=H]?.w =/K!0o[=%0Jly&|& s/XDm6Iby*Y}Պ ;a;2EOlMar.o DJM=zLT[ OctH.;g0^LxB2{:aq[ղm|' 0A$zDD|Y{vi;4E]FB,b3"\ ?uKRf,h\: NWPyN!rT琚-E!] !ЌI"5z :iSm T I'4" /.j NH1' sR5f 7ʅʿ(Z4$jƟDrƭ&.rņB9=jb/P?USnCo !ugInawqk2t "O*nO U}nQ˧՟qM2/7RNHVHtAj?,dy)Kl8 :gx8M4wf:;2>YږPDܻک7ȁlВ pbo爯#1p5/Op𫀊#NҪ{K:!wm|e6;K\!p.[/ް,>~iM|#|*320qn2u8Ưv{L~ނ?82HU[-JE:1'eGd?gtWf[s,(u\$/\Tܑe>4qhҁ j^TT/dԋ}攦*fM/.c:.k^!- 5n"H 1E)?\9iF3{)(~+8`/A8dD) Em))Cn>#y* e8gd LLo6$;设?Z ؗ?JX]DMb`.V$ M .o%RVcЉ\Ct_ЖXq)~}vFኧRc,V?M̃d{F+@Vk UV2s_J] 4>4pQP.!JVT=&BV\aO%lX5 ϐ3_r&lQ \3՟ıXL6BXK:1,<@Co-8(}6fWPYIgΒT yP_! ܽSq.eo}% TaS42jFa\YC-!BP%/*|!Q[Mo]'8jaiސIJ3eoDrq?D, ; `j~d.`IH9 Q{Z $sыҽM_WVŴ᝻m^u`jG#RnȀ`0I硟7e+7 յw*ڊ^cB7RXؼt~kwkS6vZ+0`<'`^Y/uLesmzC@q+#60, -PS,N7e%DntVaxC&bMz=.l_*D@J hyo_A^uq@E ӁPǼb%sȞ4FP:`ŀLa( c2fGT3~iÎ( =/uZVCבY-q̹seToUikpA^xV2IgT\)l!7yB7 iCnRKy8Lo~迦 &J/Y) HuJzLA'=ji<zv3ڋbc`)m*E1"> I1>=l p,FP&pKaQ9~!",lwC@u־9p_~NM;6#qYPP&Ld|%1<{zG-&~Xπ3!CWQ ,[8ԏxz\dY_0Ac_ۻJunȘ7PhD`Ӧ}3bo~Ϲo.C藛Z~xZTYF/φo<,JDi#{WoIy<9/]A_>JtՠjPa5~lQ%o G,"r.w\_9枺PH>X65 .9WHv {5 ]X֨RF8b$ЫocX3:b@+=AT@%5N `S۴%=d =vٜZܪE򤓲uڨ&6S]_rfK)N„j/)W:D#u~s.?vm`7o~Aq0&xrZ;<6 ,fA>J7a&LfJ ֈ\eȿ&}!y#pv"yt:=}&.m79:n~AN4rg"umt+(c99$YGNLA}[%6sODžXc9BRmWVX\LrpYYKp&k R'U܍X#S$Y "#7>G캡|"/9?s{$dDG.t>)m_Jz6IW%x1A4"MޠDR6m?̙`v %!Y+rypֱT0P])q8IPCʊ%I)&/m{88T[h gQV,7/mjyF$"b/2RqzJ l/TI+>B r T|5CI*Q>*~xі4ܲ]P 駒⣃tH+;u7ɤ>u:#EBR5u{G3bBl^h+-t?*ȵiacIpqizJPl$>^K^I)mc171tZӜy&@T|,xAr[#cZ6w̓==6Ϳc`!):ʾv)yZ*3kY`ȶo2.! ;eSh$L/6DO"hH&^^G4œ ^DASiBղ)N'xMMs#f)u/o\S;FZz6ڟ4Q&,?o7w7q0rȾ|`nZdK8Zܿ`F&~kͣzc"NLm"쯏v Z n`=T&DLj$fXoW;(%ߒjDHJu7W~ɗ.xWu ZI0 ŗpjA7 Fyy)2A?IVK벦[8;lCp6UwIpϊ]Х?<;?$.y`5OBq?dj %dDN';hW+F }` #sv._D^F⟥ ՟'S<~ xD |W$ZX0L0B"3>g 1PƖM!}74Std-S+6#$ŞySq׷+50/vkD6K%*٪z*|dȷ_R7D\؉@`\P9·pF=P"> XyO Xιgb0g`n$hHz{%B쥪@ȑUd3XXˢL !ǣQE!V[Vq4CJmpKY 1*B"s[جaؤd6ݬJ|W{" ׊ gr qV8%r@{^[TMQ,sh{:̪ʅq|`)ro>+4_DuelkTM~ϽngUL\o^v1xf 0i|e#/GH#DuBp'Բ( DUml_YG_($# [|M Pӎ;-{  겐Ղ#:E>sLtSI&"5oh@6OMD T ^6Ol#PRORMar5ؐ| <1w(Tt eO|| t< n?u.e(Ў/Гޥ=P'ㇰw'Ap~D - @9;h$~ B^+F'"Vģ_5W^EǠIYMr mQX{8I{Krٛ:[+\e) ؟(6өœ}o7 R .xiݻ),o LuҋmPw |)vzIJilg1?!' cAzgCD:ۍiVb;J@!Ɛ d@B[/0 @:=y~Gwfo5̸`|}L_)Zn B8]/c(E{oob^;ݶ>Cұ{{b4vvCE2z9i%\+ڑFFt1*\_ў^ώ(<hSb_ht}OLdu\V_C9 xjKͮ3jan~]w"|6\Ѹ*(UǍaT-= EqⲢz:dn+V6YPi Ax _%N0[t*`ws$耒H5nlT֬bQH6("nK!/ Mkm_x=ThԘl[gE"/JhLG:okd?yOn s#lgt`Kjd$9hUR *IT0ּ`LEo AY&c^($mL5ݭgc:5C饊p{lcpa``΢> 6SO4JcmkJ};VQj-^f}¹Vf@8VTG:ד$ܜ~DEy +1(rV<:!I\tU!qX|5_T_E뱫uBsd 4lHn-zxi>V:' :r(V^ / @b&[Jf.+J!75y5ƯbIGտ?aneȷf .8~ї*l ௾Qҙ+CA$xMzI40t_j.p ` r' 3!r9J4Yi. ii^A!ꂐl}&R:4fY(ؽe/;h WbK#TU-zA_ W'3ksjHYIt\\L0Djt;:t)yE%yBW?07te2CB)0KU_UgT6svDVideiU̪tS!e뉙sO~) agaԍuw E{1uhC58(Sx zBº?ThD%@jyNGI:=iaп*sdM[*ne^Z#pP`Z*$;Uꢜ)yY(ATAϋ}~l5& ZYL[Ml/&{EkSS X&,T(ZA(@UףH u9b 0^;Xmi5 ݥӆeB18!rS}>UH*1Lg[BqN(e>RsUj":{ /9zs ,EZ'1 zқ9_ЊE8YqkF3,{QN]3'B WήIQӎ6+X~,| >9 X(4avg)==YbLC9RGQ*>U=>1R"gb4 `bphɍhgVKIlFfON\KDͫrP(pp1c:r׶q`g_2(C+I]Q/ОI}IfJ<ȅ'ſ~{a"צw%-"9+%_*#] R> n{K zY{,$(V((}k D*,"+7Hĺ')v^;VkϩL?ߡ"Bu;rVzu8` @Wtv°=_Ս$`< M0ne^Sd)Ks'џ^u$zBIE-X{$L <50>N7YoQb)0ivqb`28);jT'| xhl #?G9}<ϟCnwj->MT| _ $xX| Ss3P}C؜KT(jAnDSº =2 :sBVU]~wMCh AW_% Zk3|qWZ20rR:qc͔ p[Q}=dD@9^6zo +Xg6tM$K(9!o"8.fD\,\EPwեj(H: 9a!/m[EUq!߹B~<7uGV $A )5;x} T٘t[ SAfJ{M@# w ̤Ea-ڋvq[̹yl./eVtŒ>8˲&$v:<ߑ|Vy[b77l [fĬ(wL{YFX8B5AEɒs# QN@w`iWjy1u2M|HȺWGɉ2֏afƂvz{m+7:αgvc3F)9p;*B/ *? qpYgAӄz _)Cmhl K 7N(<:+-ljӽm3MBn 4MHRW3jPyt[vP0L@V" Mali($yZUuTkh we?-Wcj[LCa`(T(wxڬa ߘsk$Up{ Ô4Qf!Gϡ.mtG}D#BY5 7tA{몇U.kWO+dwݶK|?ߑ$njbH E&kʗO |}d7τ:t}Ō@gpȽ"%8ۃ<948,jn#$Ze/CM6!NyS Bx"h(PH70{#٬uqJjUǏ &){KΜBٸ(|=J(|+wJO'/v!]Ctm3mCeqa!ت類 _QU1 9 tP5INLeG_]$:]hhȔq\{3ޔz:w'/ސ:%zxT}fh!!oq#CYf}V(Ғ s KR#&20Epi!.prPێA_+j6D^Mϕ)#akDҳAx-5# <0FPwt!q$>_ۃQ }zKgJѐrm*_\em|Gײ N@ [ eB{%/A,QptR؄$e0UYǓTf HjhkEPa7;Qa,A~Nqy-ģ&(l_3Άi783uӬlvm?De5&: /ҷyϩt8; ^y?Dd=G{Yj0Nv9\`|QB}K~[Xcݝ'Qq6,5gr7Gfoxw#mPVth=Z͋ i{m%uJXTz?su 0sKo0 YBxЇNLɈ*4*13HzdT2(0qC %] 0#8ƤƯL9j mcwټVZˀ=DiUv2KlJVji(!+Db@ikOuQLӅq̬mJCׯr^Hk|ÁT9&}QyGu؆x5bÁİsWd`,5Yy-Ǘ=WgO0`ϋ7߾Yь!s)۠P~P&+$}̑:wMX,'&#rgcRQ1~ykƾ4{LؿrWsINbCkJ("A%Hu n᜿[arYN3>Zw~t/{C{mUޮU#Sb~W-[ꤧӦv[P6w9A3(O_^,D=;>B#5@֭6mc8 fV.\C#e3۰"THY_=E&`byFus'8p Lף \~3#OQe$VLRIzj : :7Ԗg. ?dEo^61c/s(Z3ܯ2>!f"aUum1ϸA fN$Zw ^- P XAABxKL p'x. 8$m L\S":;,atF>WVp@2cDghm ,$ū@.RAh4_:KoP,u9߯"]xPZؖ0zWO ^aQ݈p׿2)u_T&q#)d{lBDܓHhJGpWо@e]8AE,G"1@{Hq(?3tFDI.5y)DgPA4_7]YĨ2C,P)` @Q<3AE,GI0~|żh')@C*tF)Dg~` 9A4_>hbx'b['3AE,GI| ܼ4> r*-tFD )/Dg:A44_˭d@R@2ARE,Gד1o<{'(*qtF)sDg:Ax4_˭d@RA2AE,Gד1o<{'(*tF)Dg6A4_q'2AE,Gד1o<{'(*tF)DgCA4_ 08k8y'yhihBWOK9@XK5AE,G-_3 2C*=tF+?Dg4r^QeA$4_nT9E& 05AI KׄRZF Y[W ۃ|x|*~P1q0c3)ij V2 ,+%< 9ABE,GoZ0|bGr.atF440=cDgF 1_dž_﹟ws*OAh4_t|T0e2S0`( Q 710:N2~*_DI"T =LޥWǘZHn=Zi_Cem;BG׀HN-*Gk=̄Af5aN `iAE,Gk:dN<g|RMV%nn4itS$~@61ShwXTETj@G &6\7Ey)^ B#MxtF ҉Bu/a+oҰ_xB邩AT]G1. ۵xm6{W8H\u"3hIU*Xb&^b* <)\u(!E3f/#'DgVeo A Ҥ[~Qx6{sT:.`DG̭U0^{Mx?^e/`@,^cUjZ}0dA4_9P' *JK`eqZz@wzSEI dՏ CB`{KIHr?)q//*M` V 4[W%~sR{jJQ mBwp %dw_@36v `UpyYwy0 Y|2A8ݭF@kTh@PAE,G;~ gn΢$NÄIGh2{b~$=1tF VBDgut^ |vpZ/7A4_1;i'N5]M|36 H$E@ŒNJutOk;*D(*=iv̲> <;Xo)X}~H . 0Zfl#م(6ĭk8e_p_XB@iûLmBhApAE,Gӳ 5aJ48+N{D3KLCT @ɈSz/\P՜a"8-tF{."HP}/7,a/Dg\J=g[5]po](A 煮3y+$m$Ϣ3,(?ij}T3vA44_c2RTPJ`w?ug̣ mz+4`WRG?"4=#/lpՙHʇ g[p3MZ@7GuG?mbIrdV=WbP'fVpo4@"Ax4_  >;#}rS,go[Vy +ozEp6Qs{rA`n6.1c?z cT\ 09X%VAE,G*t]7+Q}Ƨ2r [#I;tF oebi68Ì;'g.,Dg K958s[6A4_oJ:4 02AE,Gד1o<{'(*tF)Dg>A4_|;tKu7h>q@Jc)!2AE,Gד1o<{'(*=tF)?Dg>>2 >Q0|]'_IдW( Jximj cۖ{yAPQRvdma Uƥe㒷0{ĜOG7iY]&Lkug@bաNVU@VA_&WDMPB:B'<)f ;G(~9_꿤wſ.뚀Bi(6ͬoQ\'slK_ ~y;쎸o]x*:bbK1jY Xjѯ{&k^*|rSܓIMKw9xH)fc J?!@.8qZg]FCRޛ͔T&`@!X" M ΌE޲#Et6|4ɷ7 qp6a;EJهx8JsH݄ Tz5c(,='(C-Ô$xQpP£*=gɮG:x36廬XZK3(bmZQ)WQݩգo v䖟LM5n]wgqkbt"2*VI\l=`{N/ѐU4h ^጖bF L !. 3^!ё^J0kdRJ rzVI(x !MWvW{!MQ\W&qnSҜM8OqDX2䆊K7_IUڊ{fMg0UQ_?UJ6I&/Rsy]bB ncW[ Pgs!,;bp1&b/#BZ6`gAE,G1C^qS+FA䋓LTpD,۸O ]lP}1g%eрV۹Xk^!]kdԥ/d2cNVaЗ/HdaڲxecPgŰx >݌-vCYtbf\{N$Qˑ<>ۊkO4Js^ -*!j_ɯ8|JP+S4m}}z@~p-iw01,x$,:wr6ٻJw!W` ΀eZAE,W PsPWߒgM;F^MF`t3Yn X.ߜ3ipu"~p*)iyv8_zСD~8-`qc:Y$P{RgP9yڻ,$(H}u٧$YU69kO0.a W)^۬D/9y`W Kϻjྩ&@_k6=VYuC8T( aDg YoIEٔ\GxeD"Zgd WN*DȴPw>X|2,\AIѼ]F_r}rH¢m6Xo%@CA }&iX*ONE},:ks>!biH1KpS>ro~6FD:Pd+s=r!ccyɴ968A4_c70?PBAs a L~W6(u,P-|91'*Y#Ԁ9 ZeԔn>VjqO0r8GޏQ7X=ʆMO7~Ջ^Ja|U:WְMTx̕o%!~?=2aO{JG,x.3Ӯ'xR8ջ|_I=xYO?FqGޯ^?+68—?3x{s`Q'Pw3\$B ABGJ:wwor8!Յ^~ 2$]fzv{R@Wgp X%Q~<"Y1A}0`U'IǦ7(Z𴉓u`Iߋe9~)-5`C#/X* RVZ 3V / j\n.U !HsEg X&}j d'zA+;CTt = >LmqC_@^jd'T:wC.)+FZ:+b05.g-6S] ,=NL{5NfGRt` i/JD( -@؉6Rob0DcpZ<,17x  a@`V`ݒNOA E,GR;;r !dPgC>4jKVW^\=P& V6Ѹ7hٱ{DqD"Ȑ5l^4ʬh&gفUR}U^] 'ȡ@,m׬*7T^ 2Q`LE[Sb L2.Fe۷=yIj+oWyQg%^.'`sz;/l~z 1i*4  ֶ|M;p.M;YR?@N &^7>ܨ^?y3ѷ-S/5,tF (KS@lc< %aQ[M`{"\`'[YqSLNs 693a$vӒ_Г+|}ٳ6AUW@s vТAe[7y$m4R T"[xGzM:zD߾luW"tVP2*m lr3+^-wȥBN87 r7 x(i+Յq$Bd.Dg_~5gnS kK -AAۡM쎒OLTMںN٥LiA ;̓dJ2Gv77׍^Szg{lx84b -/GFf/ve'G!ҋ`݉s+mbrf 37p#_k-*2,gA34_MKq*Huh&zkE><5}"Yx x6a]y|(S&ARLt `m2&AQE,GP D#@%1ZkWAsSЌv݆/[mgbjfm?k. Z;jD1"Liy T>Tª 3n17[EF`K:ptF\[@:mE{QEс1rDghWQud8d;nAw4_+O8$t۞?1CrUqOJ3[%r%!*4[9"`ӫPcVg'`t.RYk3y$PA]ٮ˿D`jCd H{^Ŕ/~w8#}N!n#,bթ .K3 O!p]lxBIC;Vq5=$U*2y@7@H_zBb= z&dwH$8ّΒ*fF7Λ`GhGJ5 b̺  YmzHKLՂP7zq jʴ0Rz2لtbJA"n^{@abMH4]|p@;l_<{mvt? iN \D2QdwB\![cIP?/Ό^bvLh$G %2d:IݨJ6ɶ%m]l 2bP~+M n xkDk! uUn)RVe\) i_==6:f畠*'We< źCMͮy䂚8_|F+Ea˸BA(htR:%Sc50p2M IzfiE%Nr]j8(iS@84lpƙD( _FiFd[GDwJp!ŽxVr@q?A~ ;9$Zz)n;U\n|e15>3~;g Ozc [J:閚]EWkFL؁%)B.iɁ]^"#O|jj1ɨkOrфMykZa񎒹Wtzf܈[}"~/`뵪i kW`3Lk=̿RFִѺcQcFCR"pGiugIh_-N_ۅԪ}`آ#qkZpPZ&ĺAqo9%9;SHX DC4ñ`G__DRQrJ40Ff˥+K1im0Ʉ.cƃ4bCLFZEMnNGZsDD6'|n,Uzz *,NbZ|lCـ{;fuڵzH!]mK}~[_AE,G+lC Jy]`(B^ʗ-b5v9Xa.9"o3U{AP5>[k N pN$nCky2@XpUԊ'K} Wi3κu0q] ꚅ^ &G @?*U8cfZd{ZXJ X%|e2/A3a4c]z[BJV,a}h|(F @CӨV m7; X2LUp/9wI,4EwLMaHWTɺhr1tF (>\n/o  zYO:qKabS͏?z9g]ގ뉥1n,z.1.$Az ~j֌>pr}9u)MY>{"aHT|TAl#GF/b0@ :5|?ndZ|{# }Lg`ff)[F0^dǦej禽ctd@OIA4_81eE=:./,O7~VʲwtvS֎nuNtl"c]W/QEyKH9n@ܱkYqo+чECB|-_[u\] }V}_VPk쉚ޔh@|ٿJ]9SK} 9ScLX.\P/4+>]opRxn'lxcB`'oǺ7֥~ՓZWI`(' Q3DTߦrS^b{8p@AE,G:4aJ2rUc*D11tF_?"TD/)Dg A4_8@F4B#n}x=㝑7ug%(ɷ3Fdᢅ}0CXo %͏*Z mY4_./Q}E5OOs%rL*,  ٻzcKd'!:j],~ x$jR#ĵ{߆n{9Վ&$`oY-ZKe[F7jWy,4 W3VD_%_:AE,Gex'BOT-`} ݉M5Dg;A#4_ͦy-0}<٠X x1AAE,G1o<G*`tF)bDgAg4_-b+GLI3[vFtκJ+㦔7/o`vl%9lXwxX+@{^&Tt 0E.%vD"5Y9Fhv!#:|[!&y )cm'<*~?Y\ 1~Idp:CNҋ]&RH_, .ONVLtk_cĺTdx͕?!TҺZzKqC5TQ _ Y@Kc?aJi\w#t!Lm%mSlUya֍r7}R즇w@f72P`4a.)]+4]&C ]~%Uyb?Lfik[5ɋ-nC1\C4㊪J/g_D<0&{OhJe:/9;apUvƘ ݤ|2)ΪgÙ:H$Xj]ȑnLuS{Q wpWR2r݋ՅU(fQּqu$HR0;JL/릘*YEYg>g>Gy*\j&Ot˗^4vgW`W|5mhZ6ndU C?EtPLag|0}`i_Ϲ*M͡ݝ]\`TMsV.AV) MuPCA{ C)IŋF'l.:ld,JѧZH5#>-H (X<~2o~jޔƻE >Iʾd^-Q~R̙QV߂r?rv;k]gΟzDz^s~y v)В{,$r ɴy`m/ UVm2Ɯbũ8cBcfX&t̟m"Dzk;oCYX؁1-gg`3]!9|9> RÑA fVCF@xqdwSǸZ- 4 мUYP {E4QdB>!5gp WѰeXz:ٞ4YmPɶq7ǀ$A0Q% r*#kx{1pAHC 5bM{ܦ. NȮcf%4*YMDYAkuxhK30r|X<Ұk?:淁C.-dہf$+UǰbR'Ux}1|Z~`\ oAE,GQ̨ Wqutl*9'[b}wUwaMe?q3_aCGߕpL=!XtF -rߢ 0YF<oZ Q0efVQ= y!*JOJD lK`ODg%}|aQ NTE Au K e'>#mu<LA4_8ǧ:./em:dao s_?@^huvuJ{M쇇p5p#hw}wZyf B'clk``>1me/NZm5!>$8ϥ Ik$s;gpXY+ްvLgPC Q #NN-S-6zmr*ar/s=(nǵKuKO )47=zqދ\NpylL M^ D?;_ ue{&f"bUU8I$8}jroz8N^PJ&Ļ!D t|@3mkz͂_տI9hpeN oEF/sN{y5rl) bu@Y@AE,GrmO/W©GHNxvoZΞCngN{)jW; ?РBCdS[/P!L]#-g@+JZ[e@Qb3Ѡœ0<.~|a DKCs0|˻G/Aoh֞=+ 9`6H3 VÃ/,IwY f3 f_~5(uŊdbj. O_TlM-+.+Ӽ)aLfYɐWVeH>Uܞʓ첱&LPwT|o~pӮL"{cjD<4"qK|q:a~ҦN=;Sp%gQ!8U^h_wݓt56ab/WQҤ, @w}l|tF99NK@޲F{7*Κb`U re:kU٫0>Q@F|LۃCr>j.4cBۃJ< $~+PhҒm(eg) 1#)0g?qХwE\PZtOx%z_4sIU*m9/'ֳS5i_yÏ Ks%@Sȟxu>kym\tQ>H7, .Ta +c+v靖=}UrͱxHCijF>݁a4"RA'Dg(B*sǗ͊ A-&u| J.aG40d3ށ9S/žPf1gYu7h0OKUR צk$.ôȲTm]QX&u J 0wY4e^F^ln1KnoC/C[sauR"6C3or¾tIdB6R'@&<Op'6;gFZ:z©B< *`A4_"FEy/gDSWumA oVP0P>_E0W8UvJt&$,e=6=aK1Z ΍)d G1K&p_+Eߺ}/Qpu\[A=$g=a4\P̂wzBFKWt9@0LHO`eϦtG4b?Xbtfl0N_ )ZfSsH78uF]IϥO{5FYBo_ --enD?!XWEʖ~EY-_#3TGÅ+`TFMigtU1㶍0`RTXLEiO+OF.%Fjc tx)PlE[շ M;VAXQg5LnGD[*t KoAw@(vs>KiSqh1 `ܶIv\'Q;n=}i_`#70дQ8t 625ln\AEbz?4ZQ?)U3',|é Z7$ӰfAAj#'}lBT`B53bzָڳ$6qfDX%)ƶwcA E,G1~bt?) 3|ۇ=2=e4Me㽁 Y,E`5/+!߻Hyͧ))gnϷԁ,tFvt^뀕& v`K5>soB?O(>^+A3P-_WK.PsH;pu֋v#o Dx'%Ns+ |Jgkm|g""l3ˇrVO%朏İC PzJk#|ΪN_5A34_"QF@$ތD7+ӿF.VAww JҰN7cDoI>):;Vo$"hqh!˕;N%5ΑIjf$G܇+ g3jobI>ḧ́ 1%AId4gX2[pȞ"g%,evCgF<r&9 U7O%%-sDodAVc8\ ϔ B|vK @aD?Ɏ߫kez)s&jx0h Y\YUJ/Yp>J^^ůVa'OW'p89>J2PF 13g{l\sk=P83. mճEf 4dLuč|y`_q'VR]i׎j ~vzE{ Xz)OפnmsG]fI⑻WGHb RjTx$Ck[ɲ0 j\Q2Iu>@:Y-:쏅60P*J mRo7pr$|UrcU$lR?WZ97u[`\V#VT,W Ǧ+RdeQi0_oXr蟫RI/!:ςyJ_!}drpł-O 6WׂaɠXʪUT!]JBM p'qV jB)4BٶYv B?͆߻(ӓ Tsj%TogVa/K}>+:LrDgf bQlS[`) VTl (JpK&8=)f4yA9.aB^%hyɊ'?dCAw4_"IۉDp|:=dֶ Z E=v,\U_ۂs㰠*1x갊ow+a|R_l].n0G9 _Xdd( ΈMh(T.U^wj[Fxa}ꀸq%/:9޴JY90RW#RNs<+*Q )NKKfĩ:\t7#^XlKj}Id *fzGuǪYarfYxP\lM,¬Qn62im*Y{R@@$Xtm _AE,G;Am fwQt3<` *B^\YJq2zf9-y\Qh2:P_V=WV=`ý-ƹ\nm/2rJޭaJVu.PƾܺAR#xDli:\wѼ^/&i30E @)){cRK,3`E\.bAhd$ T@)Ơ{tFw\e렬$k!S.a+/O`RQ=ع}8 k\o?Iο#HjCA CvDg_(/-@gdP˯u@̧#dPqdv=M0Уж+.+oAbnA4_7D\++;s6HUA&[ܽRY{qGpHR"4{5Csra7WH~BR Ay09X9$R;!EkI-sI4wf+BX4ˊJg $a1AE,G1o<G*Dg-A#4_i0HaZ9*bFՀ;Ο:rrﻎ͒PD<վW7_vgqM3p0X\ : IK&6-'KSP^J SRVP U EtK:Vk|M\/gBs"* 0Dpއi9ZNK+NEG_p- /Y1Y]%ČLw 3c:(l:  O[XHRӾ\ܐb}k^ qBǯΥ G`;Ռp[͎fILuMH] =QO[Uwf?"rťN!v1[3_)G֛tvCkr0s&r 3<[`~ʎ쾕=z$6mrѮ7ߪ4Mú2ő ή'?Ä;PYNxyE,usbzթvR%7m4hr,T݁~lkbXWӰQcQ` 1Åƈ  /.ORMaނz Qia% aY]Ay~ I}>PtC,25X0&yyi0|+4$q#$!9>o}n63`vE.^E-,b57=uPgAO8>cf, t<p {D"b+wGuF0B c):WSj`h%@D I6AAE,G<\ԕB<`!*`tF/bDg U§K:bYAg4_%d 8. [w%'/|׮2`~;܎m9?˃RcMMR/%xlA>6,}[?Uʐ#^^SY0Tqatr 7^+ +,4'nAA. 䗖'ywIkG9=sZo{Y<<'rdŜD_vX僱2ms#ed< | (Zbڰ>~{% PPC8Hd)Gj݀yv|i>;9@+szCr%邍pO."ma0^aȎOi752qcVYϨ o./a(U*'k[26ʊFG=W‹XCkB??D\z4+\Ȍ9kq{wSװVn3G>QFFlF>(zӟ=ںH0ffVzۖ?%dZnF+Ɂ4;W% 5tZ+6 @7>X/x7^E$.&kZB_"uc .[ ҳQ866aŸ?`&k$']YnQ]d"{!׷/rc ֳʆ3Z}PdoszkN5:E!@O*1ai<;øHl@.0xc( u[~4lwDegs䭂8IfY-vfMh 9ojcVا!3HAӄv. cz* ?; ރbpc1 3oxj0Vۚg"-M$Y 3PMwqAukV6Ztҩ[EgjS16Q6! 87y,<ջ+io(XEuےZKS14~%-I@L#@j`J]R4 9k $ɞxi yу! xn=i =>sj>}__j1=bBj%s,(Y".EJ|F̪^i=i?<Ȅ<;q[,M.;ZQn#$+(&|OI8Hy>\vniZMԦ| O2a&nXȉA 8)֜3X:?$ʷ~Pg{ɼMfߖՕ_Dq<):GA68jk ܻxxt5+'_49,3ࣾ t|HbXySe$d/? pwh=.ҍ]:BLBO%w< uX$ 5GL`o9 `WDx@طU=a(Ds= MFP,MwV5DȻ&(v>sӌcrOs_R+52ˡI8J5"cC:FxK$P̩G]؉1WBʭ/iΞa/ULCm& X0Faf=ƍuCiZݿRj. C-i}j~zpkm'8Ct?z,Pnc;`E.!'4m E*SzDXSXtt '¹s*!\bX69j'}Rsh%c+xsvK<vlAņY}EV \p\F B$)@0n+lN ?Aa`uXme~;Cr,}.Q<{8edNiJG.^K~Jto:'6;#"[#Nx'`eAAE,G7`n{9%EBJOk9 [AK&aKR_S-ZdƝw8Y$ݽ$ y~y.7za۬۵4'@<t`^p$*mx@lof~F~nB/k>@AR:cƟ/7웹Mh#a/BgƧMc8B^I(Wa,k)T D%.:x|_Q1K:7tF "&2 kkഒwJB:)1iX4Ah%2+737:̇n)VOJ*ӓ\K9 8PDgPBzIWlκkhJCv,]:3\^؞ACCўT!}?hLCL<>`xʋrKkeL۱S-s]C79(u?.2sb/;%Xz7ć2faAH絻`PK^A.[|0;q;A4_S՟I­C zLQe\fB(SMGrpnlPѽiHF+GZ\MMmAMfs*:{r6% A3Q | i<)b0;+Ռ Cec9a.< 25Fju;~r]FG,56s/Vˆi?AieT%[vPJ2V*͂5j1;zR?' :]NGJ|F|l(X= (AE,G7ziQu q)3ToAde]GnYx3T$ֿivje)mXPҐDL$B7}>CtL~tF-J>vvՕb5?Ŝmh(kΊkܿGFПP5qt )fj׷/ҥZrNF IDg;@BbקT\1oW͇Sp#A4']hB'.]$HX폾Ivh<ѮNdO[HKU64*8ER c(U& 9L7|ͷ6 2-&?+.+YRDoyRT>js|Ȝ$ \?Y{h\`g&o8H)QzG@,tF;8uilF䮙T 3Bpof.DgQ;A5bz}}Gl?NFc'zlz@v_-gw~oj6mu'R}A14‰]uIZEdV`J l2wֽU*IEP7J]WwBoރc5ewŁRdOXMot'P?T" <A]*agt$1[ u Vp! F? X_/&"en z|^#%er\5%,u-HPDg^[߁sU$^pbg=R;;zZAR=Sx=WcfS_|+ 鹝BVQfqt9ǞТX'?JE=o-QAt>L)k/;N6(b+pҲl̀pEyț(`P;/y0DgJ^`ԉvp;A+@ }\Ч[,=%?+q/AEE,Ge*]tF)_Dg.AD4_Y@+AbE,Ge*tF)Dg.A4_YA+AE,Ge*tF)Dg.A4_Y@+AE,Ge* tF) Dg.A4_YA+A.E,Ge*MtF)ODg.AT4_Y@+ArE,Ge*tF)Dg.A4_YA+AE,Ge*tF)Dg.A4_Y@+AE,Ge*tF)Dg.A4_YA+A>E,Ge*]tF)_Dg.AD4_Y@+AbE,Ge*tF)Dg.A4'+AE,Ge*tF)Dg-A4+AE,Ge* tF) Dg moovlmvhd@ trak\tkhd@$edtselst emdia mdhd<U-hdlrvideVideoHandler minfvmhd$dinfdref url  stblstsdavc1HH6avcCd(gd(@Z?jh"pasp sttsstsspctts                                                 stscHstszs)E06<7-T7.-=7.->6.->6.-:6.-G9./=2AT5Ft<emafZ?0:6.-B6.-@6.-sIm^S9!>5rcMD5-$>9-?5.-s\S+gHz<E-95.-1:.3]?M'UDjL^U4?30.@2.32/.-2/.-2/.-2/.-2/.-2/.-2/.-2/.-2/.-2/.-2/.-1/.-stco0budtaZmeta!hdlrmdirappl-ilst%toodataLavf58.20.100RaySession-0.12.2/manual/en/images/video/patchbay_fast_cut_paste.mp4000066400000000000000000004435521417052567600254600ustar00rootroot00000000000000 ftypisomisomiso2avc1mp41free-mdatEH, #x264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=2 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=6 psy=1 psy_rd=1,00:0,00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=4 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=30 rc=crf mbtree=1 crf=23,0 qcomp=0,60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1,40 aq=1:1,00be Zd"q 1DXYDR(k4HMn0D*?<DG]܄ʡy5X`[>M&GArIu/m- Gl^Z97l>bևuh(tr@{jn|G⨾;& ʃۑMߟTlL~^9ɕu`BAK?^h}9EFZ4C*RWSDۧ~ЈOޥ}ոvLx2͛TS+7 ȁ&QڝΞVeJϋ9S;[ %P|}(:6}]tCjaL7{Ȗ )d(צLJ=g%1w&,^|FGqbxxCTIնnz.j):O oS! /c'iʖ-d$H&6;+hf+ lCB9se׾X >Mg=,y<0h8; ,G/4Rۗc! {_ϲ҇44 m]WLBKMSTF fb$.,x֕)=Bq\ygI͗t`~ PqRT?XF~}O>#De33ˉPc$0Zsy;BK$ hT&Fcyc+?)bEs@%D~H)¨CvU Qfbĩ?K !Ϡoz!4|>S3IP(U G}}.S a{óo;fQD]Z!qˆkctYv-Lt-2R܏߃V%jlõ7x,JXН! `>߫Wd.w~/:ܳAMK.LeU<‰dkԭS?yE ^Nl%GY-9%4tXzaukH2H钐ᙂmc I3F~oH4?B"-Lo p_NϵGvgL`m[X7S9Hvc)ɲ! z_rD5pji y=ﱗ,Xufz?HsAGeᰝQgl^Ǥ`5ADl$K4d:. )S{72׽nnaB*1f+3_ڏ+o|'Yf/VP^ P}3]>ec - #1tIgcdfC i#Je'5g%M]usmxБ(D%IY?4{ME*{sS(>5Y{ۅvB4b5:?DbDMp"klh(ؓcZ S+ Bl>ef`"1|=r ,^?ADt?y< p" .f nß_wuiiu7TnZk2%.K;X*WWm =!ǿ`0b&G{YSWFCKMgǯ s仳^1 דnϓ$#ͬGGZ rT7ث3 XQD YFфf,n~{sMpMծC/7lgaY%D>"ڤϒ>c}C׮_!PfbyfQ KBppD_E^_4zOO>H W7d"ib\ ^MlGGz-R*g $ >#_TXbf|'AO .O/N"2oCށ\Ǒ1LD6ʹZ :S ˚F*Wvt:^Zhp A/RoaRxc8 \'8zӐvS,E)mB<˃>d$ZO|<5jZvlSUl)Cv&ئ,芐QG`<@t8;_пc IM&%ϸIj  h`ʃ;Ԫv[&w Z$p7{;)=*լzI '<,-YYVyuW"|j""< L05B㹏_MMIOdEOZ -g׺đoz4۳ԗxQTJ>x mO>>LLRXn9U2Q,lK/+#j=MpCaĐ#bDej,tL~}R3?Tbuڰ4!iRO5(O7"jwvVMN\b|sw-qDڒ 2pt_+lYD?g=ĬacU0aD2-N<11 $8?qr`&·pYDAHoB_KY".RKGqf#M_|xx$:ڤƨ@86v[9"+ ƒDt^k­xO|qmMx.%cܻf(EˤR,?p΀ F %e&ŃpYf s0B%#g{&[K\q" a 0 %~Eq VFNyf'Y 3x)عvۦc1R/ZmwN-H+?vLhӅO/OrN*cYHc>7T@k9*m4e R3,@+Sl}Ǔ:m0xo#-'a1N*>?=d<_Pv{=]Xr^87^ɠ|/ dg$;eHy*]a À^д^EO'1/S9T٬O8 @Ksw$A6zsX$rފOMDc6!_tM b]thke-O6\WY8wLrƑu:i݊R,so?ۘ?Q/G}='+%F>a6ߴ2eoEgyxty750C/ gͭwڭI0z˜.Jt>mfb;YpdI36Tt)/#luTݳT7>̠[~NjU":gsws^^(i>Tt[`cl;'Qm)qȦ{NOE?WO51 +gw5hunMkc EѲzVi\KOͯ):Y"o \kJ|'dپZr`R3'aQKS[@J?r;'ыM8/ePIXꆘpCJVepЉ߽HJRϭ (g cf׎kkWѤ+DISt^k=M+(_nNn×b,wJSB{5!p/z7jpԓqEV݋Ry?ZfHJ~ep=9,wMl'{1MFU)b9*;OU2%KJdǑQF]CXSMtNݜҜl:C MG&FbЦCиu}p4*%8Rd_4[Q{犻dž q=v܈ɫ(H HbܤWG` 8U 2ч"(nEMeb̻uHIVLH@;P&. \=-npG&:Gz-ȊT*C7-»[- *YS U}UIF퇓Cr ּ%P/-csk,{{l:@}mwf1]$7eAʉZ R_\D-GqosÞ ʔ}hCma6]I@PgW6khҤqJsnDҔnK=.Qeǹ`eL:F%mtz^^ЃM3tw4m'Ksk[-3gҋ ؉s$:Pt]ջ3b̑!#糡uȷn_HXCA*t'd63ڱǩsC76(jy7lV^/ LE%˔B3mdMe}s(ƄL4`N2-7W_W]ƽ8^pEb+ו͔Yt+ʥJ  yO=i>zj)'L(U~0ʹɃ@|:')̣M'R%.Y5FkP%~%lϽH/$o*x^1D&&س'a$|ls`bCZv-#"Bg2Bv +f~,C}8/0-gVy h+;kcֵ yy+ńfMU9yÏ/&ߨvPEG8 *Ga Nv(#(00bo'@|+e4Vea4s @GMXҚ_4aٮE^g$ ۾>"}]i“5U@0ư 񀁂GkdcSms;Rw"D߿%vfخCʚ$w)mG:JZV \{{)0;3(;[G Qg$"3rΏ'\ րJ|;IM^ GϙK=Pf,soG0C`rGW(`C4c|$= IDGcT ނȂ۪J>/0 ҩ20*Sr\|5tHm4A?_e؛ !5Z5d͵5*qt TȡU@=`VM|G 2S)ÚHSy߽Dg(afu(ȉ,M-8/w:n3HUuzkё~ˆ5v`C+bjJ\&Gz-C~U.s."C V2?r_uH涗~C:}FŽIFK7l 6E&3ed Bw0.d,sLI>nѢ{nj8g y7Qf>z ,avQ|_1e/(-Hγ\jylX [YNOPsh/VKAps.0+Wc8}ǽcD}a=>Z۝t F@ڝ ˡ($̳|k`6APEVk:zP>]/f>89'՟_xyS{+bFukHA xID|zW㯗T3^yw5HDWEB  s^ Qa1 Ǽb#?i6vNo4̕1sZ9i/ƖUA^Y|ֱn)R窱,|C_Rx- GI#nצĖH6nke[اg sw0NvWz!HVCtSGPz" 遇s{0oj Q&alW<.ڃp{(nh$Q?: !EIq<;<vjUYNdl{]0PEk&SxBOPOTeB\)u%Xzur& gQ6(F*GdV'?V^zvx a`3{ƌ7Y|LkT'MW&ˍZxPQ7wbЇ #TJ=H,hY1Om4D~jY%b} '3;˝O$%\ax*)بb#bV)L,eZHK}a#ظ f sא *v8ỹYZ'Q=nXՆnQzU/ym v~oGþ416 a3 T>I9kӦ^0" c3?4k's †E;~=stwM'JQ`MbXiݨۃtg6C3Ő~F;ӎB{JxNрD4Ee-n2qpdURޮljB`ailEf)g쾦~?].sɲ KK=:}nS?DYΠ-śT}ۧ;*2!NիRݲؕ>xc-?KNnGe-)wFqfm-/ dys05tC$uw 'No,z/Svgp&6=a<[ ȟwvDCSV#L :x(z4s-6yh__nZVc WS?5c?=g~KK0PBƎ렾i`Dk ?ai| 5 ""v;GmF'F'b-늹Tpah[KuYL~nmm, 6RGh#:\K@Ud'EU\wZuz ?h K pb@2t9vń΄'^~EjZ}xQ9ύ!jpp!Vkr7  Ej)!>DR,`>.TH),*O6`e'Z@@.ؿq[C8St'w'z&^1fjX ZeSw/-rma 73#SA7=֋SbEoJKc#!RX^1Be\F JR}=ξGcdc420ɣ5}u )MP~-\PX?ǀ!-n%i h%았E2{3'~<ڄ-Ye/ ,iq )1މeSDIr^8MIZ㼱4Xtj"WX~C\ͻ cBՀ tzH_H 27w=;nlmqX|!| X(t!]FQAq,]c7QÞmi̒99@Jb m?m}H| Id969M e61UnTd0$e|ÐȰGO\|PugNɊLKV I/?KJ<܅> -~3\"Ȗ*$[ 2Y Mh$Z#TPg~G' S]N(YT6H@`Ь8CVCln6VKŰ~j-bD' ߷}=ٕu qsz&z˂>h *ubJ!p[1KduF%|y>YqH?ޔdS1T֜9(,+o~: mt 2Y}{AWXwJ>mƒf1;gy0#@9*/BBE<κs=s;o+]M?ٿj=NVI6lW+m7SU*gBuS0rԮTE;Ictv|_w/V4f~Iċ}ëUDjf'3H ޗ(И7 cOi,Wr.֦" #vP5%vX pex(xU:In[#˧^#g|l^Eb3?а޴ϴ[!o4!gΨUZ)(6zESIvoEl&kߘOJ&PUlHnvKj.iWۦQ`(I%VF7Pg`7tdڡ,13\x eF"9$ H5{rº0KUL~n1UiIJ{9œfKB6a[SbaV]힑x/I L9Q~ߒ3YQwN#[{ٌ[hsSf yT;)G)ș R W^ vfy`IP9C'9U2NDTRI#|~wlOr$mc?k{F{;= I7saS?7x|m/Gb \ bp7e|V?ũOw*e?Z049jKtɋAD7u3yy"cy:`;RM+\]tęS.rG0ͪ NiˇZ? ̖фǤQ\+yYM$ha z9i\VJB7-]fYu)x$V;wINcʶx@%ͅN6)kUќ&GY*_j q ֘rbtnɿjNMH)f)(eo{e?[My6]Cf|޸ȗw%n 'SrқD`8N$[:cq\0,tr#4Vׇ ,?E8O Ơ\Q1Xާ%>|n>/Gk!qΉP+VP=.-8(OEIr 93L-Q*N=VgH5 CJ}tcũ`}{;A$\jE̫fq`-IP/)@lBDpH&%*,AgLa4j_8[ܶ/jf6-#S6Ӛ/x ZixVv–!g0b4$P˗Y`*wf!$ɏw>M͈ls"He_0q$%˙qh{vfr /l pfVcw s."W958sAHk@U2_VjhR5̙G}e  x/|re+ -хp#%"Ї :cG+#:5{I? :~>$bk4)ex̓uG)i6[BN6aha7w L;`s"ΣW?ؖqW.R66_ǚ hIu)TZÈܺ0iYm(S4IaFMPؖji\vbqM/z Fa7=A4ၓz`F'] Mf|HFݿXoZ4(4:3M jޯ>(51P9EQJ+4u|o iU04y߮)+! ׷.?{'|OWZx] 6ki/|3zQ kUnƸ)|0>z5Voÿe8;_VWq0sH+N4Rd2||*Aj Yz SWտ]JY<qFbDbtHf; JEKC/ }n"O<-mP68`O72bEMJ܇r,W\dOh[f'yOoI'=㻚jDG>Њٗg+ Gɐzmheoavam?웴.]iS亳Ȅk % p3"A$By si]dTJExmKݚ^B 8Jw#ەØ(y'&@Q['~WeLVǠXw=3l X%SD <þ;9#/]C\!_"U-.rm^\[bbJQ+8sJ 7u"u6.Xb!L7>|(CV.%i*)WqR{ Ӥ|M:|k}Y1udN\yO9]pmE%IMG@gRpXj oAn4cu]63xIiEr"(8vYr %ebV@ ymF8\+;: rNetz6Ba ry uL64L|I ;7TN+F 1=~+n͂gkQIR2^=p*ޭ*CKa{Q GMn~l:r] L;'UTNY l@ӷ"zEބĘ.RH6UE9XD7x;Mڒ1:Z(rBVHq9+#z)*"81 Fb,1ý a _axD7b>pU@)-$$';@-}l:in^so4ilu­ZQN_*el!ۜƳ9'm4?Ny໻i־veanTqp+@X漆0 9;6ܨ^ŲCG|=^V)38%uR,=tE(<98'>ռyxȖ/8?gY`:- ʗ"7HF}xspR'hƅ9D{6Kxix2 r: /~N~wGTLCLA>VcSyxe-S߷Di=aPsدA&]ӖQ!⏡Pv)ۋ33o.In0BMU%6 Iw.YՀh~}Y<|͂4#oڹp+e_[g7F'?P7(1nFM[26\$QXRW";ŕ۬kC ш_`8G2+uv|[Xj4a0MD{)ȚD /u 8?i`S-=Ɓ]pE kO+kp'zrVIͨǖQBvXPԷmأtN1C-bI߯=6xAi`)T[)7S%r>_6aU}1&)ܪbhs.cM^;M#E : >vdz:~p%#9z- fTT)k#7Iɗ;S|.7i8 PY54&Xmb6mJćZJ+> |ǺB&f<"ژfb Jz0B aTaKt!-!c7uyd s:>DZ} "֧>{D~73;-*5y3U0lE-L,},z|rFG]J%3#=5ʊڭobim*q_N -TDjgy uv]'"_ B\$6]5O2 lgqKRi z9PʖIɿQ3pGfj7i/įr3<^&{>Μð IV|n^-l"Rs=$_3R5v<% ƅJ#!S۞JQN{>}'tE| GFM_j2B3zZ)Sbt/&$R]S1H>)3NyܪRXĤc(~1YT x/%BN6t|b)L2@蕂4ὢ&[U%\V3Sm*M32FD|y_m|?Jٗ^⊓$}4uy)R"_X ?(Fx/Vv!O&l.{$g`e&A)sv~؏֎7hMݔ0&X \w%>pB*LbIz=w({B~ YНCRC}Gaao`+HK+Z oz'oz24-4qO9G%j* lf|̸\gw<&8iᄯfhԳm7"#(b Ð9((gdM^ر}'Z3:QBuXպW vN֖g"-4@U&eֹ͚xN gs`F?}~+)w$#N8#vrzy~ة2н;/{LK9FX*hyVa1,vuEKLP̀3$4$m:0T@0Bkz~ 1LERKi(*hqߓ nH!g 4M1/m7(΍~YWFgڥdu $ߘ1-晪ps :':Xt,+B)L,=F`:To%Ք}X&bΐ6# ni䊜{3/ ܈H>w:!y7KLB0%~T㬩zDf6V,,PHqe}s{g)BR#}3y҅5~Gwc^}B#ع;(rM:+$_L5AE 5ș:틒u{XȜq?!PsǞJ]?fRKajn:+v̟9>eqzC '4@r?%a^3{ZWm1jA15y :NBʩa3y',,F1L'WӼfWV^G._qp'-b-60b?lA!%$`R{Z.i|1qo)շn`t+C,qm]r0z FJdy{\ Y`],%g}63L1TNi|;=%3WR\jqebRN2-I§;kx??-_`A\c"'1k@$ؑT\h}ϓe(<؊ )y۸j\$En(9ԺSw+  ĥy3~y3ܧj9 [EMu)4}lHK.T4.0Zk#TVیjT.OIb&ҸMAdX\3zYs388s̓ xToC27`eDcZ:fZ gĭB/1E J%67D$۫2=KK߁$l@mcJLV,xP;'gHT)mWՅ0[.H$LP /J[qB*[OR-"ΛDĦK5fS"_}8,-fȖ_w9b\RX8/VHP2p_NCCjfnf8Y)jʀ\~f_˺֘ ԯ),zr$|*Ydu!Ro9ZC}0@c\RAI$(bڰr;ګ

vdD,ZEکrn'k6.R;滻{QٽL Z#_ 7WOsZߺ= "b΂\F뽃+f/O@}#3ZD"a>"K#XDeՕBÂ.Pԓ/JŃKY/?3C2v %%TK%^>{ۥ=VD`HZ$ʚ:p0U eQ(exdiN `r0? h`mP_Ξ:pO9eB&Q24k8AT/uؖ_5!UZX}'_JN[}Cn)#N1ԛIn i~Կ;N:"Z%>E,.9JPk8Fql!)bnKQacujY>j iB貽 7yz{͊Tf$wS:RlN6qNN^ S*֐Ֆ}Ms_ݣy:0%>sKS.#uCg-lԀK~ap8%GBcHYp8A{ 1=8OJy뤄 9Ogc.>\hzX +ю̵u- +ökjfSR;IPmi.| w1CaKXPk\"b2E&R͎QӊqS5ۧyCŒ=$R|a[v!wV癩Gqy`aM:Sh->'A5!Q)a^Jf <3T} ^m.PJil_oĻJ-\*ns)3_gc )LlfgfՒ2IGsn݊%6޼e\S͉ẚ좕w~!ަb肢w_{pynI#Uŀ$ r% <" 8!L{ gWQ:)'Nnn+D7%-\&=:j;c2 k }a{m[o`ss᪟Xj1Ʒh4}ֲdz+Rr Ry_y,K,(@=Fp~F2rb(A勒tS,V]XGE%%qX뫸_=Es I^#7(R]|_띲g}y$`%P 䉥KG!*y1WۭRzt*#/V6Ks؅|x=簠Utkk.-KMۜ˿Ĺa-#*5x0g"Бݥ;O%{LZ&sÃ.hp*T>s/9Xg:/]Ux=]QJA3G &,KP0NhFn6t@ PAj8,89y=2&`<֬J1>:~%JB&}5dIգ5?)zjC2>.^(ȏ&=ɆvdȋN1Gm:NEBycܹtrF|)S@^KGc3lY2TaZTc $f {oKxI.;M &7G=AvU1EcJ(wfW q g0|M`;kў"3;/:GE'~m-~.8PI7T~vľ#vG(HYe8^S} 4JbYUgtJV |Ɨ_: EA30{V/.YVOuO/ۜ|Qk+4Z59"f6t`)tC#p>sx8i"UI1v1]4R"i +3b71@eXCg@S|Y<#V"U!EVˋZ]t =_yU* ih0s:-tl/K-]F|(%S=S2q; aOg"oKV [uXف썟]xc0rCB[X 8"ѲfI.e9⏋\x>|))䊞Yy3>7'3ff2'f8=i0J,+l [SfzӨXo :W[}YSmU /7-7=NsJ iEtSmW_M4 z_l6E92&f4? LpXW:#$Q  $\s={S+b[vN8^ y_=yˁ,Q N~¤>F9Po*A4#JSJ2v~{tFu qd%J#8w%|-;e@ڮV6(G~ܡvX/ܔu#ֺf- |jq+VsWRH%u-sۍ" ^h^c>MZp Nk[:.O@,_*MrbAVf)nZMV .[2!uΛ,H`^Z[foXq M~;~ ]r*Un֏ȕR5fa%FǼ=IZ#k&nT.t-ntNa@Ͻ3 L:[v% }kkVǯ'[ j"£MbF`H7TS&n-8JR8I|:w&RҠmVd4M5Ư\wndp(`8C@P l(`lDA$lW8`mHƲ [=YSTH=lwBP3!%mKs;.\::IɡfMLdtT@p/ jEƧ|u נ;Ӻg9^k/ K4שbWG Dhl1oꁗZtOO~gkkB<*xgP`l .ι]5ABx36p[=lBA\5#*atFLR-cDg RqAh4_{$`Vrp qVfn}V[d2E4 =6`>2;"<ȵwe\C?gUYs10}$, t- 圐2AE,G2f@!s-tF3)DgoA4_mQk۬ 2@>ӢB_QkV]_t.:Ua-gU9|@ !Grw.AE,G3)'a*tF)Dg9A4_ IJAYNZĀǐeA.AE,G3)'a*-tF)/Dg7A44_ IJAYNZĀ(.ARE,G3)'a*qtF)sDg7Ax4_ IJAYNZĀ(.AE,G3)'`*tF)Dg7A4'An ^9bw6d.AE,G3)'a*tF)DgYA4'B^1N g@MX{JvuyY{rB24PT9%??>a2AE,G3)Dv8.=tFF,+?Dg5Q )`A!4'BГ` joj/-pwr2V~&HKxo{y% hkQ2?T`HAd>L)k1zp3rltzǦ8SaŪ> `5Dgy23XhkA+1ze_P,:Ln@qz66sN+@rXZƢkiF),('$p$aC tFħ|T҅2 DEqW Dg& KG0`oGp{CܢȐmE!3A4_ IJAYIlp+_T Üʹ~?>~x3Dg2jpի_k%Gs\ Vuk mqo{;D* *Ojlp[>i٠E,G3)'`*]tF)_Dg VAD4_ IJAY*u˰ bs: rҚ, &; Pk۠􀸕O&1\&2>c]`ACW~ 䀘54e HPb[JVDnN'‘#al_fҵ{ 6==#Q|3u3Le2_i{27o/0;m fHX&4~9 (60uk_N^ia-i7좩@lRoAW4dI`X:Lh]qK ?42lk:S4i~ `Z'ʨˎyv*eNLW-^@nɲ8]#esBl\w%ڻ v)aЄC 1uK]GzYڤ'SQ!AuJxEBYaa(*ڍ͗32̓|4/{9z@C #=j8!^@ܾ/I4I?QK|FT*PZ7 ʳc 0<(۪ȣL6{w:-NUL: A0,S;r.k|{e028BvKq:e$\ZJK$tڍ7Ӕ.ENAyǟIDK`-w`53%/';TƑşѻV gE 0' !a~ť2>CEhkjLO#fVcRF3[,dNTלʤ#)@F4h/jYu d"h4NDUUD.l}ʃc2m򓊧*, #SLF}Bs Xʩb{@<(qC tLS<-Gvuțe+v)FtXEWE6™d@~oqN]hH?-SuMuT`Uaxˬwv?b\4v! $;K}kE!egm٠gj=*h]Gy҆ jٵ0Չq7C RiJ~  쯞p;C,CĠlv41* OsQr@To8$G[xq_'eP#^$[ni!ШH]cFdr3߮b^\yRkHڝ`-SV6.&PֳObS8OsչqCdn*9N@/1~W`T`To):dS zd"mGmR"kܟTɣs<,YtclS.$q.c' 4WC1ۗ/8iMmCT\eL~GN3KnGv9U 6@]UY,A/pR֏nLJ'Aq=شqOyiw<豂{6͛hYmZ=Yc<1fRMC0ɰSImhDt{1Q &cqE)@$`Dgib0Dۂ-%X.+}ykl3R=H[x 4Pk~8 M:>g8RJ M̋y 3WC%]0@-r DS Iwu ,Dci=M;Z3e .!.A4'BГ` jK[gcU}XRՕױ=~"犲 4M#ѴtS g\:b9Z]aH<y >q%6QG҂%:ٿ3y\rQJ)ww$">~vVsV:%iN_wCm @kMIwjrzo5dF f_M>5ܴM1qh?f Z8%7U]x(c? 94֜ݨ'ŋ-46\-7PuRcm.{A@ )CJx{Pƍw-h;z@Yvfln@تr1RFCS>މC:"TRd=O.J;|mkv4}yU Z!=δ EU2hV? ;AE,G3) 횜Brdؐ'c7vGktS}˸!jND4ޏS>|OcFc&tF O]42ydM}]K-2ΙqufAI_eƍ:fteM79@C|F2EL~RzF]^'qBorBϷB@#OoY7k +gtZ-u7sc~P+=dv/_m`۲]ZǕĻ8^qǏ]W*Muzx .)v-A=1z\ i'N} ~O 6t{7(e*Ojk%A(!>pDXQ.zdeq,d8 -HiӘ4w U&Ff_[;5 Z.M\r3 &kGϺ@JQQur~xYJ/,.aVu >z85; oGɹXʲɣ:'4PGc>H\ʬƐ<[B,|_NLz_gpV"_b?z'k/贆p_?фF5}q+@cV71H-k;]Nk  gv*tF :F]["H3lшEYAAOE,G3)n.ТܩTQ넛,M}?݂ sO|'WIJ?3[ޓeJkGө8p}2Ϡhß٧=d 8grntF aw0A+,}B@WCGhwǒT 67VQ$T/<$fX0d=[Ql?5@DnpDg D++$SmLIs*:8F?K]ƶC;GG؛ 5g3OzS̸{TBDX<&4vv8As4‰ IJAYIbĜT}6unC';)!(&lDToْЀA(bԹA:Z.[nI;pKXBΗ%z%夹t|=go Ff*{ca4o'p =!u9*e(yVVY')y',4R6Dӻ uݲN~_gN$4~RAE|jN |Ģ$G͍~n`M 5cxp{>Up}[@AE4LG3)\-OSJo\/QHPn8 pݞ>9_x#A<0LXq|Ӏba#}2՟1.ez_hXgzD{F,u]VfSςgV..ԭkxR;dAAmRAtF eؑj?tD 󞤊_mٜ_j>Z/(wYJ|\Efl0LDg e,) xk~hf;YCNRL)v\Ѽ6LYd탬E֜&d:撕a,$w=o^C/l͚~R`gےYMP8R-&#A4_ IJAYI?k{?{џsZ} @U?Ķ[ƒO]A|cF:+8mb"2Y&Xj@b}t TuRYFZ1QuF涼¸D*-y+Z;:u!MRÇ/YSݔ* XY y΃XP1|l@&05Oꮃ?r9.ZsE(W+0r ~lgׅSáqWTp2GJ}wg;KMt W+݂j\ޣ|򏦮 c_1x|qtK*>^ɩO˞$pBkJ(U-8mAE,G3)\BŸe9)pя0i_]7˓WGM iju!Zxk+hKL\2°N?-CC޻ {?L̯k wAX[J3iTmW59vCVn#F:7o "_%;ca,f.ڴp+wP=bUpUG=6PVtF{N Di<xʪn瞑2; $>P\CT `t.LȾuڬq)"q.w4^z> gLcl+ iFiEDg%q$өSY2f &7k.]ׅc~z,-qgvU n8Gg]BO: W/YY, Uˏ+  A4_ IJAYIAY r9!k[x8CNRq͔Bˍ:OLv{ #18?Hjc_ܴJ wP&N6]7vQp9\Xw30G7VMu10"x{\2@۴FN >[lBّ5֐vٿ(<{©t ]MD<5;|OîTd7evRm#1{1-o%p/Z8 >D{Id__ўOy6 /PfxK}px) MgZ[+P2b5&u3fN_K۬OSbkSx8\jy̆$/hvO|)`/r&CpQ7p>&A y,RCp7S³xlH_vrz|"~5AF7{31}-^1Jj5VH|5!Qחx`_\́Xk2H)/m:X0iԯSjeIHlr?-  ]aI>όv^+)6_>%%9Uܗ6 &&ܵ(cYRu=nFuzAcUxt ڔ0ZFy+`@BwvRTJRԟ%k<>ZCΞEgFK39:!7J8Q=uqvFWUzRJ(zHl !Q$!p> bTyśQ$Mvx`?W 1"V%&3h_tk'v*RF;(FPXl0>se43TN=u"` rDt9hP%7tfMn_ @=;f}$+69jƦ.[lA0ym(?R4s>udFz͍QќFFDLZC>Krs@إ %LTOdUqk.S&sp1TS՜Sxi|/afꁦR w~|Ȁ$A4@hڠ]3i۶;Cm~a'O7>FX>c%nO:/=TT&q`Y*Cz/aUθ+[L0|<;]ќ &h"_OxE^4B sjV=dvHK{Z}=VM)j[F+_qx@44ںe{B `̮K$YMHmw;~K*I1EhtYTLIt;Lhyqk.@6WaFAhw9?Ne&-@f3xQ\ImM,-SX2HRׂ<ʩ,d] p%k 2QG9Kފ~_e-g!໻+}F'Vw>Ebtaڅܼ26L ѹbBf`5w:n,26UK{&] ]+`Wp/^ϫ0 lфF?mMTT᮸XUIl7 } {X\@~Z.X$J|%n+-%fd>zTS(*Ѩ+=rVv?A_hek%!fΜ[Ӛ 3}<-zFq _84۾8"]w)x Am0ӰxNAcw:D\C^p\4%WCx!sjj_{RJ MlbxtGv|Ҳ?Zo̢Jm6$2Mc&Ng.> mD(ƯIp8>EYuemBcE `':oBx$(1_J@ŧ\V+01X7 -$!y@+)i4LNU1̳"9RM )fTiىJmDIBL"% qYp2f`yGϼ)+\JGڀq1A=E,G3)eiP*ύj_w&1E#S`4£{WG;& &L IRU\$)2GqiE;a(Z_蕧 [93?I8jYǩ{DCgRgIM*zC 62~*z]5 tPuƽKM`[epd)~ |@!: htWs8_Ԑ1iO\tF z 7[݇fF-eG[eڝ1J8j3^Dg $yEH}aZ[C5QfPNH 8G」Op/?\xI~TEBJicNvJ;WAsѠ4*fJ\xF݃Q(`AC4_ IJAYIGo%d\$Ֆ5&5 2~!qAti 津6~nNv^5:i{kkq& 2`WuXAUX2'K]&I<#A@ƥZx}S0;5qXEThLl#Dn[}_VDX?nXKԨ VQ%7k2ؽ:}k^.((j@J{{R@IqwѼLNcؼI*!H'@Ho8eL[n5$ \)M54\U##ʽWM{=3ɣ *E˽ChȌUἊІA0.eyF >Cq.CQG1'=ZW7mLd7 I 0&7 oK K|Zh=/P1GQc pߙ)ZGj ʟU۬t=݀YAnAaE,G3)%+sNN_318kah6167[@; RBޅc~.mA(/JaOQ :x*3tF&L>[D6<Dg!Qn(p")~[@CA4_ IJAYI_ S 074AE,G3)$h}ؙ+tFMR;)DgCA4_ IJAYI\FfdwtodB^,/AE,G3)IŠj@*tF- Dg̿:`;A4_ IJAYI^^LٓV`G+0A-E,G3)]VV I*LtF)NDg8AS4_ IJAYIm?WYh~ ;.AqE,G3)'`*tF)DgA4_ IJAY]V%ԅm11K ;_< w6K4Lnd7=h{uY0baL42a?\#\nF|DU38V[FdGnJ>Ju4G-i^R+ޕѽRtk6=/pX&:o{>uV!A>j-|S?йڶk`h| LT;~[5TD{^ Nc#j;.'[7xI+ZCfMyv u~@}ve;"fp3#M %Xa ^=Z+ iܯP򽹞]nV4pvďsr)bGd龾\O0Ya? H\|!''Xv$MȞ^"σ\c/oFj_S+ tΦ) ̰|WILDoYqz+= f4M/~n(>v\$\aGUXeX;-汵j? p7cAA"#6PSf}dcQI IrTycx_RE^O-8ٱTZNyʞƨ={AFE̡شY~#&g|)P9 *]'v?놵'E!\C> ෘFgL(IFJH6QB7#9c-U;&O26 ަ5/X'o>&d0CL`]9T=y-MىՈ9SY6%#Y ~Ȭc VIaڲF5c5AE,G3)Q; tN0YK%Hw)dGb$N ~c #[ P=|ı.E=xAvIu|9 A>Sjc6'>3w$˩]{2;~` 6Cuf63xw<_)Ϭge(SfIMRaN?Jra˝ek/݄/}˞ NT4TlLGae98R8r\,! v飭ͤ#u" A_;j-d<7-# &UD!ﰌ- @GIqʳ[ T!64,̡߳C8MO81I]K񳕮`_gc4S'Q;: FL>E)t+ Huۢ^\cS66<tF&8 U573aDg & z<-7EG"MX6P*< d;^8csihtb>b%ghF9ոlG1}\@ y]U7MiHr߹rs(@8yT4y{[+HWa /66CW)9Β;%L NqcWE;yMb [f.B2)LjViE>)4a;;h6t`Ix^M! Չ3CU]]M4V\EpbLB!2 .2RH_[nֆ*2b1_/XѸmG75=|u߿<̓ѹ Jڠ7Zz.:Η+ ۟1FvGpAE,G3)ϹbWsgdz6?tēH;W,,::Mzlh|Za]_c &kF{{ݤ*%em?aK؅#}VAx3׷YѽE6:A5<n j[>m" Z{;]9VQ· 0۩fW)sY6k,ӦptF&Oo2rԩw$_[)R?@s/?ZWp㥾ҔOR9܇oz)CT u"m<àNDI@@;R1 Y"(؛4|LǞZnJlKa=ϲ jmDg&k(똌jO{I7zz˘gGuT4[i;F(RW~QU}}O.OMuµY\p赣n,eOPA4_ IJAYIU\#za 1'ކ4cD2z>ts\_%Ԟ5.R:s]i"8#s~{z7 38et$ (_O֞t?3~$/j%/xSBayjLIR\tF&'P ܦBF FC3$ZBP=Or~p`>^DgE%\gD5SЊ5+"t-YLXgBpBkˤ/DΤ^>|(12YWh$ڈYQV3*?ٰ@5*mt_Js.(x01pdkBM7Y[8Yh L|/uV^d "TijCЅ , ő'ga%`TW.r䦥#AaE,G3)= `a0߾I9;|v]XqbFts5jeviē]1x @:`X.4>; (KZL [4sl0Tnr;T3w@xtFN&ljo#cyrjR!qKsA0cҘyopţ`asGzADg H7DdbNo/ѣhA?n,p t_NSbY K 9o J7rK"u}4HZFm -xVa=;Tf2b]dVSM_xA4‰An;qR|8dr .Ⴔ+#!b$_nJQ1QQq0;1n`(f.O ʩ3CiW3gɑ3mU G*akՄ7}:UD>*!| ˾/;7zf_f]S]s[DLe6h[6j|YADg1 14,Bj3?u1Bޤ8_TH//Oa B}0fD%}+} M:Il^?}#̕[F Lwo'@G)5!jA=1zp3p6DT'5)P:.Oʀ4֚~ I$#i&vA$OQMA>L_ԀDv@ײ9Z@~^I;͍AZ16AE /tFh Q!x + Dg X?: ށHA4_ IJAYp9z J{6  8.&ob]31A,E,G3)=W€,KtF t(a)MDg>AR4_ IJAYTU˒ @ {40m0ApE,G3)=*tF)Dg@A4'BГ` i|Z jHAG0AE,G3)=*tF)DgKA4'BГ` ix+zahsTx9 yb>~„M6AE,W6}MvWLchF )4DghxE9L1JA47/dv4yglO= pc"|': 7A:E,W6}MvWL7 mѾp H1[Dg9T_#@A]4767X\Kkjm@>$jne !qFA~=]98ScOL!dXsnyqIA>L]98ScO˙Nq gBW`WA$]98ScO&5)IL@i[{\6j4֠?O=/ΎGn +2:N MoYcW~t w_1?㰇7w,pȉLJHC̶$R*~{5?nG9DŠbԯ g p}حA_q^KYԂp_LCytK gQ2Yء +~4 ƫ?Ї!爀Kcm[WLbBz &_0"RN hdOq<;{Йb=5>d;Oת*ٿc!?tI\awz8hZAE,W"<P֕[qO[)iMn Nuٱk#yHHDg@2g"c;mRs÷?ʨ8PM:9AA4_1z{M攧ȗl"c]}zS!j0({x{֝D)2%UWoA#s=iM9P\KtF1#Ѽ'E7-_zNkIZlfe4E"z\9`?@e&%R䥟7 fiKi4;(dBMrͅ:Wb}[/pRA =&9sY ]nJAE,G|p}fkH0Fݿ闣i(jh>)aLa*1rl!b[gsg6&#jq'MiR^tF~=e?\m:=K6:[.u M?vU|شҖ@*+DgIFM8A4_1z{M攧ȗm-,-A4E,G@*StF)UDgAZ4_1z؋t3OO*bu浠 O~ )' /f?#/b-q%ª ^Ր O$w>k>e1بSŭ;*W4-3ޫLUf瘗ў17W\ dɍӵaM!h&1=z?I{8z?۔IYÕqwj^`e1R)A){L`i+ȢGiރќܽ?nb/dRm4KQy/nTI`A_ QXQ}vF.%:pf19Iruk[t<~MM1*|@͛Hq1zY؉I>ܑ >i/1Ix;u~#vb=E1($M蜚-zE69O#yi5=|uh Wδ2;rV]Ar~ÃRA'!?M򲌿Q;wnDŽC CB+Um-XMfgߕPT>:yV!JU:?ʻߪG$i$4*3Lho5mN.)JitL*XU/Y^׵H{&tm_Nsc4TA6A OFo4{ ZMߊ GRZlm~Z[`HmQکs 嫕g`;?W㛪O'H9J^zSr/9MsVzg^L,8L'Œ;;8{G&Oe.Bl&c~WΦ]elT#)5\&eV ""+fT[ۤR~D7sZ)GnR\%XT7HC'mFd2+>Q?N쎕 ={13F!! ۛ:q Ġf6dI]H'a`kiw΀Zܚ( Ś Q;$Cm$_ iRw&}YaՀ A"mNDwGz`9c`uB(TuA7묳HT")&G>EB;bo;^3%(>DĚB-rnP6Ӏ6Y##ZX;e 4䥥٭845Lcq{'#R<&~)%#u9z2QxU"\Ѭ;}6Aݠ>MkQT,GR$j,VWo$ݓ@gAxE,GdxȒolQ+2w4֟JBGwƘ u ,H 4isdWnB̕!SFxT$|DY1YLΙ` 7|ޙpI|vbFRx2kX\j(,.כTYK+C ǐ"HB[`utF ,P0 š/fB͘D P)iV -G{囋1AѢ#c- ZvH}Dg ,P3Uʄ'8 w9 {&Z)Dy'B("| Ʌ;Hlgp5?v zlL]mrZd#o՛osN]3Hfؓɟ B j A4_1z4&IYQwN7VQȠFf燵E-6e33OĚf'E`\`D]4斾AZT'︳Lڤ _a7)<)nqg6qr_Mrkt8 _e  ^]4rz Zr:(ƗHo6Q{UG/ѩLK"*Itxќ|>VWy>aI KHw2W:Ȱ{o$f,%>6~[nJZ(͞0hW.uj %jX nҿfad`HŔV&C aDd|Ek˵,h9gHAC"#W[^)[Oҧ *4.` rrx0jc|",-5f>z9$H&Psu xQ=S o+ Dx5ڃ"9G%9^9]CQm8%7" =hjw 02c+iICsGf6['`eM^3qC774>vOҥ/D&0p"%vpLz[?rǍG<V(o<TU,VPAE,Wx@ )|>=El@D;n#XBhmW|!Mc) fwFDL !*phr>]Hچ+|ӭ*B 9g/)3r hY&Ik!?zD )w4 ҡƄh\A4_1zn!A#ZF_W3CݩD`we뒆at!BnX9#Sm$~~x5ݷ}C\^22M%P<5X 21; Lɚ.pP9U4dl 썇W]j V$lsR)Os)B}ؖz2h tYwd\/ƳkW׬@H+-RO-T-Ղ5 :nnOK bxYH[$I"d_v36n=BWCmd5Ca.Gg NZ!Dy9mXlݐq4j%: 2f|)xͺ4ŻضZ+w]G0ӖF;CUh' uNmӭ5%b5M hoR KOP裃S@YNvyeiIl:!6Ʈ2qF`F0lx:D6LV_'!/Ԇw¥Wۀ>R"6DxdcdrlXQN.}j۫F5cV /eV$vn?t v1%Sֆnd9Oho+84<_e6m@tP6I$*`bAE,Gu[ZϾ.Dtan3 ,=BFu/fqf$^BTPrcH:Z QY3Jmeh[pDcss_ ʛ;~5[uxCݧϫ_ -h޷g ϹR*Iϯй.+"vC+Hsx#bJ}RޏUh=v/'E`ϵ!kT[ݪ"U]8FSQc0xF@_w~zFeC:uFaUT=>{KtFђ3ҟϤg9]8<' C6P']A&(e7+t" wP]eAsiN;,Irj`H C:|aэ8;0ecx|D@&:$3XZ$5t^Zy3e^*>E$E'>`Dgw` Vm2!TLgѽ 9J%X|A-z9QcóہNNVX@˦4s+=3I;oَ5Ǥ j;Vbm|Ѹx`4FFP\B֍Ye@1'=T+*1H m9m~1Nukpb\+ ~~k v̄?Q9 snHwJ rVs*@(Ҙs7@A4_1zt!#&!tV 6!RY2q/(JPYЦQe5GɒB%#Ȱ""}?d~@gr5*I~xPN&Q-9F*Cc<;}PjL n24& GJ'K#@CU:Gi#,$}5z2c!ɪ^VR }8R2Yx!lߺBzf0g88/*iU y+0Aj-XAE"56xPW?^H#|$fA;جXK9Ҥd*/g@1W̊CITZ/Qf2 KUZSh$;ᷤ&%jb~w_o7 h ~3 _!Vt/ǰOQT7BX[3T10{۝=~0jC^rE!k a7+p˖XEISqI '9)љa*Ir]qIІRY;#c]=ַ6 b,Sj-ђZ;-d\ -?Iҭ(H,bV I3rJm!&o^=pLO{4qAck)ܭ$NpGQŌn^yoXg/'pI_O]9f^vF% 98нE^h Z͏"j7 ~5kr,,O-;} &&7&[dm *xVߕA4_1zdV9WndRTƵ-ns A(!zB44́^U-]D_<8k[M3(=Q(o'YݮŤJJ"{XLS2FlSZԋ>sHz֪Ůp4YkEvdOj>5U+M}7tF Ϸ(m9@oYT /DgT(߅AA4_1z'3e|+ͭa,tg5vQ.70Z;Igg~r6G+gȇx<-ļMF}6z{Fnw,ŻAk.ry[vKe&,;~6}4qƲ S%D筲aNNtPJ*b/v?gF;F63ೌtMh [x=t\W8Mۤpkb|"`eM)*C!M^#Mrd6梔iC˺ӄՑ>ґbxs4):$?2X]7J};/7sb=gcd* 5_}aS"f=mIu,.!8~Remo9휠 {!.7֝فgMK"RfdUp'5 "HP^n9}׌Ӯ'M}읯,/?(~/i^fӡ1toAd 'i25m9Ahwrh_U*oC >eZ6w}#Hھ@H(Uy5B~Ŝ#@XRP1~ɌޔI"\1ƧDgEw/^k{xVgM}4VNקLF8/5AE,G^馉Hk/B<%1tFU'< zpDgnK^S ~] '%lۏBUcq2j'?ܡ[:PJ]YN&E& Ʋ9JL % SDm'%Z+MEEסB6M9tްJޟʠ5Dցk4If=jE(es-~ڃ8ZNb#>xѺ@\:1|W0h舌,*܇ىd7%;δI.4+d[k%ܪcML|I(]A&??z/_V(]V\{2~"g*2k\xBW {gtPx│K&"%|^:܍M @ zj A4_1z-K <Í8&?kogNRm);! DB :'W9oL 6i%?lLSP0lZ GU֛QhOK]N^6r>LrDDq@0.!_vSd,-8r8u4Rn?$uUs>+nnO6.d)\j#4ƻ{@ĶcV<4P&Ri\gu $&㵅~9f8"`g:`Z@;2נ5D0vY[ȽK%r4MG :  ʷ&uB+7od*kBBEtIoM[7%b>g4;%й& ff_8xӄ8!T9C" :uoWj#] 1FLQʌ'^$䕑KR5[NA'*Cf@&R0Bb#?4BbOeX)`WIy?_|uQmK}9J6K29V}# Cr-P)0$y/͹e"QPS#Jb j1?Bvy[%est3A+T3#=XhUαğ ی;6[D$eܻzĚ" d}f[P@#+"vfoKVXDsT oS/k2Z6Ž*;787 ) ޚDrY ZҷJjYmPdi%>,oApьĽOꀆu¤{kܦ_ 8Z~ˊ [YXR[Վ.kf'CӺ3J)rJ?JGo+v1Wq9 l[*r 8 ݫʬ&vb3,x`GM` z lu?CުP\1p0:EB-ZO˵$ ]G&NF61ib*v5 5AWE4Ff>~pJ ~&zO*QÉy ʐλw~E>og]5 EZep7s:/;Xf$ml&e _ch' dDL"L IM70B J.nqx/n іRwh]$"ܺcx(|>`ۨUﴘ5^x` s c(&:"JHrڨ%Lk3YZXBHÎP\<|~ !_%ټqwH'600.{CqkR+2eje1{֊[nMDX:WkdP&}ER.7,˹CAB󬮮}+r[p݉a債#yfQ.PFvZxo8d~ZkxѓkzLpRdBN7؃ɥ+(`>#K)۽}C\gBj~QDD XNu <{`]o"k>ZQ!) to).ڂ%?@&ysBQKg)uڎb>}E B|J]C8ȏ40WV #•4ymUUV^k$%pobC:Y曒hX=Ov7IjheJT( P$K}#~!aG!4#OE+YfSIqfD k^Gn]20ڠDtؒ"_%e6W%6qHokIGAw Hk4`)S:@TMD P1ъɅ/-9N;My tCK18dL u] zJWDW1pE>ϔK*҂$Sg_x./:C4Pi=#ZB-ׅCPf؀;_~8[|ɟ/zJ~/fҐe  2iCɤp_yU {jIu%D ʎ^+OӐxjO^ld%j==J٣/Sq0H>߉ Mi,uY;t 6,]j Ïo@=۱YS?%K}rEq6䷍'GSp$qAc Iˀks,i:ڸiu` 깍/VMz#Lf(ᆭ}d(U69 TMmn` m1uϙt`+8{?&"mCȕƋW]mC7qB˳%h{aG3JE"[v,a0ĺ~!>jRtFn¶RΝdݲK%.!J١K`ba2 :ux(öF] aDv~:㚟5JI~N='WZ &+-."5*$ M_lwD}kz,s{%Cwals}u^ZA'Gw< $s3Į^Vrf~K0߁mxpfbƅ7Z[uo:y!XI&NKF0#I!0RlpUoˁqEtC4^!Pg"TDgj$l}ݙFoSL}m`-z7 {%Xe?n %Tuod+%vdoQ9?G4 0r b?_K|>7s ޔޥ)*}-WPw"Z$M-ʲTڄٿڴf iVTKc?Qy@\?0]\V(qFŚڡ2h F?4*}g&3)\(AY4_1zq =q-v)%)7"xb yu%ղ!]$cn^zUb==fjBym΢A͙r˵sAͪ .7$j,LG$(c'IcfPI#i6up_RxDŽ85?^pQVx?ѐaӄVc Fe^hh+[@P7Gݿ Q}շ3\V)R|s+3|ߔi[A6 !rtP}򋤕aҰ>Rg}v5oҴ]:by P4BN=3[o"@y}(|. k> [@AwE,G[qmMʿ1,aǧ`E!.tQZK^'d yBKC?vV7NjˡlT&ҋBbUv!ěRi72?=2GyfW}m,6|ӧV+cxcXs vb!i}{ Pz3SOfh] X;ʦ~rQ%$Ɏg脏R}_I9!]f$M7llWϑ9 fqDg ק̀QyM @.?/gZ5dЈQ%,(rxD(?Rp8F)?RlH_0-U!4WᆛuJ>xfcu0;}!B0A4‰1zVyZNSa?II.xs*Fl~pNQ(8d!/ 2p1CTtF,d*M<~nP0:B"Oy`dO@{ȠwRaNdK!X`ȿ@qCyns=i,*]{jS ?Dg zG8C-szJ6>!]@lzWXY?yڃHVlyȻ^մuK{eK ވNbTHF.aR2# ukkTA4_1ziZ NW :,aΜjZM{Afxe,Ic[IFyn2ffb1ߧ5c:<_*0c6b&=^c'{%r `aq \9apetqE+s̥ȍDO4AE,GScFF2 tF;.)z,"DgazБU A74'Kk^ܐ딸B5b#%֌A=`2AUE,GD)e [#1ttFIm\FVp.vDgD<'|Ay4‰fJ<*7f^PQ)'J& <`7gL_]:lja^ 96U^2a@&0ZtyDo':BXz`5Dg"E{ KFksryevvh,0fFcPzSpb,;XX3R 3@c 0o wJ+ mO+Cy( @ v@6o# GD F]8&Mg/f='ޛLF Y(bnJ z]^:zWA`˟ʐ0>~P>R3DZʝB!O $H3u;rś~fՆ4w +>nY jkx)| ߲G\m;{{f`aCӵ7%&"mEX0w_#}S'/R%ᶽM f$%:L<{L*@1}BV'a#yvyh֛|]u%LI}٥o +Zj՞RT%GDF*QkLO\ s_Pm{qP22(N2HU̡6"z-D]B[͗R:nw^Z { )r&wSї "5\Ϋ+nCh`*Yy*Dc}Q0/cbbePP lk=MHA';Ӭe8SqbiR_<šM+|n|)'.mߝ9CB`ߥYZQ)s_1~xTG6 (G;˛S9?нN+2f[";kTc=)'1`7 rNpZiʈw4K 2NR:No(;xG=vP҂\S:%i;kn8ʃdgAp}.޾KS4h|W|o{z%<=.8F 㩭]"˒ YT:f ތR~w\:8^>wLWdOr'/cl>NWwH?]X8}u׽B^. 7(T쬏!2JWPO6#ejL]|1g*;^߳{E_,rqV%?VGc_?z?4ʭgMl'@sޢf*/Kh֏Y쿄UDpvpeb l͸KkfUfج= ?%͘p.zGRQ6Gt lDŽjxR]c)u78X*vdbrLBx۱@,TW3WK ˙Kן(cl[9/,1BzlverfcI;K?P|n\P4[߬ g8tWrvO+Cgoĥ PHθO`4R oVPZkMsmI}KܻbG~Ud:=Nb'ssF FCܡkVW=("qεZ!-\Z 2<;|HCN+'cqOmf"szJp.;R?^]8o5! y)K`Fi,Ɛ@ +P6BP90-A?m=#D1tNdcŔG/,vD@!sf>a59 Ey@Έr^3k)ݪ# 0%X\`Xo9cL8ɔq1`J n>ʦ1ƘLW&Ǎ #ăq^˛ ۶^} * ;: h]Vbj GFy3Ip'%2YZs;IiDu@)C+&dޭ̘Ф,R[H.f ^w )[w`)釲bO괙۾[.>5t:ɥ轸zǴ/&$>=*ӆx@_ZZ2y(v#vT>&!dF yfPmIiCY -qkK~>atHgaWay7Au . /ϥ&Z 3)or;zD04q6Jn`{*˵rKJ;d d9YD>LߦJGx+Q@;@Z逫JTGɢUeeWS$\1H\ESnf \4+ z)Dʐb^f) rb\$h\}V|5 0+uZ E:偮3*\jXS؝4Аd5( ̐GRʉQL❪ӳ+$86Î7~~PV<&*0x$Ӓ8mW- ɽъS&PVƩLX[3(O֓7-걗ۧ6Fc-T?xqax$\ӲFP.W>4DUمkq/% C6290]I>_ i`7[:,j#U$t7Gߓ?_W TEȒ|b}PN1rt#ڠ-s3ˆ(E%?nٻ hZaֹѓC(@!x+ L2W ߟ^=R>Z/:BJӆk=Uu2?MR%oڬ[aoУƽ)R6q_ǟ{ XB~΂g('l-x2"^%W6$+{uo͉4-*^pFoǽB5 ȚWvngĞ~on8B6N&BjO8$&]@zOɭa'QƊNt>]JvO.ʑ—.//`ͯ 2]N3$au>`"] ;y#'L9lU<6l:0Y ־k ik8NwtGLiϯ5CaDv.k:BW};] ])Oڝj I2>{&Zr;:l~pu7E9[Hk׾7[P!-ub#9LiHiz vJ[~=ETyQ].ڟRU7 qԡ\0A[k4pQO`S^ռ׮aV_L{4Bj ˯^Wf Q(EQ\Z xy 5Aׄo c2xyoܪq5sz4B11=>S:>K#A5wVٽi{` +Gܭ9\;+0HS#yB}ShX_+2%`J>wߵl77X:K-VU8l.%UdEu_HقI@a+,vcmʼniDOcKFj~!1d*.$ʯzdnC>/irE+ƒJE_k~1tL4F>!M}K `VDFWXUs?q?EYBb;| _QL<޴6@ ~F}"I7 lka2Ґ38d 3tNގ1-^>T2 6;u$1\]/x*U GYKsȮc:ak^MuGB1D>@I( Ee:Iie!s"0j~Xa*_L<SD6GDwL+͒* 0b|3/Whܗb[UU=?Δ_*\+ »&H@kP"I'dß) u( X+hԪ~ sJ*@_ҋ ۦQ $7k1اu)> {RU㬗J՜x∉ Wq3=P6J&焕6>]kdYU Y2 |ӑp຅ |h#aȧ場5[e؜W:1;9XC_Oo]R9n.y OGoʾࡏrf85^]wb~~(C9al#qt"u(ѶB0 b ^7]:۝.S͕FU!KB@Š 1,֑Vp@c>~;kMCo+d6Qam(pyQwp.I)0 [Tʑ߅bW?s [l+Ea涛iW@ӽdO¾Idpb)\H7W*)?Z ~ +|c,`xyPpO fosHJ]-{+: =Km]Orn3BF69BLq"IJ$/m&?p,JLqZ6 H-;s[AVf*^#dc^)T6@Q 86 |e6|x,\o4Ev0`W7ma PQmoZɯVaW Y<CDak6YildI"}`OlQ'72˾^)qXd%0syOگgfgSˉW¢mHF\FI%f*JYG"r'"@8Ve [?Sv y>$)21YT loV&88FwqػHQAh\_WnT/Aa" iOh \vvnn_ DLji+H|F&8ħVs;:j݊b*eqB55bgA;@Q qi*{m%wo2ԸvC C2Hư\ᙢT[t HWlVP?vI̩z@^YY,Q"&Oc[!_``&٠٩3]̹tc%U*˥H8aU mӳ ؿ|F~,/dtQK`3wkvE>wBeV)PjqXf=Hѷ9dj?pFSxdatOd`9Eu j]IFyy,od'!a&=bC0B֋4lb#}`{{r-abI}# Л&e!"|DLbֶf ŕSA[Obm)aCaǴL ?-abk_xqCb1-5K tOz=߄{ziI\K/-iYW*<8ig7贱R{s%D.ZݧX/Up[Yl9E!}HFqobػQΌͥUp*UEk|iF!K-|fgsIwbt)Yߥ ,}!pE^fթ/ )-r5HILWYt@PI74(Nt ~ҔawTE"+&GE< uP/Z}ao xF1=Dm.-${. 4r7WHy>mD`7 N< Ǣup78 U yKyIu}'M|(9P-l1yoUdIs^3T{Yiھt˭2;β{{=:L>J7V~S`|ٝvo(JX>n?_ d)9F`1ЂmݳN i/Z{E VD7׀삒OPw #ʲu_/!5=B9)HWaQ΢4i=~[AޜY0!Fb^vψSC(~ NGz05L?쏁t4>/*Dh- ,G"%St H!AB v>aEyO3Lx._sR!w?#tj9'0 ;nCSf>DId-'hS `ײKu0)Bc/萻(ׂwʗ1S,@Pۂ JOQ,~uRUAcwMKqU+ey9#A.uO"> ?"2ZqM^NT{ mr}\y:Ir"Lyc|!N3x\9d|bu_q/ 0s,MPVGaSL͸/ wu%X|vz~I͹iUùpH1Ծ5A~ Y\hmŭ40\͇2A<ϭnlpV&Avgn]48!YDj5/G@^$8?.\6 vmܖ _a9m SR@}n;xۛqxMjX?fǨeHB"=TjZX<[eW Rc+`8 ~#i}ɱæWȝ<4OжLFYDDm__OmT{'*r%:KQ>uivNjӴ~}:Ͻm0X݄uS p'eQGW€j"dNM'm-M$t:X#ar/ ('pgi29>(;u1m;sŇ WzB(xZew#guA1{b. Uw+1\ڥ 5/_,"i9%qh<0Ӝ VfYnbAqt/>tKKr\Guz53?"f{oO7Lx=0",[xҟW06KKD$ݒ6]bxn5qqy!ru$N4Lv-R1"G$,5T %|]o=%DVhAc/g,\EE8By™dpmO1^,7*Ya^{o׫LZ }s9[%)[;"*Ic)eRߔ)&Qi,>= lTy:yv8y7ޚ/A#(1D<gO2s_j$[ g\$A5Xo$y*ߔfeNAx+vlub"!d`cE -dY[B[}H7DQMb< E2S>eWFLv$7 Ilu\Jb &Vs"E&+MiS&j)?c]S5ii(stkozD5dGC"vjN/o%[`O4/g+Ob嵛X8 c` !4p_%Wk-x9⼯yxxF>%._"a(wɉ/=aDO+h8R7t:WYs#gjQ$w~~5Ͻբ8I_QMړ&ٱ07)'\>݀TrdKP96֬"}ɈfjRw8"AMw8Ze-owbfU$ y~ܽX-[WE:?yTG&gpd|\ W0Xp :}XKK@J.79L.6VK.d|;UFhz ` l҈qaz6VtDjF@H6&D4-?ݿ.aS\5 au7Q;u j`roetfNS(ZMZ~E\pS#KwDr@li#ޯjtو@oOIl.ՄIoz] E1C`:@R+fBwwޤ~xXal1,Y/[VUR N٘7~Ӳpt7i',{IK\}ND\շxN5by6 FJFLn(t[KQ[+Hu#'7薚 +ok;d$*ύf+zfVя~S܉u%M1ļQ"ɤ+˪m:T?ibJeCުj_x/Ah) Scx5o}bW#k\>#0U\Z;#=;)[s<0ilqKig|79Dv{nTxLtȌ~5(J%,|/6!u`5#b~ hU>x<,ޔ8;P#Áp-e9xR$Dp V c6u\P27ytFAɟg2&ex&$}= t.A/[==^|Ze^ ȶ[p_q; dP2,xnW>(QG '7S +'\x5_Q)Yy~[̿k;[ g|h dp +JhQ> mC]['F Ú1 O&;| I ͜H"Pq/ߧD.|8UO%e%ݡ/.9I;s2=WZn-gIE+̠ &4 n׆9z9L&BG_jrwf6Hί oϘPsedreͷvsb񛡂+)6а#7κQTxC ]Xcwe2ZlKdqB̰BN~y6K2SזF?8 fD DRx~a{Ck69^V1[@3Ն RqyVb^)>$G!$LA{꧰RWygk/t (ăgRdNa@>L[`B wy\+:Tʫo 8XLMtQ;e*\%iA߷ C{>ϘhCVwKČ7yG#ZmB;*{UF?溹ru*įTU]X[|`=@vkF_Fє];&8(.Sva^Vw3F}pSwN' TViZүB/ (VAԐtoWΕ?@Ij}91`*95Sl&[y|J%Uyϊ=G6ҟMxK?ڬB~ bAz*ک(~  9$y, 60 "?ՏJ7TL†yz%Wh㥰 8G_NOr"̈\ E"#UJ"EU9zލo'3YZ<6Q$obWōW[qgr>5Rkn 1ZXJ'J>p:+#'CR]L[NtuYevZzmuÐd[ ^8ojӐRw[Mbjul^wu3#Ǫ`?7&ZY?;B %TޱGɬ3<bʡAZIo?GOpydNN zXz|}Ġʃܟ"=(}m <k\~F!Gljy㓍 @$/GN{ٚO+SCAYQ2J 6fVfC!Z9Dm3o-C<7roZ! {RV*G~o%X sN% J'o8` Ů'yZB[~ z W!C<CsLҶaBf(>ϸ΅H o;?Wt\_?U1ɘ X$kDofb4n"A p#I#B?g5 C]!oVhx~X"=~{ҹ7UY>")F.JT,9#fv^pIUBnJ6x|Ah0"ئqKofWo.hw,C3#ΐ 7~#;V< kY9a?s і XܔDi(~7K D;H AرP*Gbs[ehajŸ]3OF?Piok 9Q|8:}mdUDD+nZ`{cD) h#v;8>+JlΌ 0 K/bG?v`BU",KvԠi'?q6yJ%Պ3j!tM5 콿{Apet rH6E(sqdWzmS>6QMqyl(T{_}DI3I?.f 9Y11'?GG,7{T ({<~w̔]$ҁkz|ĺGT@>|9}VcTрqiJxHgT8lۤT".M')i<ߴ39fM^h-[iKO0[2 "t`ŒFHڥe@d[vU_7AY(F#YH'j{?HX(Aͩݓ#"hJ>::)0<.( oYa\"JGYǥz(]jBY6UwGZeQ}ȩ۫>Fa0Ėuo8pu1-WU.4Ynv"Ebfu\ 2nv\DlXri=Vx΀BbvkK (L4e!`6HZfV,|#j]$@j`Y.H$,ΖMyt eUF7z.@:ɵEd3n 1yH8p/|a$W,CKBDUؓMЇ 9`.OgR5_0ei`Dmlt qU DkC23<`yà j،?fVL|loP"yw C#F}FBYe\2¼R;K&R]wB{ V);pc-rkM`ػmJY.wS)b5yM?j.l+wP¯Sc|l逕Bˊk‡[l bM [a|̓n! W/<'?[UF^stMcWj#ҦK!*ku7׌WQnج4i>W b-3єv&J TP.>gUaP$MpO{T Tn',2TI͟D#k{zqfP9N1_ZvO4)Q3AKx* *1Ȯ!ÙsczтB[SW $0!dCܙZWSF\ǔMxj!9v+F-DcKFf'6Y;j0N<4ڑ>㼅'M^oLApwU2 KD } Xh5+ #fH^&Ȩ#7b7\l,ej HL\ВIx<{amGM9- G@' A*ڶ=EK=My4fx oUGxa BAr]@\9 ?v[AĞ&tN=g>fzgd3$۱p{']v+-yX0^f\(315X* K h%h%}oy* ux0֢f98BZM}r35a@z }>gTrV( o_m3{빈@|B#Տ=Db DߺjP={r~'DbnKbj PU^s7CXy+oܰȽ{f$cF"*,8a"6 fwռ20>̦5z,]uz|*gc{fq*uqЏe{m"bZi }%_D\Clry!N<Ś ) D~',.fc` =dz +ž zGvwӚm{~)[n8tG.^& p:M,٬| ¯q|C]6#PF[؈z~; Y py >)v;=6$'/ 'Gs/Sl~\%4a0e}銕۟FGs7|f}V+wq*I YW3UmMJBc=VMXMkE4L\Vgν֭fT@#O󙀌=| p7 Gh4ܐ _s ,aJ :~ u#3@Wݨ?^?~ӫT}k5E\OjZ-jք`JKj`GddzKK&AxDo;Y0/B)뵢sЊw[~H O4ӧR:tXH^|8,BtęllV爙!gNb y6l.}2E+Cylyޣxlxw[X!>j*bxm@+_+[O_Ha:!Zƣ*㛅9K֣;d2JZm| k,8݇mBLB?B1 +9|Eqzf 23`_9Br_ +$ɠp|X>Oد۸A~i?!z-Gbq?O2場J\cP-ѱf,tMQ%ȭ0wdž H?I M;2L)/l{%̰d5˞NTf76a%Kh=u U݌^(Ra񏭫C7^3 RL(8:B w+h»{ U5@E9wu0k2?{yBhՖC$X#I?Ѵ@OŤUn>$5&n܊؈ y3J"zۚ &XĭL[C?ĩ%=}6sNɎ0EկTo*@{us Tmmh6sa U)SCd)H$?Y)vmJw |8{jq(MY!+d?kDAfn#=:|!Kd #"w9xb^sC⋞!K][A';T̺YNyK!!:7QTZJaQ󣵫}Zj`*]*Wk'[Cz'2+l1*_ XIaўPg}[A;_|MVAx_ _~OlorL4SH̴B- V,'8:ARw/dvqᆻIF!N@qq>CkڡTtʱ).i!?*h{7':my9=?Lc.6As^кT!'L$ٞ0[.2(ZN ^&é JW5'F'OfdLQ_.KP`>ֺaX1Jo3*oac܅ՙ,QΓO|Х\T}$!X@B$"sLOE|KD.=H&UT)t3d2^#sEIߠzQNB"9ۖW]`+?VNc~A?N&70-j fhE%/?ZÒB)0.k)4Yx6`k >nM d~*0/3Opy|΋UnMp;k0F&(% qt[v76ٟlMQb`FNL"+@k-El(qM `.+|V^k˜[^jGwO倦xrEN֦IXpzx(QH9VMuA pK ZhMÜhG;S` ;'#5r1gTYzsm"R i'ț۹g;^̍da.+A-%lWx ]> Cq37dm2 jX#Fėts2ħ%oOǣX gRdzU/iT$I&jA0l?jTlQ蝮NWgq]]29:$ 9?3,ZJ};4ӽmgy}jÃ@e)QRs/Zqa aݬ 6%h=VcLꖝƂ vx%]+*Yc6 ̟xZ# jbb%0h7M 5`Of^;)dzIׯ“VUwY̮>B+ ',z?9(& m}Μ ^kdQ>$o΋ ծk=dk'MZ^+pܱAqo2kG)\ j1"Whغ; X1lå` ӑ Yd{UJ*^6iހDVBcS`V|k2)ec؀n䩤++MmnȵlCd{7GS2bw W4J>kr&Z58^=Uہ=Wu8!6E_1.;,uY\SBe05.OrzpExy&@`fuTЌ }n8d'EGU.qPLd8mKxf^ajnv canc|4&`18_$ʓKS Aro%Z)\ޅ.Ez-mƲHǔ%Sv+6Bdxsh'uv\tz C%CFLW;~d`r7]'T%,qP8 l]7O֦k PeFRDKm61-SO:diqyJ}V 2I zJW ;.`H mpBO̹!sry]鑧κ%تf?ETCirໍ(+6Ck;,'o4\:#< ?!mSk=sMPI63ZBO 6dݗr /t.3^d$]8'oz˲k&)XIa? %#&ɤT: _rL{_8Xn-l>N3_(w7˹ ;dYё}#N{M!w3K~ $`LNfт#]} *( kK8]*ɖ'Ƃ0XuKmdd>rU&De^hC﮵!Fq|!,XE*WxWʲzvBD-Vzb|`1Kz-ڗ$JN@6JGPcϥ-hxdl6}i$(-D4LNh @o(1$"iY'psߢ_#R&4ǰaفT!MV^̝}^J\?:<=¹/ NFʘލGb胁Oqu1] M[Trw|ƚ/fsWFXq4{#tHBVGxBo`Eզ7O⃎)ϵK HRS~|^xN`M rpU%T'P8mCۤP`3z9?O.Z)[FVI31v5TϷ -,-՚1үJzMfEG IzD5T'ZƁ,kP{{p]AЍp5eҖnXdsPNVn& }T n[^p4:mөyخJYځdů'3b;גf#gI`-+ +\W+ &R-aw_r+7o/,uL'ݵ?ѻM͞5½E77sc0g8ъ HF8#nE貦<9AFEڨ~ݜ+@Ia±u:bVԽ7`mBZ+w"h{(c_|3{mYHCDlPay .#_wQ3sP .`^ 3xyxe }46X'P3`i[FISa١y~i m]LYe= S+?5KdUGF:G#^k[4F34Wh"Hx*`jzE`bT>K5aO&Dm6n+F,@ ;Z{QބpjvZ9g؛' -1"%<+WP*Xm8Ա  os[=8 /<5 T-ǂ nP-DBPj .`iN|>,d*znUO"O_ 3ӁJrً}h$|jAiR6ASE 4i Cٮ)fidZ_lsb>gvou,[R;\+Dc.3m /N̨Se3u+&B8пd KjXVm扱<SzBǩvu  L>L_$G"rC:l_i!=\􅒍jpc#˭J]'UyCZZG zBޚ~qdG^\-Ʌ#k׀emv c߈|X&t3sܺa='tl"iq1 2T RIqF wo|p4G*jetG?@pPՎO)fv22ˉYc6:thO<%8N dF:D&48<41d{=D !D'oHUgFBې q&;B뚏d"Yole~Su`4>xt s9ᶒW;J,sD1LwNסU!L@gST ' ƹS7^[ses<}Y{)ƚ؀>M뿖4g»Oyt"U_tu$"+%/yZ5m'U6=e?FGM_ku3S3>6tGsW-85Jqk-,fзSOTqPzXLNЁbCgH7Y{5+T2?3No Bh M2"ܐiV˦ܩo2+(Xe+7u¨f\/XuL)sxsJ>!۪ wԈ1fcЯ%ME3K?r ? 0 NO]mitz?g Z2 k4jO|sBiMs\5THǥ%b$Ĵ-Up`NHO(yvIdy5tȝL?ߑ$&|ΝH G նgf5<kKڿ i !b Ċ]a¶CͶǕI{ouG3z (?Sv~=-Ym.C,iD"e,Dk\2:AԚO]@Ҹ#p jaK9o:dݿ?̷w\D#yp-Zo~FW"!SX!SA;ƹxzf湪E[= E5lcaqh/0Q0( *Јs| dlTʘRjgu"ߧq: `dlJ K#U(&¦Y5dA=DЧÆ (2 loH{fo}/Uw(N EHѰS(>΍uWndBE4J5#KJa8 ;PuK X7]1c..1mSvي,wRȴC8&(OtyK5=i@tπF_":[M܂5hҬ,RDNnCc,͵!4q=G&3)}iO!vKl}n[/Y9*_iwm`~yV*](UG&Pn%3F5*"[t+Z̶teύ#:c?<Ƙf{WDsRL8]+/!/`E] 9cFR-73hG(b%]9 /1^Ϳ/RYs@);.cIxY1vd}a>ܹ#3dnbԮ9"?y,&~'--̏9vSv>` cM [($4+rM+ ݉H#Do~.?Z_lRH6ZF-WgXM.,Ŝ6oA+EC t[L>:mEZ>IтB ό#c0nh0'87V5Aإ@Vnu#2klpՌEx,Er;<ƚ 93"fr+]7|Y^f 5: -8 8 ?x#QDĻEoC~TeŤgq#GpD(}(V phW5y)r\ѩ= AC] ug^u&sJʼք[X#8JO*/aʽDS3h۽FB#/[Q>NBK&tMÎsU'XgB 7v7F[=y X"Zčѩ~SCuf&rZw=؈c3OoWbM82->sab!UѨ J KP_=ޑ~N@z:o><M,$6RP(I(X2{3˱އP58:\}tbCO1!ka/'psmD@F w65_ViҾQ;8ϸ\ƲMxzr к5B߳x)ڦ k`uS=0ȕ_2 :Aiݘ$utL[/})& ~ I%zUbT)_nFҬHjzg5P+A` h͒PQc"R-V~d\U&ʹ6 fݮ0PE<]> #~W4 Q0v,Vp,sZCfQj=p$z.dvz҇%, :3͐uh\oJjn,]72'Y8uLN~giB3npN3 x1^EKka74?/%fv(7x`su) ye9GCas_9԰D D"bT-NI3 "} 41\ʗȱ]_WAk-{z‹~lP?޽6D+Czgjo2ǖ4ڀ\n]/e>NZ %{jċ<Ŷ:*b,k}rn16kĢs|(cv)g t gA"lIeXyOE: [58/Y2-2`X@[I\y$(y6l+AyhE@dpoP9sߢ~?~ȨM;B\KuUɒ"i-k͝ZstE s$  rE+>bR0gC .X}sAC+9z3gFV @f=9)ĆOoAI=l$y(u? y5"OAeS1&ؼBT,_ZQ"߫jBʸw2 8}1`3DgG\Qz#Arw86Pn,A+9[H' 7,%*~YύqrRY;Ն@gu#搜wm]Rba(xކ'.vw_h* s7XYquֳ:<_3TvfݹWx;5@յjpJsI(xՠwȌx"tFs:,ƪӀAE=Rgm./@7) DgA4_DriW7@${%KVM5판,-2X/6ʓ\?ݗ^lE:5aiN-s6lFIZW9.A/E,G &hZU,!*NtFVPDg ׅҪjTI&b%Cn x9-~+>S=;,+h@AU4_Drzkb9}Yӳ~z!8`3jQ[ұzuld9X `@g*:aΨ+q)q*TmY-AsE,G ,K~=,tF I)DgA4_˚$3.g۔4sߓ@*07s& Tw8zU$+nLΠ!Vz`xa@# WhdUSPQ/_^2`Ysexڽ:L:JˁT&k*6G>Hzt,@wDɶ0{85a_0h`چzw I`'M1Z_:+ya'$ˤW-\ YP0;ThI;?(ԇerrITnmBzߋ EL4A(xPb]A&&ZQuthdP~׼B;ʙGs:Ԋzcj[2ɨYAs 4M6_1jLQJ mfL(`؛<_qdԂNqRа,(oXcIغ|Ik,G^5Yž[m̽M*7t"㥆{tTO^p(E|bYw`HbD 5 vTҰ.2 <[%@@L#Q\77~8FWMO8EY[&[㉗K:D`TER/I[BORkw6jz9FT۽MjdZŷ^,zttU`VW?vԠU=@:6 5 L.?ubH8d^l6 H-~K/-Qb܂3(\vaznz]$*.&V-^C0A]f/Ï*us@-Ø22}$=g̰燕z?cU[eX~K G+{dm(nJ( *\hO+;5(^ 1սxsd8HDLF irdRU(fue+ӃC]-7XLѹ݁ n)흌UfCqE a~QKJ$8hݾT> yu8,|J7ā_С>Ma%M j7St*+TO߬Z})bMw/'!C ?xqDpjĶ\: ޫ!hyh.;SfU2j1Na\d#KӌwE$,nyZw֢: /W9sHeɻ]ŕ(,C_ ~.{XqD<V$+'%tW70i>DwB_.W)q(㇉N8k3T'/n|Px'r,tq;/?~B8Jӊ5s);Qk;P.!@f@XH lbhriNwO4, VYkB&װ J%9qaw%͝^aPMGAE,G '@lʆB&|ԓbS@%ğKkpqNj@.tF AKDgibM?{6JiBCK>@k}uG#  x'A4_SHJVօ{QDhy#m^ +h.Z_]uʁ bP|[0^ %q1{Xs\ڛSJV}N0pǰ.fq`ȼzԥy֩_=o~b(y ^$ $q yVl_ĩr`:[,c"ޞeDk>~9k:.̭ү:%q8f=Pujn AE,G K Jt-,Rȑ9F3 \T"N4ua;]Ì[c36_ % pe\[OQPM|œ娪e%̭K8*NNIWιZm;\H(.%XqZS+TB,~3S :;ΐGd#I (V#WJCBƘFgtFh+퓑>UW-_tXo&48݃M*|A~` `1 KUo]BLzTw5/&%%9{BOC#Cai9S7\z~)*B9XJ@Dg a~L"NVabM^浹?yf$MUGV+­;TVY~ l=u/a]O.z[3-ݵgpvI,"z5lLI`C*>4,j*Y`K'iu?jȰ1 ^{S-F>*VrX#EP(]~Aן_Ǫ3BДzH.YApA4'+)`0kGX!0>uN8xM@N֮uׯH"qqsOaų)Ux{G=q3rIQωe,~RS$Tp"@$B\sQ!gX_bެ FOmٷkWj9gvaYb 7έu}IvQ$aF?7M82G!,qm#4K*O F]O$t0 Ywb904}Q_ߘOpqJbMCpCI:z WlJE)rkZ4҃/;2 ’hc*'wL VΔ߮F0 QR#QsTn.ĢAҜ "ѬH8#֜*\E6|\||Q:B2_Fws-YD\m(_l%+B 5hs컛j- ߇FE$Yr`-3poks¦d:iv_͜$>_+_7ՁRr))1[q z%TtA?E,G]yv6 7 W _+q GLT.L7kb? !=H^􊾃- |g;~?$3nŸr'5rE&7a35mP(Cx?7̧=c!9@>;Qr>W Ce .3!g>Jk(biDc:% Q `%̩}:?^?[ E6$}> 8YwގBvS̜: F 4E9Uv= Mɋ-=ǽGYBxl%,8ʻ -LJ5f`0_VAFЩ97;bpA&Y}{ [5[QGhk-"ksC6!.~r -SקhdEF O9EI .Ea^W.W939/H6 9Id0gیsW|8/_yAC4‰,+jZ?@]Z{u XN3 ?sEȼs9=4OFh(n9po(C2ڽ9aEճd"Uύop~7cq%[:݂#Ͼ&f.ކqM<{b >za`f >Z. ܑJj])qu]̯e l؞~u8dJ&DI:uief'σP7[SYL{@o0@v G#q$?2;Us|-.Mt>ާ,7&qNె!춽JK o^[m@XuOד%Щ2 Jd]uT[D/y4Q_#"w&V"hs@ۡ]&,z))dNi}r" Pzef~c#;%}C Ԗ),۫9؄y((Z[(1;*7;FY˔uƷފF[pQ!CǬeM~C<0?~!)LDXފm@ E3M)MWożsmbDglz'aFؕx +~IDYyTd{MP[8pOBE\*a}l7KQL^W,8vnK=Fo_f S&u!=c~{rwYDתZ@bk{T s?$r UQ1z j>H-4]h0Psk8X㝠Ad=ȹX~ɸ/.jT9H]5cήʱs)G 'km5!- bx@HcqBŬ%_T\N襺KK p=C[ i5@ՆH=گn]uc褄OV a4a;6&e2 ~o1GSr+@siS hx+aXb-C޷M,4KDLB@*#;DL&GJ[<1x3=E`mPX+{I7 zn>-~3H~U*8xmfTKCQW*ɇ a5-zk,d)!`=`E-b.$v[<&ݒH(j7ޮ7&)UuG?UFLI8%'Woc@@..fB^Jp̲u^n-Bq9 Pc̰>Lvqo^gqZviXj1}g&~B1}9׎ZUE{uͧ]1ܧ.JBZJ-OlZǖE!Քarn oJ&j<$[^Z 3*Par*0pϘq`5XtF eWM)dW#iTB@]χxi=jW9mLTC\ȫȵ0)CpA"O}_v<ǑGRFicKp3IJg2] oCQ%>y]9J U,O;إ 5kd\0Ƃjs[5O.$_-Tͨ"a`x/A4_A9=.:P-+H`tΟS/!Fٖ[pWKf)|žC'Lߦw9iDl}ӭȣ9߮]Tz-K)W /"C ,<#ºj<(2#+Qx3l[]BX?Ty7(2`)}F?_cG]w_\ϰa6LCvzTB_ԸPMEkZZZ} VecBBUVzLi6Y.<NH0&vMlC-eYaOXHtcv #8lʏ82 m l ձ0&c-p)H;Crr 595+"Ҩ[IvzvoTJ Kh5VLƐa5E> ,\[O[Ԛuh5&nN ^*;EΝ0t!3<gg3Vk̟ú%ÉU٤K:>^ê$?D;)J"b6G4a(%v{E˿.f x"ME>m>'IZf[@|g젦95$' h#Ю!͌;{sThgq':?VxZ+x2>k擖6?T+`Q% ĽvO jKvmi$6?/,&Yye";\ ܛT 5u~x5]%3o1즜^}n}8Z"%¹mP,LJ=],ZgJrIUwww  rArXM﫿Lp_Vi5g x?u)َ\3G'BI-z̷2v窴yE56MSp'%l&l!cqXK~;tT,:w_VS'01+egg>\i`l vy UhA&fD싋;g`\Jo `ѯ盳7>x⊮ڟߖ#o ^+PVD/ tFDvm< 2*kc=O=c!CEALٟG|y4q]Q*‚WZ)#ޕyaS- "B|Wjm$-\䙸MۂsAy Dg .aРb#Ap@ hѼ .@"Qvjs5"ߒSb$ )&!bjN Imߐ$mFP+~A4_`_+#f lYs?|Am ]rXlB9!ئ^awCF{ꮈ`.J2!YcTr1/)$dBG=B|G$QDe#os~ө#sClT5 l{(t_|qY!J1wpnN}SmP0??(ON6 I_aVQbc^' }*G +՛p`T}һ8Q)ÆSNUȑAQY))g/&^n;! zyJ [DŽ\AWA.E,G Z)Kxh;#N<+i:A?Yrq☧[p24MtF wMoӎ W;m3ODg糁 T>g]4ρAT4_tY&-&Vo~UXyhoQm%k<~imݑ afrĢjR<'2)SۄU&% RQS> ^,=3bOw{mhDF)6d@*;TvgOuG$#?OdVi9™ !|in[,آoɦ(ۏGٗ=6/dVn1S WWu$ f#!10A "YT؞|{-R>T&Sow2ld5&!B^y}fSNgΕ)fh::`Sڿ, Gtwon(Q3*4|Pa>kD>ArE,GiSy2DP\#0:tF# wWe[bJA1V :DgA 8ؐ|}FDuADA4_:4EAӥ 0.=(7AE,Gb +R*d:t#`.tF-+Dgz eA4_3䝀LcԃPx.4KvOy]F@ c4ᨛ:`~CHkuPʇ;eSaѣ/`UTo5Wf6 g b%R9dSP١># NlG &LuP9CIdwܨXte6xFEF7.y޶/pRe~ba&ms4)w}赥Qc1wձ=tf5:^qc-oc)\tew@qt*KK,R6p;}E57e>smѹU?삮Н'I>3&89 TfD5S:wD4eJL3OV/g/Tې;A%fz BL={}$̞a :p7YŀD>jХLf9ND/2\P* * kQ>tAWBM_nXQC#$(vq3=Gjp^[e];ڍ`Gc/TGFv>KG8ؼOXlː(rU|;Y:q؀.ͦ JàzN4\1l-W篞O0\Q Xe':&Q1 ^ ȖQx ՘d j=+}J]* ]~99j0tӣ!<ޗ'hqW`-HNT Ȝ3@.J1caAa?ޣ 6G+5ʡX-^[~Ņp$j3Mdzdž),L9Rmf؎^F__N͏igh3͌U5:|uЪȢ';mMX :g&:#C4S!1YJUGiyu~^_J~~?Q$G;P}3_7 sR q@*YVY3(FZ /RE?Zj=9},yY7nXt/:4PQ$HmU{Ȥh]ILE#1ehJ T`cyB˹~ǂb7x {^ tIGZ[ k/k: A4_:!oR7V=a_bWC)Qchqx̌3>]Z nG/i:-up˶ܠ1$Fb8R%iK>)y0 w~[~X R Kid^r?2 +Eґ\ԍ==\YJ2ufm !{iwV,m1+3t:j413>@|E<$s|%=R 7bJff:sJMy{lqꅌvi1[&??6*'FGvrR^nv.|sJ x]ΆP+WO |1Ҿ9yc5I6K^-qAMH=4al@]A>E,GӢ>|y!$H]νJM4*Ż GTbES :?;^:%grI1-^%wgW쾶GXL@: هLQ\m{Ђ07GbE[[#}ckH阒9$ZgZ3H]ަҺEq8DّiY:]ڀ aU8k9˨<\&!6-߂TϽVv!P_"^A5E}%57ZnkH抯/YXUeM28Ь\- ӄś!޼l]A{+x$ L+{x kH ^RKy\lYA[]tF&ަxG2 cFֶD͆LIԚE'H:_A#Obau)پHuH"Pq\okrNSYp %4)AD/ ,v,<L)+!%PfHr-ȓpBY4'^ūdfrG$<C2Ղ"I#H&'x왇;Ucù z,Cqf2ɨ#y9_[@q7g|̣bYI"$[>nek\jğlhG|n]5 (_Dg&'b黁\jr+2ӅG/XHl<Е̪}Re-MʺyBl{-NHU8Y8V*Lao,r (}/aRYfdL(EQh *vO[ӄUnbOQ9yKn܅|Z&d,.Xsw$N!J vqrAD4_O1s j$2Dϥ6#걝!fu>P.GM->߈TphK穖tQ-,'L;1L?wHBGVJؾ6ngG-0+b R 1txkod)Kj~8Gx %5oUލ8OcR-P&G5 XJ\l5,!/o;DgO"0:Z4!4_Vb248YVd Րi~y~b9&ɍZli 8@ĭzwӂK?$ì`AbE,G wn77E2ѰM;u8wɒYI"ew{lԓh~o9}]8gJ綽ubtc,56F;U55IOXX: :R^u,s7a#7I 3lӬTU7dެ{!ui˫!Üg\ZZƒIք _yAdcZ jg wDg&:4"vL+6iB'D{J ;zP2/ncuknrVVUn$Yz$1šV.̀pA4_<[Canw8W&vmak^mV0{:xTZP4V%fpμ&vߢـ}DP FwL?:ֆ>Ʒkڜ(.BഛG(RNg%J߳_>'"pK5{{>jCU:t!`-Ib&G>}+d7JF֌prs(Ob-?mN#L3·Sa}6P«TORπN?@Js^cd Y׏azİ O5{nfwHfc'^-#Z;Hfx*R׮:ՠ= = Xi a}z1_L.йum: xvAE,GGx\(’=9*h,OM>['Mz`ωb8/XcC>%㰫 ַIN{\HH?tFD̘;^tZbS$lDgQHp4eւG,ð*<~(Q@fN?<ɭnoSqA4_!ʢLYZT e,GcpC}pF|B)@tJ"dȸ@f uFVP)r **0X=:f#E_&~dl`|jl)i]aoTs 2E om2LwTn;;^WÜ2ȩ1U l|?f}"0CW_P#u ڔ4w'I4߹Ő w p9 &FTӗaJXK cx HJTVNKR*iH+-ku3JF/&=«ckmgSCSIN1\PMlevt"ۯ@hq׹ j9$si#"Zː˧Xkf" VUu< v=Y;pBy'~B/zX=V,u}aֳ[7o Dg $uLJQ /рKL FxC#dn*}덝9(wl%~\6^@A4_la:Oߌ7~iwqYDzl~ QJ{d6ekɧ.sC]wc댑%?s) 'b㱃1 *s pio18psmO9iX%X7ͯp탩4,ɹ!j|F|dӾ7l+R]9=I|5eM&*őy1A.E,G kSd]L@B\ұ,Aōef\B$SZ0P.#*+N$tc ն7<q䩇-l,E2L?"_50w& hU#5`zMtF&ᢗcz|4>iM`$MQJoʞZMyJdsdox.y !bJ(jg9ʎ& :85|@ ODg U04;Q<˱,Z{(I!.*VY?(Z gLLc}/73<{#fCs0L2 ǢRAAT4_lRt@ Q7*p$\u K=NJ>ԈM9,Rjnxhv=p 30ЍB\_y[4T5d;S/8Oah!|6j|I\IbhhY-ʅCZaB$O,ֽ!g?&OsWvC3UBFoIJ#+J*5\}uvlBw`}3fmFBٗ'f!듌nn3/W7VW:&~[Im{=>>'mtNi! g-Kw<apAjt2(T81gmYH3H d_:r bs2UH p2CzD%6R*!+t^EM 7*ozf0K arS[@?=.y`w7;G 5;-I5bjBj-~Ӣ B^oNըw}&`ٕ;w6%y~IqQtU3hy{.xpnlugT}NkiGo&̵% _]HUǠalO|)z ):]ǟSl=9]e"2XHM`I{E=o%SJòCNkШM)!ۣN5haԘ7K$r9q @{zEΐs~8w輾|ɨh~ J95M:{\S&KCs󊾱=~'#1+ria ਐoG @c 3kxӦ}x,BdT4;0V6k Js1&u5 A/lBIi?.y]4w)^̫BNP04 ;Z:29ݞ>`ArE,G ^@>[#qq$=XA+wU7b*9 JA&KM]4G6x4 õC+c2[2eq[l"7Vxv?2M-sm=ؕQgouN{fH,1ؒDq=X'#u=ö4)htynDj+eGQ EKªe q r͋"$%ܾtF defr֖8ABeF?|2J_њ3cz74_* XlPBt8~ ~Zs/J~.YZQ=oZ w3pZ~Dghs%_w%[FS iclOΘbo G#'L)H`ӌ `znQԗDb> 5O%B /.-^d|2˴e A4_A h&Re=ﻆbHʑԶ|q5ϔ6r۷@uDX9?˽u_Y#Gdph_T"xs/H-C -U`u7aKo߫$DlHp<;[F)Qct]@ƁAE,G (? _kpLʸ.v~qK|?m%AyIQ .\\*\w|t]זE[ fV q;6Eq.ǞIp6Iea[$(@ËBCq[3ȧdUPk\#*ByuLHdx ntF eFhۮnv@0MAPE>H~%/zs?n4YVu:4ؕyߠJHc[=Ƅ_1=@(8_:,0tuDg 3㮫"xɀNTN$)J?e|]^0CɞV]kOhY^<[Zƒw ^.UbP ybA4_rl5A\wЎ(NtegzqSPk4K ^9C-tTZ7H a  jm#X&.:^w CFY Ǘ~GRg'5W8I:f;GASv6{t\w?On>WD$.ˢs%ޣź c7vs2:w{ToeƵ t$l$`]?@ .q[9y>%@us=Dc|hcY mt^$kFn,JCM&4 D7B9:/zd〔(>پ[a2DTB8>2NО9C\l =/Kt$$[O8I#N93́ No m1VktubY[ .uX"n|Ŷ~fK/% dKW,j^y+\pr0B)#@O ®{Rh6Ӟ-udͺwR!',k*\+5o$]J$s~!Xk\jאRN}rXVK{9#`JV_@G,p} Nh6_oZ7Ҡ 8'?@+hԉBl$ohc99]Tlo>161=XEBJlI=@zgI|D`1A>E,GyJ,6^P(Xjܼ`"n2|Em.dn_7(;[",鴗[\Q8j?`<>j ޳:R|^V.JTL8L''Zh2%" Ocq߰o)oh;QZce){qi\-o@7ZJƦ[J/1#bO?"}gb2M;N2:rM _ _\·r둑D9;!˴{~:NboG͜.8AbE,G2OPD=.QCtFw?o0&.fcb^M& ,DguV@A4_l K#TᝅeYR0Pm,AE,G +tFv-ng*Dgr a.A4_Y@+AE,Ge* tF) Dg.A4_YA+A.E,Ge*MtF)ODgAT4_W=MMH2Dj- 6PG50kR!(m:թع eyp=_G(ͽ߲qEQ7 Gܠ,>cX }ȅJ5p k*d؎lQtiJE!1%5,wFdrIhjBSx~9)Z .ġxUƛE-XzY9- $m#6  ;e#1w[6)aE7s7"]YJ y\2صڥ`-[xղm4LSsO=pd0}W \^% n7/*.@ dcM{5V_>oMB۲sAwhQI@次\Hf+"?{Z9*( ufr8[Vޏ0mZ]Pu wTx]\ HvGD^& 'MX*hnc@]1ArE,GiEY.*tFpDg%7S  9uk)l8|(,IV^hGa_h`rj$"WbzKw ȓIߟv4Y\MO,82bi4ǬX_ɘDRmGp_lCNo'ỵc7n2yrEwj& HBF:ף{keGrJD{#f"-13l%tF<{Wr'e[`:YzzNS6֏F’d01Ɯ=Az$rς ^mΫ8'E#jM[8tۃm;^;(R5#V!}U@wU4 yX;ĨM-+E%/vV~]Bq* w'Ř8Fۼ_8vEPu;J_Jіn@6 LP 9ѾvB>7Ty_OW悸{ct !V~,m_ol_ouUFnn;} 5_v*q>*=c2\[ΆpC,VZቿʦxjaM6vb%vw v^EZG%Κmy^{:Ȧ;t n? ՛Wf LЃDyo%I Eb|a(Iv^-%OjS/BVίPԔ{w{bݶK6bQ0X4̐^ɥo(_].?ұ$̦V_"Q+9-ڑ<-i 'Dn6  c#.\oI,sдCuܩ qCkI/`h' N+!\f Cf-l>>T O@PqM- (@"a׉ahDCS Noj?_Be7{Rzu~ςh*&(wݻc:8W4>POiub_A\k;~q:!,Xñ2(ö11Xx9`vXpdr?1d[K)hPAWIg-܊ףBo.캛0$+2Y%͹ϣ]oHFeuN0yfڜgӪ#cS/K}dmzmH\}6Ip3m=|e/Dڡ**; Ehu>*{ q{8J{`NN#%/8';RL`#,*5N/c%BGdEZ]ꩇ"^=|oC1L h~2bCfkV6p'(J =zPmQ|;/c'p `-͉;a֯vm ,iʵRBzq9UHH__# _I9y4e[6S[$tF x 㫌 HOnW[f.*Rt쮯mrBGw__ğ¬PP|ۅkȀԙ>[n;%EW+þ^M]X.\Pp3xp IK[ufUo,Oٌ2S~5>gF)a##=\(q!<[H"0qmZ?eB  DgibECށxg8/)?c6zHFҗTKQ7;*@?|]Y'd^-o[=XY5.Ns]ÈR=7"/ ZL$" 76,&k1POw(&`㥧Ǥ>Ct`7A4_d WokoV@u**L*`Gn`mC*>wu Q(ƈj\xh[i6ݲ6aV~]ߕv _iH'5r:}Ahxy?̝BI髞 =5QlJU`(Hܜu}"Fa>`MDHS'|\H47tsKJoN&أ•'%]BwHW^ |D6Xp(s rQL,^ 6v{ZtGa$'~7?&-ːue |0ni5%;6++/Œ6TWx1aK϶0_j[Om4٦EP*F%7>;!^C`ų{A%^ Ǟg+u[<9p@Mş[ nXjE y24l70c R;9z9(&FYP@ AE,Gu#5[ OtS?Q|3S0:g7>$W}K[dΛ6c.tG~O@X(5`խ1-2i?#0dwg=OXҘ1~R5GcMgF>)|B"fo]|xl>h^n_wTBjƻ5Dnʂa ;bZ׬`cu^ơ=deͩˀwtFh Pނ3_NѾp] t7IA$$(Gꊌ%@U_R~p9q~֘$&bQ3<)gGndXq$A yDgr)wd4OH/zjZyή{RPez)a͎P: Pge-eX:@pR]*B :5$(800>K}yDR X9fDZNb8mř<A4'{x,g* f]QKXsoϡ[Kz_Ocw)4wtA5&<~~Yfv !*)2RJMd 8#LFǝo#w99_%j"(cV1"?!ؑ'۫P}StRB3ݹѯvgYuE8+)*Qw YA>E,G^T2Y/ d7wE5Zuzc= Gy9_Қ2Y-~*5iʁَ>F 90U/VJ k]tF3.AXqEnf&GGhQzxK9caa~|ox$D"UOO.1JC w٦}Л^C3*А(N_DgvlP,/l ax~Q@:J iAB4‰{x-O@CEӫvJcjS\DbTF`ipB9WsYR~_qWTKs:*`񞬪At6R!358uu!;aDg(CHRg'&OD>PZtRHAc=BRo uL;ca!"CQDA>LC~@ڟJY"OŰ6*c=sLN!DݱOC vΡY;M27"XF4~)b&5ї\Qq"q"m(hd@RLs yQ(iPT0!Y;ڢQ0AEw 罀8A4_]5-4TW%H؝tRGG-AE,GtA)8[@,tFX-) Dg.A4_YA+A-E,Ge*LtF)NDg.AS4_YA+AqE,Ge*tF)Dg.A4_YA+AE,Ge*tF)Dg.A4_YA+AE,Ge*tF)Dg.A4_Y@+A=E,Ge*\tF)^DgAC4_ e?:Hk oHC=vC]%~TKbRon-2^ہ +Ut ܘJd_tgZ[+-Zd7I'AaE,G58T"c߇a,?c=4AZawl=G@}VOwciQR[ @@Шlz'/y+ "uB6EDg>۸~SZ6([x;ԇƲy4լnx%b)mSW5ܫ䥬&F"WZ]`G:Gc,R\Q_EB]9A4_l{ӭ:jn҄MW$`x3|^/SgG=*JlvTy'͓B+.$03wPOBAE,Ge~8櫑+aw-+?^T"ʨJlG wRj0~W|3Jއ%~G^EʹxWu#`F&tF*p +ާHvT^oYZqӉ].Z c$M8ىO۩Á#"^4E4גtDg"/guqVd߫u*y&?ee(m)r]X7Г޹}Q";K[\Գe_ *G0I3M.:zHѠ;A4_!ަxsej`ݳrCER|P"&dXJI DvkDz+ɹI0͚!8P3u{AE,GIObnndOCr4ӝ"kiz3 {dl+RDFV:,鎇 ’TOd: {`,tF "Z*De2A[4%פ4_9x}fMN]2 yqoV"aaRۤ;EF?)UdJjG?aE#<9 }l  Dg:4#)MxĵLO"۹_럂`Mv\m-D;6Fa;OU6Q*U?@Qf4EU9֭~mhHBCHA4_!\(l|SB0x_$jS;6vay=RפN;kAVptH19gfm'`\ `>7i n zLJb; Z-A|U/пHC%2k3|υe> S@"hXI"׽~9:OS`oS/>AS4_ #"pT@% i+'j`zp)&r22Pb2]?旑սy/2vPj]μ=tcX7̖ëYrE'.YBAqE,G'+ @n @oq+y_bUXdz 4MzM(IЕދ=/dUP{C^;.L'Y-= Z\8+`tF-Wn>Ң8?da:Ia@y#_ ZWT.TBTeFCA#nn'M" {v?aN:"uZ Dg`|<s {!nayk@XQQvJ*v( o: ,`I`YUM!{YΘ:ԋL/m1t E+0S(܃#A4_!^3O{Ronܙ3b<1*%M&W)bث;k^r4Z&U,6czFw8?Jd9c5BWK>d&gՇ_{ aJnW߬`*aAE,G?#@VҫgAKiXmNJQh,=??Zz?j/`=`?2BT$ 2 VKO@2tF^@:]Ιiġ1DޑX P3sAτg\[i'N<9W{ư6R0 vH΀N(-?1DgV4o-LJb; Z-A HP,&lBw2P29m[C,0}^3JMZf跊JhJiƁ8>A4_[$Ng^h:V+?x1,AE,G@f@-tF݂\Xx)Dg8A4_*WHU ǀ-A=E,G6I*\tF,^Dg1l`@AC4_+T:Wyf<{!5AaE,Gc Wr=k8!1tF6_BӤCI)Dg7A4_+1˔ +AE,Ge*tF)Dg.A4_YA+AE,Ge*tF) Dg.A4_YA+A-E,Ge*LtF)NDg0AS4_ʷ-+AqE,Ge*tF)Dg.A4_YA+AE,Ge*tF)Dg.A4_YA+AE,Ge*tF)Dg.A4_Y@+A=E,Ge*\tF)^Dg.AC4'+AaE,Ge*tF)Dg-A47I+AE,Ge*tF)Dg-A4+AE,W{) Dgmoovlmvhd?@trak\tkhd?@$edtselst?Imdia mdhd<U-hdlrvideVideoHandlerminfvmhd$dinfdref url stblstsdavc1HH6avcCd(gd(@Z?jh"pasp sttsstssctts                                                                                                             stscstszefH9.161-s2.-=2.-;2.-;2.-;2.-]62/dbL9o83>pG[mOeUh.?2.-;2.-:2.- ZN2?*Q1Vvrf~  Sr7@G8/-G3.1?4.-<2.-9@evVB|nQ:3/L50-B4.-D4.-O:8N;5DJM@:J@7CYn^Lb/<1.-yf!@;395 n&_860@95/8/.-4/.-A1.1B6529r}wS7Lp2p-2.Z10-K2O+t()S}[87B>>H;2/i[0i_v{zCps~!yfo<G0D0/.2/.-2/.-5.t~ R?L87<10-2/.-2/.-2/.-2/.-2/.-58B01-<1.0D95-;/.-2/.-2/.-4/.-2/.-2/.-2/.-2/.-1/.-1/-stco0budtaZmeta!hdlrmdirappl-ilst%toodataLavf58.20.100RaySession-0.12.2/manual/en/images/video/patchbay_rafal_connections.mp4000066400000000000000000035165741417052567600261530ustar00rootroot00000000000000 ftypisomisomiso2avc1mp41freeV mdatEH, #x264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=2 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=6 psy=1 psy_rd=1,00:0,00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=4 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=30 rc=crf mbtree=1 crf=23,0 qcomp=0,60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1,40 aq=1:1,00We Zd"q 1DPu"\4K7);vt)8[ZJ6BPfHUI=Ą~/3?A׻}^M l=u-~UW\d 12eKZ,Lk< \>-ܖvhm e=Kq"K-HHVsB«n ݴ'WS ` ~WZ;LǷ'Sg|:QYeF;qZ}zM χmiCDx8 .*|{Me?s`fB[!R 8 @WŠfë (lIŚl=F? loΰ͘Fe*ՒSc3Nsɀ9ִ5p7=z!O{xW3Ǻ7I.Yx~+0̯1HyΔuj0s o ԧm+q_A[ {Q_oMvspB)E[XXXI|Tw%3شǾ? tV}ϥ,T!>[/j̰]i *?/5KX_t5./ݓ1k`] Ujm6[å# lrē\L[PM)@rJ)vy/cChj%,Uv흩EǓؾIcBU|>e(ݔ}qfahɻoGT)4հւ&W`=W'$oB|zj W<*%{W3fQdXbMy GLSR| jxV` "LacKϧ?XGR |k0CCʸ_4\>JŪVuTI{S ÄL{䅴 +C5 pbaC:ITDtE_OEۜcR&)b\(6r.ʶ#vށBŽ=ƹ/mǫgx{R2CO$+jv_kʦvuoݙLNuJ! *-1bՖ{4Վ6xb L`%RvBi\z֕C[$n2H}Mz(Kg#.} ++|I`Zt$hf}SD߽M'Yr|B0@fu669E ;'g|kNNZ5%@uIE :$0]ȃ"ˣ+.Cѫ>JfɢLCBP b[0=RbO СUt,e߯:rdKi2᳀WΘUaTQe)'1[RY k3b+E1'+bN+9渹I~|F';IMlڰpBLpFz)BLNͮ&2g`t\}O,{7:,6i[(`YM}jǀEMRK856Q+;j&4-~ox3;TfKQ ȑ^>v99zS?j>Z{~"]~j2!4D7ѐ\cy!)/n`(eu#8XߋO"YGa)6,4SXyYNx> -pSJ*@P/A[+I?/ g)˛r$[eoJ4ЬkY޵.\Xh_pAE*\wm ط&2E\P^`AT/EOslhPIn JɚFuI BmRkIV.D rRX5?ݭ о\AQ>7aTɻ# LEޫc p4evsqD;lRǬ֬~馦 YbA)ުH~{*\RxG ʱ 0YᴦrWfLH;P}E[_njac4G.XimC=>XKk: c5̾xM+|5jC|=y ]-ܵąMX/M]q=6U'ݻ>I',~k$߱*:a?Ɩa9B;F.wz\Sø'Qdyo+,LԹ W.A1 pCM~Pv@"V_[.?ѱ󆻔%^+,CTo>rW۠жWFd.ދ$fs,l,]| iǃ՚E\g&s/4J~3>G Xn FCF+2#fL.Y?*q>`7g*IDL#d:S (oo=1L)K?|iWh?qlZ{nQ)~j}@sS x˦  'Iи3R|MAA`,P\Yd43dj{<'6wߩ-EɂIΪ W5٪&5iyhnK`ƾdEo:vU]^˲փ}& Lv ܒzZ]ʼ4@˜2֡!t6k"~suI3sxKp+ 0$/ß9 ]d;  4YgBٵՀϰ( 1qQbSciȅq3T+lT|zFfm guF$ď=q66P)3Lz\ӻ0 l>;lqBHl{ sN(\KbJjNnz3-%4W5x@r~'%J`l#fV:}'O(8[ KSc4;>T›I{gQDn!VV<˰,YSTtm Ӷj_QwNkJϗ d/ҏ q+botQУSVKqMH lΌ@{" ΍5- _ઙ"sI:آᕏɧY=F5F(1x'pڎ;|SY͟!N %zGdW̷ύ#i/ՌNEm6S &TŀHJhS&z ΃taRG>I 12 u#]b/n^4&~1ԣNr`\FvfiSQ3Yg K05^2! ]tSE੥l^F0sCF]͟ThޚlvȒS)u@. ʑ5iAaMԈ2LT8T/Qkg¼%2! 4D8z >Ty>E.#$ HẐЎ^V yTGϰ遞Wh>wEd~ac %`cG"òS4Sl "aޕ=3<_#ӫ'5I>󓕞믏Q_h-Щ~WLdN7кw 3G"CEe?>Y]|I¶JҒY8[Q<ݐ^Fhdw9 ~&\z^lL0S!pm#Ob 3x_{ ;[;#Zez{v'Diq_/16UlWπND 89AhP;tM y*f" &'Z}UH"3 ̺GIas9n\֘XG=>^ .4̢C6`}ۛK%:-QB3 `_0bU>L ͪ%)-`V"G {`-u(txg6L"WDdo4 º;2qpf _Q/;ZUa&D*sN>^ jÛſDZwK#g*ezh\es^׍_5LIHk9=):-=޵N'o"EVG>dLVX}7YRS_FROsAxŏ4 vH#8oUfc}i.?ރczӈcDj#Qh7ya? @WeWbF;dQR_rGRk6~)fZ!N~{ޚ]!8F :D9chM?oނ/g4B˿' n2.4 K~P'X8->IТ l[wӊb8jnZX+ f%cS;wʱTTZ(8~*=,_!H,X^1{_X3TTz|o)UFo\G&C4qo>ώ.&%(R:G˥{yT[m$>Jz9AW.qi(Lo]ԍlxm82aT1NHf?ʒÚ6T˻Gu͍=_\ɣ, ~*qfEP$]#%,,B:/m)agȮPMr@-(Iw\w%ƕhJqS;0bBZg%kY#I1ϒ8aW8\ z{@(ls"RŠ:qhvOGCf4㲥C[ߣ1)hmnu`|&WsVs~_ؿ4)tiK]w=7=- 830 ; RܛJMK ٻշ'B*_E;v{@߀H̹4E)@% , t􍮵iwDHAQ-+|-vB_$kQ%jtq Yݓ{+]mI׬ w(7}Bsq$˵F j5RRH5yhyǞv-cqkXP 3\ϟ;$'Ml|~Ktu>vl3S* Jvk5c-;K(!h\tA^^2 Vvs+勬ٴHYg8wժm |B?٪尲nK(y-AP0OTe Xo0e^jk=ӂf{M%5fTo:-X@o}]l@|rbIf:y\=p؛_^Q̤e ]oR"m{tAE+\nj=I L(?s^rs2-"3O rD)v3JQÜ<ؼC)$(_;{~h]Eg÷鴵e@xvtojQGT|T!t3?~0D&zA)iu#a]lW+g (W."߃2h|y.(>67F/0xj 7/a@ asU{#mv#2HE%miVhq*"%䵲eD%>nMiOp$;ϼbRKKg[DQapIN)ANИu`UPs}s0?@<5ÕhU5J\Oi 0t픑DUwƺ;# db`GXuΆS~g(؀jr`OKhC2*r"Qxb hZPb|geFS<?_:r\@SKf^RO<!ɑ2Œ}k6-K5 uP b]u~QiMRlA+ ">;ц:"_yi-1գt7BXoȍWLSϧ'F~Eq6st;*KS2/3xS2]#F xwZD Q˝ڡa2@Zo>>- oa&Qœr/@,Ѩcް$~aV ;/Fݰ!G~vd7Gtsap @.52XLX֡"FtS O&VH{C1 >Zt,/I]wmxGJN[uUZURj6zuhOe+R 1`}ׁUMoVFF@+XU%0O`vS#1CI9x"zoXqD<0.>يR#GfIX!Y)"\ӊs']^8\pw9"!ȔPq"j4_)D\sWKr =.6ՍdEAmT PLZɆ~DpFXzC}aɅT3'cK1ON v̡xeԅ7򫋢2/{:ᚼm@ jӅf'ɇJ_8Mcݓx4i.Di(tj>|).,&1pt:;|0/$x%0b.kto|b eDs&ʌ5sVkb\, 0M/fBS\N'J K]Fs[=TGS_18b7橿X@pk[~ 1"fNjwӒOBY)XɠD}ۏFڶ}$GZve#$M#@qq5 olcߥM*w`%LɴS-m/{#sk@%,983P[y5f:$3Zl`ģ7 `LbBܖvܗ`Oٶw7%qZI*?@;+N#˨J6?( k8/P[V[6™ beI U(0z~b|1{K8"5FV?yip%Pj0p(x+PpfORUh|[C=c$DA=[W#@Umk6 @Z,d~nzOq4(i- ~Z?Y,.;`nN0r }ʘx#H6$V0yn?Z<} Q87BcJƶ!ϋ6WVTYU&B:sހ:[-Xsܐ|n"]Oܼ'3'q!L,#PH<15܃b縬zz7FX"\0*1[vՅ}% y@00C:9 K,!~=gUll/N4ܪAF/Fxc BOO`2pEdPճn'ࡧfW?܄3ѐ Ы8\&/is( D3)4ϯKB-%-_6(IuP_-t _`(^TG@jTZ "'O6|rzz}T" e kˉὢAߢ|ˉx)C {4@ {9MZ<_0j65ߔTHHѕ1YqK-PTDRv%)`}hL4TB-BB$|]r6.9˂Q.\-:*M0ԝ{u n LD1 > ǣweq*h.'#5I7Z1Y 2?_\A?K,0;:B7f;TwȂ1i+ˆ)@=Ml >wJ~M nA ܝir7|֢#^$@I^}u?y3/?Lc&mrt![MM9ʓ\M*p8VP9jz1X5eLb- o^H`_E|Ie[c$#՘5,gH\녹s.Y+IAx{U.DxY'㾒GI^Qfy6d>)%"49a|qՃj+p "KquQޜ*eF |yP/҉ZZqNLhw`l`[t|xDQA3pB-m)PwJ* žG'cpK?n^n$uFoqoWͶ >cBJoig|8lD_k2g݆Sm}IاbBY/BGbyUӪ֓$mɩ1v9b-K:A`'dllW4 Ioaq%,3ot9OpWFxpbo8^X߄F$8_ ZIFC7AP4% y+ebv끔/@78IikveWƵ]R sz0pJogHqA TU؝y`Q@ҞJ^+5'0Hppr4ڟ++wH8Z!{h;.y5}Y2Vۇͭ]#Ѕ,6;. uMF?roNplʭzN)fe<[RA8gosF`3MXfxvsD Sh g,R{R݉9gA&;Gs F`'VDB$]?uω%hz'| # mMgK xpF%Tr@dEYP`͠)GXL~bNczbe ,Fb׎u$[#g*+G/] X5G#(1"lb\rK>' Q|w2BM8 [Ak]po\@c'k%wï5 ̒v7맅ƥ[!NmkwQTa +YMZAK 땓]d.o?եxrR1d& *H4B7C0Ca'[]6Q%U;bKij,{!'vgkL^_~\|WW9yтV~cs_Drl)fi2[Mr%<COs2.:pssjܤizi5 GS"vÐ$d:jRbSbJӰI8KEŌKji6@6m=3guCj${mŢ5e%DL=1%3"mԢ3-n^OL!`R&gH Te6񯘆^H)#j@򸆧k1DjBp2_e,s(XhtlYa Z_mtG׽ ,e *M:ƌ&]##*OgĦF)+>2 s&yR+bAwj5zl '!2o^=Kq (xB̫ؽ)+be+8Ю\B< wF+ôU)!Dh7c'"z|m fz7pv  "K\eҷ(|Ga{9_ߝE<\`{#1OBmO|#ݘf{|un]:(cvEzny~xo"JvfmXT4W-Ԗ!& p{n҄`/+3=}Z6@KۉuM&:1眉XMZm/:y:jKWl` y3E}B=y؏IS'h督߱YpWlu,팿fl]:XʚB:2d@A˯/[2pval)yIڕ%fEU0{Xoi8?q͒WWcm4q0vhU>/ ^4/fsm=vDgjF.L1݉3%ͻ ɑJdbWGY{Y ە 0 fqX~ *)d\3ɕ7V<_Nvs7\ Fݫi {ܪ>9I\?Sҹtf{6w_u~F;]V g)| ү@R э'YOodHR5A[{V/+FH́K!,uT}tKbػ=Ra.2 `pjj*mxiV{{z=/. )M{rb/ i=onΪ힏ab~{gIci~rԷaѡeG%CG2r 7N[HEb__,B gm:ClF.KOxa,Į649<ˆE`#+ O_ c)FUPra g^3(d#-)"2C緀vIU wyӈ>yLNc+˂kEk P}zKSӉ}9FT/1Ǣ-|l36!yqz#Eq[-~~@촪tyoj ~rm@uFS<`WG'L(XcHxդtWXj \ܛ }FVC3&OH*`=/{qɽ8]ZL}^1Oɮ 5I XLT>y/U>(s]"K$DJeCK`ti4_~iVpotsCJ3^lO8WFw;AKu/$zOOg|Zthˆij #I}}*]WP1P=Kx:&VxeƟUKTc.صw6N=:`bլСbv)1!r*%>y4Ra0X3b赛hTs$wD|QJG콿wp(YqǠVt ]gذ\/6g@Ov%T.q&F*I?Զo\t@#j[v0]R<Ў$;疽@Q6k(<$SPb?7ѩR +gz;sTa >DF^TømXg>Ǔ;bnæ{h? 6t㭹y`L 96LKln_1Qgy_$7p,̺=֎w} SI~pS:XSԲD_0%ZQꞶpߜv^/&*GKUof] PAjxbWRg PI2kĮ󤛒ˈQؾGŬj̐a"䇬$6^Wc>h%[1V_k6&QsfXX VKp-D G!fO;GeWVEi$a]ld nTsROA3=J|Nv(Q[OMn"d9?\T_.-~`0o6,%=թS`gS"sFoG1; A O5>$ͪb >%u1mj{6yW+X/"5duJU,2uF0c Fnlta#/c^И<*)m}8|APHb*!YE9 рf.ijT[Z<%Rc-% 1ih/--zw;,7潑wTB 毸 kâ_Fgq!)U٭f[rqL<,}2h'FtcN"cH|ڪ:hۖ%>X sĵ$ sUh/ |_ژʆ( 9+Eҳ˝#nϓWz~5Xhx:v=Ru{ B"T+J#N\_B,&c{ɗ32honL_Zqh^͋Α6<W~V#`D<[h'2~UiqoӋ11TLGIl H ik¤0Fo dCV)K!N|"ЏQ$pn/Bk e+`tPHHC}gybX䞖8R 0'0k KFK [AP]PX+Ms[;\@ y~m ^׌%2A ^Lɬ{Ɂ~q@E2GsZ:;EYe9{r(zuioH\`,괨M3Hzʴ{h.:Z{NxƗ{v?*J%,VM!bC?qX֨э]Bp2⵭"\H3\=!\(r/υ9o_[= K*EYM)&ORV=\g}3G * F8k\8owF~ъit)$qZ-S5y;"e0OaơJv!}3IKQԡn\p_&oe>%XΔ圌v)O8'v[܃ŋ;~ "m_x˹D5d{%`}t?m!|$7a蓰 F*JYq r0?},YFk~ w쥘*¡Bz2#skLُ 8O|tĽ7rf/ ̂[G-O@lX5;C;hUӪtGP=3MA#(Qbls:@kbCkrKָ tQ|KE 0'X$#3㻈!) fǂr0mӴG բَ!G@iF&*./y'97JX 33i&64}J %tM2?Ͽ_orl\s1aTf=Yj>9o.> ]̕Ł0'7E |ajRz !ꕂ N6:QTӍ<"!)F 7?Lu gkzj)J~T[G:1q8 M~xdx\k.Z5FSsz.51_L  ~F5BdL:}З!K* $359բ_.g}̶iT[HĹ3Y ^|X+oTzHQ4pMs lɍ;uQ}~s 2(9hJ(s$4VѰ5eBU[/ʼn1K~Wqp'Fˬ: ֳF\ߣ0[dU7yw~d4;c՝ -+;wtZK1sisaSUeqC;G=3$fIŬd8\!I Q?L0?Qqo}jH^FBK U(Kb!Q0"[X53/ G8l^Lr| Ƹi}$k"S }UF}>Am0a4Or! j#g$m^I'‰^6'X 9BP~ bH[Sx[]Ęq̈́azt(~ʎ*hؿnx]-Z}|Dk|AW̳Ip;иS7!KUGX8t0,"╢8E(k#w N$ f-Cʭy6~GYZNc{+O)l3.+LKqz-oupw۴;!Qpe4:$R(\,c] ^a)bDafVR%b-}|G@D?=9Ld,0Qaiό8@Qvnz`3i°ٌ["bj ?ǔĒ^NtE ) 6&T,DKOk/ge&bc`!vݎq><VՅ ~z(KHPSc7mu21Y;5v+k=NaxZ5H?Ӧh51Wbݮ|t bVC͆h=TC;E{K>kw:BgBohQ&M%a`koM44xKc_K*X=;Q^?^E>%t`[ M1}8 ; dZOWv Oۈ.:u0/ O|)iĠ]:/({֯Bsܯվk$J]1&MdXFW]KPusdMMpI*!xLj!JȀNs4>̄>1( `wu(dL ̑r{,G4,g1cK>ֳC*ID/#ˁ !eghXTۯR JP==A[ n;-ucfZ4-Ck|dC8WAC *fPCobN2AIr=x W~nr[ϠLav 1͗lb*8&*d4lY"3ką}`Awwfj+ eoFG]eZz%ZNRz5rMz$5T)&$$8HVC4$Z}SJa6g}U ʉ$y!]ixsu`*vd-Q]þ/k(uL3#/_lb!XPI@Jwk6=d~U/Jag)x B !HFנbGӍF5նP&K'KTp^7 ְ;Zk`G"0_f>Ao]uzkgGXg"yEi6vȪHז ?ਐ@L!@ -R԰)';hw爏R2Z+%(Q PT/JW WWXQa_l{ʾwT+NOZ<ݛBiGْob)+*vnsiI-HcB׳e>K$j[ }#\H0j z RDEeIJBW| >ꂬ42kaa];000 򽏔ಮzT]T^=(1\;~GBw\$8ҤZj h2Y19B/Qh]).UɊy_W9 S ϋܕaZjS+8Nf\m!q b&%=k\n (*RDfSwDaKu*!U;x :I"Bmܡ  bI#>֌:`+h<᭿N^"3&oߥ#f(~E}㟂/8YWiPskŶibtǷMMB_|ƃ(7 %Fƾ!ljYY)>A~VZt~olͿ cp`7+XS$UU QP nz#zF ,݆\+ŸBn((;X2MiDyD a݁3.jiO[cyVGwKHPc>@%2yKn=<*,`I>ϳP^f}^yk w"ߊEk; 'z=o$w*$;չH}Ve=_*}HXkvP-V x_Ief-CPEcx4ٷU1i0^?ur .GRKB$hxͻ"+#XXO3 r`ukV(ȻCpIXN3wyƱdӻ,14_a01E(@{ KuwUQPIu^11$d s,EaQ)2#ZE0 JԡɰC(1uh a.q3®BσodeZ# Izr"3S P;!",lF$` Z?nw"";ͲMj1 wGj2pOT7E/\m|EWW_ӤhFW"T 3YJtv Nmp/&4 _׶ aQzji!; [j]Yd[sXߊnPLj]Փpozhғ4X!7SW 87'@t󚉔SY|x[*# Db)JFin_V&^t o#6q7cKؘj@([FY$Į!22t Tb[t~db,bT#^H #غ.ik0.tT6pjV --z(W]¯*MӉmڎx-`{`qη9SVonbZnrIj ïGhf%!Y/M% k"H PFe>Rw@E#Ӕ(.l<9 &4vpP'w:]y8z9kH9tIHɿ|ڷ_TeIt5E|o8 cC&OҊȗ/uzvѕZO8LZ%AA}5S<ʈGںkh/m͔k73AWeUWy!EY,$l6|N鐀 c.dSmCY xj_Dl;T'<F:J3 }!bGPZu9llF~ F7 Ox5ap-ɫOw=~ˊQ%lq7 gھ5% V$zVh-淔 =n 3>lVC7i0 neRֱ/sv'-0n >Qt3֕}Ƒ7QGH_>Viʨ:a^@H ⓸_JfN5_?+G_#4Ji183e csK4 4ep,zfǯdx_vUxPkWb>r饛&8: .33qaVo EFթ7|L\ns[uU aʶ^6ne'9(kI%nL 3xV6ZanelVmhsq ~4 pn,_S``ż1>jM'(da}"/L&/ᧂ;D}/6#Mzb7H@UEforSllǂ N ~5_@ sd޹ßo'/c({m!vG5**,5#DX4;m&0`B[|_#nDTDvWc&S\Pmi_Ki#߹e5~ŌDX{?y :u?,{rv9^$J(vLIs3?pܟjr9b? תPJ/ʼRZ bևn=2"W_s IEId%>6;_X;A'JA Rj$5t#gKiIaSm >ޯkЏz|!nO\~/)_VgyQrx);G?.@jmٯzwȇ/tzYSWuzd3e֋' w1t>4Hڭ90^G|yW^7hv-jhC׈UxF +jt; z,m< a@k(9n0*Ǣ y. ARIL2xgJwj?#HԌ!ؿ;H-3dRVWA恈z0LQ FWrgYb\K`bjTmsK~fԯ&(,+Dh1歾,pzh`!˙4Gߥ{Wc]-*Vtfg iI ЅcHl#X<&єDz^cZK^{NXPŨQnh%z`$bEE8Xno'q\?Pb) nԨ9&[İ3 pQXEmK8L8G,* NaZ[.P $FͪǦ;W o>]N!ɦoШ '({B(i>iۖd6D OA\S3|FcQK52Ā {WeK46aylAz]ĊJ d*|T|߰9ڽ,8ӝ8w.Fx^_AkXeKhU,Q̢Dr:n)"(zx%(CC>ibL%7uS)*ɟ6tm+B*OX~^Fٔk{n[JJ!N4;{<MgBt>LկӤF7&vzEzX|Wd$Xpv u?Uh5H~T >AW%oeʔ)$/#]8mNyQ>my2+YAcը}-oz"x25~ZuVM:ESؒ랤K kWA t3ZQҡ(7zM<AKe$lwhګ>fLj퀓Ƣ[ժCDq35ʞzvbe 7< ~6,4OfE9AꙞe1۲n>Oh+%]фЬbd麟ct)˕(h RWW/gwO)u8)!0"0NH+:[OחUO>S{]pnRK;Ξ0݉ГqO^\.,u.lcW /%Myٱ[Uڨf>Aqeo&//_͢֍X{aK{JAq%DCXЙm.ڿDVR[C+y(Q\ ^!u.b_ º>zP12WG2 ϤkXVfiV?3&=7} A缄'+ G0U𮨾6Ast0z.O\A/5///xz킖Bp,@Go߿z^SIw6H膌r&wAMY' Rk2ϐƣD1U>x}ixZu=|.A {^xQ%Xbo̡5՛o}zC2¯Ubۣ!-j-:D=-m;eSϓ{HeX!%glNjJ-sivm[&6lUI~&VB A|@Wo~r>E-f6d/ʻ@}Q1uC$HQE/gWݐ. j6ߧl PR9rr3F +!=BJ5),,I匐KW'C Fa8]ly\FrJ_:ռYRa/?XHjv9#+GN6fG;=Z?OƭmY@N+NfH`k2{KF{[~"V~E ·)6 Ji ҏ*=AqTpUz}-VB\h4QW]zKKf| ?W߉jnؖrDPa8kZB^g.УByshʍm]#Gwƻ$3oNn3#Ϥz@]đX`NT¼+iE> m_aE-}v{*gD @] llr l Yq;PX`ʩok F=Z3hT\9~;q*ǻ)ZH-;`G±-d͈`MzT:jO'w]o+긇!nNz FϐC,RdziE ZǠәϋ1)p;%kݼ5rr +"%a({[TRؼ,U)3kEe4ƪ(FXY8׃i'D)kTxKlPϾ|"M5}G4msᳱ7anJ/q?CUdbլS˽CI"S2NFx4h;Ur(Db䢢7L")p)R~h8g2GUGW2 mXEL+~ 딁}@5 :翘䚴I~ I{0SREpQfְ#:1 s^]=eFBsFqݦjjѓFp'34xGE=y ǻ(zOC!zjր~FXH~[Z6QiW{/'ꩧK߲ujhh}&?ⅆLƦg]md0R@j.70 OJzP!* <+W_}HpQnVYu84eymHl4">s } AUJ'OVJZ/qK xq#':*kl"ȴywްYL8 J EL_]A8el2[%(m \ig\!]; O@{KZڕ *`UX`WSN-q/G*Gb?jG96915-KRsD'zcy')Vy<$,rԾ9 )ފښ^c|S:͟4zrXg-tqpwN `Wj;!i0tivyZqrj hli~Ff@sC ) j)]%UB ~r$h}|'y}hYLWnOҼvS'?w rW뺎Z,lO%*z! ~wj(,N'X}Yfw{]1jtW9; 3re "WEY j\HG lVxH;d[qi9ʐ4nJ_ iQ,a| _%v3E-cѥ[°Tg L".Ϙ^B3XOvCH`Rl΋ r M؊R,jȘt<_TYdĊ؞KuQ?#Mb.X4+{WM2 ~#>b@q{'&̫!5&Z&/jD[wŶA Ӌ%h*6k<: 40POpӪg)eT0\6% %vEy=C}S9c 5Fa3OqJg:-&QȘ;MlɳcNir= $ig˝Kz2S lSM fqA7Vr0Q:}c*9)JOtD&cmp'Nҭz jgp!Ǯ&l>P~+oZqVĥy-w㎸`r.NR{=Gd],n7mSt~>_@7iEa`h|N-`Ȼ yndy6EKRVViYߊʱ3442κGbТb\e+#&F {L/>LUBԓCws>@cȻCgJY2UYvq|,Ǣt? ;! Iß6yFMcv|KHc.rh{QYqcϒެ Fy=\`)Yb%Nz}(L׼yR(-b)=UJ d}໶qM2(, Рyv',voh=HmĄ ?[Übc]إ"q'8Wud%d/6ypN*(gk6P!^x( UJi,.@D^ шkJ8&z]0,Įy=Js0ev|tS9 &ēGߝ j.®}h:w m1c3ʊZ/|KS_&Uݔ@>fKiڥL-~Q>l? GxQݔ}VCn.JD-Bm:!\LI|+u;aF.§@Sv7Lu HQ1@ ]f)&{;k?Z83ѕB)SOddU6G'r26I0\os^6(gTįcHz'sGSeZayNXhk唷/BKj wt>&{͟fbpERqXOPr! S*RB;o-ynօ cfNxe#ؖO!,CMqvv.z+UxR D6f>Rcwuؐ5hǕkli%3HDn"EjmHџcA#ZVߤex*v5_ rHl{{ YZV[`_~J}7깫Byeá{C|mv ܠY<ς_o|mf Bs^.E[ON(iCosΊoQ#[Bu j*ʢQ{G#E UJf$17m,#ւ\Dv@k柾>m`?? $'EF.I x9-@zbZwѻh#d 9ɓ[7kR0)W9!Y (Je<"*HlKo*jydP] |`m*NP\p2;r7];9Q<.te%,NL|`5v"uɟ_3y_6',"GAHRY"x4 l kY|!=LJϒ[~ *?HYJ[Z3>g@FZ\n\pt_7҆ti/5;?pZx}f^.-y";0\ӐTY#ag?ـlƃA| 61u@ f(S|n+UI~d!>Isk\E/~&P D$*3wNlibT CO윏Z[; sƩRJsS{* [и @ ml_oExyjәz7<'Si|V/eG0kݬ~l#VjcEuP̜6-s('(n{{PEZ/ޔyoCO*~g_͌hY[^o8E@m"aAA4KL89l_kTl0:ӇN*mn#k#n0NS2{_#8p̵yu2IM>b&X U=Wי@om a}E^hO{4sj+W PoR_M!XbZ`u=Z>.2s,JAސ2I7fWUub+^i `"D.\xE3ծXno Aڙ ]1@MbRkM0g)5ojitCB]Ʋ{`FQLJkTςABJ, e%ZN[{0`5j)5h]!Yί\%'@+4'a+gHӍ3&RFB< *3lz4+{Gf}f_l sɋ4l^TŬ LSpBW|_ v ˝l6v\ڹE3Di!YE.mW6oV,lHK!6q[<&yx /e%YqhLH[5wu%LkBV$OP:0[^pzܗ/O%1o8ʝlť$wyXhjQ)WlK ş"d݂iDxM=m틦v-$km$c9/ùVsjse ONq~:/6}TpF!=T,Uʟ3eWwK|ޞ"[~O˾*5$x|Bs NiuItIm*uJ 8DS"gƻ \P h iO[tb>1}ƴ(|p91]<|Ǫb4Yoư⻏H9 "n!Œi/v7ޝQjwhlRoARROd^#A£?VDCZݍK_Cz^L$TPDp49Ġ tz$ox찇g}2[L(JmM*m9_}.-L|ަY!E{e*Vcu4̚7T6%}@et/(含ml̉ ٫0]nՋAye}^Iv:wyrЫ::ɕq~?z8! QT9; d[I|G2ZkG.ytZN#נ.~ Ʋ'OW`^`+(apy1K%$%f!=Y?%q>C~1K}~瓁i-;M9b߀ɷ<ρC!C7U\.m6MېJI}!cUkiliQb/TJ4_a݅ƭ Q>e0t2fD%DSo! yoco.Kpz lnWyO;IΩaȟY zC=+^usfP&` S pu+CS0U Œ'BKc- 5Y.bә`U@6X_n5grK߂Ts%0?Xj2<:h0e_>FO!\H3H|3]j۵ƚ7PN!(BJY=X*RH~x3gK3'U.EV8t/'QtB\O.Ge[WV2y6jԕPhU7A )tc=+>=+_2ÜP 9Akl芫G ][paTT2CO6ui׼8ce6ݍ5(a1 fWa0 Lcg4qk,fhY9 VJhGh)hDZ $ĽfYj )²tn-U9f9ĂWI)Ps)孇,T;) x$<'=ɝd^rsO|։/:;klX[m($QEkc#ٵU`]0E'vrnnaۥOf)4c^D}oR BَDLA.qR\]!4,Fy- *']*žf&Yg#в;#w?V\h\dDrD,)>WA{nF>)j(% P{"nR$|"rUϚ(pi#vP65 ͔a5= ב~ lN*(z~m uV epmh'_0̅eqѱn4-SA&$kQ;vDvmSc5zz6!~K$&ʛWbo z.mhc!g}T_]]w6a6XU?ONώtx 0j,lXkfZyQgznQ/CK͏^t:RݯMRx0܌L$JW{b_prǛŵі-OB+ˍ!fڄPb{7Έ=3nװ]qd.gK4~<)lIl ȉ; (bE DGWf2b'iqH|qu+xDhsG-:8`ˍMKi#Wq?Fԙŵ^7Њ}i%RRLjAGFA)P%]PzoR9 wq :WS+F/ƑӍ7z"ɂnvZJc ՊBz8y:Á&t-v*ZP`[>6U\PQkR `}`SQSQۡ*o9I@:KRȁ㺙[nH[v 1F;I_'v= Wnmi2y''\xw@]_Rc{YVyV5Wd4W.jb Jԝ𼿂m+pBOoO/ y&mBW??|P%1?t“vN)pC :KS9Z;Kٜczհ\Lt6dm-lTq~Jx/5(h@q6+0-8dע`oQj & \/ӛ9AH \,a8q=lw1r. <$KW qZK'(sPj?S()+uU}--oXx!GOj)\̓[nAZ'Z뢚*McCC|:^FnJڀ""= {r^oo295 q8uFy|S ;ֻD1M0X{ޘ*oOAnn{}>ʦYRn?tĎ2P~&QB[Zlw^ɠrƈIXˣ9 d?AD7g9K/sÐ\e pT2 *=,n0 [*4T`wT=@ql"/r gTeɏ]Dۇ@S̩y;Uhv-Uq*5Pd!ٝ n#(?,}?VˀW/~/m]Eߢc0cDg8%IP2Ah4_[W$y}lr=ji0SRP ikg@]&ci#+Tg0D=Q֭( L6~tFI4Q&~Ia*Pyʶ14!q2Z桛u~ˢ*{ \QG%7߈)#{E8h=*aDgr=>nXvs2̟udk}*wߌ51Wqd\fPMGD V|b|y=?rɰUɽ8-rA4_dfX@udM{D_lk6;0y>_% @Y20սrS _30هGMpuXFr`KFڇhf<#MQv W(f00R̰Y}Mdp0+>F?~}yrh&ۊ uVAE,GfC)Ax=7@rٕ\>\=7!qAi]`tF= L>Dx($=:Dl$#"#;ywBkڌ g,Dgfj-@MA4_dfX@udM[|F˫b<%tDQ_b仼sL\^|q;"]N̰VKJf*X9vЃҧf6n {].{BexwA885:u%JuGT 6 nFIbP_ɫ_ ,[EBB1yS;ZE+3w7xSw꼳U[yt= _TZ2. 9Dg{?<5?**)N~.^8iR"`pO7!1jA8>?)"W( r8PsPIm\Ն"vمɳ}< Nch)q} ]PF*kWl*Z~mX/RMo&4Nc%pvYZXUsWo2`߈[5 s))45K]bs)0^lN 9SYV ?AI ƍȬ4Ώ=(qɐw)pHIJVYji|;Yx< ]b[@/\E_8տ .]_Mb5ß- 4;GfJJ֩8n*‡}}lT>8izQ @ch_^,Y45&)CHgEf4dHϑ~p5TB7?[Y{vR 9wK&9j vLSn1wt&s`a{x"&L)>9yfCw2^6,=7/䞮oueAE,G{bJЂf) (!*E oNLͨBP#Bll&bC8S8SU߮pY={(VـY:-tF@ͽa@e_=&|qe/Dg[hR $S$+Cr=@MGIQGVOl'd6J]Y9I'{O|FƽYPzA44' ^DB8D\w1F/|-/,nȒ e Qܴ6,I 6w'|m?7 ~KbG_~ W TDB?W7ޟ~Inhb/ĻC!H9 bI'KN$&Ckk LUZ6tq`lLd !RJk6E;3!4+wVy^.Gj+V`& (Sу  N??cH}~Pf{Y"AǸc55tWiAϓbtG޽IdHAoZf3buTU[#+x䁢U6FXJ :xH=zV_ٶ,S04BY{wPcz`1@#|Glk5h\gqtFA^fq>݃DŽp#wsV oG<Ö▆a J ő>jm.Kƀ!=P]2ch~4l}26,a8a*2hS^` 8sDgA*fu]$,MԌ-͝Q\_0pYńbT(,^PRK^^)́$t:ןiRM]4.}k ϔol85EY?К,}ؙ> ȡo oV=OtXfc| ߻&}7$t*_f %I٤-d]Au4_Dzw/7ƙCGD Ȣ1,0~`,.F~h*`Nֈ;'.;B7H<ͳd>`8)s1cYڨ)x)8N5-`y,fɭLOmIWdf¢s(2"a.1i'{2tm+ E[kÊ9}X=ݐ!A= *ZdfX@udM$2\-! <ܟ* 퉙k}ߟ^ P&WѠ܌XNy^eBGi\؜4x͆]2bF C kql%7;D0`X<Avd]aRI͒jT֩s_Dʼ[Y.IFZHgruQblNBSmH.V81r2S )"_coX'ЩjE[uFkO]LV?ީ-kws`Qo`i:h Lִ*l!T$<3Q>a+e33|CPz$a2hC;K7\/"]~ #ǭc{ P[MYBb9k2x<zDG1^"ۥj%) :HMIckX7Ǭ&AEJ,x+!>~ Gز(|} Z5w%7 +dˁ3ag<=?.>A4_dfX@udM\ep[=9GW>>U3t2$K)bPd'"h, 06(M#hs]I5bkA%ytbdJE]ZU7v:)kJ8L2O~ x 7oimɮH#1s,<3MHMqe|4_q+@R)+y e鑛wsuen"iaDwm^M& %TwH~@@:{*xL{zPd%Qbν?C(RY^ɪBܑAVZ 'h 8qz"hk":>K0 7z()b98?|zLH4mW\qH,ݕ2A^{!5%ME3Cģd38W$E$b2s,h@1&c.l iF֖zu}qwD/fGf@d~Ú&30As%1>:G !HT )tbZڷX'S0K[[=T[_XBq[=8~'$Dz}YkZVdN \rGԘCM u\\`C/xI ]Q|6Z%HZcK#?f)i0 [GtHXX !ن D6 \{ڶ)(=u&o|Q\<.d-['֠,>vdK{{=&.H}(jBc)S Qt __S־3(a,7ެLBȀ K>ND3Orz~lZ-8dowR꾇N$XBU>xV /Q7q(Ǯ;45A1~\װWM\>㊧IݠC+sjDv`ጜ' GfW28 R2mb8x ͵2<l\67ԏ݄a;>vZ#Y=dx1{LʟNA|8;AE,GE / "C.ጴ.h3)0â nWnBEQ>;+.тWAE@ !5*% ApXUU$éNqӟyLJ+-Ďjd'_ ~ ' fp 䲃/YG_ΡaXڿ_'/'0K+`]>Dg ` "L}vWM@O8 V;Lx苼JO=}A#4_dfX@udM1qnw6=vۀFsNڠ /C"3nZ2cB-fVJ'Vrd􆈙$Y?Ki6uyIH2AAE,G< F80`tFN FP)bDgAg4_dfX@udMoIt-mӏ /T/GzT@kҶ(OǢX sU /tŻ*|Pen^CzL.餓lT+ζuf- -WN=ejLJXB[Y5Vf}އHLLWīO15;2BJulyꓑjSFNksx< ˾_' JY{[5~3r6Qx2wK yWlY+#+I\y:#> P}ode~{)í$VsS+Ƕo72AUq'o%nPo,*cQkWd-|"MOwZ2%` ~ҫ9ڑ#CsV;լdmIWM*ׁ.][[ \ Mcb{BΧ ^ Y>7H*tFDg][_y _*Oa/  S]omW[,1_0v>2Z]u>S02WhQéX@Mћ1$pOCV!r<&ECq[tz@" UM3@8W=~sq4N8xbBw(S.7_J2̓45<"|i|=.[g]b bVF %L>Z^چ(ǂjR5tA6j[D/G;FX7B.uQٮ:ǯcG9 |9;usvP䅘 .Z˩5nERa ;x]_d,gۈ"oɷÛG=|ZF.=?gcbuyvYE{ApNLe[)g$J̧%Va 64)4O*f>`hAqBb`&#_6wiN~N Ml.C<*:XGNoFfnqXu p;k3%s~}q6 x@4m4ʥ܆kr L 16? #{|(?|>$ٴdy LI6ghC5VWjopCGⓁ˳x͎Wh`ps2^5,P@AE,GN0/ Aкa Mui$˓=3#bаMqmo?|7]Ud'*S\&XªD8\ߍCM)_ыLquIq,XR(ʁdJݐ-#k~ H_|(XY캸KL:LǗn~y0V涛S@0"`tF\C'آo;{6}3X(,N~S^!l3H t<9zwtXU0v%Gn9\0^ f:b꫇wIW;?XNKbLR+r0}hHJYˑ,gn dDc`+vDg[~J(*su:(͞&%gMG0gqdj,rza X]+Jv7"!ԚX;A4_dfX@udMolXzj$f~t+kn0^)W9͚a=aĽל'k|JπH;g̮ zKe3ߍ<ЕCw;GXd:gty =Jyp)fE XCA[ʱ,RպJS $)Ru6Ax̬*YWCQلV A E,GNAqm;1]DO X}3:)<46Ɯ-:ȍu` b,rl#-UctRHȥ7RHQ9|O;ӵا?{f{c REzPlWPlx,tF["Xd9x˦P2BU d&a7@/HznȚŰ)`jz12n()V%׮o.Dg 7WIŭUPy6"8f ĕ{t(w|v?H +@- G:W4fy?=}Ev8A34_dfX@udMZhnJUsm}0#fu@ +?P[tOo\ f~%*@McȗN[z_fa(&'VܟP\0-Q>z^1**8@cA)UKAQE,Gi)s)#Ƚ&vHyrHa6?Z5~ςe$ cr;6[Þh 5@ ]0͜r%"A ?[*F%-AzڡUoWϬ+ptF !' .; M>H,mz?%d*|;D:RvCeEzNidtcE5yٟy$~~9,IG%^UM[S$Q&ۡg/KnrDgj^?3eZ$& ΍ԓ~c˛Uqw KL|Pcӕ_*r&/ EgxA3& X ˀAw4' ^DB8Du鮐U5*䏃a|wQ.@e?c'r,U!"g)'IfrlЛy?ߪRGQjmBcw<Z,SX.R 4 5HkR%Yh8$ӐhAE,G'$!@$pk >41aĜtrBg ֡S; KF -~E}x{n(=d]f7`3ݻlftF.D ?QKvY.AE,W`w@)DgA4_dfX@udM҄[?[Y.bibbަ7S7…4'v Yl݌–w.}aiDEa\lmq L\t5V7^k>d*¦SK 8Cr(3#)Z;ucrL1,A=dfX@udM҄[=`2`>!%r iN9X1m}& +6q6Nd94XDQo"Q![8&1BA=E4LGt3D"A1dsSz#d\tFI:&-ȱpE3ޤFE=q↿ceOb ,^Dg.AC4'J W&C Cӑ]U$YM!tvg kM̚"۷ e3>qN{Їu=!x,gh s os#0dlTS(TL;jײ!NUPe<|QFY1s# A\eM u8~6A~ulZtTur{X m"4"uIm mSϮ F >W~_zNUۇ&dٟ lgè RSY8M'O9hn~c0b$rtj׉Ic=RVۃ^XddwWr6( 8P|>q$$&MC},(A&7n$*ʚSWku-S{>N{GD]&Ac-ؐ f(֦eX[Rm;ТG~vT?X/5cWd65>M|hbUAaE,G,0½GIYkKW^Fhxq?[Tr4dYXtR6_e5*]t]KJ֐aYDH?6StFfeթ*^󕜤ܞHhuVe^5 tW753gDgPd>@f^?sSA#Ga8|9'6-"H 碌񫤇k|X zpA4'J 89&C Cӑ]U$Y!<3|[;'"?*$6tĖrQi c7uoibcހ0>X``& OPaPZgg9WތM aLvdOn8u9 {5Z:lp=$](dWG#XG"%BWTIf6'nq:;*AKOWJ jhvFj4L:[߷?i8iX`J-1֕*VM)oYs s.aj 1}ўQPpj*>#Wy^֢֤jj-W/Ã+ rrX]Wnk# @2,a39Mݟ醾9=y^rl1) ~ {'M/c7NZfc!cq:2m:hCYX-OJ(\ nesJW 3єB'xh-%Bc%kGSAAE,W*=Ӑ+j;!I@ r^/!¿aO=FqsCQHrr]BW`:%d79 ]ُg N?yar7 'RU[b'S]NбxA엋c%S}y pj= e4~G̋jF%n-EqrsO>+5N}:jL` PdA=# |({lv1 , T=o&l"dbTaH.IwH)m;_vN 0*uɚ9\ x¢0oexV= ]M|J8@xw%ec#xb=qئex欱?-lO9I kp?/`icKx9s!"e OݿT;Mv􄪹XیD|s7;L](Ox@kS~-8ܖ~TOxԹ#z-b;46Jek眤q(`"TrU|(CfMUs⹪{Q:Ml361ͭi)hK6)Y'A >L)k# |( :{DP`:Dg$(=.e/E2a#fnǡ>gmK!P&>||(VQ_Fy2}xJA&1]7_3,Lx/?wʹLhjy"A /dFFܽZJJL&,Nd&ԤR qQpsG洲%Rh~.7!03Һc`B~S:WWrb,΄s, \C5?7:ty-P9A[9ogYB©hCGe^{Am?4 gz7d9b(1$s=|Cn?h$3O=}E8T1PfP):Ttg/켣Iȡ, F6}|?&NN?MG4Zm)KQ|3S)&MBťl-R\f&TVn.r֠8nS?W@oۙ̈?;/"jL9vaeH_WlKʵ&;LB\?X='̇ ~1Eoҥ1-?"Q%1jkڌozO}/cwC6\ҪujUlx[mɭPTS-c@T_վz@)Dg_QlMjǵ(V9?H'JYy{3P)&dyC~)/_iM+p J({( E皚N[ <,z/ H%0JFa:ܨHYhYYxLᘦΈ p0#GUA.+# |(i]x !̛b5cO umGxX>sQ,ƗZ6f0U 얲ߞvW}4O`Z =Pٻ0Hy;^Urٚ:٣UVЩy5)\*7ܗSj3\5A;K}˜=Ƌj0ҹ45_=}˓%a}c-{ɞ2s?zO qF1F(Y `34$cGL؛3ENe D l2̜veoaOykx,Ȇ iRQAGȃێp (\d_C L-(J؎ޕ0,0/AVzq5 @$oW& en8?+rg6k0hq i`z4\j\EoH*xl`6@%:Bޗ,+-=ҙ=g6ϸ8JCL|wb*ޙ4%la󔡤5Avnp Uԥ ["c^^/Fz7\}m 17\*l4!/8 ^Uo-yCͧIY6f) Q(ĿlCUTj+t/:MQ[23ԍ欮(h}D^ gvYrzA"'/t? G-@Hr)b!%(_NXRƽ#,); e]Zƪ5ݐpj>^ml'+vXX404hhsU?ɶħHD/>\[*bzY጗fe#e];u5Ė@i][FE!=G쟭`)'#̾6qYߎ5Vl!$}чu]͚ <٪2PuuU^Q:埛KOP5yk1&O}Ro(O /cT4aNT3"~y+J :+&VԀ)SJ1sf;SP 2!R:p|Ba^=sNˡwJ/%lGlhTԓ ^;yt`J혉"u򔇒*=ƶO*g&®G9Ma5`/Adjqm.<5uײ?%kȚe=/ &W_9h[=l t ^9oe15 ބM cr9LF ~5\#U oS| e0JÊALEaAr4_# |([)'VERC|9[1=s{xOAF` ?f  *{}~-fq~m^u'qr=eXKK}̖S0SMHt.Ҏ' T߁d5=F4K\tF.wWYXHJJn}Cspj4Hr%Ff7ޖD\*V4R_cH4e9'ؼ&P_+2GAq%ub)wBQ NN b3up$uMD4]~߃_8s8Ql6[oUqnAV&B_;N-2 csOqj : lp%`qH>)޷W3 K!r6fsD=uMi%8KB$"$N%NRc$ YF:{8͜թnYq6гF/qAE,GobS1/+JF=pՍgg*e+V)Bbݲܛ8./YcW4_# |(G a#0k*ŠuJU{R\XD9įcdyɯ[K\{c ba]oiy=:1z\H"M+> 5L t0ZHg:u ߲1G)}wBx8^.aYd բmŚ> j\SKJ0 5dF/ r2>s?եΙV}m~@kS M b~/ppѸF U{ :qi3\H~.sFYlWɻUQƀp!. ?3 z0*J{/>+;;l M&mR_p@7@A\E,G:-@ l@5U>PPA/{tFv) &#;}Dg΂ 7sh )cAb4_# |(Z-eG}Nm %a.4IXmPl GMȺ~'7j^ċooW^^ď1҇8A%JF eP]$.wYg -01} `&5lc֨y1 !34< [)=`aRiap AI DmttVə+!1 5)rN qo+2@\pjc f;GHyn(tV 9WA|x(tĤ{ǑoOn6!LQ+.VuBnB=:k4ꞽ/1,ʌZ]—VE;&M\b-Tb{g&(3$6{?~A1d-r]I9yAh Qe3`P!KdC}ߤ҂R[@+yZtF+ .Q_5H1[?gԳ6|K5VDgupzWF8UThGۮ[dmlL!7( !($NTFY;ryǕ:nn6A]K-U'4D69< Cp~U\28< [S2 ,58t0eQ s*bВ)鷁xaR.ve؇NcW qkDf}r)FH-]K,s<[o ҴGB>]h% njvE5 wh+0@ZW{zHrJTp a">R[oAR.SD(4*N8GGǀcEHD;Ip5Rbl!twk|MI/{Xwx<|l?Q^NyHf2#& qA4_# |( C?.@tx.3Deo:SSܚmJс22ndGi1We|}o 3B|Ci'~0f 8@=~'Ǐ\ Ru%A1 ? VP PGgTc\%xLl2d_pS 9\&H2Y96 k4|\W=N*,Yq{]O)Ģc xgq.[ [RK8Tg@ʂچũR+Z[h G_JՋ::V@(_ɘ'ww]eUnJZט<9NB_D:!mnёwWvIsX P!4%h1^ `mai.`:gڜ-ӻِ-T_֘WЪz.l!Ҋ򐏱H#5f6j]V:k(o7B澊S,ГpP~xKcv^db{ݪ aBi ʺ KlC,/`$CNr@ߘal q0zJ_&ë?6>8x-bvq뤵!SR>箊 bI0yKQD^hJ78Í|D;ۓLN1lO ¡oVi`a8dUgw xRW~xa( Qa_\c#@LUfϕg PdS$OShh\oJ":a zKݶkOkVlӹJړzIUC-qApn@f z./>nyB\r|^ʟd*cw͛!.^trC:>z%+Лn[4߭.!=3ÎDlڢjkq nބMcSP;Ȧc6VGpQQ|( AE,G1 +>maInл@E-ކ! 󱹔]?.e"Oh@lYaH z8mw_26کˡ̞"/?6OFHi h[XS26k/ڎnwq&:mJ'EJhOb[;ޓz _s/zk3|?|p{`m5D嶜-uNՕlS\%CwfvW )WLK3~lFÝ߁zP C]Op̉SF^X},|+;!*0 *g}4S EAњMJO|[;N݊b@%Ҁ0]DBfoF?NRک$s>}}ϧ_GMX"nstFuwe;k}Vܵ1 _bs9C~5jbmR¥s6Ur :Uͭ٨d)iuI ba'DVJ!m6pD&j`X}f4 XU]kJpVY: L*qbfOG^1-9߻ʿ6O[&!Ccq{ң?>`BĬyK s͓Wd3Tj1nKRY)e1_!j/u5![!bQ"Q]7)s`b^vm^(6gV;$NôZd뎽UWXR?n u9u/U~nZ?$Dg@L!di&#xQ]||M0 MH!\̏|^w{*?0v^_ݺ}-{糚f4uՄ'Ih|r Tai4 x.o߱#t{-rt;˃:dbGęj I2p/5D~(z(+6PŻ(U%/raK&w 4FdvTgfmBP ]~)lfׇ,B GDȕ|^vSeYJm.7f. ZK9o- #ee/4΍Dŵu9]UW@?ҐaNgUZC_ߞ:x #h"'89 hfwՌrBӚ§*_a>ƄoJ*#Eu9fe]nA4_# |(эaX1^t/a*U&Ab6vюۿBH7\~T A7BSGKFb5WVv2^fęnl|y}6>WdbִM˟rpT쓀Qqvxxy]ߎjdC 75;en%?ř9 Bz?Cr]ڷĴPԇ`p8v6W-% @lEᖀXztKFp@ԗh㨙<;Lbor;]rjrr8Fs eg`ʯV\45Mk `CKQn 龈f9ߥ[fv_!h}چnB\=+_ 0i6yيL*aRMo`A.ʋS,v$>NZCk+)}z9x`\u? cvCHx!wBŶ10DW6)<#7 wj%H.V.WF( @.O.Al&Ns~a,?M:M{$PRL{N_o@1JK@D͖\>%粧A$_ ҵh HmU?QchlS0 <±u%#DASAE,G3MsVT='Rٜ|0l,vS5b.jh2iA:'ijau"DjdWn`N )rm.TShK{>#dskK]K^Jį*xOH~ou%)}x[?ҽH-AAH6E7X+Id5D@\v8ĺh[<Õ&_#>J8~t\Y2x\S9t$m")Ww - δU$1o:e|-!B^,U+ ~›{d^|E:4S ܚ-"sZR~݂HHAD- QS#(t'tFIImd'eTlXG=|O:$i/N@R+{_u]`-=2~tSP&O HW*;ǧ Dotx+ >1X@I ե7j Qj/vC"`xYp1$3oD~ 1@L-ADPRD*Bm 3 ` iTfBjs*ֿِowݹEpA6B:sq99k~ʪ~ZꙀځ)9L "([E9=@=L-2&R|]TN CNN84Ǻ$܄)Dg^֒pzߐܥs&!assH~bE˔h~ytܝ[X #U4<}@rD?J7SkOa~89r,)dyA~-!q;A1 ]S8:R *ȱ]v49Wf#476je~&b篏zQ&O)9MQ,N%dI't+1 Fa`NZuKWPɁL5; A.4_# |(Ð!@!n'tr^/~92 RyP~/W+`?='iSm<#߼Z2|頬t3! .š-`!0qʁ8c\UMy״݆Q.%o7ёu[Duv`XdhBy撤A8TLuOl9 d5s(ā#( _\a ;/Fg^| "CE^AdT16 LeG>M7N7c14f5b-a^ǃMNXN`^ _}O/' l/_r!dN(鏾P)qގ(I ų*S̨  tZ3h6, *kwmlg}|M.KswVXkl[ m|GY*i_U[M9k{WO](T+]fYgE5al( F+`t$LSr?] HqX#;c UIW'^KPyiG9J¢gږ7VH H]YF-o{iq:҂n| EALE,Gc]&H{`ᇈJdI2GktFM%?tr_4S3~*V8=\>D_Тǟ}KSjP$ u5]hzpQ_t0ގr~K_j?uС! !0pz%75OEEpJ}(>)mDgGAr4_# |({GjF-t~KiN4p,AE,GcSp*tF)DgRA4_# |(xd, I0MJmpXߤ2;@s +AE,Ge*tF)Dg_A4_# |(*fF/[{)k5X˛՗[ZWEt^8M(N[WTSY(b+AE,Ge*7tF)9Dg+A>4_# |(7 wybH>ރfthl*!-B6'oNzvz؈ AC2^^gT}e80ǞIctH'3x 6}HJN[\\\$/菣)WcJ2YcL!+%鍂]ձuqJ%8~Ͼ]ebYZC{v ݼ]3sbxUo2)Iۭ%K0$~Rl!O%(TW3Bb*١&`BϦ{k"Sa:_}ngۼ FKКmGլ'C)_+6:,ͅVohDFW&"VSظc8:(?gce:'Ee?6ܗ2%IxkI|u#ʤI7K _z޷r@Y=fr]iqL ]Ki|LSAG wV3P މ8L|N~Q@4 Q]s/JO6i<*|Jb FA9<`GCm3r1! 2{0 OC$n{eLe(d#I@'%Ww;;!Uػ+GLzB։ܞW LD6u୎8-0)V?]TХQm]F_55h:[vR#- Ŷ>w` .=ll_7 I}Dg;l,ƭOzQĜDaF?|`61-وʐ7RRY>cSYv;SzP~RT~r'Rc+O4賱}pc;LЗSVm*&&߸<%nẓZ;D3D~_,1`FrQ2$c/`d2冸;SQ䅅HI~ݨX5޹ha#ˈ#ۮL6_7)jB9 <\^x(PY L>GKP<כva4I?VT\:} 9bH|AE,G3BgRVn"TP[yc7Ŕ<+~>Cjp,yYz)hUiO-f-Ƃ( `>{ʦ$=;hiHޕ ݐr@ ďc>-z/ڗnnϻ'Mܻ_窹M>T-w׵J|3o nwSk/RNp$gWc`a*r_L֜nBxӺXu=Yхrm,\vcEPG|U0⛪`N0(jZC;$XŠ޷UTR<inA A Pxb%G#^^i"{Gdu=EIdi x֞4_Y1_nx ;G2MqzD/EX!ƁMR˞: Aۻ,>^䮸@ITӛI\d2${{Cm %8 +KeUdVo)тF-f e\u?&OLpzdOHG:;dŏz-U|* aloXx A7qbTSIԎt/oU{C5_̮e_(=-OKo6Gf10ϗ~`!)nЯQW4D-ʳFZk^nK M0VD$}˼|{/O= jYJ=-wEjDTs`p{N\Z"5jvYܛp]9A4_# |(kNajlکϣy$%@Ҩi/t>⚥Ћ0/|3.qCˋT'o[2OUY6\}sWPQQ8<)\=d[K褭gV&DXEC.L)W }p&i[J<\f] $.5eF$#DdƵ&o)S1_RN}(Kֈ{pEFLێ։W s+h(Lrd [@AE,G6ePMPOL~qPE kڱaJӟ,o@_XމȖ &<[cјv?haq=lYG!ۿ* ɍ"P+Oϭ/GSDhoW! u--rp`Hkp>>"QQ `"zw{}~]"ޯq:E/^ShRcȥ^Ycf)k~`ncQeo$oafm:6\yar^! #>41; ut1?G8/N}oA|tF:*z##F!MEn ۅVG񋖡R4ۈ>v)MVf ~BR(?ha*Bam RN,qk):ռ"/Nݲ8j-A߻֗f v׮Z)8KBmsѻ~C$}AHྵ*I%9Q 3]Tc!ܸ\x F4򶠃tY f;kbB AFu*,PkqaѲ&K~&RJR=r'R<3ßQ4k'l{DhQx-iu|ԁDg9;dZ8>8חYmr.qTv3?O ra|= KU \{,?k3SS!ai*²+Zsez6 Q-$:Zn5QD9"G:wy?Jˇt@dW" KpprmQfvnfvjUA4_# |(cmLu\٧K'K:/zuܠ\3/V^`;3gTp;$8vÿ( InQWe=/;A'127a>z~bQ`A9 tOw>z_kmg8L %yץ^$x-!h .bB{pc-z&Dx'ͯ1 ZbdE uXbP:yB̈].1L*#ws%U|[Kpr&YQ[?Lsf- ' bDk#iT3 X(zwZELRfk{K ˺λV/v<ANz>N(A<^l4o7ْʔy4Q2*TH k:m XULր)R#8,~1'wPZ$>z;_t-[S["2O-!)Zbj,<4Y:؄W+Ε6'ʩKIZӥɥk<1r\ rT>p ʺE0.RݽxIwLm?"Ck/x_'9HO,HCc=P;ޚlqgC R*UB'0]ֽe=8woN{g|DTAF\0^jZd~9-Ό6p䒤n1a#D@;d99s76[זpK̆:FJlФdBYE5L(2z2gkB-,:*L&l6uj a f!vA"7bP M].v?j/eMS\mcv]Ll{=Pn*΄^I+@tj2I? !?Sŗ(Vtv@:ztS̟*iL}DڝFˣ>Q7)q,FZC;8(fIg/_H ܨ,XTH>4 ")鋍y0z諷P9oB3nU1cI0n;5E( A .o vf|vAfGcN!wUZ3y[;'І9Sty9@%ZTAE,G86U?X嶛*Nw d2k٣*\E>]H?cH.QbSMpݒK4T?#ɂJ]KnnSiJf^#̽ svfq+f9DXvRJL*?}1g?#幹=-6LWP9rրHe\ٜcY !陇`_B=qUьg2PTE+j)d|0 UZc5# G}敽OYT@"%ū΅cx߹{Ec9]& y7Ի)҄x82L4'/֮ C*Yolڠԫnv 鲃=i4)}K=URCÍKuT'$}T3d@]Kc3۱B.~Ҍ Yh r'*YJX_Umo|YAM^vOPR]`jJ$H< 鈠b@CQW&'tFv7Aր&7j2MZ#FI" qc 1L8{ 7Y:<滸2eŹfW%0td`V.8)Dg@Ap{аxVnRտ(h'_`2iSC~܂9=~ޓ)- Kɦz̷}춅i7 I@cɼ:mK{l2%UZml.C:l9x(vi]  O\aϐЯ琈{@eyTN۞oȩq=u6/Mܣ+dD U".rM6ё^Wju. m hde ihr.z$^8ta`c sw*C!@H)8wcLN[}r"MgfӸӝ+.;.\o!ji4/i|Hä8©>m9Ӎ ws입՘sNvqtn=l 1遂hLYпlN9`o뜭3/&7qAqբ#ж}7eVm 8ӓymQ%KR›c6i ]W\H¦y>dI >1 @X\d-ȬdhR6JJcY:pxgKFDžr:]l M⓱ՙ^/ui]2QJ)6SdV96)w)/½mfu,OK#(mNw kkͲPЬf}FWqcr?91-gn>pkx7Gb0 벯Q~]A By>\)]z-8^g2EC1bk>fP\7KDgUis>ӫ&~ҌƷԦ; dQ%;}7&񽋖[Xy<:20F#&QѾY@ճhޛ>4tvGxrJuw@ ,/.3wƗ7&g*ѥjF=0ǓV ^(!_7'ۈHLb1SrRZ׹ 3)W3|͏ZҳME 'e:SM1=>4OkX@^Ο_)Oŧ4ũ::`KAP=# |(c(0<K7ELFCh1yPN^/TG,JHXw"jgwKtW`X%FZr0/0'c^ 7` ``=zF)k_2#]` xuJX"7Ձd]Q𸁅F_u%X:(W4'25"W< ,¯;fefu"$zA"\vpfpHPs XŃ_%+1E[.!UYWKa#!Ƣ $X9։|\_&o'MHC‹?d3bdE30ֹ݆}F4(#BhABI K+,;uE_DDЪ)AwL+tXxwcv7 µ- ? 6+D6`綿S(e= &13g2}Y5ՔUv>ුN-ig'4.s3<"Avń/@*2T]◸¯{;4`4ghV!sLcWt&5OHS0TQq?(sIU'Xt}m2lEcswFQ\0[ V슙Q#g wkWun)*^n1 G9~E~?]j)v+`&CqǗ9ߧ?CeѤ8JΐOѾ+\nU~*`ŵ0KG@\,Kt6Ab3[> Xj۳۟Ҫ GkDxQ59SJ ^tUrr]fY1 !:XFݥu$ <՞Xh{Sk+ZlSqC=l|^NL oZ8N(,X}LE:wLz%iehSp?-3ܑקԿDǤfD,5z!6$T"twhֹ[b-9tjQ,˱'90r< \aI]k$0ۀ 'R΄rF%'8"znf5:i_ jVu{ yacf$R"FDE-6]f_:JwB}ۑ載qvE!b]+UxiL1۫DWMtm>Ry$!OY `!KYjxWWSa9$ؒ&^Pg4UZ\UevI3Nߢ/^RS,Bq_'$S ޿"4*6.;';&Լ)[ds 0}QUOq{Cޒ sձJA]p4ք6"``*Ȍ-#&AI . (AV[z#8N;ގnnl-7u@HPi9 )u*UanzǪ so=vQ]"UQQ*q[: X1g#Ȯ͸@ rO*m ȦjQ엳 u!-WS?LnmPD*뇤 ubι0FG!voCq\)2^rcb?z)cih}ȅw3!ƋZPdx;2LqKe|HNr~XF?hkÕ$\XwhP)^iJ5;iţhQoɓ1D7(/S-NAE,GhDñLHxϥ;AH-tF$3s@0=Dgw0? %{'Μ-p9$?A4_# |(c%oɄ,`FR*%<+AE,Ge*tF)Dg A4_# |(c(hyz~wIiJBN&SCl޹YNc5Vvќ :SL]5y% 7!E%26o)W{֩¾.oяд: *p@nrfbzmuT\y ORp`r'5XI{ճD YKWWZDZ)Wnc"xMCFpg)4kXk|ic;p2B6 H<=;ثF'58a!g4%PhgfUlN~דoԓJ!_ʰ4m9O+1): :?<)ǶFp؟ p;P̧$/büm@ JMs)'xjakkl 1nƟibuކf$ut#_"N^%ָEVva \K6Lߊ$Fy_PDXS8BvI)^P}N:!IәIo qoG}1fqPԅXe+55zP|1tc+@@{t+@fZpXF|TltO= =s㖅OB:/F#+U)8a=_6l<2C ;?bnH(PD|Ȳ=u2H+fِr ׫+.`%_C;.-hP^pynUtȇ{RoQ N䣕;.eJ,nb֏!YLerYe{w3^EUbD4%#V"at Θ!{3g ٘Z7TžmtV4]3ce^`mMKfVGD+d}/9N7Bw6ӫu!^(_ħ&]*wH9B)": %z1A,rNw>߳4~b#FDTռrNE3 bAGmՂV?ZY5k=o9pKV7gn$kOOƼWP)$y=uov$o:ΑBZ ZG0$XLP+:M8pdP|q hs]‰Kܢw*ր1_.uU-67`>i3oZݧ8@Cl=6<ߔzumJ/cK]Qފy4y'jb+قLr죨>pvq;;IQtA:E,G ZV>*G G^Y`Zg=Qx9󱑡j3T:Y5_L~>l6F-]!8 y YtF`2Z#k2$ +[GTD ,cb~& ==,(;)*-\B:AYb|;y6t:pĩoїR-,0X7?U;?ަHm/r֏:Ijyx@]36q CUn,MGs̽|2o=X/G܏l;P{BRz8U T,i[z i[Dg$x9,xUd^mwz][Ue$sL*reݲ\櫜4gXA@4_# |(c(@M9ċSj}8k{h ~n7@EsΌ {K~VjIxM&†^Gg6#"(}ُ7POqY*C 5|0([ lZ10 l,LGܙ? d@~5).U9iT9m`T?j}c cc"nt?xon*<*N}ȓ3y^?4{-"ubժp}9!h0[g+2\I|LNjk\"zLH9Y6@Р:{SJbŧ?dZCOL SaGfk=_s*_T"xkM6o -;O}00lqKf3{辭]kqbĢНK3+ú4]gBw'aVA~E,GHRn6{۩0[~\' ' iЉza8ʮ>\{\CO9,8)lFg[=fPƑ)%ӚV{s#GϢ̭ W['t傰Ч~YzAΧz&FfSYmQ֗lV!9ɨV"5&:>PvV1bp7EvbMM;r 8AG =-tLH/C&)?>~[D,0ލ5ÖIH=[-lfx =W2W`YVpk>K)VI:?l &dď^T;杸2[ed N9/B#ֆj?w +.UyQɇV.x`N"գ V{@{/0KIh]_ g2_U?R?mkɎJp/GH}"Jꄜ1`Nk1%Z}v%hcC-8OˑwڈD RsUsopm=Q'l3oh6nAzyidv^Yf# ݁^.tr :cB2I.tq0 Uf#+)/8JtFXG9yfV;L) '[R)U!c_&0 0 uz#P~@V/ I3FUg" ^\K@'c:h;ÿ?0ՅG骬\ܜ@,b_2jVXI <!r0NX]<i68rDgrH=kYl;/x'!oIAͩE&0u5~ω'УMJBPK'^rg7+z ݯOWֱhmrl!صq)!IJs+cj&beb`c#R;YbeSoDC;J<1cĞ=V=ٴ`||q F)i լe )A4_# |(c(xyi ;f@sH-&cn :. MP0drJMH*,^OȇE~z~E#3ǫwc"p2g8`z'}yf_~FrgnG`peql4e&=#˫2b0.OX|C6Chf)8ైüM6"#y@߮q6z=mdXн/gnccU$c|k~@&X\sNv ް9mA埏pX$΍a}j7 Ȕ@* HFiZ@/o5l/ q0k<ͦnU+af2c.i||ӲxgSE%"Eiy 0AE,G(cJjF̎؂a_CҥȘ1D6Iᒩh/C8۾MJm߀Ź.=0H6x-8 [n=$a*tFr@m}FN@MڶE7㏹8O{a 8ya.O/ ORR #*Z!ȆRI >긥{[-Z!H]]ŪsZD6?^ܳ&J`mlczP˃l++U^D\mjG V3Rf/z#aEV L9ބ D%"iˮ2iu?/9N1>‰i\4GIᖀKtU"&X{m# 2Dgo*B:2/(^(zEMx|{q ةs*G .;ݣ(⃴{tgWj- vLbSl)|2"5npX30PK6 -حO_y"UD/7;zYBZzAt &.А:4ySm$keDҍr~(q]XӘiEieF?J.[Xi< *K/A4_# |(c(Bt枦%͍F- 1Fv#]>6`{vFVÐ@4vP xŽcP?ns ӝ9E]tPGϖ$Lu03$q/ M~s6!SW2hj EUhHأ F[u[cU5)4UNkfZ PfbʭA[!6D?qGy=Eci@O\{ׇPưq?A@h ]Z9O&2oȜxm%R-kQ,{1teS^); M n_$>kS5A@d?G:n5}\+蝌JJWKMqf &뒺E9)?t CbzԅuU,"F-'U)3AJ* :߯~D.Z~V \j#G*J-,̳l;bҟ1шP5P\uy? ET:@?aÚ{0XdNmHg*S:apц p&ʕ4n3吚 e-(a,:odzE5ߢPeC?M=7SFʕZ_AE,Gԭ v3Ly\n4X*:e=x~ =W.g!#:kEޥ'[(THR2uFR(}}{ M }hhx>Hw7U ITQhFܛi\9j zJ }ou*9ϖQ8gd3tFE &y88"_+/噃>1Uz 0 M.~N=0?Sضi6}fSDqDgyh9c37[&b}S*rZ4H\~'U0%sDJSk|/s {ήMh9 u>AK)`͍?1;fwĽޙz9_xMKW hby>BV۷V dws~ũ&)Ӱa #TMz6W{JS$PǶ+r6dhSG3U7?r%.fv)Gƍ+%])PpA 4' ~a{g 3ͩ RYR蚪cʆArrOHUl6i/<d(}dn(l0(T>W|qTT9sW[ ^ɉ`RNo(]}AU̿tU} 41nzVwSETCCr-gjxB\y+"PR5e3ٓ/ WRaUT=?OȠ0ԫKf!@7YåtEq]qO)~#t{^b |gRit9ҊKEk KC];f'~|υ/z3Ϲ$jYd/Aq[w\~hj6I6(o㚊ܸTv6.~㹬(8MՔY 1y7}5Jk.Xzwa`99;ΝY"2)9U[& S'>}n !Ύ;͇guJB3r?z2tSe ו/NJ"Ni/r͠X&_nx 4Wl|vYcޛ37LH9hěR$ռN-jI{YIiwr Ǽ"mh~kq?3TvX_7q A+YpaOw$ y]k<9Mx$f:wG;W\G%!u@#½lx涣5kJX{L|TRS;4r]e7c Ц!Emp ~n*@^9imC05Iml*3_HŦ-gJ), kV S^qť/HTq2YAm۠= q.Q_Ud^!13<1XN@QgsJ{z!E~Q-=)JcPgg˝1>`)=*8*ӤiQ%;P1@ P"9nim'umerS 4p>73n7LvͲq/yR 5QqbCbqbKa.lpaKDw%Rbn| "b|8a؅uJwJq.8ư[hM7<)COHƅ u2By\L G\ vŋ͓JrJ7]JS&zZ VW{s9Me8:!124s+uw]!OG0q ~1" qq7_+&6)WmI"`A*E,GrڶZKKiwJ(m\ ,ITʎ C14b>:yQ.\#yG7;ձfVPoVI%C PkHȷ[B},Ĩh% c/N<(%\(kߙ|MjSroΥo6s`$))HPbp&dΫR cRq["T@SX1&A#.o+ ?6iM;5V ʑ4eZIS[978.ڂ:em52Oҥr/ze8tDVƺlQ GNazT!ҹZItFmC9e0N! qtYk{YKTqܘ/r{tzҍ ٺ]`pyB(a3+[+t8C߀;-=-% F>K[l pQNИBleE1Xrl:oD|C檊ߑ?xG[!ﲡds"FAfL;2qEV3xph;A-,0\VD$?%.͊37` cd `Dr!o 1%0:#Μ]\Ť H;{vl59-=4.sFyHrӯ@ !y.y ~J<͌ 4ʮ+՚*=XmZ.'<-~% zW.-\p)NY1@\@K1ֽ#HF1 )S?/Kbr.Wg>rDɁnJ*}]>".Lv= .W0SRU_ G͘&yg݌CD4,FT3̈́RX(eUea S_ mɏ LKDgeTO0}~#hv&(_D`8̿̽[׸ 㤸| pepewoĪ ">k,0`]BWk̠Z0H*,[3uN"N ܶ\h~[Qu;=s1& BAj*md&c.U F@׍t hS ဍYv׷̸p&'M;z ,e+$o$fAv e?J`nsAFPV!M$pH߸ɪv~ ȁ h`grRiX}w'@ca(h(g)!Y`z- N״gCjo?hb[˅Tز3,Xig/F];I%(a.®t أC d $naXkv]oo*| ÃGD #}%4uAN4‰# |(c&DmZʼn`q`lm gf_!oJؠSics|{1 ne+0IU=Dy6 UPI!"1YAǒڹggV{]/a"Kᧈi@|M-*7-l0MCLE`}i(@􂾪ffR¸;, - wGIQQAs ,bkܚ[ڂ3O Oo'^}3֫8 #"VΓz+ GAp= Z# |(c%HKr3."+PR,мh2J:IL\ndR $8wPUB YNpz lx#ux0O]!bbՏZMRlHHa5z͘ς\KЅݾDz gM*pmn5)h3|q}{XNu+n^Lea}3!5;tS╿fڷ v*dрV/&e<›5-v*prv ^VyTα w!zp? (RdA$!ݴDuj3nw_<%iBW4hJ,zy= @O#Es7)C@{7ねO1A 3DDgzucɦ=7j*4g߇CS~4::ʷӪAO5B)1ũZ.B:^mJF6%qae؟?FY:2v%cB@Uѕ,>([A+# |(c%:$]gnǤ7"e; ;-~.[m㺱,KkD/o~R x $Ic)J#%M1+h͖!E.Ie8qHYBhӹ1;Sa4Y|qgokH\;-6Bo_@#?|"VB-> 򃄪:Lu^J ICE_$)p)T 8խ@rayig4º q,c/ D k =`??++5O]-VmJ0jd/Kڻz܍; S;7ioZ/DP7q 540O15[`K)p4 ]=-/~-oSmd1ON4hԔ/ ]U߽]VФ gjbt7K[Q̮E2E~=Of]7SA[V"Ʀ7!ˆK7>|h4Cx&F0ߋwdPg<,s,7Ŋl61⻦Hl],-TɝՄ^BA&2)P81Ttܐ@ijnϢO*P,U@AEhfY8Re$]V.@m-7jgQ(ٳ eid6_NhǙn,3opV,A4ž# |(c&>{21~V4zѫ2=\ 5T_t(3:8mDzY}49JGTy{(~ ܇ʆDl^؁dJy-*sGv͓ cMZn<Ȃ8AFr1A4GA[dqx z OzNLxk+nY/m|^7CL"=yDg 3T.VۭhPˑ7 2_AL=NV=iժ>XɐڎI h";Y=RZr-eA=# |(c&7=8s3B/.{OoSL[ ߻#])3ƔϣNk࣭-cU;d&F/je}ŕ 3Ϫ#{oHen|g{HM(VC_ݻ_6@"QKpDdrWZ `P#Ҡ"Ip )TaV#6%AE4LGUGypmEaIj ihAiqc.[\ttZqNIqA>4_# |(c(ŋj*? @3k8Pe=CpJ^57߅lj2Pd@fg[k` #_sϵQQ1)nj@-PlP=%kbG!cW\V:H98g/+˓f}rw.:x)IA\E,GvF|>V'\)x_Fm+`ƛ |B bxֽg\h<" ([Cp J~T5S 3#EkOLUcr*XL>jѹ!_Cpՙ {tF"=#O| 9CiBҥA9pfl*JHZRTi6t0CO΀HAđE"mTl @}Dgt-Xr YsLsmJ/,*{xe `}l`.9_v1c^6鞐Kz7]j 39,>*Ab4_# |(c(ŋp1RBpQ[:3g\5 .D =3;*I%aG4 XWVOHO~!TOc`:[0eBШ23'ү7lm' {Ϯܨo5z9D軮kR1`qAE,Gm_dol 꾂) .g)槕(B<hnMk҆ 5$qtFUδٴv>nef 5'1QN(CDҏ?-^(cycHvmic')5ٴeQvERDgF*d^B8ɝA^JIIo^YE8A4_# |(c(ŋΩHYp;£K%udj"Ur+ oje͠o6?v%w?dԨgGg.4FheW :`j?I? 97教ҳ7ŽR"()Dg ePN oe63%*"an\I[Mqy1 $ϙzgCxrAE,Gj9G>^6SpdS&bA05.'b9֡`w# ) =l?H WtF\@nA.Pw&P$ wMV>}c*9-E%UDg -gvfGNJ^ֲT^q$=x?tA4_# |(c(ŋΩz!Z#mA%BFL.-VƏ<&?UOdz!H Z֯_/QKtu.AE,G,2d]'tF &{UbӪPt~;[ prSl=&N/0o}@{M+&1E0 4Fu{ :EPo¦dRN XYbZ'd&]ڄq]&'{Oě[6-sueہH@@z;'mv]is];DX3U({2_ >Ohh{ō4Y:^l4ktF0䚟[Ԋb@9!vҫMc+9M_`ONxX(Scá%q8bl;XP雛i݇r@+hi W[ұwgG8N'7p-F|B˼aIeCmDg F S2 ʀ; wb_P͖aL7dEm%~o.(d hbj]ZL WvÜU_ay&%|^7 Ua&eD!EKB#i_ٽ ʕQ0EE4oW!z"hϱ(ɯxmXnynd ,^[?v$8ڭ0 Ar4_# |(c(۶M:#a6_)c8v xQ ոHEnmMIe~V+k&҃gpL+o#d%2}4bc;KUKVd]1h]*$@؞ mtglr&6uQVjFe ?ԛӻ@?{䦃Y`Orl\5 LUSQRlS:sg.Lo{/DPXrɧ;Bxg[KP/|yfzn(k$9yW"Ydq< v?6^͗䐌y]u c%_uOPo+?&e7 SF~PNd^Y+ ]hW\X|=-t }.S/D7d. `{JJH(o#(ǑB 'fRx{.aGx0-Ѽpx RH]EͼLOiTk~B6ew#pURT^Ñ7oe7Y$dSH7QF ?iToGۢ Z.!@$aAE,G ߸!M5 Kڟ|'CZ$J*ۛXN9u>Ӷ*WJN@)D8vD1=Pޣ)AuuiAu}ye:-SWtϤ~g}b)0TyJCa{1*nm& ';Ub:V# NA3~p6Y1T[7Q@n,S8A^wl;N K?<Yr&͌Q{cV QLWtW 6v?(jq% %&N'k-Ph0G:C_Ҍ1Ƃ.LYsdfwXuqڴ?tF M@dm]zXtȊ3] (c'&"j8T&?b.w'[CeD ԃp7OgĘiJ]ng0U!zqS† 0|jop8?Cު`oo ppc!R뛗k-k,uuؓȦ(!##[s5(ACp! :{S XV - zͽoWM=a۴Dg {K.]K}r`@PHevfCK5$Y Q X:hISEsH^CA=Ȩ1wC?òƺ0ݻMsPV938CA݁oYo 2߽}bq1 )P zs,4 n Xsl3nf' C8ª;fi-Оь8yS8U &|O8,?A4_# |(c(ŋλ.!`@bs944=“Xw;AwLi̫wCWN!WY3Û+,_(,Hvuk\ez#mJp!.@y`ڊXtUꊸ|ĺ- d=ҾAWJĴr8ވ> ^|=o3RO25Jj_M)[H Zs$tX`Bڄ|fbjQsy]#ߩ}0~#dpgU Fy9Q3Mj5)KL6%­D"DOrۇ|~ؚZ V8hFK:ЪE8 ˴ ؃:h?{'+h\%gaSDsNnODNR~;!{?wټH jSA;>ٍfgll2]{(M¡(.i< ?ɝ2W9Qm:)ӈ`?"}jI|CLpcѠAE,GX3U{DWpEtZ8ANL;@Q#0.pv!oL_i uP*@X>8Ԥ3ކoWۚ}*x*mbbvOb1B"Jz tFgz܇wqr]Z:.U!M~"Yy na~`gqWV'r@]}z#Expforѧk^a`+Ε7g!L@Dg [đ܀E~#fUmuuşiWMhJX^V9Z1_}.IWk_=s/ٞ4fmş%H,WgI)`zA49= _3Wɞ_ő6fe? wѻemNW |{::C8s4ҮRU 3Ҋnp qM1[u_I%- ?XnߙIGqq\*R߿ ^ٿq y`F=G}Po=B#E>L/ۆ :,X:A#).DW̜m?=k5 eJFgY?jKfM⌉(h"Ϋ?VS6 |ŊoU)改F 򌌉wOK{SڢRe *gj Y 3`;Fr('Wpduqyw-4ͪ&ҳ ( lΤ􆖨dI֦85YNk {5z -.&`ʤ`qٯ 534Z3dŎm=$Ë\bQ^'.T>dkfHte/%KeIuQ:7o}C= >t޻`2/iQϕ|WH;lcO4DV`:IRG㱚^-ͳ1813𘙱Ӻ][\= Z'r!tLge{}nEHG/^C{'^F <-xa67F'Ȁ9ዃ,&TOXUEiQJZ#^] =Gt1X4f2;hVDG=b%+oXᷖ[4T ٘eQ8Rv^q/>3t -׏7x9҈s2kxLQL%Va1Q\;*τe79 $]&(ցBmS5:5DzFQ݀aM Ӻ1Cwsgl=)(oqܐUoe<韶TZ,{9r1/DB~Oraw)@yDiF+l2'Hè9*;"h λ`9tM){wqC<&8k+u kFBzBu]: 1GaP#Ib]RsL C% D,?$qï){xߣJX6`@K3}@13h6P$*ݾpQM97Hm]9Dl Kۚ/˙H5˽0Hu{89.'{*0,5WMQr!i@q>^]:k=tWhfkwQGUDWy~zyh dhrzha,A勱fRE)oS)Lbi[gfmma\%tG1geR X^Q*H_.=Z0%ˌOnGtJQӸQv`}ZQD %_g\vW>}]fuhWlWE]T Ӯ =Z|î{?{t/S@̊ґYXp81O%dSErh˰2~ Խ A#|޴Hc *&bax}+rS#Xr:Ott{U^6=UVT8aFɪejSЃrq=P[ɷ琳(FlۧbvP ['ṔO8fBu 1PU,d&O'`({qtwR+}B@:ceLe٫$h'ýTESbm Š&\iǍ"Oj?|'U3J6 fJkAݳ]a }}ۀ60ZIW,wo4|=ZƜp=n;~j'ea[kX,e/QAO mRk݆8P7P5i5"&ҎMAZP?K!U1(ޔJoGe(:술ܔ1ߴs@ ] V-Ű)7 vJ|x h^qwO.+AY,$ APZm MOrXPy%"ŁFvbbku<<1I jiOytֲ] Z 1_v=F-S\T9$^F*$>R.e":msYa.| w2P8`3~laEx`S%sD].v7 +vJg9CFg3-ũ.hؔSj;ٿ?l_:gX b:^2& [p`OY\k#%\ \ºB∟5נ(TJ/k jA=PasFRh4,qbIkb㚨ci\Wysg)yd/Ri|=3/4x0q:oa&0 YiKx!JzdӍf[KןjpŴX]DXYvT挬8%"b1'9Q5xryă[4a*aA 6$yނ]㛊\yytŷ7c"@5~:!z H,JPʉmam cN$aO#qkW"9@xZڼN;*Ʋg\㕃 PWO>NPIyq(]v{hZB/r@otieN0@eₒ{/2Xtp:/p~'c ڑ%-:a̖X =yۨGT'JXo'[b YA3/h]S1ZS=JMCTY&Ԑ&v{?13Rҝ ++3j>ilRtyPuP ڎ:wTeċwFf t'åia6š %#hg1ŤN#0BQH 7Hbƽ'D^e<[E!YEcPw[>Ey>@1 2!24/i"?lOkCm7oJAz*b6L~\ [Y`.Yݡo@<?ړ?zlrS{|: 0+1^ bZB -Y-ypOgbgz8@9_(Ɖ,P54ZLJ'ӔNP܃oA!4rt 6$U&Z@9ٟ8F=q*VqI@ dMTӲ7憐& p@()t|u X^__lNEIspcgv/CH@!wZ&v2qIDFԤ>P8vTn׺>|QNŇ%WY\>6¥Sn QxIVIS4K@B?` k}9Z|'< pYR?P8mP2Ɛ:$6_H콙[G15\H؉A#3FL/Tse//icҁxp}EqT.d<ۚGE[Y!f&}fH¹aSZ-+CģU ∆Խ!l&K% Ĭ7&YxHQV9H (Ug% D#GH7h٢شrrr~V72z#j8YL xqSu^]HU/1\VVi' ;r :J4p0A~I'ި!v^sopa&%(w,2Vɵ4nBp#dGy:Jv魱}>ә(#8"}Cw0Z;^co ]ω9 9WקI+Iq=/BPYPjdJq 斿]J}Dx>Ev* d'~16W{Sv^?._}`@3v>tj2>b^;=15uʩ᪠gyYs'ɋ|Л,|}jV/X 7g fP 䫯xT'3 i- - rްc4QTZpR#MQ&cHT.8T5|H7^G.xYPoTa.6i|Ec}OT#2q "'>6RpKfڔm#ķ|XB/R>Y\1lIP\?bmHVf,4 \2rK_ԶBhBbT׿j$J#1own"*:j'koV o5Q xSvz3.7PN?sJ/\tsi@-3vx |(vX#!goa+<4`V|<+ֲ8޺;Hrz @yK|5}I(1Ͼa>_knl,Ҁg3QNcND|!k3{wj$µX/90elF,+瞡k{C{xeC!5&w G37Yv;^$mg5 Jw%8-ws+Nq3ǿ3euHK3VB>!b5F5r*zM3^_ kM!1}G J܌2BI_ ;}=Ԑ́B=z.+d} h|$Lh^~ʒzйa!ѼIǟkT'{)>i q|1kOQa^BѦ6|?2 7܋CGX|lrEʋPItYd=}m2{ښ9א)c&1b0iae/f0.'K z~big5$K.ЮfӤO\叀l5G-B@ +ل6]w"FoAƇZ0)S!= HהM;~iЪKtO|YoEHN;VA;d&rB"ROܾ69Dzs|eHǽ7l☜Fs\lҥf5+ְ(_AϊAϬ=R¤(ػ"mLjrPM\B͍T[0 uѡ|pqu[Tz~u׾)#Ȃ'؏e`d%A79 EAƈ|z6%0Brc <9٦z˴z6s壿T+6[ wO#5+GkA eaVX():p]oL#6X/~{ct1KNnwzا mJmm Ƥ Qv`KL Lµ'y l"N$n\NxNM"*0IW LfO}ٍwn=w#KI %kO*5DvZ>zm8"8W'X7kP] Z)5j6,8M"(vΖ`QWtOc(h6)_1p5_hey|oQJ?KoQAY-EEHmszc}f:Ѝ=R Լ,/YVTSQl_<>' u/1* sFDTt6rV:W"vc:jb}>DAZN9նcbz _s_>|b7$bȪ/|yxxQ+7޽\ &܎AO:0+?,y!vN@dj62cL8}eJ聁yUBepX }d*XNi|L&,Y9x! *=s()Z0?YAI@ay}( "l([.#L;7\0P0"veɽ}wM[r}@_8QڦPh(sugn%)z 1Dk\-F)6<"Ա]@`”wͭ?ԏ`?glՐvm r@5(ԢiouގXګ w`玻qgnȈU>#@(7pN}{ +f6 s5܀enѺ/2rX J׍,sÖcOqo8hUI(KLU"iB1:% JHmh~,OUDa,vW(_-3Y+^tf":|[9"^KSs&vo&J0BVU.#a{:zf%U&@ZLNMUOdcO@qas c[U(8m~b|qCLgrk"kN.c㏝oNnؿE?zYҷp]F/'tZh'jyNuOI/nvPFw@ %" WٞƉxuNQglmށkxQGnsԹ KN37 R,=1U8TuBV@J0" j{6MN n؟ P#<(:Ms"7ejP4WcoƬ'҅"\wU7vt~>VcXMbWGpڡ;'Yr^\w(X[um!.]mc0vN\z'oK rƯ9oaIFD`I }|+Ն8Q(X-rLrs\89\qgJņ߫ZWg2j'_#)QpxrBSĦ3ZRKDh=VVhn8Wj [@mǷh{@,b@o-eȉْ+D 6T! S\K 1Z1>eSvM!C~Lq(T Q+2T~F6YQkr?hp?{Z|Hv7#YZ٧886 B]XpI,KWQLP6@~]D4iS lي3E¦5ZM&k~ ɳ"btyV+PE_|g~Ƀ+,>gbw߹Y>aAӨB)qAzbr&P!.=?ȋm)d1$is+ `V'(1w.YGL;V ,@/aV {5P\7,_bE 5c@u4(D680fQ1-mfsfh Ayd#z7ؒT7L|֡N_`!݃TE:H*=vw# N5IŒA_Wj>oZMSc}؁/'pVɩ,>C? 8aM}Pu_(jCRe|K>Aonw k?ȿ`׊o (m2ZJxD7~47n\$6~6|U)9rPs hÝB34,^[QQ R|cI"%jsB3+Ն}zrRfQp?aS1V2d52iuߥ K07/Դw)0E o>IY`qe*LB>(gR-*WˬX:"쮿}k}Q͜o3\EB^8 )g:^=9QM֮FITϑ+lWQI"ÏQ§?cw Br{>^ Z O`,`v2y"(bi [4B:颚<*Y5q4@ZQGFǩ8 Nu0΂<*0$RˌB y# 1{忻 e|`IJ偊OZOd+vT߬nOGs+ܻ{e,uq 4u(؟ÍPA7oc;0=BݛXy$$W%G BoZf6jp:m-BkۿxI]G͈υbI 69 uPLi+S/sri^񻏏M ?rwsI_: ޗ/߄4U,82j=h+Yx \<]!>W_LdZ!P8sS3ZވQ P3;菔NoG]x"VT :I|PH[Hn$CGnFor3!  .lxKl5$vs X/sbZ:jY/[:i08-QGC}xAAu R<«~{;m'UJ Z,m뻊WZP xg UXI]crOMkP8 c+Gp4Lmfjp0lP gu~k,n%}T2Hɢy#U*Z6@? #Lf"wɘ#Qc"f sNk |t5! F pCL؀rW飪tC&e:Wãd:s‹@2Г *R7'ALȵCCӛDƥ=@3$Dau.첦jEf3 P|\s %+hEԎqR\k^f|d],DDj%[c-\/7֓qT ޭu@' %V- `\J'XO;aN8mn? c!fQ(/+`bFi@p#ֆ iq"AeZ)O^nmCq]طtdkIk`L 6gtMf6ٍ9Dnx7Jنֲ' XB pB FWW5_xi7 VE#zBp/lRג{bnv)o<#AԆ>*%={T!0- o MAJGbPqޚoc>cƼ0=?4d}?ډC$_vHgY/0M^bCâ$B/s>HBӪ06MA}v+1YÄ6=wC`îmOj%JaMjQYSs;ƮGCi^ZT1V%uW4qho=d?Y_B0=vޕBQP)ñ<(گM%֯ -' |uoH}"/R$BUJN/y$hFXH"8`"ü<ɧMQsdt<%\zn {66 sEyg W))/,`?Ț4knSL%c1s s‚7"̓XԨz5*_IjG(['J ;FF^J͕_ =4{~2 sqc9P} 7ZGwrnkQM:Bxoo\ޖ V)H'=O&/bgvnvK+.^.iq (6waƌL:7$FAǍA6%w$o+!1+nHjǫZOwgAcu"=l +"d0fBukc[IikxU,p 5(,o *ݵ Ti2e. r 2|2:Pa&-#p嶶V8}0"U] 2{E95ܟZ^ҡO/[,᪛^#76?@>' Mav k<0eaS4mRqVSKNVhDr9ki\X&y i38($|9%ۨ#b=я! bC6 )0M̥s04vRp_51"l dOc#}0c=`O;Zﰍ0HPaYTSnRK֠%ɶ)O<[Jk _3ɯxo:%@_qDlIq,qD#h [?XKfz$>o_ U45`r|'TN8$cneg8fqYqw }3Rze2ֈ .^|& )EEy; cS5.Rg_lt s#0LW6e4p+̀^]TU(ZVK^C-24a)O 1wANDЗzl1:O߉Mq!aeؾE>[H /A3Y|j 0tGyO3^o)]sH^86@Q R||'Kd҆ 5 1o)WXlFW2,}mD,]NuwFK9تG<7 #'X Yҹ1{BZK4fI_;cn.JUMԲ(̻D |\o.blXaM_7 1ѐOm{. F`!?WcF7P Efˮ7Z {yZl?bY-UdV b*u9^l4:v|6,Խݛ=.P^J1n=A L} K5] ͧu@a.S s(<`pwm6ʍi@K!'(HI@&BYJ&brtlқ%"N\zf0k. *EuloYAOsTR'fw'BVq1_d,6KvZҐrYOԂuj zf 'K?*FHHYf͘SAcOEzW J_7m\) b 458aZ2ԩVĿEdCx 8ɾE~u\kT%u)j*ԓ(F4g,a'V}[H䀳*kU|FdOٱƚv;`o^p$/3+6<5NڼQRgm ]^h* ζMY)gej긹s 5Ŕۻ2A,mU,W^*$K:t8ͷN*48C,zlHZۄ0~Ϟg]_Nt[FyƩAYƭ3{Z @OP? BiG7 tmSr>/Ÿ:,bp꼆,j^EG2Q2J}-Yrbcj+MIB;k7v.$) }y??k3FTkE ^Bmw̝_İsgEv~ri$eMP?OKt B"\vO2Zc2p?@/3Ev \0aGF86A%ª z+j/Qx#,B>*h8c0<"$sza?*gt^u^^'/J={S瀼zZ/ߞp}Զ- "ua {|W\a֥ j>˭$9 .̹&=S{R+C=p/ y"SI(̳]Ea}-63~nV8{,g{Bti=۹4%R UQ<ݲr6uzrQ9nJ+WY%6{@<`V✽᷺]ǭZ"RuI2Tzq/Lz^8㨰 phzB_HR<J?˪. ^57(IJȄ7qݿmuW 5xKq_* 5g( 'V|oݗ汝ч[곝ҹQieΏKLLGj(:rJ *vqa$w d-^2P(-p_"0_*c~zd&CX&7[IV yn#Z"*}{ -M>J'DB_1̲yct Lg{㫠 ] d f 3F^&$)-M֗GS70AX nfVb0ө2 C}wjv1ឫb~ LCb'Wt Mh5Y7YPhkRpw.vJBB"&inV~LQ^b+O"Tm 8ҳߓ/Y"e/-[ A: %ʏ%Sn1$[92P/U2`:@>dT$:OɌh jnFqW-+ds?+J*ce} znb:"2`,V :/hVz1:N@){pɻl` Mg~gt1H]u˓L/ok'4s7iQ4qj+c`D7Y>A;zM^|6-K%k Ȩ 51xԿ}$xj<_;Mp{q&F0RoT4ʑQڼa+#=L4ƭBW}d_o 39'cÀ^;mÍtd хw/oHh5ë?ʍDƳ'l@Uo-Mjfa^&: īI!o~ 5D!G)@FDG q"Z_ΎJ[fEVg{)ύ;b稾!.`<Lq _Ljy`k?[,u '·WeΉ ]QR<6a#y%]]tkH68zdS8 nc׃#ӀX"`w>~%etR}Jߓt;hrtd$eJ*' j1.5̐KzFD;x^K<1:̭zSgYd8TmԏBOT0y qȒZ kFJ jYw{E/y'騂Nv*.:2|y**ٽor@TZ%/8gT̾}4 M~7H |~ppcßCJu6-8qDMzoB|frB+?`o=vuGRNi"ΡD{%qQQs/MX,jnyӳmE,tNc_ bXx*e1mf"m{x׀J8Rt>5NkXE0D]yVbh6^FNy^q3/9$Jb4bn>&2b?igq߶bX',Q71BR6 QM"~[/ e1YZ.zPI\ ԏAc7;.x螉ci)L +Jl .'OjAۙNS8L69x0/[bkE=RRE[$lju~|"<˶d [؈$Q -it; (wFL]E JX ,A1ȝ9wS {1WzSkPCV#WXX b&`mI{f E |*+UzN>p.#O3y0U ,V"0"}~ CWDU W0ć}|ekG*`a.kߏhC}BmN3O'I(ϵl+-lwF>_)ˉɀ򓉓v{ۚ1I~Og܎.{˭҄oEY+d>nK;OLrtV U[idBXi}ѫZZ8*nͯOTɌ2%$G(b~ck%r{rk,oIG9W%È TgRNa+OP@-؞gIh7tNtsH4;/+XNStVV=o.hi'FE3|jഖg-r*[s_o !*<06)S% sr%]o9]aO x?2^`8Muo^[ۅ1%m!hAYWMTdDaU7CtL /]]P'#J?.a`,/]5@@㜯⼗OՂ岁T>7 NbL52kY%5ѭ|{iȿmO/!r劼r9.o[!X &SjQP]j[lf)e`Ivԋ%H0P7E1E`9 g~gVb-l$z ^1^#CW+ ,FOQ¿d؞ γx_re ծ$X5+eKmFTۗ@hXnkv d,HeݍCZKr^ ^`XIVd=NZIwO6,ˁ̳Sm-9 . BZ%f_ 7AŕgQRkO`کٳfVȒxwבz]jhwPQ?/=t>0bs>l2;˶o͖͒!tPEm5ҒC6FuVqցƸ=i@un>x[Xgxsnjb0dqXCW8%| ?2(,Ҍ7ZK%v ɵ!GGut$tyɨBye qkL⯙z4O&FľVYTR}pb?Fh>Z.Y A:CgQ%W)bXS@:"l{B8iE[K-#78[#&x-/a ԗ%Qΰdu4L6(viQb4O(SRgWcY5"W= 9'"!a mc`7 O-ֹm%ިB@G~]/#h~B-R)_c\rX3Ywm9]ajb[.o{cK3 5۱/FtF仞26 !yyO}:hZr1e ++1Lqpұ~Ȏ>'(0ztpo,:X$Y4~K,B]<@ƹa4P! j;HFRaoK? ~H̢Ϛ)H%aSڦQU bi2 ĩnq/|C~ ฃ/=6wg7)RV@f`GkN,OlFYtk /ֿ`w^JuV͏a d$*۬$&v,!N&>U~ޱVJٞT<+3/,5ݚm%`pX?GQ ¥UB l%Eh"S#XYLn&S#Fً D>g!|8iL:AJ|A- Κ$pUsLx}]J?bI!+]kH<w' s:_8׀= Ԗtts{g':#c >YinC]YXq3] BIᗝ*1y7}FG,vSi.A=ֈ*O@3eE)F%R9=[do~2^;g9j$gTYf..k 3lult/=cy8SHvzB?W.+?>Yg,J#ʹ:c 3FHHH+Fߠ}Ҁ{I.pL.\mH ] ~-<"AisG`Reܝ!y.bMh9q[ȝ (5Oq1\.P,(l a'/!cd:ki* ;bSڦANSJ-ꞓ*I瓅> *tɼ͘G\b?}WBʷ =W'(;>7@8ƃXQ(I5@UCH)d-)'[_e䅲t]:)GU=ltB{ھ'QGzJ /ʦ\?JV,n&=p0TS- đy ϐ l:hy 8wքRWQ/> RkTI0-b-F# AjyMf4:uB;7[ e]֝XOt̝F}%\%buhxlR=2wH} d~E1Ff]Ey Ĩ3HFT83[7l6q-\DN!>%Ό"ǬcaaCYdEw?L`>b.ŇU2Bt! ͅK1ZC 4k2 {dQjLǃ7ql٨؛3kJ-?e"N>̭OO,18-o"3P1g˶ҽ)}?SXPy1+-n@"cՙr֗/ ;`2#`"##[scur) -rۯH k29$5)\b3Al/ 1GZicKe"U=r6nDMՖ-|4Vk`f|'m`2~!/<^3G2<>B`z6uVˢC=lpYTa;,bbg<= /g~k!nf2\E , sS"B[(m ^:'%Zfb ϱrnn}Z?Kb,!d&tLv8wҋ֍D$]hJ,|%!s+ ORSD{ *ğ-+շF<xe (ID |+M՚n] S88.?WqV8' 6Dsj3q7QuT֦ pQ8:pFi Nf\~K*d8꬇}@W9~iq6)1otXa08*WȚY4ܒ1SJ VbeB3EW۽LڎGqBWqs)}p咁MXYglmvNhgjoV:ۜ$O,sCo+] 8DsdzBS?㿊ЉqkLPP6}D/k0e뷕bű[X%=: xmhw \Xtc*#j\Jכv.զTI|q2*{HU<z-(y+ZUE]$y !(a4^N%UƵ3>g' 8O \tUb?"?VQMXzO*CEX&U9@ 4I\{(.퐆p ^HͭxK0Vl9 zYCkY;8>F r{D} !lʢ&i~rlc.)oH$fOIC*N?H֦gYQDӢ/gvSX#Haϰ FQ:*.;3 jMPgٔuFTmZTZRcNCEt%y9yXhH7Rap i+>R@Zq> ocg7r6~?Kf% oqK1|1] x'0oO?X|0,FjdLf"@K|Ƈwο y0t Ym'uoIoo{>!:uIS]m}8e <Z*M9szVo=TDnAYhc^?y__)q1 4H@| oR~kk΄gxF0V* ПU3s|OQgSz>+;aj*pd'wi"k3y `} (94"B |Tnߩܔc4&rRؔ'&F!i[Z8 śHnI2hk9ѭ99MJ-h.1k U[B3k%amhX1⧠Io.8r""jK&iڞC}VXˊ bt7ͮ0Ϡ w*-uP\?KwcyA̫R'UjPyS$>}=p-IQI=+/ͷMBF"fnoCl]ɼTDujm-BTsI.d|#6DZ$w̉ /G3xBX/:zAD";.Eq[W39OX?хM< %gOc֎<4tR? Ze{(Cpk`ϼ58baTbKgOvUZ!vb)趷_0D<|,SiFX& 4@)yL QG)`E7(n#{Y[v ?UDW`܍)SXbՖ4m fWk1%N ""UFN0*H0t:Y$f{m$:L%(2Г*,a# b$d}Aӕo{,.S! D҅.k.aC%Y8k?5*4`W|.rˋ|Bs]=!忾1/ bz$isĨF(d*&cټq[+j3p M )@^(jz34K;=^gde[wXo^hep8Z^lkK_$qc?2J'i q>f:FFLZ4R%3:_`7U"c)4sˠYaݻ†l#sl[ 5Ν"dwvmS^1 5T;8.`k.Zʩᚆ%VދW8P-LN짩;[V̷Gޢy%unJz&@`O8pL@<V^? MKZzp;ѲDrt".x;,1r1i8 /Dr @ 6Ձ+$ﰟŞ|*ȎLxF/$HA)ؾZ07Iz8%[Pƀ3Leɘ^(~uPxy=AXaDxM.-cႌ9Cі5IΘ#@iTl9l_b,9޽ Os񹉲j]E}ȮGkMuA 70Db1G(b~J*0\,h$ZO F ʔ2^h }18, L<@\.LP ^*P|B_XGcP9q?v؆! 9FC"2sN3^1O*>Lݜ?ɝTxH!g:NDT, =`^c#=ܓD!y ٝ#(n6qoF`U]P*snQI ];Pv^9Cs:WžtɿƽH "IbŸtLV!v|L93ΐ.w:PWN?(y_͍D3&k/06~|~RZO_M%0$3~"Ѡ"zrUXa'@BNv >8\9jYYPvddGnO#m!-aȨ&O`ihhp,z#F )YLXq|/א /.@YN(e306,I68sOni&zʔU@r X4 [@bPD&UePl%CYr ÀAH!1݌đ+v^%kfUļ; U"(>_7+Z]I@/2%1*eG$o=/"lՄ~>ڰ:*+Dx2n@8A;E%_F?[Z\\_n2l¹_KqOH|=Oٻ\o!Ww+D&dNjB4JA=y $1&hߡm"^Ir<`E,\ڇO) rxҗX5f$b?<נ V47kQ?wMD ׳}Z(dwI2FWCa2 m>B3cC3B =P.y (' {4Ξ~35L !*aiǝ۬I)9p5>ox̦U?N_A@m) ϣ4}CY|S8N5*n(Ѣ+פ1ю.ZCN<8͋pG,@\#YH@W<1oa%DU"5u>lX$&)QER_k^YrF%Obun'2ŽdK=?yzZ9'.xYHQ=ļO|(n!=jy"Sg3P&eo@.[0k@@M,ݯ{1-q||&vl[.BǔR${or,Tϟ^&oSʾ VztAe3(e>VqI%AIc~Hk:'3F{EW=bns%}ȳ |'#Q!- C֩JoL7)j=NroOӘ @܍ʣ 9x sTίqI}s Ԅ5:u G+;W6s.f[񺍪~clwY>816'% 8Njn !Sm~֪݃S 7aN烞 0*:: [יP_,HD|8;hV=+ m/O5d/,*!h~4[E/Lq̢y,k@xHԅj5גi > x6ٮUg絛 x$@9|tM24b#!#0 1Hy_fV1ʌ)y&)m#fo.)iRK_U=آyw>dt 3}5UrtD bE{F-|ͳ .Irumk$bAE?Q6to2,/(ǥø෺=Nw%^l37ۗ6gIܤY1#9HZLKq4}3 JÃ4}waD1`HW*&G$ߤu(7tz%UIJ'AA-8#_Oջ?^ !54O&7D:W_[m{vXp9a{tdzNGo^kXiˠTn#BfϹR!o--ӟSL&ܲ8rᄙWbs.xcDtƾs ӻMc3?ڴ#kңq 㥐OҮ=bca7U bJL+zqъޫɧ$*lƮ]%πx󳨤-e\Cz>כڟ@ZjF_d]qȝPfwpG^e͍Ӵc m |> x$D,5W宨z ڞCBN^\&%.,+`azRqb{jp"|)'(xXWsҷ~5F.-UPb" sP**? Uk'cP؈a|}1'H}~+ej /Q ׉ѕlA )c0T}\ù A0"™f 0]VԌeBS5n18QIfZ)zr[+uldQ]4/&O0=?L> d{B(Ja DRDpZ窱SW˴^@ (6tKZyo<ԷguuS8xm Y%#|0Ή&KSXV%d]o!wO{1f_hZ~f⽪16&a/Phcrr\R/ ^ $9P!c@ 2 tz108m#/z@+/gJHsT,=k_j!={+ХGKV}JB.6GjxwOB뿗ˏFN i~S1k*1BWh;=YCFQEw/ًS'ktr GwjhT[ [+0P7ԳL qBng)kdMY;X:H0prv_)ʉQ{~ iqˉ š3W@iq_~-I\ {iqk$ (/L+vp ,z qF *4rܭ3P`!GK[a1ZVKoi5 "]2[Ɠnk}knx8UW2_) h~ }ie&:{\A=yg"T";>lGqQlc][U+ ˛U?%>4fpI})OI7 Ǩr9$u&߱}T0R^鍧,fZ@~Y2Ŗ%'SNٳIXE~^^3]R#@9#es?1@4u ^vž9 Y{:4{VfQvXeÞ0[m3 6 jR{Ջ|~ÆYH`/%_mu[ ߁V-bo[`>Ȟ5QG8%Hc 'W ޻{ RSuF8Ș+naz@xc\T?8ʘA'xVQ6^6BM2P&f3f:Գ3yFjxňNff_L(g!qq.טS(sY]v:XW"H, TWO H:uy DN+3pDHQ2:Q>VxkVg," ]f^eڔ6ˇ2T_"׷L{J cIn?]a"@\?MB+ ק ^]ߴX~tm&̱bOu{U\~s;SWVuWנ Jt\{-eRUc&Q3KnrV̒fzr7 Y%M8\xFR4f]*3Mf^<1'U6C} /h 2P#Ԕ 7}UK8[QZ7zam(^E]{ & 5F/1#⽅̈VzrrV0 #_1HdZVXOpȫ-bzI 7 > a"?{p}\6"K\ɕTJTSu\~IA|a&ZTI⒓MHR :nX4,[q3"@Bۻ7#2.]; < !K-3+ mAa i,"\݋ 8adلO߬ ӝow@*:Ț X >C(.=z oX@oӵXzWù;LJC&tS(*:r߫R9"=ՆSX67%aCNМ -cG1X~oPgQSqᵖani _j@!3FT †'C%̈́jGv"mȻ 07C#HwFI8;ϓz+8)nY{x:~<LW+3KHe iySJs,ذTZ=>ˊ:>m]x-'.÷ @kS_1jC݈p48YV`OM/6}". |> Bc"a):P,Wj:n챖IoLNC|lݹLX"ea}N9()Ş>ّ콍r4xbvdB^+wb33l2X)"f=?hXX>!r ՂXi=U閅4H7BZ.(@o2ԑlrHؑ)y9z#Z;-LN?2{HZߢ+|=RŸ 4yGyPP7U2 -azz rt(/ؖnP_d`u5˨[֩9LvfY Iyv$js3.:rcڤ=%Ӆ݆a8p )V$Qp˔B vbިkZ&N ʖ*Tѭ1D ;/LnW 8T`XT{*Nhٮl)L ŝG4ش)SiۇνgN=9UmhCX,Jx%>]P'|P|6J3ͯ"T.鹿&OZO@ύzUxA6G^ˊI(C"_5_ֿP^ G62̳g.RG6 *i!d `i*b%¥"S;$_E2.A_=J'Y5W,S@\uXڍ<{ՙ-APk*!m/_[!w۰mIZёqn>i`TC@NEb8cj),uŰ5+&A_LL+w#=m5Mոı)@8`0 M ^M#άoj}v0K}% kXN[rhgDtw0>Jl\0~WH{HKw1~_e \dQN8#}k\x &BzzHu B5{q]578 ;Qp-T/@ߌJ+ | .doH)-"zT/yv%==_GI2D7jèrՍ0t_1k)6afe؆pM'`Ui/~IKŭ r6EqND >')uJ d Z࣑ 󈾱4ˏ0MO%W GdoL V)4aڌ$UO \ho^YUKxmJ!Fbe#{lXr9r䯄8 K-CykD~H5=p4fmkK *RZ*d_` cEs?' \~9c=Xe%|%I/x}EWRO5"g*0` l-SlvW +:̓-TH7txY˫.(jQ.S30xr&¢Z!/G5%L~e.̂S&1Ւ;KWSҽ(|^8"i'U8!#~KH~ j)^sM(&uGȁ`u%&xfYPZ,ĄOWjw3"xn؝m%Az F`qV0dD}w,r5݅Н뷖`JbM8ۅ\OM觎oBcm<翩g#Ӝ=%nmNrMGET@Q1œ"w]N['%rJf)f\~io1fx,TZH~wWk.un?<wWJ{B*yD-^~㳔f~%U9uy /AbcC(w0(46GzˆUރ;bA]dM+vpGQ+'R59Fg.|Њ.G JYbc xyMI/xmV*@(ɤܞ@L#A۠eTݡ[=ѩy9Xɺd{`^`1;7.,'e{S_O2.N{)BC֯O%:W+!$?8%O x&5!,KԷ5j}^>.JDfK59 ޮީU ϑz ̣}Be"7pȄ0k_;D.S 7KQA䟝s/[R`~ZП\~%>]7ve1l;?YТZN{ɇxQ7?lՁ= ȭuˈkEe>ܷqpZjU]xҤ%o_My vFU0Q{kbޝL薬ء؅L`<zccI,gxbJ0=`a EFE8?'Z'CrX4Yђ<>&FqN$nX,41r !6% ^A,!YH 2o۸pۄ` c Vz9הH+Ht^`~,[fgR{o2wB xk  9`seW ]!dzQafٮQؗht3U ԠsAUH`iz@r#hV#Iv}6݄V ZujT[[og;d(*E[xjncMz5+^JsNGy8^ML%SP{FF״ ea @#Y5y(}O>Ezta`ͽl0R'!/e7P'c"9soU ͏-Cl/IDW&J14v#5㪅Yӥ;Կtͻ$4͗; `G0`у`30A*7[7`.!m*w$-=(^55+/xYTJ ּɆVkUMD>a EHPy^&]z?RѴպeM9. }HzU)8s]:zToTv]/m&"""t[ԍfi6C-XjPaw)Bb:l<<iյxˑ8#:@@LNCn8PQ֠;$b 7^ø[3?HÏ.bkt:mdjb-$Z[cCc#=Ro;>S|ʹ X# B]3W7[õV'YZk?!m(tnFz M nu3?ʇlaxGFx̷i ѧ dy ]di(s_GE_nOOF^H_:VS#2ciJߗ\fٺ~Jywm@ԟ8J%kFK&H.N=SYzV^hئ@юAomp :B4,x.qs DCVqSF{+.w>l'a 8_IeqTc+~s?k:bA:lyx/ wdT&9E~wѢ #^21fh 1\~~x ȌPF?yAUKw5Hy'|c~?&ē6,QK`ꥩ@%b(qL)?Z(s9(}U?qe.'xTщѭpMh5`^V!>G]ftKvx pJ|p"xzrDE'_l޼M O7jN n4`E- ^cՄ@\18)TE<-0T}}mNNiCsd.< FdlQ'؎z8¬Z;7G~AEiL՘5=#i*$n3ۇڊn0nƺ=Mܨ1Q7~yY+ Ow]t TDj.ٌ:y*ʥᕝ,݀^@xQ [ۭJ.8 c53o6YsI9^*ѣl{BMN`7(!y{Γe*NzN^C+fƗvD^qx+2tv:uʚYC|֛@UZ+5G>Ij\WH=R|)Vx"3R7c$P(~0 47I '>964;5Zl T4t_Y ;C [֝ߋ $z2fA6vpS% Eqvy}?86:)b{ j8u(XrQM"tCeA@"M Z3Cf6gtP*,.LG<<'%æaԯ'1},)=Lѳ*1|mHH~^ *(/ɲ@$?ZŖX 4{9ObLQ[sA׮CުnReRPZ:'mZ_,wqk&u_ -'[jJFA<|Abk}6xOgu7jV;8Y_ P. ([-$T43T {I <9*DS>r1b>n@K?%m yeb/c(uYQG@f`I,[b{&54Ql3ȼ%q\?+ˑL[=oݥR#P nJgs&؄&yZKoĒ/_' QӏWz0w[}FLƍL){[L_UcjΐQNLQY yذ|<&M| ,G S$l @#-Φ0陕О{L)QvJjM}˖R,y>uGhl&tK&~6Yia4,UAɖ:hqSZƢ bV@~蛓ky)U*^@ OѼa~E&O߶E8zg6@_>{sk9!ү?*d\zSZ1Z[3̓8׮/; u!Bi/1ڒq wjـbݕä6!E!>  AWGy΁Lm)A }@J/KY?]@ D=0ϋ%9% d{_!@b -4f3E0j{6%Nt0Y=#d dOe.wqы dF|1="&JX ]P@E\ |I|XxR4>=l7Q7n9JGo 3BR$YZAMpzP͉I=)WݜI?sx|r({C\lϳO!\r fpF(_03񩟝k 7'#ۊHPDFR ?96jNƏDA[)e0DKjifVJ h\m>k[XglӶzPww> .,-xd-rf 6h7?2GY/4&!=Ci>®utbȻN1@b1\`'w@J~7&B|_t|rw`:QImkO7oʭٯb= P+_[H[cLxCawOWDcH rּwߙ)|9ϯ/j2DB|vq>]Wu΍7PD@"b"B*?q6kL7J gsѐ| u1408GEz}Ltó?PE3a1|0qޢ/Ũh.rlB+8)kaPZxðEO\ɉއ {Cqqrvq߾Zx5p ˎrx^ˬ '!)EpPvCEi]zEz؄ olN1A?F3&EZ93DHr7A4,QfJڲs7Pi[Ү K%-_O Xh64EWd;tH?,d5X5'4\Y؈+MX|kyQQm|HYCSč?7_-Iutzk-rŞͤFf<jUN/~[Y3ĵg44Z-gj3Eca`,fzG5x_?Q@jO\ 2vq!Kk' 졟+,,44'zy?8Y>jybf348N^XͶ .*ŤDҒafsꎿ&C+ A]Jj$Z 2+ a1G|rY|{(@ *wxE0V"2 㸊ҧgb@:o10/dKrh^x>Gk.#Ǵ\̩6u N}87z )"{ 6-vW盹_wBG-3,c%1-6/v(jUЁ趼 D!m W9󭷅7j Ȅ(&3>aTi Kйp`syE9ur3QV^ μ}-8{@wӎuL/Kݘ `p;P{`žY]\6U2'sMߣ8FӪy1E`A=-*Pݻ>Cpt| 7mpo;y"Z^ɒ1+~?9IxA],2ǯ7`#P633بz'9'V "qlO׌Y@bV!>S4݆Ȅ}]$1Q\H@335YBN|mơZH=y,l?IS{$GLS hp̉3I]wFwoTZ1>`zwr 8 jy ^$/)\PU`7Uzo!!^Rw kP+< ǹgUJFNYpx!ՠpw0ưW`} ">%:e9dOh!Ճ 2SY{5.KuR*07S/O<3TTϼ ^Z}r(clqL2Z]^pѬnQS(tcy,xDVp癳2]N.x_9OÅ0%ZL#C1-{nƛmlqG"mf!}K]@J"o!G3n4vr{DM3e9>4!:kZgVqr(cd^I2~lKƗv3e!G m5#Yk]浺Tj߻&+Q"~aK4G9x^N=dŻa9n^iss)ɹ%ڷv<4rCIt2OE!@B<|$KӒ7g W'EdĽ! n!5L\[a+*$rjKɶӟLo}7"Z Bvl<(g^1k.g-ϑ.}AϿh^I=[/](y$-F:?a&Z`?T!x]v0,L;oab$lAZC{S!eJҿbl:{GH>NjF ZCue?x1G%EFq ) rv>IE}$XSz8ge|  n^Iv&n(Е'kv :6.kٛ낄:BgD% M0wQƈsx\[,dc]D>rW/E_ ϸQT2GSoe*odsbEn;0& J sIVgGQfwMj{7s v b`Wlk L+Aٳ2Λ(#jͲ?[MJ/k= N6Wa¤3h#CQ#Wq2«PfWn Vrp*_>OBfi?9%֧T+d%3zB'i{Q3^XZ&$t|iy1mz'wL"."5sɸH8}pj {68R-_ŐN~ @(+C, -f+_#^ ?@ax,%d(y{}oZP!0ho8Y ?}洉SO+x5\rUfL]NL^ UЧeGCAI#WXRcP0-DŽ^u4<[gYYO;y6 G-OSִL拸'NKB[b4r7]iIj QMlaeLzY@wONׁod$bflV?gz\O ӹK7MW)(KK?s=m'grR|v|h $ oOCEt{zOjV27!R.qUHuebΫ#\(xZBԆ܆rf}ϣ>m'&cR/`Ѫ,B^C=*}o(z 5hs>Onp%ɂIK ~쭚"rQP:};3B6tЛ]HkʃRءӎz6IPځC_l pJy}]&7x Dwe|<'}ͨ]1`8+>u V!BhmP -47 U*N`'l-m{V"U bw`'幈y6z)H&Hq7<۸|t9xw`]r) ຓ]^kDӵ߬oC*NZb`Ea`K2ٸ33uA=**ńc$#<ч҉526hZ;nq} sW03j NE'o);S !efayi6o!5_nnϨM=/!]?ܦ:39RR(_GIVy'peG(Sޥr#Z Iv9^us;5+UR4`TmE-1('V:_<Ƙ_k̻IHհ cYm cę*5OsúaP&5WG4u搰3};@{Wv&YYZn#a=yE{*J fK][IniGȂr5qPL0"9ow:#^B*W5F_էb1Zwh˲z4PZ% C%{{ll3N1#NS0Z;E h}u~jgNDu%}-PocaEG$8gN&4=^䝛ؘnR1TkPR&$  } wʓ"vS_,=' $!hL*t QlE1nJZ͝+C 4/-/3\R_o9g`#t]Ӻ(ع4bBt=_;CilZCq0[ɵ2ny\sC@C7qNd"K-v+5\@qK8AF=ƕ߭{3|&J,p?8)>)Y o@PyQ F_fqќwkAl(+*p3}25%\vT_~NkZ\WJr瓌lD|iM*bZs0o] .HWӁSS㱒(wx _ ;.iMLdGg][29𜬚+s'3s:o WHD QHwrI$t7UۓhVβjpSA^13̼{gXX\t%Ves!yY/.Ձp-.ף kDE횳f*8g!]T>Ґ~J k]m64BM+iU ]OH ׈o+HŴX$Dus  MxpX khjzT kX!7 C[G&ILDę0O/( Rğ/mŅʼmAmuwT&+3Lt2ҥJE:_>~pHc%{8|*/Y>jVoް ޜN_쑖!t84X3L w]8wKۡH=`E Ոp)XAl"ϾX #Ej'{w*OO^&M~B6's:h9e*d,db!bg(/`OiN`@pVvOz b$*6'*!T j (kDpBKlj8eMo"3O9V6JUJ^ 6e7ˌ~PҖlHC(]Ddi{)8^'WLA5:m'j)4YHb\ڰ\v~bہcJ= v.\RUM->3XF^K:O}f|)DvN*pȄ1#˲M : Hq"owC[տ﹉Re2&6=9V^fQp{wa񙫡1^ @F> ONo@-mo_( 3K'FZmR~|Eli@.P-`K o5-A$lWĵjDZD&5gbcMM jͨjz (#K )@D5si$)(a &[2 x&WEl hM!]f}~J/'ﮱ .8#GfW|ad3{32$7\yyzjPwX߱w[QqRpEСv%| B+MRh"<W6ܭgb)Ru)z!'g1zẈ4&~#"qt Jܶ9 |&(@ x{FlWUa8KJA0]!Wz+ y_6Tq_x_]0Bp}ڈY`r#Q ؂EO'hILUdSI)[DߪeDxEn7OHYٺo'h 3jeġMuUsA -Ժun"o9[+~9+gv?#s =Uk\f ZA֤Չ}%aoWnϷɐ?K.kq3M 3&~\/D5X5A<5Ox㨏FSzԽ |sNɰbi:%4o;3Ɂw`];1'Vw#ڍKmy8JrS\RM ZöE>d1Q$Ϊ܆\ =,*[yੴh-ƙ_=s=sFBv5UתZ9\Q;nؿ~)E7˧,hg^]@őt}9!l`%L [*23u$Bj'ݼL σ%h'5dqoS "`843jAKUUIL($PA)AO% ~TU]^O[}{^w/yjr=[tV1i,Hr J<35iY8?:Qk. lGvk8ֻFeJ!^17SvZs@JRoh#fx/̫GjyϾǎ>/{BO\( ,`C"|g1LD9Y˥$+I\śalv _ h|Z V;䃉;8Hi58=oC&TJZ%`͡uGؿ_TS4P~-DHT;cR$NlݮC`]?0Q$Q = jKZRC+[o%sM,ziYl37ѯ>'U%9aq[>u×Ծ&m+YwftABx (t Tv| 1* #x$SJkm1cʋՔw)g̩izdX]BkTar#,Bή:fw(VfS&Ű蛝5ŏ|Wz j,',# ) )_U+ҶanwQWہ`j'gJDٞ m@=ީg|pM|atF xdPJH9kJgVh%mxXC}4~'{i7eDnҒ\p H;fY/tR'.k pWvGH猫}e 􂧌b$$ ,Ji*K̫g`o0N!n򊢠.>51_X_RuZY?3=B~ W9\Q}θF$t?D/:QsI-P{qq>ze}i1ĆWxE6ofj0Bֻ~Hi~ͺ@e} scl9.@i|3Rub:-HiG >'BdXhx}4!p~:U$5U Nh޷엥㖑FC2tg3#+nu|Q`7rJ_o Axk[xd ̉udPq;>1g6]x&LRPy:RDs*2' 2-Ry1|j 1p 58?7)Ϛ8ixpUf9& KGVgaEp=Eܰ+_2*f?ׄ?#7XbqP FOCNV6t[:]0iNa_>e)ZNMH# M?.y˳s& _;~$w)n}`}bz0=s@hE rVLiΡe9e Z^,ö(qlRm!Ķ8"8mY7 4).rz.5PS%)'~6M@Bj;gr?ԘqxN"%&B4AE,G װPpc2 н/E5dϘP(@? xOQ&\l(=M `{ GOƔ9 q6<7^i`IΌ:nSJCbG1LͿU_tF (,L@yefJSnKHGbϼ2GG* "$kwIHՓI8mbV` |s˟[R2[u UlKWiXT38(~Q hZ[]]oB!Ycw!ȹz[3ML%5=m[kXDg (i-Ox.g`(Te .cb'Hz`.osQ|h,=ܕUy1ոQ p=&Al~Rv < ^M6(J: ]eR3婹Dc}}딁G{'x,NȄ4fzqIjd^zXEإ0P׻BpT7cڤa7@x1꡼EG źyTR0n-NK_>O&: 33 f뉌o  ?F}{Kk4\z};oo8P 9$@ } tF Ң0B2EBHMi,"z_^/k`/1B/[m4ĠX #>t5vyen`Qb=P Dg P,@VXR;>y  wv42_]&vZ2vvG 8¥P!]&viz0^o<6YH ur  /YY!^h\ZR9ZA4';=ʺ!X8g }=p''=hq+#9N'rnU ȘX;vFIbg1 {k=w-bU-. P& -7s RP,.+8iF& `3e\ דBb@_Vy}J`(*4m5Uj4~!D1)Ԕ{KmtւAR)'7RN_OQkE/?CsSG+RUƐwtJxiMր2%a ZA.E,W ~.>HA1GIA`Cr Fc>sYlx7]'\0OgJ H9~6?3 2Rq\)쀎!wۯ@ODg (JJIW|.I8}Bʥ0911Bߩ/=kmhjaA‰we҄Y/P5F ufJP*u1HAQ4_ĵj1~2Jݾ¹A϶W-CU6Yp9ꣻR^pȁ *$dbDUX[$pK-Ҿk; $rsBezpxQ$Uͥ5$c1Yk%y^Km|",h'}q)i2e+{0q. AHAu=ĵj(A$jmUg_揉tiO9V!gs^>p,4Du-`5ً{њH݀^#GBp[c<&CPyIu-̣yC 9adfDg &D v~%_XXqߕV+~dFA4N*q^ak6i^ I!A4_u }EӋRdp@`Xg#S}*V;&yzI%J!и 9p=;jgV6%d߾KU~^(v`I F-?ȶU//(/l[?{/DZ ̈ #X0rYs!t 4ek6MI0 h2M7'n wgD3rAceWn2%'zc`=QDs"z(!%2aJxAE,G װP+auzG㊲H|Rw8\4(/. XGueXk>xr`䣽M}V$_0[tF (,L@zt>NϾkg*e-da8sC?GDg (i-Ox`O,Ae~, ڜ ;@pA4_ĵj(fe5!"y'1.I22t]jkF73Eaf}9V6QEwYV~(g<46KK ^==Ļp9 4]Y>Fj W*?Lҷ+bi,e Y(fvk4Z$t@ai yf?fpH"'e v8 C` AE,G (ogmy,=jehFTq .Q]9ՠeW%őkP?RJ{*m?zC*kT(nDqL:tF xF{JO\)A:K/Kl͵0h0wj_I$hLC*n*ݡl]Mt-Fy<`xUt9lF5Q{>Ne)M۰:W  ző9 |Z^IiJ2;āJSddDO8J"9QA?(Ňș{s)z @E0g{v+/iƀ \Ҫ0{`{r!>+{ݙBC 3UJX9Ez]45Ad8}zeuO'MVF\m~Xq`e{O W>TM2 )-R*6<>d_SՋ|Ck߶'n-xQӃQMؑwc.[Wcu2q#V\iT4̜+2b ED2KV^L: 3!{R01"%X !†jW@]b J `/~tF Ң0B2ŽB2JGK!@/6>0(ȭD0LW_)#>μ{Ǎi>czBAT`R<0  3g"~⧋K7׏!Z^[1[ ZsJeut۫T{i~˝t*|,h0Q5 ja5f$ڣ*#T)qͻSO!)$ʴiSX,Fpmdrlz OE/o(0D:] ٕ~?yZ54qdn$ӞMhx*E$ Zvr*|UP~Ԍ~Qfʁcp- ^Р8߇1Wih])6e&䗳U٩GU^C,^a)D )̈́Vq[Zu,=51 ?خ $'cW Y+䝐K4E `5to)ͿBG%sLG U 'dqM}ULI61@W6 Fqm>~@H2S[|][ ;0؊:2PFW.0M?DauݙwVRɘ1qmL,c1Nn9cYl+#VU8Ķ .WD*8a>7Jh9Bn o_c&*"]ڷIԱr)s3tgv d%q~C~#AE,W ` ^1 %aD=Ӗ @+|?0#tzfH3K M vM H&p !̷uVƫ!=)< \Y5 UhеN{pebvޤh DŽqd5e͗h4߆R"ƭ$;*d5qN MKP%y zOjYW$(5j oADg rO)m9%5 aPYx>d:: )bha>Zs\m@,^||fͺN P%VYpɹ| xWS ӲRAլT~x Ą,Men9}ߩ'C,;Xy4Pd-JVl#wxڳ4/@A4_(lak@IYZxГN6l@I}8pBʔ1Yrҹ#WF Sү؟&re5>JX~GV(DQ>X(j )!}i&Ɋ`2`;q+ +.tcj9inw]JWb6'RG0QTKJ ~ RkЍf8uZҔ!{"!TBY)PmU=PѼ^}E|f&d.bӵ¯BTe  {xrr|nĝ~W'7q˅2^7T?4А;Eci1U,P3p`EՑ$%#mip44Ij8QMAiAPgTW4jGUp?(@C$${P]Kg?J3q?'䲅pӣvl͘nH9`+l%҈bX8p:`(eRAyj.*c| Rj "4R"In/oCihjLĈW%eZCo}o~Np~i1O2)0D"Y%B8[#B 9J #`S6_X&pH`E'#=ɳ_5A縼W4cz=i_?ļhz` O >'_pîI;Ϯ)iBeD/]C+c/ye^{3\Ӓd\_+ "zztE-'n$cW6ӫ+Ga Ga]%лcdv / \M9[СgvA(ɱAE,G $%NCET;jҠy) :vr iFhW Osv"3ȿF%[ h"Q% קIOdT;by-7Źp&zb" 8*mW(4q|. -=v64/_fk}_2em᱀l^tF Ң0B2I#ѿmAEq7>1CFu p| Y%a\岙Be#>BxIV֞>ee[~Jt8<~tǫCOjCz0^UCOuCRg 9D}I d kMӍ~%fJR G5z8"З3~0^32?h-nx7u]mgjB1DT] }7"`\1x/ڡj9fgz`tHyqIwF̸!}:^RNN@t55\8?CDg P,@X'e-W[25Oyf&.z@ y0=+2B:ʾ rVyOBTFtK#Sm;fA4_ĵj0<@92%j{‰/8]䢒0?b%{'Z^ 80qc?<6ү)6D4HHck:Kx[RUv`  '4#R3+|x$hF4טfTn@L J23&w9zG}"5ZHIN,l90NO!|&GXrWDgrTdo\ &XDkʳqa"rz<S?6&l>ۙѥ| :HOs!T?ZV4I) uE+_:ծG8?Ŧ U'U|nWrƵ\kc!ob`6x98Da$|4cddCQ-щL*qV:cR/*ji'{c-c)"2byw<@XZ }؅?)9UQ@VMvqk=wU|K#CA E,G (q6u@9$Hb'JKnnoY )tF xIzj40G3/?%',HkXu?Vظ. C{;h]~lT³ 4:ݾ7XL rs'a-+Dg &D 4A04_u }Y6h0ANE,G װPT6mtF (,f#0oDg (UU@ 8At4_ĵj2mŀ3AE,G B@Yl6tF (,2órU/Dg P,@ 6A4_ĵj4AE,G ѿkm IG[6tF (,f#/Dg P,@ A4_ĵj(I^L˂xGeӚH;}3FO mʩ(p[?\2w =# .qCً+c^EƫV^q4'UD ? (}lZVV|)Go@i'ßv!Rwt2)86́@ cg+xG,({/E>h V;!xHpƇˁW UDvyX<;\iսj ͜dY _0|HI 42$V^g ]0 )XB?E,jE{J]VUm m yg nP̄6~ HLU4)Դ4^cc[2/BXt}Zp &)&(WS!-͋B#xa8.42קYrjцSt ||%R~REt"bxj8coj}:3!X~ ib o,M٪}9F$Fv,1qr$0^on<}r(Z-]5qK4dCϱ [qO2 caԷۢ~{ 7,bnS!NAû6+'Xbmb`Qsغd?(ćɦ |N[ᝋ˭FG@lUpw.K-yĭ oa~Ԑj;[IcޤzR*dXl Cj(X!@X]ǟ0(e`kW>,`K{vǀYW6<2;|_)/ sxziڶ?n=Fx*ݱPy!gI6k_쪍2~rL+#)o(GѦùWX?yLu{Q )3B3K>[quVH ɔ ~E'> UhcoZyU]B\>S=pw Ңv}!YC:]A#9s -2yץ?ԅϦOʽbl&q*Iȗf' NLˆv{9d@Wh1ETo֒bϽtǸ^=ӠjZvO=Gœ%qo9r˴P

b#xV:beIepC▻wWGJڴ1IaPxY=ġ~ʦxQ :qb\kEbw,[#OaF:vg;BCqut1턬;AE,G [̎Ҩob}g!06uV  F$Z {6SBR>jėd =mP(5e)~`ul\GٍB\gӽonXH-0VY3)>N#9V$"*FJݙĨX`Q[g@f%)t;牄2rO.=:@ˤy.h|@y}پdb~\P@C9tF (,L@|c=o=r n6 Y`;Dg (ك&9P5׹4[eZz J Z, wQ޽ܾ@g3. o@A 4_ĵjcemJH\G^4vIVh:&\]P:[ewAhU O(*›:ldUT)yY9G~@XxEc}+y?ZLB~֌=9m [ !35؎a6k' Ȕy+R"4oVGڻ7$)]zo%=yFN pĊjE$D8j-\V5֗hʌ42 CAqXO&X (n )D'$9ZN$5ڪMJs-`iL dwZ.:ٛWOUWhwLUs.SI,Ի%?AV2svEEl!mTn 2ā)BWtMui~ÿ(˚lK)a)?Rڽc6zBM@Rw [/5(y[RpkɟrШқ-6eWPR0]_,~K0ێƱ!L 9 &8O#GN..)~,:YިP À{ wO`\cQuULpeVތE;o0-{ A^E,G (q6u@q ֭B\&X~i?n>g-H0t9e8)Fڗ9i(eچ":~-{O3gEAd4_u }Gۃ͎FƷa"2[xYCjdUr.K`F!;I6ioU#roG, \ p`[~C]60LtsA` =HWRT}zyWIlZxK?#w*˨^P=bлeJ,j`Eśի fJz+m[Owx;11,}Sx)"%oM{As8Q, RJs_{]/<Y3e%rG&.&#^y"G+@!&|zp"Eܣ+hؑJfAy"vl2ގѸ!o3~fTZ+j`;HfTbBFåflA5Zi  Ѹ`?YnYՄq*oNoe7*٬vG?VS# !~cI)d7@}xoFO{["X|Z e+N'20)4 `q@ s .շ{W〘UV N8'8hڠ$.nߴ]*>nnUQ .`ԌEn~QB!( ЪKLco0kFeX*$7FQb/&o'M*;qJBv2`س`Ug[sŴ$3++X#FgWw7غ0m՚RU+>|qHJ0X E[YT4<9KɄƝ?[TqЮ(N ve]H4ݠ#E?gym.OG^np9+\4՟R$\Dt.=p'kQyl3ޣ~/v |GO[j.f;Ldlj[F}@2'# {qbF3=Z.#m$geB, Vd4#$3+o L,H"d$KqN<Ǵf,C}UH:Ï(JG.ɖOiQ~ϣ3Kt]Ƿ8VDwNV/(eJ8g#7&<g*(YuĖ,~{CB 1/S,&MQT(:2CAI21rS)U5^P^uގ߄8 zTd~5d58_ L'07B"Y=?ݨ56`RFi1X&/g4#c?u;GSm5 ;cȽ]0tfYOWl HH<>}Ɲ ql !mL FϺGa°X? PHȺ+r zXO\T*I!Y BfэN^@AE,G װP,e?13#z)W` (4;"dQ5̙ ۲.}b*W«[6r rwS.P~5z;xrHre 0*O oZ'+=SA>7;DF+W+zۚbD}4]-ilCEy@~]nvr\_w9g-ݩby: <_2I~r#x,˼$ÃymH !4{ M}G_F G5pT/xV3yi p`':5ߋM [{)vsdJz "*fk TtGzn,A:q z1\<6!:nZh7y^Y\ etxNq#*!L/M 1=>oF+9Q;ofQmyÙl \,FA_kNu}G˕9S~[ JF&.1A3Rfg :د&Oh)Lw*ϢXlJJvgf )>M;f/1R:tF (,L@ 'jXOi}yBҬ>Ϧ /PT9yJ 繍?2or5&g s%3̎ A}V*8 Mҳ%~eگ'<wMz#6Ą(KPOηN?vL!z#)fEsCZ[wв\P6;F'/e6V/0}]Lo1ysq e'BFH'w ս]KeЯ#.PML+Κ- wz/$e^=}x,7*wm/@zdO_E׆ԁDg (i-Ox '&Fջiѿ浆 fZ;C(U O~s0ӕQ 6fT[ 5hReC|3XP*| Wĵ ~XVE$T * ՇpY8B_:5Y(X($:R?%=9rP|3chlRvbBW_[6CZŞCn[JzGX#X?w:lLڅ93!PzVDY C@^4f]ZmV2M3eLeox^ K"wC E\cPP<'6pe0.BxqgFWVZ }:a`8m7RUw-,ܘI-[ 9T:.|r`d嗙jK?mBcwCaSD\& kfBMGj:Ш"eP.pz<9ֺ E0&|bdaA"Mm dyoD@kN1ҡl\7KC 1ݙ*[< S$BTHG'AXJ[Fܿ=:?҅d*U$SKW&Q_3SXգiߟhUDƟ{E1Lc.CS0SA4_ĵj(̢_N]tRm2l0$BqqǍa(#wœ6c!fUo7[k-^G:TSѡ^:e6P l! y}'ث$Qu(Kwf`?)'MHcPL 1iD'!?Ã:uq-FZ,?IJ\2IU\t("1O?q^}:h iQ7֦JIrPouwEBA R}@Ih_*:)9O ޅ+Qfq#cLz?93j.a5L {@тF"̛9UAQb'ml~me-vސn̬-KӪH3oDƠ3hM\"^A\XE$su+W3Rv9*R+|l#7NW}sr ?Ǡ>C1~hHRgx Lv#̌r8)cӛ&UqX26p$\oGI$ g=t`Bf RU4H ȟMYoR{[]3refڒ+㾫GR#mYӓJl0+&h㨀,3P> B.ML'Bzwc/+Pr \ M $(S̓8쌯K nm@!taf HѲ{+jГs%3R-[:U`]qx~3oy'/ $' fx E,DwZ Ҳv.gPg)y!F㫟ŀ1ye*@ 9&#/KOH;o R #u+$ٕ6ή yZ$`,=HjEPǽTECq:Q@CyO権J¾k/T~^Ŀ#{}t ˛icHW9SxCy }!"Ε8!1B&m %Mr9 0}JBn#Aٚ `wgx^?u|!A!k9P%'?=M}Wdrp f< é~ R̙ք%$w?]85ֲ6r:7H[SBgYu yRx]K*Ǚ=_?whjFyJ¯ $1yW0Cr3'zyMg[hˆU" ~CF_dq}W.6*(+L*km Zpf ܠ;"uc~e&( :a85p(:.e60p-~N;Aהål)ɝAQ^1%2n%nHN 5؆;}LqA;v߯2Q_m49jf厲F$G%\7 >H.?AE,W ~.>K[l#PԷ<W5t^߭N Zbo#53v -1v΃$`A=oF[r~9Ma2:X;#l[6$N؟}o$ƒ hyu}\`y6fN^Ƌb Гȇ}"xVC臇+/[:4dRd 4&. -WT:X@λWmI8ordU6~a|{D+*p D FczMr+7i(ZV4RR V{̂')X?hI^q"Ep̌Q@V v`L#CԦA5M:Txnk4yx<Ź|YԖ}Axhpzg fiP@ٖ3I;$̠Ng!MϸMfrd1g9j$A"+[/d1`dzZ> =M[9hd!G]uYh9A-:QEIK=@GϬ/#bRbV>:BbTx's/_ HhR;tC(BR WM(xπ3ZE(tʖ]ӄȘ0Txl!.Mme{u*Pޮ Im":TǼӋۜGOҝ/₟sB+ګfęo)_sKWa Oşt&\R^`b C1H ~ {pA4_) AjQm׀;%A, PhN!Jl-4`p(t&t`Orٷ)hWURͽpGN(PPx35RQs0l'EOqYaspgB*U[٪>y n\SmޕT5;">RN?#1k^U|)} `JPst9l/_[C:4ҟhN]Ƣ^b(sF^v_ $V_`8?ּɄH:W (NͲN :NHBa[PNCWAEZ1 >/lu^ |xIݯ_8ہg&~Îk,P[{(JM8,Z}!;1O>o+͟k:R683khMєfe%!|ޥwr>yG.}pV>3gBff~ȎނZn^P1 91$9'i?ý} C6}hPÈH1тҴF%7 ]qh-k1ꊰK'^32"$qLB!pJ 6B t{w ĹƺTcA05)DУ̭IS|{l=YF;G^KB" ||:J6d_7*L???;CG}d*7EhQX5ھlY}NZ=oY"<hzFIַzռOE՜H;lCiqޘ3qϢn +ާ>e};$}PH 5Otց\T`Xޫ^"PgyI3aZAi??7NSkD7bc)?VIi砗p*;7V_Z5$6L\DA E,G $$|5Pű1On$@[ߊc%څZp(tF (,fc]'l-%^il]*^0@aĊ 4P3&UKy [?Hw)Jo8BLQn^4vgnaP*0Cž㕰(I7فMo 6ܗ}~'Եّ뵆r@dK䈂^HOm2*Dg P,@mA/4_ĵjd KnĴXC&?b_̄d a~b7}$d;GRthO*:kR@37AME,G [̎Ҩ61If8q9ltF (,2órlii#1nDg ("iU@ As4_ĵj'2q5).(dt2 im:'kC'k d@DlI6Ǽ3x󬜦H 2FK<ӕd#J`{HA |W*!=&. BA^m`S&c^Oٴ%~bvt[Mdk'~~uiQ -bݑJ ӆt4⡷0;NpEwO8B"ZE%Ӑ!(Z1&&{Z2wM.vg.Dɸ# !w lTSH5vpN1M{Xb2 .ʿn$ޡ*# ]Ciϲ(h=2Eog|1ȸodYe̚Q:'T#l^S#Fכ~}EecȚ+?Ida^lRߨ¸a'+:PQ+y2v~hse,xsz=}rT.U4ImC3Ŧܥ :wEL f=fځ!{$92ՋϬTe {f\4ZoPGut>(>xj]@m_vSM;,8f҉i*|v7uC|":͹E̍e2 p=&V3%@a&_?@#%;}2#a|cu~´݉ݬE9_(` ÀF(bxuI)@cF|ӤvgF΄_#jgg/˻3&C@!myΗ'R%̡!=%#l޿ieHJ*/RQEirjV0|L5c;1NUSƒp ;Mlqe6nc ni$[O?rJޫY4g.KNes+%GX}&/fjGnyJAE,G (oLUC72sn ͟4T/tF xe@:Dg &D ;ްU q<)Oո$'m|erDt4pC   "s~/˷;5qZXui.ࢂ CSJv4hLʏp̌bM@Sa`zX DtXvI -*9d֗eTϯt ER3pHv kqi^E,԰2' hɸ4 ̻!g̾~|C/ASTKl{=G-.DŒ]0'xŮωmG֋KN.oPfxk[+Y?6o A \H"um4B'tÌPn=(@]R=yM~8Վ(+4Ji4yl`-W)8 Usξx?k7iˁel1H62EoMC$Ù*XwJ2UvG活mjC "Bԁx`T9A(Yt#PmGxF{ zV~% `5팍/ I[T^O- CWH4F8f>J`X4O!)"ɭXmABH@)@{cX"2.ǴKr]676GoK4c|C;/BB5]dEJ$jB'{HL4Sʦ_hl"Y]<1Rȴ~ኔvm{^%e5l%肜0 ƴ*+Ǭ< uIgeI7i\9hܜvXo~iC(_c s|(NDd<+TvV,7>AN0OzɚSZ!mGcJ0$I1_ecn"2W EK`P5bmk&q &GduDt*9,֢ઑ;ΰ 'S@L]p_[w@=Hzo$ͳV>_#;ZÑkzwx۩sͼ'*gw ,SwA߂}Ċ}5NLc1I.ۮş\^wrH b8[dAd2D+(\n>6UÏ \m 'ebrPIrAE,G װPq7;`gO;?VCE ?X6Ւl 9}EuB0m S,he WZɊonviT$xT^\tg0{?p6N|Eu7m,IztF (,L@ Z;X08%n'c~oصCjW>EQQ_l֜JϬ>n55|QwXAw i]EMVY@Dg (i-Ox%vŖ,$/;q뱾9Yx>g#f޲UkA֎@- 7#d @cio0 0m ߱,|Y C;vtɅ&Srה |)CƯw n_cUL!k# ,?: :`*n/Co1MU+ 9lgwTE6=؈3Lp%[6i!/\*P- 'pT.ƶe^ȼsjO=@j*xC 8FnAȩZM^'sZgiH;~N}:1]t7խAI56;>;$DGt՜^Hd(gL18 ( ѿwG<]s)=YC5x1!Ӵ`D Ϊ:CGXro߯>-TK kҋcM4Lk ROGA4';=ʺC,̬9Y}Vw_.4:ʳ+>Od<>#x'nr ;o#}I!\Z=j]ev^dt|U%=·,NF5ً$(GVV.RLp)چZ1P!Dj/GJVd#ƘGjX:d&H>'L - <j}УGJ*Jo PWm>t,OR'|Y)Bw3e+oMt;z4 7YԖ2Ӓ)%AA+ly=τ0hL? fxg?(Zn~8ӹSb1C䆖.lٺ5_|U;4qFL x5`fD4iPf,[e>C(/2xP,C]#`/&;t^d qz!Qv5d4z^7cig"1×qa}-&w2M!lM莜nzȈY'=T> @$л=ñ͚6+I\1|,XHRϭ]@DrQJ. =Xnʲ)JBzߧkO%nMnֳņHo{[ը,dMN(s0B!{4en߼璴тUguF$OލL-\ xqF+=uBF/ zB1?Nz[JEt*E{ xДNt  E!4wD/ߘ2ׇ^.,eQiV"*c=rV F lҝ [c42Z Дb YCi\D{1AE,G B@Yʽcxak#|7C 6~m\%iPc9P֜1HJ޶^V:IW7r>>KcAfC>Ln/={_}.BAYy|M3P6(+݆ ϶PBp0x45X~zk xUS>HXӌ*_ضo}^1[>;RPDN˜f́3?߸4J- Y>lx lDlQY~flM^NKʆnuEBJxcds~܀Z#OPV~Pc7Ɖ0Ti1û kM5$ߖ%1Ѝ 0֭8{PBJ @NWF5]2GybkF80(0Ɓ|jj!t%ۺ$d:3W})ga̧e_I#&^ʨOYM_F zO4ݤTZ`?5ܠs^"fP'1P|m%Z<5Ӏp*XמeH\L7҇{2 9(ЍW]% b[BT8tF (,2órI=폀-KK 4^nrDqY0:Dg P,@ͮ RM8B)ƾ0-MJ{D(o2*C1qV3ik bZO;}g%eM6,a CF(r (wY_RX},!k GUtW|%h{2Ѻ15Mkk"h~Wx-,r)xnZX6 ~ANe>-ΐ'CvleDg8ꅮ}S{EoUϫ0ֱ ;? W{O%݊ZlsUTNPbFXу9BmAZuAP (cw{ ?pn-gA<4_ĵj(e1N[XM^̷hi{]*U/M]V|y{6\4 1K} JXB\#H7u,쓚WI+H7xҊ8`ɩpIc7Ցmtq']#a,{3HqQ|{u;PLݳ_wo2/(ok]SNR>Xwvn{3G:DP4#+fe܈X'`d9<]9|'ڹP\-B{'o? RL2S?%u>v};1,=50S.0ftC [n$ϺѠ'x0*eZJf2 ʥRRT] wXܧZmP Xt<]r9zg.wBIc1̮((& Tc 1w 04B@(JDG [i6JMM/^R7}h&ߕι@0FM+y`jӢ0-+n^7X?J4*F`ڃ։D-,ik9M [쎎- !k}k\DKX:|ק'R5.B% ?g=Fd͢h~MC0i v Uoc4ƄObgRk{q״Zj$ 9鑉ۺ06>j/ LZH]E&yF]8nj'|0_ބSTC6BapBnkgpP[t 4=) ?;?7;NaF{/]o8e-[%;OGsԑ.A\VJ&,d")O=`XF 8p6{ #fhc 0Cm5Ȉ i"xAAAV z`zňog;τmJy)88`w߼yc `e~rʷ/=1jWPs#ə>Tto//tEKDJ^ &bzZ)+p&\kPNy%E, ?†]W%ʷf|CA~3oN+(wM8[:<Ö[\y C,W.]Fp\Qx̓E< ʥ' ؅OUU^iw&J9rbmuSj(gV+INiÖA6&=Fk.r%?vL&XW~Eu Hؗ1]ljԬRc{LJ@Z=yɸ,U5wC6/ 1Z*2cwT4{?m7[GV{L3L4Yc0c )>;̣g!+]SY[(qa;{kkcϳm;TZ^6oė Aagt`8rIVrs9e<"@^&4դWgsKݛcC uo,k#V@ऽxeq0q񊴌5MQi6Zߺ bOm|*\Y,_`iwmF<ԣxK|%sݍ}{ ;)EPHU=< T<"P#Iv5%q#dQ-hx.y&psA@=ĵj('_$$jeY@7~Q,(]\)0j%LH2r1=OfJ\$C]˷b𞡂%>|b+ApURwT${8?E'^ĉceIjܜ±jW5[To:,p $b%mCۥ-n JߥzT&yzז*澿YGWK)e05$~%;_2欑;:Hō׮aFwqqc uբ$/D"(-7"rhq i<Ⱥ^qM<.E,'w ìU~)4; :Bz3#X*z~ ~GޯN_[<&h 5+BEc,Fg~&IV.:߈N\>I*p+F z oHїzTt*wzm"FwO2Fo/ ЍSs1Q4=.ƓG_?):iaX(BVmwL92W4}rMF/Xjs 0ӧhntL˜u Ze/DC-DVƳQ' qD~;{['}^2 @'8Gׄo}^&թʘOڎAc,DxZq{Mϵ5wMw9e7ɹO@Ij<'E,J6%vDL\-\F32\-;3n.0aA~E4LG (qlچ-*coÛri1~׳.<$< ANEsfl`^,<ΐ62~@ہrP%>.RL0PN+P ުضW3>X]Uv/>iʡ[9X:8s|$-/7pjN ޜZ3?*!R4ÎE ZOMr2wfzd ft݅ '+*L!iג2ݼLkśZU.>kݔڿ8eaơdǏ\AR!s"\0>wx ǂ !Cq1\PLOv10>c޴nC,<…TۦVft\" k](4L\}aG?7piLL ]-~pIlUP_'K+#+ĩ\gtF x&a( o-K 5۪!5 w :+5(`а)g3LEzH_Cg`ǂYF+2~ۤ8[p⫓'$:Pf~8 l9[/1X72N~qBŖ;ld]}B8\)%S.T5 ,M:p)5iziz^r, })CX`&d#Āof>ĶY|_ 4rdA}WD_z@r+I؟1BCjf ng]3<l7ؔRn>y1_;XMd̵iztxNK+Vӓ=|^LQSF+LdGx֓tlDg &D >No:Z(8}},_KsaxxVj;1?,2˵.޴0Kb9(r\!6YKY%KUO Q`^ ?,wD2O_+vk!IQQ!BG~\)h]^5a-ޘNͬ+y7OA[ ]dqʃ3DCB"VԾ+R0k$YA4'cAkui1 [5Ћyenj4 #CkbfD8Zi~RXI=C _ qʯN j)n6UQ( .^k]W؀>EJS,uV7!rOFo|{/RH٢U0+2r"Ocظ7LΤ`[mJyi0tVb~;ފ7aw4M|yT7@WNaz,ܺ 4)]ַ՗]ZHز/K)Y#2i'hG"9`\qϲ]?e-7`N).TVdFՆ/֘%>h@[ykdlk!-0Y_hwĶzdO? /]O| F~ڕ>B"/QdocniL[#hg DI|YcXH1 { یIV$N6VxCTaȳ>4yPsrɎ%%0oՒ\An2a&. ҿ}a!UH{j;ᚧ! τ veM޻l58]]*j\/8uZb9!<@"DbJFbjݯ4\v'F][U>+wRoc$qPg7MՏf!$_6coݒ09'0PV(EuL>g++~]om):Vmq&!?Lmょ1[C?w0>RGsz@8"lY-ĝD($ao#Kly-CT:R:\xq$I/`kzqIL&sL n ~cWtZj]*f̌/vÄɏ,Q 4Y2v+䕋4)[hA#|bܮ~͔m}5J}RۄK SZPBn~а$^`Vtjq(!Omb3X?-{G`o@Y6pc:y[=Q:ߨ0-N+1G^J3f껩=fk" *^<~x͊D[AfWg,784[At8FsmQv-ׄBL-t|Fnfǐisv\b_bTzৃ <l_>ϟdHG|-f#%M;M-yߒz*Ў5fH\px`+2z+ALaL*CH:NTaS@U" ~b^J(ظN-ߤuІ1jbZ&ħ3aXr n X|7]{`NS< YO U!&/I1ؗ,p%z4FGRt0S}.cwJ|\0*,&\.YI>z‘aʥ2ٌB w8SyK?`Ă!ȩ5`J~Z816{5R>5WVRVu|k<-Sv )i:+^h!lHbb>A'C@N JAE,G װP,QBZh KM,rΌd/"{l &n6J9j!ͯzA:h3YhS-m7 ;1W&9Jߒ=P3ݳjBΦziĴR roVlYJEW(yͨcmy×;ΗoNluF<T¥`̕T=BXeU?~B4.Lgd3H,i$FZ#-nHVUR̃W|Q6 N9UQ9 "=s8-GM_C%E-4CwZzs5g)yz溊j -hniَ5$!6Gۯ)$ض]W`6*- A][v.Plsn˔|a&[Ju#⳦^)#ybhBwvXTQX1cݥo2)Є즄]7ّ ;4$,z2`S j Ea1K(򰊟Dajs6ְ*1j!+}EPyN6B¤a#ʶx.ȨQJYWrw叚r4-H3?2+2FtNYJB)[aߦ PlBS P*n}\#RmVZ:d![f*h|STFD_pk z1H l? 0tF (,L@|},Gfujܦ"71KY?K~''/ڇ4m]CZB)}ѳ ,*gP&.E74h$m0<%e /eif$Bދt%]h/O_VFA *ӀsBz\.3D1pK7y )ҩZgWMZv)r]?-UɎK˷ *!`Ӥ&諦F~/D1"lZE cϭt4ϐ+7-D04kTUf7 =1e[򬓛X6r6u@iRf;ۚtUdu䪾KBղA-tAJآy!Mɐ }AǁT˜'!-m 8` X|Sx9{ݣ$IDg (i-Oxk%,P,JImy{uiu (z3wwFIVuLL<)340PH+;hu1|$=?NK` eړȇ~Sfn(>݂s$kТ~t1ipYbL*7(QEٵCә;z!*R&a ?{W8 PϻKc^+(ЍրDGXCӄo9}ECV`%{[* \wx0u&KDF{Ê|iēT]#6MP>Iv a 82(ǃ?ǢTCܦ#/X,2&"}'Ђu 4GL0|QraxMjHfz>BQvmITw+Ct,6Eʂk:}ឭB?8Guk>]_?ƨ>gܷ>A GmZ-C5)vXL(#CC. \La,ϚJ9! =Mz(GZ/.p]Oɻ 忈v"97WU>_rˣ xq2͔<Ǭe:P9qѠMrSCK\P-7>xe@t8GT^(ZOy'@%`;,q(y6km4"S+, ,f'Q< <2=gJP(VE2z̶2leN@PÍ\A'DasA{Hh/PUt;je͚a{$rA&kGF#a.˘{쿧+>~MQhƙ2R C(!JyV亏sBrWfsJmTwWӵp^]!6Poq?%ؽ?/[ X+Ӷ rUe>%շTc5Gܻe<<14LD,ThO XwO0Nȿ|'ѐgb?w`NcV\lws6"10kބG5籣+@EYC{\ `eDeR(F[6khށAb#$vmavĆF #tC͍aj.z,T@6IV @_t&|n@w Êh(}R.KFO^ò ųD鿹уd"އfXR`oA2PTC1@1r C0V=]UU)6~NDiomemlLL j, ZWۜ0=vc~~5'S]ٮ*H5EkSaVFW{c#ټvZB0?Q%)v`V(JQڪğ8+?,K3>Lᙓ?KB#֎{u+9(+1e  b4L:^^K5jhJ*-%9*"g6,2<1Pan\M4'eaXDfcwl,Ť=CTJdùBw/66brM< Q)z/XP=,ZY"8b܆kCVp4"?@gm5dUƻS *={cNi,ۭ I33 "tTj)3ٺWX dE4=r5 30ˡns:a\*Oe[V4PjOn{b}'5>8p%a:L Q qߣ8K'k@c͈h}-yBCZΖg|k;7q|DZc|%#o4F^~d@`{1DAGc;ǰJ}6tuXRB3D0bos؍aFA7dlds̿P#Ã?lorg1HAE,W ~.>M˃τUEk:[?RnEQ NF+H_֧JIOYNpWi Rfncۥ4.obqgr/B&fiLt2ddZFKѸnfQ~O'?]P#L qHagkԦ13:qTiB4Z/_eX =ٵZa]\ҠMr4۳gv.%THP"~?+>{P+(p~\0$nśL p@w )9s{nm|F>ЯyCdw~>S]n*i=OR-T`7ќ(<:WnwIy<.NGoDվh&NwOgK%.FTc|yCrX"p9DgJ&8%DswnS?=J=C <\ g J>o_ |㛴|EA4az! 3)0u0Y-NCLWRG r?.O#|2mߓ;ΌgD*_@۲13.A ui_1\dx5$klhʕG=wDmVAw2$PĤ&ws2hk2ն 5Ot18A4_)Йo>ģ+dR$_ ôN~XM;pu3!~QLh &>WbСAp -zu젟s[M#>O x!%/,~kN~diuT=AY  6珷HcS`I4y;4˰ރUMφvn#@e %ߕ6%4V+'NVD-U#S ;@`V2(f+IC[WH$l{5 L5낮ZkK~2)KfHݧ1饑NʜQz",IQ`-FY{J,/Gh9 eXٮޥ|e͋BY.j9o^W}qN_,:>8'n͐kOSi2&rտbJ_PW*6F@$dஉ6$b6KhnQ݈&4TvCλ 'xPDRA,q麣Q;I: ~q76 ksǷ(LHAfEY3Mel[eU) #Mצ*=J6HnWC8 A,=ĵj)t.6g3L-h2h0 2R?Ck$c ЍWzEE'^*C$lw]Q[?"Y|vߕيwY$Xg|ail"(z8/4)pξp)%*IFCv~G(t{ZQ0xY0%ڎx!o*cpқw*R8ZDs6]}9(R>>w3߹c\ s?F-.9'ˢeԷejNNǬ)ׁP&EQ8чMhLq ss""]6~\n<z}8uF0X306x{嘿qj@]HY&_5j=}DZ%ەI2-Y:%xe&)-$zs0z28݆̔e},Ro#i{G,Fz0HFs9 J9zYZRV(,7~ϴ/@⑽nz!6lZ2Fv|] (l N ;s,B76yZb&*fF)'0+lDbW7 dUJMZ3r&=uuCPecE̊(,tEELh2?d~)CuxxQ|dD,(%oo/u`A5'cO'Dwz`5j '%QIY9$qM!,HϢ T#MyVBtuEY_{:htlYXkX24,ien2qO)n#cNwgT󌧂 Z[7t9Á ueN!dz>ZN5 cnu;q.Іs%j_T.ko\?O7 -rǧ6T/H/8[8cWzwMv:{rWl:[Dw'(@=/Qx:n mgibinfW}0NE?YgڏEk(V4jMY 9=O(g0DFCn܌XZKd5E9,o kM&L M!T$&%-Y/L(W扥8(&7:Mp{5G #DU3%F d+\kW*9gBѲ.oΧ )H&.=%?|zr-+ ɷ`@ p~>Od#s0N=HcM6(Ճp(n׺UsHF/e ;iBn`PsIxk7LgTl kc&^tzíઃP6Aֵ^`8/zч_DTī`o$7Z!$`I!=ƫ۷=P&Qמ_nh">HUh1lYka` `By vJB'L㤼$OJ_',,Jpaxw*.b[],rN+5g|;ߒZv|sr]9km[[G"] Wz}J3qA :%U~]{j`~J2nN$1gɀbI(YC4ڻHȄFF2o&xd}JhvOeLMDDx7S~>>$ 0Qǒ˾"X+6YN* G5BΰS.ϴ'(M}NPYkHU%s17_=5O Ʌ`N5d^]m\#:ZúbkvBsf3: +TYu8#/TfJ=Y_1qI0`a" eӜR!jne)r{ g*N.;:< `ǸG9ULAn4žu }PЛqL[RnQmcǏb\H&l*L"n(H.m2'F&'XTc3G["5 k,'B%#Qfbd8t9 cڕu#M3e Z^W-q7p,IWK2} ZTO!n=leo׫Ak+ƠwU' f,03ۅU +L_30BpPԗcDg 6@ ccrǰZ$4]~57N\PRtԲb>AbsD  z6y]1A=ĵjJ/ΪS6~; LƖmfs0Ur769 V6vpN*d#reP6uJ}Iʢ,sJȾ zb7j<(ouW6VwzrmɯBg~ ;4P19N\h]elc/+=etJ (21Le&\c3R.#v-Z1bmz.45*.H\os/60lqj®5&SLAE4LG (qlڅec"HA%dj_ޑR.DE @U@tF x,qO*.jH>( h:_b%o1Dg &D !.2NA4_u }Gٵf7X 0@dݫ1G S1AE,G װP1Ȁ8tF (,f5p&/Dg P,@ _A4_ĵjYK=nd6k`vp!N@ys %b$pI2A8E,G [̎Ҩ+6WtF (,2órT1YDg ("iU@ A^4_ĵj)8;nJ7zZ)L삨 e 3m=5Sx(az|^ QU_Q p_3%0{5ǂBIX<;ڴ3p) ͭp88yfɶ=$DaD}_̹6 1ȕ0N)G+EfІ1'Z\q-NÉL\8r])fkb$ĺG} B93j>j|Rhv5+8u5X+(NCcmfD:D!2MO IQ8KU;/4(~g"_ijrUB Uf{ߒky`T`Lm5e_}]]؉׌avq*^% cgd!úi![(vR l%Xk|G|&ܣ\?0H3鶥f(̵)c8d),QX%CbH |l=k Ӳ܋…ݼL%.9nT -]NlQ(GrrVM/y F Ni~:ŪG^rSRS ,Xf"/{~x;;Gz@_[n,psRP v  ',zٸIH'!<~9xi|tQtJF-ax,GA9kcM.;iůádyI2~at>'c_ 'NMnZ/-(.&VC[ҌMJ38@ (aac DK#py78ޅuTڳ>?z܀uFq){00š.[0!NDlP L䁡< |`p_N&S:r&m(n!U b򄗇خzH},D[Vwu)2Ru\54;A-:(Mij}JХU R1/H]^y"*=L$=YVL.vr&;\|~0|{_cM#~db[s4MSR/&]PwLniQ,+kvo4Z>&i )9F6R bBHI\8 Dp1Ss?2kU#,sB%8idZ]:rȳ| Ҳ0}%K568\GܾgCT|rDunCD*\ޤ?϶HfOg} l)$I#ًGn^ӿL*#N͆+EQ;Y,%%KR >6i3k &1 XSw'U$K忘I3uGiV rP-N\ iu䬍m%ʋ!g9x&銳1'5aU [\;͢h1ѸcfgNv]ֶ2ˀܖ%-Zgcln oYCng[<das)?L["/yp6i@Əs6ڨ>Z׺ۡqJw/K1O3 |Dej# 1Oܣ0"<Sٗt @Q8!VQ2M*u/ 'ذ|\,!ζOW=Ce$!_߸?,/'Åł$'a#vOv>9JjziSSd8Z S*F^(/JFe!>ZZ˙.a/x.é'ԖM0e\V/"̐DИ!0jk EM[utTԑf0ω]#=V|nH,/ |4'DhA2ӈ 2;X8;tF (,fIӡ7xDg P,@YJ!wmzSOC0^( ei#u>|v>x \q3T]^?u]|ݺ5j@2~ (ѫvtدT)N_x{Ê/aj1iT?ɚ+ (hzK*]bU"\3}%M#K}JG7%f޴  d7Q=LGOJ*&Em:P+P}m@U#,o.Q5.@ ʨH@YT19D/%^K5i \$ ZI'{nA4_ĵj(Ay0 ?t~ 4Qt+i꽜/M:}̑ma>cM(GrGc 37d@@iIC[q>9 y˛~4Vv"۞o+WyCS_>zk\1 9t1gkyAq4=M3|XQr%og`u-*b~NcKZI^]nUf[ L{%b)+& kI歰Eǟj wc/2\/(`ؕ\ ߯tǼ qƦU{ rAq˷B\#h~{Q&](|{="-N<-)%9K"Q)!bLn .s=79pD-6oH*. 4KV;Q]|xyaiToz>a esӏ_K w }C?9/p>ڠ&t oM0R#0nf)W$Neڂϳc<{C:u~䧓„IS3 +z -]J.0T,h;SIɋAͺp/90(Mh6=|'m?e$SQ\pK-S=vz3h w֏)ݿQj[RkV,M:_@W#iTm+82^-&΀vqMJ֏?W '|HԒe騹$0azV.u{Ǐ t+g_Ti2Ϛ<ô|-G\4vn'N;Z5#J H2Ҵt.0T#R>Щ/8-PO<X:1 (p0 $(0Zs VJԛx|}=K{ Pv0݇s)op*0=OJY$BhG(|:D!?"& yxIJV5B?U&@'ۨoVs1j@Ń ҭa}6qVLk"m.*";-@6rjtn(KqRˋCƓiW63>7p'z 'N{0<^XZlzr/e!U3> sghJs.j}!WU4ac«~ ?L깨kGl֣ϐwOhwh17;[pUIBCBAiNW`jqpbK3VPUח_@Y5>QrΓ/"LB)epkI(%}cEФXQЦVvo픚" :xSqFS:Yc]塣_ǃG&m2/; ڗްa-{v7(7d=JA'kM; 4M}у'& TE(éGxxraÑkTutaKA!,|Hp},R&Yd M̨°F^"M[vSESD O@yqP7Dڮ7;'L w.f&FS,,CEJT 3=ktA 򕍷:CDM]H$6lqZHI2c}?->\a9_DVT̆'AE,G [̎Ҩ=/yC:+g'^O=%eҔF21FS=烤$9E4=Aq."!Cffl0⵻P9(fT-4Y晦}_Ydۘ- 笠Ƞ%vS/C Cg'g|llHʀ tF (,L@{χlK85Ҕ;193&Dژ+Rsr8; 54j=keрlvd47w3ؙN /ѡ jj=("rcpL^ʌ_嶪$[dL`wJMÜԜ꾪ȶM_,ֽz1V}uYis43A4_ĵjF9feC"~&h0S}!WޑNgv 84UqEkFD;_ =ЋWp swXp ͹/xhiݾY:2{F`. h5 $xaj"r&f dr saHT̸r,Fnrzk%FUv4N!,F9IDtk(dҩz~sӶw#IAE,G (q6u@-XUU[;aϤ~X %5{HnQ^BH[#s_\ſd_`q"k]F엤SX I$wQw \tF x)c^o-ex_aIe8 ڈ$lWi+F0Ne LNEDg &D 4k%^JismA 4_u } L &q(}8NPYZE BbX_XU`XGp"{>C'5(=sj DٰhZLS SXqWn-\ID<gESjU\>꣰)ȜU,?]աkF n $HU?$ Eb R\mMJˏ}A;tչ0A(E,G װP;ԅE.K:V?۽u`5 >oYH[qcٕB㢰"9Z)w v7;>4JD|<GtF (,L@(fJWIDg (i-Ox6勯b_ipg'FTyd'Aw8$1)g2/[2={Jb>>=頟i(%8ڃb TI8z4g]o3[@0!AN4_ĵjS ޽4z\%1gU$d+4>\"a[M[61`Xд{ɳg?mg` 3/SFN.oOD[=7] YAlE,G B@Y;|@d-EqNqP5z%XMva&cQt,=T@W(ULBt}޹XHΘ*F$)Y97ll8{`ÝkAtF (,2órJg'MIwOkJ({=S"/WtwǷS]w4$WB>ӧ?"J.C٣.|YDg P,@ q#2S`?6fT ?(b@&+]w-y2.t <7paԦ a!4%Wz>ҠA4_ĵj\dցZLLorؗ~ ` ;MCNfW1D 47@nmŪX~揲%K NUf_poA*a pxAE,G ѿkm IGU(F@" gq]u] 12 `C-^Oz  ^" gCbG 9Hyt"+q1vpwAtF (,fÝ_n++5/8]kzEc - 3KcUH6RІzuT=2g;!#6^kNOZ~8zOĩHvqDg P,@ dlX}Sm|X r{C*mᾼ"TLk.VXVT¢dS 0;z97cX?&,4eVfQfrq%:[DG^6k+OLաx"8 ;+JA4_ĵjmi"3Ţؕ[1; "ׂzӡMBҕA Upa*M)܆C^'!ZqmBܥGt s܋29Ն\t̿{~+ZӡZ#  +ocфsd_4s>G,9iWl%\O+s|5Vw4L3v+aDg (ك&9P~"ֻ+^䐡fϳ4a_?uDOI8tody_22;, p<ԣh1]Ӯ~3ȋҁRA4_ĵj QGK8b>W<6Ӗ)7Κ>&`Mq ̎L8^*Xq~#,zu{9SI7gLUM*s(܏H#yAmQ}Rd~޼y7-[/S{J,hRR "A8E,G (q6u@(~Psuwel$I)GV׎9 ay!czdon/jo%rz;K ?!^{WtF x4a--srJ1r)kMӁ% 0㕄Xަ ky 3y~񌌠6:W}?V?VD  eYDg &D RV!gP_},DL7ϴÅgq3 TL|/fň* {—}D A^4_u }WŖz~\ȼoÎVRbю_Prɖ9vU?Xɽ&zbwGl"SA:8-/}ewB ybRݵ; x0ElmD~?|6Vվfk,D/SN3L0\->Մ-y0poOA|E,G װP`*q LjiJ|X2ȷþW<~Qj+jXy-if?1mϵF&d nI UUp XeR0yRz܆[m`+Z9)[i#ހ~tF (,L@ -J[|k@ZCӷC!+d:(x x ZhhDg (i-Oxi.̶W !/hxxOĴ./Q,9@ [J>N]|H/wecA4_ĵj^APQ_a_S\4υ]#"@;!(&ϰQ10+̛&u t% Z(?͉Z&w]}+5+\Lٗ~tNV%ڨ˪!5 ]y١s k]vt^IJw :Xn׶W3m?@u`1wpOL RY92+dPy8cٓVV[6EoIa18b5#$g&.F+ӡ[&~SpTYb Ve9 >9^]ǯY'Upۇn~dӫkQ8&)0>,Z\"~u݁gG@{2g W^E{1_`sk~j 24x9a])VǣQQ {`"fIO-yH g]4P,wb0ي7d"E,&O;Z~ŰWmSvkHp41a\i k/^Fd/LXHx_0oxAmػ`'-a3Of1鵡]3Dd@}`CA5n +02}\z0Y[@FV AE,G ѿkm IGK…1`>Oa6ʨ D?juy>J3:.hQgQ-7oOw&JL[d-NCVTgd V"=/"^OU2hU_~NI߹S?+>M׭0;QMi,wXv`o)BqW \tF (,f)nŦ_M80\Όz;iWNDg P,@ҒLVD Sknˢ}{N+xSIG{H;lDYCU?i\K Q> ,9W蓶N׮! x0}Fbu7'yE|<='KX:v0oS^.i73S#=Az;^O(we̫%>*)8[_*vo\7qy>Q偻&+Xͫ,-׶ie, jvUh3׬_lsJ!p_'/88 QA(E,G [̎Ҩ5Z4KI.DSTl 7TqMNVK*2:!`sI _׫_> և!8})_WË|;ß$ J&m!&le4w4nulmdw^'&}XqFS~tq]+z/g*ho#ŕ\j+㲥 K?*ape5U-vp/FػwpP3Mv|/jVFvXP5GGtF (,L@.Og8覀j=~ic(~R`˛Ý72$S zv)IA_7.rEb!Ul ⢌< Ҝ ќV%` .rj -'mסO L$Hse݀C>y,4֘P@SbN(T6[چT e& >`IDg (ك&9P6+4v,޷۸Krvv/['g/k&Hh2f$@'K4l+u'8&PX8amJF3)%15F.MPs,7+:19tAoMg@ 9P %ȚN9,\ '=8/ŊP"l1AN4_ĵjcY1_,a<7i4(9E&6.:ù.Fk aM+[:alzqJl;`eoDT BG(HI< ];Ϻ;&F^,I 45TA-(<e,G;̶tIcWP? 5+_];ZK}㊖6 Άh[˲3ȥ,wpbMr9$Z` Xt-tLwJHO9DV]n]ƨ˰Rhuvl^=E#GE ]a~Qu`6ه nkc9͚a }Q"4KCk ?-fBCߖXܱ?]`yf6 2զSi|q.G p[H@6é+Y:AlE,G (q6u@?(qo1%]3􏻍?*Gקޭ}-V\ %Ђ@ HEsvW"/ u%5=k SzM#ox}7O->O2ck5<)4jH5'f~%fH٦W9YK(^6=q ]'=!eI0 Ne#L1 4} tF x<69dw vrwyMvGM@-;~Q&`Ik5tkRP*DRTբJRr,qe= tc  ̀&aDg &D  E#0'<pE)=Cp=q{5svɗHlFO9e2b8Y&%JO$\#CgD]sC HmpVy;KJ?9둕W (Pu^.Ǻ`Ǫ7p0ڷاN3D q15Ou6+Ӧ,.Hvp;RYy[FKEӌ[iWê)%/>bțOhM[c(<(EPY7d~<m܅#;xqmFr$=msŤH ]?V@/ϭ*T-gIF0ܩH.eգsG-?ܒ> SAE,G װPlQvcSB)ZT( \vliG~LgUQ̸oz":#naPR(Mј,m*!XwhOiFLA4_ĵjc#': a\uu$zluҫg(kぴXƂ=+83p66V~k-' |^= J&Qu/7,չ)Un{;`JuqIP͗%3sD2^^BpLT⋴IcdZ%95 =&VJW<씯l\]u]Fl)lUMO:)`(Pq͘1in>2d7pIbyŝQ?+MhAE,G B@Y\'u>7_nLТ0NFQ-k!򪡁Ƚ鯋%z nRנβkwr*xRفVmtMFK?gvtF (,2ór  fp4!c:Q}AќP(<ŘMo7wx҄#/cc ^HQDg P,@- ׫W %}="37t >!GGq K >QP-*G./A#~y50x2TcyNpVA4_ĵjd@I\쳫 rB!$PzpN529)`|\V'V[t['@׉82RфzJC`@X﬎duJ8W7P6 `*2ҁtBu2F_h91fơjQh| 0g"gUᙄ&TLN5h2jQ:~"J5C> 8@SR)PTYO& ]ko/ 'ospu&gPS^$"FLP~՗9x>F0{YDg P,@Ф$9D VfsD?*yX[l% 3v^<:Ѯjp> L=P[7.;Q(ŀ"A^4_ĵjcBxMkI =]q7vՇ%گ.%d Y9/3\@%ZGRV!ob?^d\E;i#.Bc f=KY48^l8}5iNZZcn*2Pek"t]Q|&r ]7/O6=A xX33&؟?ғ<}-:Gp ;tF (,L@ -S0^! 4<ƈDg (ك&9P5*/~G|Ҽ#Y'8.bv g-!z?qku3ʹv1wpf)CȉExBt52$zQd#T덗cf6<&!z"5kNLM^;yj]QK|&K>@$@:aGA4_ĵj+wwK*leratNH| @Q(ڿ*#K -rto2ؒ[!K i7B) ecX9 G 6'0) #E;ftQh嗏գ{~kV^bF2TŋDzљ`8Hirxp#:o^o~P?(Ih;O(2EOJOq!fJ5b'JP*31}jpQtA#%![3&a2m~•Wz.ۇIA;Φb<5sy℟YV`C|N6߱+J_F@ P @1@A/VF~}J4'({ZTS<^B2{(ԭa-r9æ_0ݐ4]yKTfyrjs(0&?w0uzAtF xZ37vLƪ 8 w0/-FvW4wNfFuu hԥ*O> @m5 ^Z,~MxCUXt>#) j_rnrp:ȑh٨ہSBd."WfJCAӫX(Hnj{*qr& Z19U6꬙]4>\Zx)GDg &D BA"WqiOvq~L(%?Q୸yaA"Z7}iZXߡ,W3Ξx"X/>\kN)ZNGs &LU9EIv^Og41ENCo㌄] Կ16s]LB$VB0g7b ĉI =HA9-<~>}EMķ,+\qq#3S'2e"hXn@\A4_u } 52Ϯz¤P,q4|Ikw7/ZpArbyiي¢\*&8E gTe^HB =^> 4"IWTa]_eU{z¾P^^d *INݴAXʬ,n~>YjUIh[ޅ SS%dZ(C 'pm 1V y`:|6rќr[B2@ԆkJ+]1, _E^eST+AJ)x 3ͤ᳋8U&ZΤ> @6kP]B'˱ ۆz{H0e\_POzw;xN&<utG݇6ROc0iAPqx}=-fm]k+=+ec@ `ԞA Aܢq?ߕᭉ 7oFL*m:?˨4SpAE,G װP2|ݚM-6/ /8-B] XrZU<\Xqb#)<e_& f@^^Za"cP=&N:uwov.o?e5@H g7'*W'1ڧYz^"G:|_ǮO3f)L&KDhwt\< YޘItLHDg (L aL@x\ONbxʔݗ)̯ ϦnHjxw925 oi_qCXj,G6jC^](J?`ՙ'P,AM4_2NI\Y18](آ؏܋K%wbf T_Nl?ilra(== sAJc ?d qtO(rE<^|dO0$N'aU׷3-|YcbԄ۽Ҕ:Ef-sep^&u [6dlc`礨l;lԼveiAr"#G-Ҋߡ,Xhx2)E+헃[8G=J_OsB+W a9cTt&_ڋdtNe ' &OYCn\0 4RGnG SDRՆL& ȟ'$ZT$ mo9!C$sӆ>OPfM㡴1KY5IOF0P39'oE~# ]e?~wH AoN մÞCAuet.Q%h(%@#kҁAɠ1>$NRukq8##!լiG.ޛ~Tf[rݴ72b.JOn4]j_>wRPE0Sz~75B8~V[%PJ-kzY>>0ey FI^ŕg  C݂\^ hEٝ9k!p'`ꭑD"FGSӀ_M>ǭ [̩]-AkE,G $ey!rf|ģ]j Q$&jSJٵibKl۲9`:㆓!jjRɏn+S1VspK&O$uPxN^qעWt- |m,dbwĆ&C&5 ڇKA,HU6A~Jrl=ZB_~QaM ocsQu:nvlG=ط|0q:q V`iQ troԫb KGcS#cF3n7)´^ f8;c9A4_ĵjȕEF^:8j.ZQ>-7 O‹P_E؍=ŷO7wꬑ8 /yн S\?D ?Jv#3hwꢮ%AHzߜ'Œݩ r6.U738J$Xӡ(1Gm$`{TFGzgmr}uz"6yDߴnR]ҡ,p!*3d%qؖe66nIV!Oqa6+;D*k_-Qq6S5lr(&vO&SdYBޝ+_F@y@-E8TzI/IrMLꚁxڠ=S$IBUt<$^O yk=h 睂|/a9F:KW~v@PL3OT0 pD_mU+QLj:-M\Z^l]04(d/Xz)[c^ci+`8 5+v= K~Ӕ]'֛mɆ[<#Cc@FƠ39F*< jJH#Y*U-xI=^_$5ݐoc4iHAJ?h*0 ݛ) GR,M5\;f^HO S'^Bږ#h YPR /V޵/:Z~-K.FI{ebErMmL J.O}!y˾*L!vNuq(<WV @;msRH2%Cv!07et>9[#< ґE@y0WDU,Lg@ ֩] ק0sUSWmO-J3Bfi0n\$s!_߳ Wr0ʞ5yt⯉No7\+E+-$ xXtF (,2órZYf2|ܺ[7iG8^Qvԛ#yDW/7QrH,j6V!r55;㛋3+w.jotc>0=§5]Ț7VAМig"lAEðb"~&/kCa#i6^|v' 5ZE!Qf/aO:)@ipJPv8[)PQND(HQ2R *"lЧfYq70;wr4y-cgŤ3$kJpvOSʵZ9Dg ("iU@&)C9eʙ+ (&'y("E3/%ћ]0?^Enpޯ A?j .?إ%ЄkF i̋Z6I".L^?dGjJ"kb1h'  tgy~/@B1ަ}#k/` l\ľ~llr2a`+/ bnl9}4"VG%-|[o*ܡخg/bigM1&. A4_ĵj cj]{".{;xOI qA5_=[ʑ:!CFa)2l4?Yrv 1CrxK:0ݽ Jd0{;#8 :H()p:BhrMh9^Av:ISs:LutE:I/ArlH"DJ &8t{D@>S[no y=_4I;qVZTE =!$;"bxȼJzK#`b?>m#hq7Rf}2pJFzpk%ld-Og~!9*L_`,/ $mwL1(^҃ dL,.Kg?-bp̮ ,AE,G (oLUC7k!{CҌ*jg}nx>#pT+SCb2tggz[No )G-IKKUޢ(J<2=T)fYxDtF xz:z ~ 0QFlj/G%@gMDg &D +Qh|5iyyw~Qkd@ݻ@6a~A4_u }Bbkh ڈiXC\jcpǟ_n 7T*^5pўF" ђJΒy2xόL p|Hp9c`+AzI٤W=R{c<7-:';t+]kTa1UtF (,2ór ~13q/Dg P,@ 6A4_ĵj:`y Y4AE,G ѿkm IG[6tF (,f#/Dg P,@ [A4_ĵjhAGF4'3ٚ-g1L꜒7=&XꚋVAR|2Pi}L 8ro!D~^|8s\ 's_iF@JYA|ibp{hC'Vb) ۯga4JA|Պz!:4å+@v31#h0z!Sʞ s@Wy24-!|{g#3Moj?aqp}ᅥ[6Q_AEw`oX do+Ê}m zdaJ%+g/dMW  8r8+\7 H?mpO #KÆ܎({<)]5%9 _!Uә2t1^Z5= o|8N~G& F3JN#d Y(WrBsqa>,\_?hd=ƙWŖzlec  JMW~8S7Ѩĩl=0eXO$9{j0Ir {77q|~߃Ѕjj}qIB7}b? CG[n:ʔ i؝j*\%WAam|@eT3u?iT_;8q> ~rU#Qĝ)Qs0EAE,G [̎Ҩ7!@;OQDۆ 6tF (,L@?Dg (ك&9P7unc{̕s>@qA 4_ĵjeHSGt5r).թՋh\o o=챈J6 hvGY.]g-vzܼ SNV|Xj!B8Sk#MѮr7PJ57s Eu"EL%%XsY3PRMMVF~)u\'N@&wA=8ok 2ʞKՎzJ%נ},Z XWBV8޳Ay: n:"$~5FM@Cd!Hha[@( ~:{}r\@nN}D|YylNioO0hk6RE93f_f`F(HU~y[߲)iM3Ay+/ Jb )4 w5Y6# m#jA=(|weTm)5Do֎Udº,w!Ц!05D!t*Y7 w׋R- [3לG?OK&;X4Etl3XJRxk[+=DwK#9uKMKW͝7(\X Oa$ O}[sVyeԠOA'7bJRvr0v:B-ݡ|E<"&Q& ڢDH}AɡԷAܚN2X M8Zrvwu)C x,bɵ4/PgӀ+-z`t):6t}fI(;Mf~ikE"t\{Y8eL;@aVѭ|g&wa;5 Ʀף714ݥq2𛉊-t{|A'E,G (q6u@.1HkJ~J cpoy[=ɟYA[e<'`2M*Mָ%(͟Xv[Ua[YMZM((#Cs#5[FtF xI伵((|ĴgL 5y3OPb(&HDg &D -9L/ ºlj 1.Վ$U[A~r *v {kiz J$CerCKla8imHYYar=Nv2w5&lFSzfhO\+,vLu' sg{^KZ3 @5ufXu΍0GO i2[qAư"1m^"0#L>3dpNYB{/.Hd ϰ_iցB4-<{;RwZ%ZZG Aq+FY.DNSk^Bvu36vK[]i)u`'+>gxߎEկH!A븫Uh8.|OW]$`7 sX !G@l %ڒחoݸҍmwÊU1gt+ o,T0o^AM4_u }Bbg M6%KU >Qs:$_jS\Le soٚδ?s"{gt'qŵyȧs܅5}ju !Su^/}?WQP~z׆%)Kk|F#d$}^,otYhɑzٔV/Lu+|ןl?hism5 y? %[P8(Ļְ*!oI8P)NpjD,/,LlЪ%ypi bmTEH1eKgQ uK5ԗ3J8{TcV-323c ,9,Nc} bwњ>(Sjwz4F{5Fn)A!*z)L63òAn(cΑdu}+8DZl Hn@YnMvXǙ'`~ VA~OXKCyUEMs&I@ jqyO֘ؐY8M%a*ȿD&PK1d{-9j̊WŐZl5:jmli臘*Zϗ?-sWۃ1rDW m~= )%_Q03uE /B+L@n6;u"6 G $ngo&D_F/{T?އ\1Wi[~T|ntj;ʽ3Y>yt %WQ@ǛEC:ɟ|[\}{8I%J{jWKL&I  PIu"'{EI>ʞۨ?{bj }m`F/,0d07Yhaa-;MtF (,L@*6Pa…"i_@sfeE=K,[0(]vV9J[sIr\M|__b;q~,mQLhm(/.*l~T?g0aSZq[fb./>㽖i_\L[L<:rghTHRbh xKU`hP W.-Wf 8a5l03e/KF!O AGu7r&ń{7^N&Ơ'}Ұ4vFV&"P?(.]]2NzF‹JԊȝ '67+І%0+@=Xʤ "7k)/ 3qZhc ua_&L"w1QFe=Qsx$=7GB?9QZ<0jt<ޙJׁU~9yRNIhe7Ugz0RF/`o?4O kh7'U T7]QLW.϶;UY<˶1{v1gN6XV6+4έ\_.('^X} |)2*X8 LVй͛Y_;~M k*S\[Vu#̹TPESmldyf-Lq0D^`s`{fzӫ!Vڔ]".9wĺ]wX%@ rV Y6Eu P O=! /A4_ĵjfIpE]Q#(O&@~h0~=SNw-lg$Mf=s!^m#+ʹgtУ- AkfqD|P3Yª}i9n%ضk$ʅ+Ǹ.RY_z6Zx.YЁ9|BZI!s d.-fI6!s:%Ipez 3!:hO}i/W{Y|HPrln&\;o~|z׷rt"~Lȇt]wab1$y J~AYBkU, 2dzjR>V'`E~Vπ^ET7h=2p _ΨңO@Er#n>̜%y\kḬvpzy5<Ë7_M^$^i Wph낔zgJ!QL 圥*^Q]8S#"2f,>hUf#Mv|]]JZr}6aOAm0h 2"da*bL5*aIԛn;X&]VJƧ<@Y[;odu.풐g(UZ%v\4Pp>lGQ"D"<٨DOajViq>;ݘNKU!lmy6ѝ )S+})w験ޗp3cOack3r]1M_]4/y o 𮆛nAIت K! gpeb}zj5f.+3a2lWxM)$rqqTIl"0Q m ^V\SBjq.c7WZvxj#b[D,E"#yk:UD0BsEʀY+aw]%*[MflDts3.)hNתk㳭ٙy Q)1ru2.aZb"$xK?RC.Rq19"JFӎCXFNtݽ+l'yh-P_թo$\ eN]=Ȣ\m$V!mhDjɋ!HM7];0 * vx!n*)NHZCiܪBlֆCE%]UX\ܣKnN'К/!=8f߱.SFEdS7r)H&ߕ>:M=G gRnOʜ <p# 4ͼjxe`2bt[oMQ-ػؐ4ld±|$_aܢWFtYdr^P9j ^Os <;7 vfП_0.Uk$xI\Gl~Ea,,h3oFhϾ sf ~Oq6ơ`Zf}z-sm\6E>r}_dhb.~(8Nφ;f&2>L6_on"B彖ˈrN2y:Ra6}cc`znÕ* 1/iUB0%[ɢ@qݠ,C$ ۱rW"355p FlXU%H$5!s i;}~Kx ^>gߝ9TT m Qz̴]\u3IZCycW} yHĤ7cQ Wg~QS.+橾JIHd-œ" YOMHlO >$/"FX45XUvf1vp=%7 ˤ i%Uީf`,P7%@eı4a#MNv2:12W^*L9iƖDBgLU1.֫BӟWDgYo,J0L2Ed dw;Uq_m2K?5G\V*=glmIO/g}pv)B/yzƈ ,`{Vέ/AZiDq?=-r cBL-\s%+3Kpj}6&TB&\WBXo[X_R_tjWkWRY'kɍ)ViN>'; 7ry>yIAwJOS*iv9|=mFQ%}/7ʃn0z9-sX<1&wJ`?XXTsD_G]'7[*ow0%H1 ŗXN F_foo=X:[m?t`4y|ЋsK/9PH*{MNآ5JL˗Ky;W7ai䐾lka9jc?<2RqzБ%#+\%xF>-^EoDB)ߦtF (,2óre4_fc~4$\c?0zr|/Oj}bS +ҖTZ 5+-y fæxRtMw*vl\=ho?poC? nȇ,x{ ђu! >VTG{RDWL,-jy_X_^qKW(bGd]LqØA⣏*?O8%]SfԨܱP m㭻, 8Q @:J2o'^Ω&˔)#dťb J'!>TQJRfTQ-;$sm5i\EAgl/%)[\5;/ãs)h]zF}"{BݷK{],wj5w2IZ`$ .U+=[  qbG:I:K5ځZq4ڈ"Ɽ* S?x.Aĩלe <|1OOATd^80yK0BZ$QᄅPvT~ zQN2J5-\9B׊i7ghB{4k^? = eQ2__~2\̌t?!v5]"w_ڋJ9LDg P,@߻8A'Z:DU8Q [3Da1N/KM#}(;9&-8S N=tUp{ſ¾I: A=?\T"`Bƫ(FXg=rBHY, YrXɱ{ >ָqrڰ{z X%C Rl]&\gP5nۿv]Q;C*3j&WP\7cMB`s?a͐u0$E"Kή_KDTWhD*i!~E7wja.u_6*Fh(?"]ش'rlr- ܙB=sHEBܟ0噰;e RιSI7H冋u#pגeAeP]ge-y'gf|L1 5\T&yۋFweXdQR.ʻ!|6jg 2D{g0R>šj1Iq@ yu(nǀ.A4_ĵje).*&a2ԹN (dY3"GDꕹyلa&#k-\&!#.Ԛ40a4 ? M,Kq Q_Lw@z:^Ƅ 7o\N(6Ugn)щmdeM]hzbv 8v[7<2ƻޕ@DZ3feHbv)7\R|2 "ߟ\_|s|,2̈РaH&Jvϔq%rr-;#1 /KE „tDY~!9Sq]J70\R6!76C)յ?4 ^mDՏ.brR3c3 3Ōv}5KL{ ! %5{UG@xRdquN?j 7kXyʌDu O{q-|͵F +l\LCbw駞Uy7z@=hZNWWB;,Mj)eTCJ'[;vd9.:=JI4t'T-D#&XKcdMv=/Zf?|K/kR.?Ō6wa߭ѐRΖCy3 -8+߃8w/f30M5uWL(= ZU"-l/Tc(n$LRed}Tkz rfGGIHM}-5tcO-ZKz ?X21m\] >YHLw S>ݱЌ%nC ;4 m9EY7y1Suuv+/ F'$^6,fx!| bfG 7b#¤f]Hԫ 4>DYNLDK:~btQ.&a8fș /B.ϼPxvf´gH ,?9*.%W=ťz/E<ӱ&ZxU8at~ (L d[\]u+{Jv5z=.\^PIo+6ۭŒzkeyúۊtP͎r׮ WefYBg6G\PЈt?8}m)1z0ܿxsVi7߹>Y㮝tf7)%i8_ُa vi+Bh謹#ANRm=0}<_8 #aoa~҄B-l{@y'O1zKBL(hoW\ܓ%#,KSE*mMkiBZCO6΄>n:NQ xAdg0t&%|QWgo#~>G80T?qS"uĽfn7)342ob_I3$p9^BDg P,@/46/A4_ĵj u|0"Yz~xc!9i2@V, 8Nt޻`2/iQϕ|WH;lcO4DV`:IRG㱚^-ͳ1813𘙱Ӻ][\= Z'r!tLge{}nEHG/^C{'^F <-xa67F'Ȁ9ዃ,&TOXUEiQJZ#^] =Gt1X4f2;hVDG=b%+oXᷖ[4T ٘eQ8Rv^q/>3t -׏7x9҈s2kxLQL%Va1Q\;*τe79 $]&(ցBmS5:5DzFQ݀aM Ӻ1Cwsgl=)(oqܐUoe<韶TZ,{9r1/DB~Oraw)@yDiF+l2'Hè9*;"h λ`9tM){wqC<&8k+u kFBzBu]: 1GaP#Ib]RsL C% D,?$qï){xߣJX6`@K3}@13h6P$*ݾpQM97Hm]9Dl Kۚ/˙H5˽0Hu{89.'{*0,5WMQr!i@q>^]:k=tWhfkwQGUDWy~zyh dhrzha,A勱fRE)oS)Lbi[gfmma\%tG1geR X^Q*H_.=Z0%ˌOnGtJQӸQv`}ZQD %_g\vW>}]fuhWlWE]T Ӯ =Z|î{?{t/S@̊ґYXp81O%dSErh˰2~ Խ A#|޴Hc *&bax}+rS#Xr:Ott{U^6=UVT8aFɪejSЃrq=P[ɷ琳(FlۧbvP ['ṔO8fBu 1PU,d&O'`({qtwR+}B@:ceLe٫$h'ýTESbm Š&\iǍ"Oj?|'U3J6 fJkAݳ]a }}ۀ60ZIW,wo4|=ZƜp=n;~j'ea[kX,e/QAO mRk݆8P7P5i5"&ҎMAZP?K!U1(ޔJoGe(:술ܔ1ߴs@ ] V-Ű)7 vJ|x h^qwO.+AY,$ APZm MOrXPy%"ŁFvbbku<<1I jiOytֲ] Z 1_v=F-S\T9$^F*$>R.e":msYa.| w2P8`3~laEx`S%sD].v7 +vJg9CFg3-ũ.hؔSj;ٿ?l_:gX b:^2& [p`OY\k#%\ \ºB∟5נ(TJ/k jA=PasFRh4,qbIkb㚨ci\Wysg)yd/Ri|=3/4x0q:oa&0 YiKx!JzdӍf[KןjpŴX]DXYvT挬8%"b1'9Q5xryă[4a*aA 6$yނ]㛊\yytŷ7c"@5~:!z H,JPʉmam cN$aO#qkW"9@xZڼN;*Ʋg\㕃 PWO>NPIyq(]v{hZB/r@otieN0@eₒ{/2Xtp:/p~'c ڑ%-:a̖X =yۨGT'JXo'[b YA3/h]S1ZS=JMCTY&Ԑ&v{?13Rҝ ++3j>ilRtyPuP ڎ:wTeċwFf t'åia6š %#hg1ŤN#0BQH 7Hbƽ'D^e<[E!YEcPw[>Ey>@1 2!24/i"?lOkCm7oJAz*b6L~\ [Y`.Yݡo@<?ړ?zlrS{|: 0+1^ bZB -Y-ypOgbgz8@9_(Ɖ,P54ZLJ'ӔNP܃oA!4rt 6$U&Z@9ٟ8F=q*VqI@ dMTӲ7憐& p@()t|u X^__lNEIspcgv/CH@!wZ&v2qIDFԤ>P8vTn׺>|QNŇ%WY\>6¥Sn QxIVIS4K@B?` k}9Z|'< pYR?P8mP2Ɛ:$6_H콙[G15\H؉A#3FL/Tse//icҁxp}EqT.d<ۚGE[Y!f&}fH¹aSZ-+CģU ∆Խ!l&K% Ĭ7&YxHQV9H (Ug% D#GH7h٢شrrr~V72z#j8YL xqSu^]HU/1\VVi' ;r :J4p0A~I'ި!v^sopa&%(w,2Vɵ4nBp#dGy:Jv魱}>ә(#8"}Cw0Z;^co ]ω9 9WקI+Iq=/BPYPjdJq 斿]J}Dx>Ev* d'~16W{Sv^?._}`@3v>tj2>b^;=15uʩ᪠gyYs'ɋ|Л,|}jV/X 7g fP 䫯xT'3 i- - rްc4QTZpR#MQ&cHT.8T5|H7^G.xYPoTa.6i|Ec}OT#2q "'>6RpKfڔm#ķ|XB/R>Y\1lIP\?bmHVf,4 \2rK_ԶBhBbT׿j$J#1own"*:j'koV o5Q xSvz3.7PN?sJ/\tsi@-3vx |(vX#!goa+<4`V|<+ֲ8޺;Hrz @yK|5}I(1Ͼa>_knl,Ҁg3QNcND|!k3{wj$µX/90elF,+瞡k{C{xeC!5&w G37Yv;^$mg5 Jw%8-ws+Nq3ǿ3euHK3VB>!b5F5r*zM3^_ kM!1}G J܌2BI_ ;}=Ԑ́B=z.+d} h|$Lh^~ʒzйa!ѼIǟkT'{)>i q|1kOQa^BѦ6|?2 7܋CGX|lrEʋPItYd=}m2{ښ9א)c&1b0iae/f0.'K z~big5$K.ЮfӤO\叀l5G-B@ +لP:igL!`UBrķ9zMkBc}6..K $s|pSʹ)x5UF z 0\7BjIޕ j,ʬlC] ׏U{Rڛt筮wh QWB,oz^Q}(GJ{#nȟD#E\5[z4=хyJipACHGriHR[{~*@pui߂ !4z*~ ߈8#CS/bFB6Ag0܊\˪WmZW(t-P-62$4 #<}虀6j1|8\(eͨgVIk`jGR v(BUSeZsx`*Y)U͡x\c6V3fQhw@i ycaRneg яrpP$8*ՙ1A(M8$>Y.ת-nWy'(] YUV>^:SIK {=SE]֞1 Afp+1`^e1B.|VB+aD:'9Gض݅jcSLjĺllـS〻x5sGӯqOD?<{+'A* Lr*4GѶ)0`3]y-\QBm՘MES|$XT^= \zk. Zű@>YMԮ} f1{M7PW g dZ],sw֮8o0jSko>pLN5&U>bӳ]rePzfbBI[ϋ&A; LEdu'prp9hP7AQJJd2{kq3Z_M (^yZ# 3o4yDžy睈Y:\҂BH(B T=oHU=Qao-?9E0StSһL~o"{G;Gfɵ,Ji R߷(D6_zV ⰵc1IzHpޫ,I1e$Pg\XD_318D~!((F%<_M#rEBӬaG%غ;Y4ZzVBk)8DlԦ aDo F+:+z:'$8,9ǁsVۣK+X}9|If᎖]rSM((¬x6Z$ B,d~` )OєM,YfwzzǶMc6rǼˊ-%1>43_{sAHK;–A,Ԏ7! :&>I!tk0k rC7isG8")ö"]:x?_|m"ρ$b`/ }8<'e|W̍jc"xS5sj(*0Bd5?hA5 $Pد=nv2!0ZxBrJ2@r{3ۏ =xߞ= g8(ܼh)WE1\ò ^>+z$ǚMFvi-n:,Z;e e#*|nI.UiIb^ %WqY'Wn {* y{++8&^#:G)ުOg{~w7WQ_LM%f{ Tw8YG@jO=vF SJ Dιb<ȵ^P%nU,Z9 xt@o )^V~9UAjmt^O?e<$@˫@<&A20VLnn ظs_[1|M׍S(~9-zW.$̗4Ȩ!3ཬf)PHG=/1fW+2նf)%bL%y|/) b~"pk&()xWϭ^w^ִv8)_Y3M bfFx3\ (j3[a==Jkn01߾/[)71oCjP:uݟҰ櫖I>Pi;6 gqPnr[t}oD,s=:s =,iꕄr}]ԭA;#;gޖ$E1{8v?e/×,>/UY{%#4*[Nu .v!hjѫ jODӆz #ݵe)1GITv@Y}LGqVPn5 j-/ˁGo3szPҿ?!'hӞgit*?Hףυ8ɏBڮ3Z?OT$,pq-2kDmΔ2K$ Lem. ܭ\Pdz9 aimj싹v˙&38NJH*(7ЇCzp]L䷼Ao;Qble>9Px0X0Cup 3kGr+>1^0]ƤIjȍ K%!.*U;/nlaB:( RObsח+~Tyc&|O[% L225~pc/zz7? G$m<c6 ԛqV%^)w ZAۅO٢4cJ%V\'C2@1 f8A?3wIbd-}飯n3|Ʊ[ezdW,L3ץ׬Du$6rj㼉BƇgG1Vy1Z69:V HMdQP'0.U5Ƶ7FW:C;ƈ k OA>sW[!~`FN"^o7^$AƟ?̨Gxd HSo!ݩT~As?Ͻ}FY5nTHwa搙F߳(s9(%k0N(tRv >bSG"u]iۜW 5/RnWrᰂwВ}Cj9 ȭŧZÅ Ie\>;;)d{ȀƂU*yaS1FhTư+ZI`y6oZl]n{Y/*Tjk÷0ue_XpOft|$`C\n}^I;d˾O2"Jo }I\) &7X ])xy8男[%w5H*hGi[5יB¡pTܳ }oV)?&8_,ڜDƶ;n̵њ %Yn6bJP0Z+K~ q zR(|DSgr0sT((]D}vifhC,omgs19%5ø4e׈|G!vg)P^w)SSO Q(jR U g-.-r`"<'\Y\ym)]MfKIOƆdSіWr4ld9UF^ MW>!UH{|$nt^|-(M!FD-'5t9qؕ}AZ=ks{bAjn)3( yB)n~lx2Y|4ㆌ%ZLtY`M"[7$݁ MM?h̺-+%,W[g vHW_7֮"k/FlRQr`P*uWùEQUƔeB xrqzAeQ`/C{T(B<ѲrȞN"8HNd;:U $b8#sBϔOgU&Y|p._}:=1Fǥ m51IVɄ|7ä瓍3Ek?bV-]F.n s~߀`>g:^=9QM֮FITϑ+lWP̓B7i6m+h@ *}v +bYre:DQ"iu٠)E4ynUkhL S p0ra˸LWZ`H5K^F ('@bw~>8@+$/~V1OE1V!k/[vIEDxuTEzo^8gfo"ǿ{}ߨ[kO$ca QHMۋWM^V#'K234Y> w ߅>|.o 4(lI?XQ-=We{~"IPw2vi߄kZk|Do"r {d HVl tcdW!uI(gY諸C#+wʹڙ}NazQ8 bl9Q>0!sP [䞛c\g)n ΰ2lZ.p/+f0gL`ˉ7/2}T/E:ue|1fQIoĢLf>4TŮȫY7WCQ? Dr1#DU9{G+^''W,PٺQ0;kʔP B>Pm(mI`Gs0}ǰM:KLbI/A`;P{_ԭOgx*Rb\S'lv<)| @k)5"DzY)=/e'$@I*`1]|[Ld@'WR0,4PU}Ͻ5?>;KuRY>gf c)_m?w-oHЎjm4H3fnǧYfc2Iq1jTMCۂ F:k=Y#?|ƻ¨Dkb,e%b`?tp!{Cps_dԶS9:jb{>G@}6Lx @]z2F!j⫣1HB‘C|s`]4{׋mE\Sa7S$J 1ǔ-{QJ0)y!vۤ[țmQmw8E(^2IOrE9,,::+8"-gMWFhr =x}Y˞(:Uƴ@M-J ܃8e@>U[VUiܸU rF`:pM^bC $BbELz@H=5wI+7XOÉDrD6=`h>/'oGoA0ы}L4asƮGki^ZT1^Զb4qho@d?Y_B=vޕBJgQP)ñ<|p(گzM%֯ -2aWǩ Ijd^fIM˻&~qEwK -{D8x6;=QǍLJōی7܂$2OF9sjZ($8O"hVS5eԩ.6>PX?0 HhV̫g CƥG&gsV/KqW.{Xc~KI{e*hE8|dtȜ_gYvxaO2BSM D)Cv2`̣f<D:d,{+.&SO2$/Uy-Ӳ[]Tz]R~IO|9}L~53\k2+%ju8bޔW"-6ʸcǫZOui<qq+D[rp fVO(h\t[~-4! !YF/ˠK U'mF4rs(R(J$j.CaOCjB͠JJJy.R]Cŵ⎢azwDO:?IJo /uЙ_䅣v,/ bfbQև]غ4T̄jj|WN}¿*OQLU~,Eb9`.axu?Ws{o.*6la"m3.x2@bBi'ږ#>p'cPo]L䯘zI^$ A18OBo uJn3z +sZI~RT@c `m)+.dP~B|% !Vm" X:fh%cG!ѣtl L1٠aA֪y)LrZ2)#s8ڄdT}0y9~䶁?+oST^.+eˉt0j]Y:A('؆gv"e$9@ĵ{urߌ? {]kJf}E< .6B@\nFF% aĸja}^D]1i)G*ip2ckP]]T!,yn;,>OPgTKjbj[7u" ϐ&e`G8oTea-s8|qH^"b,*I"<=EQ:Zk{R%:q&p'_2O豝M}+$>8K B]v .@4U\0{e HO$f窯8̉'[ců3NB^<͈-s7Cnq`CYY-bEG6о*cs0luY"O#>,kR1>Pgmonqte&p甫pY쯊D*̬,0M?x^:U!`i ~닆ƪ.X,{µ 4a0$=λи?IFR:'nQ$o٨2}(F3qd~~&^ycr w@na8W!=^I.J]:I1|<l‰`kKW%a˓Pf(z7V呾\z\Dt'+>4M$ڃSD E4U_^zH(Uw^Rn;- CTmq*lwKUXUκ3[ty?zS`PhRi##nCS8m`9zVc<䘟2_TFm0Y#­Q]iB٭ͤ9SSO PbK=hUwt\QRN+木MwtwiMP/F)>U^ڋlru·#DS-c8&  & mFbU (!j'q.$2戒!MH7.~l< /gߑO$2ufL߯;X߃EP^ P՜f) T╄21Wz2G!ӻ HA}˓M DDo8K/I>8k.ܾIj[Vx:n>fEW`;i$>F[vW@=c{l =_||y8~C(%&jz+f.# jmn QT(>/l)݆g؟}B'|f,"P'8G:t:}g9Lsk[D0ʼWTPoV\ |l u_S} -X)F*.# +F }ǁe,K`mRϻJ՝V/Ϛ}H~+f Hnt(BZ0Qe<ַzb%L<ōM\wrwj&.J"P6m_;ڇƘn\Ed@=ȁ6ⷈgr*P?KE- < TPl`5h +H}e R͋f$` (T|bwM|܍ChY׭z? i/ޭ@8ǟ+iQg'JfԨ 2TvJ$}ըZDaWC+C XV|2 оtkd}wXH擢gvsP`#&3NAnlk2{K~'4_vڥǀk^|l?qAí C\*ޤd H6 Aq=8ԍe,`>(76hea`:}ƎǾ@l\P5G0Qt;9wGW䥓7}Xg5WgF`Uy%aKОX}&Un.ay=pS{gK7½RuNJg)k VᰭdzYftkiٛְVZ6$H3axЁsWe#9M>‹."`v Pk<.`<\kY'ֹ͍ɢFRBWKqDN6{2KSN$4w̭Ƴv;^dInú_mbR- 5d,WR;=vvf 񙝤Bܭ۵ ҕڷ@( oj`|^̩ jSxd|Ox鬋 X*?O9LUdx6NS>loY %zsw `MDiY*=[( *#_!U r.e)ʪёh^\& K߃|@2@,`/`n79Nlk+Wғ(PZ-X7?N_5@U{rwK}ofkצ:uzXKe)Ż̩>x8NM;8ҳ{yg"Ѹ i}hH?V?"s҇Nӌf+f3O螖:!A?ñP^Gkn藐CeW%Nt˳beҐQ9;aÌL69F#f+zvϋťX(0,Oձe1".ِ,(֙H"p˄ lRm|$td4ǪI: wm43Zo)`yFxFI^V0w `Q?3nN|F15æx;*nƄXx$s[+t1E-h-V WZ@VVaUZqG&4{[gQiWc&E{m(Os] K[O0Ύ0][㶞"97MK8x;)/hz7'+wٓxXQ_oX-kZ8U s^I`M%.{Cŝ<\Xxjapڿq:-@eF<{]QjPm.sTR8&U$S0G܀02乒ˉftDzK4 S6ZZ8*nͯOTɌy2%$G9$&/|0⏵]JC2:Vv}[<ΒXc`B\KL580;˦ {.\ Ov4fi,;jmklnvS}.hg0l8011ٖj{E0CdKDЋ1^#Y1j;*CiU16vO./CKmMj '%;'# N4'oЍ$=*jvPt+x#uXi%,XYxu2B&ɢ-$ȍp{3(k_OX˭=hj:\jO4`#?pq$_k`ctscc❦n*4F\4\^,D1L&vKloQsMϚVIs^)s pm %RE$nXpşGM wwHolNBBe'?/q)l+hPԕTZ?@ 8~ELcAMw}߄dʃ:/r7о74U# BW#W:ڳ/&V cEq 1U*_x/NS<_9,^G_Z|j:S&’%ssoEjnB.RQ-O[4x;䝒(dN!yjrJ4E&Y !j@tY NRr $egx +/Ȩ" X56II#/MsJ-'FD N)+RAXQɛ:Nd{3hsdn& O|>.`xM˽$CXE/M*1w3F7#-od)'uesd< ]ft3 t̓ѝU#e<@y* pxg({3*RJv#ع?wi{6SM {r8іp eDBW`ΌR8(ds<#z׹\&K3dv1⓹>KWyTR}Š?FZ.YG\lP-*)H^5BI;A_(fa';Kdl\֤~u{#}raCLτʋ!?0F2=f8M祦UW :xJ=tDo, gdSKq_(M6g>UF2tio6]G-LD# ܖ c]lzmdoYEW{Z]VzOR;΋1O `a(Kd!j|K@%+!5'rxX.3/2Z.V7弳.%{06kVGM%߅qFxT]dCngl 4k߅//xdXeH!Ǘ &wZo3*{T*%?3+/ JV9 ׃KUHo|cTqļ7?RFSotJ0(z+*3cdXif1h dso f0U6Gc9H pO ob2c>ys$`PHMǴaP 5I(*ՖsSn6wdKo n_|3o+G4c]`\2ǡA f8C^dPQ8)]"62zw)f\j + ʲӜpHoKCUw넭2IU+XIa1M^(zy8<2VJٟSFOebf,j?4K%~Ȥ gFI/XJ-RbBz3Ȯy :@}ȻNQ G={O0eХlzWn'oS V™pz׺P?#_tx=~hwvEl[76KqJH'iZmhӿAoQV%{2aO}`Ne v-dUa@]zq^s|цSP Uo:N3B`齉OXAh-; A+白\ЛJJMGIYBjp)z&ڶWE)f*bXuj&^t !om„0IK`w-;KFJ ;I$u¾z{Է?|L6t!gk8b^݁BhTsh9{uDds8h,z9FF8ELkKGՎlvZ7: +fF&䑉Wg% TXB3|]$_ BaVg{«";":"r9?OZo;m8}[aXXc~XZDfcɵmª̘o5LΑ¾ɦqK&̲G 2c5mvnOY7+>ovfVs2|wE P9?yNy/g~k!hS1%ԑkrkhlDQG4KoW1З-tR>3nFtBV7S&e)8vm"Da~pzB"mO^-y4TBU+l/0e@02Ge@져KaSi3 YUhk[6ڑ$TUlu,2}mh7vvo<稄kUF(K?3E{ $+NW)d[k`=UQ6!QjBݔo*zyqpx@F=R>y{%^߁dp;gH̒֞G.Q?Tt=;Yn# -[[g.+./mIiL]Ύdq$C 1PFұ@EO|πx. S #{xafUnKf)Kѕ4?i+Bdfc)UESWFLћ +хoI? ҪIlёx7!Iff6 oL"G\KIWp^贯7HM!yWd,o>kÜiXI@&N j(ʼj𱅰']oQV0A1'o.Ύ`m-5N?$;)5$}笤O40[*<[+ڽ@+* /ۋOdkZ5u[f9 Ym\1dWf ~:"3_C9q[!yۢpMλYpAۍċMB,fdװ,TqC|ҵٱ]Dh@;  ƌ #l+l7/I9yUO/w8#ÍɤDm~ ku޵BX$(zWyGA֋7*"rjxc6M (;pOA.`$ ni>&

t@nBX2:Z|쀃~.;;^X +ǃ-ú;)H(.X +>@V񬉈\zv/ZfFTgkXKNb \ T-2,X CBjSq[ER/$SAzF@ms%eջX5p@OqO%KʒxN NΨe1[?'ݫBD X{>1RvEuyH ϩf,ѯc{}U%CO=ƑN Jʚ.ūt .CoGwu m-h]sߍ'4AJc6Pl\b/<7>ʕ.}>; -YIJ~ ( 0oA/]UilS!?ݰIL}Hqlv잊@/RayG+@˱$rPcp+9ʎOVCy9+C>%0@prl\Dn.|txq_% G > |PYtX_?P[f0kV 4 Ap *lQ@8&=D.AyK*]Lw??\y(iَʀ`D[uy6+&#r\ }Ձp9iƂN!"!m'fn0o+cTp^(s)kSM *f|3%|;# ; J3aha6u}K 1Z49la9qj8ܵ2p{ t]f 1I >O %iTષPǍvCgsD[OLi pQz'xGx TAdnlH#'ö$5Q 'ND`i ֹPg~ 0 oC cƈOJ}7`Vﭩ=&.Ԫ*〼0 ?GV)YTQ,^; ({k#Rsg^\BpgaJ |KΎ&dr@p*?>2߽Px* ,q#XO d(0(䱂aVP_|XӃaQFf xQjAn:  z =jfgR$2]9 -Ӻ.#X{!qbQp6 י|_%(ÖfR5,3sd+4ԑR&ګf6B͢XD4iGWXwO*_Sgﯳ ޿Ecq.ìO}dش{?v0.wK O5(fN|Q@g7! @ϻݸꐴد -o])`٧X5.]KeiVTΕc/.F^1# Tw)b]~ڸon= Ll_|߾gtKwuQ }4)QB;hgߣ/ q  ~a-lHsw3>LU,Ќ=(f"sfk^Pv wM|~# Mz݈Ĥ@f7p}$Ί(]`% ުUIi0A]Dw=-Lz{9!V}yY_x+r]PѨx=FǸW 4q@|DG+sT*fWTB dԛL*c~ ZobXG ]*sJ: v֟jο6?,K+EtjbM69 9G  -)9đ۝ L "{bots1ZjO&[ PUѰx',M|sW 1\T&0ಷaqo_)fPj3kc;yQEdq8޶Kfz9ǤܓG؆=u]/uvT+^XP8=@zN1r7cIOϨ&Bl9T`D9?HBcDFccD"u6&+Sr#}t)p;D.q\ ߎ8DAܽ,_h*}Jk EMG2xب(_OV0k<.b`?z$;Ckڰڴٻ"'ĶԼs~p]+ {2 *5jAYq2'+w_}V[ywhVL_[a?$[^E'lGz繘cΟQuZا=a\PW <`:>C*ZG4Z6+'$A=yv( ,YZV Ճ@' 34 ~_;}BX6|ܶ@Tϵ:+e}2EA2 nAQu 8|3]Ѹ qz&_c>;aXs6jEj0zӗU+{mZ5Ltɧ_t~\D_o76 Gi0XP![r+'68o< m̌M:u֑xY~UxAk'Yf-{.?S7 ; o(&f\XPߊiOif^ @HEw1"vS)V"LU'3t7l?2#d2ۅL;1Uy[rs1xV;rS5^ m͋?J:vͶt啟u̸׼m\2͗q(b>LW(܃*̈́h""(HF8擰fza/0YQc2͡G V {}5.(zg1> ,7r-ۼQkNth9 js2}tF+2S\յ"=OBᜉДrIdydp5LOz)JʎkMk./IEԴ`tU׷AF2oǥe5+`A4۠dt  SgcyTGp^I]l=x T\ø;z8&[tRNv|[ oGpbzvҶJ;@? P{y&pCa߶*D Q6ݱc8[zE0zl TxHHu'-^m#:[F˽bCz.En{,oGgNh36F|ICd#jVP6kp5_մϛ(3q[dvYI> k@|lmi9HYCjw Lx Os/n,bH{?D#OlaZݤhN禖Hc]%n!I: Vːa:kcu53׌-z2~K|*,;^b _ӄ^$bpW.΅qD׼Cxi9Dzգ^U^yGf,o/1Mt; BINN8筺?xq`Wc=(Rs&pV9jD55]yh͸j\ e_߫m۝bfls^)&O$;ǀ`O U9ڑJ;b#)}-ێN{?ld0{ &%@X+ۇ`,d|zot&-.J]3xwCK N"N/*MSMݝ ܃AD_ [6F.Eq9gDu3r <դm IaAw&];(6Sbp @VЋ88a;<+'ri194a[, mV/]@-o=BsX]FI?Od桹 -ٳz"0-CQځW/?Dfı. !dP'`@z!JȵBn L6?T0"U^|Da(d0! Q%MsLkt$T1(O}9CcEhWF\79X*S!6Ic3Hv&dV .~5}V+2xp'= 0;qlO1KY(^\/ҿT[[롋w{'.\XVCKnGb FӚ9ݸAjƿ9ѳ姨#쒮eGp,"\&?v2{ڎT4y״; BٛƉ~&klqskѹ<:v G2 7[2>8iCY} ,^`za#iV#=EL~gSSD8*QupU0t;| $${]:{Is6hj$IQXp}]=Ǭ| "񕟵0 e]?ͤg6ڟ?9%;"(BXzRX@%I5q(Xu=a)?@/,L/B`Wkd0bgݚO)2CRB2bZ>O3jB T8ȵj[ܧV*':ѕd"aSߥ'v|9S? @l10'R6rÎ$[$gJ"[F: o{Q4BkuTWXu6SBk G,,Y}aD)ϞV]Bf߼ e\(Jҩң?=Pv tlK1~yCl_[ Gwlg}孆$/zZ!ޑ!pVf"&I;`l|&ynIG!"`3rf^(; U~#Q+5^`[IS8]@x`1U8K"ZyzW{]}|-NPsm?fGd0SKSʏfdFR`۞^R =!8V -9ޗZ t}2+K+#ߩ213('% 4E^@bH@:\qפ,v,6ӛɔS,|,@w($ۻۅۺkڣ *$?]IJ -bxګ%LDz]}Ci l[Hˡ[ݼqfgrfثJ[ć #I, *˪Cl~tلBd#j/(^VQ6>6H^O ]PJ1D`+t g:WO ]}{l 6Pp[gq*  =*I 8ڇظXn=٪oQ QSë.t>5C@!@6gՈk=IN@?*%+kB#xbEzgæE7 C?B~_̠gh1J8AWH:0;~m+&r+8z ƺAg$甗elupb`G+k.x*ُ>^Čve"2Ů eFko[Lсo})^_{/)tZ8=<ڊy$2,,$KmA2>$BL OCE *UKHw>y"Aij*,v7gEJE,rx/q0aC`AE;FSv: $eeA \sy+pdQ ,8 Zp]< rЗں Fƺ;ԅJ WC% !1!9rwyt88r076]*Ăޜ

NE \f0cr9BNUdҴNh,ڢ,x)l*J9UCvY>Yr%5dW"fS+gxA]ږݚ'&ʲ FErON9RNԗs?}m}ՋC X\L\v(,Ѯ6 gyq=^k0ثvˌ2({.h >?NX`l\' PA?8jwo&uر&-wCPO ~ZDM8/R*8Ø]c ޷6X_Xx ,CMoI}d pN;i[UPJS:J6}t尻/ djKҜ%p@6cfC_"pnUv(S{0SnqF+^\< |$؎4g'ZH w%b*h!#g&?H@ӢNY²a3:&qy@F2םj8'l\qwǭ{Ìz9p\Ǭ׃ꮊ,i9*}:[5MIeRhټtxaSc]bgBb^>SOXQceXGEQ~^:wY*R}>W\Y}`.D4UMW&HȘKzS[CUqm?.!f9&d u@yx3+s Kȱ+uHk$}@C*iGkMwgZԠ~*2h-rvq31&3z 4jȏ@`D"iY$(3҇I\u\TWz\.q:or54bKAA5up, R倝'~O<Yב ~֦ɖâ:l]"#D))XC7~QJ}wXߢqw0 R'U/mZWJu⩄; GY4; fY +*qZAsw0ؠz7h[h :R"xY3&MW]<'m+=wiUf1"`eM,áG:[o|֬5}M2_Eŭ8̗)W씩)QA3I0LLf7Qc98RVh dq-a[e r:Gm}hcV`[~yexKZ@LMQ(KV98f\@\y0 x/q>_GQqKs #O*doIm6:Z1- xUW27{/7hs+fgKT¶AXw-rs.w$>XO5U6t矄.\&I8헓4) 5mj; y$z2v}5X7ЧV os%݈+adR. da(sA4 eƍz!(v0HS3ypp\d!}= ];׉]tt#6żjh;6!?A僘̳eE5sE(pޯ<?JGvps,yiP\,)2 eko[g7SeRˈ6!,9O_fD H7KOxGђH(򳀺y*HSSm4#l~Y<G? B0)6ÓTWGu;'5&' IwGx\YK Ç7 R3cu4=AGv*/إ4\dh%>r CQ'uAg|h6G^ˊI(C>ƹn Mv?Y3)">Y*i!dt1nxנ)VY_/f1F]]' 3T y5+@T'zAp P[9nJ{LNk#XKyIE|i!):" rwBY7 =공IS }?h؃7W(DW̟O \P jSab]\l+qlJ "H!.Aq.@}@tKUy&2\?!(ƪܮ_Q|%QзLtӺ{ Z2_ƕgg2]OU)Fm/9V==%Ӂ ?&ZJ:NͪC^(#‡]DUK:_OL/>1GU„}6MB(b&f攏^ho[-lєЁÈ0ʅwrmg.cU5-D#x/3}"ګ僒wcs+ItE4K3V["E G4_!ka $t /xH hezt٢& \OF{"2\\kl-e6w*܇a{!樟 F]J덊IV!0j!+'=gS$0':NU>@#/N kt%k$&ꢅAPVnQIj?:^_ D"lB0'zKaxᖼq,c"ɨ[<5Zz"kQyET KcWLz{7|U/h(lɦRߧ0VJE ]ξFLkE[٨~*z>VK"₫'/x7QQ V7im]L~=A w7di%^ $r9{Ƣ:@ƘTYzgRre-m;DJBՐlE ra؅.} Aެt%dEXnsϹ?Ų%6}oQ(FnY)l\<`jxu{qs'㻟^A|⤽3G pRbtMˍoژ+;W'z. Z?47۩j#h N1'pSkC°%UTөg^xŬ X, =BŠ7F$| ;.Зc tX]lOGnd8A5^"beEƚww,aY]j%I[L}-ͤ$=]j\hrGrz.`%wŪ$9yV,Ax i4)XIs |apѐmmD vhBuS>g_h4;ʲc'7z %cyN[LLgڐT}Ǿd7NՑ˰4 >𕱑HNN'_M}`|ipe!Ʒ֟it-ڱ >X.`IZEw$5uD{X+<ݹlU3 ,r&ggT w &zG@@> nvтZ*ԎC>(~Q",, *tCJG{m|ohP"Gh <^'tP{}^<7Zmh ߙ 7v3pyŪ/ԺӸ(YZ|S OS rN@#mYaRBM>-NqVcc؂3~VkmDmʒE{K:D`@( ёĚ޺|ά]1Z /dKg7d5O~g]g&J͹ ^,Ujc zҟæ3hm5?wn/QP0WaǢOOXuHki$oFZ},1=F)HkM3NԬØ[)2*Y7|߃n+=#+fK`{uYӐ}G +ub{6GzX ]QLc55?Dd̞ -PU9O]ShU:Dɺ%3¼|p\7ñ߁iBΛG.2~2|9&NòYN+M-C؃XU9@Տ.HSYt_}н>_U)-TBcd66F#H* >!C?еCPыٷ?gY\z=~,i>$u ?MO7/,=VoI=fmZ wUqU5Ng˅G3M3bZWK/a4GC0`PiEn=KGzlx@ ct~4?!EVfTאҁH @m-lI 7nvd]*I!:$67jvĠ}Aۯێ7F^;@]?U5y`%s?ZBeb̠U+ c߳צbet7|e^fIHS,\ÉH8 +:r^STjLcϹ'1;qn$鼟!+T+Eֿ[#0Wbz/$7zVOmA%:VhgǑȞȡ-H:'G_N<8B]q؆r İ>x* WEjZ"t{OHDy[+mXْ[62Y`Apshճ;L@ M1Ls0$2' R=I`e.3{RPbJ`Wip%-;CJe=E )TuaNqEKB B M+|׽LQi1x8iQ؇[VPrcgBs9;xww3i2"a@8.8{ҥH)k) M5_Ԡ@YĤ(Vl;ʊ5?Ce+[ZZ<:il3M{AK&i80N7r-9cŖʗ㜪2o /BK%y`Ow vQ V<8C쒹;:v<Њ5q CgxQt?xZN+)gv_"4e+^D➱sdBZ( 9 ~Ū Q*Д4)E6KUbeTLf$di O z`a JFX[BU˟=ћuYOk2䃐̝j9m&4}>}uBVug #z jYP/tQS^*M79ʯ,-W%RZ)YƵ*'˴X>hPPK80Lc~;*8 gb}S]Aw3kc(\ w? 93#dwj?-y)EK'58iװMf< FcaA; |`+:B0dnR*z*4lNM\Xd(feUtddcVWT0Q?,#lhBI xʄ|fTt侳$SLG<S bi Vˋ,\ni3(r>,(h<[P1TЙ3H5hO!>y>M !=?_~slh,BݩeAߛT2.ύA{`i2Q5,Ήr2z51ON%ax \nǴWpDB_:2'Vz|ք!x(lj2GtIMP@ؔ4_Ag~ 2c7ΔT|x[a lύ-fp]E/ߋ $vۑn3ʞ!~A\o /SQC[#%k7cna%7]uQkhavy‚+:h2@Wˆ$4DvW#5aZ-{H+HKx^|Al-}u -|nh! DƥD>4HXq7C}NSiUF-$iv Q 4OQRzJQr&ye%΋Œ;Ƀ"I& x`Rd&Ü$DxH"e%Q]R{v9xdуq=QF ~bKqβkuij!ѦZ4e6@(wb^ʣa䴁8;#Ap_ּ^tAU͐=$iM&{MCaLba w3ˍuS{Yޒl!$|y93>%F)̑נM"4myʖvY'`t8F즷Dz8} "qbw6<$zcA` 8%ːss`w. s %tanB ' dL{١֒Ak,-Ssu(5n1@ ǀYݭkڳv$ u2"'$R~=  ;R2*M4o,O"W#OU}fɺ :y17ej;m|@ ;JiHXzX3o| dAG016,˥ # ё 6+Bg)PBN/g*JB>, 86MR!ػ "4&I "PH^s1+Z^s %t^L+BDF቏ A#o?צz^񉰳4TrlM39G>;ĈU^> FE?F.Vô6 VMYL ^ьפ=N.@ לZ3R¡ pKI7} }7sR 9wʳ~5oA2蹽5$AzyOXgrė0jPOьɁ#>'b.Ot[ՑۧuVB {yc  !jYB:*cR]zKA/ڜ;6"q_#,0u0V$>kQY #%{i:#?NZzE4mr[q+Pr4?;R3f!TLG;mwqIIn"+FKJ3AC2ΎPH >4TbH`4Ȉ;͞dFN)W uCߥ]Ə˭l6/Es("&ë3]/V7b QkMwUq2Y ;"E+"z2o (F.&u|/qp)~ PUa~v64uI!8uBK8U79r=u!jPV`΂eccmzn=A3}+5CۣA!},\ Vk8Th@G=Giеo,rRKҏ(Ϛ=I!mfco܄QKяo'Ė͙2ぃ!WzB.!֥[>¤( z{ʐҋH-v\7}+J~N RF-rK io=V)s9, tFsѬ=_>u(m^԰ "|S Γ(Ŷup#3ƍa%}üBd7ٷ5Rl5/b۲T;D:|7[n Pv$g&hEx4I /=cUptȮRZ\4 T#8vB%Wh_Gb(p>]|~^YYPr!/ E5*ȦFFgͺ3_4i}:gC462a1Ǐ% 'T|li =kr9\ {{z\yxSCȡKޝ)ʅ4E3(ybt> o5i۝D迃D'\ ¬Uy }Lʷ)EhC} n-n %q$p=r/R#<@7{U74/)WR2{ j dž {.Ba ]ahOY?*XU_0&dѽcb/ j Iqg9>3w=ʨ|ݦ8*v@*yn;,v'P:HC$;1 wB>t@ub=:Q89TTe'|AInljmh爗t'խ(t0IyK|eQmF.BÁxԠ} uaZ}iʖB^86-EBZohgpoa/U. pzソm'>P06]ͺWd.`ks8~!j"d:,$8 >ِoGH70RNO_{ 2ℑݳU7GY;jq}'l*c1L~2}HT1Y'L-ۦ3#E̡( /^mz?8XL*DnO"~[W_=} 4Q҂;ea| =9g\ApPL|D7ŻOرudy\ܸ{~6Dc7qlC;$4vgCÈ.$sTN}rsPE67C~z'_D?BfmxPنOO@~3`1U74֭ 5phqFhL}ѷW3LAcXP&o/^i$Qt NUH5ABbrd/,ߴ#+V6^BHخ,t/H q%}63ь˅=$.}VLl`&ikVy@-FyA# |&E<G݂`| >7b ..Sh$n:\!Wҭ+fR Tj$k&߶' @fŹ8:VW7C^s"+1䟵Jq,\˿hC Ū5Ds<B.<ϕlG(=h`K?!w]|i}C3znCuE o %Zb:rkUbWݮ0bw44UwDZqs}{"N.6C%yJsDe`ѶfW$]d}6X|/ E@d_M(p}"ae"4[GEH}_#v -G<6&=YIՏ-xB[KmgѼf]GzM}vA8vrϠj (^`3W8/ SJjh|~ѓy͢CD0KTB-IoX#Xo2>y#r߿wHz'?)I3\}mDsLzРRs%ҍ3rh[ `xTŤ[,]Y/A/q|{z9PE>[(X; 50IgsRߖDaĮb8.|{4t+^Vg :"'|no:]\b'`26_E mO=j.b@jN6 9P`>#;Ua%]b2F+ ">.L( 2< P W۝P&vS[&̶1'R^۰ #8u`5?\=Gca ;zpf&:NRp0%bXEV(oE@ Sh`Ԙͱa uTO҄c!PSM y)ߑw53r?=[67K[pO7I0rF$F뚤2_c?3́]]r#z4,!D'zG7 *+ao K Jj9hi?gŀ  p$f+r_エ~Fuor;W*H(UX˴'"hT.P:Qej&p"yIuC1Lif9 J]-9ޘ)&E#p3+xEJ"p$ -_O@s+c>i* :_L&TX0;'qK>NqN&]в/)kfW& S,j],(286o$gW-s ;JopVso Gx azM?ľto592QkQg wh.K>)^1-oL2dyZLiی V`)]f3Uήkن?tI>t+_IF\ )U()ƌۮx=1{/O%m|&lJ@Ͼ^^ 1wm~X]ZaX ejQU!`P T[tI%%!l8ӺuU싶8n^s6se@.̆ c_g?+7κ-}'r81{ /1qn6VTeT7|@q̃w75̢% v!Sp?X$xˉp^]\{qlFm!4-{O]UC[R-6?ZۯqRs®;'}:LKΕ$؋x<25wSE.7-m?÷ђ(bz.mm.= Zq @}n Y0Wxqhʼnڕ CAcNduI!#\c2S ,/Yk`()M\XC9D' )jg4Q/v(ORÃ~XCTbXWԫ0ٛ>JjXs;uQ/3ظd µɕˏߖ(JT<%6)wɘ$(j3~8M`L$-R;lQs< &F)'J$FS?`41fb T\:/QUb}jyXZrd$2$pKo\4Xz:6,)El]QJmD3trpkDجFiWU[ ԛr5L}[cA` (=[&9C{ACS<>baPrC}| e@WI(ޒ 2R`yH \2"n+܉!MWR0g`lqp0^]%a|⿽k/mzDP̛l6 9J=&#of D\w _HI~_ #LX8xd7SqaY8eHkT/|i {6˜fp {)IGX{m4n5\{_;vQj# Н @i &xN' XA$lWĵjDZD&5gbcMM jͨjz (#K )@D5si$)(a &[2 x&WEl hM!]f}~J/'ﮱ .8#GfW|ad3{32$7\yyzjOT:g{ Lȭ\&=6:G F'=#8a_ <67S:$ (Xx7ǂAI`?/x<+kcIABW2U`*һH^k>DS= !SuM7@z\#rZM="pzOpe6/)=dt`D44M(y<#ECGh#Q9ABx (,zCnw'r@V tԀ5atF xd=ӊ,_-cDg &D lAh4_u }ĭ lAJI1, !9C>m5$iKBF./15e 6I)"EH!-w s@=AE,G װP"|,Tƀk_=d6tF (,L@3Dg (i-Ox7iρUA4_ĵj~hbr|I#݅ˢb45\ T]4\L~7?AE,G B@Y ߜHAпibo@6tF (,2órT/Dg P,@ mA4_ĵj~h`rVqY-t*BV;p'(m /,_з*?AE,G ѿkm IG0x1Lq6-tF (,f#//Dg P,@ A44_ĵj~hbdY|3)Y wEl~j:d>ѠT4^ψ v~Dz&hϫ3U/@>y[OD5GJrA+h|RLy%$T(dzbr4d)jjSB(CM/~W7}1E]v K&t Y)}R K!i)N##o(2QKdAt;"hZ%ĚwUx?ܧ9:EާԝsOD e"MSvQ)0 ,Ak*nWbd#Jt^ci2Rѽ0C^KN^l;'RkOm ~)!ZinǴ-g.MoqItkLUE;;1(6CD"Rշ~1y7$vsF֛rW~Q s:ϙ|ڍg]Wv1Cd7\N# h#_ HUfsu3Zl:V&Ը%5JX jmO)VPq]Tb frVfN& o%ǣxBLV|@IGdaz.00E}KtoX{Ѣip0qH|y0Z"LJ@n^?w#$X&10R&Cxoﯗvd3j¥5}&W۠~v? фevWӀ/όv*4Q)2#z]Vs7N-V9lrl%Ϡ:?j> W?a\i ò>@O:b v1vV#kavHxCFiN4OAg$}"4PrSC^*AӔ!yAr츗|\Ν݁!.QX\O_jyϬK-@V9@-=.a(#5w3\[̻zKF-Ӳ&͕zJ@vXx'nmDdS: a/w<#8eyR26!v/IvѨI PҶig]J9"K#s6bO;\/䐊GFE6 .H$d(YZ$1m4T8#%aM _BsAr?&K->FBT݉#c쥙v:NsVIX\8lIض6bckEOn!["u0+S=<8V>/(bg T]molPȜa WQZ.0ew,i{[3+ؓ\*k։NnU&E,C{hb^ Q)jNNGݶDN]Ft*FiHf<@-d-2I mVSp84xbo@UyARE,G [̎Ҩ5vLD=a1Fe$?IPK]{)qm|yJrSY;H?SPX/SX9if͗`P?D?B>nCF[H@%>ތۗz.+(F?x>@igcǍӄs;b*ﰒJS ͢5 =Pp}k|nenYAqtF (,L@3yY90H?LTORb?c<` +i\Xrpb{؏HEdS&D4+m)%_Di;QL>l`T?CT>0Ҭgr}S hگ[ :u6_ʎYNmMiZ*~Uu$2sDg (ك&9P$xn(0Z\ǓE5֠=!o 8`=>١ұI2WaXmA)ކl;PXn8-_{ TFe&$q&d6-Yp~] zjAx4_ĵj~h`F'@MFZ߅}l W.C?z1"F{JZn6Xt ٸ~f^MQk2ڮ$fb]4܍Cf~P5OupfH뼿._nݤÍ g[=@%G"҈\rY<{(`Ne{tq]3-B\P#bgMp!kj@8OHAaPpG8rQHi*5gA;AE,G (q6u@$=rK\jQXo'-EyŷQ^ - ( ?dTJ mbC[ipS677P +Nnd ƕaPṊG<(Ri:lgmwv.j$$,uISﵓDY= >D1 p6]sgWZ1P(t: =`wB?aR|5\}H >٠ÒI|؏-mF|Z#sīSciANUm.#qG]X)l@s)֍7-ά9p[qU Yh?4GZ픴Gi0y ƐFΉBd8\3Z$b6_G6dyt$Ώ.k1N-C}0Y]T_mWݲ._G#OUQBӢ\1ܨ\ZU.fx,KI+VnUB4?P7 tF xEmuZpOƩ)?,-*AIj޳h:j_t?KknXwߟ0nsbB!H U$Gz.3#+WM]S! Pe9Wy[gE$ad_}r:Q DOYF4TPX ,Mu*@X>S6akO % Dg &D  =-YbYyˮ6JzӔHh+ekNқ|t%;_ z>u} S)?Ts>v] kv7KxP stuM/:7ײg3M{#@]QQ@T"u/Wp%iI{mjISr­^c;d㉶i)Y(/i!1q#bFLbɩfkkXO2եV k;0yK[IX] 9twT]GU*jT\@J:iLBR06հ\JFԞ^Xk}.$*/ۃhA4_u }4h"'M|`EFSi1< s/.sE=DZpyNUc8e?i%$Q(d]`qirfK <; {{u{` iL.(,j}b&+{_:h@Vp8|.7ONuHe܄-$A~0@_>"U˥=bCVq o7Si>sH{arp˹yZr^c ʳz] se*tkၓZ89~r6.PS쉎n\n%ghO\)+;BHUAp_7ll墴hX^tW9hۓjBw8rMShKnGW͝4iW-&1x#\ܲ6V8FIŋ"MoSf$֬[Z1݆0[?O!mg㰁M/pϿA t"{?ʟ 4JI!#:./?U#AI+=L $5F0RR؟i\5 e\iRr~E}.,1䨌1t/p0Zrz 7yph%Tq=n'R[Gʹ 폣Ncn%ֻ=i~Sk~4oQXgMy-pBܘ~Qۣ$OzH.65;og)e4'l k?QC=e:21ퟠ^eUr F$V[u j ڳr~ =B+pɩ<&=QB1h9VrwK*_cr٨ϏԷ?^).\ 8M]^:R #=`qc6͘ (Ⴋ<TJiӀej+&ŭtF4Aذ"OJX(&htPӀ.XSP;n2~uG,P `^:29t)lu+H\AZ hey3vW5rQzx-fǃ')>i;Ap ";2?M!#Vݾ]JD (Bq?P@$ps\` :@vWR^R鍅axY+U [3~71jz}EJ[5EFM߆lg6@Qb`:+4'GKhvQ|0HYYfUܯ6fjsuhst1Pʹ\-sT#%)5 P2۞v{"5o??`(AAE,G װP+_w:4X.< XJ(賓 *c.:MOg$_zzڙ*06^.%h2ճ3\ึ`2mmWggIM ڪP 攱4.~(c켤(  ɍ#]#dRf&H@[;P5(w?ªfQ +#$3TeeL:R?FG oޜ~;lRˀZ9jR՝x hjxzI#kx[ZNjo<0D]j}K>BYZGb:,W7URA?_ϛ@l "%\wCŧ/rHLzE8gJ&IƈXiGɤLi3giS:NS!F׌di{c ftw[+Ѣ uSb@:xE;/3km^K+3/5Ӧ`tĢe |K"4!bspp~:wpm84-ARu@b$ r}#BJj56gZU F4]L禙F4q/u&.^N @. kЧs})Qpz3E&8MW3K|x[ m=5o.br[zq+(Ђfy kʅRn6.unW]OÚJk(X;hvp$53P h8՜$9"0K"<~^td ug<1v[l/9)$yL!ԿI]C…W.>W-iz^~㒚NZ]Ƅv0Wȍ ^?Kgl04W$LcӖ bb$2(z 5qUjV ] Եm{5 AoZ772oL=6\ى  $Ջ5PJ@ZO{8҃;RR$sCpLo|ĈDaP_nA!}6 @lm|o츐=RƓjN8@^<>Ũjr/^1=<Ҋ˂nZ<\csgNiMPow'i ,8q v-5,Q7o}KLG9 ]`)ijc{d. u_=z߶ຕAQܺt304Η_x#lV UE{&(tF (,L@yFNjz0{w+-)wj63l/hIn$2cz2>npv}Z"prs3}ցe7*8AzT>SjnG5+"FrqX3Ýt]1g%d]y}FK"8xg XO< =ޗ.@>öb\V55A?2::b n2ψ1iU^JJWB~r>w"{rarݽD%p\{^`⊓^}Yڭ4Ue>lq#D9m"Ʒp,gb"_.nVv̢F2}J+՘  ,j,{a:L#(hp ZB4x7ۑ]ײhC+b&kgw&LEuZ0a i;=%@~٦VBgbI 7POkB7r0L`,pȚmDi3~Dg (i-Ox11Bm޷Y>o[FBL$2^o1\J]'!$"-*RMq&Pn l+aQĿ4 6Wǣ^ij<R~x 881T[呂Sl;$+Do$7,~-1$ drs P+1# WA4_ĵj~h`ڄB) 5A]ZFg-n{ <(UR/ba[o(BwպEIJJQuˑCt[rV(I%<;E?\$% _q\I#Y>Cx+I%d'@GzZH Qk"`|MPT;p70+և )r:{І+-X /{;torRum̦>(@&<Eࡑ>fYzIީ$P'HU]Ǩj{sX@mPQb4 DǾfSC)m ,:[=fg+:?gPm+BkTƉfJl\rόtű2Ҹ6*Uz:GrhD:TJZFj馸s)jw-DUp o|#VgaЯn ا\E%kb3$A1!$n9TNp B_aWlU/5ϿVf+FKӌ"_?iG ~-3J_e2КJ2o"γlIWu+ j @F,Z cYv)k9 hWlkxдi-c 1C)BzиZbrvWa=*rGϥ #*b4 ~Ob ;Ol)X!b,o3J@h|'+,}kMzzs2W~2!SP $/YHZ'uf9 3!RGOȓYM)ǣX'=/C>{@Y!*4>Eh5h*3vzl1[+ƎC&۸{9 m7ՉEqS&b(+-r֖/VT6ΛL[cT(4'KZȽ./;*H0ɚï}vOg&}ͧ ܘ<s\OӹXpr\aF 4? 8uuA /+ͪ2f#JCnv%S6D Խ˛H{jtvhhmuU2z6x/XDշlAAmgrSM{˧C~g9[p[?FD'+,-)mb/[!JНөzOH/F|$Gϱ%[~;*ͭ:#w*-ݱ^(.MooUJT =%g`( qb.>m)g|kN<4 YVMY^LA: fQ'8j\']G0ԅuk'^58kxȞV~/X1|6xx}f,Dt ݓN9Ic`*J3HBf&jLn64gQtY+ it T:rygH3cK:0 \R>!NT5D^ @ElSS˃D⊇˨su{o =t9Eݴ#}06{IxeҒ S 桮` u,2f 9d*u»ʇo[sK! 4_^z8A/J4bq=tF (,2ór  v Pe۾6zj۽ꦙXt)S)'R zE"?BuC] /\b+k"#f {Ec+7 Baê5/ 3NP=ր.{cIp1OhQJhsm Eƃ~Qj-P}%[oSb/,}BM;iT{#̯ _fT (W!l?%#%0iQ4~{^4Co-քΤ(O /,NV%WL.JB XÔx}os'6,(h1r;.|K@9$_fh$12_!Z gLIMXm}zm}>ͿP[+ꑐ4Z(ŷd"T:h OQ="5֗=^Fe//hqzz}4GgB?Dg P,@9~ iكzx畖'){n\A$4_ĵj~hbzUl7 w;h[ۮ[E @?Aw"+Z ۻcB,`}0slŸ@˫ u[Kk7[J0 ](p} uALJqE +=eըR!<Ϲhѣ2SBv#IC@BbFҠNw7[ 7trK!ӯF.LbNj8ɏ,ź02z@~ VɥB\PAOABE,G ѿkm IG44 &lo= Z"M74D@/ibIPPA 9atF (,fPg0cDg P,@ qAh4_ĵj~h`k.Cbe.3'<Ólmxn'`$G}$;ݴQNWj,:C;F̮-^g1=AE,G [̎Ҩ2^q˔7Vi26tF (,L@2Dg (ك&9P+yA4_ĵj~hb8kn vV˭24g;:ϖFv)mI *q@1Xa#Ko(s*xAAE,G (q6u@a1")]\DC/tF xe@.Dg &D zScA4_u }4h%= -|! [v}Öc,O!O"f{`)kDfTsB&2AE,G װPWF8-tF (,L@a@1/Dg (i-OxQ A44_ĵj~hb̞ešbu`>W\ o=gqj':s 2ѕg3_ ' m$k(S6,|n+ylk'Ku oJdB0(Q.dʉ6Ne7Zo Jk Mn XS-Pv\yagn9R8sP¾MRiMm3cC:(s| kDӰb:&(c7?%&Z?ڒ6!$  _A -/ҧNr|55&yD@N0>珥cJ>V>vD|#6_&q3}bzڄۓ+a{֦6ckskL:s*s9U:vfBKfpD6K, Ul(n]X&&nX"/9;G(V߻C\f;")aN'Ijlצۼ9kz2!:άvRd. ȵ&0hbN !'0NT#^v nf>U';7C峵m)^Ke IA0A8P#JxFS">K'o>&|~fY Ogìk"*»7y^ߕքresf n,(ϿPލ.Ux|!:1R/|M$f$fK[ ަmL_<8WJqXLqUQԓQLē!2d5#I+cHZ+: @Bw Á# +k:9+P9H NKk=m }G^2Ļ3(\ )i\qť8="yP^C$j?Mlsj (CfEyLSz+= ~Ppv,G:#.{*G<lj(;)lnn1m&U Vcɭ"Z.mSn 15qaSf.'zdԫqb>b\?P…Jsg8gw2WJu|eZ1㭅zAǷo drF0O!sZ}BRT>93bOPp)I&Us!"3䑴+2 9*S{W̶L&_q[(yh"tοeZ@j%Hn׎½M|݀KOrD"oDx|^o=ЕD[p҃'kVס+ʳC}k2fh()x^HEuhn h#XA 82yNu>!Tq) z#T*M]a'lac3MA~Iňz2w=.RS01J$D1^Uz9(&hX Im@cJ{edZVVd'Lč3J^H[;k2Ql %#j}cJC,8~ ԝSTUNo _21BI?Uu,,VjX /b- (P8c}WPlQs$eucZCH_C/[8{aûQĒ Z]@G@A~eBKJxY@aT|M3FQa$~TH{}`r(Em/`Ʊe Z7Z뇼04%)k/\3ьtYY} "7*2 hEJt/W,ALZi f0,+CE|ǁv/GD)(0~Y1ow9Rd>zc/kB;OiJ)i8i((o(~'AS'hV栙O ?kG7^lOԞd@ AAH@Е.SO4Ub|=TjLdK\摵pQv&ꀉnS4BXLMϺ62'/ƒ;݇pڄL-jV^ࡅ';[MzxPZL93CXU k5žGU^tx/}Qjd8/K`n`5 ;Y3Y7{i`ak#"1+|. je. NtU/ke"j_yN5UU(F8RT&Xawow$@Tf.UŬ  ΢5E'>%XWD!euH60HyrYӇiARE,G B@Y]_}4پyBf}PbE:d>˽Bp),w1(MQu6ӿ=/%H_02O;^_K0A;s, L܉nr_nC"ոڡэ9`M.;c f0lnMA}WA5R;{y긃T'W9mB""ùwmjy@_ H9# ,z^X<҅>]dysa^ oЙ$UsW\߼\KsvdPl!Ņ/g^sҳRsT9›`p`p5cC2HS*FpEPޒצ8ŢaA(6cOXV=zc[΂zAIOJxy@3UKywqtF (,2órk^"(V^}1>t)mqZà N6?i(h'^֛WAڣg7.2/o6(z_) s52D۳P^cI?h a\rOo+0G X rه[ Q=y\© 7}=@tQjT\@vQƂ00}h،KތDRحJ"!1ؿulYeFy9Tƴ}i c pgN `<5 XHr!y6^_/o@N`}uE7s{{Gw}w]]nU nrB 6!BI%y(ED&ׂ81q \ x|<6s )\ VK+֛DQ#`)H}8Sɐ3B{WNh~}zpl D_i);Ȋﺢ) M =~l0hb/m{ssXQus@W6H)1$Euel<$f5c¯UR_VC J]iuJt3ہ#`qF"EԬCڐЋ{&l}{ꢶbAx4_ĵjhgJ͍.Oȴ )O\=ۖOX^6r65FX Iȧq,T"1a7qVcULrreߞ_ bytNFbv-,oʅ5Hm(7$%I':%g}AE,G ѿkm IG 9Z}d.UF~Lޕl *6-l>;֕u i,a Rspz3͛$SǢlH,B -C!L#1+=əbفtF (,fDcom$(_jjeƃvW(_W"A'4J/g#P9vucid ֮&sE94!8+JG,AD]}(%"_ _Dg P,@ ݷg>Y.xc=s}~3\f,DU.,(TF XA4_ĵjMT,9qu!Xjo|>?rE'G(1r{ۍG tLm#['Eds:z(=:R(|k 7twc8w v_(4@AX3wSonx9 rdeAE,G [̎ҨIlUgI욿L|\?Rnkny`*"W;DglJ)TDCF~{0 p<>ˍ|o*vIY)t ckxIgEvBbi,nw0@AE,G (q6u@φ蛡%&sɍ&zF 6ⵃLL$J“1 .%뙽 < ܷdAm`xPmz#$ۉi}2\v 0{k޶`m5K:r> n#ujaT=tF x[>E ?:3ڠs} իo~>8/a aQ̣*Oǭ<Ŀ/A` !?f:ZU#!9 w#4 4tS;HZ?Dg &D p3cRBI6t5^ ?J+v7|Zi(,~A$4_u }ErJ_m&e bVAK͚0vguʌY o0D/`PU2>wѱ̻=RNvƱ+pS\rD%bgS.ScgY&*A?ɰ 55 h=@U)BFH~%ABE,G װP^7%{ʚI-XnKL~5mt HݛwZ*.) ߹S)̭ysfL z]{u45` OatF (,L@f5,uzDyMUpl8_ʁYcDg (i-OxLU e|ºWSJlUMSa+{ըf|pAh4';=ʺlFP8/p,]?1S' b4ܿ=(oI\ mXcn:SAE,G B@Y|\}~3˫=N,a!&ݝXDFr9tF (,2órr@"A9Dg P,@&a2 @u  yA4';=ʺ9& ӃG ίj2?R*qJdy9p2܂>B#\PCe yJGnPL)kĵjU{)r *7qBL0 L 6=mͱߍ@S $q&vd.aAODg (,zCnw'r -ekAT+ĵjU{I`ZܬCPry{?QS @+śr_ DK .[\O9ArENs;2|vq9AE,G B@Y5 MOX9tF (,2órGHg@;4Dg P,@]Yx_K XA4_ĵjU{',brCů ړ?GOyojL!@ ۺIY8YȞIH-. (-04 ׾XqArԳ [n@\{|r ˳/ 8@A>E,G ѿkm IGp(aqI'jTO<]tF (,f\Ҏ}6_Dg P,@ ^YSi  AB4‰ĵj3|`,ѤMp'3hzYyQX8$*Ƣxz*҅5+H#1+F}^c[\&@I>$xnȭ~͊t< [~rspdΏƷN]&=3,^^ O4&m,k֏R5 xaDg (,9ŗ`@J+å(m}G(Ƨ2t}uObSi rmqT^,l_Sv kqשyLBPV%Hӡ'jRɸ4_ ihtF x(ҷ!inZ!Gl=$s"X>?Z/mZ$Y0U Dg &D c!sSoK|E)MrCsc$KvGir'ezr_뭶X_:;5Ƀ"T=bY`v4A4_u }(엽Qd]}tIVj۟HW޴OFg J,Lgo(]_bFbU߾,{z~Lx ,ӿO9}!! DZ+25Q9By"/ЋschV`{P|SrXlxWGHp̳@('/=c f]K@fYÅhHoּ ՝KJӂX wAE,G װP<%MR')V`nCؖjrOxBր2wuƉ@9G~{ctF (,L@G9W#p%j*xGo^2hiUax3譀d{2 RђNb4SNИeȭx[ p&IbsQ~ދ?-8+fZk[,O?84,lB;0/ܖj#UJК{ Kp8Kј-WNP@nA E,G B@Y_|ywƲtc~}w^< AU+E\GX,EU*ug̓r kilnd\+tF (,2óriD6e,K T6^x}YpgX-Dg P,@1am#-Xo͏JiE]LXFg(~Kؙ A24_ĵj(qې;Y3#(zc=Za&U~,KhR'RVߠ ?zۀЊ \1jQm܍b.X.@cP:qg7C\IIԳ5G* ns%=0ZY1_jߖʶmjDu QPWhNd;S׬`QzY [rpQIg؋JV-Փ(u՘ wD('tzH[zi!4Gb8@MpPIí8w=`$.\<>aFV|Y$J%O@HU(v2#FaXu!bԬ꛽NZXÆ7'QdA_w߹0̤FKm~FaE. d]b,! *#twP*d-倕PnYt:{>8 D% Mh(՚'Sg!y؀D~"UM~T{&B7 p)~?Z `&3nMxM;Y`Z*)zMiRh=F'55Xm#BRV\=$&0w|m0EpŁ6iU6cN4|ݴI0e@%APE,G ѿkm IG7H@ˋu*h]kۏ29Q :(<ܹIFl}ؼ VКAcZO>)GAEaϸ|mU܊Q?^k~_ au+69>NFMN[',tI;FؖRt)?XV@YR(.FOd"|718If/7)/ ?ڒ'?OYPU-M ^n*Y\-rJb˛bxA:otF (,f7F}R@فqDg P,@"<|!K $ϭFSE25e1gĜxEHu$7,'ܙԚM(d:c?XRH ͉"S1Av4_ĵj~K(l0fn:X t&q[2yǠ)B'@V$ \n73 Zuc6Z+Kkēw5K(GD8 Z n ^:BUj\vHusxnH Y12mB-/2scbfuM6=2e#4kHJvOOZ3+ @Qu8"!%YJ& +Iă:n#[R_&ZZNNh_WnF邠rXDqk-r L- UXLOU}{=rLoHR&ɋjIٝ!J}Aˉ$B$?MK^0M|GKm 2g_vYoG^?$_1D?&dJYхl|k}(SݕM Xv1#aǺ(K95zdt7 謘Tff-'&-%(2 ;VQώ c@CtF (,L@-OCq϶xiʴ*I{ L]p`]>N۹foZɏF+fBY`I6nn#{]ZF9 ڠ/RsZK޷),a7j0O~z*Q*QeZtּiv}*o o0Oʞʘ\ &d#}hE}v/<ǦWNTP:I?=J>&<Lh@‹PU:ZPGǚkGbVJ{.e@$Dg (ك&9Pf`O[1_m&qQim a@ &  )Xu NL~({c<޹>"+J&㸚#800.j#Uk$j: :`c |cg! 9_K(\e9!C~OqcƑ>cbۉz#*]M{ $#FtXȯ$XRm@A4_ĵj |TTӼ{3۵94?j@zd4kD֎( U](OԑA! =&g6^MwxB)6DW:;cQ#w}\iTE}Vlp]^ȫ0%|crYSD`%m~gq~y`>AE,G (q6u@{RQv u` `̸!M(os<7z!'vdeUp'9=;4?6-2#y؀F#F+/X&QS܁ 2Jh@[md^@0SjvTPؓ'`AArDٽM襤4h1띱c t>t"G~Up`'t~1_g>H*/X$!L>bn8uT$n:uOCπ22Voy=BlM7'gi& 9ʖCϏK;Lj3r ᴋZy.^Oc^oPoyY)0a@8ػZ3U@VRB HK+EQA]1)X2,J2>MǙɖn6xa4 +q_IW(rf+}'y(d0!ӹzZu%z!;2nA⚥n4 n[{b;ِD^;hV YHDg &D Ɏ :DdB7awk=x+NM.P}$~STN4a_zf|(+yb(fq+qz 5Ё2XI7f&%o|:3\$RLE<u8n]?.1c "seЕZa0`o _t*nyIyo{jwK|jZv}gI!]5:ߌMރ5SoyM MMŽ=lƀeA4'cZ$,W'z(-wۆ!j0G9%KZQ{*K 3jp$jR}(O@Vx ="`QthiQkX4!`>O EsܤkP6;tF (,L@>W@Ka) 1gֽq6Pߘ~6w%YSKWbɑfPc2~LJba> T:ʭ˩1=Zǃ/sG OjB^fܜ$k‰(#6fe^V=Dg (i-Oxm/Y@ VxtR5v:&igIcANo|htӊ#:nȬ DZgRi[8X2>nJg @!At?'A 4‰;=ʺK^s4լ-N~$~NJ?{DUy?~At_Vb] ͎r!ah8U΅:uG[?,"fPI6Ă@X7UVu ꓱ;XZb&zi;) V`pv3LHzM)/xPاrE AT&N{p^*'{IXʰJY"R@$`e_Dg P,@6*Ro:X$jmCR d@LWsK=傂>&>@+` AB= Y?;=ʺt~N3q̖&fib-}8111ϰh 7qU78U:V֫E ^M\!`eV G[R0ᚷ`Ǚ]-vHHiSj:uAIQ,`<4|  kAʼnesvzhTQ+*^]:`aDg a܋Pb[i.PkwaA)F!"0ZVyMl&+#Nqtxb+f?Dv|Zt{W>b6 8AdQ5ĵj=Vw#榾$\pgyp]k<-Xژ|`82+QV &zǾoHݐKQ~]n;=aϓzەta?-}ס$[1hZp6؃ڥAvT,'uZfpng&U(@yS6 ~o\pw02^`71\(]$~Ms'O"xe?zg֕RRd9Y/nL@,PgI*HnL0-BE~KDo)EzDg P,@v{UL .!|qd IA+ĵjR7 Gj^fd׭Mܕv)t K }_"N?#;Z;a q}` ,xuڳ-R M8Uu٭dlv3R-ut֗ܡ@'-θI4ҍIămC;ܢa6?̏m6A<^'aPL%!I(@~_/AE}v;kηۥxK1deO}p19`o 3Ϯ < J-5CsDg 6@6#jc]8n:YNtSmΧi#DH=XYr}5N=e҅eeʶufG4s&]q=׬A=ĵjb?5YADCVP$Np陣d,Dg P,@5`P0ZV0(DA14_ĵj6؝ӷl@?u6MR qDqxj%#\ܸ)faZaidXD}|RJ 6Ij.pSV~/e0$씬e7(`guc6ˋ]E%{!7EW Yx0s[=~ѭu/oZ'>AFfV#6#럕Zp8Au4_ĵj[b$$cON$X'ό=C3Y,ZÙ5CE7~qx_Uptr3U.&ڏ5cX(4+ ( G:0I̕s:.9=iV-cZW OrQ;AE,G [̎Ҩ \Y.)زtF (,L@O⡕W*Ҽ9,#COo(nCK?O9T,." 3u%U"ͼSqD^ U*Rep&vlLVO 0[L@=2Dg (ك&9P*A4_ĵjxy4VmԉOE#4q#DlGxCgx؎WlTBB s)!Xj M*n&p9k1 8Ga r 8ѿ?I'f][BXB,؁&w1;g :9m{sAE,G (q6u@ x~;~u9}婴 . K9~DM/Pk|g|oF ~ KtF x5Z{z}4u,Q/WE!7/VJ\GԲͰuBAp#WZAU~:$dE uDg 6@7q )pw͊s0)t.F*mQ Tܼ8d+.A qז74+`||י:~L DA=ĵjͯrүxt3V'I#aLwcUx o^$mQˈ)l Yma(@)p qX'ѕBk>w쌯9v5P Q0ءp9$mkP7OŽd#ckQ[PR_E.^'E׼"RώF.)ɷCŚ* 1Br`|1o&Rwy3O~~&My"_szMs !m9B`בCk\IfjoVϯ /w2V1KF^U_iT!vA6r<J < k& Bz+{~;4{#J)Qj@%7C҄SȨ A6GfчqfȊC&_&~>^6^+a[&1Gҝ:C/ ;[ObQ--(qe4Zs._+ċj)&z H004Lu(`f7A=E4LG (ogmy, e`.6' &Lzjg^j .lYUO ڵϋ 5BM|T\tF xXYS(',qn Q!?Rͳo=a=~ۈM =ߚ {QՠI`g/*,7*`dH 6:F)[Nk˽-O|\-u~&fݠ{0w0%^Dg &D 'ݡo '9@1@8+}٬8@X]s_!t̪KR!nnފ#:䀄,5ܫOLHG3q4؆h.[= H["+kG\AA4žu }[ %Z*u {(%~ڥ4 luw0g,UQM$* lwR^^o ~&tvWd8>{Wg` { `*bO[w2R;NЮ: ] D|iOfYMNhf?܆u=gfޞ뇻`kٷ͉}Q߈ƣ@+A_"CxD|.(/4HFq(JsuQ!<lo .[5VP-(bv{x.#ThMs– `Dg 6@7ju+mgKy)͔w!4tޟm,XY+=6$YG4mjzMJR_) ̭]]W C> S ֈ4QU41Ae=ĵj~$Ewv?+uwNf}djUg;DvN|#oAcG:;_|IthAH*H$YuQ)Phҟw^#tvӱ_BĿ&- `X6ڂ@3J8 D)?)6+sGAZ5&xz=BSkDUҒ1If{T'w1C"L_+ZG=Ơ<Đ%Yc!Q.xDHǽyT 4m,\2b*tX4"iټU*U]x^U,~YȀ16RQpa$ȫ < 8ENjjvT.́߷juVjb>~Bz5V>;;B)$&5k^#W6oUH9ZϟQ< \i3cpj7U+ )ctI|yK\ܦf*Mש6%7vm {AE4LG !)L sřX={mlHD|*lhIꓰqcQ.L!)'Vr/8X-lwjda A.`DZ9%7C{O@_=CE/8bW_ [l_P;Y+V8ѢD8F h"ni9sWqO0XG,kcKdϽ{o9ByμEX+B$0QtF (,2ór>P$+AG˂(',{Aw.=ޭgS'QOƣE=䠜c:5'qqC{: pM )y% $fi8(v(ȱW@(1 \z9pZݞ+v k;"̹;( IDg P,@5 pq4Sh\DHic1T@v;{e7(i١s>\CO!CO7فsoGyTTi963wE)e(ɏ>oS`W^uиo0֧墋ɀ^EaWbxaR3,0A4_ĵj/ͰrX |:;sy"CA"ѿƛ*'\(j96@ǜ9Y_#~Wp40s\Kwbd7z;O1~c_rr*lq5d-6yJFd{{ Lѯt{yl#cH"}#B MxpݠsTN}IB,-|rb\K;4rg+fɈaJ<}0y)@ WT(ӦY/ V[{|mt$tI7,/fЙBsyRly=sRQWTMہfI'!J;qt8O/mNH˥0ka I\_5Cz`<‚$OW{ Gx)2ڀ1N=a'́+QrzXzFC>+D&nك F׃R =N@ag2J`_"_ C]4FrUx?q@f\ܮEy@⷇% W&(^OtA5("X7Rz:M$Z`?df\>sEdEޭy'f$kxL:e3eR,Dg P,@7kL,ǽ`n҅qLurЋCLX7g0Ɓ4Fh?UgGs ·l)Ā:'2e87f&9͵6#"Gc䢜Vʅ#䎷;1痐R+Dֆ"PgA4_ĵjwEV(FFJq/QTo|.Ǵm*IRF E0@U ~ O$Ü>k$`#< Bg| P۫yyp`B(% R5oԜΰ«b~E8LYH?RdjsѰE% =ށ{ʎֳW XYw|J4-{ǜ>aؾ 9>3-?Zޜďs"IK6$ pVM̱{Sw[xP'Rz>5{B+E30#.}rjhAIߑ GLQZVU޼ IJ0U-jWMy&(ʆ)9Vz~1ǹzW"qjjw3?׬ 1.ᄆD av^i(ZۖӿBF 荬=|ՋށOܳ3,%bTn@wWx1`Yw즳ɔo s.`9 yd>c2b"QT)ˡOGu1sx`kghI` ԲR[Ji3`Tе3^J zu C@Ls=x^kmiZѼٞtύ̃'6@i&$X}{k(3 ;xddӰIi -#vT&=u3I*tF (,L@ 4ǂܬR»,Dg (ك&9P қ>'G`)PK6*KaọpwpK: Oy;rpُ` :#xѭ@vFsb.VxmzX)<8ٽ=dqb\n@޴L$F@v9[ώ$AӉ{9}=_7NB[A14_ĵj>|M<9vxodT(.e8p vhgG@k!:J S2sS@z}A8W'=c^R3gZeL}cFѕ;"^Ϫ#ee.":a9,$o-:!W!$[8;tɯǤc G{){K:gb_D9iW~\=p!kp9soA C ۠ 5\/rzm3} ]&^?+O +vpT}CO#Е]^9>ym']#ےl H|]W|~ `s5ݡiJI"^^:6HXO?_femt%֚ǖ}]k4lSdvlpꌝ\pv*X7Y`xYK8IuL mR>X _d ^P1|P|m_/4y^!; ,;YiwTqr~ @2bzy(Ƴ"nظ ?ȓVڪ"Kq'u(ߣFSS 㳇;70b%9#g(<$Ñ+)Vb2Uu'!^NY x=DM=@% 02SF<-ntF xve5Ru<}7| r>EFIV <`1ܑHڟ/hfːB:ja}+k4E{^ ) N)e[{+a Ife {ڕD<ש9zF|KzRMV0fek+}}d7T0A.m,&ߵ 2ܧ ,u}rPXC5?/im8Z}Ow_Ntэ.ךX~9#>ʔBpDg &D Qj.Z@Eax:zt9Au4_u }Q.[µ;OgX>m 4 z6_l&ůt,eDQ=~bJWv_X͂}Ykѹ$8SaUE(*Cs5>ޕFJō_A$Z0[#^f͐-++EbgcDiHK'A6r$d4؅.)Ůa1۩9JAE,G װPDF Gz!KPZ { ʂNLtF (,L@>?8w1c+\؜B|,6Dg (i-OxkP7A4_ĵj俊:vF$ ~&'vӌ}=ȦAnkwFO ajN78mCp8YV'xR yქyDE5m ox_M GzVG;θ=\gis!Kjqa r{b>/$!;֘9< g*yzw0AP KBO51տ T5u27 $h)Ic3?~bgCs:eJeA4_ĵjlF =O˂ ?TZ4^#xq;FkHRh2uhYټl(vK_|Od/U$s TL([L-kkD.d!L[=İs(ĥD&#zK'gmZ&N$o{%X;zPьEO%^74'fѨT"rUW? -iJHTث#k$\B4qbׅ`ߐwfmZ2JYv4vSܬ/XfxpX,_Y(9z6i遥~o3 ,l˕ )0 6:b]?Z 9usܭ?G7XGp`A,y>qxGlZ-'H,,[NkmvE xҡɵv8R$D@Y@❗fNxH?&'e:Aw E~U; ֔qa&BCQv3nAtnEݻ/ǻ0#!!\e?GlWKGv.,ZFg9="!wCp_A*DsD&8WW@/(:E9p?LAdƆ;U8p3GytFdTbk3^yZu1c722Q ?rs:RJL]$K*YyxѯzHW%ˍ|S[]V(\/u@S cOV)U˜~F V v j0<l&m5_()p!zj@~8I&~Kl8(`Q_{o5 I"5Ƹ)o̜2E<)yk)݉Voz䱲[87xO`g;ӆI ezt`rFB7 hzvρl%oi"0|?ѥ֪U/dsX GvObpJBxT$y;$,tXG-Nt-S}L= jQ,W`P&Q&tlgXh2ٖzT-*r1j]-xںl&'14xbl& i@ڏ#}ʲ`l [@!2SMnX5彖+b꒮1b=wwR".meS9f0ȶڏ:mW'3-=z%g@\ ][;yyAE,G ѿkm IG`;̵jԈ>/amnj  ׋K 넵>b0QSzL75AW)/^lx 6tLȥ n֐RlsH67PJ;g}P%ᣱ `"Ω'VG1 l\~62THte#lu^1wz\б77Ҍ,[SɲdFht)F4S^DMĉ޿٫|o$5x xwSBVZsBb D-U*ɫv=jY:tF (,fW&tn8Z =Zr6fw١X3)znp>t02SSS*Jϩ4:qVe^ۮQ;.GE*9^ߠ||:o;14S " =艎[R&Уk"dT QΈPqgWm?V zBv]0u>iP축G":-Q4׸NeJ,G5'3؟+Ze,Y4毕\Xqؼ|O!);? q!g5)zEbe|Umne !;] ځI8T_^Jv<@ gYHERxƧpnڂ@ŀ0A!4_ĵj12ʗ'JߑE!mSַP)9.5]^B6W'c$=EAvˍRw|r. I;h!J׶k o yx >Zw0l`b%T p"m+Ӊō O>IswG~ ":$䍚G⊚+u|L،Ս6BU{Rt4p;0"wfRP/BN " ُ#-NlYѲsT@Q'^H!ﶻP  _xYh!?XBN5] +5hIs 8=Jd UT9`GH;:V?ɟG Ѭ Eo;a_imM͢-`,%w~)&z ҫmK^N@K I53Jq/seӢ}t+ ˢ+>RG" ޓ*`]Iu#ԧY5| ṖyO3sȨx]EBФ 8Dҋ|_YU%Y* ǠS)kZ=zb:%#Dz|Ϧ?RD+<#]Mvtզ.5⿭26olL T{HNQWEsWX_ IbVXs ͒n^#HK8.S5)*epi\R ~~5wטHGztR_ƃ_wXA*kQğx@.߇I5v"t[JXtҧЄ48Wdgm՞_a _Uc vͭLVG'H 嵑F:\q/٨ [=I5rsrљ{a?kc^ kR~w ]M豪ƧDٟ?'c)07] 2uN ұa7aO)s0a]`؝rs scxY`3 |yɂn'Rm)  )~aO¼LIʋXH-w[O8>Hg2zWi ^%vݼ(g=vM;vFmk:=FXC3+xCM-ECX&ݑxXR'+Oo01RX 1lM Eb_tjA?K!tn9肅B xs@>\#U]`_,49fP`(݀?I(Ǫ`3xh&zb/`rEYmi=ØOX}zWZ&a1"#+ꗤM>˃9FEU%>fȊQͦ}5xڸ*[&LQ`tT6N&7iUH 8DuA+\ .f?l!̘ZӘՓg wŃE@:U+g^0ta\B=TࢠQ-'~KF$2$1ɸ1vN}~ !ܾ(a1ːOj01P_>r UF !svTI`P:Jˆ/'pYӵ-uX݋q/`G@ ~tF (,L@O? ݜMk(0yX2էBB^S/~)Z.6ywWųՈ +WGˊB~2T< `Dg (ك&9P e]K"2bG ӿS;<ΟƁ _R?6={`԰!zkVfYFs5Df)5#[@L1 OQg!f6#rf3T"qA;1oSźg{`lSFV^Rc\j!;FKj!=mYL(NZꖾ@{N{TS34>ZAd4_ĵj=ldc1J[I':(sh>0-7-rI,(C,zWbDePгT:@_x5>ތΈeq~*^6pcq| ]qɍoSj@OSghG7Ľ^&H5=1.AOLw[>g8CDv}f'joQ<)"ǿ64|23ϟI.ESl߿Z_Le00"Y |%kUև*)O7a6(Q R lF^wZQ-BiWK -؅濈CP^#(29-il&"POַaƗ_SeO!NWG{#nҮw$mw^եLW15a]ʀmYi]i!KRr o󻱼m,̕OYajXo^͇06.J`#6Ynϐ2sF{ tp>vãD)+8_{?7;2C̸AE,W ~.>|vy!P9r#nSϜH4l _X\\JTjɒ 1Xߴeo;Sg4".5H|C3b|RXE06k@,jŹXyԚx~h+/afH50#eb]K6ᶵ4]%8hAʉ e|h e-WJD]3hݹ$ඔ)YfRsŘ10D`^[4,Dg (JJI 4!c}&BiI*'*ݗvVJθ1Z95d`66b34\*W) rw #@&IUn7l&Ԋa`x ՝Hr?qa?A4_ĵj=l,Pf vJ~qaՐvbw6*>m'm;"mؾ9};M =tVյx4O)@CpH;#"pYy̅4IߍZbR&ECCyQ;=v1$l ԢI^Ơy5L3VaL.L r:m~j.϶kO<\E,kc6L41vF p9ќ?3, Dhѧ tû7cueyF\m¸$+1繼u?0[|RVn& r3ҭDGi |MUH ̪Gib%JǍب W XFX<O 6V0@ķóa~aur0} 0GNj=[=Ra4 B' a\j7j6eRyr!P\tM•™DP+aԞ dy]<([=yy[Z4mK !q4sy%>QӋP% >C p.[xyQ'X&o86u3R6ɏ]5̺]@߬,}7 &jg@AE,G (q6u@=y 1"3 bJ@9tF xv P6e|)dK-Dg &D pA4_u }?&Ovޛ:/W>.O?|;LTE։l*Z89F بo=wkQ0A E,G װPT8)tF (,L@ƺ2+Dg (i-Ox@QA04_ĵjD*XC9^$ `! p3ANE,G B@Ym6mtF (,2órT/oDg P,@ HAt4_ĵjD*-,jBۏl4AE,G ѿkm IG[6tF (,f#/Dg P,@ EA4_ĵjD*X.v882AE,G [̎Ҩ+6tF (,L@2Dg (ك&9P*EA4_ĵjD*-,j!;u@5AE,G (q6u@Q/9tF xeA-;Dg &D CA 4_u }Er㶌lP<%0A^E,G װPU6}tF (,L@1Dg (i-OxPFAd4_ĵjYu`gQ3AE,G B@Yl6tF (,2órU/Dg P,@ EA4_ĵjhN;p4AE,G ѿkm IG[6tF (,f#/Dg P,@ EA4_ĵj.M`gQ2A E,G [̎Ҩ*6)tF (,L@2+Dg (ك&9P+ A04_ĵjSdNc=I _3GZ.>@{p" lRSlckG l 8q+ec'ɷ| O"1P-b kl(pz?>ĸؼb!SoV`% 5a_P]z}G9SUc27bGA\``oE-:2/L@;YVT^ 0! ?S¬hbEq巰4~gIHΤT$w }oo5IU(EPmv2 QDÙV [Vf/ &qZPO'R!# &^F)Z͸r4uTEV/zeFGWr҆^gdvc#lQK^xy`DjOVDm5~4{ U 6RTJIAT3{-̒nx/wR EB~`xb&GG2~Is6݈ͣV@`x[Dd&zUb%V 0i$r;𔵙 ;#-:"`SQ-#xG.^.Eqk+&cqUlNJ{˔ JaQQ60 *95`|5AqmՂ̸@J9mHģca@TxDRNgtj'St2~[Cm`\ZѱDZ=^[hWf:#<}Kk>b T3 1SLg˝t]DT GϏ@)\㪓6l[T8Y۵ʊ ,YH'$ F#ߓi3 ڰ>ej\EMQ ^#%s4b$J.oAfxbWTb쌝+)7|9bYLhH.BOFE~7TYVDk=gUY3: >.XfsjP"M@OkZ)yt lin'S QHaxLsM;(Sׁef95#GE ּZ9>>IY26_ h aYMhKpa͇B}kwL;%I$\-<\ܣ({PB~E;V]it& G_٬YٿghMY. (*Z$tLz/<=ʐ.LmJh-hIG`eoP]} 32Lg i4q@W #DAY|vkau~|ئƔ9ASvFmǙ,W-y,-AaE}a j?hH]Q?s\Zg\ lvgyhQ-JČr؏gb5Q8e&)9BT|Hqb1vu[B=4F| wsVO Haew%#FQfMP li[s$,WF[\8bDnr<v L%E;KfPʙڗD6y[o7(Tǐ+ï.ۣj1+G=Zs4|] 6 уL`-O߃ӁLWھ^>F ѫ@?]D7qxXDLjW~t^z pWυwo "ar4惆@bRpwH85xxR|gIZ6PV.NE `d];8ฉǹ(2אE~ۮdIVN,(P\^Z9TNY'NK!A}Ur|Rƛ*=ND=^n"2۫># BbőZKq@a9ҌL˃dzRù6NDYgm3t ;Y+d|PoA0AKԳw<e8ft+,X :pdei9L4yPjr\*[!6B-do5[.ՇU17D7%Vq=:)w^jYPTC+ܗVfcRh ?[]S_>-U2IRG׋X[A->{ymbCcΉvMqcҙj ,2GyQzP\ d`B/YANE,G (q6u@:.oǣåWn RgnP߱ϛ.r1uҗY6{SnàI@;mtF xж(Y䏰Ikg=??boDg &D  nX Dw$4:ݪ.euϦhTvubĿڽ/Uv\c<_o&b)}k5t鳩y|At4_u }Er> b15>k4\&|n;@Muxak>elW>o)gNWR8nֶɱIdǦ<<3>DQ~3=swf8?|P '.u y}KlJVź!@]R;[yE3p+b6Hr&ிprlxDy}.pԋ ց(s|xQɲvt!LDZb;[dܢnxa%awIZP<=K`mK^fET:'k!hWSH߽V0 gce tԏIN<5d>!g(rϵW{:ᵢ l(HΑI ,@Y"s/ vϒYDLf/ٖ,bxZV07=ֽmTԇy\vYNFV `y|K/-?X[% q\$o0"!QmH6aF" T6F}j8lo6}6Ne@W:<~W}Y?`DAE,G װPl(g/baa֗⌼Nϧ"%dW?4v(8D-Z_aǖtŅ24*eޚ1R3 U;YQ@iqx ~Mg `Kӯ_̩ RDh%3Ư 3ϲNžD4ZՍety8 w%)~L4$:ox聼]ө(z!I_9Llֺ J |(?09Y;Țʛ{`&#,2c`Ɛ ec_֮A/,Iq׆J\v'wmOٟj"X3`bMEG5!r6͟7s)?FX-HzzF:/cAJyF# @`.<'88#SwIϺLrٟ$И(Ӑ&!Nxk} 𓄈ae(rp"g;w15ie$E@WL'$63T.+!o%̰7fIp=/B]Y?- pX٠xzZV2 : '2@u #tF (,L@R2;uxKUwH}pع Ʃ>hd&(VK̄kY3-|4[y(cC1p"n`إ.<^I }/D$#%m]CS$Z5TƁ$Dg (i-OxPƓ,OeF[lkfXxCn5I7'YwTo鎒@/6oD:#U;.vPHBγn9H>;˔Ǟ?vmΥ^-w|UlM((ú@NΩ@\1FXyp, "$ZUq2CL|kQeL^nZC{uK /7m{X[=(j!jQfT55;ؔ,DqH徐ZVGOd^OJ%J` UQYt෇`ژ+cV F&T j@oEBgj3(KG*m{v DqG-+p )a[4!sKin9drmhCd~T 2m@)% kьO)pvZ`Ҷr4t\֕ myX8dG @ anA4_ĵjq g\2]I!NWeP%r(vbF 'yi8#7%㻤$ww r膆Τ#ֹ՛бwق?`dȯ`[W<޸M vlf.(Fta<̒D-&@0;`y$$`iK U8b wch&a։* ~zP#%?Jӻ6th_ZX}9)H1u8p]''j CڬfMLN sWC٧3V+bЧ|S( bQUEp^ Gh ߁X@|AE,G B@Y6{d?<̹ oq}Lc3wB~r@f& $ŷg!u-sJd)us):Un1MG7 SZT_ "W?I0"ZXaiee8)Lk`FJ=^^y.e[>(-7; ]*atF (,2órlS77 0]e(}.3^r ^ +cz 0,&|:J]JR6+ؘH-y}Qj=V'Chbif|t$E~wdO~b64mv= ^̼va -͌Q%PX6%J\gBZ7"Ukɒ9sٌ6ha| be$vF|M}>i5^i>k?3fA3%tB]v[JwFPT|&L}oӕ.;x#pdduo2ՕCD E%Ih@Dg P,@8ȱrFP$I]2Ї.'\,QNTm>rN-uQ\99PSX Ft,o$+g GL,rq 8.fdj^(r+_ȝK}fR ,Zv:9 URz)wPAYA,w_3"C]j`9x^I GJ&Oq0b }ixD&@N@p mA46귵i%B~GKB0P9#$^X;w/)/pOhWK-06!,GaEsRɩiCh^4zqFYh;,rGInѬSp-Y1,2e/%KeIuQ:7o}C= >t޻`2/iQϕ|WH;lcO4DV`:IRG㱚^-ͳ1813𘙱Ӻ][\= Z'r!tLge{}nEHG/^C{'^F <-xa67F'Ȁ9ዃ,&TOXUEiQJZ#^] =Gt1X4f2;hVDG=b%+oXᷖ[4T ٘eQ8Rv^q/>3t -׏7x9҈s2kxLQL%Va1Q\;*τe79 $]&(ցBmS5:5DzFQ݀aM Ӻ1Cwsgl=)(oqܐUoe<韶TZ,{9r1/DB~Oraw)@yDiF+l2'Hè9*;"h λ`9tM){wqC<&8k+u kFBzBu]: 1GaP#Ib]RsL C% D,?$qï){xߣJX6`@K3}@13h6P$*ݾpQM97Hm]9Dl Kۚ/˙H5˽0Hu{89.'{*0,5WMQr!i@q>^]:k=tWhfkwQGUDWy~zyh dhrzha,A勱fRE)oS)Lbi[gfmma\%tG1geR X^Q*H_.=Z0%ˌOnGtJQӸQv`}ZQD %_g\vW>}]fuhWlWE]T Ӯ =Z|î{?{t/S@̊ґYXp81O%dSErh˰2~ Խ A#|޴Hc *&bax}+rS#Xr:Ott{U^6=UVT8aFɪejSЃrq=P[ɷ琳(FlۧbvP ['ṔO8fBu 1PU,d&O'`({qtwR+}B@:ceLe٫$h'ýTESbm Š&\iǍ"Oj?|'U3J6 fJkAݳ]a }cmf_=c +.}Ԙ5rq yvGsE8ȁ9Eg7F0JIGl,#C~v8nR8z>\O9^iSr J\ !%CpҽظNʪ04IfCnY 첩!}!XvPykңH'@'h_6fjo3Q2wKiy 5"&L"*_(N ~ICs 9414Ή! ǎ.=T2$PY8Ԡa/Ra-?WAQxϨ1+# vp![;K%򤙡(7*q ^xB_^~ 0DzX( ,WMy.燔F)!MBM5&:.]ˡ 7ҋA&3kÇHjk1d?kDE̷\Rmk5</"!X.W*>g v7Џ->L(v(Dh %yTu>(hߌe7^tER#Y`XG7է͋[ a,CGKD߁Knl+3Kvq$W+WChTQ`: Rh1K=C1A%vtQG"n~:Q1(W}&s{vU kw%0M) ÿZs-bt<9AƕfIZ% 'T;MX{$HvL5|g g/ۋ-cm )jua[)xy5;T;IM/P2J(L3eD΋!7TTޞJ0?q{E 5] XĦh9D'C0%2Y-A3AxC%eƫd04e)@BW 6(dv/9dR.|,!ؤJ%[JsQ U[薚KuV-liĔy>1ݟi$n?> j2D]X=h\yWxG}XLԞ+ra4*J[I53?%Ӯm ^EH .^-5l) CFƥKnGEzOܤ`T0[R7dL9?ǻ4u*)_ܫ-klA ( s3E `F UpGIIh{c:ڒgF&z3ZSree~m_Gm-p_*^;Q¾gN,_pۘxY`An9]S CV>ɗˁrK0@ ;1#wrgR`[\Z J|SUVЀ!ߖG2Ĵ@6Z[20&:S>q#` rhQ"0 38NOx Qo呀{}|A9%`ZO/[N)~.Iy0] ͈Z䲗K[ AOt,yD*]^/YRwN-.Sbs* X]ǃB*0>ӔNP܃pA!4rt 6$U&Z,9ٟ8F=q*VqI@ dMTӲ7憐& p@()t|u X^_^5@cgv/CH@!wZ&˖v2qIDFԤ>P8vTn׺>|QNŇYTkZ }-v{O+7`h6H2N22NPڙgV~_:B[UE^VBCiDt7*͋@@1@n9G 9)'Ĵ? AF/VţÖ򱹕Le>Kտ0@&S-6veWWo9aK"WխmxA6wG *N@bp:n\>_ƄRIl\[\';IIb%8;U2mM*P\2{NklAOJ:P V6CksNC8ҭů֤ݗ?(vn|^Z53m>ʔ uCxų|9Ի'%FTX&gR7>~~j0+*/B-LZ,[(Ɩۜ㡲Fgϸ\eqTvAԛ$[WS}((1syF6Fu:0sSWwR7<&opbGH!uճvnu7}{n v@ #'gi)8;W[ q~0Io#Thv¢g2^,(AN7+d Ջn,;Ƶ2"~'2%n8}kK_Þ@ZzqǼgh"BYSs2@+Խ̩ ]^K>0 IVTYxF;Pf:5S۟1sokpԺeTpP3@ed>hM˖n>'Nt'4&D) Nm2U/&L\Dw pS ֯Vs&U+1JRVWYĐؤc~չcPC$"3wR8[rxPX/b,b?+vdUqq`}B-9ds`فd}+4hHyle+o08YM#hNJ' ض>fbzu3(U<E*قʹԖP􅖅DTyBm9 oX1@~(]*-j8)r ؈(?1xe*\#}QH,҂AT֎ ^(vͷ^B0VN4Ll"O8dgT%R3PJkb[j~c,!Doxd),ڮqbW$[(.a1B $g3Ot@A{9%[BR4e~~ !x1*Ps5@dDػK7@~҃sxLDqܵIՓŚܨ )=](VG§rƉ蟉Ya?`h%EE:9d9>;,ek/0~LN+?TjkYo]4򟳼i<%ǁIQq.D w7ߣ_:ݽޜbbf1K I1j_IZiFa،XW g=Cφ^C:j0./W6 DB~ڒ;Cu: 3VB>!bF5r*zM3^_ kM!1}G FG\2BI㶵_ ;}=Ԑ́B=z.+d}"|$Lh^~ʒzйa!νǟkT'{)>i q|1kOQa^BѦ6|?2 7܋CX|lrEʋPItYd=}KJ{ښ9א!c&1b0iae/f0.'K z~biR'5$KHЮfӤO\叀l5G!a pdcrq%&e$=_}#2N68^:`**L%*MǭrbaP VyupKnH"+Fw@)tQpޏъ͂z%?dbD\,} xgϛD! >"3<4*rGFZ"P?4nXYS?&I=~/q-ֲ*b#+=v+z)e{-D %ˏGʉM#63Hp VenwvN}z dhH@饟,{ kn\!oys˗݈#0y(:wI9~#<\"I76%hRj?vk8$/Ȃpty:$'}S'$9 {qR%3 :H^ ԇcU*U)Bce,dЋw32 F>w>xx0M:Wm_D b4WG*6]YoLvq~15N K|t=Ӿ# K;K1\Fէ~ Kf83fToЈt0d/FC2{2>8|  .檛ɨ%!.ΰ62$4 #<}虀6j1|؉U~wTK[x#FLԎ0 )! Oni94t5ɬQ\dz=ZR͚=E6a積?I q''JBDVd1yA4⠒ ygT ^c@_(X YU7H&p_IK:jh rxkt\ɷydE4 3{' ,.+)oscL2idW|Tna8GDik@[и>$ 3ݜ˳8艪1^.k/%UqQvLr*4GѶ)qj(@SlZ8ӯ9yr}cxfxS(Sm6)zXaRgΞCs3ڒeqw֪3(Bǎӄ:X,.!Jb 6,9:M1f(% v_zWt4 '~1D͂5% mG:RcDwd6Ofr.jh_/ޡB7Hl#adaKOi3tñf뺳yUs/MXJֈƥe1tʷDW5EI@**αEK;K2}԰׊nxcWt^( 8!:iBuI`䈞 Qwy+1 uhpG/qج׻ٿgu.T58+}fԑ!XJHRQ"J$)𔷯CݶC+A^`@T4d9oAgGfm/5U;@Ng%{}726Ċ~5ld? ^b!7v^!y[8K wl-~\Gy[RWҨk8v #}o*'OQ8ɭ&YxVRtTb.1?s.{h)տk|3Xj GV\B9wg0za/dӁ:WahTIu]+&!+0Bhhm*#zO*Lٶn 7bGofz anlۏo Ƅ3Yb2s Yv$'d5(Mm_C3Rxv>e H :sn$~5%sAlP1[521p3r{ I͝?uh9sftʪb?I&77N Tl\9&Ʃ?R|?ǜC(@a1'}žm>d?A$$ucc(?VZk4콭}|K.dZʌp2d?A(\i4.Q66 8p3O=ē?%IƎdxOSHspTj;[_g3dɺrM34'#D,%}yNgE޲"e7aǷD-`?WŕJ0GGET49 ]⁳c?,y>=IB&U\}xR;7nZS5Nݬ4 Nat 5(A>:@_;3MNsQ"w9p5'7 [3z:'z#1ԂL^5$i'{:dB1 3LWCLc[MiFgȚN/bOV>=I Q1}:!X 723[G,-9~,9̈֓؍vM!J~6E)WYXwhbYTx鹄>7{!Y XFQCNp~M߶i>r}!hXrI(ÏՍв|rZTe@z[8l vrVڠZ>oxL}h.GHLGj`[Y 7Z=ZCjnI ":d{<kPa T]"pٽg>/c;yg)F(ZqVkNGE-xң!r@FyMp̙'9EizRO_$_֤. z2߈-O8^{H1aQ:)*o%UL3޺-w]U2JũBjg5QG̢[KWNO)XqE@O`D'n0߹,h+|΅$X6G/iP&DqWkBt|> 2|olNF7xϊ##Z.Muyw׵x˚>7Er8 RCFd5 1YF{Ѥ r{}Nd.q7m'\H8v%tؾ\D%sϜ{^[SfgF©40F{g'%9Alr8#kMZ +imsJ"/{GQ˙,nID8#2RBV_-yXk>d;s^B8߆˩!bH2}Sbln産l?ϭJdnwzpi_pԆ2 3xNө6mBߧ6M7J'GJuP9KFs^`"yX&+-lnF I>`te>V$¬SȿBJTm2~9Uӿ\R]~H;k.ff~FuY}m%-$h |Dv7dr 5ߠ}AyGVո;L$oŢ5>,avi+/@^aR;wN1]uP; 8Gt]q I~ 8p7NX]_I=nIaj#(ຑL%twY#?z,DnX3*'!mxius%['2ݑ F7:@[ڰږHaqh4 %A#qwe)CՎGmMkNXE88 Gwrel|Vp" O7Q9VQ*`KQFjgf\к 2_S YO*z)eF\Otw۴[D&&v/d9l:5 1J**D#\SQ't_x^AmtG$Ca 36vƃv^k{Py/S .kRʛثcV5ub<[O ҡec;ɣD|\;&r͊Ggy'@kFǏdأǟj4;ZÏ(LR*xysae%jUtA{Ͻ%7G/ y'mTQ98|oYk!mA(NE`QW7@Brޫ@-1G$+51FcT7Z94w[_WúOq&Zju ۴yQݷ vMAWZ{ e}]D?&^V͸L=Fe зku6cs0^{j!Z+7:.zF#F+7&-4= ;L8o$|Y6xrw' %|l)?cysǛAO7Tݬݹ1s%=̜>u62W${0y'Z^4?9|s͗r-srTN#廼UF~ !~7Xj٫? * OlՀ]q1vd?&킒x]75 ٴL1w[BBq8A3ȡ(8_d}bty.iKZ`|, I?EW*,B OahdQvGGLs吘!9i7;~9,<п\(SM\Oԇt"c{#{6ޙ#G+X'=("2R抃ͪ>Czi?j Ӌ/2ʞjͬIOJѪx< x~kJU.big^DaI["h_}ϓd;:^ !_-xGm0f[׭3|hA"~{9Ӟ%RnCXUBttvLm^)(C(Tr t_rRP翹C|e{V HnGqEWs.:3NuP뗁 g e5 F_a:tNȣ(Uo6)v]EerlYw<$WfZk><>ʭa5ԕNaKYE;[qv|/VT8X%>luxDl4X)3H[Y^]A+A@s 6L~"T!-7oY A@ŭz}WbZC{W 8 -x@8TӛQh̜톿Z8pV6vdꗐQtec6lfpo;~NK1 KDWL}|Ka7ڎ&5 ?7Anqq8mT_dJOm L+f6m͍1l2RcRtU7kadm` ps]$*Ns@ v~ߪR4ÿa- Tԓ3+sZ.~"te7}U A Y ' H$`s?V=0gHO$wOm16ornYyŴDCQ+_kf[pA"4FX8o!I嬶2y%*`%^53)ߖŲ(>`~z 0}9`F e~;gߩҾqW<_n;e|P2D u+?ҩ OQ[\1UKǦ ^N!'fu-(f8غĠW[R, Ee߸'${VjzdE=¹ rͦ>2qYV#~>.=i})V `O`ha(`0]B!>Ty1vѨHTn9K}sҼ ([ې5ڵY ^h~Gc<ѿrc]xISv&Mr$Q ٗ2AJ(H"6F86 Lq%ª*]EmX_i4qL UJvb^HCG Tc!F/52(7t\XE6 Fm0Y#p;C|7hظm6ضw$fEzx\wT1+H:wőuFg=Kl'EvG#{QQ&Ĥ %. P{,: dķnY-MsӖ[Z}DEm _KIAcR0%Kt7*6 T,$$Eʐè jSRh,kig/~E?Ԓ5XDe}fopeT=&,EHinX)94 ͂-:^}%!rˤD}5I:.0&YQ6ՒsB*]_fTY✽@п [z{a"dX{J_$qQT`hzB_HԉIp?]. ^E7(IJ8݋h7bzޭ"j2]ш ^n{WTĉOg/QzlNՄĂFd|OWRV9uu 66_Szkʓҵ#a}Ld=^;jz?@oJ]BCۅ²z騨\$u0aBѠGH$P*L` LmFn3FА[R}c9>耉.Gv->2eu)0$ܮ5G˾)&Lt}̊)ΊuQKKZF '5kyZՏ)5竓Ϗ">o`D̰ݝNʘlGlkkp~NA_k=Vg;ܑpQ.iҤ.L_L?^B%MO#Șݾ6.ud42)jt0ϗ ZmcM*$腹Cb'駌buT;؟'o@+~Y]J`7!yx_ը|5j0ęgڢR4Edx5&PG;80\ ϸN]RpcT*kRB=sÀ^-r2ZZ1k4Rbs!8-Ղql?2{I>O!XJbWOZZā[NP׃OmĿv?~6h\I kpe&%-T uL h0õ=FɡłyAd{'9K!%k@gw &X8K&)ǘ7!{.o?f_b2b8 q5aV&D9G^\ !E7ftpC5* u%]U>5'X+NO n=7hh~ܠQ淦QXvJ/[2jo)JN,}<*A1-7ܴ hbS3 tvE+߀iwFo`n(@kU5kwt9Mc_xOCմ2=L1ON D6Jd5d,mIj@N{fnI(%r^xwR {8GY$ ;en+Y1VM~2#R78+:ZZ0X7 ~9QA ގ{g򴜒 @8wHb y;=Р3l]|T ˂(Q٪ :fQ 9f:~=S?Tx*e*Owew'V52^+4=aM VNQ9pI@e0蜷?D<{.9-7_yT=[M;Gv9g*?pDa Kpb#i4$ ˁN9Z.zP@ SG d{W TS; dv!&Ήy6TQԵ] Gt_Ya~R#)&Hԡ$HqjnEY1ZpL6mȧ``e:pˉgQM}gi 4 SXmu0}(@ͯñwb1ȰĈ$Z$Vh(-AqH)V4sjP8]PNNvJڴ8݉t2LE$NEk ^c )ɼs7w5smm} /dߐ N:*hIH+w՞u?<,k[+yt4n1yyocnƨs|g0c}L!(aj+{7Dn`/]P'!?.aT55,/]5@@㜰⼗O岁|%7 Nc ;{)b'z2@r_Y,D1j*hT`6򝦏0`$ ~W)WBhi̎*"s@5'NuꥹTȋPHܰUBFwDP(" \^ O_t1UA  O͌]%JTC*㱱pKr5bb_)Q+xwY8&U%[b@;TwxkSzn|S4^z(R8` Պ[+h*9j[)_FǙ;7\NfjFfe,2:N<9,H9o[{!yP҇@I2LoJwk~J%K&|A= }u"/_/V M^9DU  x޵׵b;{w为DɐH?VߝPj{GYldh !Nbu+`]GfL5K a<(Q5e'qr:1ⷜU7d%%[!5`[4/}L3X Wo;ͧ(Rh\Q}YL[ڎDq|IgNЁ?S^;?`]q{tgRmQ2!!}o~z1~Jёz.%:Qf&`2Əs%CyJY^O_;'E`):Ϡ$Cg\gZNrj:i11n̞/QQa&@J)k.3\F؈YW(ne4gTi?r?R 1t#k IK,W8m/;6 z%ʝ mN,6K`s?Xd(ҖuC_(pxtASPLgt?ҁ,7ychU w~` p9BCcnxzYS óOY#K5,$/BJdp!?)-;LYH>$ϒ0gHO2H(eEҟ>@^+E]ih4<~k2r6Oo?`!!3+BEOd{-6M 1LtB0 ?c++a2]o䍳\@Bܖ!GM m62@XZ*61a?GH0E@8ʟ blBR P>V-{k2Ly)edɹ/ܟ鬯筁w='D 3- N6 c US>Dpy8S5#&*)`)C9= X6~ u zũ95ࠑ;*l¡ @j BgF@N4I%9ߒexrmv9+)8crYxH^Iޮ? BPxer J j_Qtː|hOu kn QJQ/ TOVߌ{+\`|2pZ2SE ً;-R4N|Tk%Rg hM%N"ad6:ҁm9&ΆAj7OͲˉtjtѷt$YQhC-^>.hA 6IӆSnmϟZ,. &Ҹ8eL g=^uaW'boq'uRӓ5m]>Vqh'DNWn81V8s r G= sUԺ|ZbVaP:O2{[(UwC]@׌$ xgp?KBO>%ջ&>a :a#`.j/"f2NdUa}vOM#4s*,XM]-0edTQ͑gMK~ CX$pHIpn@"#s%F; S6J+&~=Wy@l.y1%/s*Ѱ)V8FVgokz02E`fG1ڽTWQa:#k/:p2~?%?:w Yc\RPc ŶPyYkrsP8[r6Uў1%Q YT:`$sӟhIk\u!ڶkZ PƸ8f74囟I5\*$cGĎ\g&EX\ FX/cGѵh ?~#ә#aUaGp]8iz*߹, 63\LV8F87_Kqfhf!u^7![~:;! e1ܥHX|)=FaDxl1旒.f& jnBgrMvxpb{;R}ȼ8Ŧ|ӑ9#3')mg]6E9۞/HMCճ ,a.nj "b;l{Ш^J_~*6y܇-7#ͳw_X+ڬxj\u$]sHU 0rm$*8SPep@}Gθq{c@(v4#2KZy?FNHa^gkw'9.W!]f0\?2t 2 (+I+Œ{ *v 944=xOðK&\Eqgn/2hO›~RbStĩrP?a`3%Piz+x V$߰ \Z 7Y4Sri칌 ^d.(4uJ=ȆɘjH9uƸkOؼY<~קV"ƐLmݶ,KHXqsa_wρD2tS)N7Y)Pَ_!V1+1*~~4/z35B>To 6Л8.SG4{EdŨ*"Õ$Ƒ0{ @E^Lp:zൕXDva-@+M](yz#]m_~;._q/KdJV?M nMzaD*Hcڛɿ~vzU+Oݿ6 vgY*'Ǩ"lI\Zn}Ϝ!)!0[tO0>}!ձп8:lxʸQykMNiA=Ʊ_bPI`aF,iX|2}d6ϔiv:1x5'xfrD x0kR al}jCalh12uD+դ4 z fa5& Oy,@kTH1}Dօd/8FKfxIQ\Zb:{/ye ׷,ClUo]җ6#fߦ`<Ս"mvXI]O`$Xy(mQ̚Iu^_!򕞃bi[hKX; UrZF}m*\*]`x6-d(ZGeLmvQŇ`fqezN OOAabP+-N0ScC'VHOV'բ{`#߳!1 m|7lX̉-'q/= 2+@hT[v(aPuٷ3P8^O,tJ HZ'Gt-8 )7vWYE,GLYA?8["IeE5rZX>(0~Ѱ~nv6_ǯz7ڳH!]}aǂzP Naq[\KΟ`sD:% (w1+B|) eNgC{gCp9ض2TJSyQR*ZU:+4 r3I|A/Rb 2@<Sᆲ*y3+45&~Ւ"{ݔ i\ NVAN_$mӜ7*jԷkYӜ_AȒ3Jd,$CM>טhz0q,P3xtPO#B1Y 0 zǎ͐ǻ ]I!K2O v]N'N*ښh2H5UЮ CV&jII-#Ԝܭʑ :"e)+@O7[?W~;<W_6W! L-EWYh.x qK)Cy5ٱ5Y /֨Wy.8xۓ!N N9wm_# گB `>6~yp)jO+'|fy!/󫺔(AG|p UeUIdɫr&yo4 9oGw#⌵&'K_h]sߍ'4 8yQtBDFtMIߺ)+%Qql{'9DCRǎ*U9P;t F"TCմCϠ9#gal:\ʖUK3mqi^ȓj]Ks(RJ35#0^Y_Ͻ#{b]qt(3ÈzԱ#@xi;8BJ۷m?m]h S|},x-)1/5er,. 42?B$P3uS-GOc-t֭J:6ēL{.> B3(C2ss,`o! l'r=jA3݈f- #r¨UWcھq Ap *mɸ&DyGewEb&\?[(/!õf: TQ{6׉珣2Ӑh1uW@ǿpAX %!bj.wf=g;0xq sSjSⵣ$JZ_+[pPvGzP9q?vDm,&NӝF F./^'I[ ?AM]T,B ~jgۓFX 󷂪Mu zUk_^TK]olvf_AAۓAq%CL)>3$/x[vX3ro) Fa~GaQ|YtVǥ 7d8݋?3usdP,6uzR<.hiip)Fbz+a\}9b0B<!teHآ[4:"fKGZ m' 3+6E 墂RMIM:Tt_:%\0Yy+*"M2 \ŅV#j2ЃQ=0Qnu[k'@/ |J E1ZZ,k)!4ꛬ%5 WRcւ _6?\*1%-H3aD /cXzyX~EQ^<9N/DnkIbS6K(c[I)_)7~q )qKqԍDֱy9^T] g3&¢dJڇ=g^h(Q[. L9LtS2 2_c,=@o` 6?cH3~:P&%,Tɍپ8eRۧy}Q`;óQ5Aۤ_Vڊ<vU-ܴKF\Ʒ$ @U&SQ[538̤~`ylsV~j1yDAvU>Sr#;+-ykwqYC5\K빮NI9*OK1ErQ.0D!cЦL_a^~Z㺓Tj^u'LbB4"J`MzJbvxP;W,8NV6JP dԒsg5ѧfR|;1ϒk[oDP!Tn2.#@W%jcZFm6܁,xCtP;FonώIWڳۓZ}o:;>|dPy,4.%VLiɰ+)<` */60|۠˗k_2CW7jɇ􂰂Wzl&\@_esѸov:h 5L,"(f{)2 N,Ic_FLs_OX&x/5ƄQ[l&̨4_pW0W+ڙ 24}l""7ݘ'Lk[@"ɏ8LH*X,?_̶Lm"s Dt(s# H'S{&MϞIH,d_$SuS.߆K`v > ŢJa y@)y2DƎ`u}'6څ V<:n2un#2/Db3d-ӷpP6 I>p3F2}~A i{3$9 dBᜎKBNoV4j䯪O,eXU璕Q/ZQqFѐA 9o=#En[tמ4"{pY6(">!u=ɉ@!hw [mq|;gc=ե+LrNtcذl YH.m,Y7~_jj%JK~:T^x\Z. ɒY]-cvO1w$^{c~azr53SmT3R9tI!nO>1z.dbBo*3&Wѧ5Q3wy%)zigx/ v jWO%$'h"&g5BJ![ ?%2 -?Ci"cAa{pk'TD~Q1=mX}@".yG7uzfe vjbVT+03xQK т>IiG 5ia xMpv2헊aED'Ze:-_Љ鏓v8M ֺ.f|*rFUІ )&^?X|/ӊjW~BҚ΃ȼўeUXw|ɷ9NYYky 9}VkT%k6[G1h㥹BCttGO7? "iVl U4`BƦo=@ŵ ZZ U%៲9/rH8 ;O!ԯ*!1p]݀dYI8&=Ķ ^ÇjTd: P f@ő247͠JCb43G҉3cF |=.lg; X`G ʯvi; F4U]E#(wH2 kG*pzHWIVZ!:8 6Åhzb(]o*m#! b𒵢90,ِVj|p"q%)ZoԼA=!!S hk $`m6o2ɑj)b`EKu/s !Q$Z|R]K ZPU t9+$)a!׷Ѥ"C#;ٱ"kp)b 8e997 TaP=xrmNռG\W+xJq0 zMjj$H&ȺL'3)WD[7>eeT _(/VJ ykXXp/ɢ#S'p73ӗ@ ik ͟sKpNry; M/wm(_lu{ȿTW4әw{')GVCKn=*p/DAÕskSAI y *漐wX"yhsC51nxxM '׽y^ Hρ=T),Y`tʉ]\8:M"״aNc+>Μ-[ƄπF09NDJA[뉔h&{=cROtc*m%;1/M)1BBR6mf9+DiV}[Y17Q/kY%ǰ;XQ.Hcfdm U /-*'Lz^0#v]zʾ {~9Rsa3#Fx^q*h& p){ 3OLiHݮlYS^/Q(mwD ? bmè#!&RcԆ ",dT՚{ =a5 Pg3dbm ,O6QdYKb–'FkPص@ȄO f|,'$;SqIeJF6GT2Tja&VE@5haϵ%XyHRA`*%c!)yv ߥK>dB\XHp3Bo5[`> l.y nkюvP9AfFoTr\7[W4vŃaVQ(Ept*Y7#s^Yt<<߂fI:ͨ7͂fgrq_ k.yBQ\6\9, _(ZlY$Vݾ΁rwjN^?FsټTmk0/%$!ҋ9hhc *ԇ߮55m=)\{QwG.Ewm9=Kbfs/]Q~@?IF2n{8!m5Q9Gz(g?+׀.}ɀľob}~aSzYe(W帡I`02uOQ`$IruⲢ^@v"D 6]Ê0[<$uFY?핸QlsgD %ደ0ar4 j@jztvFcQoqAE9(0C&pG!Ms>F;u(ca9w[,hõ/bh]&{LtZRNQYJTS iUS)~_Z;0|=ulYsz<D[jEBӶ)HԔWu:u WzV/W  7%9K[HTL+4' \Y2TaG% +N+)5=ZM=cM=>}&apTx9wv y}p 0 5 P9HIC$=?N VoEE3ܾMG!) Co/>NO9̨ 8ցQ>q$R+̤au_(Xd'/ҾBp}Z Rhd!%hC:? +v6~V k4dsQnFfm!+2"ΗZ ۴{2, vѣߩ21+-_f҆5Jb_npFp*3Iq54U~Vr|_WNj{nPA43TlPcT:~0vt-4HaNs2pҘL+l+Cvwq{%\){GϮJC/&; WWR[@E &8LY *gy \y|MWh^NnzO8ο*p]P{&ZQNg|9#u)JUGai?H?]E!9mul+nJ;F'fBOjGN+op|jY9^,I>GO"c ~{K6aҊƀ&wxSQT+_%.G(iv|Yh;rŢDB ͂[oz#-Ꮘۊ1ؾuq(E:OȢU{g,Hg5٭PRѨ23gBi}wD 4!g5K(.st&?Xn7\|<;drSE'H`M':<]xt*l0o]񞢚~B;Hm>U1؁PnubqH`jQ9nZBwAgBDCk ž/W]Iz(9tb^.SU-M*e짫՟rMdwPoQ ]si.{T]2分nKsͫ/)0+TiAQR,7kTF.*f6zT L45szh`7[iv\v>P}s@zflAF A|MAg9Q nQfgLetͼh~f ~Eʚ??+g\T0G@v <ٞKw@WQTЇ3W|'s>N4\&z j e`z?${nWW:PkEuS0JNŊeЮ5x1/MYU˲uR,/_MbrJϸ Sēy]7P{c5SLrJjd' O-RM"dJW^ft=ԏ\@!ux`̒@zT D|-!\8IR7Z [3YaͲ k;~(5|h1o* ۠<b`ۥld/#Q_T|Zs apXS(.K V$u_"v&A`P OS "U  DU2wv!"< =&);G/ZRL'8l J=Z434T #$Μ_vR?|ގ{e[fĘU׬mUifWo <@߰w HWO[If &R/i@@…+&{ n7wΊOqQ($sDK^۵=0l 6T -δ@] x^Y ^ƀt'nG Dø(Jt\)G ЈtsB+-" wb X9hȳ~h <|LH#>^v+]>fUU_"2pYwdR% x͏?s:xٺa4t_Efں?IkZx=)]vix˄(QvbEV_e'"Ap<' k 6x/Hcu/PsLյk^WQGx 0l.Ԩ)XdumD< &X_eh:h>?ʓ&0EM^ ,Wfhb;<[!E^+7%u,БC,er!>ZHAO-j_[b 2Hc6Q髪Sw0_BiXIɌrDln&;d~G 6T}*qPRɛ??S9H] $(U7?Č50gn}*Ư6##(V w7hm%h^^.6a _I1Ulu :3j: ɔYeaW< ?xko\opCjL̉QZuCwn P[k-eQYR q HdTAX6?"P+q W"9rhl*wCJ[N\ó "a5d1!l DN}ǻ{f'w_ [<Oo~z$楪t8i7hR@9Q z߹b ?(ubR7t%37V4͙3ؽldCY+ W\uempd[oӝ&jvz&Eul eک3RqFQrҚ#@x)5sՁuWnA48S3B \{G?E|_5$4|/'֛?CR 7'lTB2:Fm4LWl^re'@)50sːqƂ)ՋE"ȑqԾKGadBZ>9$`\P jSwo6yă[>M^ xɂ٣*!!4~eN6vC|E̥Uk-o]/Sį(bהXNqMRrY PaAԜGb~+|5~sAwui\.fL:1]$֍ňm1;ì~gy0~Dθ\K-Ѹi#Lhܼ4Yru_ ` tlo=C)VZ)4.j0mp%m~dP!@ 9 wx=qM8K^xG0ϋHrMUO9x@D7ڧTf[ PГiNER+|2&zMa/.t`(1$ċs#Vj)Gة8ENeg}9Vݭ2%R+0Դ)Tn Z\!#plK2$L7>N&pwH#o[>򮮦&rr*ta諿_e#b[\;Xu?6 V 9L;:yQ7`_]8ȦyQ!)?:=%Ӆ݆a7(e=7ny%Ԭ~>5 |KSRٖn?I*vc#Ϟލ- Kq53ㅶe qqWzĨWcH'$TI~ ;0S~f?,jM_W9Um͎2W/5g9YO֪/S6OdBP}ֺ0NfD͘;Iۚe@uōgSc_S_i Q\{1($܂.?T% &f {wjGFvyϮi̎"܇gӜ)- 2AK4vIfN4F˛Kƕs>CD$M \*K2Rې#GzkV LNEϒ# Ҫ {4LtBЛ Grܘk{Otw+A^Ai9_y YHy1100)`uʖG= k2H"qk!,gdo<c}^5 ES6T{+^saq#s|4o 41+JmxùOP#~S%{ELClΞ*)5uxQ}]zd57o|C1<"*+NmI WN.C:c2 h6)%FYоXO(ܷ2UoWI8hJVTZRo|c@;5.[]WѝQA ԁr!x/T5O[X{a^wr+akmܪ=QrnSΣ{25 OP˸^S%4a]zR2zd^9›V=I7J8 /cN1&||ghMWNtH7I>-u;;-ZX{e&@ m^7Dq}PAQ"a刚 3 B*yY $(U9WRSr(z5Cc!7y KCc24f$-ˈӹ&Ȍʴjgo+*~m?*ǣiDb'ҕ)E15F3_9 @\>`wN0G::Cĭq> l9xZy4?}W"fR.hm(hd_`1?_"FmʵPa_HըoȂ H0+W450oҮ&e#G:ˆ C(Iqq8(J ˡsϮ'|L[%@?~gY_%.?` 2O+]sO ]aaKWU?,{߳/H៴~(xD4*Kae8w!bۯZ@]SyTD2EvHE@E6U|PT\oTkFpS^Qf ڙY ^{t<|ik/0@0slmtqK?Pp]._)[e;? RCճ_Ch?%4ڇZF[%j*x_OasAU ~KCI@ut/"mlBt.aBqT_%CrڰNno\ljYf 2{q]2@}#uzǂ9L7cŹbdLǵ[ Ho`,~?L>ޟ.;-K67k DmPS{'9|蠥+(93vh(3xJw]#A = b :uJ)d3og 9kU’M@<$d;FLUT{v/3ozgxbjQl`ӽE};ZPC`v0a4?JxDK-d燠v$v;Swb)='.Eu}9v' kn%p֔! ~4fBu'v>;ǛR`z`9Ճ|8J)ЩɓB::1Ģ1!,f<Fɵ`HiT@ h>x2_y 4H2ojhNAe TzVlq-UH(bСDIX0>|-?Q4S R <ПóOS՟Sqi6=\c|R>qk;\]ȌmU6rj1+!8[R`~l M2=qK%Bw_s> ToLd-$-WEmBy G*g;oéE#Aj&(C5&R -)7惟tn%R͟dC<&K"-1*-6g~"h fq(P"E4s~ƕh,V5 * xbjkR!_/#Cն Z4x@cX^SȼdR8E95H{wץ\WmL֨q"τFui$sT<~T/*cޝY1?HbU!YnmѼ^2Osì:T^FN= ,J[o& .0fl/V4 &~(@cA=eOGB&S)}ypzeh4upw?0ذjK]y:l⩇qPh+Fp}/Z&иN7 QQ(nPowF+t38k# O"}$Pm/eЩ?0B2 0kg]1Vqz ͰYH(b~zZNjYc{a{,lBITeqwODRtx~!Ҕ#g?PӲrE㝩6-'/d}.ǥ\IK( `DzdDheQu$gG $77;%enY*z1ԯ V)#LI"0I\-AYzQ Y0D8ӷ^NF1@ۂ?ZLD'=iS=nGgu _P`,Sv2 jY'2Tӈ}poUxmuZeld0) K([$ GZG>cEA_fQjYqMzNWL12Je%f53ÅaM00Ņotnq"]9anU40dJ\/,p=&GR_-x xѣcYOf@rYZ` %AoM!?v>#%u-n{WNT؋p8+zA[??G/%_RH^U B63 qP8^.8e~q% :^P0-O<8+u&PK(ԇo6SЌ1ভJҚg^Vł( x nIz֞ I$(Q䂂moy6ӧhmIl .7 j+Rgr&y'{˞)2sTDҽQ~:H+InST( z[p˖ߗ+]Ϣ9pUδk⡄nj^2=s~!NV v'_R2qnkW{^MEP\wJE\u3*{C6Tzہ)V)BbCk:-'h-vAp8@@LHvz榚Z?p? a?;VEћ"XևN6A!0}U)=h>i{1oNX0@Y?+ Xp:qz77}Vv f þZ~C'YZ_LEL2b2<{~Y b-aݸk^:!پ`y79a#;4sIa:wfͫIs7#<".]D*7vⲝ:Ffsҷbp)F2ZĄηcloHMT@oHRv+ÇoniPd81fʎVl$0h=8QCޚ-pVw-LHnj!aNAqV ]LaSA)JB#ܽ_Q>J\6Wu`,!,K8੠6؍~Z_N,S%4ʱ59Km.ֲ*)q#M~D 5@[_HӬX։)]]>nl lĐ, ܽ;#$ %*tOg۰(3کNBpXu[ b+ ~JUg֖ݟcwo37h⸷⬤ܬ+|pS FㅩFgʝ}1uI+"^NQ*}BlIv'"-6\t[@@ ik/!]^L6sd02>ܠ1Po&N֮ H ݆I$PbG4X=[IM:>-RpptEׁP^4Q3hRLvΒ(GhoN JlHn͈Meθz04-%י̗hK/m<D^CZh3ŸN0Yx"NՌ*hh tF<1m*LZn[P+7X;@YB PVbM&Ҝq=ٿC] ! 4u ATu܁`E떥#DYgzoϬ9)p ښ%߮Ah7ښ?@2*YPĬ +(UV^rÏ8.ms~R,aa4lh9 ū_k۬ZDXo-o|%#4,:tl]愶NߡP#j7YeF ъf+dKqpg!e*"]f˦<'T ww#bIdf㐆DЄh95E:FZcOH0amXO{&Ÿ3r ( Od8Qj߮Vk~AsH> %{kcsλmGk| Hy`Vr15#)1B{^RiZA;+~glc [3¥_!w(d }(qe3.%.+|nmsIb}|HuH X*_/L)dCDIgʌ3b U#7n%TT!zÿy?[PX]6.U!nfM>Z\zVmkZaRpw –~[ d-DAքf:e1 i #?Bm*a6/ ˜SXlʄ z`׊?X?J'7C/nbr/n tߨp4#%Eij3QWG8.G2r f[VY+F0 εS;/Zإg?HI~<ŮX2 F)̑נM)myE/ɟ0.(:5(.}<_<2GCݏ1)u5߷gpJ~]zk9TO8ZJкW8+#VB p$ȭ2% =-=Phڍp&Q-ZRisLk䛋< EBnHuZp>GOZ1JkhsC#'_J]MW@ q%՘l!0|Ճ-Lt$w#\Q$}UWQH8O) g:$.abtx\QՍ.ݦә; L#|C 蜥5f.ABD;z,,;!Oي˚Ս>U?qV0a7~dCB9#epog}[Vfp{@E\wl5>aB|C[?X&[mrQwոF-+ (JUQ[و܊i/j_OA/wo,-H!G@%ׅD w/P jӓ")͕"z݀pdMٗ3m1j&A#, W_WLN-_~\8ubm47?!rيu=ZZv ꧫ!GNta=+M9\-i]ƌ( ,cӷGU*)zl@U\5-xT_]ӉѰFkZ-H{5ࡻP^ o풑KzvXoln* ׸?ԂTElD)| '_gPmOq|-!]7c:U.f"Z`\&C0pVjȶR!}.8:􃆖)/G`+|2eE̴ ] X""' `\wްLQ4R۰q;4OCB@DpU~9ql6OC~`esifW ~=L-ވU> ;CMr ;>w--Ej58nVsj 9q|:H$N ǀY5CZ")pr"F> k2T6Z#u@Db@>$8$e2yn~y!eu /GJ}?(z@wB^uCk.^wYRjcxH#X:7+0D_ߏcᓐn]7pFc%Нv; ~T)&Ι,e|e"(;otCTyM"j^$>yݨ:[^spww> _w>~3KnjrhD#G S?q]=6?4gtlCHyUhY]>ʢn$vd|&( J?GA~=vvH}n#7 y NvQ%PJ76*v"W]5[m٨|KŠ9.滕 dT*o>;օ_|w0?3Qp}˝}+n27uh a`F[ܟS,f̬ )&vVn_i5 ,44!A<|/+!vYص'ˠii8ܼIBR|UB>>~np_DyOƫy>>Tdr!?Q4팸giⵣy<;KLtI.mkHW♤%?Q %{\Q>[D4Ȥ iPS{99q zU|A/9 qÀ 1Pwү)K}Gr0 #ړIS .;0He!J}J=/G[!4 Rt8|@n25[|1h_n|̔ŋ^)d_Qr},u j,ABM wQuͩSd& jxV {F]Xԩ?ĆRXkJzMܺHEnN1| NhZM:؄ olN {zDbYVOt314, I=uyJ^lEAއA[tF,Y.M.R0w OShzc{--ƆzE8 xDقp̅&SZpԵBV#IQ1w(j. jW)IYe z> ׄ64/{8ʑ)w~V? l/M9A =H5*Ϩ<:ȳ&,KlGq;h٢(C_֪љͺ,Q,9\G!2h//;!7llo>bqӎ +rJ]"$Ng:}B1G24!/:nB* yG) F>ز9+Nt}JY%s*.0iXxǘ.6`3 ~8%XV26I&ž(PiSO ,bꑀ=D|."m@*jP 1|/8[\du Gߠ" r._){sBsGX^E.o/VvrP.$,GƧ6:.$|<ѷlr~B5AL?({GI $>PEtI%gly%|"Rr(Q?|V,2x(u4caz%<* *IiB@zZiZG{c.s 0cvKQhwʇ;B.~tQ bGtQy17#l &LX!8Z#;|D>jb}D%e#!Lzd( ۫:s c5QJGDʠW9K͊߷&n,&^F]7jAmEERÕV^߶aOU"#+B5""ю'N@%*_VǺ-au{؄Uh2.bCY/8D=?u|)]@wCwT8zh"viSc }:cZ8mAQĢWຽ rM EQVC\oZIv=`"lb3#uhbDj C1EOv9B)iLyIbq7.n1;ڌIjb&>'-XxW U(X_I2UQ\; W7; piH>Xiv`lԗIBmk{6:\nIl[i__//XЄWW#PSPhwɿF&飦MKQM*)J3pAw `#CW)fq&BduLiJFgʾ:^֔4op$W˵[DoηmVr&ǨSFjwfbBbRy`+vlH\_ 0k{uif##CS@oN%;:XjaQ<= zW%˂ FI0 C ZovP3wxlEV8 fG's[gsC#St0}ݙ[7 bFYz7[>V~A 9wKKTbX>zll>S\>6 ᫀl񳬖_FSaII0EiM=c E8V{9#Zg0F3S} Ԙto TWlstaS¦ΐe TI (OT\bgKf6yxc9C86`vߤ߂d4sɱ21zlsFIXN!4 _N%Q!g@EQj%=vr C"?D\#0; Qp"œ_ePk؞5(Nif Qau}]m7i!L1f1M(n_jߟ꧰Fz;ûdkλ`N6R27Asg+~IRE5ac7WHۗ0堂c +%ڰMG/uZPjCxHb6djVBϡ8݁mBG#P) r6q<Kk?* g7lkFb'7^xOmT֔)'>l_K@r\Wˮ tE1KeE͜QH辪>ZDWL j=%\ԨEPl[4c^9'|V=i*:m:NOe9zŞ|LIj*qlX͈A8 %Lo3;}5m9{dBRUXTZ X8\~e3#@g?EeM/WR7ߎ]IEdA=lr }tFU.$m95AWc caSP:vC_bW:J@&}*ܱ0pT8[^Nssr{ja8sكXW޺!ӓzOpRX"D=$.}UVoߠTBJ2K&GR䑇6] 5F%x˼M:]F:V}G .&&2I#7hgDt[5 Uӂ\stM_} 5L( y`atEJc;0-ZJ Jt` Z*!8lRj~KKC/.!X` A|Eߐ^8crׄg GEU\ ;Oz%xHMf)YZj3Rj OHn|\;ӐIA/hW<* f*WFUsTWwh41R[fJ~`hdn)20_q==_!)9?+o3*!@8bö8u 뿕|/c>HI#K"m)t=1m6ĞN}ҬTȮ*F4}iTaYTXf]u9ٰ1v_|mL \{^znL]\BX~*Z6*8 Hȕ W&uB3hJViɆⓜ@Np!*" SpxC}I?vEϲv\Bmh7^0?NDY$KsA)dk:C*җ[70Qp<ё IO[50}jZf@ddB`p3#(<ZP^A HX(ac)ZvFʭѮ>lyH+]gۗDXvSa'lbԿ0 䗲<'-*c}@A rQ@djB0bH\v|&O{Y47I?.+B?o/Ol0 7@چhrL._d$;4JxIPWy;Xg4~Q /4 4(*RP_G`ލl#!>}?Yy+T_a `0<ɪɢ 󓏳FMO6DJ5h7a,ׁRYJ}mu{.ycr/>!f^Pb%2?h*͎=?g N| y"0W0:x74|7ipkU#)i9'QPTn7)16]j\kNCJjZyV6E&_bS|=0mX)OIJ 4y.xinw@Ҕs+zIl^-Z(+>Qm~BvߛpFe~촑FF[P2<ferPj?*-+? RM`=L}CHU] xpD9zbyiP:X?!^\wL0妨. v# ԕk#ut}(gQ9@xG'Pc5Zns-4|B=BZꆼ,Zo*,o i9 $eq/N%>un%mt ^[kڟ~ gV1mDr=|)A>Os?Pd h 4wIyH!HBS:K||q&^(QY^NFA!Y 0~u5nn 4L(Lc91f+3'*p~n_\D7.' Ecz\ 7D`D_NL >;Y "$_ vc?@9_PU|_!тmUzz/S'2D3SXP 쀛ݙ)&Q|q ̉G/s16";fC-R?V $U)Mï-ɅYƾ;Pb#u5o'VOw_k*'ShGMsTb$A3%s^󍠙,Zr룖 0X`A^^;kj LR9<$ӥ%BPKRު^{;8~ %d(ӣVCx8{ &它sxU{V ?1?"KKg%Ė}DQ8}`&܈ec8Vu܈~|C{EBvnemj 1 <*T=SC^ݽpw0ݑz?uT1ͮ?kdT(!$Hm]> 1Ŝ!U~TU#-;tbIf.!bYb<ޘt,9^@+r.f?xy dFwdxDx&oaaN\zL'bbAr!ԫ0١>JjXs'pR@wޟ4©n&H^oxdrUWSuxY9X'e56Le4qɿu-IV&a$dg ;b|+pO俙-w g(oaN`{]S`(]nLlFZWKx9)kɓ8Ȓ;I~)h8N NraY$Sغ'bډ(gM"\ (\G0*!:}}[cF ` (=bo2.C{@CS<>baPrCk< e62n+}N'YhoIV䙐6h \2"n+܈bJUPژ![.ނB% @]7gsɰ3dfAcB w-E_5NZՎJRd RUϨPn|6$"һP(\ sn $tں~wT3sl|,c§2L\Pyf˼ hnf1Cz0 IަG8qj't8$DO"_P =ȕxL3a|a@.MaۢUD2K[HF|{ f pza&qUzʟGG=P*>gcBLKvts+m/M R(M4ܲHYx -viw1ul3Idԩߜn@ (f( yGbZX Lҥ3(*3UsP&^W}7d`0iq#mZ/;@Liꓽ?`zŀgێK:eDrI.lrk"tBI|3G?=T  DjL$FX<m!?E5Õq /~1nsu}psY0SPGAwL'`%Kq6mc՚z{d[z]r|{ה֧Cn aoA۬v3z._MvؙڿAeP4L%D {: kCβ>z։8i\0" AB4cA rn3eHm %.x=74~O_԰(]jc)ʧ=WNZ!/jm(RXww. ;cCA+JPzTm9#ئRijhzCzPב}:džMGIzɧ5^gu4vi*V]0?m|+J*n)'ӊJ 0I;Qs^g(*hWKA“/ިP3QaV~<BWs=fyzd-NRDf0VmnONąy@긇M`W_ 8p o|Vu+ 9e:4,yfZ;~ xADLʘ+nT I-3e7G՝+?9usl?8SvM\b$꽤lcTbiôRI!>o++ȼ]BVך@ϳ|~4~zұ2ZN P~X |MxoXޖjP ?yppZcy*|c$Q`߉Yus:y"#5nld1e#OK3q^T.KRߓ~qLnb 4Gz(RZX+/U,=]  "K6jUf+ ^Ŀ02guPHXB0j#FU}?י^w/-SOd,zGSʍcYA%o`N S ך|ZHp8y-h U4w p"ezyY865uwxd OalMY j>7S~L<{8wjnUwX*krSO?M":yN'.#%NnSˣ3G1{H)xJ  G8ͣ"Ein8v!fV:ܢz% & @Ia0vyAW1el6gtσIEV@V'$/\ϫe :<< 5ԣN]_%R02ʤ2ǽ<>ȇ(1rmg{92Ea7tΪSo,184ae0D9IaF6ɈmF hֆ+p;aMQ*qK/ pBeY&uVSLa>tCKRK;PBPm HI 'q_+O6a&5_5o;cִV9a*>;;" 9nٝ(9N| !sΆMVX bxrn%ޜ&d/^bFL@f$ a$N? OXŖ[JŨfF.K,D֗;/"@ JL|ְ JY&DKmD?{ >nC\lɛc5GȪؠ脡7g厪v4Ij.1eZ&k ľ^D0} !s[o6,\^Q+Dfulm`htFaDC_O[bvNGOc|tW|Tg5mP b]M$pEi&Eoč^V]%~*(*7bdPzr\'j =g>H;/֤?N%R'$G&׷yM`sE1ÀcOZp6g^ܤ. 9ͥ;:8~v4-u!g=`6C|J |3j ]jj&IF>`]gFIӘ"hMث!A8Fe,ʁABx (t Tv| 1|<'s+)zݖeS ef1-"GB@:_}Jw~%X=B~.qGPd|VatF xdP \0gF KȗQKPGq6-:ZdD>^cDg &D (70kR-D]3\{v}Cc:a?0G$Ah4_u }ĭjyq]jt+v\[~-:;Fo^EG,LjK(?v*9 a}~;gߚD刊azYLz*(-#VMb_{t偹T3Ä)ufxGq4OKҢ~&@1Dd).r@C>?\> ~&L'_*h8(Q7m2NQB[7Ϫ*z{xt_<(?0i1!I}|eOO68Oo}-?W·YP9P`S}-#΁6e[pkF;!.ðIi\ɤ/9 XL! CA-Y^T-f_O < FEyJF1b/1 @t^ҜbL 'Y rM6{r6CON@`v˜yШd1w[ϊ_'59 '`AE,G װP"|3B n?xQ%/謷O!El- 'cӨ A,%Ky*̎1آ]xK^;M V(&8h*Hr*pq«%ݿI֥ uB}e偒k{Wxޠ43/ImcXg?Wzl앺VI2p/`AaΘr 7Wg61>zQVe4%- NǜGTw<%ޱM5&% >=)z|W@Io.b˂2^!YR{ zÙC/A rvq'#HR6CZqUbslEcP f Rkpqt(T5B/\KS|3kNâѺ˩;-?j-=al *4{vbwNP S*DlkJiZue)"UV*qY}~L|UtF (,L@e@_XĈ @ɜMR|lAw遾vݷ^/-̠-ߟx] *+!x+c-hE"\ $?iLW:(}{O?/5U k R1Ͻt[Y^c|e>!g}J0h1iv1dvp"Su~Rnǹuv]lgv3LMy Z+ /MiwF9]ƚCM}0sTLD*Ѷ'Gk.Ok[몫%e[9HLXzsɛ=x `4d}蕋"~ yp\|v2jF} |' yҘ07\`X^2L29{[5`M9kQm$"!-. #6#'IG:PP̰]p](SP;{jQdD~ #mk[|,ER8JruH7)̧\$@Jp>(.AP ;:57u!>g\l\dl}hij&ODT+eO(Wm(O=&jt8縚X? %3]{2hh`n>߉i[&ӉC{:=!ҶHm:`m z^Zb_.~j 9@}`*dazPW55Qs)qVuMA4_ĵjy@$ txteMpYw!K.hV/¸Y&DJȃ3~l=Ca` pҗqMC }wPli{ź|/iw+@Hi0X"7anY_L'UBl0A5Λqk]ދE.,Yr5Hx{=W|W5}Õ]~n4PE Ǝ55>Q;uӨuPV@X+5)i&|6j@ o ~1jC*t6-ZKzL9u[8uj*OKfJy0or-G "(" v)LUJ]-|Rcj\M,MK{]~Gcsv} T>l}fƒݱjoE4'I3EN(YDlItz'zOp~P,7 0Z"4;`UQŹiN$_)}L=%wɅr͞pTbbtšoBxf+$4 |h>fyd5AyAjY ^  s>~'ZkG@"䰜5#|xW1r/Y/ iUW fԍy 52)0X*]۽ "Oڲ5{iҭXZ=|E 2_DŽW.问wݳ'hDC'S" p|Bwu2E$\QLLpkr]҂""8#ߴ'!T' [NP>ZfYp)#d;kU {u+ ;c/Nv~+0 u^bw*nA"awX4d#Qkݘka81O[蠌mĵS:+KS} m̹ib8sVſ93xFƒ #u̷~pO08AX,vP9K?[EDCV_VxiHeʺ6 &&}1_wpEQEAE,G B@Y{pjbYoނ0>h @ 5=9C1|5:jAC'f+|ު$S-nڵ"t6ȫq+MZbl">z?'pA,ʷ;pOV4gI[xgAiE#Ç?]K_L̛T$XmUۯ>2'H{{}HopWK=4g;5 Uwuuنk< tU W8VhlQg$D$ D/kM!ސ7tY(dV'^RH!VPHV='<%.5(ϯ\X^Ks+ةʾ#͒⫆D/.w-cV 7 ӵd 4n0isz@֬&̇^ \&6\_7%K=tF (,2órlmtA -|(:PS+Cc}~P7elgSKPM.'RLЖ7_̳v} =-$ahܬX8MA*" \}@qnGNRjY#␣\\ {1KVMCٚeQhU{`roH$aEP5*,[ = Kz7*v%1JGصahz:HSg.<?Dg P,@ Ɋ@D(>yT ʞ_;ƪڋN3SFt`[FAM)6FClae쇐kLU|V GNn*ܼ"ol?dYu"Gd8jQz p7?$?i H+эXA.H;x0[pDY&Uj@ 9{6kRd9}n/G >_$b̂pkC>)G# QXD؃VzʲXyQ,.=28, Bm"%aʐh6^݂xoIwCӠ54}ٖnڧxSo߇olv7ZAdcDSqt9x 6?6zeYk@efg+\@&XUwԞLE&XN79y5&Dܧ 8_|]zjMSw@ 9^58y|W*tg|Z :&aA4_ĵjy@$ fe%C{|( VJA(k^E3 -̇\h7BNؖeNu BS:&qaH{ "MY"H ^?>C7Eq#msߓ a^տW}G$EVr=yNVq7~?è$?5g a5)8i)|cJRKQ' hG|/-q J6^|EdNf"$ۮDD1tEi_t|ၪ? XQ.w t_'jS!I Fnu5XHe`f<'{sa+)!}2yْ?]&i\0C])nl5eR/&ޟ9CZAHmQCޕS>y0b x iΑǝgݪwh Wjz )h.{DNvς`1mɦsMޚ%D#G^真>kULr+I&H?&]+Zx^Kג~%=9#k/ʽA5jW!Vعq{TN͋Vڒ&Qys̠ ` $P'ZyݱOVv ).vJAJH9kl qk_`p|ӏ_z-Vt eZ| :ݓ?So^[Kfa0hXXsd} Jbw8)t/i\W4 0o͹H5f:F#zYD 3II[?S2u9X't2/UZ5e ?k|ݽSw !msOׇ%-64ɧ nڱԝ,e/V=~1BւDm4q]ޠ^ɒEUUMKۦV+ȺqaLb,}vzwR,~aMϪX'~b8`4yADe ~Ługܿ>TAbD_d\L]PW*3G@ۭ' ꔎzAd`UX)b|Ov(, c6/$BVJp1È3[3CZn}Zs:bf#T}[QkpZ/ٞ؅w>D:ށry k+A8dedOCíʫwFFXAE,G ѿkm IG:#[7A] A{*uxT08({I"G#r(E@4Ʀ>{~7y5\ήM[۲k")WTVt/as KYBc B4ƨT;βJ$ lfW\a:x+_ p(V< ;Oy̿j;TO!KT4ٛEF8pp.,7:~L\$j>~H`EhI$> v=`VjQqu]>S<xuaJ\]vBkQ4mbS^p6AAdCˁn\&;&#sEYddU7^"ށu-tF (,f<_lQ)q\ǜ3+cyVǮ(O7jẈE$_U g)lCST*Gl)<} BI 뫀M?lU@i1쎕3 ~G"; tQ,neKάP}A͈0;=']M)T5b9h%\{56FŮ4 M>|Z{TPkWuߊIMefȐtg1C.,&djg%:1Uc c _+^t֜HP#tsu%.y;m|$A]R+&h/Dg P,@8@GTq_rxízX0)W [ʰv$`3CdE8kнt7|b_)ug}T wuGc";x)dt알mC/q*t/hW3EwqDEHi 5Q;G' _%5D/=J2ղIBåF> \c10{TA&E&)h@]˨k ߟFf⣒ݬ$0DCIJtz^Rw J7FrQWn9;pQ`W~!g izIU:ecp47h0NBޭ,8mq}r>hBo ;Ax4_ĵjy@$ xR?~ 2~Z 4ZGe>1s&M+agbAꝈ♣_qU3[Tq!>fGyVF +KG{>lOdwvͅ}@ԓodO;n{H;;f,==k#v<0.` .Y7hYfŝL#邰L0$0VRo4Ll.`j]iGFnYLx}Gј&_2,lmiti1nق]:_(dH9+F:f5guхraaCmg=8(K=曫]zٺj-UDcUKvqfzڴ:ْDklD3hWc y\Q3>3RI\QB >mWaL<c|p;ݣ7hJ['@kZ0aQn&,CNYK3kZ#eKP:8x//:3CBiaA8vǦk`55ZC/5 T$)UX.*>/;[%/s+Ң6)-'x[$O֟^Ǜ*[sRC8`¨)ّo%_{[0_ tOttUS[-XVXV,T}LNe)BBV' 7u$/u(I;+o#'z“XȰ c)6 Q*m`z ޗWS#Š?qy%- Fg OgWri|pHݱ/)/~T Br:c%!6/=TbMx1 sꄱW[Svv$ZiZ9btBYevG5Y=IlTω=`[Qt'k}]mP_&}8lyw'fօע;+/$*N!M:x W38Ec*/'~ )2AzZ] pY QTFTǃwq|1RaUz/PF.k?%W,%aALUXSHǷta(gh{!;l־ =zhWy&Y;5IٟZ^i>|FBo.KU٘N&@;m@yUysU;<5@۲)Ks?U(fivBM jj'@'K 0r16y!O;pMׄӫ.}7QV}uַ h7slq ǃ}E3 cf֓M7Z[J'ysjL (2Uqƌoqv@AE,G (q6u@q] @7}}39.j/w f6QǴat1a/7˭Hef}2{rIZK7}Zmo[I*๘$dljcz2:Gq=fx:VxA] 2~=RmMJ/T(-:A>TsT)TntF xƦގeZD'[(z"ڂp &?˻. -Km+cD-T Wmk=G9hwMJx݆ Bu!$xkA 74 +)=/X`lVq$y{ir5rdѺW`Lr=il@T % "l؏ϴrU3lNGg{:x}d:TlzàQ0L L.τ!b[[Tܾ(GrߣǪ6ljM23 >z~Cu صAA`%92onqwQƷST+¬AHSFcuMԢN<Ȕkψ2pr,T\'Vo"WyX`4$>{Nj"5XOyX}:qxjÜcd#V2R'<;x z pRTT̤a%[Es%K]`[媝&G ar6j:L_3X;V?P+&ڍhg303>CN17ėO'D%r]ƀ;vf*D|YЄ+a2|(q>=FRs4rL嶳A^K$}h`JjX"TÏ" 5!o^]  BAE,G װP;_-00߮#]x C6fEyCn 5eC6'"E5,V_2P=Fj#@y8:Z6i6]l߮, _sAmEBdf$tF (,L@ ã?/(, V3׶V]?]kr:2`ђ3]<ٳB)2%:+wn05\sӲ#'^9W湢tVr٢鶯PDDg (i-Ox+| *9*g'53ʅ !kA4_ĵjy@$dwŕ/zz'mv,tx* г@H*|@fp=`4AE,G B@Y>P8=tF (,2órpA/?Dg P,@ OA$4_ĵjy@$-x@47< Py:ɓd4ABE,G ѿkm IG[6atF (,f#/cDg P,@ HAh4_ĵjy@$-x@VLp2AE,G [̎Ҩ*6tF (,L@2Dg (ك&9P*PA4_ĵjy@$-xR)ڬUe0H8bR M5AE,G (q6u@Q/tF xe@-Dg &D  7A4_u }-n3Tjt,al55Fmc~/UZ2̳v9,yBKZQ˘@/1DQHJNw!'2Ac#$y3P%>.)2A~Ndx٪~U,SX{3èCG:d~ȓ3q’Y_rݯNΞsSIO}}`Q~+{ ?`oQR/2Rؑ*Y}H2Pg9芛?4H,@u Y!G\5Gxu~hs\)(n/\5Z6W煱"Y@NFTmVI"_>_Q\ *pbt=GD1NL=Py72գbVK38"xn1rL %iqETW|v*)6bG|t}&HRR@e$8 g_ ГsAȜ%֘=S)&)$,A=UhHP~N|E2~7Iw0ZJ߮՞[g[ 3}b}d̯Np .'>'=DQ摕51U4*vq" p)GXL`7##5HjXgBMvjWٔKא,/.$Sݭ7̃So>6ͼiYJ",i!\{ *%܈>$U O齥.4rI"bۏo hX`x..ÍpE tzkxRQ.f.3{n(O8qu \hXx .3Ӣrdh$Y OfY7JVDL\7b,pa7/5ݛ(ta~Ki'\&a ys:vi_d&y}m5{9I=i,v}JAI )^ 6H+?5|{Tl#|kma)eMOBّv03F3muWD`J &17`jaCR:5n!6?7c޵ _P,mpbڶg42gp+Ӟ\C_߭A׮i9id%ߓZP-˙:"G#Q2NSgc)S.-Y9Co7[wKa~j3@\:`2k0Hʄ1$}y_E6[{lFM9ڰcËݔC %3vFPc'|x8 z V{gq`RQf' Vy# `T 5~YwF- ]$?bӍJ Wބ z4Y_|IWd<]|MTfap@AE,G װP uL*~.8 ɢ `2 .ڙ1Vu˞=yR[/_ 壥DMwʸ ?L柊=r^ ұ>!0qˠ0)U0-0o̥}.FXoohr}6 c/-tF (,L@vwy"CʿmΠL4Dyl+ ߤ8|Rb3Ƞi&{;iΫgK`=0:.RHް-SM1Jc2iMR(3 $F:jإ2h{/Dg (i-Oxy~aM 2#;u@SZޔvY_ԕDM&l+6"LR#;3AݤW)꿢9jw $8ΧŇ@Q+CqKܴcDY )n~/,x]z4əxEn~36^ƜhYD .J%fOzgRA8V.}*rGp\H|I:PXufc s.V{3YOLܯpШH-mZvqn<9&!t&`LQ&4C/0l1z `̎ ڧMmdZ츽x-glI鉜iVh пaIIV?u@{0 A44_ĵjy@$>"ߠʦTÉWpȸov3>nZmq|س99o8HڽY AEC.07 6!Vٿ3GJ A~ G0ŏ 1ruG;@2l{;qvM;?KKh&9qr.0"'iG Z}uUبc/,,c7N3&J$G^4 +PSrлl!@LW"U,? 2ʨnwG8UKfGB,"rWnX:,AZ!`"kћJ2jy  "_;EVx<9n !K?e 4Ye ߧ0acC߾=>J-Ly0}g";6 . 3*i&=}P=7Pg& @X,OO;Ym zA##' Κśq8mU=Lg*.m{\= Z^~pG ]39nA/M)q fo8)|veDMʭUރ?)3MX Y=GDUO눛ޔݲ*AǢ3幖R&Nu=pi>e,_[,U°>̽ssI 9TY^b)?cy;;2f15Ƌ%M78뒗Cut,ڼFBx5_MjmI$AR$G1TG oH/ &,#%Tlն4{_[f"_!tx^)_$}r9iwV˓jZU҇?yeู&&nr*IS S}IPWO) >ARE,G B@Y|< uॼ㉷h/h!g[ީ9J I$AL峮V)Lo6wA)8ӝ)ڞ!09R&~vfQY#~x XU6(~yĄO+650kF~$k@Mrb}S'T*0XRr߆~gYq+W.=v%axCK7g @S'|,m_ ݯ"oPAoM$/Q&C9]~vf|z2n_M5׈ EGbMk<'8zU DI^88yYr1V25ysk(;(ޣn;Xht=*.g[쬜U$(Nb>D ֜Wh'wgAflĩK:1HɧZu@y8St'3kMеYy). xzHjmE,VedD[$mgbpJ!h-*+}|Do WsX\kiAOTe(f'p{92ʀsDg P,@rKUBr ba򀷯j[W|3I!OkpRV3:/ʴSS UH W-no_du" l&&!Ϻz$5̃"%Cv:xIQ]IDW?bRnjf9s5asWd%_H9󼁎G9HwԶN֘"-ȇz~[8cAx4_ĵjy@$ uBҰ f/x̡5؂KvԶncG`brlr9cn.0n߼JX9Z㵱06\*?전hcR'lUp4O掿^V;&f0AuFϣ/%շ*BBmі$ft<PP_.m##b C 9l)yw}_mȐIAt>Lc T쾿Q1eZ&xZDPO91펩8u r mY*ڏtw4bsijʅQPg% QcpT.ލ(ln :gN]kb Vq !:D+]=QNGhveK<zz*[x $ܫQ%w@8Jͭ!R°kPZmj,=$xw*.>\וCi%~`# @om>Rvvjy$@`2-,`;ws$IuK* pJ4WVMBߺOt>EEͣ+HyόBFrj_{r N͆1?Ou/&HmBLs R!".HOESVzgy`zk͕,=#7(,tM*7Z*M !v}ox:m{\d6iM2gO_ DېJ㟾l ӾX-6q귫'QZnu+)ZksAK7_@)isUxUN䶦}Ȼ?S0.,|'ߚa$l2?ѵ=kfdWL%ƥI\ lp:h.Q]4H2i? 3 jNma<[Nzccu!_a/{p(bwNcl'-_=EkLʑ \hLݺ~ȮYZi-^vwr0=Dj0XJ8_`hEбVD_*U a9Qm[z\;/pX8tCW\xI+WR.$U*r$?H,bgg#/5פֲ|ί\)J;_uJ%q=~_-^8ֱEIT)Pe &6VDlʃ*_oiu2ə{avY) ;"}JcVRŏcq掁Y7)M2czu0_ٍE fq4>-K0|SN2کPF6PA~9`B1;:?,}t awMg /EyʶmMȊcT0"ڢӌ4!g݄#>;wa-G*-ى>zJX XAl螣Y/G(rP l۽3;B`S:uTPg6IicAԽrVLʢR>؜H@qBf}6a"Oew˽tL趫[~(#'˟)y>R-M Dƒ5 WHD0tͰ G4oҿlayIŗ)עHftc`)RЈ,`_1M?޼OɎ oL3lgTi.~&l@NwE MZoN׺AF<8ioXP^ @dAz5[?0AE,G ѿkm IG9NX{2@n ,B) WTc5X!?%b.9Ax]+tTgjT]2A ڣB!RM `@ws\p|j_K *SSqX"9h@>yhXޛo+W'\) _Gػ$B acxw^*0%+QT7'`F7f 0{h%.bHfpAe`d]I U嬠.tk[o{vuaLY#< 3 8Ao9ya1H!-㟬J:)J6 kakj!j©4cIO|:3ƺ5j̾m\Q@LtMmp|Adk96[rarY}/?%+R,&ZL!eNBF65;_ %F/S{GNIc|KдRa^-r)P6xtGcHN& T:.E*E;yֆ/12?n| H߃{-PCG6/cgǁقZt^A](;C.=6 H=3g7AS9C_dAMKh]R$JGO0){te'n#$ѨF ؘ!o}j~a)_TaraމqV 79]ԅVgtRP h9s;^gtn֏+rԢ Z0h'Ҫ@?<:CfOx/'*w6yg:rc3ݬ#G+Ph!/ݨǏϬpM"5dRW(HF:x "F هY-0fH`"Ͱ }fBs 5O{i)oT&hZ;˙ԣH?vq)Brdfg'شYRD:0>tdpUa2xVܠ!#a*]zG@>$SA)?c֪&N'~›Y=_5XQ[`3}}2Xg)`)*ׅ{pW>)rƘ^a0V|bk,}+(򌟑oW`Vm(Dg P,@CJCBHeN[[*NWKո6H Q]zV oYk/,.>Z6iJ=i?vbr$^P [,i㊝h&\D}#fw.)'e޽,1q܃1|ϿtW>y? %֡,Xz!Lj#Ҫ~&k2:-tH"cswA4_ĵjy@$ zu/ Bs N=`ֱ>`=ql(#x1sWUuW k"1\2fdrar2`qA'ڞz A$^R"enDIu6V4(*VU)B_.^\^ I 971D&0eBFKƗSBt{h'-Hb+D.2N| !)RxzPOeXmi# CآyXOW7Tftv oLz +xYa(z6߯|p 6nx9E͔rP䞠|$ =\kjᣖ^c* j/՗[c2ĴmZKTtTV0A('ZL1pCꉟC_NO7  eTmƔy]N 1_W"0&`0eE4yWC;U6O s\h 'psYώi^o3 gix$E Wu:2p4)pIa/uފUex{:oW^)'%LH;G]V(R0#sh*L9tKW_yy,,yU*1.଍?is|Q}eFZ.9Hll=_o>+'(h^if&D`K~(tF}Sƿ-([#àIՙv<d[F>IwD14$|nHzT9![]Guߠw7x^5W8'Cm˳e^Y' {z!`G{1*x zz]ƾܙB j7Iu4hP]㘴a<>{*zia cx+(.쵖CmZZ;cfI_(q2DYLIH<Vsd{gö~rn:nSCb6:bp߀gM.oZdDs@]MAE,G [̎Ҩ,- 3lp $/j?we%GЇ|GȺ'n-]phc`,Q FxMP4&#B GJ%A4j{ONK84LÀY,[\l`[I>t $ƭO?q!{2[wʨ#!S[dr2vvXHG³q@H 7Y/S @llHI$=Y`9JAgZ{M,dxF*'l=9J`*V XWi"kI7º!GgXVN(Lv`NkG Q!zR:S{(~%BQ5p7n3H~N=öUu]4 #IFŮS4jNsD28O]Vr7A@Srr{ScSI~$w.% W@O>5ǎ'%Դԝ\!ov{B!Zx2]jv,xw+8lM+cz*{ˑ tEAlh|nB6(O{f( l%"!iԗ~HB'qtMOȅ] G*E@gIGh8l:a"M_"gX+ l P!"(Ԅc7ɸm 4[$ wTChY'w8BA,"(԰}3NAh_Y ^ߎ;I~"TotQ$F22G JkU#Cb[(Ft4:V?VQAg辻FR܌^p; l z,I -[ZxGxtRnam+J[TS0Rvgp\rSڭs~W2F;=(O$#UHĥWؠD<#J YZ Y4X?Z\)}7)1xH^5 {(AjFDQPO{7z1 N屟m“)? |([1R?@W?+1˞a3Xw(Xo>q2F|zlaz& :k2t QZ`V\s,WgVtPi+#l6zcI1&<A#hRID!2Mn1F+fg]6cwר#kjqX*ZztK.%uSdNx|.1²Rc4Oj55^ :~Jyo_ _781ؘwO]\gߘ4po "׌k+eZ8^;=x= &{o-Z@?]Qz?rn3=@\.cԀ/=tF x `r@g?Dg &D Hfv=YS|_l/H* \ F:[oa@|эpow!yq9grt_ AՄ"oYVsVD7lvجt=2$$nPdݗEeN#PULgK#;%)_!( @e;D.ڣ' zOz^}AvX~'&CVվ.9F9b[֭&NbJ Jg˖ɫ+)H}rrQ3ss5*_5> ijx !VM5=PǢ-#9ۤo~FU=k Xl6 hw`MrMH<@Qnkl8)πvĸ-)7tb }u][cQ#[ ƨLMbQMT+4:U% EZ3ABE,G װP].3LosXsX8jl4SaL@30(C*_'Ke#1/{hs+CqEUYRx O%BY8}8Άx~7[HSv٥yۗ;phVA,A B/ZfiS TPM$:?ȉ&H0PF0ۡVO"Co`VMUaUupK@W9He׀N XU޿DBԑ1ﺕn'`]MQ!d%5۲nl-ML6-F>a4^GǞc^͎~Rrϯ`ջ8&Ԫ96~4jfZ߲,n vQBt|, P#GwRTˠT.ȼGbYv>y:dYV?7o@~cLpߺx!]K1()ʟEFF>[E& e99C"o5/:Yu z%%-DW  atF (,L@poGestWVޖ$)ͨ,hxuS:8+.K'Pi?o\>]T29m~iL'dnþiBWӇTū|:R'Ǭn s'HezK&K|ٱz짜oe ^ƨWo!&MWhmH=ʸC@/X/yTv'jut|&uͥwF6Ÿ8:-\Om? zUx3+hOe?$/f u):B3b7J`YՋ9O㖶zNp3dy '9ԣIb jMM06y:'*I!H0JO5^ 9/ ?zRheC7SVJr븲wbM8#f[.?2-sP zD˸X#AGTfB¶eh cDg (i-Ox#0e Qrݼhe\pLR;& 9Vp'O2W :vHmdJ"UDf~׋S~˼^5XT8H dҭi|ߋ{'V*˜hl+TpZ=C vNb TLKz\柾{ߍN<%a'Wq"X,ER$h<#sKgT.M>M]Gwv&Ɂ Ό,[B {Hbf5q j$)\ ):(f*S l/dpr`61妺b 3[}uԬpQ , `$HG }7(>B0FT),PSyd=[tю?RFB8Ř|{oAh4_ĵjy@$J)_N&h|(\q(yxty/=~T64hKpNk~~s/}n6=4[>%wC&OjwoBF{p;X ًhX.z^*w6w$1)'pX5\?q7.qgi\Ɋ+D:K2a2DH;zCi͈3sS3]1km3o#NI;j3KTh!WWa\74J)<39}PT[7 Lq@6H{jLq#y`~9@]Ϭ<-kb7$D%1,#= ләHG $*tۮ_vQjS3EDCU`v˷%.46YZg2Z7N_߳}kyq}a`efa@RRc xD QYϻQ:Z@7C^v ],SebkgOyä-Pj4E3QO1CfyԀޟH!K^?56uzq!Qӛb_I.|&NrV5͑R N*Uj?&IS6j|(يTG8wdoX9bv>]d'[Jr,Kx@&/0[Z;U͛#aуK\f~LJr@x %OqKmBCŹմ{D6вi`і;}d T):`)\V쎧Rf~e_LPLX`,¸.Ch ^}_!7y=Ut 䇽4n8cYB!ݶͿ?#D,.pPuw"14 [GȢ.a dgn ^pI0Q0hIdϻwWOU.-m믘]nȅ֮h 0Wt|Qb((K3*gF>Ԭ0AE,G B@YIiTV7t~4:R6/<` ` ўh t(x mz +Ƙ *ݸԶXc,HcJh&?iUY r!y2< Z|"`f֢Hp2G!{y&N(3bˑCu~'uj㭑T7zk!XIaEZJXefD=NoGIbDUW~n)gNf\}HqE9Som6f-8WeuH2~;v'w~r?lGsj7|q&T<8E j";{_OOy\Kc3AI8S.uTip}|)m|26%E ! eo'dc3|prġb`$lεkW%iĜG=S ")hzDט#}3v0+>Dz`h˾efEW`fҲ~l52A&ϖ^AUA[k2bACK_.{%\>L:T?dVXN}kp"}ldmB[d,bSx+=AZ %]gȇ^|J+{T'bW(~Ýo <)@mӱktXa1:ѫcr+׀F[HtF (,2órpO2@EHT"@`]=Ns#)bmo ,d=* N^3HŷD0nM_e8GWePby.wr)0.kTq&ZeAhDǮ>ˉ(;4~ Qa#2.ކd=-/7[kTF4¤B =F]v;f .tm .ҁ$ p/NEDwKNdkJLeP">S׭P_B^4TdqMUeH*P `o,(e-6&F&ӾSic[V,#Z%f,ܻj[y6ErωN0ZM:@+vWƼ :vy~VDkj7o&\G;Ui2\.KlՍ++* UFBJ-R Is|J߷>2 3J_/*% Yi-Xy#HB6t!AC:o!^+E3SHq(QTDUõjZMNޒr@ڏzIe*f8/E[z KUvw,ԄH\l9!5*&?[RLk pXo[p+p2TCFZn߷Osh4& 1uNE A4_ĵjy@$ x -&_VN9+@P0I2f<^gIǢڕa'ۘ#f sWQކa+ /Y|:>]j) D'E3iH|2?^mP`Hq;]-0B"8>5V{s{~wקk]$knPfkbOZi (ʚ rOcYj h^ܖl:\~wĻ!3\%~ ΩYjTB ѭrp n,Jj-iZ]ځI쁊|uv!GS|7 :|d-\B>Ȕ[<[' MtY O2/+]o"r`j.I%9vAzx4/ _t4皧M~'5oF{P7`BRULLS|ڋ-H8j,yIl׋ ݲ>U"q71.`?|P7sy5T /\D=\rZJ{4K-|0v^OAg$C@-~2:8ޠW2MvpR:f|.x+E3RǬqRPwdn.}&Mɐ\ > Ō@ M`;c'Q/PϫV8P aЭ hQeo9܆gd0%y_1ftNߏڍݠ[''EI⚊hqQOGWD)A<lq)QJLܯ%2ޯr"Uux '#VKsʢB/NeqJʑjR}4v'FVA[vRIeP{h6xXߺG&~Z$89*TQW롳kr AQH~YVt.#TcB.Έw.IGRۏiOejwl?8g''^Ob𖿵C}7*Ͻ=:l[}鐀  '' vd0˕V)xgخe7s9FR^)C ]PFL #`UTc;q1tox:XgjDGTA\īUaD_4 OySYzS(Z((66Sr"+A5&j(ی ÒI γ pOX`iJR`9AQkx>j)N?&2D@\rj>Zيm' ̧bMMMe̿冀cpCk,'1u2`.PIXaz̝6y)^~-H{;4n<\*)_Fzl.xy0+I =GRG3@g&VM Xκv^Eލ :G g'l`tf%"qX X\1~bɭ׳A@A4_ĵjy@$GV!^lS鸵;%8~ eA"!$or Tq% T{IKwؚ ]<.;9UYAhJ eX:R8ZkgV~S,AIbqo q{?c\~2MZ\ 8S21/ հTݬ,6MD`>]k8+ W@LxTTs,pnipEP5v(Hܴ)h/M~OfzQ'§ ID("K~ԦWT4:;iǘRv"=Lqx!쟮TosȘbiLŞVhE2d E *'6+ =2yD!J!k&D${jnJ]00d=: 88TD7 ߢuh8>'kƴZ~W71yNTm}t ȟa6`VixwL QƟQ$[?܀]p]f|]6 ToG'ˏQ;IB_.FҒaY;@Q8Y*lj:Qq#^&Y\ HAE,G [̎Ҩ|kړZڳk^?%P \o#SKuN  -tF (,L@޸ 3*5޵wI9"x]@e''O*JW1&U^U) R I .xE[?׿\C-j }}kooN 0s1*=~A2/Dg (ك&9P<0[A44_ĵjy@$d!R ˰Ӷy#HiP5=.5ARE,G (q6u@Q/qtF xe@-sDg &D  ZAx4_u }-nVe 6[/TbE(fZ)IR}T|L!m+6Vz am6"2=Sc(- LT!G}!!?[!rJ"DȟLCvL$IhspnZiOrԉa0 n5u)C {_"|ӳLrgI~ ߥǩ-ExJ@wؔHǯDXTg摒2N/dKC ʦJrOn~' &*8"cê}J*;%Q4!2N/{j.WgSHde5 C+[wgTSI }6qt75ˡigdG?©F]5|_M?KxjOr1sI+f4 *ٵbzzTUu 2p.)@Yi.pE+aϲOͷXUTy1(|+D|*q_[1e`rMYA">4ua-OV\XP M2N]C\ܻcMx`wyhQM 3"7 gW "[݈Ŕ& "XmAҨ٦^ ^N?fmJ4?x12/"x#UGoLǵD6Yȓ賛_eWL1ǂ_dvsfPYf6{ޡd<<yi_y! L}s8kZ_Hbp \ _Wb m0+^AEIM83޵!I^y&lsc5(9E kVp%F SWwJFbJt?)shm(_Vi.nDVWj=S0- hgE;*n Ѵ>ˉ{cpf<3^|rpJZuƤ'($yJbk%#}UV5Q\s~hv/v.DuU7iLpg&mL,n#mTKd`2iV쾆ZP/mq"s brz}/ _ֺHiˁ>yܼ k/8)|7!œM% 'u/) t=k^tDz#C=S%cmgܣ~oqWM5rRH8/ ⢑]m9./!^k:ˡs ';=nWJVO'~v>QT&/?4@9doI<:B3)e$,k<;M63u5<0Сg[b Lc⇒G2s}rҮ ɃIahdJCvQt uGE`ܦ˸yѴ'3Wq0yaUf0Jٽ4\iOYb 3چ&Vv=֟B6,JS&~xT2u:V^`:+ł-|Y&omhnSM_@Vjr,v5F_oIPiymtܶ|`{`e5PjO1pg3YYih(h>Qo"BD"!>qVU+[{#M0˾D֣1AqB0{~j|YN:%ΤYQحw\=nC=QGr[ZhsaLzʶeu/ޔQծ6$8~YuAiylh!xքUe]`;˺^dR,bx^DW`Zc !#L]O*w=xi'و _:D$kZ <`{ 16.X]{%nuu9۾ Yh-l׊roe\B3-#ᅍ^iêknw-ZrjdkZ,)3Y]SyRo =`ytx"1Z`E@eA,r8|~˔;^lẘ~`';r|Nu7`(y1%ɼHw+@wׄkLq'ow7d@TV=2~؜q2f5O7G#qg 9;07ו7'/a3S$!ȿ-S6H?"jzy8^׮:#9ȒɎQV`7ɚ~_Vw8tZ*|^o#ҷJZNMJ)}>911u,1ΌjO/1H~if G\~ Gxk ?翭;t"!ۨtSu! {_7Qjm|Un陀?nHJS0ҲlAE,G װP u̲ÝmlG^2ŢVn2h#] \0SDG3pr]"-<[7`gE-CF9 ~mtZxt3) X HkR rvD" etW7:F{6sd"` `Qg_p<!цGtF (,L@SQVb?&eP@:Dg (i-Ox $2w9f%#sh |L_jiǤJ.7 f#arqn1?3(LwYD?k!Zƃ+(A4_ĵjy04&!̓peMEc)`z \zկFCPLRX鱀ǙyR1԰/u|ڡfR }t'@a:pLȃAHidjL+ILw+=ң;&Y;PuZᒇNH-RUO^tyTWӫÄO1Db ڋdDĩvfDїU>q ~1&q=oEn1긧FQ{K"Ž'nAE,G B@YL+@`($xiGisOI밢9o]Y8h#ixY)wczГ-pISdIR#~zlD?ˠE=w6D~i= f6+*㸭!s.@[\ \)۟R| A~ U-6'o$,{ ^ac-3_@h|Ɯ: BɹS7O/{Bq 0Ct6M} !w t<2^Dp@5_v'3µbo(M=6y,|OIĭ'l88z6WWmx|*Xʣ¤zBW_$X‡jC.Ȫp X4koα*=6 rk'ԀVtF (,2órhO[P!f e۸S0q|Dg P,@C5u[@,,`$9x\ۦk.}gyZؽ )Ș)4e :H9ASb %7ӴI‰  =;Z3֊W':'T ]uZ#+mp{Koċ_sKÕdLҥC9ɺ|&7eԶ830ڵ猞%7U/Ce?$?Sf|WK`hUyQbX,H(xV}E,8V9ʔcugOԹ@ja< 5JqHZ?h |kiQ)ۦJl:^O Udt(3#Pr@䞌9B/O8ΑTx]τ"r $A4_ĵjy0:` wԳT; _{IDYOU(/s!k#{u9§ 8hăT kR7n-hV ,WpOYyP5Ûټa ]5)h6_c|BQO Н,TwcٶʀAE,G ѿkm IGX-JAS"{袦e} _h@ϫnY2k ,IVAYze< Ғ(toxXI#+wm5r aN}VPTwmvpVo# \1dܪu33AϢ.@)Z\DPywk5:e}glBVemtw v['Xp~K 5A/ lG5G:xϴz#wK~aQȏǡ>e0cI~L:6&+>άOQg)nj37iC$b;@K>=DST]h0k=tF (,fL[|nЫ;Y)1eEQ]OcPg?ʧ0iǔs(FոH4ZW) E] 5;-&)?`XIҝ\ <<(F׃Lq_ Y^r~ H.FܜpT~v'ŊV, E5Weٹ6=LeO@c# Ll!/-Y'᳅ R@DE!u ;( %ooIXdLdX BJBbȯ5iWg &[V/CZzBR?Dg P,@>B8 NS' 9] Q/@lݨNqR¼:l)+N} :5T.?/SzҦa4^iReǧ~DO3g Wɜ\, "emA~pm‡Pa_3XZIf`bI|[A$4';=ʺv4 `j(] NG*w^V0E+l؏9{Np{~F{yi J޾U3l 5_.h=~2Gk^-,eUW{b@:Į[W ?pӻ[vztT}fI1 tu\Zျ@QJia=`F! B%%!4ťޤO\Wd=IƖžT;Ĝp<-C1'@WlCAL%0FP?S_*4BhO+K4wwk٦Z `J/іzux@2#A >3I_!!-iy`}^-./hAv+6Y|S20W .aq_v(^z1˹+ ?Hi-a쎎XQ#rCX;Y^\ 7b{ߡQ%E{X悯q0N[ Fi} e;XaV0'Ã<\L&35]ٰT\e1=ۨ% &1on#~ wv4@DIy*i"E KW>vLn\$AJES;f{w(ie#VtP*}DE|R2ᕇxNGC"!qOb+鎭@8:s{`.hEWRe?N͖~60sFn'Y_Jn+42^TɘBH;E!~j, 2_)ٔ~ ʭ];nx7{r9G1i[ 5OMД9`'S ;T- \ߖ0'kvbQG0 {aUܓ;@TuUN2P_ۍV\eZS6 X;Щqņ?2RԺjeкH2ηVWAmB9 ]ət=9Ď~s&ތ/K?!6><7靰V1u>[l:.ڊ bTK-hb_yaxA>n8^vüd 8c%EHJP\XiPTl7.H,C'Nctg @j4fi1!N#Jp);i85W0QuRi&OVwxl;.I &&5H)}{rEyP`dOZ^Sg@ ?ouʏgV *=K\RklPz(om%Yrt5i%f=xPu J> 5rR`_JȲH/$ƅNu]-uj7*C9 sad9&;̙4ߤ.@љ'7JSd56X3H8%ͱc RqaŠefp8IrUQSK.ձ3J;"'ѽm!L~)1"BlTU?7,ɇ Y#!F"$32euc8<$p4=bnފFjE~lKA@cwˌrOBQ^ѫ4Pˁ>j 7  ABE,G [̎Ҩ#uQ7%WeR U y%~j15MV.9M 5v| 28䟔a"FVҫr24ћtN&@8k#~IL"ƣhKlmgqmcR9 `( ݌H#T8G:t~fS?ϖbq3%K@;Ӳ՟-`B٧}@ԼAΎ⤾X #PX?!X&gj2M6anXs~枣gz"I7s\F3z*竆rN%!f+(?w m7n.F53DF uV_렝qrD)f\,vq7-K6W&Dz:ދn[˸@;Ejk`c5N>]'75szZu3ϑDy Qk^+$Ωue+Z5Wcl掣iп5IuK+Qeėہ5iTLۋR_dpQWd'%vZL-j"{eS*|(8ua&}u%cfJ&ԌdN}ș +jWKUm+ځ0޵@J&^D! H JˊoOe'0+fJوwo#C+%,ސyX@%+,2~*!gq.3>9!J|rI B~)$`Krʩ8\{Y1O^>nXHe=HI(%3:6pB¶=My>ee;ϔjteX}Ϗ[8:AB.sq=ף}e8 &U4$!'_OYxXk ݦ.>z:rKAX#ׄQQjΩMN>_=m6I,W,h_OmI] "z ᷽7Rl]'+l1"ԇ_9Cݏƞ=g;Ǜj ~p1S {8RxQ'+kltI]W )JJq(F*@pU@4V_xH}DS6Pu+nI*@c˨8-\)!t*#W公R!X5\,/CЉT~]=aAe4_ĵj0wKs1~Vf(+"[R?Ҹ9L7R =8h 4:Bxd=#{r (۶KHMZ mS9Z7јy&W^a$6 KO=^mjAhuPHۚ:ϓ@ ޴p7}k"^[Gc.o  l6=Co#`oyăOM7p+K 8%5gt×=S%qrǦCG)6cU ]ofPَONKe0œg;0 =b ?B}tR]ȖY/hOi. u"%P<Jx;+v1S`w/^9vwPO'=V+0T3*u0S${>9Ȭ$b{Owr2VMX^X6qmyHR:mqJ( ?n 7YK8ѽ0 U./lc&^nj,VO _BP3=0}#'!){^04w5sYx;l-5î50cnhxش޳"Qս$hr#Vc۬t#s^=At(]wGXF{ka=ڵ,>l˳'4!zaP}Hy#͟fK3XSnAC'ao7׊%]$NqaeO.V7Ҿ}SH3-46%_o$toP4RᄀhBLcӣCqb >'6ԾcL=mƔ?)O͉lI #>cU 4%cm/p?~Fy!G%N"l! Ӑݩ9b~@J`#ťެXCp|A=ĵj8Dt>))8W/2fTG chXD?\Ëq.)X|)Ti,$W):x'x:YԺyn+,ī4zg(d!SߐIji $C}oiT&6$'"f%fDR=$pM+5j=$FJ5E&Eо|F  =2v)Ȉo)8g5c@㉩yotgxJ,%> {H}> E(`E U ;6JەdM龻kYbǢIwՏЀn/_8N4)n mbHdt>Q657߽!S '!rO|vR+C$ws4݁^buJH}&/l5> 8߆>,JxM{2=@YWő m)#>+91-_lI Qϳ˾XmofmCA|MT_5Dgԅ:U>3ՙxğUm ޜi{E@YFsz.x7>u}'*q_O ,Ȅcy= Х$RP8Sp][VzN*,/A$6XDZqd&ᣎ %kD0߻c҆ix5J S'x'S⒃\zj7O+vF~C@ju{ޛ1qw:2Ϧ9'\¨l01r5B:Z0.\$Èh<`񖗖GTٚRrg #ˤ{wWjZRi;Hޞ *P+'X`Q]Pia(baι_]*E߀Է?Y]e$Yb-s]0>u[UrAG%D_$c[S_{LDž9K>y=&πyg2o@Y 0 F яzҀԒVv},+Ѝ!t+c %%==jx*+_uIO9/RL\mAD)ksE\ifb3w]0NAE4LG (t Tv|  E8")5БֱZJM~FKߡ #U! &C><i){KN+Nx۔jkP?T纥 mfp )d*UrKLҁŎ7'D5둝D25Ji:[Vq't pbLN}OJsT OU&/! {T*'8;ѽlAJ-E6#`gɍߨ\ s}rvZ\v~瀡2%W͊lg.hoJ f9w H$dEQx#@"}+kmxx -`MtF x ] F)`-}?Q$iiڿe=S\4Yk&iU4}Bݓҁ@ MRzN>bgzu(f3Ȃ;" e+OG=3&Ig DWR> B gƝ0Dg &D lT )F+п^,0e sz i͇Y/ c)1b˧TbCRǭ*t X|lXI+Z^όH)7n"O ?#]~Yu0 L4EŠ s2;0>lX_jYC0=(#x}?6Lrn)i'M $̵r/XODrfT;zs!*18JU.FF4P4/˞^HoJ96:¢Ϩu/<8?Dž$>&jDGӔG%vI'u(dXI]֒#kʩr{/tr9KWXNXTeR68hXQBV]{r<+, *OnJ%B*WHDⰪTe0xY\x&#z_ۼ<ŧ\JtwnHPFT,=5!SAE,G װPJ|XE{r47]!.yU* n^vB tF (,L@6x+hkX`oj\1 Dg (i-OxP ]A4_ĵj8D x}db )ҕ'1ݽA}zCYg~\j ݦC%\7•88{V.9="|,O~ ׼ݲVS}T3Shq)X?؍ ;@{OR_M#OX(| IoV)(]e2sGMz]{,3Þ /IFݜ{)/wE)!^.NJ~IoD CMlTDXjdZ)/"՜g!̖e zdM,ĩ-ǁ;X;ˈ` l[ݰoGgomzJ;ǏV#hpفVm_&L"ɨV&WhwpG;>R-Ǒ3*;UBqܨ;:^gX3D5RJeH armRRfGcwJfЯex; Ϛ;;\q;)\}f{Y]J1b/Jnc)uy{OP˔l4B[r[4$n*8upYv ۷;m5>b*(ֺ%cfqJ跳d Tҁ^U,ЈvT 8xz|XC%)y\V-"r5hA1Pw hcɺU[)-h\@d4 0\9r`$R)fTdL5.[@+"֨,tߵäoX4P4E'I%P]h8L{%|'~dg'vr> lQ}7%ULF$EF? KܔFWkb rDȃ9JcGp""k,6 kچzsOJ9=û~ƫ$aT #VL JqYBo_ϡn=}>j8E#1Q!mp~b]Sh! 0DWtE EXI+lQF"9$cr_WT󏝭T>80jqo5eh3?%Q)wӴt/[%ER~|DJmVmL.ye)èw&wd*_j/=.ҺY_?\_ՠ[Ntٞ" dR`u.<5o輶D~ r^o4pS+R\ςG!~ I Dؑ_GO)wVAw:S@Z;i.E#]=s:qCȚ@h|A̍ ߖ(&I72(?ݑf;:@#;-I W>#]o/VR?d䁀 Kv8 VL'FC@)9(G^^_9CAU6߈mLu;+3_zwRolA_6[jcrw?-0ٹsR:;`ؤs$$Ǐw[ z kBZ;z&'8A:Z&4^Em^Q |Nt Yk5DӖ #5ɼ)l94yB>V41i Bfi_ajF]pn公^JL֎oZې(@-@9nj{c 0kw@]IO1E8UC#7.m1Ca PY{]?0`Ϊ6K0/+ 7yQ8C"%yµp/iDM"쌱IU2@_tpm kC2w ̤OǨm0nyJ. E|pˀ\W:vv$~eśNzXl-b,sN9~I8EddP-YU)lGE˂šE޼ < y(6FwZd>"n+#/""n etjO-s˵l(r }\tCЁ'Phl~2޴OS^I3s{{ԑgKִ9:c ܚ1Kiu;#GHrF74\[|.4N@?X,&7x6Rg! zB ?UE@$sc:9}45A(K٠Bb{_C+}bb̅fueQVQyx!J/tcy9zB&}m =>`n߾%9Z $6|nJ 5M?ুU6Ϡ^ގ`4+#D T6Ù&ޜO@*TY ?,JIuU)AUZf\>H2YC5h {f{'uOx6Z):rd+UoqL6ߊ2X4[e2n89$ٌfI.٘?߿BS}LVX7IZ*퉴401o,~]G4>oRQV3?Wx$<Q|%i2\QQQm۝)a 㰮d= /@>sK' s{Lՙ 4 Σ"FE,=>( u LR z{1u/BrHvlYLN{DsQ xvX]iSMדyɞR=VWw;KCxy¶ΉqmĴ=ֲZڌ!t{SeiW]^F[@5"#BRJkugtZV0LeWH39*Vr&tB&wmJQOlLBaa8}17eEvK^X5V?ڲZyQQZ0bcq&T̆O,>mnMh@` uKdCH?E/Ђrw~95ԱA9qgS.P#SSÎu9%?*|ψ5<+Q KMP5FHJ|sH氄qW7lqj1ݩSSVe+h~D}%kf bKVe}7f>9}"5NNtF x?H5Ejp*ӷ{)N i3=˸^#,HPDg &D  %*~2X(_h|%Vy~XMNZS+L՝1gStӪW)aDkXeA7pZ< hAU4_u }- ┠5܋G.Khag7bT3[-E [:";8M Z*$H<8 'R* n:RĽbb0t k#P[Y6ѧzlOu5w%~ SY^$gԃ! cYHuOH];r(eEl:Y u~k}vl,)q D3:{u )QRur )#+"glGݕ pCmjFOj^ ٫΍]%m{AZ{ Yy4ϐS%g7CqYKoYGUc h(G Q_Q,E\0 4&ATT1j'-;hUk/xNd[P7}9&럴5df48W:dṕCAsE,G װP:?I3 1rHoCBA##^(kSa)+5lC\O<~,]ܾxXDNDS&E:L?])\txASh$\`M4AL p$e#$__XoQA/?_n#1K?E_nB&}9 &BRH:\iJ Lnd >VLy@IebQws"_RVI<Y<a K;FU:Wa"]:M+ |j{_WM?yM_s @Y^=Vt7][q?}Bv7l=bJ)A$!.\MıB+ "5& e&ީsF~n)c,V^Т6|zo%H2d:aw'8o cZk!4;W Dg P,@t~lORF3hn49ȳ[>fd( *o0_A9m1 qʂye;ZhW-\y>2.`wNY\mfR?=Ԅ}f߹@!!QYJ%Z+YkRSw0#b- -QUɹ";=$" tϺ-S?}B[gɪt™j| 2 7^CMl'3px.W^R%RE?b]x,Ov.U6WȠG*!z=NuEøN5۟@ )J$r1C`492PS@U<,~)UT^1~:3Iw8 xH)2p~Jx4I*yÉNw+zSJӒ؃"! |K6>[pM; 3m5m/u)GܵG>ˇ*Zx.KI73.8)~Zk$ m-_g"/Ҍv'x_pTi/5QJ:FhWĝʗ5@sjF}7?, sQw ^^pͻ4Pb؉eG] vMv64TH[$͹c8:,EJU8{Ö%n.f*TV$y[S&E=_D6䗾NuJ-%H,AE,G (ogmy,&0EcAş8cZnys"YbPpa`; `4U\t@"bQjo3m_ʬ2`;u.ܶvi?2?DJ =Y+%Qnau[Jʔvp+"t6T۫ꟈλ'cDՠ+>?H0JxQQbKƠX\/_i4']/3g*Gq~.$b[b_M &BkC pFD ^G |Jpsk+]}q%ƢGS]Ma5-PB;EJk9`1+tF xR*OmMczMb]NZHE?#N׳4hm3auOo#c #M{vT>= eo&ZcɶXHUQ278Ҝ*thH' .6maR=3rGYĉ-,loӾ.σsF8cve:aDg &D  'RGhf$IfD^$Kǒ29Yݙt/%Rt(H/,Թ\v#|:ON'tW7 BJ/+/Ax@o/Ŷӌ}~ 7$J0p{&5`(F31l_|xfW܈2֣+Ut2e &GͧuLZya9{  7k9ޒ9sQB}3 }>[_CJ}8(#BSez)r8@DRjYHX4 [i? y:y6d[K`Lq\[mH2Zg8ԆᲉq۬@.>BC2橤6VZhq鯻%/[־&i I,Ӥh.G#Sױ\ FMGQ@3PQԖK%nI^lnCD俞_߇_wr&)Gu@枛H}u/RP-F%ЭCU;:NjAGj⋹͌8P4*5 VFI]IYr֗ᙤslp19+N+JWos-̗cht ^q'rϫ"7=;* T'adD~YE ˿LlJ= )WO˥-\q42v_U9.s V&~SQaQYI~ږ7!S%2h8Ю)䞯O7Noy@edVz o]DPLoSʨ$HZE ?US4?$w ^`d~pMr7-;8/5ND(dp n(&|eh1"TŪ$fgA (7x0;\c'eLWq"{ T"酘> O_c~f %mlh"?SmHأ8L>$ b7x SZE֧dз'tzA YrgP% 1=?6;)2ذ 'V<"5XU?_> Ӭu%5F&)9d.ِ`[-qcy oC\KZ`PT^P#&<4~SQJ͏&I*0(Tzt}d-Iޥ8=po"~zgBtyŐ Ͳψ_`73 ӡnpÁQSbZ=yЊNAAr'X+P7.4*@@{n'izR@*0= HWD;vJq\R},;'gh*ӻH]|pty^Rz,lZK h][fwrm;Ewf.`媀 PxH?% f=dm4~iu< G..8`ox~1i{hղ"qk[IȚEMN4k"L/=X~FGB|*1\|@ʄ+b5G iT,g{fmx\[A9; iTk* `^okwNdϓ$ ˬ1"+3 "b_Ă>Gp ˂Y›@͉b>a^u }:J_dtmf4ݡ,64߹ bGe ͛&K' ۢxfwin=m lwbN\(gŶ?N4 FczWd b~)3OUz ˹_3GZug-O S<}H܊VLSJ衊C͎AwxEkT><*7:ȬɄoqi"g+߫/oPpwk+-ko_M':,pLqQo`< >hݘ:xT0)!KV|}gR J\21lDHne+H8@tc&)cx/XGgMzD%|@d[JCLP, $2y7?-)C8"@* H^?Ik,~qq6cMgnm } `ϳiyȟ&*4tv`xJ\5g^Wf[1ؒ7vq T2 7!%+ kѐJ3K4W>k*{J(ŸuF5 z cJcqz8;SiV0I׏c\m-q7Oj?hKdsuHns&c<,Uˊ C肜?„A)Guo6ۏheY ;zѵ[^?kz(H [wH/f4W6x}ݚap3*_I$&Ϛ_5^͹(TJٓW!lM`j_pbr9V9s4K)^(:|ַ/r;sm*ޗi*T7*\ְU#I)0:dZUlc'Lh{mGOiQ]Hi3IBJibk@}4\/kEdNݳ>]ǗXiuOǤjY3 ;݅."^o/~!7y&u;k })q?WSƱq]eB5yP >wY |F u:/$|u\P\eucJNj&@E!#)3kb^yL7[IfG.<߫RZJ#3T2#PpV?M}XK 0% ToKaR&ZVY9; qT79W_tH}>`i>s`'1%LdR;L;0τDJmZwYU5V?ҧz2 u!UUz]֤GC=wfW+4Gg_QO]%F.mu:n6蜁1c0Bx.7װm!LkXdUTAE,G װP,俷(e`["lq ?kg6Tz|y>xj%,; iTćgYOJ9hpVf>ʉ4rq⿋)eNTJ7,&˂۵l#qE 6`#|t&{IKb¨YhtI9PAzN{5(?TI̛0zrFl&$'i0vy.ok }z_ǔ>vdh͐ϑ} pta$_gyѯeb/ujJ hbsVh-I)W:l!WZ׆aчjJ4~PS<ݰz%8'HK? K@"2cn5zM&4.7H˵L^ȵc5Ie5P5@DsPrD*dEx[?w^vZi e3Km+2fę܂))vj<4 |`)՞}vAΖ~WyL~1=VCb1VR1^HGIp)trXFC i p ߾Kic.ٺFvӯsh[ĉ)bP;V/*<>Dꅗb䊁 %N9XkQu1* Bh Hg۬1Vwx-,l<@\37H1xMU1{-*D'B=lyXiqk{z'Svs.v{‚0؉gLJ\ʾa ֩sdRoN{XyqIe0cYbJ!0TuM%LR> Bb,5jM:j1[{taC|(2SQ&1{'(rZso /3<( Eo2xYfZOr󄟫>ڵM8~H8BM$']`s^h{?xx^cB2!HN%f}@SISZĔs3kpV^|11%=3 ^jWrˎ`]6!z6+F`dT8vg.2ܷε9q`[ϵ6S7 GȏsXy ,t#>J=0- 0L+.ӧe!\~:1]W$N1RҀTmwMm0Ld"6m%PB7SľD)1֟]repz(\<,?pf`}Mu>]5ɋ T&G.8Hz*^ xbza.w8~|B;' yI1ޚF$ jpZ͈IP6B7OTۥWl~J }Dg P,@;+qiC 8}r \\7v?VO1yhOO4Ӓ?6mx}{68.ɡp6pSih'.p⚐3zV2C1jr2ZVD eGH#bvI j8g'Ihm h; X{H鴠Î ܼ _s+4LK$JTmc!G:j)W~:WjɼF'z 6ĎO6뻣Z;I>vss3C5VMF)@>#U>AgrI(>^X Y P 5_\{s{ RAAC/c=mM. 4A4';=ʺtD;^)]ıQs=2UXq3фfG﬽ U'ޢ%:ׅ _z4qҳvdޔ]nq$sR6s#ZJL=q8p%DIhԬsLm蟻}$1kJaHr>,oR?xY/)Ec:8"z s qi ,`[ViS#Όs#Zb!Z$օe,Ę~&PM״xLA+j<}5RnΫq%1$B#ko$g;fݒPHO0jېRG7*dP[/JS8ߢ9bݎ"s8iA;sWKt{d'f'Y%>E?"np/J⥍CDouրH"%2DcIrp-!nE (c[,צTzʤɹ 50V}g[UuQUf<,"]w5" j ~a|ϝi12v/\U@jDёËR}Dy>w {>j0zLq&mK"C|4 ı<|V&|JNLx1ԞU:M[2V 6eyeE ɂi,"rroadv2BsO8χKԫƈܖ oi>FEgA40|"G=A[Ed63ruHvLKeCӑx2DuH+kxX Kq*y+~,?nJ%%t$_+Ut?! QjdYhW:VBPoi >$P~2 1vH_iR툤 tOܳ'U=QfmHoej5B;3]NETm ?H-Pڬ0h(Wd +Uޯ C߽M9cRtФ̐UXnͯ-S80gEŦ'.joD0`1- )!SpSb¨Z#JN _ժiFLA(nz-YO 9C #,nh3R,yQ+D<7xwLBRIVVh6GrX=RC߱@QZh\-jBpV&{=Tdsd= 6814CهoD=, ˛DԞ@E k{!$)sL9 ?\ExnEb*-:26rY 05^dG@ɉz<9poi7,] ؓ%#tn?YA_SRca5۩_Aȑ@>o;ijGHZF*waR7 _W a-ϴZN)GL“Ga ĺ/$8]0#T9l癕YP~G*:Sb5IA134 "PUT#{,mS` yݓ%܂%d>P<@x4vۿ8>tg_z5۽% Ľω'K!9yVKbao[e׶. 'Md $``SNi >(t$c&gu!8Y}a[jY72~4.RHTUuhB,:U:-2&Iw6~l>&|mPm`ĶH s>_j6sFi?࣓TLc !12I{/2sc "ڇ *K*uߢVu =hQMkVgro'^ 5}H+|QkmNp< ,g,{҂mg~0^:A?E,G (ogmy,3tsB<,qL&ұUn*"Pyp䓒S$;߮x0`js"Е9τ:krw>E""xCTT,Բ',܈r'77hWĠ]mkȵ;Lg  ,r- Jl6-/".: o+ZokmMx!>{]0Ȣ]Ð*lo`̦J|3u4/?SQ3d2*?J6`i][ս߇Ia6Ҁr[t{pY'ժe`agfog+s´<3XbIΠajȼ,xs!;0&O WyM}C?=m{ZK]Ȣ45+0x\yp46%RѤpŎ|YuG9SD&"WoB;aMCz"#/RPFaf'%~ >~ltCp3wpg ÀPӉ'C/"(c>v@2F6mQw?+PuGpKƢG~psGܣ^dF[L&!Ͻ_6yCR~&\BLthz8 U][?48Pٺ=t}ݓ'p{=r~/tǵ/ Tt3W[ JW6oN_h/9LM6zuQ %~0!5bk#8Vc}ikڌ'r+pPߟW=+" ǩq,I T/MǏm!T[ v#06鲑S=ސ%y>^A IAC4‰c>Z+93DXo& {=PLYgYg@o31\dnr- (:}p^J /- .9@',HNєf!xibul-¨fQԼV SQ$cp3x5Yz8+@PI< aJ)%(P`~w4΃X]pbབ'c;(:;m)aSB@{A==GiŁK euh2:0Em7_$!m%کqnp9#ȁX:d 9༇D ^cIj0л+gk:ACD4il{"(XESl=:ĵ4::Ȑ{[% CH=}5H$|s+a#w, |̦xEJm%&GCXV ֩O[ɼ|+|\n;ӽղ4 ]N҄ /tVd}sW1X, ST*ØfYX<t$S5=M#[;h٪ v)]%FZj* rJ4|,IóK/,5<շ|^~wGg3 ֟ ԢV`]|}9O%vj 2_VBv0LڳB dxuq{R_ⱮQOF]^D]2\C;^zmЉCZ/୊J.Ty @Ϥx \uH PѼM}1 {ArhtDn6]l5(I3̘ ZN6;X꘳SԄ N]dv$2n*-*VF@6i'cCabHeLg;BF@"b]xg`?i%r[X='0B#9aϮUe<X&3%,(k\=o*V{D*Waf-ZUr0(z6v^^:=LF%:egYz Sܺ- M(}uHPG\P_bm r:a/7SfSnZ]APN5pg)0l6# 6vji:7 5D~.G-CieO ^lj4y4$p~K!ͩ(;KZvvINO6uςlg1DLrI_豈 8K1+/ˆ)Z-> lPh׹b`G`a E 1y[zwvW)"5T b<50u #o"Z==>8ӗsFN]SɛHLO:fK<[ 6gXD䱜HA ,o}c}+ 8VǾ}`/ԔODu1nvE}pz)Z#2Y0J 2Vࠊ n ;'xLŭvm~>+聸6ll& 5l$RAg= 7 "MNh@Zŀ<1#.Nm=MtUTG~uFƔ+ѻHzKa(ƙP"%LƿV1e-H)B:I밝X+~6QJ5(cH1] (ya7(N[PzO#BuAv #OBٸKi^QYqI 4Gl3&u#mu  fX* 2ҪCs&\%jV!0V A[utsD+biRie(J fH>Sݛo 2*;,]ny$~&W\n>ΗS=2d"zس-~ 6.v\BABvT #u L{[OtqF5y|Qle[IKPBT S;yzlW)uN$;GS7W@ |ne?Q7hPD镈U(Pmw2t ^$#/ \ZR5{PMfFG-.4 Ԯ<1-0ˎm*iqAq\[V [QZAM0!mNKFXȁOP`AAE4LG !)L @5c`Kd#xCbTc:S 5:tm,J$ ^<)d_߬^%nK".QmGE) w.~#sjc)"iM ·QS˽-ɥ ~0F0v:jR|Zx(:$H8hۮH'‰3[ s`hp4VY"l)XhUoy_Ǹ='[ZJCktv7`d}.Wz~{-vXZr#}}w]j^B!iP/w]TƚL7fXEf\Vt2? ɑis3!qm(̞-vBN{FK`'<ěm=`ϼn@_7nܠKXĜ8W]7ヤ#49Z$&4Fx}2äxhgd?ٿ~E^Lt3/& f? L "z+wA7h_ |ٳ#S$PrA![t UI߳#Lv 弶 ZJF *7o!iG&lztF (,2órF`,ba1AͲzj8zIq$E uQk4F=[bhJEm&-g !ײ|WC/- mqDg P,@O6p\0!B`7?mL]~dz1:}0٥AOv̒;Xz7kᎻ$t-װnG1d;7ӊ:|E-x a,網A7$XŽuǦ . A4';=ʺcH8W$t2 71P&& 3-(j| DBuq9$}c͹Ǿ^h\z4>_+22!qggÌtعТE^[?.#aGy]鈼h s'*llG'VFoX=ϚW;y8H}4Yq3N8]1Pj8PEVd >:[r&r,NU.w̪*zW*m. f;q7ll\F%7E+T{ZpU6_y7 ȸ)[2͔LD}<׭<"YK%b\(5a 'YA=;=ʺ vhB>qʒ~ B2F;dUV"ՎUCR0U,EQf%kښwbeŸ,8qO󥜇}Y*kX2Te:|4H9OjQS 9׏cc|?Pw:OrO(d-W.HO)̢,96ߴ??U4{xWjsr^f@P֙Q@>dgd\yX6h.D(Xz< U; f~Vqa/*zfx`Gg \}czM  UU+!]fKYjE݋A>Lĵj8D 8WA@rQ+V,vJk7 sw3$洛;N%(bR䳡C^R*NR}:K]#!mξK-u>fA@lڼ%(WI_tPy7ݚԷYXM*%H;|trR8b}/X\ƑgaBǤl8]< PWWQHvo^|]"j,EWz΀ٗ({l3yUe4*tǽ^bGYrb7i-Ĩw0s@~)MLuk RDQw!c 2p׬thVceMar^@ų#"ElМQNo=50`-GhFKy"aГ^ ZJ4mBməh&]z-HY~ժZ$u8K6g1\pcRGbEm%lZpX E#j}0[hn8{UH EN5?qDn4:`&E#rP1fL"jV.6H(#2HmsPO*$Ae9mǀ`3n3c-Dž|Ni ajO'yaz)V%`/62h )"1ۜI^a6X 'ww<4l+}u&قê"sZ))U eRdpl]tʠx"D>A kE$&N6\5TYԩ䴙2nzۥPompN"2a?{;_q1]7/*-?Dm-,q!}<b2KRA,E9>Αqpk(̽/'=֎Qc9:hU XPSWin8Mr-ݔ˶cz"5,lygtϥd~Zn0"]܆`\c( S͒8@r.; CT=WهBu($6jm{ C%XZ] Ŗn]O54Dc>o4χ1hlֻx`1+C|A3qN*΅z5:MFt#s:IizXh3H bi֚ ,CVBaeY=-( TrxVhA+j.axfla svRШ ct1ZIPGciG2L #+608Q[w}3 t1][E}5 XgbFQږi/tU.k$Ow=#+f<۪n)ev9=)8/c^D/[j"#6Ð.-@j$(D[o\\:r7 qAR4_u }- zE!ˊU^ Z C 1r@hxh,5Y1]qƃtF!p X-X?_J o)csX9霟$@Q- Q+"Ƶ 0(c+1D W6M$C ?p5 Zhx֡CeHR>M>5g6U2{a)u=X ǁtF#2~`CZ #=_OlO ޯu Qs~uExBYpP]8`>ȶ"]g{ڊ=RCvY4M Nb-0:EuC4H}&(q3 ,wJ #v=fgsci{/޺RFfFRRg%vm07T'R%KF_ I>I1t/1qHS~@3ގuƄmx#62AP-~ՉSj?WxA9Js0|kL8:F@R r^0*3,!iz눂paF?ŗ.2)o]٬L\ӯkR΋‪ 10c 1׬yCO4TnH#S=J ͑A Nh ;2KQHt^"Dv?qhȕvPg-K$Gzoc]ImB-(gF7S-4P~GXw8e &E+:>"rb">>'C}$?M$zuvZޣ5V3 . rlh)B<-Ξ6Zzޣ0Jl7d91v9nt(u U"6xN4Ϛk3 i:8HKdf&ءEhV2̍?rLMzl5CAco6@C29a4o;}y9g}1ZU (L\i/Kq #h]+"/VHqDu)Jnq,@?e-Kz}K]08I*yJ5 Rڣ$8enTfU.Z0Ks]TWZцnG-B7 *5*۠z ۬|@ :n[ i8_!#K`Qk4 e'Jj9}E_?0啾$(韮4z'Ec+rrE <(>2$Nf )ϣ=9ޟn&UҔ˫Y(&w]{r&E"8o}fEh|FjrXcLNAU/!W_T.W݄5x>>2{d@^x}ޔ6D/%C}xB7/W$꫒Б %,> k˦g&^+إuO6~mF't3SeߔDtl{Kظ훝Pn#z&{-]&Q>TLB+py6C).[|ﷺ#Q@mv!ko{!WNX|8!4oicrl|O7?UHlpC$t*9: M4>EO K%>$czFi^#;pnhr<29/ Gh6p-w$mj%no |uǃ||~ԁ)՘l!.۴ܠ&_[ ]+q\'B]դV! ߘ!f we[$;8X' ^5H=$\T'=5n߄qQ5W>_y+כ)J e6dע N(b+'X\c:zKj#3yS<:FF(Y:bS0M-y|ɸ1p]n u͋WҸH& t%P. R*܋2 PƉDT`ʕ$h&Rc9]Up϶͏.a \P$d=Ҡ[{BQrm1W`Vs6@W06N3“cÓwUB/[x;LUjZzk4Ӗ/F6ͮmGKA3G|O5.4KtE {%i\ApE,G װPnnQ6Z]("T .ԎUv:͢\3޹5 I@=bwqcik[2”3} :pml4ܷK>QzD$;hQ+ V p&eYzE b8*!Q'&}A!AJF&I^q0XDt#=$($\k Qp-.%𦯡CT]భ!iP[Pvnȶg]ҮvȹvMJII&ΙAt^t1]K/\&<+FYPW< î3uKxM/ F,.ttJ1̳<ːaĚQ03c~Qƭgʴ! d.)fʔ(uӆYjIY\"ڎaTqxO[ײV=1$yخ{s FѾP*tJKRdo {_t%b`dSV, 䔒Ǻ?0_J6FSʦ26BO̩mS(,KcW5E$/ՔMtje71kC%>n5'7BԶޛ1?lH(| uLDwz+uw\`OА!GK/t|uPؒ^WYeCF( \/od^ VY!*>W^L&eJ3 Kz5տD{ۺh O=m0|XAE,G (ogmy,*x~9 viZS]g2tA?Hh\ncro^N1{DfuJ𶡙S~Ù45\bFp7z'qwڷ]z82s~\^8+ s"#TmtzN"o("(b6Dg &D YCpI"XA4_u }-8myzO`u#b8ڡJvo4?8y EH7AE,G װP $ oi }>tF Ң0B2 KNͪfβH6Dg P,@2&^݃z FA4_ĵj8D-1 hz"(`Lwatd"AbcϳvpܼO (q|f?JƚXkSI gS_,"ӯ ®s npT\= طt0on~8Y'N$BXL$[:6$G2>ZI*>P{M2zS8l4nCi֣B-45F *jrX"Uzʬ bH1)Z,i[ ($x#]A`E,G װPis0rBElCf!r{AٖI:Z)NXٌ" =tF Ң0B28pKH" UADg P,@'E&@ `5'ϧXaQ\P@ IA4_ĵj8DH#0hGc *PK~5,9LoyJ^NXe!/?oӔ˜vr?sdOlrPs{Q;_i99n^6ݴ?v&Kn'` jh01]D'nYSY2~6m~~ʁ0p(`U~,û_eeD5! ^WOyNd*/s{&>$m8/zwrvXđzKEaSrOU#4o䮍 uE -o=f!'I]2pa.!?}C0`iw]ή~7 gi2v:;n:\̑sR7k:~W~L3%@GzH7cxN*N]"his]`WkbaV I/;ǭXw}YGR5]%ylf/447&5EF@F;&^-9\i̋'5Xf !@+#=k (àaGxc6j!WzmX.+ ^jn֕o*C\aNMv0iEkm\G5+[VuK,Z1!JR4ƸΚ&BvA:QT'!K7S53Zq⟝<4]& 69s_jB?Dx;;]-&Ao˔+xͷ م25-x;\C ב1Af [_CT  %5׋Іbȶh}1GupKYhN|# ƙTO!) [L P"-Z/,r"oL.,u46`ϫ6Xئym{Miiيe5>ih؈oc,Y #2Y  â16(nw@l= ( ǘae&Bu޲XˌFӧ/ qSϨo ?i-=г|z!!/|ǫ\F"Z_݈!*뼃PZy)>_Vw{0R|ztpα53CA5cy ?tg~6I9̞>u_, })fԪl&w4lq]|tyލSt\bie2"0B8RB*-nRִ \5{ h5& :57`v%ᩬw ac!t..5gO641'kNc"x+y1\s#~dӸB6V-|D*>) ,p[_" -ؑsP9 Si?җu*n#H4c rwUP F<ТS0x$ bĄPB|Nf" vA,E,G (ogmy,G`$pZ& M #Ylwok5ʔwPW#\bȆ-JژD Cd)zyicwW+_ԛiy$I݊6daY꨸ckr=ڻ+o*$vG %1=+1KtF x8 MDg &D   e"G"9 "SI0mfF ,ь6)3s8VpiLKK^d+P^ <<.fOmS` tfmn=oC20"AOjdb$ hp>R\s:O 7O3< i\sp %Rh#Lk.=cE!{.ڮXjbN8(PXOI4JQmт'cM|jTg5Aj4īoŹ޽g\f"&xᗠ|D,,Y'` ]:[ =>󴭹dV@BPgD'LgGD^ 5O }XzCɇ%cW9hQxr ai~멲LSHWq?]'Vh0oy ?DlN@w#vLj7w:r <_Kۍ 9 CVkf뗕[b=-ʖs VAXi1RR`Vw%E:NuGƟgʠ' Cx-XqN=LGdJaT;5BRq(eԬaKZG~ _M%׋Eon<,Q+U5V WkE|PbNdP݌ EpkMw:jtz[@Q{%\>1Ǣu15 ;1C.w*k { 5w<I#U %_%|?19U[vIˤ- nE(o``;!L"ACR:9>;o%"=ފ^e6LŒe#(תZa/֮jQ/*\1҅E k6Q)7G^Dg~y{xϫ?{[li_:H)(\^+jPDXZgm\ mQ=%,/fym1KgQ;yq}F'҈4C-nNtF Ң0B2da[RjR\lOCۯ fD @?xFKA4 <7A!2lmȆ9>5Of{? b38Qq.-ɛbEkm]rPO7a]5*U(\iY[yUղ'FRᣉ]WDȟݷM17pXSabODv,Dg P,@< bZ4~2NsG\,ŎL"". f-i8)TVBrZr^:ɼMmb@$C3j#QN-6 ց A4_ĵj8D*1$EkН <@1c 0ޥhU&pW%L֦kPǁ4- }0*N!]zopb#x%8(\L.#޺ŇD s1tAIdurQ /2>_1Td|mBlyb_߷ Rb||aI$I^ 7"=bAE,G (ogmy,2bxxJPjڹ9>0֚ڷa++\1Saڎy3:jS8E!~. {ݹ΀9wtF x=y^K/6ܩ{,6?Vn׍XD'|m+; U-#2`[`w@ZDg &D +uJ ^?S>ԠuJ\icJ !U]A4_u }-<aP= αGtO^ 2eO繚_:Ñc*Jq-LS-+]S3/o2`/[z98 jsG]IWm|/)BV,-8l__SuנeAE,G װP.w\hqf,LޝW2ێ3/d}{gNPőЧig69{?"j!u{c1!?* sQa{B:;*):bs\(u*$!5j.ZyU_ohVpqtF Ң0B2e}Wu}@+{i-,[T z)ݓ{",x#gK`ğbR*!v~*<|<>H 5AQ,_nGf%3ҵ K4ݳgDg P,@eC'dz+ǎ_ӻR :de.G܋^EI6-o# M/_SDW›6]p`&Rf 2H3oau(ʚy҅2A4_ĵj8DWzT(3ucoBUgHrN"q +9{/G1.5!~^(P\eDȕXѾmU$J㿉1ֽ+.:$XեLe=cDin A9%Q!2N:U-FN&jAɲz鉭E}.lCe&4xaQjl6Y )ށph5Ő} AE,G (ogmy,%MSUәgmey LLDݷ|DKJ5Y&sSi42(!3lpx#Xm[9/YϥriGh.Z[EO`՟x̬/SGAtF xXp)tC}. 柪AdDg &D ,'w{%&.NMT]`ik$*GY:еCwBx}`  =Kgx>(X8AE,G װP0^ fU ZV>[,G%!+pim!+s oM4R,Y>h%(%qIĨUG`l[(D%USH`tF Ң0B2 dMa/Ne+[GMIJ0wq+%(vWV Dg P,@ `ExՌ b6-08xï5 n=4 0A4_ĵj8DcQJ~W(+Z87F*lé>vyKaV^l.JeTuC JR|M۱n.O{ ~Aƌ5C:V 05BymD#_"'QlC_A,E,G (ogmy,M#gDQiFsCY.*8Xۯ^Ru<`S`KtF x&*T 2v[kہh}id1F%Q`jD쳃ᭀY\kMDg &D [XIEwAR4_u }-c!|=rx-k vUl>0Mqork)Sr  K2"n=ᢤp7ApE,G װP=2S@4tF Ң0B2Βv/Dg P,@ A4_ĵj8DQ8r_n+^M0HEpcUa3Z'y!{4>IBZųi BS  f6 #'ss0/ EH{fko$t]e#J=dmڤڄᗋw%&ʺnK <#535jǂ:dA/ÒX%Ӫ H =f"QiRx( θȓ1 z?8,NX,BUtK@UtF x(lwժ9VdI08"c?W*Dag'WCy#.?wPgyrM1,QT)jsH_lަZw2K[Yodd$(. h/wLv3^W6GDg &D / I"=[? OOxF Pt w?LR//\E1Y= rx&]YabE4bH(%J\!.{W}SNzοq ؙ\7AVi2u@OH$)O)[Y`VH',ѥWN8wC' u["T>%|iUbQH|OϏ{wp /%Awvǹx9 ŔendVT"oA'jJ(kiPv̚sx pQ }Gx-I(Cm[K@٧6;ۀvkH;"єhؔ88!s$ 谫rdڔrA87%ZO'j*3%8V`F4%ՁKux뎒/ / 2ze>/*Oŋ>;M^@={uFԁjHt%#|V|Q*0c];='<1:FS QVcvv a\|ۭ03]OyF_Iix(b댈 /,\S{Սpzgd=(%kn MqM B&g1XPQ3w'X EkDE"oy gGI˔kLS_?MGVjԇ'}r[ ` >53#0eWYY. 6LAT=|U>gh4+oF 9YOb=i#$Ch$Ljc'$Q<Zq5Lf^O3y:ENf,%H*'`OQPӘ۴̵N/\:2IkfiJ5]!Mvz!K1AE,G װP4A+^*Q۽ 5oMR2 ȣP#J:H}N4nc"wTN@x8~ĺx! _Q*3|Hfa^_l~ԕ^{t[wKEȉ^/cwsKÈ.a:F,gu2-ԜjFO`;x ~ l*ZAk-L 칁oW_OQj9?) _Kv%P4Ɂ\IdS:\,Ytl1E ҄I+DtqcC<5eD#80"jׇvKʚsTH(9œCtF Ң0B2'F|(X5L= /0beSK8ha+k>xGm'XjشhMX>M!$ w]fރ5Ӝ862tJs?77 ,bNO+b^L| .[({*qR*#aH1vL`М@n.qv c3p DыKtݤ5ClT3&@x"񖘖LI<'pn,&D2s ,53my;Cg3J S5{nsW|nZWC5ktmT q1Dg P,@ řsal,Jc "^f,8UBC J 6!{3S7ALßJ,gkT a(~z4D"bH{[FtxDZ$L"p 2 kEAWHW`Ѽ#+ Vz7,ph$ib3>*?o=攆fPʤj~u9.f^t&h60ǕZ*5umz@[ ra믳Є7EvCזxnvAp)HOhA4_ĵj8Dj7?.Z  ^+ZȒ3QuG~M39'ב=O) @y&/ëdz0(e0 >ft繈TfT!!R0kf)M݈[.?]7S'e >B,XUaށ4b 2-] W BjD.]]5%?Yxxr>{^%w9l\Hw* H@SƳ?y L\T1jN3 If\V˃¶k|<<>KOODQnpI|LwPkvt:y8Qf):1Gpmi3Z؎<(jWD6x?qW1t+tZiU\Isglbj#?yiӏA dWo4rl2 [.JAqN"lt͗7Tư&>rٕARI4=>]B U9x#;C*B~C^%J4bE#f!xu჌s$ " l& Ic,(IZJa>hW[˥ɖ[Tӣ(=KO(. Oq%o)&9k2amٜm7a[u&ZY땳} A=pjdz: KÎlsJl؄.;ٵDAB;5A+ݧPz7CiެAt5D[/+D  &E)'֢$ԄXl5p\gWA0GqBZN %?~]y|Vw8ư ZdGHϞ DIzD~G9yIG~Yz "?ZXN娪gpcSHU Sp7;N} O>NHR|jFC&>ni]d/ ɐ~~6) Rzn@̣e"e"lg|3V&k;W@G C<_6."pw׮]j+22@'SњSy .^ WVRcM]dzJ bQXt|u"Ahg vs:)By09[tF x'>2iXQ DSY+LǢ7b7\ NhB:5PBss=-_Mq#N 9 Ɣ'fGC=17rL]^03f|ԝ%LΗt?-v2{Jnk)dl} Ty* \6=OU¡ Gx+{z' *y;Q 0VC7w33a+U!rGAk}x=ktnl ō^S 7/dXkKx#bFRa7ԥnȠ5:I"RtӚxhah!\jl,$1seY\uC` {ʴ5BY'&ւ.]Dg &D ~p {')zЂH ^B/ $(%UV6IqAX3,[64p<- i1@o0 BZ!kh~]TCSPATI8=x~z: ј$:7&ЍmXhwq(X [#Tv[ @g$BrCnшLBZwϽ|ӈru$F36~4&j%'&ZgX^[h>iCck-/["`9hMzjCjpȵ5o8˙b52. k pJqE "Lyb$0̡:\Re5캬_#*jYjHQA5${rUK3 4?_s{+rmW{\9!Y{" EhvV,<^ ů`{@.4 ʻ :(XD{EtGS"|/*ޭ6G.L)Q9 6͠y\) AB4_u }-k;d);۴)sM>JFex}!?sF*;o5ww*!$h,o:؂&}iocChF,hs-2oI&cIpe|EuJT-tGD*3'oqгθCq1Н\0618Ɗ2\{kxܜ~.;g*j7VJ:]vLOrO43I,:%c0ɻaJxHDbfYK"o5G~b;XuCr7K V=iK#:Js K,[A>ɸC;h϶E64HdP9)wxLؑoe&4oTږ >/gmHb^ef71Q p V% ?zY8`GYƗ9~1_}L5!_7P܀/Zdw5Umqޕ&H5fXoaS" >\J_ڒ|;/d bnb 4em΢Mn] "5g0!2[bb Vĩ^.bb,*?[b} G&9}x>ImDGe@ZU'!~)Ƅp@o7;4tS$^+]QSq;#\} t=`aboURdM?~u qLJ%i"N5Q=ߒĦÿlK хlw̄N)!ھ۱fm éP(mK”<_6&ӢJ}6՛0`--eL[Ý-{<*<h SmաbrqAxmT?4X9X bWqb ^"Y_?6"\;+2H|gy]+ ;u{pXc4fn!@寒$W)=Nя2w/'FŔ2!>nc@}sIsJkqL-]>vܹڹԭԍGL 9 OL#ȉі^m9iNN|?2YtMW ua9)bZCyySYcV@Z#$7jASj4z8:[Ana: 2* yQt2r˥&\H]ZB,@~+]R:+P.w-E/KU/Q~󫉄}+z*bu(H~,}qkuΏ,W#8gޙLoMh)"J31yb.EtË QۤN`֕_ &{Db$}e׺DRm,Xv !ZtZ |cE<ĐH/ſˀ)`iPnӂtP.r 9NtF Ң0B2(6sa)43+~ϧlO6GeCO|#66+|V#x5}lsiy8]~Ї?IҿMxPeȢAêAgNA4_ĵj8D*eж6~e w~"#Җ߃9#lSX)// 6m~;bpQ"Tt@^͇k F?_Xt&BDA1!t>Cj>C$*{Ca^N/#B/NkFOROFhRi|F,+TôeQ=pȌ0^Q;4C'HU+YVMZ%wdOV_/XK\{h X.U"PNm`~–ٌVăT Ah+; 52ImNsPw.z+VEVa i~DJs*Oe=!ƥK 81kP9ٛHt+3ҝAĔ(5c L2R Sږs4.uuHZrwr%{JD24=jE'22`ĜI_dL(LQGZ%&Fq={O|'ؑxf)3Y.yWᤜ5oPXY,G!nGE⇡3y.Brb/~dZ:.`Z6llY_s/>m^1TΊ%R<]yw݀ٽ& $0,8ZIJx1h^H|!^;%bQܿ1YvQqe(jϧPZ]l:m~HXcX`Ɣ>X#Kv<@*c皯h̠Auf mr:礼2&'b p VqZRƴ7, %cmm& iIw 0nK_,k:Eo" Nw/ +Q58PF7y'4IU0?6!d*!#?Ňk/D27DE Lϗ=~:‰lu=Ƅ`}ǔǾO?k&VR檻 `Ǝ.RC iX:v9v y֠M")~7‡ vi+3]s,yzA[ÈNiYFAzw,0EvR}+8ƃQb|xŬa``YdRr&=X$/v:{݁gex;,Db ݺ|@mhb:*/vUE3@8O&25/ Xn>B?0gMOn^kNrjQ:M>K)Ul`Xk3D򔟛 N{Dg &D >v^9+>pe.>rӸ ea 2RB - 2) |=5sZH$(_cs3A4_u }- b K1 _4z~Ekjs_ky 5ծ g%$ ?C@ۛ44w U. H JW{Cܷ."H^]*0B2TosW{݄{+{Y y:r\E.=Om5$9Ûy;NsbgLu!7Qi"LnGGwBgigg!PDzN)+FTOh·Lb׋j'P ?05ԯa$#XXz6F\6Jwv`KomaD]EyulC?J9p!](#U+g8vs :丿ŸsE|lDl!a) ucF|4-| ^AE,G װP?^]HMEVZl9Uf7PON9H8ހ5tF Ң0B2s r Dg P,@uf5!υ^*Ej=k qh0 nA{&e'ʆ02n-Lh_>X.!$g_=ſ,?A4_ĵj8DDթRNP;ՠ0'*椧9Y=٧t茢GG (dW;au;d {h${`ymr\SU6"[N~ fPq$}"b̅Rb?kewЕc;Kbe~Pvd]jU?7/# ,;A,E,G (ogmy,d"@,1KtF xL@/Ԁ-MDg &D RAR4_u }-V(ȯ |G;Θ=2*-Awyc?0ApE,G װPT3tF Ң0B2e@/Dg P,@ Q7 el䡬 Gnp5sOFGnjNNlʩ^@$EkB- [,"O\'>;J %kNѕKK8^ks%@b]+[YGS5jJ< $l9A3ש u]AlY50 [S^5AFtTϳcS<)X5=O[Wwmzl+duDتBCfv]ΪO6~nJB+{ αsek%z h{@O쭪uy̑[ޞqQ'ͅj!* 53\zuU5lWYk`YFMH..kBNQ2&ך(_xʽpD;ER/Ц:`Ǐ+kcb34)( c:>9 )]?Rڸ2#n'/ ]|a>#Fy0xg3鄉Y."']ud$Xu L: 3$"Yä+z͈mclO4W"Ra/zF;jف3AE,g 6@Vl![TQ^/Mq~:(4@4ghg̳DG#lRcqSHawe6kR[zSք@KwHLq1)% aV4SPgygAE~KS@X Ѱ'h~`(ȿk}ǽHT|ǻ0y;?l|% p'qv:}W gh)'K }8e%KeIuQ:7o}C= >t޻`2/iQϕ|WH;lcO4DV`:IRG㱚^-ͳ1813𘙱Ӻ][\= Z'r!tLge{}nEHG/^C{'^F <-xa67F'Ȁ9ዃ,&TOXUEiQJZ#^] =Gt1X4f2;hVDG=b%+oXᷖ[4T ٘eQ8Rv^q/>3t -׏7x9҈s2kxLQL%Va1Q\;*τe79 $]&(ցBmS5:5DzFQ݀aM Ӻ1Cwsgl=)(oqܐUoe<韶TZ,{9r1/DB~Oraw)@yDiF+l2'Hè9*;"h λ`9tM){wqC<&8k+u kFBzBu]: 1GaP#Ib]RsL C% D,?$qï){xߣJX6`@K3}@13h6P$*ݾpQM97Hm]9Dl Kۚ/˙H5˽0Hu{89.'{*0,5WMQr!i@q>^]:k=tWhfkwQGUDWy~zyh dhrzha,A勱fRE)oS)Lbi[gfmma\%tG1geR X^Q*H_.=Z0%ˌOnGtJQӸQv`}ZQD %_g\vW>}]fuhWlWE]T Ӯ =Z|î{?{t/S@̊ґYXp81O%dSErh˰2~ Խ A#|޴Hc *&bax}+rS#Xr:Ott{U^6=UVT8aFɪejSЃrq=P[ɷ琳(FlۧbvP ['ṔO8fBu 1PU,d&O'`({qtwR+}B@:ceLe٫$h'ýTESbm Š&\iǍ"Oj?|'U3J6 fJkAݳ]a }}ۀ60ZIW,wo4|=ZƜp=n;~j'ea[kX,e/QAO mRk݆8P7P5i5"&ҎMAZP?K!U1(ޔJoGe(:술ܔ1ߴs@ ] V-Ű)7 vJ|x h^qwO.+AY,$ APZm MOrXPy%"ŁFvbbku<<1I jiOytֲ] Z 1_v=F-S\T9$^F*$>R.e":msYa.| w2P8`3~laEx`S%sD].v7 +vJg9CFg3-ũ.hؔSj;ٿ?l_:gX b:^2& [p`OY\k#%\ \ºB∟5נ(TJ/k jA=PasFRh4,qbIkb㚨ci\Wysg)yd/Ri|=3/4x0q:oa&0 YiKx!JzdӍf[KןjpŴX]DXYvT挬8%"b1'9Q5xryă[4a*aA 6$yނ]㛊\yytŷ7c"@5~:!z H,JPʉmam cN$aO#qkW"9@xZڼN;*Ʋg\㕃 PWO>NPIyq(]v{hZB/r@otieN0@eₒ{/2Xtp:/p~'c ڑ%-:a̖X =yۨGT'JXo'[b YA3/h]S1ZS=JMCTY&Ԑ&v{?13Rҝ ++3j>ilRtyPuP ڎ:wTeċwFf t'åia6š %#hg1ŤN#0BQH 7Hbƽ'D^e<[E!YEcPw[>Ey>@1 2!24/i"?lOkCm7oJAz*b6L~\ [Y`.Yݡo@<?ړ?zlrS{|: 0+1^ bZB -Y-ypOgbgz8@9_(Ɖ,P54ZLJ'ӔNP܃oA!4rt 6$U&Z@9ٟ8F=q*VqI@ dMTӲ7憐& p@()t|u X^__lNEIspcgv/CH@!wZ&v2qIDFԤ>P8vTn׺>|QNŇ%WY\>6¥Sn QxIVIS4K@B?` k}9Z|'< pYR?P8mP2Ɛ:$6_H콙[G15\H؉A#3FL/Tse//icҁxp}EqT.d<ۚGE[Y!f&}fH¹aSZ-+CģU ∆Խ!l&K% Ĭ7&YxHQV9H (Ug% D#GH7h٢شrrr~V72z#j8YL xqSu^]HU/1\VVi' ;r :J4p0A~I'ި!v^sopa&%(w,2Vɵ4nBp#dGy:Jv魱}>ә(#8"}Cw0Z;^co ]ω9 9WקI+Iq=/BPYPjdJq 斿]J}Dx>Ev* d'~16W{Sv^?._}`@3v>tj2>b^;=15uʩ᪠gyYs'ɋ|Л,|}jV/X 7g fP 䫯xT'3 i- - rްc4QTZpR#MQ&cHT.8T5|H7^G.xYPoTa.6i|Ec}OT#2q "'>6RpKfڔm#ķ|XB/R>Y\1lIP\?bmHVf,4 \2rK_ԶBhBbT׿j$J#1own"*:j'koV o5Q xSvz3.7PN?sJ/\tsi@-3vx |(vX#!goa+<4`V|<+ֲ8޺;Hrz @yK|5}I(1Ͼa>_knl,Ҁg3QNcND|!k3{wj$µX/90elF,+瞡k{C{xeC!5&w G37Yv;^$mg5 Jw%8-ws+Nq3ǿ3euHK3VB>!b5F5r*zM3^_ kM!1}G J܌2BI_ ;}=Ԑ́B=z.+d} h|$Lh^~ʒzйa!ѼIǟkT'{)>i q|1kOQa^BѦ6|?2 7܋CGX|lrEʋPItYd=}m2{ښ9א)c&1b0iae/f0.'K z~big5$K.ЮfӤO\叀l5G-B@ +لP:igL!`UBrķ9zMkBc}6..K $s|pSʹ)x5UF z 0\7BjIޕ j,ʬlC] ׏U{Rڛt筮wh QWB,oz^Q}(GJ{#nȟD#E\5[z4=хyJipACHGriHR[{~*@pui߂ !4z*~ ߈8#CS/bFB6Ag0܊\˪WmZW(t-P-62$4 #<}虀6j1|8\(eͨgVIk`jGR v(BUSeZsx`*Y)U͡x\c6V3fQhw@i ycaRneg яrpP$8*ՙ1A(M8$>Y.ת-nWy'(] YUV>^:SIK {=SE]֞1 Afp+1`^e1B.|VB+aD:'9Gض݅jcSLjĺllـS〻x5sGӯqOD?<{+'A* Lr*4GѶ)0`3]y-\QBm՘MES|$XT^= \zk. Zű@>YMԮ} f1{M7PW g dZ],sw֮8o0jSko>pLN5&U>bӳ]rePzfbBI[ϋ&A; LEdu'prp9hP7AQJJd2{kq3Z_M (^yZ# 3o4yDžy睈Y:\҂BH(B T=oHU=Qao-?9E0StSһL~o"{G;Gfɵ,Ji R߷(D6_zV ⰵc1IzHpޫ,I1e$Pg\XD_318D~!((F%<_M#rEBӬaG%غ;Y4ZzVBk)8DlԦ aDo F+:+z:'$8,9ǁsVۣK+X}9|If᎖]rSM((¬x6Z$ B,d~` )OєM,YfwzzǶMc6rǼˊ-%1>43_{sAHK;–A,Ԏ7! :&>I!tk0k rC7isG8")ö"]:x?_|m"ρ$b`/ }8<'e|W̍jc"xS5sj(*0Bd5?hA5 $Pد=nv2!0ZxBrJ2@r{3ۏ =xߞ= g8(ܼh)WE1\ò ^>+z$ǚMFvi-n:,Z;e e#*|nI.UiIb^ %WqY'Wn {* y{++8&^#:G)ުOg{~w7WQ_LM%f{ Tw8YG@jO=vF SJ Dιb<ȵ^P%nU,Z9 xt@o )^V~9UAjmt^O?e<$@˫@<&A20VLnn ظs_[1|M׍S(~9-zW.$̗4Ȩ!3ཬf)PHG=/1fW+2նf)%bL%y|/) b~"pk&()xWϭ^w^ִv8)_Y3M bfFx3\ (j3[a==Jkn01߾/[)71oCjP:uݟҰ櫖I>Pi;!b15[yn 0Di-Qlq ~751>:Sy^llˑUf&tLYEler *=s(Ǥ?Z0?YAIBy}(ؙ[`Qʹ!D)9N&`!`E˓zat.(A>4`* R>/-3MN#$Qr8CY 7Fj!Dk]rF)6<Q?i`K]0[a2HJhϨi"Bp21pj;69 Q4ჷoG,^mugoőm$n]3VwD*s@ՠ8C>FC}fX>?[W(ã{w=(pѯt*bvoYr> s5sen:/2rY JזsÖ_Oq8hUI(KL>"hB1: ImbiKnW[lˮpr8 +W(_-2+^tf:؉]n]w,Үdz+ Br$[RlXx?r]]f% v/:Ď;Odc"1s@ qap QӪ* Ŝ^g ~:1xѮ'?ϨN,9`|y렻SĆ턥vEVίVX+"(G쮵]V$?@t ؎(m.1|Y<>3 ^NF6ֶ:M{- \uk!Ӏ8sbKp..*a:zJ%|=HJݣyqGSYOpr'ȹ+Ѳu(A9{cU]M؜ge!.*U;ƨbh Uvu=E;<P.00Vgb>9sǯLN5)(19Kpddk(C+VA&9SvȮe)BuɫplH^Lzn~8ճOxa5ƌb%Ixƒ5kUV |_}~ D#h -hEZ TÃMٻlA2EbN/*~A5 xCHMyݝcD5A'įjE3g_#@Gku .8J̹+Zv_/vka7XNiߍ sc__;9jܨp" XT߳(s9(%k0N(CI)b̀B~&LUhn ^x]Qی4l] ';lӜb y Z{؛zJ.8R XL%ʷɞdp{x\Rt?/O`FSk W4UOlSi&5?ٿhmuUdqSd"ѯ3?d 3۱;,0 Hm! 19`(vɗ}idE624RLnJ+ x,R~HU&]./q0 A6^y,*-EM0W YBAb\" xZ@3(w ٖ93A<@lIY&EVP䯰fnC"?;ާ{aFyE ܯ諵[K7&F*1@[@і^!ٜv0Ay޾po/t5F JP2OYT% 7DqLDqd_kIyw}6ݙ-%<"?I.N ۿ]>r  Z9(]h4aΡt^|-(M+b1D5t9Ãؕ}AZ=ks{bAjn)3( yB)n~lx2Y|4ㆌ%ZLtY`M"[7$݁Sv!3rE`z[g vHW_7֮"k/FlRQr`P*uWùEQUƔeB xrw 2pƌ#ݽ`!h9dO'}D$vH2se Y|rx[E!kg'{p]_,>8TL/Uݣ҈$+h>sΌTU1]u+dn^.7Ls9opy3jtߦW#$gȕo6+PaǘS}1~!=ʟd/]-' ؖq|\Nf@Ek!vh ptM[c8 -S(##@cB 'EܺvAZvU֘)e!M{ב ߀ xA2E0$k%~r''Kߕ*S7']۲:ot|AVvzlO^ƨQx ηuߌ~nͬW]<UՄE!7kn-^3`?5y[8\p̋x]xȡ5Wؼ$Ү^XfgF$Ogè~s4x)Kg4/xߦ;|9a&oKpBPd~NB^ U5_4uBpoz\.NRs+믦2->vF w:8l wUgygIJtG'7N# .%d=LrEWE$I(L$C׭=$g7Ym|l#7֐\xXCx6<~ c:JE]L)a]z"XekwK.* *_cHӲv'@ j J^5\)+nI~u\G,e}.ƀ~C)mN r_ nӷweĹI9Y4Y1j\ Fاa|ds LN3p*,bdUNia4OF!aiJt=4uNsd҃lJڿxtp@ GNcxQr&[]1a5J]P&Q60 `3Ē_,/!ʈ.- [Tb㤣78kwjO_[:e a,fSE0(DR ev]V=%'ִyy1%`}A}< C::վי5#HpW+win:%cz`8 RC"k4 |ohd#ƚڳ_ּ?(d2JO1jsMۢF:kCmG˦EIYTF_52{ Ni0pH:8ZI 9\2Uj[Rސį"ucQ{L# @bz2Fe,2)k֟R?X}ho}|qK</Tv_5h+l&6/9u!ڧA QNHdԖF pk]3kvJgAmQmc٬O&hWpd]q>&/GcAK:]O+!yvC|8гj|VXQQkzߏj?j+aN3$5O.K<8 S ipuq s[e֝q@Ț)jUdXl7')y'V&bX Dy;(:g:TǶj=<\ ڥ9=H G4d4J,,אrGpD jy0viɴ"ݏRj'VpIQJed|zONL s897 #~>δ;-mD2j1߿=$C' BU3I)Vc\ J5MpGLx׃"Uf̏vVտZ{Q?(d׉ ֫%ֵl_rtSchUn~¸ ZuQFɿ"o.z?98prg\Wߍ(0Sڀh=}Rh9SZT3򱫨xW DUuIyAMd&i廖lWЌ=O]PT/0E0O-\g=yѼv$=*4r kAH`g],^q!7@:'Fk[LO(h\tNJ?QgaDd@OIV/ȒMw9{( t$0h6?|ni څhZa^ȍÖXjKx8xKVt"#Lxsxr~i{Ju$8-jX,l̛kA>A3qU`ƹz8"?kVSN|3' =](|dx z lDrB k1`T\ O^ H.QbuDYjM6^sHg5Op38H_fEghMDvj0lH*,{^gv0oaf~IC)^l4 Robҭ Xz6o NoxVL #u^R];aQȆ. ~Jk``8C ,(0uBߖZG`x"12PP<-'}qyOeNGF& ѵJg y:_&7Y(NyJŰg*5J-dǜhx!fI*GScsxro9u+W,$ e{?>Fa  `6bTK!˻@0^j >ZxY[q+ϸ+ņn0cx?P|ok=X/ױ"b fnxF<cy] {VhYy׹6+Uq(eVO`"YASMqk3(kn.$T4ʐ4 ?j F-g$=Od{]!9( %a.yr " 2n]fyQ65/( d4t$ )(K)D \.W΍Sd^ËC,fEX2%@hΰm6 [0cJUddJи&6W 􌅑 ЩnZRNK1 CQ:NY-A/L᧐HyVr74yku N Ug& "iބ)gHҼi  ,ӹ h8T,pQBz`XJAr_!C}4l@p@& +F\/#8ؗ謈|oP7>OOο|JP$^-ZqƐ ${eVMt(̉68XNSt ^<ĕoEbQ'[W[>Ċ J@,|++֭\YI7E1ᯯ'fu;h@S@RbQ`^#U-l9#BM$""̾ԩnT#AbS]k#Nx)]KL{&S>t~[uNk57l(܇7x$UUEym^ЖE/~hX_աfQoL>`gL0.+Ϋ Z^jrpb~K@%Ŵd_n'rfrg} f?ONzx\D8µ FztytdĤ4Jvv~ɪ'S·D;[L|JS*L\֜4?|".h`(D:XL*Eoo* :Խ!;Gu$7%94DaotJAt4#awg} <$^%k34e}fo/bb|7qHNw2U< w=FJBUʪ:GN\FT.VJ'#m`b;Ejk$&vT S\6K DJ[.&JN%O@"KuOHKj[BXPgu@e& "U<к&"[ Cᆳ1ï sߎ'\hZC'z C`fW`ύ39yZ0qVsW*?m l7 i Z݇U.Y]|eZ.@U6eT [1AЀ/Q. B1'("(\7@ &OoJ?h)1?L%rm|ŴAn.ap뉧f;""Dz |\Iox*UL,/HlhV"|eyW@΄&(#uKw°CZvrU3Omkuµd@ҊZ|oڣmo^Ćǵz)yjU X.^T~|Ԧ,v9|q$̵aB(zi^m'Z%^~LcFU@X3TL[r3 i[$ÙaZQT'fK.Ct{F1أYeUBюpX`KۅMcwզLrk;;@z쭽l8\`|S} ؿ^4a?&٤ۘaJUM')X+! |W *l aFhS|RT_ը|5j0t9\9@6EGj1Ls)Z +xhɄ9¿T ^`gϣ" JGM+O4Uw./Wwh51F(sZ8vƳ'~?@Uȿ#Γ}zME)E|:r $5'm@j/VKaR#iI5Rp \sa&VO cj{ vQ}CHgxm]EwCxO%,e/lC?[,xޤm&0t$.kFmL1?WNag.<;8QrԅׄLA}wfXj_oHJ|MIstq.XHJn(fHt^J{?rAle/гEB&FT7R?Y4n("cD_}ZQȲ\,$t1w]\nHa:vU بg/{# 7tK!+( @!>!Gne:NNv;3A@l lz{gŊb٬~}'@jKIl֑.ِ25o[b EF(4x.hҝL_$td4jC<wm35LY2Yaǧ"t t+ D(i^0b!_%ULi eB £)ZLxX|<9^a`+{ E&۟%1?ȯVQ:N W!nxP[ @AC=wđ1x!A^hp[zpC6]1Q|u櫭 j蜯ߢg2`X,c0q1m٭#E!uLh"\b-Z 9Էk}Z{.!B#^GˢaLOINO]밸m_8ʧm7lo񖻿rtWsd$|]Mȫ&+gGt\ьz`Xbc Jܸ||ݥdvzH00}u5'> >/XNk>ۣmx D|ZnS"e"h ݄q:1Ӳ*00ijr٥-1{:d.f8P ǖa )us7z.3\ FM.d%@~'*qВSBL2D\kG+)`/Z\Kǩq{p5D6c+9$1Vމ/q?4kooբ-3zkAG>sWl#릨RzSsT@sڂI 3s;FQ D^mNrSΠ TDvK^/VaD4ED6H5d5"g` v>OgΗn)[8dOg]Lw.Z$[kX`TT F ?vƋ\=b)^oN m ~W)W)R[[U ƻ$mLmj['hBsAu!}m]L'Т$UNy RJ3!,fQTf*;Yi/yJV mGR߭f֘ԙTZ?@ 8~ELcAM+M psk;:31?P+U#31#W5P 22 D&ATb63)?GCm.8yrX~]y<,[Ep xe(T&zm2Zʩ^jxɣ1$@&V߾>v~hUSWQN7cH?NmX[`)7JrSa'~S+;lY6ڐ]ZLbMKe8} lC|*ZG0ܗ`t0lhHjeL߻s#٘#G#q5xm}S͵5L}Xx`.4g~ʎM]ZgW7Qe%N̺h;,(p/7bͺpQr_S4y~& JN'l!ڄ )L)mk=Atn-aEUM+>>l2;˶o͖͒!tPEm5ҒC3I|_6-vqցƸ=i@un>x[Xgxsnjb3‹dqXCW8%| ?2(,Ҍ7ZuU%u}!gt$tyɨBye qkL⯙z4O&FľVYTR}pb?Fh>T@5d}/G2|)u:nΣJ RΰdYtEǥpҊZL7A[9&x-/a ԗ%Qΰdu4L6(viQb4O(SRgWcY5"VW= 9'"!a mc O}m%ިB@G~]/#h~B-QFsaMc\rX1!LYwm8D.]ajb[.o{cK3 5۱/FtF仞26 !yyOؗ4g-9҆wO&Q`8iXdGg=YQ:8CULQ,J`tfK z'+|da 3kep3L,V;@@,kL)#<;ô޵20InN:_ԅӌVq1O{?s`'C/RB ;Vs|#!4ɟgʼ>7+ 71es4ϳ)8ٌ8UM)"q|6ਥ,IMz |ԠآN>B"n/ec)aC>Ci숻n8GX%{*-8k V]il?n]7n/4ńKQɆ%d4HA6C5\Nepd+k0*ns~i5MR>SP% fIU,O $ W[ɿ29cNr AR}m*)J0*#5b>FVn L&Y#?ڠp/Ȥ{1qsc᝷cmƂzD%Οt!Yr>D6òm9&ΆAlCLѼ34ѷt/ Jsi_ˑ1:kC9Y݃< }[6WE} c&.{1GsJX {m4V >EYa$a$R%NB.ePMS!g}I$8WO@zo/ οIQ0hn!p49KS"p )9ٜQ=cS0+:Xxr/Ã)IYvǦn-cٿ&*zBMrf.xmF,0$}mJJ6iCI471$f/6U咟XYJAg:w Ych圩JBIO3CcDĬ "%/_A3v%CیFt dBϴN[B.:Lgm絗6 0FKf#&bED hxGu_fh/~cu Rz>fIr>o5+~3,ZL/O{~\: !F@>:+e+CxTI~\fUc*11HKA9Hd;] `+Mj JDջ`t M?ZcNÔ$ `9Aez0E]4qO]$0B2/+o>hF; &ޘE* $>Бi_'nAݱ8r`k\:%L:(1*±2pJvL?Nk:9c˪X)ş>vPtK5R=^ï̍ I) І3k.BD>Ka~IJi /~ϔEԝ0?=h};K(à ݟA[m:P\Yk%F1qj"œvm;syAkR޺¤%<gI^c6}w2=pYXƂ{S2TwcBg:}y/ d8 o3q%6Z|\ aűc2-&Z"q%QmqDŽ:zߨ>9يbmY>eĀx}YTg|1e5J?ͫ$!6E('BReEGAA[E倇x2;CY/32顯>D\1ȘǨɏAb*.ꈻ/B8b RӅ)3U&sBL 0Rh5M%BĐК#XtQ0 E! |]b\cBݜsmqL8B'b%$ӹ:LV;D KO7[$ "!I'{/.{$% ]|7Zױ= Te Cd8os;.so5H ms󄿈uBJco9ᝧ|+ u1*o0OI|&.`oWwW?՞ĕ+HeP|l*Xm-*v?[D<dC)*n-4+իs;.#|&zhb1G(T74X=-6XIM\sD;1Iم[ Lh!U!?5 :ZppaH,:E_2%9:u$xS^XMRA֍s\_ڼ0 N6Lx#Ae+u7(t_SB6/uX.h4Me?Kq=MgðcH!n‰O3=Нay,&߁6_ ݗ_.`(Wq!Ӥ7$O,MtP+OoUDH[pІ'c{&isg:EA,<=,uUb ϕRWh]6AҴ-i |iLrqOm9VG-κe jteMJǻC +6MVFf Ŭ1td N4άNGOLX*(ˆ8hr @h0s)Z#mEׇfxzb0T6;VSh$z=yEV1HWMF(Z"9p"{BW GI6J%QmK<՛&$2J?AjZ`ψjtPyQz~Md핿6"5O}2 ^Xq|/`2(0D$)0"̒sgZYWгvw)^V>N0@Gu-^R[S5Ղp5 dTUr_L_9ymtq^V^Y4$ǹ!rǧ u2?̟6ewoBsx5SS c攜-j@ v'Ɔǯ ov yhe3smr(?T7xv\f8 Uh[`9I. AnM~|~ Բ Xa܆yuRɇ»3vN޶IQⶃȉ3)?0' }255B0:Ł8wRL=KG BXQ8 \4$&;jܬվVCk?]j} ܼ] GG:1v#,.dzZUΙ A8M# k"ϙ<m ZsX$qZR!# ʎZ3ʦĀhm{VV;Ao|HFKAH--_J^)̴B՗eڕ d+[q2'X+A u\+/uVOl2܂*HVH~O.gRBױ}C{??6ޘ=a\юW <`:Y*Z`bf=4JA=yb5_(Vm ⃎HmՃ@'L)hOpRVLT!O 5I?UV8\~58:Ed#01]2_UuمxHf&ҤGP>5ࠝ7AT1$r,GJZKM{B:@o3fbaE j}xsQY9Ll֟2Ӗ)f JvTJ'%1ɤ8%Z_w0*w-%}JaɷpBC2m'{V{Pjյ񒛾N=Sc)դ "IgCT1SESo$Ek$:_C׀j3`y\Ҏ:Qhkf/C]꡾VP!Yޭd_SQ ==*KLF`7orKQUtHQU@tѧIZz%9ʅ~?Qo k.ceTcZx'Us[T:kn랿j+AgrޙXoH]e,!Rv˾0]شKt6EDRj@"> À au ꗿ\frI?9;e*V1Gmc ʣ_;EGęqT´5fԠѯ|Gfxc7aKi{ba@T8Bs; 4ױ4/Zm`^ ׇLm1^ȨD٣0H4̨/Mgӊ[. DKMֻdNmoH-yH%le- vpTI^ţt#m:OБqĆ곆[Dmo@z =\gw~{EZlkE=kR~_ h2ȤSIQɲ eipDX5 x h)p+#XW H\=ļO|(6P"EtSg3P2'!o@W>aAD' N>tZJık)0~`FJr>GZC-!MSvnW˭QDM[ȞXq`uH|/ӊjW~B-Қ΃ўeUX|ɷ9C]\'#Q!;\q @u$P4mO^{Msq<Zn|ze V]o`wM;( Qo7e~ w!D:z62\3G3$;aET3"wˤ&>. > )#53APmS3&RnbppCW+mlvev۽4_4yUh>RPB^enH4M-O`2pT%(}z۹ 3$gZxQzdȡ[GӔ& ; F4U]E#4#wH2 k̋ zÆ.F PwJK4__bTN!Ą)fhc ԕkN!,c<,<ś9xxo඗Y"2Z͇yd{6Q<ϯY<#پU>j2|p"GpR8ߩx{Fw( .IArum]WHu)3HrSq/I93h"R+B%v/( '栵1N"mt"~zoc/6韽L8tc]+)0Tin ~Ya'IXp3lrϭlBv1Jչn0NJ`vc?9&H^,Imckx6٪`9f4"ƴQPkr^]V,;p se*C`;-v,r?<{J`$NYC<0rіᄙWâbs.xcD[n ӻMb:٥b5/b)4:Jj?oU39}K9QT6;R/ U_?_Sxe>.g젷XǜwnVto1XX0Bϕr≺DG0yv/$7exǫRmy/;l+ÖbNENq6Mb8zb]0k8+ .i}WÂHITqlrA;;h2c]o Zr!"~S8#_[3%@?EѴw WSRXxEɼDZ͡^^kX7$xsLDD1Cö'pi $+* rqAtX_`u`sOW1{wq`)%e)fg)j?2Ku4i<0?񼎧+0 Z~*:;rI=uMT? B#*^<7T.u;1 2VGfhi|†T^[AomD T?\P$)= El`T,zBVi&[H} 1;Y?EnYIIUH0Dkt+#-Y*޿rM'K^NIMWǣWfŽp@%Y; "dS+6:)i,1drBd-C+ǦO_)H:%cQNk'P988䆈{q8#2ehJd0#Y±.̐vXN^NA:#m<@"RVb+$s:?6KBӅlў nkd.QmSR#%s# w8{]։ŨtUj {経,#Q;6a[MTwGI7|n(kPD'j]Vb|3}~a(lY܆ m+쵿xC[;)5oNjJ^x&wEi/I2f OWabw%pOW bm~&}fj4Gc6 6ri,V_6KTS Q BWsZ%X9|4}CFQI"Շӎ)4Y0iy̚Գ|α촯 Y>Y%IAxHPΏ£(kbd€K(VG5*!pLRmWZqx0<Pˣ,=B:= W#HYy.#oxUTO@{ӽً]liOW7$J PCXkX[=AӽQ Q/ xS3 ggk膐gg-^yo+6]imŏ:*2QE up:mX\l4SNCք#?xw3 `vLu_+bԋ:qfiH#υ. DBjRtgK"[D]tN)!r)I RaSee13*AM  x]֒ʼn_Q^/BaF#znf9l@~5~| Xu1YhIs3x~ji|iwB1\=41Es[nRՔOnGO1Q0f/=; 1KC.S@D?j_a?alGR~ji1M+r}}H㦜:9 Suz~\ X 7h T2Ё߾x8-e\=X&,}pP^CK>&p|lܫ0CIM +η?_?֮'+Bjl/MI+x vn:V5DP.VQP D27(.m=*Xk^*fkboV4f~%ʰ<:h, A2.! CTz} Ph`*uaNۀb^bN_a6:Nόaqtlu.$×]-!F/j2XnƸ Ոԟv\ZR-H[Y\r kOצaÈap1$=$ -1ntyn?QP퉙5擆]X}2Qt PZ^,(6ߢ:^MukgKd:V/w `\ *d g2eP 8)VUie`|dqWFQ+*bg8w7D_FzhǠb|FbqsAhlE'Rm5b~IpY>>UM=z4":;A Qz-0oRh=S]LNaBCA=%IΉky|ݯ\ʼs|=FFt+\xaw* 3 LBL>Bc<`v\/YJϸ a&aj+8kf BJcX"UpZvՖ+kX1Rp^' /O=$ LфUU!gK]2BtKq/$O⦌Mjn$ylhw?S} v2講(JD_[o۩V;]G'C&vYyx!R)˘f `u}|ı!Iic8R/vP}[ w0-;)? [ɿR DbKCRV#E"Ϟ,@U\J Ag1p~j=s^jBpbAoK(Jqpna\]; sI&Ef v-@ۦz --eh&͢vjeqsE\x#VPN>Q w܎ P$iyf+j$#&ZS SM-h8R+%O26ğ%e_ΛaFK˅N. )"x"'#fRLNoW)M фwBѺt>N,yTf°RopI,!vc3QEO#NSx gPqO&d/4S@ O#q`UUQ=-P ]s`|t%V pHҕDSB]K!cчH_]NuHu&C;Cuօ>D.G4#s7_任Xn9q)Q*_qc<$W?_צɟ?A82.]XatET tX1 l`KnqG,qEIͦ馩v T\x'V%4S^BJC I[}娖(J"a{t5 gVy BL,eB {C綵L47>U%uG<˪[B.H4+ 0) Nӻ3ZXf*oD%ב&#tc}OpT;'B $s= 6V”n9aN\c?|N0LBWԚ [ h 1{ Jd`uf-9ݐp:WE>rYХ07ƃL"8AE.NekEZ:=VN VsC jF_"f+2H ?өЙƜhOm2z[qx{"=))#w$北hR@9Tx,3>PGe& G0 =K7@C(K;T_@T&]]aͽ*Y&[;|{~v‘XRKA85kYrjjUܭ$5bj$.˜&tsWlW6fWfM{H&xb(92V DjUD990(ZI/Fx/` 'Nv:#;4B'i$d8'(H<).WcaRVp%k_K{%FipIHR# M tPsr9*vۯn)nX6߾KUi8]mh74H;{{yA1DԾ/$ fAqs=D#jо8o5wF ~]ql׵$EK,I= J3Nv`6Ap OSnV"4OiSOƥxp脷 izW<0dzDgdw*wɻRSHg]anpZ)nR>^yT} L#ڢ`g;h>MPζnل@5}*>Y{A]}&EJDLOF-wki)wNg> Pk \QjaYϩ!fMC^1ޏ'$Ƒd'ij[ .9>E~/' b +| )e?Pz={@vLK3ffDEe8N\48Bt w ;Y@,ߒjlzw@+?[=3d-ڞ\ $$Yb0yŘ558e,ķA}ĵ~|&,9)$bed2,UGdHh¦U|~r7\Z+lZ,yػ@hǵqS( f|Kedy"BK.;L^'6HoDB׵HeMܡŽc6'$L:!%*EBſ'J{)?q+ :c̯7A%bʙx= *[Q[5m}#bJժR;`J =S,8Qk߾1޸,ۻ$;): ?m.:G(u OU`O]̟h竿0]V]#h߅ sdQvhW$) ؖBoG5i9"ѩ\y4ߐ{ƪexVZtPAͲ>\ bZ(Ml. q 1uU._ɣk"g /T=iS,w𗖪W 6xg,a;v-v<[G/=g\Uha -!Hzߨ;`|RfшyoVofwt%m)uB˧t_Oh_)⨗%V+O,Ωte4jxY>.BRLȞ6lCJp^rrΞ=`&dזaŧcSGP$$Ny^/1?X+j} g:w8\f5ۙϫ8u%D">-ZzH?j7wkXdl[sUy8dt!'ϖu\Q12ফ5|$o|pRY(1" xt{^-$[)=Ho`c ǫ,1?Y iK Y]P5NvTCf{nAzuOyf0yI+@  ΢r_c#)6u<[9- 3-|kk@oAB{rS&y߉}qSi"ULzyu :.eŘ xDfHg`֫&`ƃ5kj׎g ]?]\Vr|ֹGZpd`>ήAJ2~XP+S4~hX0`TjiiWעj]<ƂsS)2 2[ɋGu^/T}4, A}{P9bA9{aHC5tC C] 79%ؒBuņ~qkU\;"m3d7}Mmm bL]._)@Zu^yˁ-|&?w]w%3&ˆ{'V&dG_Pp:;z%$QN@wticc$E8g tu"]GX7nMiOƘ yv^x+bZ<]W]:/)~h@d'`„`D~ <)-uxc\?8~_4bY3%98 7i}.gnH-$jwlBб~8յ.8Spqyg;ŲMC @N5}v~cw(nVꮟEHye"۳ߚJ'r07P)'YBŢMPFz=]pkQ4 d&|U["|C^UK +}7DNKzM}2%KQk4 }ΊGeczVM8ͧDϽru5Oh*NڃༀUSEe ˭g؃#HH?vgfVa1DDŽE:pBڊntDcm?:cp5^V^{yzN罇Y99 ;Yq{  yG꽃axgE07uEYۮ"vЮ"|hU:D6”ڧx_C?<U$~r0rd.yB=>z Vt <̻s!@;6n@fjM3\;tcFeȅSfL.5+vՃ8љټJf߄z]y[;A3:ْĆUqիѾ0fpay*X0ԇ뭙;bT1PWv1L7 % 3RaX%g |P`v*_@a0u?0<  [wg?Kw8tQ㝩5CjU0 o{^%b1dp^^(& HQ%Ȫ!eT]HI@تƜg_!D'WinDnT-:p%&qgZx_Mu^@Kfq@)UY,@G֫YOwWN:څ i-cGj2ش$xAizJ+YcTxS_RDάsp BF\9 .Yf 8*i`ߎpP3bӻҼ]MxTf|"omU&H/}BPB {?]Jq4V<\!Jtc=="x|nhͷe(iR G`_򙁧kn`e衁T0+f:5dV*` kM?j|tmb8iO16՚rz'@1+hK[cæmD:@ I  ND&P64vϊo[fzoxR '[#9g4wGa:r9;p/Z2w34X'e?'G‡݊t}W:50fN]78EEK-ï5ۢ43CVܖ=iAnSA 4d44gx|T-*57RU>8߂,0.B,d=ߏ2#mГ`9*ܳ0g$}N߱|lcA?c=6T̉OEټVܸ)9<,*R%r A[l "708OTe֪3}*}qGw:`̭tRѢWosΰ: AJ|m)8s[?H(8oTva,%<;"l|"t[͕= ň6C-XjeHSw)BbtHkk;I1 ./9ou$RE729$%j(èh?;VEm&pTFևN6_I!0}U):(>c Oi1oNWK0e+ Xp:qz77}uϹ?vaKYi-V/aU;A)!'ؓO Dn7MPօAN__ӻ7=Pfd8*ˋq&{7!uD#.fhAԹOPo@H'cgʍAùh3h헴!ы? ^<zn\x!ԗ[㏵"3xv0H))1n)xU/`:&^[!h6[A k>@">悔C{NL!Z@7]HsAv@I$~yQdźo Ͱ{X.rLȠ,(CidBqA@Xjpjv2Wn]PX@!Slu~.opV\M{nOo3D_QgoR\7QKС qŘy :I5<~!bi%Awue{^ J CF7=Qe2Yh7g${Փ2ȓz.싶c7Σؑdm7`+#A#8mj>01a}N]1*jYFQ=*〜Y_V(&cq*Gar"T#hD K<"+[`3d"2KyTNw.{:ڵگ8 ѽDk.8-26(tٰe1T.: Wdxn藉8OkDszUArՁ65uacL=3ۏ\ʔҞ%е7L1KU+hSM4w!(xK&N+ 7TϳXM~,;}hs $>3ݤٹ_\6 2LԑÀqRN[=sn'S&b'rdum?҉+nTʆ0'FՑ&bnhyP5xҿixRs"X_Jgҍ"p4ܫv]|)~η.2ē\6}h+T~d?9)MB SB\G'w[:?zE{Myi5 6+"Bi"Q))D;pRMw>:B.7VEqveET<:EĀH3n`@KhY b){.mo)zBE!`t!/ F*UePEF>fx'32])ˌf<-w-=ύZTe`QC'@}sǎ]_H;qڷHXpan{!zTW駃z%g@y!֬ MP QG<,A@ K]YX.b#2 d˝ s_Գ5p{ NP9%hs=}CJReR*>Ѐ?Ӹ-'y a8&ÞB㬶ůoٛK{Z+_Ԅ֫֬ka|,"LcN1 HB=WU+u.<3gQ-EnUlo`ŘP~{K X Ξ]KCsP"'^G5q oO-ZZ85H2?,;]ʄ 9-7.xozO~ҩ0P:+qX MkV,*NᢈM } ct\ t.Zy% Q; 7`f2}?+ծxÞ iD}/3-w9ޛ'/`8 J8OD{G0S*l֓sl΂2qf*>;b"t-( Z:Atq*_VFD=(=6$x4tmvHM+F0,#Ί9jbUVp\I"%r;#}tK԰x_|]6(wG## ,.>pѻtcC4_ԀOrCG f,FsR J=j4 3 g=xS e.iDcH4ztRRxJU&Z}cHy͜\t2u7j'rOJ >: R 7J[ *4$<; S@GDFGː^вsM\+_Ne74',ߥ d]MDAƽqxB:)m^IJ$+5l=Α(Mo.qP WmÔq iLwB?FEdKx6 V'O޴ts𯛶6f:/S0Vꏲn TOcVq]/.Ih^ $7Do=Sf2R(Yj}UoԙP0/қsNgXK*_k:ݍ8_ 3ҦJβNᒨy6bf*`Q*g}x*QZxahJmV^3ŗ8' p?/!$3 B\-K9sa=Hy5#ZT&}?1(̍eKb๭'"^Aɚ7jJE[Ji/#˓Lw?,Ǜsm6)D;ac`y8ɞU}b%@B֒,?% =iW +9­R8-.Ch.PT\$o(ԸE3Y28 rJ+ՇX<8%D:)IKMdaՆL &Q)K,m6gnZBbNDnɃRiKտ[Ell^xFBc 'qGIlݹ,PkF;//=_"9.W[ko$ Z8*SC#oZ(? j@}ވUSgZ(V =b"Ax$)`79V_T+95n S⮇l. `@1< r@hXEQ5[I]L,a*)~\vgާF>v/V]kEgXF]C #: K4um_x5;J:kņX3y,yK,\jr"JEMMץ.96/Pgϟn*e/W-ty^7+&pL`SȋucřBLЛ^j,`пc&RC CKݭ_O?f:ݢW"C2 ?N=!.͏e3_PEV) #4KDOtibrg-?SfȆig%?VHiE`CJ{yKiqNw*Lgx|΅G݅P0oɳl !dJ`R$W zDN[.suObk).3EXr|r2CKU\k|Kj7_#Xԋ%WlNL]Yhb(P,H,~fȆ0֝3ȯXD@'ܹΚͰw)QAg|"Q?Z@׃YKiV$y=;572z?m"Cp*]13nGS!̙p\\IHO<O%[&(a_SrQ8>,G:/ 8 "F#.&.ܪp TyBYLW2\&vtrhsF?p%Ϡ5*wsJ!%ߑNi@lhRpg<y.{r~LUQL)=]" GD2':צ3̂4t- @Z`xOQhʖOrʸ?;Q H9 M!XdBnݨicǚ ↠ٶ ԡFc٩A_9f5u9cęqH۵eEBzFWx*X9 &YTg{I&c7'tho4Y ^lޫhULKشGժS +p>r>b ɂ8\UW|ңv" )VMۅ|M:+[-*W;ӏ9ON4]wsJ:6l=q^SZZlrG4 KuMV&n[|iuT"Q3DfQ1Ɇ)4))3B2_e`rOg?_n(S63Cp5(H_3my{ÿ&=5@l|1A.D_ߣ%9J\d!`Dedfy)ʸ_3h✹uG'μlAԪ<˓0c>0w~z;u^]y2 ߰eTM-)IqDRCAX<&ϺD$J9vHIsY QUJZMa5xtB7Llmv+A =<OuSsJ 9i]ts26Ye&.fCy$bK95$zvA~Ni7_LoƜ,$!=)x G L``45ҭ QPJPWq93\tY_-t}9B=Eܷx:.{Ij W9b⮫\g|B񀱒nҦ z2ou(Y2pf΍+f_ug e&ILvW:Y1:eNBQ T.GWR *,d=o%PD6D2te$uGt]U74+ܲcOhU͝&9'4 9sD,r_(jԋ&$k@bIbИ !L:*h{,qvO1 28{ -[N7GW >|?I(*P \&~!EA.VI>Lp$.G)T)Wjh2ʭG #+t%eug&) VйL[\ ^܊`Ǜ蝷Iډ\:eD"V<@.n\彅B-r-lN^+:õFlx4ό%-x1T)6DžR ;/V~ _uZ>J)I [IH\GINa WJ,7:OPED}DJb׍EL8if:idn#p&)2(!_݁sF":'JkvV1m?yҨ A#2O̍7b@7gibW0Xxy`6uBd+MϰQ;(V7OL\N VQ[N=a]BQLd - ;x֓ Iep9șh|<'e y6l1&kZqW~C{o)pteK, תgqŊ-ұ8 J?@l#)_SlV"֨@JwvJ`W)PkVg횠AKWy<(tYFKAMo@ 3>wvO4>qxv_ZD[onf}a73f#qBMe2Uz DuUBȓDћE9ĸ@s͇W;m1xQmyt¿rLm&˶C6ĹY1e-,rmlNj d&۶F,Ch#<-zS!LyM& ]6`-vte7Pn)׫@{גǪZO"o}e RS_Fr02=LJ: `Y3L+bm8uRP?u咢`½%6k95=,z qVR=--hx5gHoX'^%k"BWCHfߍWC.D&ZAV  1078R@O$VM^ƑHpC? YzVp6E3&MF:cC/TKA>;>a~O-hqEW$+LNNVOwh'dڸGT!FuU$\%Y##?A% cvK.5DܔQ$j~ˑ r>|9Yi45 q*h8M,^ zFBI=Sffr ٴ XUFlg5Ƶ.'tw4gxRxL՘MT B27qJ6kX_UJ@# Hg !$8f޲ӇĆI;RN咮NHWh${F6QT>6B?SހzaP4f_"QD'hS}?rO6#kϖ{< ^ {M 1+Q\12F`d(ig$/:뾣WNdIP_ȡXoOMM:1GߠB͐J?[Q)rOmlNhM%OG<Q7R,cm m9a6yZØMa$%%>Yގqǁ$bOq Xt>(-I|AoCZ>D3S&nڹ#8ӽ~0Wr!‘t5$nD!{hb= e)"csN}iCnn"x~b ] 3L B \Yd1Z/O|%℆A("c!2t.VDua%ٖvԺKD&mv纒X#L*WFUsV~0>7$zqICd}HL~( m=R)9",;o!'PMnQW3IIay?;*+q,+RA¯˹4}iIxv*,Y33<[ ZI0uHfXJ[-HLq܆-u5 9f#P%&ȑbph B(,IStJTraa9ֹ J$BY"" Ζ1R.Q!˿f`"f{hxOF (?2IO{GYQ1]˲Jֵ]!6 x]ZvN np.AO'mKps(@aO9 qc5Y tF7 Z$lCAZO |}\tGuo{EK7=bIrũl`Y?ل3g?]ڏF൫GUyVv_kA2W^s d1=Mtsi#2֙f*҉bFlʕ`oߢ0/gȗwiSFOEO160-[幡,4h,rK/Eb?*pb3)ilas :ym߾<ɨW]SLa!\`oҿͽCK5e]WTyW.)'5F£N( laW<>^HWU4S =1?M~K Iqz$CZ|y 5RpDŽ1A.j,M}uVm'jҝBa>v;>nu&$,(Ooi5;Dp_m)MtǶ*C 81"Ըi+nfbrlJ{M̌DTnBYfe/QI`2%^JWmvYlB`<ְ}YT>x@UyuQS&2UzR(]'qѺ4 Ӵ4Q=<qa9vf0|.)\gcQ -D)&+sSr압O%\dL[> v~ ?u5"yd4!`V+Ftox,8=yc# 8dxa·yvձRTl/9xVf!۾rC)?}m l% D):hC^IM[ & Kt0 }!= !&.kI17h<6ea) a/PR#pwW TDROi66E$ ۨz(Gb>ٺy#rT\m?`;XjɿXvvBl[[- MyNqbR c Ĺid禭k#a 闔@>"WZhϓ蟒>3lg x5X޴cத|!LVG8 .7 x\#C}B0ӭȠzv9ELłGV`/'%ab _}P@Np-8K!O=Nysډw@N9R:v:VR;cpDx[j&ڶ@Vf:R5tB OZ9S_ T 7 Sd.p*~;l10ËW6OUŽ?M!O5~ιq""$/W;B@rԏ\F(H[ xۜ,<2miӎb^=@U`f-RPi*Q']J";r]0 ߨ|%g?7d(3သ@@شyΔW8bSPN߭0yXZrtAh]ELK6k/Ri(+޵;{,a<8m;pՆGbu*8?ˑves=xcz üSUN2GѽS۬݇B|4I\[ u7I|V)>Jn&cpƜPm;Y]A #Շfr`s_{elg:j]yTha[I?V]d^XXS0䅚~*@6 67 ˅;<Տ`*Inć7Q&VsLJ /p^=/vbBB eئȃ2FQ`)AvW1Lz'X҇ۿsEp*`P{ IG kOݟ;`S쉵|p&D>û8]|Pt)B$M4C5KӡMS',_X,jD T~̜2݅u:/(f'KI}H`ŭmAq$0З&2<5M` {.n !C`, $Yy|Bd jJV'K9@ 0{&gҘ0}i?M)/I!ީiq@9y_wV EUF8 8xRmtd1烊?.H2u_:}J S 4(yhydX{ڀIc&Y&Q!>%rΕ\-gl Lr l?Vf$+{OG}B%Fb;؄b=vc>eL pt}d-e 4g&,7$Ȟ>Z?ޗBaٗdӪ,a,ha`9f66m䡒iM$#5hpɤN+)r5V/;u,0kg&Ŧr-E5eC唐B,Ng9kr[+.E/4uxi4D(g{}+U0uދ44B«~ 7_J9V,q`Ij1r,1?.InapZXJ^rz<Z_Cc0 D86LMÎϡu Q"qS)SkUU:UYPmWvcЬI._Z'+jZ 8Ovzy}Dl9%i:QȠQ]L_Jٌ5*paE{jpdxea-Ö^f8D k@!W~w\uH`%^kq%#-Nw$-Y u['n7'Na54CCrAg H M;E"uRfcBjizW5sdRO T]oQV Xŋ*\XxtDWE[bPn{$~D[e}cVʀ eN|Pd)hH8Gų%!K'fBJ/ަM2-oa ݎ|q}kSpgK5PYr]F`y޸Ϡ|.)*(YhoRƒ 9/ 46LnSP\Ÿ] hRȫ~*9*0vT7𨾜}d9g@G-6P!GRKM-$.OIbGQS0!ֺ_2ڊPAqB;5vކ@Gȱ-ipY {qTJ#xN5S=D\jۄqڸaV_;~X,N+"9ȷ]Ƽ4>fJL&h_Htх8]9J  '%3am~|@not./ٯCpֻ(rJDf<ɑ_X%)dޖ‚ ,dX+{H52[7h8koڙZ6FM1{T0N=ޡ"7j;1й]Dpn؄A0NUe3JZ*onH%ˢّEIӁ||/)2UefRzW9*52~g[sqv uy0)\4V.iKT_$sKe>T1;X` Iǁla 1A$lWĵjDZD&5gbcMM jͨjz (#K )@D5si$)(a &[2 x&WEl hM!]f}~J/'ﮱ .8#GfW|ad3{32$7\yyzj[7"A pW! R}W"L`V@X@VmL'֘cccdDT*QbOR@4mY2TPhBT\?X{Zndï+rpP[(p>`4x[܋k,[9WC(=a6;r*ՒbPXu >a̞u#/CVoXg4UgRa!,> }:X? Y+`#UwfhI2.mǼP$Q::#]-H }atF xdPN;at044{rP+N~\sS{Rы'0,7U9Q@Y}Ng~ vO.YIXD~\T\T%9*;oorh0,.K6V\/-Ќ/Nx˲Y AofR3in|z`e3DrG/vαz{%=Ri^ 歏\\zd Yi skG_d!,1w{+OPEXlflp+kF2[?.GVxXvf 5{ʂ&NCɅcQ R;}s+Q&|霴+䮱4\;6mkjSq1[ GmFl+<ᄅ=WU#X $qg<2'-u>;9ş7d+JkYf A]T`@cDg &D  5M~CqB~::hJ8 1lngo}&bGG[ۿ$%6\ |Lb^:tF˩,G*V$y5'-LAMz>' σ=rz'_i\U3xJ"J- cW+;fvҊfG\[@SrDwl{.F扠T@-]icr/fY5q_]`YwV]I(|iZN?͊!H*zȧ?7k'XҁuїR;ZaG$.H]`qе|riH>L; ݨv*R6noOxΫPcQr⼉PΣkQ*;6U냂_ێn%|#%D{jpNAh4_u }ĭSbg s(BLjk͗kA521WRc(/~M~3'zoMgv\ү` 򫒈O6gk*Z^Б\ſ2_NB%ƸdnW诖$HX%,׈0r%;pbfS߻K?1N@?l4N[&EwxVo W˝ eHRز7@oFy/5B5F#|`f#ژ n 'bg,PL]hr@V&n0Yi6Н:GyA&D)1Y/yW4r4FaL"σ_sү, lC T&kR>)K̺rv%vQKv#ސ. =z6};!g 'vV[<,t!tj|7L;;P l2Qĺ3+؄6{Z.c0l$ckI~m.lBlG H- o>KiNJ?rE'LG[*n B,iNaGؿHһ,V7Uާ]qW3`ɸ|{nB̓\|_;]o` y7ayBd+A)KpNw=,ѥJۂE4ҠNtBB,WUiGD1G&HYƣƸ!2W:Ka-5Lmg+n/ne/}f8JZHӳ̓cAq'"0ii(E ̑1YR'ֆK'ie- T9+ojAOAE,G װP"|s gO_qC#(bov4SÑ"_JX<֛eHGBYLLok';AG%pZP'lmD{FB%TQeu4%TZg>@OUb"۳T0 9#^lP2O0wڥKJY`**v ~o[D _ t IYf̴#2iB.@_~TzE'{HMpF52eE8p(s]ZNZ)n'35Bu[AAhF݋ߒPlZL%/& Xۓ[XI!=-phGa@j#- ء~2JE5@dz/Xu&Y/އpW=ǒ5JTV*(4m'(qqo~^N`1*Z0_0L- @9P $x~=PYl&1ONWSg)p-ek[CBHM }-~Bߚ_g4b |3هD]HtF (,L@P HJTJ;E F{ּ985%UZ00my>ll7(6\%OXn# Ĺ3KYh{[\=ѭvQ{ T5t%:*3}h SNS݌T;|sJbW_{YMulnI¾mq,SM (JVE3ϴ37TpO6p8 JOZRF>\RnUݫ>Rq-/9Dg (i-OxtW QzN'޹wW 8v+S]fIj0lJtSk[1Enm= 4wNUlڽ赳8_y6LpֿүLW(`i XOo($RC'H0-Z$ro5޸ Ti9ߘUs0 A4_ĵj?>e d)wcxneȨ&|>+]cmaJb@+^~26'c$"D&W %şo)܁OnBU4kgOL4cG[6WZ^N:Y~a6ͥ뜟f)/gݠ9UX)[g%oXKcRQz-W\zS>1"7n2=YrHpN"ٚdg|7k*%-s'^eugk0pQ0%wh|lY`28087Q6! J,@Cqy=[N8޸7pruHQqv]$=;dv.8Kҡ#wG3uS$E׾bx7x#Ldbof{c$=OS9mztGzYsuGVk D!eZxK16{ǀ08ȵۛj;zZ0)PHi AWa"8IEQ`XCsUfFjMf ޏ,!և!"|ǽ#gORњoCJҶ0B5@]FҊXW:2r8z@2Fw;}{zIۙqf RHG7j'mV In cu|4.,kil/!;c𙙴2"Ҳ!8Ԫ3\ct h^Σ<e*7?QjG!@Q&ÿe/E2d"E_~o "LI}PMHGEAhNLY@AE,G B@Y;WKp0.[&&As%YQ-DȌqmj@m9K>Hn`>27Bi@?*KxӒ"4,rO${/8ظIޣ>*ٮyaʢ1VF"ܾhwU{0((}7Z1CA^|'fsg*ﱵ_CuBq† B<J=_+:NY.G#纨b5EU^*Ƭ$۷lZx4o&aneFYn_>=} xVyr]]W"U<{;Ĭۏ]A%]zn@^E 35yZV…>噘 ?d"ɿW떕%͵bX,)tF (,2órEqHyy)m̭%o4[(M#u({g*n~%A26ke;_L*o}ӋAKt' &{PBY08 x?|e).V|Z$ЮhgɏCm. 54MKB+4Q")ZޣaօCTئw-F !k,]l56i] K6J0eB?GU!{}}o˲9A@Dg P,@ sڔ T$hvʙeDߒQBx1c䠷cz85Y@y{Y&8Xɥ?xX iUBo6 H'ӬFP[ʵ$l.KroD2ob[<zd1o~qa>M,uʆ|[.3bN _Xm>DYdqCIbz:52g HŴmU ߧD[pM2&61-{>EeiЎ4[7 +l#Y 2VRda[Wz*ЫzTA7坷 oK=T5Ym$ԋ22cX(]0[8̇ A4';=ʺ!]`5sen$.B쒓@ﴀ4msY j0i@!),S'mi g@YPYܔtckO_xb>bxb*-ؤf1rRiJxB/x#-*u-`Px7QfZr5MvmGUNgwP3j.3*HlDvkaWN4 쨱pꋆ/؟ dڃ`mBs3FY4y3vs,M}ztnu" }$w<',xE-2}FQL3,YK5ަwI*dfp(ɼ,o6`8\|#`&u6 l5|P갔QXnޓ?j5*DH[6$DvvZ|]? 7t;n:=y`㘅j!L2YGC X@R/%rdI 32%C4: Jq'!CÕ4p!Ixѐ@hObI{8ABD{"[Rv`ipK-x'1H]7@ Yc%i`M=Ŗx̪YHAnG\6g0ꖵf5Ra_'wuhajRFs_e5 m^!NEE8i"ߣ°SͦȺ(mWOcB4.Dg &D dPdjrdD`*Tl[cmj?]jAM 1eK?vM:Yy U;0,ֵ1ŐcQ◈=z-0&T80NhmNSZNp?Ɋ[Ȓ-3JMhZ׉0akA04_u }4hj0,uM5^_`m0+%1:ԭ _r0mz/AFN r/[ԐuD}gMߝ!l@3!8E_V/n栧"W[St=Õ& f>1AT(ۂ赠eJunrFP: tC0 mF5*B >T,Åc=ȍq_%]3K!&6Ƴ74\%&餖wQLM49 (F-ݱwYU6%@m4߬T<|AMڣ@AT=ĵj1ix *nd/cA?ff>|9l8=^prfXEgJ1p:t-D0F9K(^ Y(ԣX O#(vaA3#ƌWO'è':^˥i%TGn~x#85SȝYȿ#`SrC̙Eǣf 1g4U[ԹJYSƔ@RMF<]}TGGO\q;A̚:1<.,%ȹg+eMzNsuLA=1`ArE4LG (t N1(+q325)Eʋhh?>\>O#קA.N|s/߂)Фa).mV|I_'-{_0RvPI.TGܙ78`uNc naeY,V$?ĭ}Bsw`Ԕ?$N78x %_=J^Nuvwz> T辱G#|ܔC jn);16cΠooT Pew)V %_E+a,: QY:zy ;X|Dg &D &M=}}niT/ηd< hڇDKΪ)7f~o Isj“ KE//?<gui {:XiHT%I:-<,?)e)ހxbQ?p@Zy ǙIzd YNA4_u } OwI1-:xnB(#nV`GGE9Գ{WFk?ZT^s,~v:.nZtp\r㙀t/V4eHfʘ}]=aQQ?'3d|G}=Bvg&a|bTɎ  r9L24=qqd2U@Nׯˬѩoӣ>R<S ѯ^ djWN\O}-T^P sYݬ3}s(QGEGj_B+"l py$K(4}? nGY5ݓ9K|,wX8D*͜%k!EhBPRr nRY5Cr 8-ɜxG r>>%1Dė4W:|JclJN`[ٸL,E4Am}2aNO1 $[AE,G (ogmy,?A. s]}Z{]N4r@HlvغV*aWZ]0GMZt3CC"BwS^̔gP;"0078!GS>Y)[l;P00UOq${|"50Id:d8 ˎ^"-Q./4/hD.$E]fE 1;TIYO%ָ;iAEU^ FQ&a*;,S>NM!;=&tF x79k8ާ$K1t a!W#ؽ^:(X&@BN={[\U?S>35I²V*Lyia{}a'-:Yc L=JvDm~]p-X;ZvhX4CuDE-ں*#Cl+*!uA\D[G]sDz"ʊu$gu<Ὡlm׼8>yƝbtZ/Dg &D "f!|Jm:FzA3jۋX1#婶6Li(ꏔ ̅ D 06_r@@ n̵56eaűV'-\ })\=},|OA4‰u }00&#BͶ&K z'L~u&7{}ii iQ`+pCWIfC&REti*M̀*' Wz'Ȱ^g#Ɨkp%K1 ]{Qh Jeg>;Du8Z!nߏqٖWhnc4ay$w1M-mPJ=ZF׹m~lԍ@9T#ucp,Sp>ED _{uH*Uk/b3ŇMzR5xa$ܺ;"uۺvB dQ`+"$~ ۅyI;q`3J<ڐkoǍF~xsS2VvޞYuug(te;i\ɺU3Ѯ#ER,#a=Dg 6@ AױO ̧&^W-$~p6GZdd*W7gZYGpS _"z\kq" ڦ>;Lg6Hܿ"jA"=ĵj;F_)ɼu>ʊ(H&o`3TI2/OK2 Iv5OJpaq*%aX6wyQ {ՏK\pkZ{ؗv]cw2_V }IQDTJ_#=0;VWhJכ⼚`V V0.6U@XWw8Qк%+E'l~ߵGQU7)pϨ//ênj@|z!`}gJc`&a5A" A@E4LG !)L<^2_jJ$!^C-;*1g仃!-:G`|9=6 p -B^fvOF6᭗^ fsnw) M}MZIWN3NX̻R@}tF (,2ór:-%fP8R<ȳvsFaa!rw&A#Js1e&$M=>CaDg P,@ ^(>ؾɳ}_^ iAf4_ĵjEԡw7/4jSw| `١o(@;-o8RxP̀<1;ߣAx.[ Fh,BMC1*ĉ;-ߑE5('Ri=B޼qϽvv4+D߬>k 3f4Wi8kc!Y&,bw_@ 0t]xٜT߲{U*h> BP{6hڤ=e F}xvP[r$[Loc%"&n!s=2#ZK+ÍiQhli|H&9wLc#w'M{{;XG„ĨO1|$Z BmJ<1vFc_з)FQ 7s};]q\"7 T債!//φ1A0?d Io>vKwRRýaӂ~0r5:r™ey@ۘR:UMv3+XoT&V ΥO Al kw$_F*i֔-.}ʐ)Bߍ,8t,L8'G"%,m \ 6ߙ|dRqi!f_"9!NbGWKMn)/g!?x{^kU/4ښظaTx#4%A\=E[>KwW - }*΢ Ƃl ӯ:(dRE\u&)#H=6a|bc&h1Ǵ}\z؈+MJ3%9zJraVCQ[L]TSk e$,uwսȦWlh_[!:Ϭ}4 gĎ-}:8A'haH[0.ETj6$xzfU BzIw$0?6?>ʗylg&H^ =3S+Լ5#%H5Xύuc6+PؾOҘ6-ls'$6˱S>k-Xt/(PAE,G ѿkm IGǀIDSl1d?fZJ<]gԌ>O}kO=:&qZ9;+IP#Ē'$hoB4c4|ZӦCrsN bcIR)SgU^K~a^ʨJBjm ' ؅G/S-g]rha [Ò&!@ ,V*bOLUwČM>jo2j&v;xfQS$7NhM"ݛ#۰9O(ۍ qi2Ȕ|wq3Z(R $mӆͧ)HVt`xHS(:×v/8q YPnjPk#Izv* Q}Xu espg4{3gk#+u8#İd-[ op `]PnKk(xzsi^WW A4_ĵj{UW\֢~AN}fԕA a2F tNgCۦ`J垘VHO֭ n>} Z-E|7+N!; VbͮzQl6oi4'l|X=;-,L6+(gY"Bʭ|+%$K{4bDĵǯ;n>ũ<5@sjrw`輿{d _kh!zWEu~R@!`5&+҃tmp'dD/? pPHs@\RPn,?،hJrI^2qˬ9ZZ+Dr6.Vm2tȔGQvc+ Kɗ5]ӏS1q^c,yzn`$33ƻDk ƁsY!nˬe̤)pnxS:+st/Ѳ+eHWeW/H*O&MQh W[ " '}gUSK А>\eftdbg? 8E0-CF#1g2_Jv(Ka“b"ETiHQ.Kz/Q9MQTHeSr*Rj-M $wY⫕匟,xye4o7[~]*_zt%9=` )Gl& &CDǡ=B7od茴0/%8&Utd :fԈd\CtiMQr[t6T=SKcUf'`I;q&ƅCGy ^>pO| =n6YaFmZaO>}$7Rs%*$ߙ.+٣3pAE,G [̎Ҩ35ʆ;X _R( E. ^ߡԡnv縼QCg%87cdkT `JԵtOr*|26ʲ t0-GoW36PտU' rXI$N2CV&kRsרPdA Q8zcV͇Z8Mbo2 z~vCEIy۵bP菩ǮTmHG[kEs5/p ,S*ؽ\P$|hVԔ.4^$V AO9,p:"'e@UjEmN1ZҲj 1W"gT!etF (,L@/4*A6@jXb5'B& 7}&䃠 28(#@tI@gNbO Jmxtf=b,B%_b.1e}fZ暝ws˶[]&XW_-7*#p8;QrxVp>2ұ0h"~Mb];,n9cO̖u ] Ç`u?X#2[AUmϑbS XL%dM썠C 7  _W?ݏ- I]De@Ǣ:ȌF!Ŭ\- $N hh|q)JG@iم T.dCs۲Mcx4 fѸA 4'@HW*o'_#>f]a=`mQB57u`E('Tim>s ?Gy,B' m ƢD*5(uͦ+A#lUGӚ$ڲjr0KSv,̢P2<- Alu㮥+2Bw^J=0a ŠE 2Xf$s Ըzo' Br1Ѥx"]"u_?m;-xX< #K/?_sM$9 3^93OQqGiKBk+N+&鰙]ŀgDg (ك&9P GGHP񱂎+7~o^*z,pbA4_ĵj*邅bb8)^\]`ʨ y~ZYvvlRkI @S^Nٵ1c\0kUE*nN* Q5Eu—_$HX vOB!bx^qI;}bD(Ⱥ1\,DVSxS #~XWhGfTh5C1غ.3&:h!6H^,\6.>-@ _B/fYOo'u[]:VwM_oVZp7K?([K,.°<#=P[xȕDW.3<<v{hϭgZ*L u]ߦ*,f>xM7s0)`O\K e|> |gyp+= 2 ~od278-wpP3uriLs%M͇g&P>Ѭ@ەy3JMC){kǽ@>̡0{\4?˪瑥v[&QE'u{<"=!iSv* u0'JZPUdY]N``:?@'T2HR(Q5BnB3es{dL4-1nk=Kmד5I&qɟj۩ڤ?|Mn q_5RNRP)zP $D5M<}#t2ҭE@mr۸z1ar ,`ZN`m|q H.}>]wSX~A E,G (q6u@=! @\uC@XҔKEd1θπܷ@24`~HT>rӔzCas,U&6C6UmEΕx׬--IѯJG(;8eB]Koȁ;S@ 54"" Y<|AwY@`_0iKWs͓ 픬gOa٨Oއ :Ju`}*GJΡ?Iz5ع$aM^]?.͋IXِ =([ƅ5Wג? /#i;PEcű$][p Ġ+4tM6)(Hơl,堌v4#3_o)w+WX?Yj8$pH7Fڟ}i/tW V*mda8хƿ윥+Iw>kh b6?A:;GOO )"^?ŀh ER̩.Gp}n@*=AL^8\AVH#uk"Y頩?&YNKPatUZAhV%P[ 6o\_DӒ:KL{媧.OQ@Lc $BBQU@3q:lɶ&(9嬻7=}AE,G B@Y<VZD'`8FTgb"o&Q̫SЍ6VtKCfUçS_Ѵ>~5ZSptF (,2órG?P碆i:!'S* WU 3J cdRkU 8I \]@1Dg P,@D 4TA4_ĵjBCۙ'e Z&r視~d= T"c -Q )8ѭ~3JhB`$ }o\mԛ6µy Փ<樎9ԧ,GW@>"4o|  yq=5ٲ|#4˒- Qih7bboTi/9xpCSP ?&JOZ8A[ d {7" p Ir*{/}naA0Nq%jHNvŜ]V}P!($d1ݽk6OgΫ녞Ї'" rp  sk"B ƅb$_wUTEnR!ƝMж[nK҈VB %dmAym f#ɦi"%.(e_ԃկ <^Xe BmK9~|Uy*4))q~`fBi~e  Hs[@Xsx ᚊE1H| ,dD_$5?si<Ҹ}a{e LR4^kN[ ⶲÎ0Ӷ^ZRHG6X>_x0lAx'=̾uX7 /VNw$Td>HcGюһnQNQU z&C^ڽ |lưn0qŚ*u)w:5y8o 5ʔ ZG1[k9A]z) @.I\$Z9{| tF (,f.dyɎGD2g2Pv(\rBncD-hfLgʳ|%`__KєTMwB*R?> zBU&{\4aj~F7~zr,F Pg{ \kGŠpv‹KQtkiD͘X\u|z{\#'D*_o偸pֹñH=g}q"+#ρUpw[l¼"C`5퐔9I>w}dcA,^^MhН'Q*d`D\3>) nn8D-D4Hb0,AcDuG2x_nvK)#\> 1ϓd\붔, 3A. 9lmEbà nxwTn8t֬jplx~MV `kk5  s]TrbIxY`VT_kϲJ?8gj ƽbCZ)ڭ1iUgVy2nK{G\P:Y[](H*:.+ؙEf#orqo@#l F'[쭵v=W!QZ%0L(5!ŪA>\6[Vl4f) ~!$ \WKџ "%|FQ@T(R]kYFG9[ AZT%[ ) .cq)n[Xσ\!#0%Nڥbt̷:.Zx:k%d[(o~q<>jѩӌ9 oP祟ZS&l;ǎj @皧*_~(2̝>)KYzc4z+m?va% ram$_Aڐ`ꭜ6QgR7xfwN>_ł.i\Bom cyQ3AE,G [̎Ҩ`τ3#E©\ڵom00 ^! <ѦG귡4f|hˠ&03`L1qz֋tɜXFY]Y h'iױ!۾ 8744&-=;aQ=AsV܌B* %*7x[ӡ4ƷZC.3 Sxn)~߱#֥%x-7Ӽm'Q CV2h8?]hWu&5 `Mb}qk#SqiF!~ixoq5fj]iVr[ԉD.F>[ΐd TmM{>1j{j5Ķ"NC^HkM|) D-ȐҝBlRGB."uOR*F>*jLt{PvqmQy.=I%@}W/xVEAL9cdrHb?`>-trLIπ+^}I4NL㳟O`T,gM\嬉A2*ZLµM+wL`dH Uyly ɓވ$z14]? `} v<k.braECc5JQT[͈ N_/*{ɝ0TPz=rr1,_:rPPG|I<ϑ30h<jƴLYn֘"SҲZ#5fFe@7>3;p'Nm  Sl ?g2&x Hʡdњs]xE`` A]aJyEsmATd߽tz"h24W_Nr9|5"':+%g.YyӪcm&O#\@t( ObP/' RGζٕstj/sU}fKDwLTݗ頇m L!5 {in3A >\U*x'Ѡoh|QJa_mۑz1mim gΪSHH D;Z+NsHDg <R,Sxh=+:puWOE=UzvI;tF (,L@w— 'lb]##7>K1_8i >SQ!P& &ј6GXc'|X';d;3>֮gJh:F( ըXSҩ{ŧiR70 Q+bbCp:Yq;4=8 L)+CY3M0h;D,.R 2dG&G`kPm_XGE-<2@+q># #!.wTe:>U \c;Bzanr)< $zruIR,#L p#[}-`u΁M;yMv(&=Dg (ك&9P2 _sK!R^%J)f?i~} w*T[G@s,\0X'lX7[56vⰵ[ݘNL@8X2gU" ' {CIwnZz-NM-g^ÀAEur<h$W@k$c?OcK#1흣!(ܡĿEx*e vY2OS}~ Tju0.cl HJbI^i&/d M,Hh1U(ω\&O5Dš;YH*8EZm;m DL!(zU)奥rC,K]:r-Qt A~];gyTC!x?pGWFAՀ S  A"4_ĵj'M¶ӯ!vo$vxG%s%p;sj.khaj<`Z_bR` O=6* '2&6EVg|q'ɔK@fj }JlN.};_FtaE^vEŀtCh'J>=*ӝP%W:-:9ャ=i7K l1Ê~4K06d'صt>Onk)^cN'ɘ Fe0h˼\D+1F*"ĎAHj35'e>o5WufI=TqjwAz Eyu/+X8l7Yt1_@Ϸ|# 4M6f71+3}o+6aT{i *5`zQWz{eQq*QjOo9=A#Na9R&I R'2X`K:P2˧CQC yn'ˁzI%7v/PzrN}+L, ~ӄxPa-E߂9$e$N29 em˓}R?6gۂ@"UujOժ9"fC1J&<1EǐZo~,i7VrG$c^aI~_fڿ0ZE!eA} {\>Ea# @s~uzMh5>U<'#c1A vب,.ta'쌿!7Ɏ` M5}$?P(N>Zt4qRB5v=2 +Zj~P@ov%(CWmfC T7i6 )^MMEmVL+[`KzNM6 1l]x@PDž?KsemxN Yg06Kh@*\1O_k.Wmۛ_zxD.Vun\U3xř0BatFۭRͅoI__+dd! }bgTAҲqmD9MT.9EOJ)k]1Tt'r0h}KC!}cX,K!ӼM.ơ,<᪔ES\ !:]]W݂6+갖LH r -fu얒ٵ9kc۷0>n/hRG=5m~w<))+A%> NHtF xFfuAخs"+c YӠFei1bK۫Sv_l]%[=/twBp^騐&n#0G%{oA*[@9Ӫa8*F3gu|2qXnkgG~Emzr!J(`~9zh qƴu!n]<9mt{^RРw~bP8ڐ< C4f6FN5Ћ&$ 4K 4GON ݎ'/\ŲtWMMqͿݮ2qij襇dr~^qaDg &D [b&aҲ9pK @Jh+zdNuV@+@iKC"6"&=u,/y=Û"pWW'?{=~p;dK$bj;yzŸH= PƦjxv~zMn8Q$?џD-F nJq#c$ΚBbAVYJ%4 L&,w ] 5R'Ub*(H*zY=@/'nuu'_ k҈zzmw}3X+t9Xp}~ܸJh` Af4_u }}ypGՊoC+az<`DXN%>H]eziqGFcm2s=n,lyu3~ ;`\=w'ƻğ1hݝ$7ufbF'mZMpyIsT?LE-:ma 튦Y#L/|9ui)q"6Bvi@ +jhҢk>qfYFLo8~&q SFCT80N#qxv4uAS<=EVOEzfsū'`Y@BgD"Cs!\P&CA;d [Od)pOv@O۪|[Pђ1j&:YĄ$w׽} sh/I={dAgV&cN~e|B ~WM-/RZndQC]evsH`5DH^i;h5yc?oglq<`}Pz)v._In]Rl{}.5i-1@ÿ= jאŅ|F)ϞݰB ;lqU68Ts/ y_`5AE,G װPG vvNצ8jC'ѝHOInL>vk; #akMG\aXk?zrRTe&\"m`}g#ׂ|O [jC{Nn pz<${KqjFĕj:̤]--]̈́OϭkD̩ڰ50֣tU$wPaɀuunU=4Ϗ}\vTw>P=}ń9ǿdL=1߮Li-^$XűlިOzL ha8}mx\ĭc|-Ij>;4͢bދ,43 _ W~&,0PǘtbSFj"/wjjMPi'xl`wtF (,L@1v@NTțTb˄gž43M P@x k@\ c~?~U _{;4Pʹ:H>mJʇ{Xk$(l`0BΣL@ %Pq6 < ͿPnٜRHC+ B\vhЙB8ZND0 R*4aK1ɴӹ ) Gt]*G>Z: (L=`}uj5q Lmلux=!`WtD%ΠDg (i-Oxz= 0eFN2aF25#usߗ 3exۼJko-l\,*v2[8ە6'B/ K21B_:ϳNӼ^,BT Dѕ'Ѽx\{HOOYq 6cݓ-⌴^cҩc E,:ʅJAI7PHb o}: iѽ? uk}7p33}Sytû/8Q'FdPˣv46ЫJ7wn \u mfJg;(beJm: 4\[{}QK)]:j$J}!hA4_ĵj;!<L.']z[&9`Z,Rgƞ6!M%*@}7OSq " bC}ޛn vuIuiDsqBN1a/k=jOPb;eSpt<1M2h1LJ M=q)Pr0#8zesfx[>6y͡(w^L4Wkb cǃ4CJO8}ufdV ŘpAE,G B@Yר;;õ?oղ2,Dw+(^M!m1SϒOKVEh=tF ;qndF]^fA^o/Q6Ftg4qj3ɮEWcLnlE}|/=4&ae]BM|cͻWFow5Z#zȵozna;8)y8A'jb[W $L׉ ,AtF (,2ór\3(Wp D#S&]5Dg P,@ 4\Rz# T A4_ĵj >\/ς-AaDeΖ#5A m2F_YF٣v 1(?v+yv[ `sV5bGPfԅ{<THg`$N0=|/R<VC*@Tz`Y }pAPx x/rne`WX pXѳHQ;WIzKYT<ޟ&>I߁{r:? `qc7V7 y1ɟ\" 3EBY9gĶV:V+"2NՑl`؏Rٞ ? eO -%`-G);g6-|tbjB6qv! u{*e\BBْ? 5cLa% ҅Ƌ>u@;Xas'l dL +VK2Y>l`ހU/n)xB8 FL~=re8o/B_ k3[%=_k$^]`h&3Qo:o]c iOʡmt7FRG0A$qN-o^A ^>V>h+]V o8= B3tť{ U͓^o7HNIrW& y:w2lޜi;c& j`uSd 80t ].Nx[r`w8Xy , YFUnA++k:˸&G:Un \lLr.gUR76GQhPj;` r-Ӿ~ ` I#rn<.T.ЦLrlkcSQ-O#>ߛKc:+wchU 2}RYq훰0m(%E pWyr3dfĐOx̡_7{`?Q8)\EZ툶x1c- O"AaW? U ~PGF_bQFMFh"ZC10fxdO-Hx/W_wLOv2`ȾeRo0zsp R)K])QSGJ5sR~Z_Xzy xڑsSDEPd(ZIaY"qn+;T]Dk<~[u> ǽCjR N瘫_=#p ?ދ_v g4IN(첇fw@DqAVLA24_ĵjX"\Uy dZ=Ba۶%Fb3  CdR'uLq|}%cOu z",m߷+}""9 ZzͩV[b!H1Ly惛N^d Up*SA-ODRvM^t'T_4 bP.{KꌙZCSx׎yhez۪5%0UcAm±tG y#(I؀$᳅׳||]e7 o-`l4Gc&h.f[Mx3*ȏˍv 2 ~ҵ*󪨙Y{} ըaZ\fY{Y?j}x%^Wcc2@c' >ʟF|f Tib4q;⋽~ 4ܣ DT(tzVŎy(=M!wEvs։(pv9c{W[V{l&JXLGp9-9k&[ڡTZ$'#A%(yAL'uÐLIlC(R]yN0n%3z)F=u<> K)Y3+%:8DQs)*ٯ|t1ĕWd˒nin]ZVc"78=3Ҝ|&e~ېNWP;[K٪Xį>z"j8. \ s #ݤ{Ĵ~'Na_#q0MAPE,G [̎Ҩ.wܣn?@GtK 2hs!,c,g-t^|L쐑{홧 g$PJ،-um>Η#C&rT8"ͫ7nT{m'A$q"Uv#H//;O \꼴Ltn`AotF (,L@»%?1j(߾N<"L[XsST@X R IF|}4\ Xvܺ֞v6 _6|#ߩ*$K}GSLbμGAp~/Y-Rv3@hޞ3jdY_*R2ve4- p(bR/L7}pm\g5O6An#cB4zz}U@-w! :μa/4@2іZtj)68GZ0Z.>͔CیxvOp0|h|f7t(drĸ4ۏ$jO>V1J[ƒ>a uZfU'^`2SqkaZGoe.|{J5)߶[}#yŸ3mp02Ζ295X- `cGN*}L{$`SJI`|$lbqbQ,t!]RHS HLao XMH{_gRHMWMUuXn`+"y!_n"@WNG"NN"W:#a"6LDh-j\p yǖrH&SH= 7 Se8y𪌖s#yD@ Q}1*/ydwS툲Gԓ~Nxh%)Gxia״ 9ENTD\*܅!ǡ<,y.N3Y}n3\1&ds=mJ-ω )=Ϸb27- <#)ſ3v9!GB |3iS\fSh`-cm8Oy<Щq;yʣgFwa]`2t}v_' +~PSayM)':v'f>;Fx:Ag uqLTB*&CҁF*M̙tU(P,u*ힹuhO CwIܓnc`%|ʹϑ~?]L.9RCQY-mĻ0ug ${ KC5N`\Y;K0N,u,*"^UMJ-u5?GJ#^% b ? vnQ$=u'W̮W)odQVTx(CF$O@/&AqwjMX#9BZQҘ[$4q/tY_ϔ/X]Tg򬊣lRQ}ewRCЍ0#BVlfް<" +gtQNr!&G(-[#\?b WI`,_8w0"K3|l+MWd7 IWU|h,| Ty=9bo"ϪtL+! קj..UhHL*RE,U :.,e;F7w*_pgnh 4n9ֿ_L*X݉Y̯캍I{"Fmf nlr̂X`'[p: CR㪫D{?C UN G;sӮRlɞqdK8|がIӔZokaI%'8[Go.`ު~%kaE*SC LJ*uG2~1Av%UE*祐!L%s2Ɍ_*>ty ~TkAE,G װPM,}> t{Gvƅ}8I VJ hM0ޘ5Q˂ 4knZ[b*lsa5$PV}%BhvЭHqŢ0~)iVWJ3XoQ'71cUvZdt"-C>e@u&R ї0z!a;BDQz8 ];67zEgD @6 =屴M|O/oRRܖ)E ?o.Yk_ii.JE ˓-}j9 Q(DZ\c0 h38vT̳ƣM?A'ld4yoi~|ًIj@[;!3uw}($ tI%Je29%AuL| zzٽK&dAVH>"˪D^HJ0)_.R y.7W*|qHcX>5XClpki}nU8̚9>P}vY@(o)VOq< `^L44SیDܣ >=%[cUtF (,L@:-sq|}$ؿ9cOWնL_bMG_@X :irCo}?-_Q+Lf׋eM%/f“4q6qH@jDg (i-Ox 3yloVDlQYx uX}pG0ic9\l0}4S D+?іޤs ӏ1!Uڴvua";GC>U';.Q +1B~ )|r,`t7 '[ !4+|/YK2X:p<?s R['c( C^>N{VQ kU,0S- 1+f{g ʕ}^̝c;ﺩ w | V*)X]&$>$պp* <]} WZC|.C;D xV~p 3dveF @hoofPr6a*oJ&iaY(xh= /i8Km6_*$ v ]A4_ĵjjW՟ 6 Հ]P#6:#bݷ`;ufxwȞ-(J҇4\lG*R!Gӕ>|4[KM3EP 80H  >`OB/d8\i ߱Q"0\LL @؉LdeBLmɬWu,H30 aI+%q@:44m \tCte P^-dxlXV6>"ޜ]$9m1r^a# KYhHLHPsC0c@\%.G;ӸR7*"s*2՟dw?ShW L6GNs5 K :ePKdO;q=$8aoU8,+^'h?KϷ[i5i;;oZ`M*x,F 9OHڃD*2%͟I1a?}tbOt()7骘D0(NiP iݰXtq"mԘ\CxEeFl߼6Wm\ &)?c'ʋNƆ'zߞ=5c@%VRHP .1;F 6相E䂜P1;C izj2n9#N]N&c'p3QW'O-(hG"dR C\]_~TE16 ĤC)kEg 3Ϳd-;tF (,2órI"Tf"Cal+H-WAĄTIT vR; P۽3fV]~T1T'^# OZ!.J +V|(O)D~RY=s\-p8^\Ncry̐¸'_^i AqTh7@`t\Fj3HF o׏uTY0|@9hDp7kV 7hҴt.n*AvMM|ں Pi;v/9=RneWIZR*7l) Ohj,@^=Dg P,@No=GO;L/(3!B]p*Pڨ1GSU`"HL8 C @A@E,G ѿkm IGy>?fR%oQaX8"Q0#sTm @$*!V@!"F.A M9\]q_}Q`b_iҶtȢor.4$T+-߱]{6?} @U*tF (,f Ň8Nh ovztj*{.'-tΰpIŃv_LnfQB?i*!vp UJ]CW~2@oVgi3:"Tok$a-EkqKrx!m٠8 :UX'/'\aDg P,@s׹Ɛ.#zǏǗ4;ײpO*,M8=O9FUi ѽ-Af4_ĵjSY5(/Iw_]]VʼR$z=H&f]  ]n$\X'gd\N1-SOҿ?]ǒZGW> @>JI3%=ƮHP;*AȯCnJձV߳&M-,՟커xHUUIoc4.B3+ );^]tb?sKGZ:40)MF"Ov6sN")q4\׀cIڌhDZ5j}:+ChK4kCQxcX}bnT=ʕaBGR1%o<~ā<`=^RZsJ;-ud_~=?ގb4Ӊa}3h:~ D ;8eW^Sɱ[Z/t)dHLһ087Oa)C,j퉋i%%J V0C{SOHO>P6u7} >J^)b€ܮ CT_<҃emlU++Ay`Nfd_Xy-0-U!yfuCDTL34V4z,'Zk8P[%%tņ mTJnPȐD x1woz@3bH>bw|r;@4Yo*,=*q _ 6sU%뗪/*y/NҪ<'O+玴Ĵ΍I>! $)}Ѓc7&E<:rq^&ɆKE+̧TE֧mrCcq %:_l\$B [md97F';|hFݢw{;^BS60; ƥJD 8ǻ+^+N2j"8߳yZ-ؒf/I>=RO-{'O Ģ_}Zevٸx?YU)@ւie0=.dQ~~`77!]GԼsL%#;] 090NU *ڄ ^b7Y˜Iܺm_ٍ/=~7* AK=8O?/!S67@ƊS.XZk4fr 'T4 c&uy=]=u ZwW&̒R.x;q(azC~NB ɪ~<έb?Ì: [7uݑlؤF @ lm\-/ ngn[Hr\E#{4? u% G,\(ĕk2T9{ qpHBT#oxpUЙCH:ϕg0v>k yF)?-'bl_m}6Xrh"u%-].[sDiNO j0lBV!aO=Fc#ہh+"+Nu7~{uv(!_m?}.m:.3t+UB*B-FA=#2XpziRfBHۚ GAQskjjqS5f~h?zŲ0RT5%XynM,0:Rt'\˦sLeH&̱Q hR18&w0AE,G [̎ҨBaw@eoìθOubw>0rZ.4EҤpUWH"Q J(%mB?n){:[7̶?g0 af+7yF{rnOI`H XTTy5hdK"yˈr3Rk`[G1TD˘7ē v@JR7mܸՈHJjPzO! Ca,r9'kDj`_>aBa2 +J5.wuAr UZMJX$q0Vub-Im[~Hs˳)`wAv(}XL Wpa?ftF (,L@"=%Þ-`8$u&zȔoRC9>Ɨ(XK'Uk_xwƪ o]V(`F#a^;)V/lA +bhpC߃?NdgPA^Þ˻W$u(g& *ILo%㶦;dQ I@ MKؐFnWL-dDj5'`z3f ġ"ꑡlYDuz=/FSx:jŕoPS\ggB& ,yVȤ \I$gƯd sA}YJ/GlB}d(7m6xl:կ((^: fasJZ0)L x8Dg (ك&9PF[kvFŽ=؋6:Gwos´Ym0 n^`2FK)QQHȯXM;m|F.s9+!%)֬sjv;lwgrl=iK`ϔ A4_ĵj + FuCP!}#V"+|eȥ6D/LBiՐox-5#C.Ú]j-7;IX"xيtPPUBXQ;X(6%#PAnB_CK>^#:m]a\\&bh5#@qC˥*ZLS2uߊM{l%ݼZ.8yOT֌X﹧@+D s ,BKA`1Jߗt0}R^w|fGqJ$хnXDr äɹ`vy5-kݜ;@l26WMa*b61vgnu<2u))!0,4:xxO 74$e }ABI8 $np aA4_u }]Ig~-oS:(5*6.]-L:#!ʾa#|$0<% ejFy3^P},:[{\ҫ2/-M $?i^O"&M8qʄLT Xɀ 8A E,G װP8jT7ړ1v[S^J]Oˍu4to&wsR$#J$ {O'܆`~>'q<ѭ]!濟u-[| Aak?%/RX{P`+tF (,L@|GUwюtdZc"';q9ҔMw=|{4W3n΂-5sjT-Dg (i-Ox|Sy@m5.$>`|uz:4?ѹϸJA24_ĵj1@+@KF1 &~s}1^aOT$"UQgaO*w+΅w]b!Ԡ3gn=4goQcB 8(1y7UQ_[APE,G B@Yi%H4Dڡ4ΞOj30( T 8otF (,2ór ے h|qDg P,@v X W4H@h, CiSas$ֹzʖ: ~b \[uamc /Av4';=ʺ5FK< vĕ@⼮IYf@9p[.Ej' !2F,Wz1Һϐ2[OC=[[ w+ݛ;z*lI>T``B9 JkXB]wܘV٧=љAE,G ѿkm IGH#3B܆V]Y~><$ؒJy"F[`pMf߱@k{+-|5c!q>|y0v60S.e\#Qk0{l @Vm& L4+R @oAtF (,f׎C9ksm8::.DĻr<p.xbR6JGҒ#*:vʜ [nm>>_(G:' h iD WDg P,@m[M4EKsY?O燀jenA4_ĵjףl1.#R_s8B{L91Vĩ;'yezżv/cs0.MPmL|WwCYgNeV{9qRtM[ߒoC֪HA=ĵjWx+^@HU`9 9@AE4LG (t Tv| @rq-C2tF xwi˰ )-Dg &D A4_u }?l1*"Ζ/h?k 9q>A ] 8LuJGM2FЁ@_ƶXI]-\#ҕ)Ro.A{ڭ{mf#E/,7/CL.ii\X$ވq, X\:ާ8c(A`Ϲ e4O~,2k!U nAtD8il˾%~·%˽:ae)UO?9Jq3檉ժXMoJsQMX'r#nJXQQȧG)Ȩ5|ʚ $_~g"̮ʼn)F)N9n5jqۡ~G 02Y[ku-w3 ߐ/QZ^c@Q%Z&]7CX^|I_aU;=būq .1:YH#o*'r0`dϘPBy jr>+(n9ז{ [{>& J؛~t)wqݮoU Y@~Ȅkhzމѿ&e9u֍How,n^%f߸x ߤ$UR cN^tJH0Z T&mߤ$W/MEb R4absԠEC7Qǒ||0AW4!b ]]e3LXb<<(<`E[iQV@pCw9y$J2۴/S(klC@.U sVT8j x0RR%q*lOIu~[qgwkG|bsMA=E,G װPic\3ɝhMMp|H`  %kK&Aܚ;vVٷc+\!ڡ%Zk Vە >>- A{xCLϔAV]H@,0~rmTp]+S3UK6E/G=!/Y]nR.|3%?gG5gwHxKY\tF (,L@ɳp} 1֞oZR \=H^Dg (i-OxS^ Pa xѢ7۔nA*w=߱LC*›SwL%!=&;,1?ݰ,uNe {‹nnA;!@ByǎIۼQtU [ymQXKy2YBԢWE2J:nԒ,szx`#LJI.&|3@1񄅀kvc_iKp굯3AM|W;^R^M?,.?y{ɴ2ke?9=Mva+P}^U_ڋQ=S: fEl8#6F-uAQ `]%tF xw sj JdvqW)tn֥T-)bjvc'6kI FyGV/ y89/3bb̖96ܜ)Mj~<yx "x[sЊzZY$ROvϹ*pTj$VgBk U&EkNk-J :]NFlpb$;zSWhZt}TT/+yB@RA4'c\@gI? \Q),LeD3*}<~hIl&?buhO}xx_u%5MN !͔1GLs?U \;6oex?p}TWBNuǖ󉟜_0irM!URYf%/z"RŠ7=坐{^2<=k!UuHb Xq 9gdrp㞟tJyRޫ W;/V m9wAE,G װP%٪[RX9skG(6o $4f(T[*#eBInY9W u[qhxUNՎ2VJ֗Z2@UO=c\*C-p0# a/pGR3 6nvYԽ2ݡrX2ڦ05w5\J㓆V^ԛVIN MtF Ң0B2 ^|R;mkCr; M~Oockh(-< 7 ބ,ᰫ^O9 WzB͓}c>8W(4FJkOA P[zU?cbB aDg P,@&j狳z]E)fCJo } KJRJ[CHA4‰;=ʺ5FT-wA*Ϗ9WSQ/>RH7:žp Yj#Vbތ>U(0o pi-\R/d*a5@h/KP2:؅H<:$xX;e6+?cb>̎7C%/z@b?}7QHOTDLq!aZ)؎uJImJ2ŵ?p _AÄ2COTdP߰%A;a)R匶KĦL-d3@Z3;Acp:]*2 #I1+ :pO:,~}d?7r2E?'dJ6K񩐹RϯRA'vROR-)Hg(8^cfpZͥbl>Ï&Mq1AcrX7j]R$y0۠o|0 Γ 5HDl kARg$=Nw ʇ HC6Ob /0?8`V,/IE ) )"^n@_- 'uZ8؊1v-5+:DLe1SRwsSB`Tk22\k>ῄ!~]i} rfa8L3q;⯲G%3g~?Ժ5D l$,F=kkV`_qE|ܬtz ϭ~㇓J粙Ң y _uX5.U54g; {?>n[kE4Z١ZAl>ΜRm5e$ R[r%@Id(t-_Ij 0PuT`U=p̶>8g&Ov2{[^gE?tȪ__=Ƃ_->JeR 1pA>Lĵj%Hq]3"[wGU[ 8 G=M@5%Rdl*i".^Rf=b&0²]jtqDiKX Pϒ6ĒUϧiшG(z%n}.l~r&_HSKӱ.nqHep'm.(A,ESy@2a.#D%oIqiCMG|;[G! w 'kmmUUyosUI7WUcჟiָ.uΆ]Pjb3偎֙]~u@caj XN>D2#9KS5dkuF>UaSozAiKtF (,L@,,W(a ԚF,,𖱍_ESvÅ}=\R-# ëGoq:4淁s*6O?EZ&"*/*3)5xy{Ꟗ̠=ZĖi6;־]U>woZvA"G5kO?PʹX`ܤth[ Niǂn N5?h`r2Լ+~IW?@i԰Qt2iT!j85*)(?(ٿ]xoi0ZT~O ` >1IG [ԽҐ OZ -?nYcH VoqjC9 =!IMDg (ك&9PŽHdFTVz0% $Cw@AR4_ĵj+R㓤 18bfu "~oWVO=S1SF ?ٵTWttj+J3܅ᐥk|jM m[ Pg7߶vٳ1HVH\5(Kg) #0Vsܳin(7.K*~mbhY3C Ɣc3s"8siFT70Jy spϻJhAMY+*s ᨁ ϴ(SqUx s;9O<},}V]ՅWieSQ̒kI*!\򂸴Vɷ$`jݕĔS!/Όs?$JrTAL/B/''Timj3fw]HYQ T:\ߴmG$uhQ::I_\Nuu%K1.fh:wL va.˓K|lY_i[<0bu [,zd{0y(&hS%ۡȜIS^?C$>Mumf^>UUU6nBN7S#+||ApE,G [̎Ҩ9 GL@nQضV|du,V "kb{E#x\&W*ASzEoL )AtF (,L@)db]\,oDg (ك&9P3rldE>jߎ$xJ8qeLv2F@ Ȕ:7Pohw,ӎBf@[eN IěkqLAGhC),r+ RrVQ('":m/Z]K7e+qv|I#ci qh#@Yn -:% '^X.^xXQINgXܓ(%;xR]篛gϡ.]e=]j YnA7. gc5 }AapH(_ 8߶A7ތo eЀoV{F9A4‰ĵj#π^ۗx DHvgC/m^ԲR-p]a,sԄC}C3*IvQ@5!@()J~ F Dv<{87,l'D*OS$a\N(d7엺KxGhMy-!4e&Zm'覔X&c+;umV֓Zw.QA/M}VzW)W'~@GDg P,@K!Ā?v(9x,-%}r-;9 Sm>+#4y4P/I2ZSG&,c 7mhC? G\09X~vt'aux 54b &g'f%'e-GHz]63 *Kg]DuwJS9{tN'g dpY/K,f@2Ɛ@zT?rvDL}`|3(ʕ| 5A= ZĵjU;Ss"I`_h(;b#B \|ћ» ޫ{MB -g tJo'7FdE1fYFN Pԝ[07w,b\Jd+ 0$ R)ǚX]WZ]o ƭ41FTM[NB\aRm$uB`Q۟-{CceX{W0928aȿO**HGdlR"fUB:NL|<>YVx=A"o$k3 "2rk N0׿|)t4n*Wu$ /€o>.{!Pr4re_и>T:*5_$(}ِʏi2 ͙VLaM/B򢈞n77cтB/.:$)$Aw 8}Un3">v~<fES)v*S. iI<,}69C폀F; ʆ9V4t\DZR  unϮen+X?TB.(2? ŋM$6h8ReKrzVẍ́LUcx9'm"OSX]*,^RYh K!y>Lᑨ +Q\Ma̰IZ<_tO9L=# 'ǛTeޡ3~mV2qNb8"qSxվ\0:=Kj`d~\˙ [(դW%OnIU8Z. ɸ+q)g t4OM\_fs5\+#ވ)yO]#Jwuu+| _]AwM;BߪP4%^~cdYi;YDNr]U5ՄSƹFBzZm^iʢ3`oԖm?(]l'}e2[|3^k ƨv{LRl̮ESZh<5y孳Z[hd>zfsF|:n|,?7lmt:\enQ<ת (IAEۇr1,6o1 [FP,ƍKPUWSnrtP[+EJ`# "Nlݜk|BI}/ȲrJb }Q #>L !@ict F^V_/{"K۞#zڠRIoUdCjPTi~P&?[a1WmlNmVlE F"͔iQǪ"pcAbtF x dZ t{ !ޫ/+1}][j5(IJuvoc^Sa#">=81uEG+!"/dk1!RtY I aqSp%D7+f8S_J#a0/${/L~*+ִ)svdS"j4wZx+΅ċSq{ +:﮲ Efcynyi[ TDhLTIֹCr(u'zܗ\(ԟ_#sJ*Dg &D ]D4lW a |3b []ɀ9C! &aYW߱Gj3δNT0jMSI2E}LROJyFv><ie-b5VU՜hP4k x#pwv-RNإ8,J)i@YG܉Cõ :'69"@M̔IC-H[ڶt-Ӭߌ|:GCEw|Fl(MNh Dme7 ҨĐ?~ϧfwL`:E d|=+(t%m'x,Yz9|%08lLHM;pQE[! m@t:,`0hW ݽ B| '_(Fly@KӼ'.uFi'G(, qoڪD3˼MIS.5~{49X`4u3pq o!RGj뱖EVP`ɇ(Ub43<*!#fZ0 m0 vSzkx)e\  !MRSV{*mc_6 A4_u }`O/'uvK @#ATO&~;ñYs+ڵX6/'@fUΣ~ӓ]aFp>1Q]Jӈ{{ T~10bQ3VZAc|Ϛ4jtXZX,̴K5+]r# ݮR3Ee*t#= !3~`T[]]2|({3^{`Mb&A긿s:gP a-Jbܼt.Ѽ `:V!UsL|ob\J>lܛ:O[O|E*-I),'_"i̊GdX@o G5L֧;;T}SR#->X7 >1N|0ս'tT & Դ6{\zXnJ9uʊIKfm- ] B He\itzY^L:҂]s~07zxjŗe3MZdxms w*1wHĻ3n$0wkBS۪_>OgDFdׁP0_ (Zh C#nW2 OXfDIm.='t˱'hWB_0.,)9o}1&9e z7{ ?dLmp$mcɤ{B#h eʗp$g)yHJrD4e3!1 0PӹYkl/G@ݮݜAp P#!VDg|M*^ !pI]NB>ڠ]}@Ɨ4{*>1]!(R.ȼj4G╱&@J#ݸ̲OvBX(/5w#)/$OdUz{/kVcN qotikm_};+;1ɧ5 M( ;ЂVQ*u'$HA>~MWfL"U疙{Lgv 2Gq8:$et"sgghJ8Y )l[ҚqѹA{vBF.Q\V0$rFk8)wݣ5ċRF!B`=.A&ځO3w'zؿ7÷1ۺN7 }km/#k?45rm F V6+)0w48d㖗p91<[N8+/Mr gq!̈́Q_(Pz]N\k,, :HQ;Hc/B *VҺh(rHBDmځPǢ@dPūbc,{zN!|N H{ỵ_ 8RgP3)'pwY[WY1qnfz〈#yXvdNOh6#.Za>)O3  y޳yjTlgPbcE+eQ~mXLb4:f=[qG˨s#Wă (Oj qta=CjX/5UG3KM/8'(,DYФm{Vypj2ӎrЍɺFoBܠtKaN碩5^{]G5c5~i>rEyB)o˚?MP[nK).k5;e?vE A*Gcqpsq* ʜ=0jүƧ6!,@'vy?\n13#!Z*96doŘ 0|o(.lWEзD\& { # SN![9$#zL{ m>@1M`AF!6d]Ae&]Y}\v⒖h5:zVQ_ؓ^\qJTt)M?Z,ʐ,u*f)9#8B$ Jz#quX7jX> n]"`^,ⳇ5gfD'lʼnivɭ(3c4t~ϧeS HĔG>$26x!IO]JT*4kxXMՏ0}G!՗z"'"cwzGFKڻq$l<_7 unv5gIX<^mrb5ҋ4b˜Ta?+)>ɧ5!?2mcp16]-us';{_MfRo=y, terO!34}'duᮒ m Z12߾r %R⳻} sP6 denb{Kc,5 걘]v]abnG+t|a!ƔՌ(csQwK,PNUMNKHqAR5!DO_J뽬0z$iްOR~hRErjn)nwpPq+e{1$)fFfTw49iF[_it9y@J~4|@;q Z3;gem8M2wr% [ti?δq~z躍~&5RK&wL޶-0epU&H Mwn6/أx]E@]=I_Oj}YLMIi rA~pAZ*}L68gAzas_w*He9ox5ncF],.vSfSpen~ֿUGh+uXϧնT׎ЍV}p OkTD*m%OЇJ(YPrsi%zNu+zk҄x+CkPcPm!'=f8E@b^];rj/}giRD|CKFqXzBίt)BP/ {dqfV_{6a)w.(BU燯cL "ʊ X19H>ewUW-k~9N_n_Rۆ މRwd?g &j&q WehidS)#'4Z SY0@,Sa~q`GilϔkjٿJ.fG-hF{T6O1b%?`pIPL' $?n3#/ޔާ|{ϑl5 < a-kE,$ m 巳 Rzf0`p88u"b-FY&W*6!.cdvZƦ:{hӜ[l +֠%atz5sċnƑ5F9DnӤ( cٚ?nR40`t9U3%@,ý?Xt%9NHnU; 5L?mzzܪ,2b7MkZ ,@OOOudTrg?xb5f tvtO^ ſvh YPVn?X fܽY/GMtݬ_zq[҉IA< :RLنt4yz}Ja(d!a ńxh"IQ'E4ǁx(}JeSMdgG%B)f.H,f?GO@ ]Pd_f 'HyfoNF4 5Q#?V<ǠUikϮ杰jZ_9{+5p§6N@2r:q Kf/\piZ%daZ"nmn ؆b`_Ό3_.^z#X.JM Qa(A1<ǁ'N')}W$~VS@\9 > eeL)T9:$'4#_ПP&VAXv,AJL)/bg7cYS7.ݯIMVͷѩ~jEu,cZokQm?`  &ڍǭ 3gf@yΞm٬%f/~ޏ쯑QK*JfL/Wsw̄:{IaMa_ÏJwk B)LZ*围*!mv"r/)ో,S0ʊl1͛m{-X"v-{o{`l1x'Xlf:2a69s!\"7].=%53 Ч g^ iV@XQ z>PYI[tF (,L@]5]6lOxS`A BOm4QHQVX6SX_)8L.ZygHy+2A3 w딎~%~I7X# *Z OI&p;P갼0C35 /; jLYvB ""CNY2Ѷ+!DjCE>A)ύ{~0q͌)p.ص~gyf @HZ,ZSPF @&ȹRvE Mr3X﹅h`_gr%?ʹU0ԍ}LC9ލ UxidjqGyG@sD0¢%ߋ#R;Փ8@N@'ۜɑq*aO96SD']>HSlLPVCa͆%re T $BX3dңb$[J8erST1 :so$F˼5;ye8T!72]Dg (i-OxXVnMsWt |[WeCU}Ԧ;LQ V¢QSՁqz@lMbY[X'Tw|a^f]I˩{ʑKjhn3Q޼ ,}8T1G Y2C ݖ8aX? >_t`g!D4~^ic)>i mG=(a p{ˌ<{ ~BpMLcsy{inٌ %BDSu9KEHX.\@fI-ۓ/1%&WǼ[:$0Pf7<&8(!a-`-v%kLv=eB%KܢVgeOj(ف߫ or2D^iC$% m8fjlc7ֳ7}Tڌ)3tkjtT]C1,$_Fcͫ(DF*E.~>^+:>9y'h짒R=6r]Yᕟ03w!lRwYBֽ uHbmͬ!UڴE*E J$0Ǿ<PF24.23r&6@+SC1F!o&0,AB4_ĵj(]Y.s Nxd%Ԛn{%š7."B5{ߝ#Ѿ>_!†r9/V/NK .^G3fIW;ɦpa?o\nT gp68p+ uGddnc*"`g1HP2kOY^3i.k Cqf^]W@৪jtiʟ%G(+nΦu+U7JsU/]ac)zQؑ47|d*>_3Y^#Cȝ#PvqֆB"'4FwpgYe: R9Bn*G?y%K)zT%=X z:h052־{ uts,c,}8(e^#0o1v+ 6&'CecNU3Aa-z|溸jj+@aƁ0+)ɂfԀV1+ O:UP˜^nȿ"Ph2(٨$d>,;b#r2Lj=2_8N|@$[}$#Q}Cɂ-oknwe`'r;gnԙ=V ?f4I xn5 ZsK2tn|"*爵\D?@ut}G86>לZ kHI,96y* NkqLHNh,f}l3TY\!M6Wꙩ&KY=?Sә,RֵsRr8q1 1~{u ^ w+A}Ɋ9Baz>쑲Js&)1:LGj^p=OCzBij֘38N}cí5c  D9J.8_쨕Rfg{c2/OPdʤ.p~mwtn$[g:3Y1hPwF g<ta]ڳ`i֛rKm$`\DRHi_4t,FCk@]0}.aOHsX{8'!5 Svh_ (^Gn̘6Uv2[F^y5{L$9VD~$,+-V>k}+'Kl/Vb V[vSãxhěk |ZVORk7[g?J; uZqQkAqb(|JiMێL:\1t7wv!EA`Ls&& 1n+ R,'%%=&jwT-\iT*SIAB#.|FNJasC5 w 4Xo<,|%54 L=ca:q w\7S(ZmfpBJwp\:qlnMIK4( Ca,GManZ< 9eRKzP$,E|y*oBrUwu}=}5\رFHs2| S <r#5A7byV5 *QooH28*TpI{we% r{$ơU=IC|K Ź)0FHd_U3T\W=xW&¬KB_G< Wp(JUl߄M8G/CӇ /B3So *ra_ \VkOnĕw*]KXx1-gW8&bWωCtF y΁X6O(EΪ ˶zWllt_u\g`.tq4wG{yL6터ws޼6~cBa)vez ym#H(1T_c"vKe!:w=|Ԋ ;5518Ű(BXI\EՍVEI+d\AյqHmi"T1 HJ*gpRxW>X/EGҿ"T„{V }{?˄6❧%"f#bvP\gU@֢-a w?Bt¶b@=W2ĐHjSVSתt؉.M y$ՕKcuVL.2l>FJ6A h/G5_Ko-Ta;MV_5rYRA׽Jxv41z:hKN+gx!ʊ 5'k[]042wjո LKoCZw*ni>IM٫c5;ÌAA’:. 9t~I3+&2|A>҉\Mc Zj? 4EA`E,G B@Y%"K4)JwIFU0BC9>XRn/7&z?!; q)H)", /Zo~bĬ2丗0Oh|ƹ#$ѴYkA%~0CNY #f»pȁ܉K8HaGEcqӸ u62DV18yAIBߋ1C|𧭟#̐E31Myni ҃>͛3á x9Cn.g VP26g`ڝOS9ۓBq)לi52f6G93A4hZ]1גQlar7YCQ!%Xn N,\} `b49Hw&aŋuĿ*Uߜp$*!ԟJE"0͍wOf71OjMz? 4)؄c8`i^ ,ze==^8d 9z@tF (,2óriv˸n>2G^?aEF YIW#bBKd'Kp5ulc3A}epFUwN`'ʐ1/.BDP o{R*e5+X彟μx{i~ܐeCqFYavN o s둯_IbW2#W95Lu1y` }7Bhl"Ʊw g0zúq)C H. X'@%#A4_ĵj%QgՙI:eqc#"51̝xs&I}gvk *x7UtWaD*-NsnsDoq*p`CH(8ۄBSh-;&mEdxWm}FC?{*=@!AƻuaNTd G/FX?޾Zv;ݢF3l'$x*âtþFGu\HjtQ-XaΑp@ 3 §t|A ڠ?UX, *5~vN~bSu#_o|!U_Ѧ~Eq)J=yݐ!/M3,Zt_̈Ij ix5*a˅x=\{`ǭO|!)d"R@hX+ޞV_Hz&~ߛh#TmҎp7i@g+lXS Rf꓆Q<8T'HWTc`fGd_u6f7]7V4`~=* xwc=|Vl=+lQ`87coc#znlk](s]})T2O1%70tBi(-L b@(1Hy$ҩ j˰ys;]kD}ْ iV lz@z:>'K!J>Tk t5g5 ї| n_ #ڟAl =sf[kTtgQ2>n؀AS q:8SD h .RX"n@k2:$KQv.',ef<;'$nx->(RK\q<CB /7x|q scye4V ܛyK$[>:b^r7,Kd 40ç:C-L@̾MRނ ǚH>% `w sPjv!%8vqީڎЇje$(OAE,G ѿkm IG#l6%<v'5ZuK(b:ZEtF (,fz6gN {}4Fs:I0Dg P,@SS, QA4_ĵj&Fo?4)R4 粃r}NAjS3AE,G [̎ҨG0:tF (,L@ P@2 Dg (ك&9P+HA4_ĵjcg7m`NPc1"\<5A,E,G (q6u@P/KtF xeA-MDg &D 'AR4_u } Ok.t:=$Xm Si\alj`j2_ !dڦzLcwXuԮn~Ercbne['߈LxNehkn >Eq՜$H5@cNV%02 ]p9܍Ʒ *~B" Ւ&HI1 S-fOڔ5ut?rH:t6FXo!IpBS%R?ſeǜ +n1Z\mJq?ԏm ADM뤶 QsUb$EᑝR(rݙwZc A^HwIVm)9 M!g^/+;m@w)@b.WXlHH_DW=Z СڗrCl-!K2LMϖ<@~Z ILje4Y֞д|ib!H,ߖƏbP0Xy} )!R.FXRb`OEJ##׏:%m#qt"2ht@#IVYd^/$,&*Ko";,=1ٗIX};@VD=>Wg"u8t=˱glRuAry eKu.HT9 '~\k FA팾g5=~^A'9G><n B,oAa30kPm2f_/2}+J{zV(o?P]0EG~ JTopXl3C{ǾׂU)#iwrJ+oAHVr)(! Za#P9f'~"Qzs@\+%%5ή\Hsʷͳ9] Y GBTv@}Gu% CanEu;^,Y)L\{U4wq? S\BJѥQY.Ua6SGS-<*=agz!e?ƑXaMg&̻0oS*i̅R OZz |zނ+D=èm(~ uM~~J*8SOdR#2 ޥy D01OCx94z5y2R*8m7i*>uarGmW39~>Gm@Pqw}ob ֛cucEy3C'6֊*LjUg#{d~`EX(,BgE*);Vs7nr\oTbtMymQD;e=RaVmWF0 ` HxF62oN͐b s~xoXLR]sjqvzbN0A<މ&Vb&K铊]kC؟H2^|fkhO]dLr2s9Tަ2yArD;H}X?q#^w„ӈS)/#.RgR I焝/^1o* g*࢑~Z?6A8sЃ&>׬+i/3_WxaV'sо0#H*O>lYT q%f{.!!N̏L h_4xM N,-?j|P|asF-AnĸwO᤯]M__lSTG_:9<>bS.lPtDtNlSH[s0Y%Hb21ZHbrw3"&uqldkՐ7֙|XT (~,jMu%?UzA FRtrKoa*f)н#cv~"㡟 z)4_]M3 %'M̰.a$3Yc21 Ez|( {> )ꦽ 5GqCGw0FЖ@";x l+MC%]7\7C2q:R$?7XlEh{(zk "6W%uPg\@Η^ms~ !T$gbmیL_}.PoZ/e# w:ܙ?g֑20%Wƛ&JcUA9;'2wWTP?'剘uʞkǚK6w1# f"ȠYB3[u꼃xT < bBd\>pW7z. b7+B^{k@S39:L(滵F|r+_XoAsO8+̐ G/#3 f| l?_N).ŞSfl˺ʢA}q?w? hR:zm63UNx^W[|}X;kXWI*oTi:C+;K*{ì/nH' M<K7aS*, ⤥]"+y}@F`Ahhk\Yqv~vչ%0v|Bq7/ /2:0u !Ů%ֳW+/$#?BDVqD bc]0 iDc󩈅I&.x|REE?aLClJ(u0=yW.}]R!sW!U{62k0Z[We߰صvKk="]u^1f,!~_w6\˾C,{ēN\:8VxO;,E}J9^o8#HG'$.fە5K>f-/hopۣɱS^9ua~4!Lg4"?P`f3o!V}`(Y|=Vǰdƣ5!H_˪Իc_Jd7;G~ wLY.*..&1o: *C:)Euf1Z̒FtW`)ɻw!Do @seu)jr!֦BхׯSeipEm,#mSaWlEց?jEؖLl5k+V#Ws\m%ƨM8 g߀ ck~YS6Oƿ3*myЙKOnEP-U>U'7[-{$O-;`@Qپz[LJUh :wwk#ꂁs@cJ&}|R?l{F[b8tˋÐy.9%Qu;u@qZU͇b̚o@-ɕw'?}AnJl :%X%WKn߿fkIXf":徍D 0ml1 0HM:ᦇP\vDFc[ݎK,pJ%C6%TnBጜ{c;D9ezZ D$r5-?|[>Og|4I؂=eP[߽ ӤWI:-w]}-lv)8dp&9yP77Δ0G> ໮>{b&ezq$ !2'BqOXRFt7J._;Rn s9bAE,G B@YUs a'#Ԁz+ ?>xm=/Sۜxc;~Y#'sɏP&P .S;2'8I:d-7܍+z1G.NL=17+7k{>V!Q*硐fxswqKY33ku\y~B#_+Ipr@ٲ@*'orծ:JЉo7A_)øg];a8’^% ҭ^4a@,8Dg P,@Oוۮ-g|~:~20O$s5-R퇇 JCyM^q 63 M$ʿAYgbtl;z=O~hIQuMSy}xA4_ĵj$Q_NULu>- jDU>vva)|E>QOHc mD IBf̙fa(Ё ԧ>m,0-2B\'(\AkO ^gá};U>-QUI6e=(S|BE'{7ְT0Hfo]c:Ҫ#d 0UlC1)_Ăsu2?kUWIM Θ\<8Qa8(>(EYbL gzAoap- E]X w{ iYQPC*1?o8מpX /xM{؝p tF (,fv}M$0r1z| =둔j=Xwnr\&ΒD\J- P3gHUwj3x<( Dg P,@OxJ}zopPuGR/Dg :\6o@@2_jq饭~ߔ,Hq5, U+2CZr|,mg[gӹ$$Gyw5!K4HuBka!(?ڄj[@FqA4_ĵj$8^}Y &fUd֟kܡ tV6''wXl6wUgiav}4?55{!狉?|oR'۟ꅕF$qSח M'@ib8,SC6d]{* 2X 8 JyIxܪY!j\panMBB~߫Ҝx$iOoj@rc~ /m,I7kߖ ^  PA z?x 2ϰ1Բ|T$5UCΎ aj3̵ xl{ᇥVYdA̫8sҸޫKI-RAө)p,[tF (,L@n,COGˇZQz&f VgugVt'nT7ߊg[\d?y7K!-ئm;Muig\y\إKmONml_9c$]Dg (ك&9PQ3׎~ Tz^T .'bhK.dCXZ.lLB53ɨ49- 5Gm=+ HJAB4_ĵjwZTdZdso?nԤ{wVYy0ˮuQV8=iθ0> WtW&97`po|@#{[k܊_>yqOu]R39v ӛ&uD'"f՝Ӵy6C90(f!>cwa:>*M;GA`E,G (q6u@}8vdSS1'^Ήj|5tF xg[1dX: H/Dg &D &xUqe=A4_u }Dux~+`1AE,G װP6tF (,L@1Dg (i-OxQHA4_ĵj*JWùPB 2#3Wqx7AE,G B@Yy^Zu\6tF (,2órT1 Dg P,@5@g@-)93\Dg (L aL@LA^AA4_`H֓%>'1y*7ma O Hݼ[ )]A!%IġWޞ97Vw9iPAYXOͪm9Yl|T)a'N~7g@[/qAE,G $8rH/ejkcJ#rY6[Þh 5@ ]0͜r#{iG\ OFWq<GƒP*7@ i@tF (,f =6eʏGkt) Dg P,@' =t~C=OU,ƭ Gmq}kK,E;ِDT+ѬGQ<ƨV r7Qh}Y:ް~(mQUI+LJ/АmyRAu\p t#A4_ĵj#s&ho<2SRDUvDs ^S6Q&L凵3=Hnp38.}%aP1w'p!\6ᯔ?gRجR^J@,2;1Cq!"`;l]u? VY AE,G [̎Ҩ#ɶ#K,qALU^``^p/=Ԫj$J,ehC%؛&2I]$ˇ߾@2F$hޒldĄY'Cep'tF (,2órYɩ3dl{) ߎ8S3eBdL:IJI (I'r? °J\ժTɱQ9I YI?Y#0aSoxVe^ho[WDg ("iU@Mm)"6DR/7CwZ%, 56.k;SKn}ri*KVֳZaM%{J4>jA4‰ĵjiǙ'2 _3+犘sը ^S\,ߴ %G&4Z-8pN8 ◵Xr$SDg P,@]Wh4?T茒J({3)A=ĵj';he )Y7Hf\I6}+}ŖTUE G>kJ CajTb m:P|ِl|x3q{,yt_#s& N#*zziatD[ e _:fOr,J5 RA E4LG (qlچ-*y s#[UԙxS\-˱itXз*`:(tF xEZf7B.L*Dg &D !-Eu)ˊ. 5MAgۦ҇e@A/4_u }h[h yv Z^0yD4ly3g|Fk8b"h}X<4 oa\Ϟzq-n:jM ظ WQw~iUU4AME,G װP-:5!TltF (,L@r,;c{#0DīPiX:20ǒ)1nDg (i-OxQYAs4_ĵjM62=DZ[Rvaߚ@tQJU83AE,G B@Yl6tF (,2órU/Dg P,@ A4_ĵjFM7 rO}3Pvv ]J&'b*'"z*/J2`bfFȦQ:իfln^uv>)_2+C"~bYUb%*7@9=Ekd[$,Kkja Cۮ&=VxM˽[}ͧ*bH{7r,OWu&Dz%2û\$l7Jpcuҁ>&B;LPO44 ҭ lqAns#*fkݮJEؠOElaͪF! ӄЏ/W a3&"6 {C nJW`a~qVٌL+\y b ' ( Nm/,z/i'qUFڜ){= pP;l0`M)r`< qpIQN}Ԯ,&4O/;3$rl\mK'wdF==~w}N@9.+Tqa!O\תwKAj*RnQt2oPt^wpEK0Smֶ( Щ|mt+B_##0Ive4շmQV{ v"C~º:PEwbEyTO}&v4vC#UЙCuPSKʗ ߃ 5]++e/EZr`Wz2Q^mڳk]?#>W/KtPlLNj I|*dOMmkf݅(^Y4X` J @ӋkGcRy'(K#N6KX A?iT"J+℮CkZ7k4 ˪ f>INܟn0 愋-m?TV1(ǺF "i䨀IK3*ƭb鶘nh6g +j>0[yG&Q/%TS1:;kqQ]/]11=+5D/Zѳ'0ϥQ%Y2* ԥdfBɴ9GЏf{̯T(h~SXca5=-¿"7YVi7@wZ=iv$n(j&-M]BSబ;dSx&Y%Gل":YKwV* ~A׷}[ ]FE3~d 48DSۻ^mZǹ/'Db|iq{J_W[: ҳRb_74`XjBV.Z Dq#׶)l$¾*nۑr;vpø.Ԥ;V (1$J>::9P9'gRv/^5T 1@xM1fNa|IGBE-/RzV,=<ι ^rԼ GHrsI Ppl[2\52dJn*}o-Iwɨs~VXcҫ7^-Q/[Y@K4533X6F%2b*~&]|_BgXbFUp}БoV{D*{;*!cR9q[kVE[{W!,Eѧc9ՃNR&0 9;"@zDNcB!q =,NX+<^=fYRĴ*{]F|yDab7HㄔhФ3k bAo$TGٶ5T%%PGn2rOGI'+~$}{QJ:܎}89i"؋L@&0u[k')+N~Af;$p?5vzH뙳a (/rn3(g̗߸_|OZ:VfU9CR% UE ܠ"JR2b1ЎSIc/j?ʄ4E1TB3Cyv]={ށ7ZRt F|Twm9y?\Q x_s@E9UUe">U%H1zH472Q{lKʷ'rBRfNrPTqzHXOCT4^]UIv6_WdPSpeN Xq?655WK<:z@ZMĐ{(#$;kt,1@F}ߵ\`W]nn#3c@$f(͜Ɋwj?7ZqO>_'$ylH;C\Gj&[TbId[ Ԋ b۫w,jH}9}BB.P|g Q@8E Z8q*þr߷lp'[*,O$ w o Z~|&Һ1~'!]ۣLuIEF_u#\.[҉ff@ zFx1{u @uL ?`%?@F n5NJJ$*qE8|N۷ RK%9++5]!a)OP-- }5iҨM.bOP~ j6$O>,} ?={w1CޮX/^}) O|~6a,U{[s6PAWH((kUiYP~)Sr40XhrzïEv*0Rq P3H~&9  z 88ekBswV3+jkVh8t0tЬJuӴAhpug3 m)4 ~[/ ICD|lVbl653*$PuވP_)o3>C#/L9t|xKW-J)p.l; ‡J,_+.zZ6MX?U9^#uuU^`e~TbצnbQjgWLՆMʅJ~|@lTY#m`١ÅN`1ūVr"+b156gѢ>$h;<"V# (,(32e+-BNPRe7aN`6M9nU \dOr{(DZp1sUtՀaAs:;mӷH[V -VK$>85+$' ‚-Kڰ 'Zj+Y<5QdK&nc `mb5KT8̳K֑uYj$ob˹(wAE,G ѿkm IG 2,ϸ BPn&C`]z,t}Hr!}4@1=je?6 fK- )L\8.?L TkoG˄ .?z|8L˥4C & wOsUo݄$^&.5 ][=~!2]w*[ߣ^%dһ^^/!^}^_8{麺ͳ?|e (qKyZ4^eUPL ݘFI)TΡ;ŰOnH:qu7$``y,Q9wj~E2؊/BfBN{eE Bp߿޴T5RBdcTz aSKqpi@0)T>p}ncţ{eHʈ/]Kd7_}LO ߒ3k}֔S>}Fc J xr^&j$2(\ hz0;w `_FˉOm9n e (Ǘ _x1]vztF (,f|5ph$TLIGMnPrA#Ɣ%`cESE95E||_ c#&KI4DIB\6`Dg P,@xo%ݿS z7}w745A]@@nn^\ex s0Z6dAU5PG3w9c#Rۦ9} ݸil˛!fw^־e$f&VMNIUS I9I;׷jwL^0FIؖEZ1f͌?kДNe]-@ eW SA,?~bEwMԜГn yS9Zn#4зsxˮڔ;UU *4.r 0U|ksg-}68ڴ_X7yجdS><)FqkeK&wJP5=AIA4‰ĵj;meGc5nJ$n0Z$b?귲M4 j+5Asfӑ=˨ kSK/";0Ȏ#y(q dG+?q 3E V. Ћ4\>̗&=<'"f~xH"֧P; 5iW@,JQ[`ŽM7q[>ݬ}ŴaQA79*bb'0F9J)%gӉ} D=V /'K+Nd>AL,em~)f"1N_uHȢ)PߒR9/KkUl3ݾ\dKCf]"9y=|tl8RBXkW/MͪYIdwY9Z[]vp;@$c+EɌ\Rd7ZV[ ld: 1aK9u12\iҵ_t#f8wWDYP"{p ӒJ,О OWv*VTt4N2F;C%AES;$u3^ |&FoA7F{iyKwt*udQ)䕞Dw!fֳj>QJZEꧼ> ]Y1ւa d8EqknLHnByi25e,~'i!eh|Y^~gku266)XbX?Mmmŷ%UQ} &W`gli("a]wu*Z :M<5_WF47}E=LCfV6=vr9ΆLΰܧ95C~)(%-]*GG \3lYx_g"C~n i~0z}5\'{ oЃŇy0ʑ̀3FONS3%.@tsVV `s,z[mبlt@mqwnBlh٨t OFR@glšc(5]oڋH}Bυw4b%91~ ` 6{)'A'\Oy,c$cNnQCǛI$k;pڬW8D U_YV\4/E6*Rlݔ;-//OG^*v㙍P#[ i2&9;wJϊ3Vu2[!Iv,iQI1N?!)ʹIC6[ݕtF/6'"lFuc+ʭCգ1{el>ތϮ:,YB$R-ޭJ/7.KqaȌƋ&J’)Gx٘amrzSڰ?c9{rCZdgo8̡fR@]dK;°]o@k暃5s#`0P< x>z@'ԱOA>F?_?4bCth1 rC[*t琪o\Q0amCW3[a{Ԙdȶ3y=X 񆠖Z~|F挝9Z؅s*! Uox )sO gR|V2{~HeHuz.]*ٛ9$ k2-c[?_}I9NQe3)79No9^wҳb4KOx?TzonTT+,i9 wpe(vYRgFR G>ݗp?a ;Á|^-ZO Pt,acUճbXۉLa6rciȵ*"XV 8?zP {L*Twx6| g~z^~1g.Yb2hy^A h? gBS>}Sc`m]HVyZ*KfG%_p"G}].RG¼HZ7#UOr7.M)MjerHvwc::b}J7=#}AM"(d륏Sq6O >Ոz_:-m^%vfSC zۭgVt鐶SD f? "?1Kw>U] 7G`Tr(rt_YG;,MRXX Q+Or`Xic bJ0dp;̮XY 6zxڐuLƟNHʂuۼ.`0a azՇ *&u@Q7g3.'9dÁ|+ḣ1wnjS~ 33>Ê0eP!6EBtLV^`ae;*kE%B\IpFqG6°_xNjƍaG 6Uoo1aL1+ pJ74lv9𜪆J0xOk̜!`^9՚HW{bR^t;cZ+ Q"C&Mтk=ugrPjOW? m}z4wEKm|y-c w%*`t\<r>7):WtB4 JQU;Rg,c< ~X;RBչt, 8JE-S ZU(}%PqnaYHgiQђ] c( *pL["ۄу QcՉecVNSj)v6پB~t̥Hh>qOvBgʕ rk)T S)@d+urfWHõ]Fȅ&zb~,O즿ܓ輏` oZi8:cB-_Z>Coטo#髜7Xq QHຶQɠeFrX[Td|yɴRw!Ϋy3s0.:f#I32=H96'v`w Gc6i-ee{ڧ{#%lc(MTNݼ> x4\%^n۟zL+F~ξߓ3:4+K_v}Xˣ;+ΩiRٜ~gs]'L:~ѯ._Lz|dz D)h\v픯U6>͢q*b;4$ST9KC[N$6d7*_ EL=gbzOմX\cHg<ʜ oecY+c,T܏F'^2ܴFk̂ǭ6*J {>-l25[OT{دQsGiIWٴtTeDW{{#{*b}A7DH+pb1EȘhxp5/F)"|˥0/~ر%rks,8K"^v>tsHJGCIP˰Hd ɡ(}0rqf3{X`;T۸qT)zSwh6:8\&ׇ\=kl*7?^BwiC $^/( \W$`>K9 abTS UI:7R3} Nƈ$bh8Pf?#T]gq?v!mD‛7>y9~|* |d+Kkx8mL7T9J{/SYBv I[WQe#<̽^< )Iͱ-f 9\l (~+U]2@V^ޡr9vGER|~ n0tc' ;,@wMM{\rTѠ]^T`0…xb =rK",]t KP&ŋdj7,/,QdR c`Ӗ૾'-VkFRs~,:2W9#g -@@Z}] ?x[=r:F.3QG嫒hI\;10B!] nnt]爝KlY3x<^%P,FoY?d!SN֔rtڋ= u1Rmέd`wNʹ5T y(܆TɁ똸""l: ECd1"uFWA1ȩ#2c/6N] [ѩ;HCyC,B5T EiDGS@|0_p #oe<[ XfԉԵ#mԃoPF+B4|v&}xMڄ=@58Uѫ|+Qmbw& 현^?d9-Yd-pU:K uRa CrG 2Rb/-(?6\82 trVcZEoxc, ;1mT]#Y}3w#3 HnHUQb`EJmaz8i]&Z@OVz,o5vWa,a [&ttJX\fF2k\vͣX"݂`ayC&M?QG0DN]LiMws:hdHe"UEB}V.`!B 2ep=KDTž<,vj8ob[ts S^#nא8劋ָ֦ oܟp?"sq/Q"bu˓6^ d LC _8Ź8#(4'GI`O`|)@X%ۄoWnt.7l螡c<:~9 .U֬b- sDZhjzv}[yݜH3&O_~ݓ:~-Ghٌ,qf=@ ى sXҊ c&ßר!+Cw e9PU^f56gSj/ ucP3ٍx(FQN *[m3ޡ59I_>׉2GЫzd_h缟rZ29hM6DHmܜAx->Ҥ+*m>L`UG+ Z.O6pU}8_)*OPm43 ?fx Ʒv&+~$$p8I;<:c*ᬄa2ͬ @-xq78p=s)𽷎*PL=7#'3QڨFL-?!`SSe8YxU:ezix@}u? lG5:yK,oM\2!?nS^_ "B@߅/?Ϟ4ϱv,#}sK-xPWY3nmCha^%!5倫%c "bǬJb jͮfV#їɡE\JsryDv~f"y7;͈vjN݃)Ն&0 '1HLP[:I:` >)>3 5Y>3m5x_b?RZqU§֡C'/hvj]( βRԤdnGBh#W=p^2N#ڑͪFl0=4!t@C($O\cy_Q ˥`xMBfYugHF>n Tb@<;`t] M,h0om1;8w琚="5C;U|qWrNig+0l m %B7v$dK:)>*Q4ELزlZmNuYᓄD}Ѵ׈B :\=C}vQ$U mY Ày{f[e7^ysoEW2mnXv=O Z׎IK†ڻ G'Rj3L/%;DI̽wO"Dv|#,! !'o8eJ[#?*AqC:S0Rç4ۧ{($3f] Ja8I To@R2VI[0gAq+R-eֶ}F(әJC= ɹ۪MJ"q hD{cRVο ]H#zoxDxV;H ]YGA <2ب0)I:D5dZuaU`Re `K Ru^eN}0t82Eк47G-\a?GI y`ac\\h%J"[uauaaY.Y="Hhw} JeMJv=M|1iQJ8[.9əmDK{YhP&NnB{_}rxij`C림^|'FOV\i[HCi?ÑL,TmȀ#?rml6+6嶤[dPMʾ mIʼnyr yD<$"j/W ott>&jstÕ?&an ,A:Bj.r"t<ؤqII*N[G5H c Q,ιr%r U~q[n, 4ML|0Xqb1sWwx`/uq/['u_3m{Ѻ9-@[6Iڹ[ytFUMN6,y=y٤f#I{yFIBM"䏫 pL^)^?d8U~&[6gNGPC`]c[e&vϐ^~\g|8WJDĎ1"LafOPl1 s#.>U⌍)r` e.yL^KXr7rUgSf#wҽa>#3fF㺝(6fq:0ZBicEl]IN찄;ܗ9~#q#y"UiemhK[ u CSެah4P㤦H_}8D}Qa4mK{W y%rDo U:u d_o#<+QP{U2v"7ve:|%l@]B)tՏox\cwWF\KiG4[}^U$ts1Cty_?ZPL0w\ ԫWFԉ~-fm$FJL1@WRyaecY&Fn@h#R8ZDtZI/Zz:G`|BƢҚm0xSVώdȊ94϶4&X-BVLID2@ ncJutեqY_&{_5s-4''ZJ7tC{MaI=COՋW-H혫 #=+*n>1s73$ 2 @b*寢B}KwpV+}`FQ9 =g:$dlRyEEu){luq+ohgd) 򠠛aBr=mc], #6xu&=YwqJK<RV,`Kx 2x]2W:kDD(u. ra(71ec H+Gي=]qS0P)=i.G6kSȊ,xx]V \ю8/T @%h-_GI*a](-ɁW=n! މE$r 0<טQ?I bP`v|J $sJ3Q\ aGNjW5*Qo&]eĩ 6*@RLob=Hˆ? :5m{ߖԨ^aԌP|wKmS$J^!MGJxNʷ2'XɅ4Iaqt~8 u=H@6O9n"7fR:uk=C'XJoh@{ޛXE/gt(L:䞎y9J9'EUf ~.˷omJqlUk\g5_R3cSx4)_JzC`P 0oEք-BgL4֖JoݱA"0S'8?rBpZoE0)y ڡ@4&ƶno|eHFz~,.}OZq]/ڸ¯m~ZУ+Y,v~;c!%3?a&Iڈcڛ]Ô:R:T&rd8Vs4i9;HؤQ\^̿(+ őw|~/u_O2hrL4Dň/3iBPG. oå}zܚmI]µu.q,FsT;m7jJ?tJ0*Q&j^r$íRIS(93;YA?n_[.*xQd9P6N DpnEă(Vf֮*n95`L~4%)AѠ@`,%ƨ ْ8t7(^T3_#{N+ph\iY.j1el ÷]{ iiDAhn*BCHz;ݵYe#mnn.0Wz#v4sCmw40S˼.|_,g\ 2z9g:S2~e>nNM&d(TT<=ۀ\00+NHAEnXIݜ,=S`PnI$j9>$.ֳ DzY'6e)jV]k8ɏ,K6zu4oojLE>1>7Fg ssh8\8kh$Р/8ns7?C]}l8b6|-#bݚ;li%/fȵt1$p Hj8 pn4$ :?6 5.s#Iq|/ UV9_@sj)BI^2$TJ OLh!2*=жj3Jl:S2Cnxz1ͪ{{hbsT"9E8S^!^ά1y੔4'K\춊=s:sf&qI_;; $MnjV'Ϸ J{nQZQ k=@^GF*qM?CokQ+R$@)tkT阡ωa)ۺE%*9fY떖oŀQ*>(.ba?z@;<~H|qމ;gS!>ʗĞ۽d'i eٶt`5GV9 uf;a ЕEZ+&䆣"ViEEmBjڸMυ>:{Z+:^+r]h1e>Yh%zȃI K$Fx=_cQ .U46-"joŇ)8+;8"r ̠!q;ֱe hKs@*ċWIV ʹ4Jqs }`b. /C@Vu)3VN!g Ck"(S8 Wm?5_-CE:EmkKD@ uvcY_qC7"9ʻ, -ܣW3;o{z GT֪SWNe&ͼvJ=M BڎGԝ ϔ׈k#bT 5Vjِ ]03+P6^ᔱ* ?7> uz{/@?v ^-`CbfC/Ž!qUv0wi~'&h.y8Mw0'Agv}Fߌ|æbgfzQ%GR2`T mL ;- V[Fciry9,ep%w}~pvF:<@ ]kL㻳${StYlިw_M&' nReolVVO5hz(P".\L?o1r}:?ֱi+Ƃ7AJ_ju߮f4v GsΌ)YA#_xN߮kO"+t،1,j_Nx| _*dIpNu?{)pqdP8OS|OKe$-m2&^SVm VKqMޡ`)s"D"S"IV{qUw猵Ib`s_ h)r_*RLF3Md}ڊ?\iIʇ*PAWpc4 7SbsDNO}fsZ7 KnQ$t3#0pez=s─2(}piOnMe7jcz*mcd L֗*M15G$i{{ /3 H_7#;UL]wHqYv ˯e[dUGIj%RӪ9.y2`Hh5&ڡ[ 8Ȣ!$6.oi:Hʳ ~7x:lI+Qy%R.\XΞbkrY/LFxC]٬QY,6d"48*k7>P#(Auw:eG(wg$zUA/j,3ҎQH 8瑋1J٧#ޕoa,S hf', k { MHr50{E @N6GF )??5F+MayF{ߢQVm/;&>sE7 #V׺+2R.vs6ZJP$ũU-w` D̏hwLAzmb-/pـ#Q X{śFd*Z  P |e@4o?Te"Ѝ7灬ff8Gsy/kQ ݆ .r7hc{b#m] G<,dyw<#_Tԭ+*@tI&M9Ym '3L4ԥ/+~Κ,1 w":x^@YUA %SgB܌s%wڢ'TH#Pe)`˫~/g)no5T.Lb#.3sEklD;I|1%qB&}(" TRˇM[: JL4E\13t<Tu|0/ R7RJ[hxM.xNw^}3=>n߰^/\ڽ+zێɫ@\(ntڔ^^JLˤ2iy0 &u A-^.b_-N5T_WֳN-#[A٦A)UX;;Jq`t#, r^Umb&W2 nV6u\<%ʜ6Csξg9[LYf{u:E mp9h3h_6iaf4J|:`leP'^!\RTPV8g2U܃;TM1Tn:8[(- yQPv@}WZvC&|6wQ,B>&(aS1u(4` "wC;u='1̫r0_ߋjK֮24X8k7SHȤ Cv*aKVsyʉ?K;hXf"BnCMQhÓ>זxCT{-Sh$o?4a4%lKwW +՟ jY}*R2:W:ǣ`*8!urGs&oZ֚~TiH'3]0̚8nn/qj5vd帹ݍǮ>w ym\3ΣI=8ԨU M8 SebIDM;vͰ´i jU tj?P2#.hAN,ai#z)Ţm!wjujC&k2CϚdD:}hAVCJLnOο,m&/Aql 8R}{ +R+HJ@B0 euz4")YV>1'՞H†-* V{>C%`,dW#ߒhb/$RW6>ӎEGG H8ʊ M祵s=$E8xu8ۖΫ? ?/$Vw:x#h[dK©{/7GIR֏_d*?zf+7K%p U}p}_6L Ϝ+|k?DfvCepv`nZDO㑤),k WgpK-sB҉!,޹ \=S^\!G7v<v$` / /ڍ I1O Tbpm_COIH#b9';u W/^G:p  ?7L@_{<kSu6@ӡR -genl~-o2u<8@;VG=ÄK H;w`^87fL%M" g¾0=d ^Hjkߴ4TP(v?>DeM  6M;7o̾& 1|a]fhy@C9O dCP-O6ATK&\7eXzH F.nçH_C 6KDU{~_ =w'mJ5&m>pd^:"må4}d0#3Ĵ,ZZa2JdاpI$ `m:N1nבx}Xݐ|=g3̠5&#қ];6uI7_OQCqn4Zi*Уy#ˠU[Z\jMghksO~-BLu/J6Ahj v]~ט*y v-q@ʪKK]~_2|F2GBE13Sf!>q}V[ݟ%*6Sz:SIT-rӅÆz`**Q٩-xv$HVzJCFT-%,RkF&|vdvyy7½&]tyz.Sn$\H⚈@ˠvʌǝ6Z{! &}R0Ds."Əs#6K>Z0h g9WzFOZ;?Rr"oI'пPxXD[YՓa TǙ֐I@-@|r BYgcw_x*):/3ƌ_BLaoMO^[x$UwVzIodje&8||j] *G6'2D7xmty+ Xm|[>eh(n_2mc뮾:Q* / G Z{ {`ADݔid/ nkǂ;SA;.t9=9M}k qWaWJ78\R,͑:=høU|>78wtM谅RoV*"^Ǖ9wumWv]e/ 'X{y/[ b I.ߝ#l(x9c+`G1$M1@*k]lw*Kj$G̘!׶-aZ[v^M- ]l6XEwmb,aDUyɥ z7.ª3a%Zh᧭񷞓l7}V+*)"}{]νraYOId΄ɞgE:WU+3G'TY;/F 6XE\ytNY" $Y7Bʣa 4pmOo15 PMu|mU+ 6jP7fN@)0iIW_KM*Nla D_8,"`v"0`R_*=>7@n,oH+#936.Tf b)+cj̖*3eLfB`19#̲nۄd8$t~GSj6ZYBJw2C @'v^+Ir OP'eiR`cB)/}G9 ?uKF;坸Y&Z7܉Rc~}QZ/UAVs}wL3An}u TTgTͻiEt}G@:.Lv5'zmN"ouv'IeCmghK&QGPXݡ_!!EDzM1ޤ{9%$l͠):w=xn1lU H ^WK-pheA7W"JjƠI UW`*b`A]LwRE^OOe8u K[v|%ֲ'h#KKh X1eu"0xdy'wh^SrKʍdL:e1hPSH:1ҹ1AO7Tݬ&7e iS1"4&dQÓd\ߩ[0ނ{Dmm=_ោ˻,WύO*۝UG}?rp.nXmr>a@ Gʱ'BV6QXU0j4(*6E8L z5׼`@x\%uޑ?c]^Brnw>@aVٝa:PeM\u54]9[r=7M+=vW5S.iE_6<٭uҡU{;ܦ#6034vkSN65]= /~%W=rMRVvDR/{F|~x3Y}id~LBS:qgEf|=0S2)'+f4}e"#=䭦(1k,V/Fըa_ZPMj/1I_1-H&Ēiߓ7 bum#銦 =:|9K6& lH$_8”n=y=pk/7acG QV8$J"mv z9^iQd$4S{&!m,O.Y,$$~ZSf˘%2D̢):-M?y'tV1G\A:,]AY )r!OPH ͟%%GtO`s^*_@gRS0:f>eF-x=hx$IZ}ˊ\ԓOVRo>K,NND1 5q tɘOJ %Fi\5r}Z {w Xy@U5'23?:m# m,-I`:|xЧ]' +53ym()q"WX$cZQ } 2(Y\cŔ(nW'fq8ue~\ms?ӭv,?FOUFrIc\Me_eg ^1wq7a/a۱e8508hzlrwp0Vf( Y2KViMZUȣtIX~3+\#@4ȪVR,mVr1sTNbá ՗. "ς*zƱP]q{A{m5`Kw>(ҙyH~5^T&C= r1p,: <tN[TVL{\ZhQ.8G߽ gJhȟä(oy@@-cD 𰛢a%џL!bZa *N]obvln{?qc6ޚ^oT'2kUDy7S+Ea& P\x#aXp*j_z%facY>X<,. yxq!=s>ض v|ch [EOm`򓜈 xIX9[~ &iuys`z7pd @ J.b#Jr \d*66_8^(πSA)2H튶V64ٚA⏟jEg|gȾ~Tw@w~eq]л d/PQQٮLf-CK p,0'itQP[aP`>Ɵ,iu_9" KOFJ8lwli&vSk3]Ǧ)@̶ӓl۔n\$^+J;g>SF^tU[4;= @H)̋\֣N.hB7G@efBG:y$@xjg )~KRA~%pS(x ӶS)-=a}+$̾Q7'AڴvAUVO(tqH,.0eD}aZq=63?&joZR*U=kG~ #lރZJs%JŘ]eOٔOP_nrRp#VhcNk-~t,$NJ=UF̹q i xcon5@%xF(^ ꆼ&lˣʇ,ݝJ24T[ChqL iDa'n4O[(7r kiE\N%PEW6{c0zP ⓼t7v% q 3&ptT?ىLUMwvR>%8 ʯ]9e= x{H2,vH g`T#|W'(ZWHr/lyh=S+A&4:4w^.B,VcACh7 37S$Cyec46Ŭ3JY.҃%ۍ xvuXr'EZ6fQԗEۂX k~ܬ`!̸"qa`A7`HjrZ 7zPCMg# `ˋ™k7@m^>ꫀ K¡I0ЉǦ; ՙP`_O\6v@zd `+D1:1ZPg03wT6⛍8-駳_ AX6WGM K0{mKȭ%/ïW MR}Wj<zcȏ5?׀M)C;q=CTQ(GX>Fxٲ$38JsuW`=,f`U7ˬO} ( qC'ߤY=׶Y\m(9KD2-Lm9+S3<˸DFn%cL/T;DixoZ>ixEVF+rDt}G* ~7N cԯ鿇 |tIaq;^jMdĴ0@h aȠ} []Z(g~x8R'@c|F<갳(!ƀ ]3apmL15iʎoނp JêИlb)6AH+c)V }2tbfZ@.|7[>m^sŔf%dt; j4Z R! OG 1'Cߓx\7y.=4ݖ9=3 OB ۙūXu}E N>v=4reHhAQcI$=P骚 WFȂDnA#PϽfXoQ[*~뇤'`D(e2Lg]erb8Xr}S~eGy (>6( ˴b#rcar#HE:} >ndLe6V> d;@geޓ]kj5X;BL ]'e fw!4Zs:8`4)Hveҿ8{t)Unsd40!Q@5aM)l; Z"ro&)xƛjU#Ά/wn"n;ѢZ%$y >|XdˀrS^V&; 9U B(лb Mu19@]5P "խO HvD3<փmr"R`nUDWBX+H͔xK.n4lfW?-)NN*lj3Vn;o^WVd.r*.^`Cu9'U#&Ѡd,_'ڭZ+9$mO>zP셉Y [Ȗb.$bk!V0ulHM^f8óad '3/q^kƑٹ hreRg. *]Wxr]{"Vr`t\R᫓u_h;ЋQڬdӍg&Iu诬 'UQvz_ 2y} <bH& (;0e.TwjkDfZ<(#Cq;SM||e8^!$r뱞j/3?ph+$w(xp)15f3lAy7 qIX(%mjel'cPw7b,LϋI4%K?ش1g\w;lIT`0Z! iUm gbbu9 8Q~(_p=C8^ф'bYIssGY0Ad B?i}>3 *G"1*>;+Kb v49J`W i0 /5? L ڪQ">D溗jټ)'TՐv-GK=f3 Ie91`=ܳusD|:rtL:;*Ǟ DŽ[dNW+蚉[cZ[,s09 zv:&ɘk'H*P4V8Aݷ[asO9G"Nev'۩t(Od+xӜ&0rU@)kn8UjFgsway,@t Fy GY`t 3qm`{ hڄ? [=)(M$Bb&1B5oU&uJ+Pw~#"93ѱ&i66]0IFcw'y\8;O$)#}Ē/ݎ/(?qV'@/6 @ư8iЍhR5aIA P0h̪se;B=z/y{+l~]/ǚ,KHxUyfb@=04u"4 483=q[ЌZdA ͎# ytb~+Yq&'hٌZ`:H\AMolS{!DӲIي[}"˳bfQH4l*rfa]:QG3MMb@h(>EU> XǖsR}I2'&Ld֟m/;!ihgLIas'al!:]U<dL}qT'g)6%_/wLj%/݇qOb_7 DEOp*Mr hO)x 1;07-y_QP"A$OܵӪ}_8מz\\y6?emx?*BnELEn*3s^3ry'NhV@8MkUKxB{ m(3#Cη[&\o Bޜ¢ FA~V*P+&l  u-eQkn?|XAZ Mkىjrd|QigM|ਫVSIX^'-%3clH BXlcdvpyIZpʥPqY*{B.$%"!蒭$b eDB DuŸ){ !6ui\iCH̟0# %Ԙ/AєNdtMS9:~'@zՙrԎ ʲb 2䙸Dji>Wqrz'GWFBԞ/vs8xSx; sDQ=lQa0$ߛa^:"):2m?xtx=~h Q@ LQbq{]hӿA)f`2a|dKƜ}4>84fDrrh" G ]U{\.n( BZmԟ GdT\гYaOYl/Ù-Mq=ą5!Y-&ǃiD]8~|ΩZu 7lb-81io&B1+w4aIh PnU(lJ#jm{*"}ZM2}1ڦ5.IL%](Z0vpA%`'igB8 bieŻm;vCCElh~MK18{we ܏= Z3&Av"iJ]S ?ZOXd<-wK=(9RR2oڵޙpKh="WdDSy9si|#P ,&o j6$|cU0/{pOw^1eu`MufX6WCMlSh4Z[yx>/rZy{fo;Qy:Mbg%o~BYD~qv =aZ#|;•@E_F Nnu;4?+J"CV' B@)SX}9jMQ=ο548)86Ʋ4`1 '?r1vNMrQ=c\Kfw _op&c vd "!1 4l̕x BK"TP 챐^,G,// ܦ_&up}O3%+#HhڃT0&mo)"#gZ0 6ge0#w 'рc!O&|܇_ЍaJ@f;lorx_?G:ne%.:<k HW ?Oy"Rjվ vNVKlDqLV/SF /& HiA9lA;?ג7n(ɛBk P$]^ p &r†3 yf}x!nil샤 |{6K(C/`(.ؚrU fpZpA9zBݘćt+uZ;ln$6[?36a0ϰ_ڢ{,BIE[ 3cyC-6[,1{W?`oveU7\o_jj UeC="rr9^\P d-ZKqnP~$&bKisWN6"I&jeE՚DAQQP23wH/^/|j1Y媹@J;(E5^:r)d*3۹ڲ?F춭|!0SYtiِ(3gfZٝgms *7l* u:+멑}¦aklƋ(IZ ~y0{쌰` dAyJN)]”$va>"zV3iqWJ;!ߦhJxDe T`"D'#Ƚ嘾! tl)bҩy)U|%J㪘}RLGem@T>gpjs2>K*El<]jRD=~&ԧQ^%x~+u1/rL %"DNxH'ҍF8~[BeFC#ZlH #fW4JO6j톛PhA61%kP\Yt:-J+shG̚TXM[rrC6ˁ[*٢mÌ!;Z&^*#ڿTGT B~|:fuIRb*]@xisy7|euQj HC+Kt Q$䏾"RH KqVۆ~2gK=>&6T4 V7?[WOɝik3f$6 G݀Б+Lh#:?#]g&l> D GЦ<064xse X'v(ظ>'F*a]`K7 $H5\593=DQxy;mb˷ž({N>:671t92~YYG'Jʺ3YLl_r5ZMy D']C q?f~ ]2;n4TDid` $VCIv} L m+im]_G1e{@yh/ <&b&$WckVFr5Cg4YDNXצ,k+ObfsځK< m] l}-i!H 6[#[D\c&a 9*ogˣVAT L郄һ@l=Ht48|8 l%(. !xCbBNW&´Cx!q듓ÃRW"ܹ3nߑMp5E\'X8?3w!i}) se晻 x8"ӳck0d(_Ý  2\E1twm\ovéidD?|P7Eo@DģOY‚A-݈>™1 ,3]پj"7̥⾨}F5AVȇ>1-+,N?j>^%k@ n.z5#iR^^ D@{jWv~XYdžAff% řlX/~[aSQB>&f{mCq ?rL Q>j>\('Mm\$ Ďr;b940FPvE~\K#a T_ aC)Zv rS RlXA$ET=Ɖ` Y\rMmgYh)WZ>q־'̆`O0\M0jeCI3<̐A7'mWv/sܚ0q;|6sgjapCWJOAkqBT~'@hsq8SҹI|>@տSD;eF o8&ƫ5ltֺ9Sm+nL$c! Áӣ3s~F bH< {ȅV(I8گz>TU4ctЎBKj?W휌ӈsz+{]u|^ݒ#?Y)e@F|ΐUd*C#ꒉ{RX.54; ** !;]?tu`D<Cذj*~ T1,I (fDE-MRqnhnW&O`MzD "X5O}2 f[Xcp&oL w=vW+RmS`\\6-E>{L.=ZJ@07;_%h `i# vi cUI #Ex"0D'Cz S<<|DeS#wԪ]2]x#8$t501 ; !]NI0SaY oC+ YhiQ4w굪 3 W2:fs1~;VB7h6SG>ߋGZ1(N;?v8+dI[R/x=}.t7ʲ#)G*Xu?TbӌN!kT=)iVh|7b֌l+Y6lO!)|mo!vM'yܛ1riw;>ϭHX3ﱷ5.Y"bFYrOsH -^V`yS[IX kkcRm8Mv0lgAġbt[f%Zto!_ՑOSq7`#T aMF~`]l451jNx3OcDF^g-M]198D1ȈNC;Y!dg)x*^hs}9oR~ ,ܐSW>mF?`/">.ș&5a _Fs$b ѻ,W4VkkDurɃ[1)[ߑ\J[Ŕ[f8b[ÔtG=6MDTl [%U%}G#Kɨ7 V0iphđW_L]aT=M٨A"IUc'g/RZ{>Ó/~KÐMqil[nhh_vNϪɥ#V~Tb}Ytc-eԺBe 9利.2X@+RkڬP5aZST-n Ʀ;=LiK5ø <ڌI6Od|yG%1a}3'm׾Et0_z"Wl]|(W.-x& k\5+׻T!,z 0"s3rJzxnc}22 "LJ7ie3:vmeoL6o ,(-mVXzqL8YBZ/7]ݛ]V.p{>IH30RGmp;jU,`0-z?gmc!t2w;R<:~p},Nt7fEjj 8ڕt)~YVg+U-~{mCҜ2nQu^nƛsj'aNMہ(_ϻk"h@FQԪ.7MiF=%.ϔLPYk B'+fVCPjrki+pzyK&D01V( q_ $2>Ԭ Oj5ӡ}h-H]Xs@m]KmσKxwMZ]<0nj1l;kㅦR@ðFW2 G(Ԁ< ^,dc;?~RF~˂TѸHخ[`д5s0YMEv|+&RbA.Q1fF*!?kXDUnviI ~q0W߬p' 6x7;FqMˆC.+3`3u?c|D%],pfQo½Pu M,An8~ *e}6©D9͟fgNt);/+!J\70 ?J+:/:X~ĖN_$5 Bi5<@YƷdӞt|fN}ПLwnoX"7c9xQu/G3 53Hs~qdR.X٢OfY.h{JLN@f\%{NR+=oS1b{ ʀwr FOڊ;(r:JWv'7n}=& 4uSW-c> ;)ΧK`v'4Ȇ_A tT)k.:9*F@Q'74s%Gb4(iϬ]W:h&s>8b^iO-sNe2)#z:ji읁Mviss#LԼʊ&4} Y9c4>u _Dů5v4nKD^kCva'cL,6k|ӻ{WIsA&wܹr$:> 'v 2Lp[ÞZtnO>3PDۡ^//{P1Y3Z'g~ ]]i|Zjk=^?Kz.mCq<,[n@.⢭GQZ07^}>q"HW;,sqvBwի)OD;+ð&Xߟ K ٍ-$jVUwawۚ vfQauJFfng C{.ܥ6=/?0#˙/+%iOQurS>k#}A1~>O+I\m.=~x"$vV]wmBPFGG|z[HȀ.pW.tr_93f=^!iCPsC,!:ha{;1x:`;_4IqEn^jCn? Wgb~#{KJY3HRʚkW*pN6o .0#Ntqҙ'QG%5Du&T_ChKw34fsJiפm7[#ra[(' (Αmy"C&֔lI2z>c/st$Lk2d j"{ZxМݒigML#Xx9S9v"אw;_u [&)ݎ*S6j'}V+f˟zL0 s>TCtADϖK)uv<^ .UD"DP: 6T0-4ت.e6 h/m.MB[R^x0& ޳37 7g}~Ҭ8ol܋y% 5;6= dR ]Z+v8=ֶzg: 1 .7팰UsU:/9`FE+{yQZu5W>lH歿We6*1vmG_᭰5zL%X*um^$AEghUDۚfQ[FzG+R|@g7?[?UY Ҳ## <6լ5Y5ܧWVAmK-<ܿo 9mmB#̓ל.y>DZ痈<֡ w5M݌;7:a%YH{^-~Q@53)Vϙv!gyui'J'"9#dG];ؔ[(~v]Zf&¤%^H4 R_f]~|٣M\&oYdM{]T)S& E-:vݹ0Eü*KY5!;dqICtP:z|te*E\kÒ՟&:ЭξDl]#-tc ױ~) #eH3ܐ.F"M߷@p3{lKH=x "t'6"ֻ*ĂEI&p<$7]qn#q/BI ~g`Z2{QJݓ3ckSؽP/U>-N%a#hth{Lz{xH 3xFJ%0J wnNZP1GY0l&!l螁H`g628y*TSFW4`?yM` r)&EjKQ1go*R#4? :FgZIkZIJ`,n qL01Ģ~66qV; Fl1l )fLv~e1)@v;u$8?Ӕ>03O?D7,JtCbk+үDd6#6vgy$ ZsiHour12{Ϙ]Nk1=)B-__'}A3{q$i;!^Բ: 9v7-=G[w6[|]BKD۪O!i6Z}O+ѸQMp־#z^Z:;`S\k0 a]"Bp@\!ƩQ?I/'!:@PlkV3 e1 6F&h$ͮ ^{)|%c!/WE8aph x]H.tQ*2!i8 |lx asVdf0KU?W ^?seP3aBBQx+&1ҫ͛G#wW u0yVD ;`;TKGe4eYBpk6P{^gֿ+)``uCc5TlGdL|zDy!ЌtAtc` $Us#ߗ5}68ΊnȳA)2 `-ۢ]aslY0>UoClœvēֶ?V#w .xJ5[{4H}Nڠ~ FT#0R`v-\"-R7k& Īc!nh,[bEH2+m0P{(k#Ky?1r|{ΥB4yߌ7 L}oq4wyt8Aq⍀Q @-m-;/f7^Mۤa0 \pۤ&f*גgiES3!W&>QGIEslĚTHV֮y{ d oPiFp焕T ˟{S /Om|?aÊrj\k * OY)^YzD!lt(`4//h^Uz" 5KgG?yqzl%֥^B&ql)xSD2Dhډ.dg`.a8xD){;A8t]7$~꒽Rn=[n~~^klnqv\&~\lQFa~ E7ÞsWyz=/ :ڽC`x0봐PE|u\#fȜ!>=z;x_/CiXE )ϱ㍳E()qke5d@QИؒf0nw7DX[)/[jRETSY⁹XHϦX[#4^3vRz"? 65V6'1~kx%cjpﱮFӉ)O~%*9{Fj/ \+*^n^(#pq=++v[Bc5IbI#8.ặs=xMI  :|'1P͛xbCls¨,#ڸ=Dq 6 RtCduu HwzķW^ڥھWu*{Je{T-E:Cc% |iNRULKp}qU;r? .IkA?ygӆ2}x^m{۱m͟GE7>bBwpU$UB@Ja??db"v7eG17W6a'#O>N灱T<$Uw/gyxvr r'4IAm5iW#ڠkeS_UEҲ-R>]rg;9G +GNE H"e{Ö%u;* L9"c[ yOH%oPejVߟ -:}q$%'X_fv8x,uf"@UeiR+cR*>QG$f9_nwɌȿm>YY=Et3gZ9Mô]|ģѩ|0&Nωjp NMюT !GnD_'MK<"xhOkt5[HVW=4w4ex졡Z5d's8e dW9QIc;o(3YAzgf,U'2ټu8 eN!}zL/ }CQ{^EB=4aп;dOҤfo3./s%^-NzuD&,. 8͘E3-0NT: ^[HjC!_oY*ƪ+x$C0&5jB>O)/HZɔ 5G+-} Os\V_mS{+!!Y~Ͻ6Sb٧f?x Ve~>5Q~[0ekBw5)$U }(-?s]s:9ghƛ6Q9d U+0Mvق `M`1w.#Q8`ٮiVaۃkxVi#>D7jcaSdID5P_:.oG4ę}gM5[N.я\wKoag zܔv_FnnHa Д>7< 7_]mUT?V{^?&vZ@,DI_ 3)g v˃LKM8љ7;ML ^}!3E9(lo"$ܿ)Qny#тy %LRP$1ջ.|w["A?XnjylT]qz3b<k[bZߋυQQ`o'S4QhoB?/ܢUR~"7|Wxa諁k9D]pX-CdSvŭ3i2Ŷی5K%g_B&6; <(ۥO=ol'OPEmD0ɺ-KV0]g Ó;nniYSLV`{3}mwBR 8K3Eǥ!/3`%}Zt۞.5Z;LNTihUHR+I&?v%Vt$T1p~a:Gyܤr"F%z"ysC#6Jӟ I=c &Lr9Yg4 t6\ xBZR,s0wz_jGW;H PmŇ$-Y5"ce3|^Aq ^g@{+W+An֭U}! ^X/8VbH0z'ĕ [T0d „0!Dw $k1aݛj!NFY4;/ng|k(RHfyc<:$,Gi YMqx6!@ 2#@)mt]AJpU){U&M 1M^ 5MCخL+xxGhTr!;ŀF%1R/C1Wն kɒCMZ2M"zM ,B[$=@(xTUEaQzx Q`c ۫CN~:yas?%֛a|2s_PFz`"q pTmmӓk,a4?j@ QF(+>1F,)+:CHeٛV9zw􍵀iNSn<U[ZqR0^ΦU-4(oWUF)fLrƇ.[7 gh1D`xkBYϤOzk]Eg9 ;a-7o/?*zEP7(;- ܫ;›rW?lzJ١N=k_f-u|"cPb'w64JTY0r-lT雼q-/[sKCӻgc\?6-q,}~ m(8f^*: DYМbeGOU!S#4-z;_vӻFcpQ rkaLJtո9Z*bMTBQM OllXɈF$E4ߙ<;mX̡k~@Bv @$*_9N:IqMP.? JyKfէ^׳ϭ<(G gqƧA)Pno6ISě5c\A/x|LYͶZioRsXWN;OO L aΚ%j~8"{(ѳʵuQ.صbNW -NNIEP7",P3;k#{ݝpa7( "PXQbxN8H\ :(8ϒNNlCpTy.3lē|N-RwŖZ4V:*ΘMiء@h.(**<4;NS'25'36&FqJA\ɾaB7]5;*lQ>e=4j頍xL_3C  fhIb3o›Vm9$EܮO=\|:6jX%mpu6#q᫣ boSFJhv) *_Ӿ Ss_}X=7o)91}&'~"aO\0cH?O$ҕޖ?"".rl[X-%1quɉPI!܂B2mF|}ŀ -9 ZWҾr%ě!ꞥ,5G \Z}vQ4v+o60vopwGv`5@Y-H< [SG\!լgX0_#Y.?2;Ul+xJe.UL"?xrHM٭tmǦ5ۉp(pϥʏjc2>zːQ/r&}wNCy?zr>ݗx#ИBtbb3?aZh)yL:sp|~:H˜ $یDP_6xldWH%k\r·؅@0WNpf kX@eYBӦU&?^ʿvJ2з{1`mWݠߦG0"=\}=7N&\z5Sx*)ڔDz22$ !?8h9`Ԏ܃ˎO{ps}>5k5=ݰQvtJ6n9EV[ֱ~*3r?2hgZ$hXyA?!ȟN}/h"ߏ5]iS!\\ Aʄ@0m2qJ($P8>N A1U]er^ ATv>wӶ U).~BS(aW#cՇqQnў WʻfDY$捙Mnўes3hSݜ9ץPim=̒م: {{ =ZxVR -ad34q:ZϼGJ&x| j;?]o_#po4T{W5__=z4J& &+ TkY8'r fF½L~ا,tIsyj6/~o1c#2\L({oK q;k˰9h3fΥ1E%\c .*kM]r"F5oI9\g4%xr/drmGօP{ ̦̅oܹ91'oy#]A1M0xu##7xoG`6rՠoV7~S'-W2%9/ŀq(Ќm\t tKխaʤwfk.yb_~0nt1<8AkȻJ̴b:cvug-aVlG1Vm=aֆ,.^}+Ԡ ;].Dܿ#,^b W\-qBd)NF)Ǒcᢡ Qla=,%wo(jlYUD$C}É~f}/_;q\Px_dcN瘫/ĺ%zņ'P>%܎Q<C/2TwtFdmjͷ7SeMg%]XT^ƣj1?9I2s̏V 0:<;me+c@!ujQ]#pin)k%E"*Sr_T;ox{?t8SSoe^cYaē`0/0%@rΩV/Pp$3t ھܘFZF?(T Eaiϱa6n#arlH&nIm DbyNpP2l3>!BVd72~xݴGܩy TE zr_:^fT0 {*~؂d,Xk`t1z>Ew"&k<&MYW y+/|~;gZ3t9`2DѦ7Bv#D%cԒ%A9{CmƬ{A%^2 ůMouEo人~㺊La/3q(jǭM/]WrX,mc0 )63Ufg>o`z!9z$W㿡¨Xo`J,?}wx)=@ ]55nLtwnC2}0(P  _5T>U (#6ol<'ę Z`BvH﷓H0< sR# G@Yϣ~vg'Jӑ<q\ h:$+MmNOY& u%%"xiܿU(ͼ-oC@V%ս#Nmy^v1fߜ_//v縂GJb``&uޯܤQvӼ 2 rHӅt _͐޷ e`;6֣!3jirYdJ!f̷S79l_;i΁HQ'N6Q:Xn4Ό(LS{<81L"rZ:"0f'8۝XRUjE\~KgZn[tgcP ^0(#Kx4Bbm %x.MTlJgUDv+XJ=3'~g;fnQuQ=FaNxats9$0QRxZ"?+J6~02ňGT%b#E׾,SZ V?}:>+8jmU7s1m3cfZS`:EIjdiUP@6r?OEl[f,,ba& ѥJ%5"ps\m9q`ꝷyu K{d3*b`edP rZo@^۞<༤ww!xk)x-$D-RBtkR餋o:Wipc2,|`+"UmR7oNֽhp=c{o>T) PN`샆r/ƅGTkyJ)y[%)/Slj4i5&.v "N˪!Q Way WDĒ%lqg ' ˬ4@L,, #k/ڼ5-n;W&%%$"T8z,d4=yӱ `*-d˵pfrk\urTig41GY ۲ `Q)a((UI*CouJ _oTj{ν2,5{OUW _[.eۉ^EpՔqĥfͰZMc'GhE0N~~y!Ƽfm9me;nqu̳e|`WYҥ܋K e*/g ϱ/B\RY!ŌF*ݬ.>s8edr80_32VPDjިǿCTav +fi@vۛnnOX|]:u 67y&UlTVB|*SҲO2g|bG`iR*|!2yV1fp٬Wk4>^cNx]N0[25ݷъa " eKvt4WA!HJ_iPک6{Ϩp>#z1uסgh|eɚ\ FEY;]~L<թܼ"r"q9qRT#}29VDz]$nԪ8QqA ĻZ- >\ Z.#;1ag>˧ VTX37f9^FznAXmOYyw]igc ѯwj??rN̲N(6~}!Np8uFbԝJ:IZgizȨm(vO!mTD7>WIJSn ƨmNy$PrE;Ŕbn5. 4`$h;SAQϡLuT/)HʎF1gmͅP!~8}lw F3kf)ϵ~0GKƩeZO 8+vү8Ap !ɟS+j_AP okςM!:/&)kv9G"=ڝ##nfh{hIo\ZXK?1\[%VH@Z.Wp3?Ɍ}ܮr?,pepk:QE}K-ؓE*oyjQjXA* ?Abqlf)c Q8pP.{lXV.yTP;Bw~FK1T(#~q7ZnjA-^cwdKGl(?&%nGrvB~GRc08X$/hU鵩mT?Ym=^ }ΨH[)! yk4kx;~@e:4#„Q,NT2]TgnR$ `ي{8 ¤؄}i?y/(kXaҮiN< j(Fi墿aD@_UK.! ~(RwEHvI1~jdC}޸^ubpP˱qXBq9e(xڂT!)k[ǦUkQln<[55=HKpT+u]ǾV)ZkE6!NB4eQSob])tۯ ojtD7~[nX.sc2~/dDG*VJ?^R:'o1h sFw8; ^(E5^HG$=d]yXVp>LeJ%`)~O#75lm;Ny 7ʁ?o#_ăeg\YK cj>.q1qeìi. uER~I[ R3NR/X0ᩨNaݣb>e[GP;eVj/L{[-jwx ';C "= CfvV Xv(ө'Eޥ}w<ڢ.~냑t)Ҋ[ @C" HWVĞ`׸'o^/tm ?i˹3 `,H2}ɒt1x~z(]P(=9\TL<,P>U;7j3i1DHVgp?#z4޷EuȂ.EѬ'rt!=*ib3;jw~2 lBS,C I3-jv]Z<Lg.á"*E-f01mrGbk+;of 8R$٠ k%Z2:ƾ#˝foR[Lg^+g^LZpym?kb!D?EpOMlCi S|1E'R:0(~)9Pnhw a}pB~ľ&-) Iedx;=8\"~t-n\|. F7q.򚉽Ф_r:}7zl?O F(qhы"U=oEa=?aWW;pT"X!ld,ldƐ,mv­"0rp} S? *'&2p,E8<۰wV";Jj\,2l)D/`/ mcT\y 2r !ȝx̡vфj>w8U ]njDo%'xTs0)Xe!!r8ڎF 91wNT "iޞm]gESJ G^I3?d5ЀյLK/0|RX=AbJ&Ycx4W%$yb\SX.~ ig,X͜/<4[dRSyw!eIx;njb enq'=dƀGLT^`wkWxd"~1>X< X9aMqx0ZdM"14-^Y%cSEyƋoN y¥Jd!Xߝɝ>+|}7>dMƳQOpr'8vkbq6C\\&'D> ?(5S _rUTJ5R+{I E90U9LE;Ĝ/Oپ?4\ z),Qxßi;wQR,CFUA ٘{*N;N˒ I3D/1^j:M}ZڝXCL)|='W+&˴u'.>Xؽ' ӑaXcLUȤ3M_] py"+ŔkhW!jr:CpǚID 9bO* Htu PFYfNOO?kC@5=wb=ЎRly ke .TdAf45)ZZ(b맦cUl&,Hm!!< ^؍׫,Aj&f&'1<̎MṶ ;'3PǏGӥgϤtxU"3"GcE¥"Sʪ ]HT/RrEp*H!^AAĦ8kzjF?E'}ZlKh͹rq"77v6hy\}Gܷ I*"G=A3j1*( ^RzKk}@Ξd"v"e ~i;('UWeZx{&.VEl*+i#mO0x\A3z0&17."*=>Ǹ"+\]-qti^y4^UX,(ͫj$YǦilK#' !Vl|߈^q/>H,Ez Ls 6;,*GEd$Q Tu6A"BSȕC =|HOn, F"0 j ~~ *DS'aEqUBz,m6IUWnE/veI)'ђN,WT͉%h/bڦWCٙgқ[_&ZpF68pMӶTVeMɸDu.rSx2R||.Se:LP['!R+`|]p|?8=rN.!$G9V=m&"՜o1q#,Ew++Te|r6r&0׭Fdݰ!3]`^*P՗/%(~1q9b!,/ӗzޮI`뛐 Q7;'(5G~ EPi#\鴗 ͎;"ʹ]nR}(g{oO;ofYTpM %wuPh .5O)TFjyn[zH$y֛WBWJYyugߧ`d&O/@nz? c޼Aq6rx+൵ Wzj {[[ā%,ˡ"W u/Dz43RŎޚMzޥD+_3 NrբS³=7U^cW W;͗05iFt|HÜWT>J :RFC頃aM:4]ڑZ0KUaS,{('$~h.p<; eE̎fh-6ۨL5ԵGQRlcxփq|Xw1BG$ flИ51<υ)8%dGρ4_w"QpumTu;̪3DC{+ܥ%,*Fwo90Hzѷ(eP,lAz'>=ڨRO=7k6AǴsof"aؚO| .@p{;`p߽m`зVYs[Rܐ7[m~60 cNABnț3n9]{wki`N%QiKG4Zk})>/t*xRs[q45ћ±5^4#4\&] de]ۓtB0_b$0bm.n̩GZ}P#jιe& ސ(sɊy?( *_)o?̄c<݄On.=Ef9_v{ :Ц/yI+R&D[Ͷ㒑^v+>vw t?ϣH9'fvHf'nOɜykNYg&[^~U(QH֦<0ؠ`iMZ.u~u~Oœkʽ:޸U[s9R[3rebE`wpzxUS<u[ Sʐ^^Xnci@ # vjwjɊz✒ڨ"j!M Ȁ'X`Ciʼ{I+$dYg{SJi볏}MiqưQhO2i^\U|R2{Kd#gAӓM* _XBRfEӁr$ c&7҇$Fc.`9)93-`x[R y:*ֲ < L9"2T4^Ol QEQä/yP)m/FD3i| |5SÊԩ+[RGEsԛL:we?RCَ(6_*)d0DWVwiEݰܧ) E/.7TǭϑWo 'q ^'@)?\fi2q a` OA= m1)l„;>dhׁ8ޅޙtψSӀN@2S fCh"gz1O7ՈB/c)u 6%tllC<nGF 5 eݮ@AL<(8NA VҠZ]P{^YLrb=Nb&"`9!q-}6@EcfM!h9W;oh{(]4W b^,mq$&IY"mb[ۭ*WCcT!Q<{S:, 6 d-h82loGSܤ~;֦4 qVH$349" 8>Ed-k8W~kW!2;aUa67@%^QF%^10lq@% sgUL|U\]5a&ɚѾ#..+܅x Yq[tCr8Y% 5Ô{?\FaqrP A6ƻvm$*^8D Be<=77.I+MT\ҸEaH$Ÿ9@" :ҽ/ײ42q$4\,}HZ 9}7׭n bl9YM#Vڕpp3;JC^Na` ÓSjjhwUj347[ TD4'[a,υJŭ#b%9a ͨO ҕ.%5?9 rP2E!5ײH1Q+_7#er(b7͋AaS aF Khe}u4.ߧJƏAvwAHp[o pbo?97yVsT$tiaCq̋_ܤ*:E3.q՞Mv&{/#~Ҿ DÕ?Ďy$/j\Ab [HP;V=ɨuvZ/C#/, Y o5Z{<lic8hVZ`5}H("ƾL \|Z8࠘ʼn.s'p_\@hP+7sψ&Vj81*]L|jl-i->". @O?Fw ۿﯕ"'bl^l8¤ւ/%o{] GBHku7.X&MP{Em ( bq8.&8k0pJX8J'y02h0Xߟ|mE,5]7(2d'c}0!F$4G,&[b6(u8$Q/:OʬM lYStX}9/<6e$r]֒ҺtKLE xbPFE㨵%31gmOwx8I3TYv.e:RI[sYT״V v@n(iw~$߆$8|/U17@iN9JHl;CG [,jbohoy+u1sAYOaܨoTp_#k o2W˞{װu0Nm!#mvIM޺jT.EW>z$dp WWqV{VR"+Kw<@eD=O:Ps\dm}J u#Egx|ul4c-pGTOg-vYxBp.Daѥ)]<< `C[Et+.~~l_Mװ-1$0$Bj0]fƥpU0n#:BN8 :LŢPKJZRuuLnQm_J'x S/7ѧ4XƦ&% ioeWT _Eg$3@+ًzۣ>SH HT )GF0%I.cQ*?#YV[W "V/.-__ &ց0|F~ Ivd)@/]<+!*ErC6;+in:Iʾ}J&_R 4jFOB &{~gg?YWӷ1c]S-1s$v]1YP=EF1T0aP@+[FpRCʿ4Y-BP[7PX}"K2'Z[/&>/ܣ%ۺZN C&X߹DŽu!f<_ԮĸeqYΝl=b)O;6׆Ur@Yw6/Bcvr!UW+@Hk*ޛ=;0v5q dzx,\~H,@"G* JbٳNuJEF@Z$]{\'+8DwQUV%+%gIR.T F&j7"eS`3Pԧ.HIyqUʖ,p X {JRU-cQg>7%\5.dRT0n6M@[jl(LY*:f0-x$rB-z`6[(|ov̾ T<+hKkg- |Sn U@6TN0;qY,x-?(;\696A_P;tUnJ&$;WDG3Q%Unvfy_&:wn JQMD!PkK3u'Q̄ej\B\1꓄+TNa Y9lEwz9B:)3^kRy#pOjQe:M<N9J@|#6gF2\,`quM!Ew{]*!LeZ[w|F*>'ŋq':lK T+`Ho>۾%e~D7F){% \݇vY IFg.83JtiQYq7F*m 15`4^8n]A$B9Pn<d+hka޹tX`.0' Tq[ #xZ,{nMzDDozM^j0(1L-מ4 j)_"nE'.+u7$R\p# V6kGr"~sE[>@&/blFE>ӹ, (3`:dU/8=x)3?{u$ P-an2DGxN:#&ot~׃_klVeH.شw ṯm'!1gރ]Se8<3;{YaŚ1֏G탩]2_^ۮW["U*H'Ϩ\GZ%:1mK&HdKyE\[xPA9,ffj\cn}ڽ$T7"/A.$2~iK@U _ރlqqvgk:}88rbҗ`<#H AXȶ!>3[#ޞ|kCO1<~FOפk3߼S6|4ZR".^ƻDĺI.VHbAFt""oHl 0%_I0juژB iXR11J>&CƆh*W0s*U$ܭ> eWNcͮ`ey4Q@IWpnwiɺt~l(~Я/K4,KSV,'.Y+h >ܠqUiTOV 6w<*Boӂl,;<j4sXH"9 aV(pJY>cuOƫGD65lp,gWMJ}%q UjQ'b6Ixr@kub9h$7Y6 +9b┄LJ@nѾe$ CN^ٺL/RåhLaiP 4n2|oۼj^$*4miFC$D .sq%g8P칐 hzT^~I%4<&59c(z՘ ={MΔ'y~zV JZ`-wYm͆'ijKLa)\IWH]D> Lۖ8'KҲݥFY[߃8 Tt87 ~LV~@chW_KÎPTMIp|S7>J'"[=7y1 q)-l A%#kZ6pͮ cѿ^^b8^N/#sA>O&Uڜ sPTI?ŔL+~Yl q/(|tQ V?p.Aěu׾$v iEzL g=j!i  3+ 0tAyǴt6&ٞ~w=_r0=;O4LcݩW\IdbF¨yekк17˨e-Y)B03}K~\זxM6T|?hi~氯n%G(@Ktp'򪤰<œݾFs4Y8ESμ!I%x>ʩ)9{٩-U|Fw:_nU 52)/ 3j2/#~bY[ .p |4ϛnY|gEC4{b7wԋZ7E;1" c2J\W ` ta2a u ݮ2 k?#щc=(gus 54r$3Z흀2[AIL=\g[#F7Iлm)a'g}I}-#d)|Hr L{{ų:6ȗ(ym{IKLҒ<+@6[dپIX  x_^[( qJԯoq20U`!u:qʡD)TC:IDƷR⟗v ׍@W /AXC1_ Xߧpx%2yK%.T-]kx萛Tcڪ4 2\kE'G-ӳh+'ЅC " 7W~XOUZ#[\.8Y{5 vCrކ{=8B!C-(@Nt &UcxҐb ׺ĸxSZ2¼-ckM00uyd^epDRq6FRDek,|Ex io! •6e2#na J}#ndU4r)SJU2Ʊ>DRu,Í_$VX'H}Q|ҐE qC.Big!ŋX&wJc({(5&'e4QRċ5n2 ` P(YwW?؉6,ڭ;W9@wBu2wLFw]QMosyb8⼯gx -{QA$lWĵjk) uzŭQ'g]ɒoDun*@KYG5! a;hT)>IKo"@kӡr"x)h ]˜|<9%G 6Q&e[&N/4=E@^7@t!bK%rupbM?+nQHڒ3M)a@G!pyo?ğ#}b i NƮۜ- [=rՂ 32\^%o'6Tu Z ^M`A 5m ٜgV>j1 崴ջm4jhrho_+gC׏m+j*`)-nUt q/gM5+ vhƣ3>DH;pL+-&71oxLQN."O%4G",eҋYĀs%0JM\޼FQsbX֗_FL8nEYm+)ER4mAM& 3R[84ԖW ^~]w# 39?G4#uQY S@p.2]@*l3_JJN.~Lg*tA=%Xsm+x.gg,r76U=I4O. V SPF.Df:mX:ZD&nq}tíʱ jR3 zύpL?vC.# r^Q%21Bj:pB#";^eKXGt,i+\螶rߵ6900PatF xق g2fF񍢁aֿQ-i~e] jAcDg &D Ue!#EgU74ȯ: M[ٱ%8@/P]%!/%.E`0QAh4_u }8Z7_^ KlBMH%;E֛3{gni+!y&>4gO&exP$<w|Ũb˗B-+P@ 'Ty\TZw:R5h$O4׳Gɖl"p xךf c~RMr OgcI-HEzO':/ٲMp"z'E v\_;hJ6/F{x>^{U ]rkϾˀQDg (i-Ox%ĦXwXm܇0htpݝMZQ7LYo@A4_ĵj_J`׻! @\- 'ҞXCW6=Qms6aM=~ H',.06ZPe$]" OiM28Es_׹QtY\D+t؀l+ pR!+,-qTM#l֯B,P.u M}v;=7K}  ;ǭU[Ubi;cHوe3؇lGGa~ - qFd>A\;60fQd8a]N8?(6̷\t9bH@Kd Ƴ< *&0\/eNl?ǶLMdr竴.P`QU!Vfy u;߳du>W:N6-Nq , 3Xk1;x{8gnj =G z؈13MtٖҕhPhDsB67.0=_+J!)tP7/r96\teq%t)>1~mʹI~fy{-P)fҾ},}6UBRfOd * îEKi2}1g&pY.yvK! }/Jt,v ?e>UyP;dYsugH2璉| V*A=R@ՠ*Gz_JWLh.5SP/@AE,W ~.>h ޛ%'ÇכY*p!8R?3IO0'o/@%6&(?c9p2vmqk(KeJ{45r ~F#L W!wi ӵJ88Y~:6XIOsiV\o?ۭ_Y%gזG*ݫ'S!V nDM}/}\iW0Ŭ:eIfypm IlUU6_e;|nsNc yu^dkéY|e?ԗQ -p{|`"eS῱a{HӐQIA&o 1ӥ8՚DQ=I0ץ`|Ǜ.r?87~G8̵@KT6שb׮tmd_lrXܰr &󏺁SDg (L aL@ǰU2S/ECwt<8Ŭʤ_!PJ1c޲˚+%QڌoZFcLv<'X ^%>L|c&A4__&Ihd4;_u#;FH7(a7i0]L]ˊO]`-ޅ}:[o]Npx ƣIYgZk麇p EnI('n*&4rC&0oHiexWZӥv]5W%@BK.Ž'ldunܶš,u[&vaATP$XG lDsI &C_ TJШ2ٚtIܫĉGQ I 1y&1"1_֔ly1! 3s^=𝊍w-Q-((e(kWPDɉ-zԸ;12)?kR(EU awikA 0 YEQO-ZT)_ɒA/{b6ne8W<} EL9#Y)E96?[ysc g /U4U|޳fEo+4ފJ.l:Ӓ&+g)auj8j6Jvԧxe$z7b?/vE*y}]-(- SftKCc,H&.ʁz]@ ,}s77q5O=[r8R&p|Clbҗix!@4!dr8{d`wAuZK\y٨os"û"bZLGUe8/Ᏻ*y4#u&p 7#I0 m&NEw$QzRrb-rl,1XŚy Q!o HNQsMYwAB*c&8&<"hBn:}by +v`c^Y\ڡ4(ʠH@_ub®V'F o1Ζv{R2sL 4A~Vq57JK |-`\A E,G $NKҦ:HCLF.9i($yD?\PVfM6sl'7sZzeYyl6-{u{UHc*$Z/aLAQE,G [̎Ҩ/pHB{?l`[yc82}j\><ptF (,2ór<7gj2rDg ("iU@9,ԁ Aw4_ĵj@1U;,dJBgd~#t)4Sv ,8ڵ'/tP?R[@dw΍-01>W8$VKXv㖃Z0m4]ڻZ?=QQB{?"6C}w!w >(ͳc9>EE ڻ"!#i j_uƉ<9LS0)ǛK.H~ؾpgpvK:ux"UQ`%܇tי4uႰ n5γ,餰#t$s VxSϫ U(%sxgsp H GsnIiYGCw.D fngU3 OU45Y5O(]_|٘Ŏoa 2}S;]-N w_bh}fɋvzX)8ܵ煛8 MؠE τa-.9 t-<r6{ ]xg[cV42ΐ`ʓ-lVM/$!CCw}tWGSLh/m8%bچFfـݭɣوTE ?1wl3Cf[NPXQPzOvdăƘ\2˜5$w)u2۵[g3ippa)=+ͬ~F6FJ.N^%֯(_X=yqcBߔz,00$\Btg>¼jt2 .+j'Ig׏;qdL񌪛{7Av)hڕyJ3X UrnY,t%x!\U(a{օl'f]@iSV(H!д`k`h 3'68h1\a}L%^$_A'B#:S،t vRkx'ϒ`2*꾷ilA/fMB{$B#x+ RSb/g#:#zJ<^О픀=o_zo7h?){emڷ-[duțSbtk 4%Y@GR15k 4u>e%6&+~a\‡PTXñ¨SqY uK[^neG` XQi^D,Gŭ)ES>!Y`~ "ZUٲ`:y\v^Oiw U QB9i'ZQ\K5)(neo~G9dO[&J ^ *rr3-Q=U+[W2b&~2~7@plg7$R(Wsyv)zI8nHkPC R^aeFeߖ4\m6ZfQ2!_RPUW9ލsL}f5pYEbE 3?F!]]mڪl_eRv ?va6bL)j2vmd+/*cY \_Mc,wD}|+^3n!($gYXΒ$fFhD&KG\d|:_,وxnuC{(->{Vò!)5!JɅn#WWc~itzY W_Y^r!>5RP! 7HR*F`naYԚj[ 1p";?̼dq1EiX =8ޝColM"q¼;??/nEMމ",BצEHsN](Tnn*I l-'4Qq "qa =PaM3Rw|Iu *V<6/$u<ku}*ffu@QkZVOXMX2=dJ zxf_注;Bf%is1\QS)aмLJՐhamcp\7ŷz%d/xc a&;c@:*[?Uoo4< 1FUI;Zi p:#S|NGARp~6de2u/s2WZ?NE;یHI%.΂$>D~!WIPC;7K'.6z_Z |JqБlM1-&01MFSOzN ݤ4l^}Z[/ c(VgKp>gpF=/3 }dZ:eCTN;o 9Iօ& "-)`"jϙKGa6tZz_ 5&nyc\>]{s-K[Md%VռiL$׿buh/ra}&F•/Էv-״c/_}Eh!jn5#φK\+Y<ztF xꕴN}^ggDuŊWQS&96VՑǏԯ`t mH|dDg &D ܝV #ZC:X}d~sms}yPMi9GOe|VewɏPBܲT~]ǧŒlg< sp`?tqؾxc>$jAE%߬y 2ix0\{7DDKUm.Ǐ5aAW.S{Ayѻ៛os» fogk6R-DglHugkz 11l ^.(ЦB 6 w3֞4tO:?SK#'dsrwwdf-Y1)"|gK@PfF>ppw.[i|O]HWEa!%yYnM]1ebiS:Hhn" ` ic&q _9rriL7Raͪ/N14ݣF0pڑakPeJK(7e蘭ane`|? N+`|םg7 ~VBCV8Z h@w,eV` -?A4_ ׾Uꀇ=/[p5p`}(F4) ]C-~ɇRx xMZe}P><6/d֕`6|VX9b:ڝk$sh1ԥJ {{kflRԖ+t$D +GRLS?Kn4Y&5z vQXT~n#v+lty0!_Aa%3S#6M[^d[d: Һ[Kx "i!%Is J쬫$p'4^$qjehOn@}K@!rXci7>ŗuQB#aCuٛ]wۏB*yb/XS6wJšDkε;e-N9wﹲ-';CO4 x?>&> yձOOW}?Ї9Y!cG&ЇnB.]!yXY ywz;cKLQ.#YQ쵌aˬS#[g iA%kx Nevr{w֢;t+r#D9{x`y8V(8J&Q!ABLfmگ$Ge`GoT0,K0%htIs:#:78@ޣ-/YL@ e(2`y)rt{aHs~KAʜX.'JQpFnGC  kWq X 9'%bl\{.|ޠQ?j f@8-{y$K]\ F{X%g8U2b; \w.F5'# ֚8MvG8W ;l6B@wG6ʅ]TEp~G;v{hVR\ggRB&KJ8n8D(TQ\[YڼBtpN#N,vb$&{ʃ^ig꧄h6vL5`(Qm<7#7{tS':k:&-RcwΆ\6OgX;}颼n_d+)dBeun|NIL>;=:VpG9bTĽf,vE0=IҾU* 5Rѽ߼Uރ!^!pM0Oen9يbB.5|1߻iaSjP閹PƌJo;#n%Hؑ%aP 6"~H?璨߾24P2:'uQcvOvm߇hY AP bsz 5ق߰X0~x}sj( AyIm(+FU7o ]IA^cu-z}Pةi[͸䞗oV~pWU*2I{B*IsT`{T*`Wcwh< Uɫ#*UقBOj&;+aSs*XͮϖA'&5ȁ|\/_,p܎H .dш^Z@|މ>Yuqh9c Y(}tvAy*;ƥږЈ2 (G$(n`i+z EH<-L&6IBi@Yi&_-!P6P oFĨ+D>Fo[ (vn>d5Ϻ᪶ɲ."_Jpz6'u=fv|ωH-$$dzztD8HRIH+Bk@B3Wtxo|'/~:L*?'ZXC}p$CLChM-ӎq\n[pYK4Je*x.-vvL>ֿI=](]FN=(+%<:k3TiTr}gL$e29BO _ ד-d 0a0L/2NZ+mfzAƏAi/Dq5wo (D%c ?ƀ- NG#0"8ǧQ (]>dtUC؅{"\>xCcֈXOBnX,mGrm hڨb>7Zu{E.S:F{/[J'FqMԵ:kI;c$m.z/L1 `K&n$$DHlZ~϶ ėמ{/ Lp J~q&<ߨEؽ6Bڟݽ߁%XNWɠatS`uO9=/M팗ty̮b_ 4~"K9+uCw*rk~d>cx ie nM-H?E쨖?C`pX}\D2E*y`[|06*;#=df?7H  PΎlr3ٕY1>AԏYP7hgĪ$! G h0-\/i5Hg.xE UG3Jb|0-PF-.Sz'ir|@s5Ol#cTX%s?Ҵ㤃Tn7K(F~;'Q1q $~鏃d38I -q$SlYi"u&r7Re?s= n[^J<\ zMH5dx MR*[;JЎgucʈBʕ?XkzC׸Kh6!BFnI0gid&)>0VߌT/( <9jgrOj&0 `]|Qh wVk]D &+eiKt .Nҁ>Lr[sB)Ce`(E ˉcS:#biZZie-#\wMdrW4̿=g_#`wX۾ا^u?- K0o3*suta[ȯn1E/+i2ls8z.S-ml*8o)نL^TBRa3d~ʛEBN8;Yσߌ0,3)kwƁ}~h0yg[>ڝ8e0Z( g͇:\'(F Ș"DM1H=eD& QQ>+ ![xLOyb 乧&~H_ik.}qcnY-r(CL' M"2ޓz*X7µ`Pp iW۾w cߡ0 &;YKnta-XvcLS~3{5ns+LP.&BtSWʿu]لXNu\^xYvoPkL@ˠ>wA:iuBMgU@gPFF#VNoS%I̗$Ln5'7T &/#-bICvp5RjL\::7*3egG>l V^W+ij=xҠ+\ qS: |$bbN!|F!8cxukDkRlX@8pH,s`6~X,i?%Ә Y $Ъ픏ͩ3.Ir$&iPE@p1!# )ـFIn4/KK+ !ZŻ^L"8Bȶ|=]qn6u\a.Zr/$@ 1*n9"Wu6_:݅q&guXYx:3|[enQyWs=lk1F d;NAYrWd&uNF1cɻ֏a>B1emI?y Y+I+n=k`밠u(f . eD鯽5W^"R) !^dw٭y8KFX]PVݵ#3F-p*>o? Kw xtR𥰿 &>]QS2Q&0ڱڐpv Y‡oҙ%vO|>o\_7c%>{&>x:*Y6J"ܱѫU=@-Q/ ,?%E((Dd(eՆqltvJ=_BP,+p!MALҰϚCZ4-QPδ(|,TGHSܵUYL'0 \KÖX8>T/A p'IA{&3e4Oc~O2 rcbz*TPq#Au}j]j1P؟l0H-J 'eI tE?!(/`^ #/Ž} pQHH<ƭQlm U:B{⌃x`C'@[+v(پ6gv:G`m ΕKKo\PPݞh cȷײ]f! PDzul͌3[+ؓ\ ԭva8x]|\zF[JXz"\H*3j6 =(Ȣ/Cڥ ("đCӁБS#u M2et:a/q 4QiǔҰ 1]}%3d%:g2.5wEX6ʓ oǂ\o6,GjA#Վ+7P׊Pkz&yOgr;pF6z)cY}[~sj`gϝZT Bc%q֧XNU\L]cW^i![E62GD#o)QȬg?Múk[K <1t`Vx 3,TP&,%-,tppk/B'~EU@ζF$K):og9ҬiS*;5ԮD}Lσo)1џ۲!08-sf.`ޓK18h|V`rUi~ ,dO[vb?jG_Y( *$:iUj( CC7m0^:!qfKY>'/uR?" ?#)`7Ɠ[ ݧCJ(kUO=0fP@3xrhg19qS=Lk}I 7rqߑۚ,Rs9 l(> D '9A?u5n.DgqPaHvq%5q03\Dd'TFg4Ym,yJIׄZ7`yۋ6^j[O*aa8N"+H-gZ=_%~ڟj&^,3V7 F_hxg?]G#nWVĜˬNtDOfF΁/,9O^u8d7Zu+7(p=ֵ"sFӯ\8`;)Wtad4R'"U[ao g4b {& c»*(RLq-ڧ*A_ VZ G![<rݯ!WC03wI-VqHFcY JN%РPA}ڌY@li1l~c1tNCP l@kF*蜡64Wfn x -{ >{cCB]@'}*LP1 0w3΃ t1n|Jj Ć](RޅAWBަEYt&DoXD#z?Ǩ*8ڂKG 03Lyj mX]117=vb4À^jr{Rn}&o R:ţ:k+v0&~ܠ ΟP춅IH]1쐳O6 D7?jzƦ%#!챨Qd{oczB}%t4<)@cX4ƛ;7$[N'+{۰#_W~-b>l#jJ-#F2a'O#ݠX|xmhe8iBPL'S%0Ӂ_ٓ׸_C~Ζ|76cTa+d {3C)L1:43o_Z ^FzL,ߨ &p bNNϏ⯿mTYns{$ޏFi }9αQ߿ǫh߅9ݼP<&'bxyĂټj 0O Z꣯R3nUQ;kB?KͨE|Z$jՃr x % 7Jsf~K#X3B I6 uFlџHK-ݨk諭 ZS+RQ|[dWjx(WOSSPau><Ehl%Ӗ wwo|"bBa-ǒD9@ِbp٬`o(j,˭ݼ9,IY0cㆪ+}4r,2 0_I M ƃ=$WiGWNprqC~xh%,HU! (}'8T^|`QPƴ)*cȑXZ^:ͥh\! s kkU-Ay5#]B\3'buf1A˥B/{7hz|8׺_]!o0(+!Q4:Ac}ƔNC'c5λ)zCR(f#lb=ϊW|ńqeV=BqO%hP;'셞D E/4·5IT^1UX\h%5(Gi攲g_ RC;P{L-5./De}:f`$c.k1:GV\N'?ᓮyAGI1haR ~jF,¥T@])G>hxi¢ G?DϯIRLaB#H?KrDG6O Bq-T}?}5aC%3)"ԖhB (~fOz^r E ~DQƶ\>DQVGا';@OYO^b>gZV_Ҋ|lbo+j⫓Uz@J+nHưɮ%L%b6Λs0 9+Qs@cek+D7NM@@7Ifw9GpNg͘kT ag E9e}¬~Eʞ4 =ϙ!עi"2e[\ u 3B2 5挷ΜE`g?y%Yͱ^vІ ' QA"&dܹ.-AWu|G2,Zg䵃 E)"J.\1xHUI̛*mĠ1$ėq((--IQ#RfrwKe;F sIʹ ]fy`K٬!O <#ʅ߮meo=SIQKLi`sk(R&@sKhpvsD{ uW$`dԣXs+f.ӝ6AaQ!/Z9~+K/TƋ~ju>e#H>M%RMjm.=%#p02jO5^l3I0 3cb :2}c]pmZ❬Ȕa90LmXwIƑ.2:l}/MVu=ew96'/u?k:ZxHeDaLkKӧRim8[9{_h_g׮< sŝHJ(˸H9WMZ8[&JHh_$P-}4B첛0Mqc>˛ܒbSoύZ#RoM`k4'?qC)( }zV?tfLyOx7_}¡B!|e`-F3ZBh{v*&}oj ZXa<Fx;)(n pYd{ U{K/Ɍ$z!K=(Vj+e6 i\=[2|ģH!ޝHY;"Ĺ&dž4\y z1z! %!P˥.BݕS5DSŋ6ug2rxU @#"N[cVyx+.lBiELnv!_7R$dO@9iCJAHĠGՑV6QqN)ﬡj.Hg$yaS ;Qf;pL˲η[z#xeٷ~ADN$G^QEXBO>ߢs?.J7<Ѯ|fm'@omU{JbMh{GnM r4<[a+ܭd ca!/?[PyGќ=ˏ]h:"Mz.l#qdΰF߾ڛ4wTLoc5bk5gn82MoHQ&-b7&;h p;[.ekTWKGDVj[[emPa˩o@{"jvz6y:b BM[4Qc.BM?Gl<;{%N t׵_1TL_z{2y#vK}ڦ]l5C}jr#KTa'I 0Um݊P[Zu7(Ԙ!#*W bI;HF&In<(V7j_}*\F(O{o|+pw 5/iܜsNn/h Rx!B jԬ1xmoCUW\4/qE .$1"OQ*$йNCL-`_8}F'ح9㟡u ŷ'u6Dۗxu,BBW--Pږ'a}$"/^RFx^>o:9m,`bP 0ygf~Ƶ{ѦnרB>J͘Tr-c{|3 a (AG&yDfn5:-KX⊾$@10 p 2R[D#rwV9Rۥ_Ӥ!P̍gSTnqL`_20 ޿TY@p0C)Dj6Z}?i"5vHRÀe;ef|lr9ƤsW"Y ;B(0YetņAVE?3VؒJxftCWnP} w=R,sY՛NSâY=R͹}l+N9DIJ _UՁHs-!tU[Ў`91&q(kx#\W .-NO.u9v=?FE$؝aN*6WmY[;7|Fj>Z|f!E mS$yy>*슺gŕ*&B ߑ2% WjhSDVwr9S1pUR:p۟~/7 aފiY:lŌ^b[<*%'dC](Xv%Txj|*~cQUl?bJX',7Μ8M2Ӽ-|PJ7GvN~h/&D贫 Hst̹ۮ?Ju h7o}a=)ONvXGOC/fxkygG곂9ؗ?č%ɇѹNVDt W#ei+rz*_33MjvCx-\CI^±ΤK4\YE[I]Kdk<⥹f;ZaJeNDY_/Q- ӌo&!<屭d j/x54w4R)` _&{8XB8tnFeΏtǽL켤/MfM& >Xb;LzvWUJY)LKލWv ('j7%tvWs ;'LZmAjZm<γxu2F,+̍tu`N Lel^5bT[>DO?XMEII$V+:^ӀFszm,!|"F&.8w I8J.2R<5V2^v`V>(vp0Tp[K ~tU&'T` }^ȹJEROQDzB?x&fU|YB&~di; jy/.N}Jڠpbm({oYߎv"VsAކw O Tb`>p}V?PcJ1kۿCJ+6pngL3.ۚlO]6GlJau; юort>PO2wZ g IQrh8rS9ۜ Iپsr>kO.?ts^TRvp79(duʠi}F^›, =')cQNu!ͽn:dnrx<k\\W)aE$zzЙ+aɔMʤ* Cu +ȦtŶ3u3!g/^M$흵^O `AḒ`@)AE,G5@40Dc'+l}I"? ,ժ֡E]v@E,Yѻ@#/22XxfՙH{0t*r,!TpDm%O1;{ӡB /T._ ]Ԯo/dҪђu l3yںdw,{7UdJ ߯B7z*CWV,HsF6[6|s=䱖^.pM5Ş0U M |J16 $n@կΧ/O=H|,KA!k8+ɿYIVU3Zb +EeAir@~ *3Z*':d `AFkwcGߏrMH)[L{z 1#>W[4zcSP?| 2!BhwqEZE/m3t^ŝqIgϛ$ VOsw-}2w;ZyaH򰌮t(o~Zt#pv2~;Q˹t.)srfm;tR, dE {w0@uhK%*SMV T2tqHOIi*v6bE`S(nE{LGi*+ÖX`Z&D\ di&uN!j7 WueS=v*,O&ETٛ憍'<*lp u&*9{(`Hy} Ϙwl{*9v}޸87}tax&.ZsV[ ⩦j<³RI=B]|cP ߷qAk1{'q]+:m:;EB,(7e2{ﳫw'۔+MµA)?jH=el$]2",18 ˉOfsLyhf?˰dT4t>ͯ J;{o.fزI5_wA=Z6RwsEc 訫Xu h2jZGWWT o**PZMܱEô5|c߻{#s뇀6ҍ £fr^t8C˹FvvQVpBv 1 ,dsêCsٲG| o>rWFEYP!8S?J,`a !MI{.J2xC&6=W9ڔ,P1|?&Ab~(<Hz>0/cx\xz*wjO5g1zAmZ7Y,zv\_4H^uhaɵZ6dM{^"5|St4z++IIM@.zVOA濥-j.^n *t՗EWPLtvvr  ހx3WXwG yJ9t B]V2Жړ_Ѹ8quLx]_AJcz5By^ARj3B#\jiϦ$G*6 :2v_DW5_NLgs j݁'a3Qú7qC\PAn=FKX& Ըa,qeW^Vr3¡ TlRg+S>M˝dVg[ZS [n!G%S=nid}v&hu?BX_` cz>"l<Ɔ5v_ ޖ= 'F<*}\Kd]̓]ի|Ͼ9sмֱ1&Pj%IFiGº;Z羛K3qC-=WtiFQ 7to־;I79&J!gw!mSVt=ߥL9/&+}cGƎ?rF >;LYWV@6?Lu!֜]#p+J4Ow 0'5v[8U8_> Mm܄#gPdq4b"L2Dj*u8TnVoźP+&a hj/XhLt#e/O* B"ow/5U`؋϶<N1?7[;_۝hS:o+Iz̃38í_S JfXQb~W K\G8:ip(zNFFK503YLSluż0cF$ZT†ix 砈ɺV : _pấ?™(G $q^THs롗,R) >2.vB=~קL&4w;bvK7wb̛Gy,w"ľa]̌oPp:Y=28 afMaNMzTUR 1S IBIZ]RPaC.H߮ GmzP ZۺWpe"K_ r Azoʈa]ǽf]ҋv^FMR۶sG##+nM0c `9˓P4\|QJ01*A {,88FY$aD"zB+CxT[ޡE oħ|Zelj< @̬[{'>ZP0RBƖBSV-kh8 V'݇"@?*?vף8^[~q17v',ҟ-qS"DL@3lW(n\Q[IZ_/TAF7ŁHmU{%v9V(eB y} V?'!Γrp2델*[*%B)+^D~fq!Jq>9zJoAD'MY?qX(~ ofNg|wnQA#1u}5|0JWhET6vK".c=`mW+>2@m@;Ӳ;hTT~ԈF 6QS8/e'.BP-^IKztdTt !>"rG(PmYzpsJ 3MSԐJʻ[ST[4Yb0-Ĝbrȳl/}T'>g2ށOLz2UaNSu㚵Q |:őMeh-5J+>Ѝh 7( ƿ.4I!1._皊"UyN}ۃuZдy7kՑ,k)i$ؽdK f,(PҹJB0!o3qvs ?bTaxiPofT>Jc~o_+L!:rqsN8P Z( AoL9=ES˅: pMYxtZ!I* Vx z pgIBb'i|2<\w>?1hNV&jKZ5хmx,m}yjrNj}b(K:o^tD6šJBn,0pRv?)0?mmw"b-CޑpB8/>c0ae<9[+v`<^69tH;rwn>+.$K$b 0h. ʦ! nD KP6:;vOH3 ) Yl ~2lUu<<w?v k^/vJ(t裡M/ϰn}T>2T;UK~@P VۆKlǁ^L(%Hf][IBЂ PP5u$Se4yc>Q{O4y)Ad*;TZIwP(Jֲ{Qơ<0{ŭUz‡ R xs4qӺ!!r1 ԺTTR+zcQd1NVPEse0]rVL-i}~L0Q @c6uٝ w >)^j)8DheflHPN' 㫪cu_lkCcPᑞ |(X7q_."N@07 AT# ERrA|)ȋp4;D/z[|c+kx㠻 G@ r§.I4[0P#xȃtF=@W8uQ5x@<7M]mKi'Q ~^ S=P> ?ف$,mD?IsBx ` N2(Dv >Ob*cc{a`&6O5q)b+&Ω*N+*ARvd3"/9pj/|Wy[Cy73  Kw lU=*|qa1r$ydY'DŽDrSutuRRjĮwW}kDPL߄x{Y6Ώgֆ왐6LW*ROp": |P5V0?t{3 $lLIVlHg0{YK#4y!oeR21VuF/U <|WTh~Cc..2^[`Ѓ_[]Xm2/;_NJ?Df{?U'{{,ܰ"p)8%xlU؅M"I-sV&4$$n.,TiSSzYnJ jN6 <چ<6]J.tiveۯ9֯nT]<@fVh[|CQ>N:Ieo7R5E_ `/H6d7IfCI8p< Qc6ڄ{[jE ,4a7smRm 7noxvkI"ݓmh9g~tM yMbҽsiSƭ!{E4)2+N 1Cur@i"AXd;,$y|HJԔ+ʺpzPL#:McIZz84}ۘbBYB,$&hܝv8c]'upA]j7I8?f~VpL/FDeNeX(A.VG9pS/:lɋLGc3P=˶=BBB,lHY=~Lȕ ^$qhu\(.#KmjɬC7tВS UC>B/PeMoPNAi}nbX/lpƈrE7S Y4|@*Aήn5+ mB}|S1%U/sguRfLNr1^]V;`sܺ7thzsYc!GZOwj=FX(w綣 \ư:뾋sco56:sh."m06Uە=6\(e"ήT7%h6y-7sVuߑl6+_@:SECkrSAt8M:;l+}r|\hlj]GN2BG=0Ԝ˭5)\h* jnPch%oZ=b9ygE["^l| O"3AԕϿNJ |-<JSF~Gz W6a0 gnR r+l&Y;@u0Л&}0j j5:usH΍\QPMUl@\(J/N_pJ3 <񷐶G]g+_~okmJXcTzlh0:J[.ᘲx&7yIP8!tȢu浵?В 7sDHSI 4pBk+ޑq_$EqP X^j[<Qq MG$K53[ZJ@m*EʔeoψvAxYZU'Y-/e20WYπޛ&YԖ멥/:l;ͭPRE[ ek"i2E#Yq2-uV9A?(@40G)][3""_rK|(/08ܴOqѫipL YO4ݢp+FWn`al^L1e') |4Is4VЧ!lc6:@+0i~TiVXsMg"]N`7*k,?;R` &xbkHg7׸ ͢38Z Ib[FO s߬ :߷oV$ChyADa Leۺ=1]L=t&ȕּ$@` xD7f1e*ލ276Hbܚ8wLf~,]JHOPC}u.TjOsJvg8s | 僭U_~hd&TcckOWMI%r"+eZM1d$:(ܝ{_ ~wC?V M8Gk׬5+s*dl\XqV̚ev>Fрdh(T2rm༆؜=cKiy铭>pizkeح^el>a[quVFnt(]z.bv$vT.v=0Wr$c}|f:1v/9;~:N,&-h@Dv[I>ssgWoaN`*fAU4ޜbNO!jF[- s|ux/h.?7 ]+/+.AŇ-vhbw<=M'4{RPȷqWe\Rf9oaa5z3FA=#B4ٵ EAɤ-R}1PATTWwko…~+hBiie,FZUΡ3֯,gWDѭ8GBoU5H7;Uew;2g1 anѿ ϕN8<_"fn$خtʐ"; 4Q$q5&#,>ohF3M"`Э?A_>r H(ɗ (iLg"e3xx$s۔/;{,n g=Q>saƨc"q Pk_fa8Xt}OĦCѯdlՄm Dg w"k5]ۉQv_c?Nh^ QH 7}Ȭ\vݐ>nEzCgó\ZejWl)ur9S9aXm7CKwm } T>Yi~/1Ը̔瀰[ Ŀ>Jŧe^#IA lLEth,r4.ǜ?*VpXt |2׃ \W"q0KK4WˆL$?+UJfJyW.⑺ ~g=QAl_p:X iD1l_鴗RzTV`:C6yc D_#3lEQgEve2=! Y0uy4Yި&|8%e+d%(z "S8z>Ņrt%1Pt\#NOjVfBIL4`^4AP,-!ycHJ(CUK+@j>E2b{jb=P+ I_:`]zo4-]|qtQ@Z霌~v;pd&P5ߊvY$'T\{Z&sio~ IG,t&zc&mT{0Ad+S1;¯Eϫ YCk)t^qTD)^BYٳ!׀pBAGlg¢E\|kGI()+Tg>>4O5{Ʃi+0:$NLCC6{ ?)nײ5AM4e&)3#FlUtRWpcV$ 8hd9vAū&1F.kWxv蒼蒬7HGN_LRfJS7Ak1EZ@UbK 5`fh oRM.&)zYɷ lVge9d?fl74f1?! R'B4\Mx Di6Ż=t]QXf*q5nF۹RyGY_Z%)(i)wYW?LX 3zxOj1RTs8d[ !<,iG=ذ ,[=Pqk8T$͜bEAJ5)7ob?JZx$c+9̣[ַO ܈V"8;(@Rٰ5J'wQ OzEJIsFΎ?,88WTx=Q{괝ipq0~n˲82ޘL-w4^,Sok >"b(A*%L'| bS޲NB,O鮢-f"b  V|Zc̋$Z =),yڊ%1@a]1!S`4= P'`j o]-/*19D0/)y޽3YSuS_@B"fv# 5jzupM-3->Q$j#ycj!GoHA4_Q^[.>).꯸L0h$mLAs`fu#6t4sM(QI1)mq_hЫdkւU ÔĠ>bWYGu煞^Ŝ /9S L"qrl1waY̶nsX'eF'ܩ$dSbbH9rmߛ#V&pm될@3u3Ju1$@6-@XO@!dp>eþO$'U_PIrsD9\ Mk+[XE6VȪLi39kAE,G $Vtq+ Rje{}=* Ftvč0Q Tk"[x>j7X]ZxBE'/&BϷ` nRoeLŒ׏q%#6W ? %\'^j_~iG'F^X:M}q g~P)TG< XwC,xB|mhqz->k7ל*IZ&2eBP1O({PSvr8]3[ex'S0-q87n`3 njՔ2. Qb^A%Q`܊GW:2Wj_lv5!>Dg w}뿭/n43Lt-/=,a[glqb·1{b~A3VȀ/ĭZl*xao<݊M&ISyGe$#K~QU[x&A^*Vϵ#!<31PθWWӰ+0&hF_I&] BI9NEc4[aA#4_<6w_yks[3K#T$\nu+}f, >JWuCݠ;Yս2w#VG?*#(UlveGI?]JA[uxrWvH6AXMK浩e/QJ=|?Uʭ2FgO4C|BFeq8)w0:Yۃ?oO#dVPOk˧Ƨfh 1[f£DryljSFѪQ_['@mu]s9*,A\eC,Jt--j;ePʵHI Y UR+iA]xl$?C/"Kj_/mcp7F=sT<qAAE,GPcr LA MqiH{2sr ʳBh{ìgr0`G~W,/XgfJWm`tF AtcZg~s6vo;Iq4~ǜ 3 B7^Sig:wa=]Bl梌=rqWbDg lY1`s6.͗5N9H,9C1ethU) >z}8`Y3EAg4_6[OzA}y\z_S)5͹Mxٯ=ʸ@J/9ro֘ZmG-cF!_@}%>`ha aUK F<.(]XUӋx3ް &PDY'0ME+`hM0ꢒ? `)Y Z/8֧gnςځWAE,G8Ov6pZ--; 1&6MARNGįFWW<G[tFZb(ICWoi PRˁ-;nǘoMf ʆv< = 8Dg14'nwvA4'wf84" ]%\m~Lͳ X^ODAuْ,Ix_%&ܳ^o!+S@ fƒW½ 7ޏ\Pi(Aa8W2AE,G-e!0O 8CtF"#lqS2896F~bruAI)DgA4‰Rv9.qEI#x)sq_Wb➴lrn')9oO,5)u!-mV w:uʩ;/,vS|> cߌ, zx V1!aH2%됬fkUq-"pk\ːM~_lz]wT#3SG[~[Av߁fJr;N?K}X)yӄRq^İ)ˁ.ܿ,1r;w/2?vp^ΆZXPJ l{4Q~Te]<1˳9c^G(鼽$9: Jtup6fغΘBGJc@XHYF*&nTbSwҢӖr`Z]^+ύY&644.Z黑|9@ }UOEݱ_eJ`Zw ij468C9G DgE6c(W{LTvQ攷bx雩}3Im<pgo cqSRݼ< wħ=h\XK%m#(Ohmya h|{N|qpw\)x M3̩F{"Yv7iǰ1έU xM0z%T1yp^{ha?h٬ 2A0>L)k(%WLi/6}lv0%-{R`6#yYf4Tt&%؟aђp|"⬌]m6l,ˠ&<<>2s SR 'Ž3'a.|X~iJ+N9ޫ񼠖KvFEDһBKǸf5U @fWM:pWIRk'QO)=սH7tgJO6 սdwwʗoӛV8sg1ļeDlSa5F(N:.AMRZ83 !?8*cr0[뫁Iʦ-ͼZR5v7=d>6i!Кs͂Bۘ=⑃кf9HK@+X?g`P4x 'y Deňn񯧔Qu't90~Pŀph2D~%;Gf?$XQS4Y )\:ǡ"Ӗl mbrEpm`aPK~?^T~{*ij&0הн.UՀn` :|RkFa}<[ ﭐ6/ן ЏZFUrg^meHfm26!5ʄMןJ7mp<cz.u(oFU4( :Nyɾhx5G" UѠ@ǒ']ək[S4SN ]Ԛ :M\XX)I]"ꗓ+4%*{pB" Cw',B:6?T3c3?uEihQ~c8-|\ϡd[ w}zhVD! B PǍ8'~Fz GYtQh^Z0J^I)Ej{W-6Pհg;ЗB۹eCJu=I_w"'gߪ?t] Md,O.G=ɉzD-t]󮚿<WKT9Y9^2,BXӲ]B lX 7NAԮ&6Ȓ ZPwPk#?Y6I[jw)W輢'd.YHCiLLI  yјKOĶ 46'oK6?4ODg?EeuId /1"^q(ҘKꋬmC HLq^6/o":8(??gĨ]l,]Vh -B_O1xr;63O9Rԛ(_- |g:¥jamXZ|Zą3}DυcXz3Z**{PyAM" le 8<6)yz.2Kr)Alx?smvЉFM O;KᦹgxHƯNUPVэڐ& B&dszUF{u[5]>"id,KozDYR yR2@տӕХE݊5!((6cJTۡB)\ v]yTe\~j#`bR>.|*`k:!u+T*qhcMr{{>=ɦj$G%2`Xa٫T{ B@%fGv'g[>ɡ#$Pe.3P@! $AS+אYJueq0'Cr`!k?tSـliŮz)M'cD+.<{]eD {!=) ;@ҜRb NQV}_"PXASYbY|{(/-j| IhE&^U7>lTQ1b]غysst #6:4ĪQ|{Ոi&̱ dq1 -zUXӡꮝy+OFÞLsŬY]Lݦ`+'g;Q*~$7C̰CBph$k.x*'{R,[ٮ43s\s²4( })yصZSy'zf]|;fysǽRnlOJMhH3Aڳ#_ ;?%>xR_G ;8eSd̜*M@ (uFak*KN~OH65OXI"HkhzwqU.>vS0҈$"ɲ !X&<|01YITPo0Z# ܩJ&#А-ke_iYzc& |%30:_s9;:Jeq8v)B i>CB_ɾ.j7BAyġB(=_* Nl rdir1=K K}fu>kT-c 6 lQ{-k:ϦGh4W iTu,D#ljWի-l4 >n;*sJx.sn؇"ehaIJfu%c|1e4 qlqh9| -"0ˮ2/7>ӣ{" 7RDidl7%TZތ_Ufl8bGgÖȐAػV3"oM\h-_pJdUnX R)._AM]D1q_op1vKPRUYI*Hdn.TYll4zǎs yH E`"f%Νn$BOJRk`Һ ޽xhaJC&ys;#SኰHİ"]Y3 i5? mk|gr)۱ax;Dz5|;9gh:z*ZgxaU$C:*NPk$fa6P^1bZjP E[>2d)m }#Kuau>"[me4ɤ q#V?I7}p1Ǜ& IUgza xXG?/$+MJ4΍b2ƪ, ]/dH<<*j*b `(q: i>)yRC qMz0 \t-M_N/7h4>Wp(1J@@2ۂ[_iGKG(]=i(3,ӯ.kȻ{) *&\Au_9Je,FS/#3b HڏZې:J}Q9dw&ZM勆3;K@B"q=#)f'r ÂyEg:cN 'HZXw*c]{(xl?{/`R3 ECrApr =?{ &ڎuA[,I*gٌ8MR'^>tf'g)NeD0Z'9;@PN*6 ӵh;> 7|gAqEof^ʭ>244XDK,8a׷2bE¿,J.3urtauI 2/A[]Ek4ՙJ=E+#? <=J Q ߍwt_Mφ9EJg9zNZ4~=Zx)"c2S!&Y?w{|;'_D 3"&ٖ>˟nDg=Êbm{Un&d׽$PRɾfǘ zvĺSfub7Zm3|cP nc [ m?RI(F!,1mJTO߼"bȩn;Քl &V֛Յ?t(AJ>>M (xT2K`ZCN<ohCxT1 UmFoU-șD+_?XJ?gYTkjp\1?Z9ʹnH{ʸXU-=WzF6J7_B(;T^{J1WϚk͈iyc %A4_d3=C5օcōvZ7Vgy!2H麎,~H59j<ҿ*$ؠAjS!>u uspnM뢶㹸agʈ٪7]b/XNW\06w2V|$( 'f[FͬxBuJ0E?Pپ q^ZOIHu י&*ߪRtH ͍&/} &/0z%ϥחO] "d+V^;N?B Θyr?s#Ҳv2}h:GV[riDoR:M&h{&))߸"g47*;0ZP8i[u>%s8*bf-y_R:-nI4nAGT3JeǢ נ] |]\宋>*r4 e\jmhSMu=;F7!vQ ϫiRT8dU^Hj'S5A .NiA}́/ӽ[EB*@u)*9X;~JWU;]07LK0)tP)Joo(Ծ\;a6OmlS(&~~AD<=Vѳ**‘ALJdMQq҂_؈D'^z-x?: {3_V,U0y s!l4]iM9b$8:6ɻ@%=F9kiy~RqEs  WEPtpI\P+-o;0(vi8j[p4O2bnnh-fB AMK,.3]LCڒ>k9 WiגWw&5SA )'?|'IyhYxѹLIj1pb,I\EYVѱ7st4ODW\G<5*a1Ǯc^&.BAGn$fë}-e{*y1IƝnx5(+RR `ӅǴb3T_/#ڙHdDIfr m\\j[I\N1߉i`pi(Gv `v2Hb^SY/L@ (dB@-AͯH&"ѠjFM]4[AB-O zO+l` "ĜZt#,A[@OS^$4f[?xFa빆Rtf@om?j}jݛ* 4  <ߔ1td V>>*VW_oQE6mm*ab%A -. 'N;*x&aoνJ_e-W.v;> G&)(|\+%m6z`.j_@6]wzezJ s:d=HEm_djH {GOؽq 1} fv AF1gi򣱁L}  !O <րWAE,G6=LEi|WV67 F&ᱠ~Ҏl XC <†Δ_ؿ&2ZKzs3X{ deeK\@9`lz7cǞ=FAbݏH,ģ?8bZp Eۄ žccrGRcmdqP()H/|M~Y>:2,-]k# Ou{O*m4j-ǶY|^z[&8ThVޣi}Uތ.~Fe^ƛPQtE+ bGq2qtF=bv=\Z_l^\3 JӌXc2,U0IjВ˗HGQZYOIplpjPr=°cB5xlC\`[KOw/K$mfpBI8gU}+auZL*Խ}o e[U9k]n =6JN``](e֛(yF@>/RbW7Ҟ=\Α`JِBGȉ/̌ Po,/\ /vx]EzkqFB@?N'r߅tU+SLHfd4f|M({PH.1 ϩq\;)f+lfNM:ѹ6q&hEu +^bi"C\U1V:Y#lI:Kad;E\Kl0xi1(WA4_eUA|tۅ[/sm/=LAB+-S,ѱx8%:$hz\Pj$DGrg%\M8=hGSBQ"SC7Z6X²NO_C,Ń5H;TF7a!*%OE5{T_(WI%> EԴZ]!8z:YYFiZg myIvxOzvnp%bva|LU8 }Vjϙ0̞8f95Շ5qAE,G6<).'lݾ)+Fګ9RC}ږZ :K UB~x!ӻ=A`X!*hW%(^%ttSӷ}kΤMMD\?zMDfm/$CJb?,36y5 N [^[?lwY\;Sir݂r 4q ui+5#jqtF>]0%}1ֺ S-CJSQru8WRO4CU#n Y+!ĞϣjI]^:IfQ*+&-zcG˧C2z#ѩqC6|rT/nۻ+-f X29,7Jr?I1;}aN<5u{+d&Y Ei%Y4'BeNɭ,nRcT0k]Dg=QaNXᭈr/~ Dr5)Nt %4:ZxwVDfp|!Pd*jCY6O6G~Ľ0!$ \@:dKDJ>ƓQ=$mL F@NF6{`$z!йh3^. >-^VtfϽ|j q[WNc橧Atll{nodqk*QEs36"R@gY':2W 3A=E,G' ) kcx;ğYVpq9J.4Z7]Ɋd> 8|ϰ؟%fOid[;c_s^)s) $ckUKK~O0-/`Y,=Z!-|]E=V폒zATq q=Qyid]/K ocѱZ07\\tFK޺8uez˲ #{y݆ 5̿\vxɱ|7<~Y;˩46 d_/}Hȃ1!ej "jsH6 :==(F]#e}aHz6Jl5)99b TwwQ 4}rv 1qWgg_ M{j 7^DgOby*0~u$1Y66?&>-*X~'~s}!0SL)nbTօ_oDV!#Kmb;tL00vIFKT6+}& jzvvE\V?z(1@ AC4_`K,mXZŸTq9j\d `4/e |i}6እ#ƿ@^D/"n[q9FmCʞo]6JX8W-fd9>AaE,G'AHn Dgz>.ԀGtF͜C.8snL@_BP3DgO?1A4'ro~j>31@^hb&4D.Z2m"ρ_bu l+ XNXj"S$APDvlV}' x'1(qamwVp''$zAE,G'%I/*d'bZ$p8}XfP;}"Z(+IL0 a?es9@jA2tF$ o4gDgwJdy>VPHiz߈FXLa_9'vl y% I{BWL'A.G̖ar̠@ u&c`"t 5 A47=}9~i $ԣ'~vrrUi -i坧; F'hdxapl(OXyAE,WQh ʽ:w_k4:yXsVi?YNg(OJ/*\R: ί.I0H- &._tׂ 1 Dg3U&jc~\A 4'z9,[zH V.bHJRD4w{#\HcGTym 㼙 ق +cMzA,=)ϧ/*`+ӥDLΉhoVy?zHϼ^vwV{@ ̔"a{)->X{eB9;AM>L87 G% ⹀@ScZn_44>q/=4CsP8$ p M5?`T7\[dd;-r&FӨDHl!9$(JRͣAq+i> i4gXqV"0ZlW8ƪ)J͓@K",bس5qcȁ~-]Ł2]e̪׌.mV;yOVġ?zybyL(  juw-[t1 tTAE(_n!7xh/ԲC>޲zf:sn5zo]v?Ra靽* }!:dy+Nt(&~zy7l=Ӑ 4\Og.[s_n_B%!q顲L|K}xКY!{Srh*]jPWKTCAԮ'䙿+E.R 3b]fFu`v(Bug;- cgveh]D!@+<qQK\3Dn^7^3EU&FݛmrF՗׮gvAE,G'w9Kن5א*>T` +M#)L ?rcB?uDgr/\4;vk}3W{$!E;. YXĭw7StF  xf 3NX3)Y,9 "Ҥv2(g"h#5Dg ׌n JI1A4_it _mD6ED?k+-hV Z4)n0'XSĂٗA:g罦-bZ)FL)7Tdű]%G.d4]oq!LjJ:eԞ b_c#1 psĩ͚ QXHxg3FaqR]# M`D.)J#'L6fitH!2A[E,G ݆TP"jA-ztF`K|Dg 4r{b kMx1]Q,͙\""pTAa4_UàJ࠶xiwPlwn[^ߤl@JZzi6FIŰaprNHWp0{0{Ox;pU,Ei8+'_J!hUq $bj t5"=:UVF9-X]"|k6I'ĭzSy |mH/q ~KMͬاߍ˷RbG`$ۯӚ;tIGBObU`=6YjLsYy!60-r_!ϽT6`Br ;y/rUhxC^!u&AcxE.~X D#0a.HF?)ݯrуxN1eIr4ֿa"x\J|η\='W<@?MAE,G -E>J@dJ Zq N`Ik5pY@,tF #UDg2\F[ x~.7Ob\?l vu,{a4\jRA`4PA4_5uX@$ ʝߋs~afm8Õ;֒[ 3@+'ZhNj?\IS7n r6AdK@ŚBn+,&Qw"³4uFXte~"Ø%+]]Clchgg$5m4nU*3c>X 4mEJ]x펉VwuZ)vk7J%hY 4ž L)ԙ5{_ETI,z>Z| m3;+ReuPz{_r?wYVvl#r{$wJG`oC`T*/Tn^96þ,57Pq@5-`y-AE,G -;*<1%*tF+Dg=A4_mBax)oɖܲOx0@D~jv;MI}ŭ֫#*8l|e5(uO:-(Kzאau^; q0;\?[<L:ct6s(.:6a%QY~ݘک۽6KAia>o^üROVMcaI4DWZR?Rb²V>( v; f ׀!g'% eq!kg̋knw3DpX*))es V3 U 0Q\ Zڭ@:3%o`{}Q sM}b^g} ./ޔ81$_E>.I'ZW $ >}X٩1x=oāfH[K,UHnP8|bw3 #+4@?7%bζXmg~|:,#l:P>O ܲ5+vf|CxM b%-=xp@\,37}ZF. }SI$W}z^ ^*d kqWA)@o`?CžTƌ^,Myz:3?[Șhf F[In vv NKO7_*δzʱ$ a, gk 1oU@1Ѩ'SM[O%k`}M?󀤗|vj]g.%S%i j5/e8M)|p߸\aWD]P9L6#j*.sl(:-)RvJD(V;yt+={*[<*s) \m$~XxٳIWCiL#b5ig%Ohfvű bˆ\\f$ 49揂,:t 2n=+JY.B.,'ڪĎD?~+1 rB"LWo3N@R70faCNlu>)<v;L_z=vjG.x쪞Anl=">񃂲5YԝO[OFhut**ERc=/eT9l>#(!ڪf ZR¯M+8/jSbЉa g'lx!\=(8JkOgVQg1'Gւ|Qims<9YMoZ2uyI%66~/&hʨ{u?-5@-εɉ'//_AKX/?k.bATvE/C)`LQ.nE}g}VԖ495vK,5H6;rfxɺHQ_S4|-}k.?gfOxA](d Gon 76Fp 2ٴ~ 3$!E{ 8#Fwl^$MVjrЫ%=!]%xA&@wdNu (>C׺yj=?ą FxgRѼF]jyK "$nǼU13MpEYwZL立0Ek2zMӪH&I+c-w 0Er1D0 kGi|dv_B7G~'Hj+EdR ]rX Nկs5^\ ~,܂,}Qo~ V3+! 8>ޣPb'%RZ#?{JqO0~Ifbx6BCɷT^\TdhXʼndA f&鳎h>~ O.a|ڒzzI:&5e;$Laq& "t|㙒@4o)꿛1 Xx2fd6 BRE|ϣs#*>7`A?g\|ѠV #C;c*4_ﴸjbmJ``*y:/=DA$Q]w lO>|Oʼqt쾟d܇VWw\s<$+T=b)jP⪄KÅ!iXK1"do!Ώ#8╲Pa A54%l>( a0o[Fðb1Q[I\lr y%/wȝ7*CPjp"*t'wz>cv-BL"4xꭟu$zG)*9H7@A uQd[t7^VO|]AVGx[Ý׍%|H)}8UUeSu Б;YZE.`_LgD Z/9sJ@w?a \": O8OvM҄X=dTЉ Y%@Ox[` Xm fIŒGF7m G.Y ^z*[͋W >& N< >散ߺb@ͩ ( O̐GlǷI12Y1^YXc(nOQnDފܫ5D{. 6<ݛ/c8$H*EB5 @Oxbj>[hx\'pVx܀UhNlrsap}t7Ɂ9;αB" k~:WB1=O1|K3"f<.p|^yP&#ߙ۬2!n YFy A=2R;Qfṃ7g.10a*gbZzr4 YNNuD^r3L+K9|o^2~0$R=/f=i*IbaYs=VcPŦZ͝ΰyNiKgЗ((r6ÿihԚϖ!uacIm ;z-=D@+s+ ϊ~TfxE&. xueD qۖ=̓>,\DE ~ Us-_Zx)'irJiS؂GTmPJdӓӻwsԦ!Vldtj-%x^dI>I)VhvnQ7kp+We ,HΝT{SPYICyn#W-/ܾ隶RV>U/WizÉ=%% A :YQ .[y*Bj/m;E5a:wyмNƶK_kO0[=sXo7 س}'#*.bY d]:s`Q=I lȇR |y֒W4nk/O~DpII+5q#nB}NO:6aD 5ߝ~pp*¤mV1߻-y /]thejҶ>Y]4Ӝ/8#iSdԮEfn]Zņ,DF"27eB żָ[ia>s@RN Id,9_a aa2@'.n.f~`4Rk95p;Q`9Hy0r^X-2292ͥ"-UTJ Ne Pd!]SհAs%S|M p?hR<8zM>'\j~+a(,y ] #8F۷ɖiRCQ1PJHqnޙIǞeǽp"(JD9so:U. "" q |zNtPBST^" 5~%~ir˔ /1 :HU مy;pvSO@hU/c{]~ c_ @}ZC fጳMO ᜗&/VlM p^ A懂Tۀ]exs˂'S&v,[lrcLMfwlH! q׈ \tG G\+iH 8x@(iǦo%.J~Ct#O*9四]QEo 0QE1<= 6ȪoOgAZV6F/P1Zhu-յ:AC:4Z }U^-C $翢C~:"z#5WSg&Xy<^7ҭB#[-ŚM{(%(kz:. \Yq;,^?j5Xq0Yh0ZsA*߳ rZGӻLܲFuFA bR8|T~":3Rk=W%1eÙ=vPQSGO[r`kŮVi\UmWYK*l0\֘[aJdkLLj͢ .n#R=+T[%ȏ}>]>[^R}kvvC a# "=,xv+hD:nV_<,'9p5K^vC"%ӹvlJnf;ur̀'8`Gc"@A97Eca2:ʘϪʺi.>jXDV(7 ENjs٭HɌu&kI('^$_5f|>$cyor7ÇUTjI3Ŗ9P܆es,> HYe`я%(L&ci)D,;rhۼ3'lb1 n@_q11z K&EdC0h'}2a@Kі AE,G yߝ<ȠQZ))zF,*n'}Tfx|G8<bf:M =a FYi;sHYY-Qy e(_AFV[prR0RA :`qKT=;?\+Z+{&5fOS {4`7Jdp+5϶TeG::̥N~$Xn^!^M=t!͊a:rvxT~RJ%g6L!|njH Mskqo8iYDdCȞ\k=3I0[%ЃaKA@}H1ٕGx a&o\} Ϯ7V sowպS3a 8cK~u d/ȈKϳΦ㈤ z?aJ\`\mD~9937RJN*9 d߾-į+׸81\z*y!$v%Gr,JfD5LoSS:bIE*Zѧ$/MNcS3f'wr+Hn=xȏY|JDk)y-#@(A N@e*bgkL9LoE7]Fac>M45/Û-GDvԪ-]"`nrsuD|-E@Ťe<.U/ ;QaKyn1De0&oʋ4P?Ίv~v+=4V%t!$$v:#RPԕ?V-)d-5 *xyf 3{~#p bh;NaU!fts_ޘR e9kkl3ev46zA(V+`/A8ӝx% xo9a)] Wq;W"l^ 3j16 , jsZ.`o>u$Mb|wF{] tOia[;B."PO2m Xzp&V*$%ot" alpu·B|r? ^Y[5*!=U*_4WAW>C'DR I|eNjx$>t=9+=w0f2nC׭N(Td"9m%|s}'q-u "\=])?vs:4&R'<eFGQ[Iݱ@icYGvHN]F1jxɧZuB4k,pJ;ѿO :ڨV-[;7nf91)M$砚8˞>g^&u)aR 1k) ta{lnXl}ވcq׌:0-|0~#ZPRz9~J@ꟻ]H VI%3 [Iȁ\2%-V:IMAغ8#τutR섑:=[h`\}H38‶ 7 wע]n{<͈a &bZg.tRh>YdpX?׻hGN]fԯ"cK Љ3S$T퓐y(]PRK{`I^q FQlx,۔8cg0ЊK?iȜ[~^d;6AvBTIEti% X֬@L]FF> y̖,j:Ꞃ:tU,õ@#b2ӂu6DTW;]? %y/`i´@!Cc1Ex`Dp&tF pZC &{d5&v1UJrj R2=]pm l 4m4 >`(Dg&|\ p)׾4(9Ԗ7\ Ccgև1Hm_4mKPQ6X- W:u= xĝI9LU\][CNL߂ʹH$v)R{K0Q$Q ܦ._}:g{RMe2m=wmw1{g鶏ȳ_fexǡ TjU7LX@*yB<*EB$aŋ8 6\% O+O${=/x;3X:xFj%J*v<%ԉ1βBN:dBDh.`êf*rɎ?;G|iB,D1zիʭڳdJb`jql8Z* &8k+yf.Rdy t lJ}2J1ErŪJgO-4xI\3JTW G|4ufP5]4o檏 2b?`"z Wz[[)mArdLv|[,Zxq^+!O@¬Tp:JCE!YEh߇b#4?_RЏ. !1&s'e7r|sR XO*ɧҩҶ]'=Ep*U Oj F @ngx+<[OiDY$M+?T[~Qx pvku҃5}K3T 8IV@% W.|e Ą_={=Qʯ̾'ߑAZ?mOH)|t?0־c@ʉ KʾP@| T ?-'Aҿ.; j1Z!"ϯk23 vsoVV)MӔ-5gÏ&,ē*9\MVu).֙?vY arOJ Ahh$ /+.J {0XCM}"6 A` LMz):Rd#º |3 *HfQ:yS).sQesRo _V7v)3w'sà@hdȃ1s+ߥ ڏINio!iQ2CMF#~\90vW Ycx_/Fr(wZMDo'APp|xYU$aLpw6)nitj#@ncJ[ !7̀7K3(sQܳ.vqh'o~}vn/ ]4\S:؜qu8+=REKlQXm i4Q:o?jT5}&w)Mb~21/mlڭ{oxklM'Iӹ<(ʩt\X%W*2v[5@x{&; ~^i:Cͱd"q-Oo΂xPڳM=K5(4U{H`Ymn$#cƇ,,KEH'.aaa~a3A򣺂% )asKϒT)+) 4@?ucL$3/)T5(GS<=˥ݠn3ou6T:BS|=iG |bBM_k:Eh`[G"%[UI1K58=Åʳ׉2T]r gjIߧ@tyZn2/h>ծj%k8,C%[,XOAUZU&LbqӁAV_e!fּL QـȆ RTb$dȿbr̔@eS$x9N2p@,F!u,ҝ*" ܤRN u [svjUٸIҮPНz^OZ"B窞<6VHgS밲D\t)} ӄzd.c'nI(YƆp)G1kSl8xn` nϘ>h0;33OD&qѐV1lS.Q7kCDP`Yˢ;oIxkXT^jH $ Ǣp#tK+72j])љd D|ѫ!Tij iSV682 :eC$r+)PUd6fVWMylOy~倥L#ߓP=8heO;n ]4`󚏀fG6T^~swPP#%ZU9l9c\ ; }sjVa'@aK6$eʓl#:l:Z )E ۩ O]AK $@/jn̘*)L4~/& -[Na*E0-qVjbcdjqehdu{p74KSMRK7.~kGCfSQP}ۇPV w!<ثZB{b ǁ{idIr{cQoi# $ЉE1]46s)[l'*'w>ֺ.5ّH^B#Ⱥ*^ N=l֜&ٌD!"ʼ?y[0"3JQTg Řϑ3VÚ]bńM*T )9,%'{PRRFg+תXKUur @RD|I 뒋"HT tDPFފ㳿 p ={ 3e%4OԈG۾SV^jecckC{EyN75a+cE4yh#kfyHLq׮oU"vuRE&IQFWcpAW' 0kFz ~@sc0ubαXr]O=pyd=ޖyXw`o !+$+az|s2WI#Ĝ:(\y ]iiHid$:|#/S&P^a%1'jWwcfΞv|?57KB&/ח'zF쌡 y΄guSz_5@@x#?=/|n RH;}13#շuFY32Ylp%,QM\BwQtnTkP4e s2B1&,GI5ksD=u%x5Bm_jЬ VOcZ"̴qaixPoԙPRܧLU.S T 7s^D U,~ً譜'LTHvóR_FMҔ@pB\i> >&}ȿ3I ߤnk+L44*Vg'C%nk-G *WYHtZKP{ {AY|A0gY`ׇ ]Dm0+cAoj 9E=v6[{ָ#;e"<؏[d?sL +LXşK%߂UhD!~D;B@/{P6}g >iJ|@Ut ︽=0ўHI(HHu /]l;CY0X6 9C|\ -G|>^ۭ^s?}A#3au]X!D}A?_Ră 6ەrC5]`x\Kqls=a_KCNAAM0u-+{l)!?]ל%&mB+lxֆ!7uG3-o͑u*ux,,F$M~|HU4u9TZP|ݚم!sX^%! ڔ:fs_%F*f*L'whrQ.WRG!1pR=T%!^+/u%.ő 9gJ ¾0zsR l_SC}:Ǝ%-c9zɌy4CP ᾙG 5@c4j6m_pyf;PrVPSvycV$}M wwٯ> ϚՔTovzﴓ+E\M蛚]bi?j."q16b,Vre] o*xY;ҝӑ0Z-S!Z&nt+>ȧhuHg0F;$B aI0ZA H\1t˗k:"ɨ/_7, cYrXESחL.ȡ>Yz+^ݨcireq 5'%6aVpl=4+}z\YHGNR&EMdb0:zrį#@򄑖^Aj c:1 kЗW燧YxNJiv`0;b ٧Ѵmp ur3Nܰ !$Az ώ(t D\GR֗ljӉF⛸om81)0TrsЋ3[MƝdCQ"Y!GXŔnޒ+@()n/4cֹ":NF HCp<8 ;$!)S &aRPRrܪ\@%нꈝ"hȊ  n4}SEp={.!tmD_lJ.vTW>8.{&bCRa R{# LF?+wDC&JzyD]3I[-,L˹_r|$>yS"p/=}P T/^H=ܸw}GClo5Vg5ۣ\3mUmˊCnrp[k.ڷz4.fYU@&} cXDZ^Vf\Vd/A6*9IxWa&ܹ0 $ujO,;C|x" i͞>LB^,9˩Փs BY:@v^3te 6O󳠓d @#8nx.gmr-?O$k lwvwz4Ҷ<tjm~r x9ޘ oPTƒr2wTؚ< b4:>>*-)/M2ǁWuh_=S-\X "VTuM۬e%rW-щ s]8/lR?圷P4=b}K1MZўs6x縠=N.]8tY)G39c3MKD9* '0?j<].vwÖ!{K6IlF>&1@_]{.ͼF%xএP'`}ka0\Ͳɿ;p8ma7[ymѹwf_܋C42SGvʓ v&‘ݢLc\-CU~^˕`r$#*f>JLeG/r.jORw("H|| ߡn%i0g%4gw cM;uҩz;GwdjS=i\Y,S s`ȁ>f~뉒B!6 99EVuj(!\6ڎR#e^Dhq(/8[FW>ؙECd7w0}3?Es~ Kf!d}A&|AQSLخr7Q(&$^ヴA_׏:YFz,,!ۺJtgD+:6Rzӂ\A7dJoea(Ģ?@ ia㺨\Q1`?X tRYςm$ 2*ң"R\*IG Bu R&R0pXQ Pӆl+#Cld>-(HQY Qbs-ӫI&>Bja߁>`JDg(-f #!n?ạbz ^uwM3\M90= 0Lr;8@bQHUFphv ZWV#ahz"OӢc'u<P8'o`1uF(V ^S~_::͑na}vnͼF3 HJ2|CL11e?7ݯ1Y+>`#W͉I!|Oh qR>4h?`>mSr=s0P ytc Rx ,F;C ڹӗF5K>˙` 9之#$B<جݟؐ0SMKv2E+,_ˬ#_|1DH͑(o5ЏB}rSZu 'Kw xfT͠'V˔lc67E$-wG*-c!Dt_km! C#g;ҽ;3w0[Xr\4V" G_"(紧NQ Wuy HՍ<,r+[/CRǢ렢{3q!D+Y36{{ ՚ALi#鄄\Yƻ)HTFDZبp~zvpJݖ¸nБ+cY=o L"l{3;%aa|z*r9 036{ F ̗EzTۥy SyE=([vwŦnu:wjҷۍ4o/L~7NOH-v cBbYTuk~(َ SCٍoX& y΃7@ $u\LCo0 c:qh] %UGcm/ y,YEnU"d=šyzn\_M3}tJgOyliوvDHs2NMŌ\>j^*0p37NJ6 X=ZFaEvSkH&l:Ƌ$5VXxWlt/ff,2sa4|OQT]ݣIB؎Vxs(uT>{%ESR_Jĥ[ XN0X'#)kY2Y>Ђ6mڸ5QU\ wK3(@`< ^[(G< F-Ure? X?7ÒE+&8ϊ06Y|Q;ca)u*8O>XxӸ \(¦z BrT^K$5uZIŗq!p %ʆW zU;^IoOrCl<ȳߌ˛hljuQkڟE6H!˔KO CԸ:O@d3/9ќE;BaJK">U+-.a׶}e`Ato="/ktbƇ9o^Xl-j!hYY' JԹ%ds&y|ToX򋻟-`ږ1:cǸYzࡹjwWz4v> eDN>ؓQNܦ ;s Z gT q֡MU`㽵jWT'g&dKܗjm6ĢrǕfjs̘G@נ#pA@ _-!rL2oVL^+_J,]iw~gܚX ^Ys.W?d؜dq_4[i|;K1d2Ծ)} Am0#͓%fӜAp}(ʥ=G徰S\"ÉoA+3_D((4[h=}csU4rH&t&͇.8pT%?S "+<`=b6I,f_+e6:>s/;$A&={MKav2 }`r>yC,7.q8}if?0aO-몉K*r:`MtE\ːCK-|Smz;,<ꓩ  4iyd1/M8 w(RuNYj<71b/NA^XHpخZGxc Jz(EyHeFxRyǏM53<_+b1ıp%xx¦"h)iϻŶ'`H-+P: C8o.lZ,fljiC wcKAdQ..7O&S7o2I߸zh`1i(24ݭvc:g-TE)exV5J~,ڈVoy>؉v%'T!# tf"%gF8"K]Ϙ^*tq~kxZfIFyr$ &W52A(F>?,boit^ϯwYvSȋ]ɺȥ׋↮YjƠVKew3mFur(~Fw э~uh󟘡X:) $#Q<s*H2WHVS"ZpUPQn?CO53Ѡ6l/'K]م#~I,w 1+-*"0Ūjբ ,%u8me8OGs†oz+/8sF0x8:O3Lڧwŕ)\3 Y5A)p?~n ́\8|h/~hS #>C#n]L X `hme;)8Omr^aErR/ǟkhy^rc,,0]-I,3<`;:Gv}V95d_6 j*1$'vliw,d)3KwOg|*V>f5-r}gd%af<%M}Rt^tZٱ PiU(M5s񑪛/ /䈧#SzwQ=fޟ`ۥVRJ,[a2 hs%M?0Vj|4<;N.0}.^"xw%YQ/N9s9*Jubt>a쿨ܣ,^K泰G'$L3#kHvU;s\'1~l6gcDO/5 iX8 Gl6'q2}dk&/@E|;j@Mr![khTƭfWl0+&.Y[[*E`sB=u4YwIp$c)/b9|=w @ʯ2+H|+4CO~$,9zmsќ5 Si@4e(|TIa謨+^轙Th-sk8nƵYcQ+)&36|A!Y>d-.}˳y6g^͹V0N mf(lM15b" MFU8*SݩФh\& 8jV@_*Ǡ5C!k,r[WtS(e==lQ 8 h{*=Pd<6GjnzcQ@X7 7a'Ns&p~*$:{ q+%MÖv)k#d#5o!e:*;Ct*_Uaű!Knd}0Pi1]pP ?P_[ aodRZ  ^[s|!м׸m.d8A>v M2>S! X{ښ2y$\^Yl韏/p{u[= \>>Dl^=Z/Y%</[鋧Vԣ^# <+A4~UmI:J5WȕB*8BA\aBtHW EUXKAڜ_Z}{쉡ocMIYC5qdj{cǐud3}A_fjsq} q;0aJN.wpg.Hn% b_0}:2p3HIQ5j8b[ebnS]!>Z7Rh1&FO #J4zS=teW\s}W(j&-ZSߗwo`ְX\9HkUXY&Ed#| rC8D8[jROw"pT!GZ"7W_DOf3.qYe*7q>T<=[nċXgGhPYR.zg]5>-grӦU碄ZbB?$EҌY(۽4c=V߯3.oTb"Kql!{dw1'F8\靤=rݣH9Xf'O*xno5aWd:wBJgwU4 CZ>PWŒ~Ё $Mr"F˨(l:D8 \e>[*̾2"~[>l~$ز4YD+fbE#wS&¾㠉.G}ȦVT56WW2/h4)ص2‚A}<4k0rBvJ<7 !J)qYlhAbvćRp_lxL|F󈷒^ށMYԙE3/,8 9tK8}Y ~9u>DUdܷH.+yv]J{FϡC̸т$5$;G89k4UڦaީCȩ ӈ&*{fI'8_Eȷܕ|qg-K4ӳ,Wɽ焵s@mM0 )EE T,SJsMgBQp۔gܕp,g"!!vQn;R VHт_Z/cĽ3I0 ɭc5NaluOZ^ Sy`!+njҽ㣠@<r9-#6[Lb`hڤ~2dob\8cmPנ4; QKlڴmhy`y{Z%jcj9,c?=J۸dCnl i`Zߤs$kDh~9=6 p5פ$˥h<#cN#=JSRZh_m<ӱ(Һ)C?q^K5d^(ZkrWSHx.- BJ:8v] 65( y3a<٭qIfPP,j^B|oH$ Xdg_rd:B`.$ [VD2FR 9aٴԂr=ȵڞ6UOs{x5mSxw昽uJZc/mމ~P21!`0&sur,{ S6j j2btmcnB*T9g{WFeȐl3^o(,QFם*/8=A -0l1nQW`2yimd/PB:pkD?4RN]KOSB 5XΛl$M-}Ъ6Kxa m4<W˻^_! ^ a/9;V9V1\̗ȋ-E eyՐ?ЈJ,˧zv!7CۇL~B:ti01B|hۓ/,A*4EV5>:IwGa܏ʙ9^_=}{K/KB</ԅ.2D /z*ˌEl|kCd:{YY >뤠6LxO{p+?ԫtiK97dAbӍ\SmuDlr~RZn< qT"<^wރ!kewTO_]ݞ@Eu$@~!֙#,^J|h5T=$$<<> Hw;Hs<J3uܷK ǰJHUTÒw Q pжfO dg`9$bVW nܫ5z[[lOHcp^~^g\NuTAF0 ?5A:C"b6RTTJ4@~K+pR@: \2p缪b/i]o+fN9EΧЖ[]yfv!34{NkGs+GG{E2+*ϓHms2Ul3b0T3W|Ӳ#gn@['MoLog}P{@O#f=!&6:ic*#|'ȅ8B3Q"Xw.3Jh*=ٗhp) ތ쀵%O(" K:/Tl@]օ%~Fdٕ^i_`a:8SxcY+p e/;^x bD]X4J8a$N[`I͡ߵَ GӒS~][v -2PqVR0X?xtQGkix)ख़Ōx4:1 mٳc{"#]$?N[fduA/zbKe^541"R'!A!c9) ۓ_e?=Rȱ,甴 Ɇb}ţ>qo?1G2v 7hBy+H .>}5vCzN:<td"߉Ӕ K+f/Dj9@./yFWucFn37HrCT0r &☳ ĉB`hxCe x";:]z-adܓu_d۩O=t~#'%JgHoԋ8 d(o]=Kߓ&z m"fKS@Y?.?eA*c:c8ҽ(Y9զuXOl1c'# =ڎ J+H%Oqt?SsA%rHxkhOJ LSVg8׹]+YgN\ڼ_(/%Iw"XUqɒwAM=^. "Br>)%CB1ffL%c$G068.$8nLb _8*Cq?X?9r %;DCc: %쳐gCKfg}Css95G,mc,HYR ʋ [7lM^ cLrYCYoݵ{߮Q0U ('xS5Zc2;V g7=])&`*58;Uӆxvs㥞u]rΜxk=*fbmptS+H0|pgG^F>vxVY2erIȲ@Q4V PN"vX 鑼Af2hhYWHg:eKn̽,?O"?tzTZCfzt>u 0A j14>-o83oQPڤ Fα0W2)ϣL&sub gs%YbGF>q$Q wQuwiB+l̮M sXSB",芪4} 2G{CZ;^8b+ [yk[>%SB*Xoo!DܘOaS勚o(]*>7`^EE L !4xC=Tj vֺhzq9B=:SC],q*"M,G.`؞&9deXM.:gNu4P4%Lȭ РNm[!dd7e+<-v(=ȁSs`ףS>$ x#+^;':'ϛ&m:<r^?y|| Qa! aݹOxһd-ZHMq >2xC`Y'' Iz м( 8۳ԩײ!RyPuKyR߂p ijn՞w"Mv@좃? 8o֕\af0H8Hu!t+](5%*eצג5<ȯ}BړՐ 1Ѹz[a1!E,}&\kop5=/ԝ|/0C.DwHL06Q[o <.dW5ԛMvۚ.Ra>2⠝?jv [أkDz;ĩ Enm z奯ؗ{vVB$_tԄv). oJ5#o(:*J! cXntMKyFwS! GL}5%d{Fnu͚۬]vgMGS`h51~mͭ,Ğ˗sp!ipJ80cvUIc=w5sftlX;N5߷m_-(!*ZޖDJqXV_,I{֎Hxy.AžC,$t-9hO w ڳ 6'K^ s(77K!FɦP-0Iai[M؀7Ԗ-s-і  rd̒vFΰ`S#ͳcQZyV}B$t+n~Pg./a:/Zg-* 1  6v%)*.Wg<-?}Zؿ?QTHtBL%BM|)g|&*QKnmf-TRfh}PVxi^A+mɶ+uM qg_#xQ֖XP+ap`; Nȋ/78]!$0Us*D4_u(Mf؋m G{xgM]ۍ27.j|Qް_'IR)0.ϟh8^ QŁ!vѼxuA ,#&eP ϋp)nֲS'LJx3SS2y+k U&n=Jsz"Q̸IOcwǞdu Gv`ߔN]GFM9>PCh8\Pɍu?z\E(ޱk8A)/N\a&/w=D'B^Khje 5]bc'|d #-U ha3t#oX?͙/۸$CԎy nw[gΰoRMT Y?8,xtqWLɆ|&P.͢nB0yjdu] [p*$VJ*͢R}xdR$+?yٴhc`;/|?WV9W7|ۍٌzi-8ԯ)H2N3C2-tujmK8|[)e64$3e|lwH|wwM>巬(i4pُy YՀ{FLI1%dr_ʹ;\׍YJa/dEFfe&{k"|qp@%/"ݵ*cݒu7-Y6m5R{/!- ?@ҀIvA 1Z^"gkg83#Pg ?09龀ԧbVD]PhuaL0aG z,W"VɈq/3oV7H-O`&@ ݝ9ݨ>פ-U+K 7WSyyb+rb m0^ n&ӏ-f 37&zAƎ!`@l2sB4܌3a-'`Q,UG9tF1sv~3OVeыq pD$0<+$Fc9;~wm jZ9jQ-S tR;k#v=i,5"`v~i3Q7w$@r>y?aN b eNYYLb|Fەnb;qS )rI\>XUKݒ^)w\]aH~&OoF'̕9]ےwǙ( "A2pTIE蔷 iEPT hTuA9M TUn׏Q%׼('oG% cJ[ x6%IGpTU/K4LqWuiVwW.CInb1 t2*ct\9ۭ6 M^WewzF9LwVaC 3|>oN}j!DTbqV_&Lxb\=VtޡYS'꺬:ɐ'Z+Y 9^L4 D:ҷ5trv\='p:*YĎ_ U$D׌=<<)u4;Qa/3&oIm 0fkQѭ3*rdp;I84ö 2nНV'rGIsoD%}h\'?`Sk[G}s;-t\]X-c)97">VB J:Kg +r#Ϊiޮ{I<Lט N!x)0_&] eoQnzEDqnNji8mjxiÜw&- 9{R)m0[=Cp[ūS?{sƸ0qin&( +ଆ[Ίd3sz-]<2?4XOclK]y.i9($,`D:77"ۢCVk0 wٞ `9QMjCiS º fGڿ|@q ӳՙ_ԐW5A`6IK@$U r :.Y4$!Cx($jXf~A0/cfyt9QOE; TouCd'ۗ+tdֺxduM|ŻXӫ1ӿ@GM#betѭǙr&D`Ir< prWZwh5Ce33gft?q1_,"j ciٿ2ffɞ,e].adʚvxˢ~+MM)44-^>: K(Bt|(E9p!v@S<`!Zkqڽ8c˙NDKxRPe˘P$AXٟGL(%RS2(O52)帮eˌuAӁb2j ީmIM" ~^[~0;}`7@1g@_"\(JTb0sڂs&qhTR%=A6ȐT.nI (v5kM<*H\7]2,?nsqE[ -ǩh"p':এL'Wy} 6w2+mr z䫠BAsׄdy*R;hNBqo\Cs!WPp?iwUշU2|`\,5 23+ ,Z)" u3]nB+? 9n:/h ܒ0Xto¹h#MTVT.Rzoq3! Fiç}\cjoNLmT}:+(/X߯tDxܡ9~KSTR}v8׌c-9@P6x'7״Tl8@]`KT?-r?(B$J5_ryj`(Mv&2PeU}`-y8T+;͈c=LxMm`oNc7}S"ŌȲ]@t%'|l'SUCvWe-?)F^%☔˧r-ܱb9͋I>Dd9McƸ#{:5CKHXNvMZkBpmu ljw{GyvP^)uDZp'q J_MbjwD_i:5ղv P2 "l{Zo xkWtJEjFXo1~Bbˇ?Ĵ|rO2^D9]F_wpN3?;$t =ae9ǴW]Hȥ*Ѻq|`)_87'RtmeZU xw`c/i6( v$@uJ̭;F+ Y6 t;bTj \=vF]4F}0S f'JH|RhhICR8Ku\NkGKhŢ8{Z~\P]zV( I|ޢ8_1Px#^s)ƐW*X1z}VLJh:/Q9g0K?/*}cPw=/C LwP=rSNW0L!䘽_xeN+PQ'p G` 2HINVOOk<76k_-,#ݚԧ@$;HPuPX<NjUӮŷ21"܋?Օ!}FmeaM߮$y9mN3y^I<};]@V3Q$,˖v x.FfAp/_Dž.}Lqg \Z;)9wz}nY?d+O~8m`UL't6$[Ä;_σDuy]|iLID:AMKHE$%wlCc7lIR[6wa,8qŵ`q<)&mKVd"b䤂krӦk{9'n\Tܱ~Uu6GL;$I=­swnґ /nNY_3N͠|ʚ;#cge@yâAkϛɽ‘9ݧĀ8y$Tp!D~#ϣqO x5t S{\ЂO'}6DPh݉cؽaSO4:*`Gor ƁAmE4LG Pu2Uc1 XT=J2$~2n53eI)lf8+ Fր6+>, ڲ6 w̆xA$We-((+Ye|E^ ԥk~`jqsz~~a 61:׼z8bW5^1~)}Lg1 DK8 7z(!f}+9kx.yt/-Elm<3  [ @-9NmC|lbG^= KU;(&ȋjQ_ f54f;J2_:ͩvuAv%2LΚ]  Bg24/F< -R&s]♬\QX ^}`͜2 -Zڦgyw,U)e qHLx񛷲ͳ&Db,g Hq$4Ή[jTUEng.ݎ.Zb|%BӁbtF `7ѠFzD Fa1^EFaoi*hnT4>t.@sA|Zy4bϢ)\3sE#Oz Dg`n@YK`9\-]3>?5@T- 4 Cx̟b'fQ_DRJ*  Pv.B(>uƥ] /bN?6Zk|R2ioƘtnZU4;ewc.0J=ݐ<`HEjF9#(;)9+y|zY AQ H"M~B"<7NX.* I3s:ᐵG^OJ_rO9^2곦OE}ssdW';cbt'TУWd9 ɍpфT`gaE ƿEp'@sN\;pD۴DG650(v0GGͣo$|ʦ}*&z6KjݮwV1M,|l\~ > ɭNrS#3a~/s`EnHRvCcdo_]>$wGF fIN;M}vA'KYkl"Ewv=9ҷdl𐀃jlxITu|lEoe켌08lz/iAv^sgrt=M (B3}T(~!EE- >t[|~a݅WI3DPI*(G$XsHL)=TDm_,'ځxm`D؁n\2N#u7Uv3dosoki\NwR$z78)I2:5J!z1+ NVbDnoB[u&c."GK, D7@o'rn_QVHR%]OCFpQ)Z0[U~ oUY9]v1okQn̆2!P !g8j):B=w?cq$.OJZT7Rf*uUA[>tF&fF&>> jT-%L`G驭'}B Y^l> _8Ii>gm*0N}VDꉮ\2ȍHxJqSNV@pVm-?Չlqn!p#I<׎70 ThL >qlDgcYAN5=Y6f!t[X)7BAȜHVMd%*pw/?;RyM^= tՕ*"yٓ1?Fda# b+f#[%!8UA4_eP1Nu[uD*-[PF-$sv K!g%ːq#kUq?>] .Rٱܭ!-C`4~yjUc({*}TD7iY X&FHh XF־&@+3zN,vdvI/g5Dd؈4.o;,J 4 FL:*.vQ枸gBR`YaKo>Jڝ )Հ߼J ?BDg.MlosL X%0*S /A4_e.*3{✎+Aˏb',a L؟Etru$Տ:}l}(Vdܙ!Mg;wmԃ. cm8i91] 0o^hy¯)|]o"Co2pZҕ/RJv0<#]nuԀ)4nÙik~62D^zNf;mVBy<:01V X t'UA8E,Gґ1IQe@EOrv2(X֦Rjf:oa嵌K@ۂo `(aIWtF.45EH& qAم{m844EYDgO~I}>׮1. !Lk ?wٴD }`A^4_n< 5DW)3c5Q}cICkMwԉ_'fLa\d tcN1xM܍0[MI^3)h*Ѱ<ou(舵%j|c].>y2lV8A|E,Gґ1!6I N4tFi`kB-p71Dg L s9'\(=!UA4_Z/;}ISJhw>m\`4E2H>nCN`պ9:V'o /V.B1hZg񑁴= S,ӯ_`h+οOf ,hrDhLOlQ,[%gk$~(MrBzPa:q|ILosz& &ճAQJDl+N/O(t(v@#Y,B:8D@SM:'y~2M8RP#S4; elW>Ч}09>cwvXGCaLZ@@%/ # 杼h0o#OPݺ?'+ 2.NىqxIlIt%:~ނ;.E|=is^\ =zc0>a*Ћm3#~ scͨ]PT 7E3=`@ XXoMuRImkP^h㕬;a)7 *g ޞۜ);h*dy~5uc]uA4HRҍX")zO .bHoE? z 蛗& \%{:]a`29bHFMخ@^Zg?Yεx=sCc=pݕ~\0u-򚎴(;\{ {s"BR8';E>u|٫SN"`[m|NvX K L[9Tr(s„&24osŢmB$ȗi^E"iL Ė~fgG4Jk1]g3@I6uJ52$@@kŵWqBDR^j3`<{O;*;G:qđSPʼGfm>&?M LfV{`E@# wGg{Dv+DL٭|~FWQ,Ә#F6jQ6_򄨍7ƺټelmb>(:h 9Ui蟭{@qAE,GGBDkm< j*S̜E6yS.9sOWl{ iT)!2tF^y~bwpn1]Dg<~ u11 {)35Go:}50ȶT+e[Dh8}*QA4_ϲ Y6-uE8(.=g_* A@}x6s vhpIf[MRXmpL8:~5}2qb+|%zއ$jOP%Q~Hҹyyu*d)J ~5q'F c Uq*ykƎ[o~[e*wbiM"Ӊi]T;]'0a'RI"\mf`h!5a]<'Ja(cR+"8?w>+*ٛ(Ԧd9mZ>([907\)s4(›\f YI5|O>"%.3=~x&mUX9E}0-U1{43>бm W:0ml:*chr\#XMqVζβN3 ߲]1rgOk#併>{՚S؜u, ;n^?uz1Z%{n>}k#l.1ӏC7ZT41 feW;I1TH&q#-Iݿ,:1mOLK?#0. HLh"G"/C睾p vj| ԥ)w@v,smJ_Ԅ[#9Q2oc1m@˼10 DL?aX'ʜFR002ES>bsje\"=ca_Ś%MrC'DBP(!mA29ln\U<kcQ/0czVwhk9c2H+G8Ȋ^vc`m[1 {B=$5@&GK]վ"Q"QG!u3,L1:6UyWPlݛj[w(s4넍08y cfR.j+Ryޞ) V+^}tْ+UDo5X,(5M6AP hxTQwZK3nWʛGD'Sp@:UZ}8;Zo;K0|w` evXO#ߢ 3\ڂx3%_hGNUjN2?jխj~1FZΣ"8wBaV 3f{Zdb; 21g^=PJ؍EH1-TpFzWi8 ^hc] Tu}\L *ya_>C-H tLT/De N᩠]wa}`h0gqCOü 7d6>&&10ӜGsSrwk_bfFUϞ7ͲOߞ˖q=\I 6*l4DOdP.͔j<@~KJ!Q E&4p5375):IBwG#ͿhwʛF#'7fU"(Zx= if0xծG(ƪnDָ5æd|W_IqZGÓu{lg=psy\3{x=t;@ qDg4jˍKx!z9CeY7䚞aQPM/`l:V1NQOu#`4<SL TbKhپ"|D'zly^h.?G_8nN@aS@8NJ6hse@NϦf^Ի]fk.` Vжi5vfhG^Z0xLDus=JKj(:}?ep*PA 4_ If sQ"nbHj#ru5O$=MRm%IAvxOb!-0wAS])WR~)Ɛe}7'g|.iy#qm'==nBM:2c&%ek&Q/ӛV-9ޛgaB.;:Ҭ޽s*Q"KU~x˚۫}vYSpu9sRy@z[ &^'Y%@j{qb[IA# VzT+H`(5aiʮ!m0~NLkE*#.}TJ^ YC?Cj{FrH,jjFMʍ Q^Spw.\dZj*4{F13.cȜ9`\ &WJ&'qg r /B )T^ :ouj_[ͰʌIVQxfǖ: QdcYmEN^VbZJabR-AxDS eyY1AUdSZ럥nƙj¿5 :K?pXUQ ?20 JS%DjH 6=z;P|xtT!tL"Hf,:׀Z=#ɌyaoS$##wb:2=W}TdXZo3s߰$oѮ288#I ʶKItG+ (3c3浠*@A(E,GꫵIpLOǶ[& M,Ͽ=5>^ *E~he2xF{gqn :/mTnu՞q^ER*%ؘc3Pv-z ;Q_v:Rl7I>$8:ZFSS)=*T OEdY( _9$w[c]Xi8¼9:`Nӎt1|}sHaNu%vz27J{#I@MP nH )PGtF(E7t?ZQS?;̶mv=Saɮ P|mXQϟ#G=Ӱx#E}Y􆴶M@uLx;zO.5o(m {yg)Õ/V࠹x 7#, .i<2 Qsbm 5r]-8f[k{'< U.L^$ Bj]h<,DdjmִAT73IDgF#G<Â|tVT~!Q־NLT*CV"^bܖMLJh\"ti'WnE䨱R;^Yhҋ2(Okg)|/u1! +:U!yN^ХJ{9 S0 0=x~ZeYfآ@(ÿy>kpE\40t0jgq ۨM`H9M[)z " kDŽKdݷl2xcpf))-T) 6F[AN4's7-6{eۖ&?+qh:G= PjN Nހ%`рd刖Y }k2:::br,=μ4.{/?ՖEfZFO? 4L1j~@(do/bWOQ[2i. =VG!.$wsAGݐjzV@p4P}WeI"DP/g,iꅏ>+fcb,ͲY3PXY_HVSSV&%*7C[Du3 $j[뙽1YH<'oȁ22͵-QÌCb`c;_E^A̤,}ăDUK&LV ,mJFbdoZa)Eܘ.nkxgCV ~ыBAם/ej4P\).ȴ!ZH($ O2z P9-MgJ!L:k$Cl(<]7H b6'(D&Hnȏ*;d^ް#֮bpd+)o*O l#˿?'7B'/,VY\ q\~PH YxqռN Di}2dӠPeF M!6!\:IZ䚉|dWSu [zEs WSO?p¸FM1ޡVjģx<-~MT/U<8\{';,Lyi+ԲjUkPm*8rv'c$׃0Igc#bGԘ3aV] 7WX$?^d!-xG6T`XhSvv \:mp<9c;XL@oJvkmiDNP47^iTZgXɌ-EԢ_ɐ3ȇ/)!y$ ,:5E[SX*(MHk#| 0 :$_pZNx*\6PN`XveڽL4Jd 6`ee&/uP,tfE趄v؆d߷lt4a>%ڒU:E'/om~T8n?Abm1Bzr(HC/ݽbSO4@|$CR׋5?0bL6=&RKQɋՒ#9WHk J,?CNQd~5iKiij uluaiרGf3Kj8.<^Ay͋$"{3ն\ϒ ;n+?.J BwV(,?2~V4twİwMJ7e[s"v8$|ג-2I W,*IKA<@\bV|jg񡞑VSU`g,#ׁwS16&t㧧=Zض cBΈG(|Q` _'AlE,G3E hS\P@&\xŞ=IFO&&0qL٭to&FS-Y}I-OL9|D^|Yd8aU{}C:Ja:3~D=,ڭÔ: =jV&"U4 aMa~gw&sJDG5S/p-@a}o]׺rtb7 iX6atFwx[(ŰDvY _5΀Ibk\`lPO|Ė]N` b=춅zeRV$trVpC= ĔBű:jTOlz\.:s-ṊE^G:b1 X\0h*ZQ=U$,6h',R`i{7@}p1bDgafsWB>T$i+"pg7dqd5t eriUHKA4}#b/.*od5|L,%X~ 24u;^ҙZ?v~^JHƂ=T vAuk4mU%{ҢB, ;md j-ν+"2OǪO)GVy?|ǥma9hd2xG[3xm'T{/HX.ދɿK~ ##L:F?}zV+6 "u;i%rnbG`2l>93 Ţ *DRp7AE,GQ -C$B?kRtF^Q$K-AOғ"O]IOV'Σ|w7t7)e61Dg L s9'\(= A4X-lIFN|c1v->8Vӣn_]Yv]G+s8C T)6} ο ֊M;fFpPt[O賠ѕ]0l_Ė8+LT^~;ure#})B̥kzl4씶zcEz4v| & mdXE,a3d"}&Wz)Ipo p+&CƢ}Z9kZ+$ ~5!ҖGN'E-$Q1WU5i<9gwgXVu}@>RI$3u%S T6J%'H`nk[iݽ\%q'jDcZbܞfE{/>M^_c箩 谤o%]Ri/-Rz½$~rj08ʃj3D^ђ'|9s #rn=mcW"G}_uD>.E"cj&;J[| ^PcUgGĮݿ/e~f&ùNN_B9MΗ]_vߑ< ua{MW/oAՙ&#s# QZЏ, =^t|]Y]KTB$Q^I3;' ]La&"RS;Flsx;su,T_AD2>yE6Bf/|~N^fGw.#T~kW쓆ޓNiG /_ u}EeskYަwO2]۬AeŇ'5YX /۫pۖ"%IUʱ^8\{s&2 gЪ(wwHїNoA))ѭ{H-M4Ǵc|9љhg ۢ] ݶ#?W ƹI# [{%Jc 98^۳)=YS ,9v,Ӣ AeE洟S q7 ȔYHΎ Wy? h_]=YS. s A+='yAJV]ȁ|dPzѿVQXp46 !Wt@/!W k [A]X9?9[ {!nu8F3jqsz'#`-dޢDRdiPȍn `&L|7He6F/e\ď4R?{bP*dlޮh=+Ǖx6  ?򹟦&( dԬ]Kn=B0.I0GJ*<3~ C@C`"0tTDvdѥ ,hP৲'uݠ+P~m,TMCe_yVG ;  S鼧x[xƐ4Bѿ. N~x/+T\/`ӠYAb5n3&/u@B HGR5]k)4lm@~q 0U/sFWD*L%Б^qꬃ_61J8SSƟ)yQh1MoU)6[Whb -A]IC55":hc|6~b3xt~ "Y9NHzBe9CfYHBkAE,G (y!J , *(Ee=?(0,/ma.C~v]w5~ 5/]qI`JS%OA$0cV"{_2Iuz;g5tFm59ϭ3aDg ƛYq $YnhiCyS#FxaW$(aS@w̷2 j̵;xcԐB}w~_uw.ZfT;s0ӵS.O_7pj ^̽+0xj~^j]"j`EuD(S^Ԡ"VUV+#PFr>ˀR(8YҼ*s&th.aFOk[؁.LWn@nzl:a%Urw$,P7Jˢ %o~Ӆ &7"fhqJb@RD8yu{ 9Jebq7@~>β-J͓W+1FR ik@Ph̪PQU=-:)ܪ`C/bPqSM~9'G*ؑ[b14dV]+J6S˓Ba8A4'GX&rֈ:(,ƖɌ..r/]X}zL^y@}2y$ǹE?kexr RI,evj'U--?W%Ϸݾ l"<0tzm\4|"$>X-iLRSX{+s<3riIC01tƁO& x31ngl>^RwėMk1hjfhe0B CYLs"ʂc)l0\BцDsqFM$aI[LggQ+YM F:j3w)Æ?V +73Iemj{vL'ix{/CG`mrk&N~H wDGX')d7~3XTJI(%01}Xec͢pQ`H#>`_5˃|K3 S8ܓmKG9J4QDC&],>dLP3T3'&6/ty3,ycWv$t1`ˉOؼ{H:76-P 6="O*bDB|E=oz1#2Aþ#;]_*W ĝ9í4^Z=n;dKշ^'fтڀplk_Z¬ogaF~sW;2嗸wbw?g]7Y8rL̯2zO{"!,fDq!?*.'b_rsZ*~)E7Ix1 z1uTusVNJbɛ'; ͟BpX5 *G\ 檷@:OxbV/aZ΢HH@X&P=(lyuHPyb?*O )^2ʷl t */<]<& o!QlˋS)Y8 hʪ0gTw뎩-Cv%:2ڈ=sIfTJLaR%IP^όxвyV/y^RjD4|0Oc3LGԂO)Hiw`A:9h1eV-@֚$ܡ э|`߆r'[w=E J.3ԄA"CtYv}e-7ViN-͹Sv"K1=.`̠Duea{0wS,]ǚnsOg>Ύ`gyZIu| uB^c @l0 ;~=Ya,R_ -26u#ET8i kz[,v3buJ%D {Q8ƷH,_DQ>|j(r`ݙ_%ڰ ٴ6? `PHW68:KK{ ,'TA(t6LZ[ R'D`s'{.x# r4f0)fԘ!4 KBOfˁL9n@=*VR%D싅`~Ty"x6O<)23]agGema!GDjTO,|O%'W8475JZO  \FLʺC(gԴy>G,@xr3% KA:,l-5)TGѬ#691DNc@++:,[rp_i_[+ qH5\B_h^Xkp67 ;?[B3!c<8k`i>yVM%L :A..AN#W"RG!lD#ەdN1Jqڨ5&UQ<rZ!Wh^԰x[8f#ಔkH?_hL. KU'ny" u˚!F:&-7+Xy.?p9uh#v'@PD:Et-7j2;W`:`GXWv  hd+7eJE\]J__d87\vvV,euYN>|*)8.MveS|cQe8c4-g;/YhW&Qz; L*iDqLP 6sᯜhɍ"^LIK0wDS >$,ph-4AӴ~36=X% )!b|An o8-j'',_dkVM›&;2 jk\]gF.>4WOln9o~h;&%myfg8&` w&"J5Bc :)O`L+ᏁQgPtw1@9 Xsyn:r72wSr[g;TTނ弼DoFȏyϊ"" !u{0%+aTs4 CcB{/=lCeطP| 9x)2+u ʫ (<>bNJbs̀\j~xh _)ʪȠY-T?eўOg*ϨY63im1t yAн7қ@18~D l2a)oY  +|27 jBW@1vxHk=N'D!j֠~-<^*l' Լd:?N#գ ,h}Z.PaTG4Vץvp9Kp!—q<΂|¤h飲҅g؈w(MRLA^DK?\˄R>y6!7gF?ќɝnLp ᄬY}|hH\|k?0\Ч mW$kf)}*%L1bcb I LK\<-/ʢ1׶HU/$;Π^$Oh޿^cƤI@mԼ r%IDM6A{FxE0*rb<a&$Q)`[dSdC[ e4f.gC |`Xnyӳ,wzUe=lI+gpGFˤJr6P齄Άdmq(Ȕ+]=_ex V4!67Nd1 RxA8E,2\{EKv@lk`CX6:Z襝{̥υa_+m_fLHh*aJ5/'Qb~#QUppc}il)> J8.0Mk~ΝƽNva\"1__h76qK xǬ5T\o=P}T[%m} lgSYC\PZ\[H[n|SEIb?=L)Tpwj17`mߙCKJ'Rav,Z؏,h"?"hhV@y$l7tvdcyVi |9C_*ޜWdۭ68 mE+l9xJ9BtڋMڙQ*4?X Iʭ#)H0$KJ]ٿJ|DֱJf q`GcyarmگqypQ؜A8ϐu#Z".E"Vcjd-Z gOy n~L@+Je@[tZڄ]@{I i~պ0qn 5^U#^Г>囌)']OBmTV\tDLۑL ˑk]VCZT8$+,kTӃ5 ۜ,JfペS[yR ò%*+d9^">NNp䝶1j=¥{jڥ@ B" jP!J_L񰎝YtdXz,7'ý?%A#<ͪ֠a4A:_AXF T1=Ɇ P C ؆0L;죧ɖbuf_  o*]SyD8 *u^e]CX~* JYdB@w؟JġW6G쑫g>  Zm 1@iPU8q#.cPȨ.&oM~ s*Ps#'7PͿ_n{B]ׄţ,$B"^pm{g%,hw ř~51Dѽ3DRM{|zP*Rmz}Ak+Z: ށ}t5 v_m>37ج׽eqs, H?Uiy"Ҵx*553d'.3Ly}beT-?(kܯݸnʹ;!*uT0',p D(G:+HL{KRͳ پsyN- ܈S,^ ht ] =87MY];'<^=o+E)O/8yo#FX˙( $N&].)hUfVT:K؝1~J{OqMUBF+.]l,6q3~h G[k%561<eP69Du 3֕붕=: cC!r5Ľ`w q f/Tnn)R 6=t$9?bQ5K"&N5wE''hx Zpw])b5 jQ7't7!ӁK~[Lr:?eT]6,VWDZ43`yٹi$pG9(ӡƹp%c\(S,'zf\X|!c D[d&dA W1P ^8g<؋bn¶_\̂N%Y{0c]/]Gj]f%nE [XzXY=Hx]M7'N{Um\XJ/B3mqs*/DPb&~4y$8g̨-n)+:ap6|Gk(K9q8lW5"n?ӻvhx$&d)31)?`JJ/[Dss8x+LQq,]v17sץ8[6)~"JTb9vG2.h1_u<6 8(eP;ؿו z(1<A;PKP;In_Jj'dRd,@oE3mStp3ZN*)X2{}N(qYO$'Ί?H!"RCÐFVByeΙhݔ3R|V p|"l(r,0GnZHGRle@׉!2(m;-BFp!J@:oZP\;PCb䑍xJԄH ~"L d8O@a%S;/N7zoy ui}bq4VS)D>}!2- T\+uJX`xW!7$g/L2cYӤ9k{ xL8icVۋqfѕU<[4,7FN?x M\271CcSïtm^)k[E|8\{Ek$#KH8D4l>@ n7}p>݋zw/thn~mA`c6+׍Ue[>Xb6 lw?fy)^kj)!B`e!VLxz3tr_:Nx6QR}fEj~frYyi|IWձQTƞa#A!>X] yu,g~9=u=DybWaӨSJ+^&O!#h3]JTzgƣQ2]Ny_awsMBT?lkwSбg euh 96l04-(5DCk kQ4J{,'N4O4]߉\[VgEoEZO9ܸ`I>c@1o|mOak$ c㟔] c d$B,mpt;̊Z›@)(Uz3c-&ӏ{r~ )zXcoXye:qA- r x# rzsL= s @-c;%nj^DS3KXuӱdd fbT`+&K;l .ܾx[Qn荢ߏE* ܜ=s]<P#) >q3M3KU 2LsKw`ÉYDg 0@0L=~a#$0 3US`Rc0]FsJy2lH}1SY 3l>H[\l"U9n]>noUK}a,"BfMdܲ0t3\Ǒێt-P+rCRXb *Żk{ErlM}ial}B/>n:F @|:e㼈o|go#i`zYmksUQ 4VKSG K(ߑkG~𯆚=,on^xE=8|0SX|#kňH[2l`&id3TS)r,؄MSc4GSUn#QQ}l9rXnK`mzbSYhgTó~z0 L:,"p\7̈́Q~"eoGFq6A='9M8?-Ѝ9SfrGƾ)aA[4_!K^aV‚p_QJf>eqlߔU؞vv!phWgx$hVWC9*uZ+i%9D&R_؇DRXK=#8o6y'!uxud뇰o>_/<|vN:[fa)>9.S.֯0xF$ڢ6:\"5;-UzD?M,4d(~!*}撁u[P t&nR%eƽzXNiБ8LRj(#z.:p5/IU/I4:ɴ9i^sI'Sn'Ri sУSɱIH wQ_aÏq\>>= WHWLL#唳n;wF$PD:(Z+~F9 hMIRW7 I"s6:E;⌝7DI#$>c]Qî4@r8Ҷ՗v5ߵ,RwXt~ j|' <3%}fxlEf%^Q$Ⱥ=b i00H |yߊԱ5ݞVe# w?VgDXJPDT!U{4r<:1ˡ)y&R]$-t2G05pI]'."phs˸tn=d.NFUS& fpp-Zn4/Тn_Z_ v|1TClݙ,} u˹J)ik>+GzV^ d>MbpF^Z췸"uDTip?p~rY)٤ _I3DѠ]L9 t91ڹQAIr1dtn}ܞ&ƇxgQi|oag\5|؁Dy hn\oqN2sc%f ; AȧiV;,9K_I9pI(MɗF' gFД;nmNٺ`%(];A}I^?rfi0eݲU;†* fRt06~0)?}FUTo'b3r(梻9}h-.Ѝ߈U`[52R?>abwYmBJl,mr]ott#ȣx V-ly"$$37?7?+.Ui+n2d['Yd(^Y=GFjwi DMMEx7_#[8[8W3up<"}es(괈+͔ MYƷ 5I0VVړZ|=u]3 9͖{ș-۪CAXOZYuu-Y$'%L- * W3C^?kj֜3C{ '>mhjUjJKȔfz%:5^O̓.Va )*׋d`h*[Y>,dAs@v#Bj5Lb+<;(bb,7ԡXM! 7 euH0g°z֧A˱[{> =hl̘4#wSѮ&-w*( nY:7\tX0_%W)45g #i8h :!*V?oʚT4,ap6Q$8ePW@0-1sRg&s3%%jH0 ~u8 SA;² 1d)e{Ks_T2bo֡o'ܜT4M rzuuŮ g9ј`*ʋeMݱP " )dК';'b WldYJ h?lm4]9Q 4"RNtr8"53'pZb 24۫4y]7Cjh3*{KB7A"_l̠c) c0t֜EdN&يԊr%,k,/(ItUVJLV(5hu,`wZaŝI=~*x,5N5Jb각]^`% (0T# 3i}kDSY! λ1S#6+fˆiE77 c ZlI+,67ZY%9-u AFXZæ rGnq–vGL |x.0p}~BttA[SbUT$@t|~,tk`T~%\$BOB1Nbb6x PjǨVܔ~&ުlWx3::,.⍩VZ LG32-3;MaF$?w7%^w!djb4g`RYJA͚.hc1&|둧8$FAb,fҝ-G .7R*m7z29A.c$lOH"]4&b`$V(,]\+}yoUcf˳9`CJ?<]dz ؕ,Zϧ,W`<{TU)1vQN׃.N^t]5PÜ+ > '1\޼[Nj4X{]u{tb ٹ.NtJg4ys "KAԚ f{e3$l  \z 4Xߔ4C I"T_MRCr96w&3Պ}4fmUWyE`fϾݒKdqwJ-_'bk"l4rN*J:B$3>MKtHA MLi[8ӰN=J(E@/q%izT~rz im~R@[{t 򐾏tu%8Tg4mԃ]d|:τj)qsWj _?M>QE5]蚯b&S`@I֫"|m#un̩>-Zb ?*Ԫa^: }H_ [:9LM M.sB.m bFtݺ^|Mº*mi Q6<cQgƻ]b޺A<: ti{SP-xݔҥr Yf.̈Z':E`c:c%:84PZϼpz>t*p$d%mKi'L0 &$"x[nOUy}D@۬ťq=m(\-9]e#:|,+H\sJ (=cfȿE+$ < c<{)[׎o(3 Xl6hUZNX@4'- n\:؉_PM"Lw}Cɴ|; R!6j&q*Ǒ \ *J`o;ph' qxΤ`#𶈣qV"V t f m(Q0ݎbD U*G`}aelFstPêUrNs5BRwAYdW'驢 HƤ Kh|{3 m\uN/a&u7+N('RJy.Pd/o$ MF.|zfIEZĠbn⢦t9M#RrfL#έCB<9%P_Yyr TeRh]dE@ e=ÇX44>P :|{G&*ypnyW!]|~$ϰ[vN=Pڭ혢E.n_d[Ɓt Up #pu(wr[' C?ޓ^n|B b:ڇ1tg}ehM$9DkܦZ9a {_ׅG9?;ZȸM'!wxHTNysʇ; "‰*sLSG#4f{8{wۧ5Ht:G j&jcqf$6:*wIno"-ĵ{v(L61BΈM>=ݬŞjOE" YT?iQj {%~ (+N.\_-WClO67۵t[v;?Ct|}SLPCff91m'o;AoUh]f6o:2zkƎx2&tq09^nhX˹ POO#Er&-5>D"=ߐouyj +ȂZYq6Q:c pެbH7ZDf2S.j]G>hJ * l,H!in^4ªXuG4\6t}# U k9j)_a w@m)@>B:?LdSI+P2/_H>6 eR A#˻gL2{O3r`$Vތˑ l\?|H1sw)X>hܝu /|r(;fd$Ckٌc¯ⵄR/g7ߠ v%/aR {dꡚ `vNٹdGeUkgxIvws\tʔ[, ?=F~;!:g/(UV؜H|ĀVʼn:鈦qْ NgJ{tDMс14ssh@D3"%64CHx'B:ÎGʴn+ЇDoxR:3wQn9W0^ߺO>)ܤmkp% ,j98/ .Mkd4 bhܓӳ߉ezdSsO@[Y6TtxL Aixt@y`Nj l`b.~}m}C?# p St&E}X=Ʊ0 $ZdP\; *FТh }(J4JrGZUA<U}^DË4 :σn㿭:?F{4Yu9pznmjohkaORAG۲H^i9%l)c @9М݆Rc*wԠ[W;0S_~C/ HWE?Mu&T?l`K'&m{πњlA̝ 3.=1bKvܧnKnO\%Gd%2?u6RGƖ%k9eݿXO 2CӺ Rh0j|< 3٣%)@RMU}򲒌%Wѩ6?EvGtU)m}V #RPj J_p>V(eB)LXzs6 Uw_t7u&{+Peީו6j|7+oj@&xh8XjZt(p:M^|*PjjxoÝZGPHԷ#!o)oXN䝈4 A=/3ua}x8(ӧsWnI'PvK}+~!#a(}@r9ncxTl?&e_?˥mFνԁ)55Gg/J@ۗʠysA=-{Z Sf"й/FVs so4RBq㱝k]c)g[\l9f99GAt:QuVۍiTP2t=n¢d5(KjxKAqnZ~MoFjz|;}'K/GAdVr;u YN!~gmrڂHQ.R+[f78 a^یE45aVFK;tkЩ Q9d8.sAT+đ^գO7jҶ ,‘Jt ʗa-vވ[;ДlL#}!Fi}<˨K-,6πXbÝ2b^Ob:]7 ^<:0<ƵǓw:J&c[dY[>+}J'h|Ç,&LLG:8){R m>7/o@׬`wK 2ܭl<#JΨqrM@]R}۰IxjC5dƃ6%HHy&0sҜnPPfrB.hT2*ʦxb.Wyt1{d//Yߍ:Upr9pQeL/!{$ Re֋|QO/AQ!!8_ATs,oL\br_#q8Wʋg%:egU%F;Y|W:3A a9/P'77PJD㸏#4T6~wS>eQ!G=11i \4`H X 7>x8r?rr1h'e- cރ!Z}Cy5ֻ.wc XB:Ik+Z$l|^qt6aT4CisJ/'r~ )KF~εv uy`mAH4oOj3 f@. Us:*)5{nZj`>5on> ПscRmލG!'v1tv3H| A9k`[v{0} %"Ҩ7ܯyia:.no~d2l70nmtqy6|rUEP{sB Mܿ~\ԙmһf8Vb?ImG-|L,1onˑ(wbn3D^)inLM:oWeDtGia Լ5k')M.sC56Է)IY~ 8x≫bf՗|>Ca s˷^KNgpPYƧ\ُCU3HBtLlOGF9c1vjj,nrk7tf8! rSw|tȣ|0 5k˷Y0}"[b/!f LW 1g"Ps_,> 78KYrpjl r #abS~ш'Y.ܖ᪊SGm PKanOqM'ӮJ{CpwFұbFc ̲Y;I'>i FrQުO0>nlX׌Wnfտf1d،|tY)*e.h%k!v3i3 B:nY0 IpEFO 0n#G+z,r*~D{+n43m2Qd<޻;By5%m3ؘJ\0d#8]}/Z,]9tM;0]4+6ꇴshU%A%l `}*{8zy|a7ܚB`mqRClGrM#b-/kտFjnڤb1i·#*7~$7 $D/Y )1o8\C6_ŀj0"ʉ CWox8ǽ)ph^j1U)fz$~Pe13I?e|ٝ"É kl8,3=|@'DYl陁8#j+&M\kݤ7TW /"Ls&c};]]2YFX,!w$ؽN%SPEE QyEVV׀WX9~:"]ܓY[Ǎ%it `U(Mn j\qɺ-kȑXM^3@=D@VHH!~y.!Mu 'Gf`%^UkL$ja.bGWLץT B3a_UM^m}NRSܟzS {0fCo0\YZZ,EmRH(3hX'"ETDQ=s/'o} Ju++X+B”X1=}l>齿y`ԨA2Pf- Яɇr @nm%\*?o-9y vnC_Ɇ\zMX~6lÐݎҗx/oн Ul,%fIg>8U_YWFnfDEa4pp$w˜fo`hC!%s*`X}+F>MsT1 }f Mb j7?G@dyZKш^xV9Hvk( !#}bMjo\揩0qks+Hָf l-TT$80)fQ(xdq{RJe l2'RFH66} Pٯ0 e!i}ÄiD~M `lf+:9ƃ:2)Ȓ傁iF<"1sfMsA XJϓC^8LQvhQ w̿8jO<&٪_F@̹|شykc dgYd"úIZ8pPjs>k_46F)zxw V/4,D?;~i-Vv.cbc Y3ӇaGXl潎ʹ>*ʍv\t5PQ&[n3/)"yݐ,2nuycш-ճ u ΥPF+f?#qЦ?xVjT TTq]Ώ|Ru쮙Gtܐl㢧3LUk/(o\ِ P5z:8m-j]z1TS@N5T=VzyF^`%^!Sꉨ̎17@k( f4jFxn߄y/ fCB auVGl;Wc Q_y 8zbDz̍bA]_\  FCz9sь >A,]wNcD*c Q僶oeҏt.H<փa=UԻb0sD6JKc*{d7M qKIJd[纝"i !:\׳rjp$!57_&ak<K\r$׿L<- |E9#pk7:!(QWx%,ns %<ɮCӵ֢Vϡ?:%7\* ha_ң!/nguLDs KV _ZC=xH3dpyҢt2ɥ%&Thmkup.Kf [C:r`ƻ>0Ew$>ciF{z2E92%^#& {Z'F_O px,uQ"dAE4LGTId<&QǨ+攇|ο3O4Qc YV 4eĘHEOvvPs==w{H[PckHwP3v"d3Ķ~'ykc8mCOJČ,Xl@XC{;{q*Jj4PaO.MshiƚkV("Dbi"&G|̍UuGbkSG :a1J"pFX!$ B5W_Al>\˃0>#u7 .=CtjQ /&X;C<M58Mbr{pan&^zw͘5-<)g 4|/P=9Wp7\TT~e>ޚCm%`=d YřȲFk' C2tRjv =}fBc~6[ PF}]^(38™b GEfCxĝ̆y=Y,SChu#\ܾ6t#WǞ&}3Pz&.cUg#Mag JD @_%n'P^pgP֦SyӖ1 Х 1uDgB`6v:B4O}Dp+Ā.>atTQ44L."Ay~KR'O?nk63>F.~4¼cdZ~{v[ȱ>".e2l?ߣ>{˨k)i؄b6tAC 8 A4žG Bpqddd85L<w"3tSwd{ë=Fs͝1ɧG*˺LDIuϷ` d跻$l5IjWI1Q Ik{{OI$I`]Ba*Դ\% c=W_Uڪ66Tm=*Zx3Ն>$k3&$|W<*`0}-ZP/V0]Be % DtCχ_N2$h C4O&8%NTf`g$Bucb l@MpoGĐ$ Cl?"ybj")iP/و]5gHf}5%%|[HKa85txĂ1 N+M?j>#`mI `68:4hv?s,15wYhq.wÌ0eҤ=xG+8# VJ-YK!wEtAce}DP .CB> !;$S|uKTEdpLי Dg4`-5b/dON_VS)&l]"~s5 p8.ݴ R31ŴY)oQj?`,k}Y66pI .T*v|IoJ=/ w~!ig EXF(&+,V!Miqggp+PU{TEzP Y=d1A= ZѼ b7_M1 7e.#8cbF+ш-Cy`c%M3Z6N/hլ` \1:n5p*^0D O]s,YՓga&18}#Jw DHexni$Th`%>wы*o-xsÈV֎#SS2>8XMvPwZDgf2/ :1= +dexv; ӥ:ƲY_Pq9)!{A+(/QF].sJ6'ʍΞU(]EhQUdEd(|;pL|ycm`cI>AEx`1Ȁ7-f -&DgWh_@E}A+4_(dobKc=OcymDoʎ@a(6~`c嗟`M@lmqGJR pQ/AIE,G)O` ˀ-htF]`P)jDgIAo4_톉RQ,lm'J*Җm aV1a-AE,Gr*tF)Dg5A4_5$q8Τ-AE,Gr*tF)Dg5A4_5$q8Τ)͠-AE,Gr*4tF)6Dg8A;4_5$q8Τa_-AYE,Gr*xtF)zDg5A4_5$q8Τ-AE,Gr*tF)Dg5A4_5$q8Τ-AE,Gr*tF)Dg5A4_5$q8Τ-AE,Gr*$tF)&Dg4A+4_5$q8Τ-AIE,Gr*htF)jDg6Ao4_ C{7P[-AE,Gr*tF)Dg4A4'zZ-AE,Gr*tF)Dg/A4#&!-AE,Gr*4tF)6Dg-A84GGmoovlmvhd@Fqtrak\tkhd@$edtselstEmdia mdhd< tU-hdlrvideVideoHandlerEminfvmhd$dinfdref url ETstblstsdavc1HH6avcCd(gd(@Z?jh"pasp stts(stss-(ctts                                                                                                                                                                                                                                                                                                                                             stscstsz -F846;0d210]442Q42-\5/3F54-l745:Zd0Qi>i~K*]a64-c.z|ss|2-Fh02Wkt# "^AZ/.-S/.-D3?^wW!I-K0.-V/.-c/.-/=XC;O:fR1AC/.-m\N.^y} xuVv[Yx2a-0CCqv:\]g^j%|_KP{x!bG184:4<7:3:8:3GdOWC,H6q;=5N3>/~"X !mgPD5R5<3c6:5?|r+ `Iq@il @:8`|UKPzZ!'KT`l8=_\=HQUT=>B3:8:3_I:C_* 3P2VFC?6҅\=91pA:7YC:3qC:3n? [sFS=4A:6}E32g6<5 {ciRX^S]W==mb?biEo=41E4:5d==8D@:|l {gbr`\)>TG(L+i <~exBHT8?6wO8qyH`4mM_=1FNP:O<oi]4Q D=1t4<6U7:3L8:3I6:6I931G4:5J7:3I8:3I6:6 ]?(D6 \ZbYACy?MrHo8<3S8:3L6:6T931 ;B7gn,{QK;[3 Y 0L6_931 ^KrZojWF5 a/R#G/ 8|~X/ u`#e\:\;B:J@54aAEM@54?793 P5 {^HEhdZcdo{;83g5l92zRE3b9vC?51V473@;317P<5#SL=-Io"R_*nGT kBE_4:5t5X z*$u 9{lE9 *PCIK36b2X_<[LD61]\)9Ve,MEs=KjMf  MSI4U7>6L931+;: f^K93A5:5L;:5@8:3@6:6@931<4:5~77DWV>P8X5]7:3{X&TUebU`5P@6 ~h? Lou[[_<6G-K 68r )[d[BK7~65`~XQ;W931.61OQ0Y1./ t"QfmFYMI<85Yu6aD#7 fO;V5 9<|)^B<131-M1.-91.-91.-<1.-91.-91.-91.-81.-:1.-81.-31.-1stco0budtaZmeta!hdlrmdirappl-ilst%toodataLavf58.20.100RaySession-0.12.2/manual/en/images/video/patchbay_simple_connect.mp4000066400000000000000000015123541417052567600254540ustar00rootroot00000000000000 ftypisomisomiso2avc1mp41freeMmdatEH, #x264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=2 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=6 psy=1 psy_rd=1,00:0,00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=4 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=30 rc=crf mbtree=1 crf=23,0 qcomp=0,60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1,40 aq=1:1,00Je Zd"q 1DXYkŶDy-]m$mu@ nݶBLcA$q~_=xʤdeIhEFr5/TJS`*py LB1hؕMƑqYT )jݢ$^6 {#Ca ;W2A33OBH;}̆0F擑ڕ(;"| bx17^BHYǧ,K"mDQ@J|!C5pm剢-iSayDxn(޲wp HܽYVGaݲ*ZbƝm 0-ɑ@OiC ; ^6x sJK!G8S&yRjF' j?o@~AV <\9/XhH{a7TP8Ioft1h6$=?\*b#!.'4fSЕ-^\4clP 5eK C- [3-7M?eP2A"V6k2l} ,c _Y 7ibQ$U!s zns޶$c'AQD.wY>2)=[ d\ST YRg8E2ۓ),VOBnQ@+;?݉nkڏعuB$',%Vp+ˀ7engB2"'pQVsv5 | BXH@ 25Zʉx_R˷2DQMWw*ԩ, _Ry+ߥm! Ehnue+WV2:nCH1)[F߾Q 5|IO89g#KSxE % =6.WbD4cp}B|yT,V?i7uBUj R̟wS^5gڳt#Zk&+Xs+2 yզRdwyR?zݲ<^).K*Hf ]^︓"l6@:8i+'ogkYWpk/m=.UZ`ikWrh 1+}=$)s*:^ qE\fM+<@Rhnt-Lp5 \~]`5 !]ەaH2n:*wǂBN V;^^4$Vpx8س3IՐMo "l$o@|:NT+qao ͩuf&j=W;VlN!!Mt Vnӥ1[~U(+ l= .Tʧ ߈IB_U 7QWx`I-&v`:ZsjnB1 =|oRG+X]L "Fz xťdhY)Y 0p} ώՅp?GO`WcFPZa"!i/Sĉf6SOڶEA)G\[MꏻiW*p*./ފp&gRS4 PLxbsD_ #^#M C@格4n=P/8"[-f@2Z<>@n|/kHQMM6ިfFNn zDh9up2;*iv=ǚ=Ic?I|Ń3WA);d CtѽH{/zdė>ɣۛᨻ?2*k=gڽ*ϖ֑ïns_E~ex9GyN JsM m9krK@r~:jS g}ٗ BU]Ǡ$ FNj]l#M?]aLpJo`<ĀɧcQ?Px.['A 9]WAtop: v^-<ܚ*;isdX/ HrQޏƀ(W?-B.kFn8}k|VYu4!VhHhmt'z]2z3ŷ-[-Cdi2J !)ijld]]P rpZ]g(+(fN~. ?[y% !܁i^E1oxp1Tj DpTdUx[VoFdF4[ގ~G Mk_jO㥠SثIM.2qPO#wAKQbBI^Ttֳ d]<6LRX#X2tP3/`Ţ=" v5uAn,֟3(M$JFd0 -SJ>c 1"B}Uĉ {TK<IT/s}>a;88OdO$εאJ  )oayr:[49)y{ fvAYY@jutprC`kwPUh)?Wr4f?s~]*6Rf~cyGcKu p=zuKk:K/QV2L&bq ;АnqY\WobY0a!Uh6jxc2?˥t–&Ug,\B+~ԣ7LB?ܒXu Gg9*+ܱOe=0Y9;hqA -^ؕ˼!.>^[n 5.ou o@sSl8)5j]q]W93DG6 Kնr>$o \6$HL;ϘDQ@DYVo(wDWOE*NS93}]M?Oc1 (nicWȨ*#'8w' !;S v~LbQBjɉ|: Odgbdҋ fOXğʤ^0$شm4&d:yO|n$,_:VeWAULzfƏ%JDRFiD nB]||=6b~[Ix#9GIpix"zG!YŰ7lgAJCK)(vKD `kz-}2PVW,[~@r*5{a8fkuN@zRK}p_=Hş$KPJѫ'!xjcgn2L]hh+`K GTeE\/- # "Ro"!y󺍰idvFd٣<:voKk֟6i`+_)l7UũaUo'( |c[@ Ξ+  N]^fR_K]io8QwŒM^Hgͤtk&!ۃ(%{qDJ%~ "E30æ:xKw >hVKrjv\5z/45͏' ->ǯ9S6pS31ܜ˩Ynny2MnH+=U55VdɑEGƗV9Ypg"M: Ys;J5%2QBՉ U w.fm*χE  #~k &5"h(r q,*6CVJU"gLT0sm%GhuG=םv_8 ;IeۏZ?_V xTr^_]H|󆣵-pahK`YϿE7jd3+u?lBpK[8;>Vè>,WhS}ߵap%aArKRNGRi&*|L& A5?FnP2S\JR2H\ E錗a=<&YeiV-JeiPƑ3)ͼ\l؊7갈s~.|!3BM^y\M M|ijs#[]YQߛB"h* ;XOg4deQ<.B'FNYp:A&QqZ,BY:"Y2ЋN5פhy8P0<7>H{4;K-gJ\RZNjj4D#HVڌW.cajWnN &ЦNOIKySUz=7?pHPB9 9G(VTz|'oZm/Rzۘa3uƉ!n5Z{`[[>@O5@F,"9Ih&jҘ В}7x[;@"~rs! /ޒR'e\,A G8lkA{;&PkǚvEа7-h©k+O#cY4cN]/B)"IL*6P̻1ihbzf!Q@*١n2ʀش6 HT]s#s. YlcF} ܔ⏦%xD`"_$DYPpxEWdWBff@$o_]-)f3PAUhbh؋jL7o!'?VIpEdny"ۘ{2XQeڭ+P`$vǠ iza ~ŏ[!R8KyNT jRP(|OV"8NZҨ_'6#ݐ gk%Ժ~B:W=ˑI5b̀Up{0.ar(;k: W,̺=3D$IJM<~ e&8t֟7TV>˗:IqH h.{ަuM /QE=MUq<*a Lq1Ac5E\6g6?|]S(95}ϴ>˙Ù8". Qy0Oihɩwi%ycjcW/{WbyӍ@_ )rذ0-.i IJ0r;ۜEx8y< Dq}pdÃG+_]̠ @G0Al{Sa8!W<%JkDYO.`V~4FoD4WsDYz=sEɚbpfpYe$XA qk YNg&Vbvf6ljLӬ*XF95yI kZ+! O~cc9)!H ul@kx]`·P+mv71*O^K/ANPtD|P驐ohH2֒`ݪ Πzn$Su4jT̸Ҷ䋪>י4*X = >ncTN2,p3=~bx`ni%ykze~Ycx!cD~mS[D_F<ˤ2וu9p(K[ Aq#/8CGw]+<(^ FE]T RST3A/G{iɼ96း8ƻG PQū/|[ҬM;*Ơ8:)mLRҰg.uBKltZe0dA}_9zsj7iބ 履'"??EOf@6I%Dہ;(eͶHsL%S1͞1ޠ+왁%3vr~2JW&O&XEH Qb`"*NR%#%C? jH>tbS- g L5a-ZZnR(q^B CIe.*=dYuMDž} z4u (ſwA4\n6{ϜW܇ʜ  /Ay]#[TҌ_2ʞmCᶗ !. y7EL|%l,>|Aw!ݻFl0%cLCD5Iq* 7Y7pq߳?VXv?Q7rCpg ؂<].ڝs$vU<5H Nn2R?|s(]Xh6jE'zm'ԟ+9]Hʧa!T)CNa7hM l7(SUOuT60Cl#u[?70`!M̢{We$!j/o[IR\N N6Þgmboxds-kggwC9x%j]ODvNvuC 7G)xEso!`ƪ dZՊ6, /;21lg C/xN1djub\>B\iEgCgPg(y5R(t!XHgD;' ww[ 7nsЁb&b#2 a§ۘܖ!>)G9iJEn3N5ѩzc1k͍ L7FLK'%Izѕ;$u$7IiqiO"GfeF:,n#dFIRxa/Yr\k<)#4R5ʱ ;-^F\j(tӑCh-LQM%S!I5t`Hwۻ.Z=&OtWPi?2Yxբ~ $AU%T[F8A.MOD #-"<9=GAZ|VM Ν*Y\%".Mpms l~m̝- ԹѰ:籬>(-UWs )mO ȶh#DO k謿: CAӔ<ټ|B^DP ,h?e!jg(ujx`ށO-Cf*T)WuO[vMxV^a"XH/70.NurOɡӠ z4cAϛ$A{V}BPfٝYnC%Ͻ|ɲUF9hܺY7%P$gGk2dnڭ@58]%<*ۀ'1cQd!MbtMӬDW4}f$sIR 8Tm4t:Η a#t;фb]|Scr2Z@MGVрa/+CUu T d9BپJdMzGͨ b&m߉ihgBvN8Y>=cU0E@ƒ/}e Z( Ob(ꍲ :X8K*iA~ =eLzeCSa11KE q|kbņx߃GxТ$UΜJ.6{zM?3o$h{_/eGO1;Ned1iP%V !b.I%YG%^dGꐉS=-RJQ\獪,?{v%z j=o21MR4:!8EƜ𢸓-m~I# MCq(ʹExoc0H5,ZU+K(=!cԺ qiG/ TJ+4f|e*+'~.!<7HY\ή$ĒjpCFv v*V5P6 2`Kn72e.j~!8Iky#@P  '^Myb&. ,^ ԅOF3_LӲW2&H2 EЬXx C|1OD' ĩ3-(n_J,7YoH+Ƕ4VBbıQ$A߫ױ>ЯLyOFO=~t[&97Q&18r}:lWG%NJ,95SC*B- i.ulK?' _ER_/0V .<@.sڌ"!n|~ kM2UԴj£i#U-y Fb~qy*B6A7$&͜ʞ!<81EAX|)/-EHRaih?bx svY/+roJZ h2Jѕq;f HHp^9Kv.0eN<`/j^ڗ YH:?]AǯWT6KOc|zെb^${Ǿ3<*h{{ : y =}>=V^}S _]3PÉ-]W,1$"@ݤI%UpBZ ^~L5+Y(#zTߍZ0PS)c0kej~.@[lޫ'+x ndןf +(b:ė;PT@o$u߃uZ%u,d#.+b48}]0-Yly Y☵0iw'z߼>i* S8ru_zKIݐwq̀{ڠ/FS^V6 7B]NzȬM 3Q.m-{ ;hG9јCShݾ~ \78bg@3kоe_OMZ,hzua}[NxN:;~O$zevH' XqMR-aC~,;)E viGY0egtԇ_lCzh}+rnV&'|Y]=,n,_X}m*tן0LR{0W\ېqCY]1o605GF]L$_>X4Qe3QQQ<|}uELJ%(sFih&bPy&\ fs` \ PSfObvnwh:(F,!/.uy˩/r/R %¾<3/=w2#J2GwÿY"02Ә@:s4fۺ[0@;b!c%g/2z=Q0ou Je%J ]o%<:b%1=P('mw~ mB'gof_s[à_><Q8y*^LuS>orC4tL:Ϟ~z:j^'_Eٔpޓ|zyC@-\I,~?@5 <3P=O<!?nYߣSI;["@sh}%jLy1Io{(M?@ \f%ݩA+EoR~dJ,"c/\a#݁r-4 $4l+x nIw7 2ve}v 9 hX.!1mYLm8ϧ3a3겉"o! [} [$$g aĚ^]2,rgyTpi@րe(t ;_R2p !Z)MCdStXb o9%#=tӨɓK6~MC_;A{ϖaݑ$oIpf ABM"5Ybi8/%:!Y'1b½iƣP r_jN:zAe}h=K[O01?mpVzş>_I1k&]L[>TyAao= na BN6 ;4Rcj0w Qo0 @]U`tPui?13'ޣ(ox6Tju!&t V7F:S|!CщEF,K2NFriJ\ݣvN|$U^.x2Qʼʃz8B+t-c $ub{WgBe0$_:t>(Bժ m[=_ z4Qś!; }: C6H&C`ȗGƽ3$D qzl+m/H$S{~ć Ha rgy]nGL:y;AQ Ҵʳn`'tDDu.Wﮑi_,G~Fz7],|n[Ko LxqK=C r!F8=YajEl/O 73\UR L%u%@]..<)oJjPk<reUѐh~[|yaR ($:bha2lη4LR5;: 3KܼIP/kǾ+T+FkJ]73؆.6V"flw tܛniJ%6'˰'ܾك9H-aD. 4$+}b8mV6 :}5`ib}"b\4+؉a8RE胝}JtPD-ˡuɏJ_兿{gr.^bMU~ȁNVCb6{ZW;]slhivnґ<C%Ś8&F!i GvvENs\T]p&8z([HkiytM;ðAX]قǛ=b#ٮtM_:ΖQ`M0UU1 T !y:(v >] ty\嚔?ɹ=z]@\Z@)*to`EnuC SoRc6/ҋHHuT(1J} tX]Zl+>d 9qOT ,cLiYVxZr5nn42( h8 eНIm8Kd`-OZBxL }L,<-T{okSN/Ru Z34vQaap6(Lz--U䇒X&Ld[Q #,ewM(=m;~][0xc9VH+HT"4']; ykM=I4h8L&/mn#!9γ7XwyPQ59G&IJ~^]1jyYmogWk& cx7TfW;DZ?\@f* WBĖ~9aH pfyPJI A@-u*Da0hhTRL2Rf51hK珳YM!0?_%>,^N7cqqeeܮ7ʗ-#J7if6҆BK dq84fj3Uo|Z,MD${=U{1jBJ̔gp8u||N;ka虾0ֺ|`r.u7{m\VЙ!:mω . W9BD`ϛ{w TB1q&L#{@A*nR>7o5ܪWW怉 7Ȳ¢́3sQ:@$az^}r2S4EX#C~nAK˯`)qy܋eBA-ASS.:2=2*a\+ wǍ|neor&> ͑y'DOиFbKA9ݬ9 /&f,TV;|Z=*cOO;U\zhߋ{E梋ayEJFmMbJN:njDwHɸgHRT?N[F3ױWQ@'#י6e~-NiFXX;6; ZzdLܵu!M!qQ0u?1r4l&M4O~Ƨ /m v[cN}9ʢC5q]MJi,ӌ:sP^W-G o#Hk&ZHt]'W1ac'MVd@QEg'}M5 3g 3$& N_L1 m?5+$]5v~J\pF QXV+J^$aRS5kx(wE aeezV<? 8_BƸ&UIBĀn-$di{x*n.(*n~4gR*~9$g=ba+:"=?O逗L64Pm1 bEڴ7~~_]ܖ8OeshWS>yaHזnU*ӥJ/OA`fK}9'Emo]reo:1/A$lW+0ŮKMs?3#Ca(.wp|uU(kHw۪ 'EsbpH0/9wjbs|z26)%CW6YH@{y}:Qc3+P$XJ; oGad1FTS4LEj~@5Xl=!B}jCWrN;![IuCQJ6%CmSŹ®&߇c5՛tw.Gbp3ABxLw!y*atF)cDg`Ah4_S  Qt/uѪ4-^^@#O/pU@3'!m-,@9>M`*1AE,GLF^u*tF)Dg[A4_f#( So)$3pY?ēTnr B4 0֢N '>^sxQ@ 1AE,GL ( *tF)Dg3A4_lp=`~ J1AE,GL ( *-tF)/Dg4A44_lp:S?%`1ARE,GL ( *qtF)sDg4Ax4_lp:S?%a1AE,GL ( *tF)Dg4A4_lp:S?%`1AE,GL ( *tF)Dg2A4_lpk Y1AE,GL ( *=tF)?DgA$4_lpkoO5(6)w.[EZ@Z=U+!.T?:! F;!C#o![DNߛ+D87T,pR\L5C0!)kB!gEs)(,!9NzKf9ABE,GL (JRS_+=j I2atF=ȉT5qF+cDg5Ah4'_!qM2AE,GL ('P+tFAS A)DgA47vUG[gšd6'6VmPS#giרMZ icsTs _>vSG{qӥ1֫դ`"MYg נAE,GL (ca4xu(U^L!5,oArNq(Oq)cT5 } b} b(Z%$`kml&#p 0tFA  B{@Dg@[ a9EǠezϺf_ L\{|꼅 Y-eK{Pp%x$:6dQ5L- י]yHqN(L7A47vU\m=2pg (jJL9- ea)ޭiڲ u6x&OchnêA|mrIex͎8t{?0X xѿm9hOFA=_!Ut}`oONd/20Z 0KA/>L_!Bn@`5I֗x&|U )hAgJ97YEAQQ_!e(@ 83tFT;JJPl3Dg>: =~V2EA4'_!L_/.ΰ '%]"f5 6AE,W-F/87lq3Dgtz$I}. }޻dPq;A4‰lpkR7z#a-:DguݢA?=_!TtݒM~X\(&`MDXZ}:֣>;"[>LWv7͏Ȭ"SVycጂ7}Y'q;X/vݦ~RIU>:aa0|tF 1-/~DgX=P_ҠLHAa4žO_!UvK`IXaidXqiA++lp:S? R aMVXǘIJټ05EOѷ_k{ %@]F/$RoOZhqE$%l1zKlAIE֦T%Hd7lc9f+qi Dj!Q\@[ cN9<~DmNldA4_lp:S? :%6a8\%Te 8Q@4T@5@B@ErBcW){]ypo+<ͼz{hDFb3m"fң[{2 Ff3AE,GL (25 WtFycwO# 0kq+YJf&!3Nũ˽E_m)Dg4A4_lp:S?%`1AE,GL ( *4tF)6DgA;4_lp:S?EZjGi&*?Jn/ސ{iIU2j{ LSx2IFe#ε b\qAhu~K\ǻ)WהhOP ˜XcSg3=ӡ6e$^&J.}JS@AqWfAYE,GL (<݅O=NX*5"x 9tkj1fT / @>;],xtFw@Y#+zDgw݀(K7A4_lp:S?81AE,GL ( *tF)Dg4A4_lp:S?%a1AE,GL ( *tF)DgA4_X~ +ZfeF'D%v GԳI8R ɑ7ߏ[(Ƹ 1K\RPq~"oHI3D93@jY$= -ndKZ"VQ[WnU줦LBgD.ۢH:aqyF(N{<ד噔*|57֭=(+ay 0J*dAJOxǓW(GxFKqb7L5`|94=9_|\"z#Qlη۔Vb;fHrMm숨xgCYR6fPpG^1 Vh9ʁtEC횂/l\TnRɓkV49Z(p,^{3e{ qL7kձnz"aTf͑IDpRL1_^'k;%TC"0!_EUt}^W&L%3{Hf?ۨ5_/ƍA#"J_&ڑ3!o5{횎q!v[#/:gE<ep 0dOTIGN]YA2&Dg<=pWN<A+4_e!haW. {)ㄻmm3Xi_P e?э//Ts{'i'v2ۗ._Hr޵EwqVԪ}&KASs.uuÄڿ3Ջݰ;>+>6s7ҮHRϻOFߌx>'8R%` V&ǻd)/$ 5r^' 8n'!H]P8vo‘~h;ќ ]1`AIE,GL (VOW>D:qf Ф9 ;-J6MZDfrUD>f|8ǫ#U|C!)ȸI({0f\O ,1oB*9T`xۅxfphtF`,&1ƪ/g?x!1B)}T>n@vdUՈSKdddo7dupyHErjDgw lNl o19ٍNb u1vwrp#" n4|xdxR@Ao4_eSH"2a{_mPyyW yjYԊYή9oMB_!xߘÖRWŋ*K6KiAьZtX_(AE,GL (*#) Ջ7ocH ә-C!!ɵT!1~pX& "LPaT#9N-9􄣞*g/w yPG=-hn Ӻ)J |ߖWtFw"6X;˨.N'YW;r]=… i7@%q 4h*`*aBDgtYL,#J:ٿNyZ/:bAYA4_lpko[?>IuLfo|hZn"U޼S}W1J5صbXH$U\_7v^fP$(HqpeT*9Psbm5ɣZ|\yw[x,=lpMOt(eo) rC'L9?GcAAE,GL ( qCC'JIXygh9bR \mLUAӇV5jP.¸DpeZe y&uP0#hWv(׍lB0 (ʀvtFt !K[#ɻ;IL ({PxKg8V.y<&T'ti`F`if` eDgt{cѽqȗd}Z.wD_K; FLY`,->Wdťǰ9ЮSA4‰lp:S?цD jӆ߄OIzɆӾ-J!(m{.??myg7b& ˘- `fY&C+芡oec`1,׌1 57MDgnajp0x@u{y]To*&_2(A=lpkhQS}SYz`64UWZ( X=QGXh7E*F86122]apV9]7>+<t_oM[R演m3hn4)A#lD:Q *OWOA7E4LGL (qCяkή!yPYٌԁGVtFx zؔO`29En !:XDgx zN"1f+@) A\4_lpkk$؏v o$ QotYt!D8#aE}v JM]K."ϱYO07 )'-v+vCR3'ΩM9@-HTpi~({5'VWR -k'Z.FkaIAzE,W-F/ɮ3|^NM-ް@=Dgƌ:3R]أe<\\TA4_lpk;eۀ\x{ ޞ/+Ld=z͒,̔~pQR>dG)yٓ.y@P8?rFS%,$!sy}@k'z/05]؇NeO\$Y#øӢ񠗭m2Ql84x՘êCz(.Ɵ4z%?4$4_qvxRq HexB^ { ﹇ʔh,DO]r½a Af69ʣ6ArAE,GL (˞FpC X~LFn78t4OdDu>2Gk0}ϫVo1qRђ6 #8DtFx zO˵2z芟@z@|Dgx zLRKಞP:]uu(s|дLϸ)i A4‰lpk@EVc(ZJ3seT [dh4߲̝F#$ #?o<ܞw%!RU~6~B[#2]#zTi+\TYpqd?XIh7 DLgkf_EFiI<\ pjLLDgIteZsccV< dji(!A=STHtA2SzZk"WKKč{Y@dܝɳD (ok@t;vi9B"iqAAp5഻!=?4SJZ*w#n:>/]< <̶g;!F vyξPYj+1Ɍ ilhpᣦcڭ=A [D M1Mq郡Z1V(|8{:0ٺ˹KOeS<~eEѠ8ÌP^daf!>ݷNɞg r.BXb{ΰ+)s(R>rw\وQCodxf7AE4LGL (@%=:ֈ 3\'ɝ@>ty %XʥHkth g-v ;wzѦ*QV#tF:(ooTuF\]86SN>z@`<K5 mkVeld6I+髭WaAռs$&~u)-TDTden [MML0P͋L26١kR訄K| M0ԃ -Ōp(V*$vZTKl `Z&p Zr>,U>Ef}3=n˾3a!p%3dt[=׵͗Q3 8 ׫jy*sϔ aCd:AjE4LGL ($y}HW ٬A1dxx{ib_,?1I%qK.w/C/(/B Is>{Ag잝N)^^P@8v8EIZyMaky)/7AE,W-F/U"N0l`2~vƭabt *e4l L' ;P9z~s:,[Gtкhi ( -Xv9v5_Sk9ָ u3cxL5t妙`~Dg p8 :B3㿡*nWr<[`>',ݧ~el3HVuKV#Kc$ʠ>6aA4'XY'1&s4M[bc#kx];&XYŞz,4QO! dsԴLIBzt: q ry7yH #QYyw-) 5H(iAPD;TwںB:U֡`A=JNz]IN(1t7R`ZSt}$v?k ԚnL)d,-.ZMpCfd_Np'h}42iHnZn?1I9rv+[6K]xKe r -xa5Et.Q;sj;68eg?Lm{SSZ]QO⛘%2lDr4zƐmp; 0Muc[) {;bOI~<%f\"uct}̽Hnt_\La*umu% ,S W"~x7@#XRNi'DyׂfIB_qi2DgmPV O'^ujZasj\B7$5s+#w!,jCygT"A6$!+06a.CL+!_R5S\&CqS~+T!dG[.rAQ\epNMXcYwUhO0MzYHكKnٯAhTT3Bfvتvd$kSt֧gw݃wzDR;O|jx~_ر9ÚGnZIie\A~ E6Ar~׏e( ]$-ViہѱZ&ATELw{DP`:)-QJ-Ċ/l -z00zCIYgF X`V?"5 |&Xe" PSۤbbG!ÿ٬"p$, x G" ƫq"9P>ۏb}zIRwD)E )+Tn$zd& Q$weF#п젎h\Ӧ B!DS}}2$SR1$Unj_2z;j @l< 5N9i98"Uɏz+iP/!bB~AE=JT@v ѾFMPXÈs(ėS`p-m切oA4_7.qXpx?EMTUHƔ#} C"ԯGX-5ל {!yKCbWiIO Zα}hY=JVLgˏ,I * A3&Ld:@@C|P[\Mgfr6. l{fk`wؗk Ɍpoq&7gj9FGNe ewsm@dw6y挔|$AE,GL (39 %vk['1}HBN:'<Hq25VDov &gY;T~% !j'I{O7Fҡ CcTgۼCy.,KUwSBsA ʉ\VABjGuq7ム`eRm+ؕ E(59(c)M`;&i=tF'֐+6Ct>ꕲmZ7S)Tc ?` $ks=ZKoCֲFˀh?Dg* !iKuY\PP/:%g*ުƞhB Njl[jʰ0P}O )A$4_VF=8 ^Z_v3q[ro$"QCZ6+W{Jm7;!cA` ^:xZ@d3>M]̏.V*Ӳ$~8WyɃ\vDKFCLS#SʺXW1<1?dw]7햌%S -JPeNK| O `+zX@"h\ZN K 1!fuʘGu{$?!8͙oO7:fmqR,88-z5s8)?D hK1gvG7|<$*8 Pq]ZQw^RS$pffn}ki(d,e9<`ABE,GL (_`c/F!yU1,Ĕ:buoMV Zb Vpc#џd}vqt9c+PF?,Կ֛Ō9+/Fؘ= ̿ᗖ|0:_atF}{:^ٽmKVQe\1w?84Z6GD9T4 }C^N|cDg1%zey8\ gxD/WY&y6u43桡!|E|9-D=|%#C;ag1IaCiAf4‰ F ~ę]h \!\{G9_lFUy}SÕKA*C\HdIZ$/W߀Fb [Ovw&m4Asp-M[J0=p_5$ *tU󲑑~WpgnאlzRm-H6t`< ّeUS]*'>IRTg `k툍†ismheUD\to1E`]\K$4p<\:ڗ+CꔊnBt/bE ٬<Uƫгв^,UAݺ k2 NPb4?>>=J@5ax!W`22`$P9A=;5|Xs? tU^ "ZlVw2=ͯ'2 Ϣ}@[N Gο۠kca{q@A5L o%VH}/ImMglLD#4p'nCO_o.K7DU|eD`M$g%|VOS_ﶨ3E@c̀ycOR|Mz';AC׀ʑE y( p⇭ rٯ 9zpǡXpRPąG@ޫ4Lb/ƭ2:w^Ů7V}ދQ lu3%r0v(\&&t$J}BbEmr&@ + VK@(4rӹ*I:hyҊ:i4`g é [ 9YAA4_o:dcrz&Qʰ' RÐ)4\d8skLpMUDπ^m[/$H 53׮lR}czw:zB [9Rij籘f8Z%Ǎ䂅m[ym;^K=<&0| 'B7g&Q#gK(Z"Q G0U袅eu@\10݇F [ʢu meeZZnM$t}>aWrCvϮ[hgWKˌw\(tAzR9wpL8f KX:t5UMP|nBD-oƈ;j ur4gE N(lŝ/Y0)ƃ?^y;AE,GL (uq10 ~M HMܻMϋ#6㙚<}aQE !\eYnܠR?q.q{-f xb tF_U 7ZH̳C@z[C/YaQ?/ Z ŝ %lRMU ϻU ((i5LhK1T.V۞&#sw0yMC1E$HeIS5RDy0yAtE,GL (!Ȧn>1ZP>s,--r.l/uߦ@=?MBtNʜʀDtF Qǹ])"M0]aijFmDgMG/wF QZG}EB;ݻaN*Sf]޾:W"t4P%0Jh0A4_.S"tTF/oC h1V&ٗq1z^{ QW³YǾGRg<4_5 Me/uhм#BsE&'etm/ T=(RA(fݵsf.u\JB1hKL)]!JHXi )Gf~:\w ő|]NXX@/>o"k9w PG^ b69րkM&[$_ijls󱛎 7)o1{ 5,LF6-j~A0;,^Di=f6UM ȹ}z^u}XD|uOp@} XQ51 o!nqƄj2RAE,GL ($*alŚ(t5 <کg60fE0Fy5\Tm`OAwT++Ўԁc:z{ 7 |a 1{Hv {W0wU1K:,ћztFg;1_[q}^ce{[Rh'S22@ E#@,$0ߎX̀ks-Hzx @ L 0Dg@DndB6@[e IݞR;ԫ|S by6k0؟j!%OCQ ۍ!றũģ'mzXKⴉBe/5/A03A4_)j5kaDi# 詇M av[_udLhY5?2Y_#\Wl<7?O<:էovFFDo]C02A̰w{Hu~ٛdvVaw[wZ)C!fXE"?č9㰩׹t*T/"J[<#*L\8x(,# 8?sPW?^111'hÖYʒ j "d$qi`Z7$ i>!5s=̢>x3nEeH@\wy@c9 19ȥYխ|uC\aO/Lw? (eu@Ҽ_ mZd56qLiwZ젨LGp1NvSkq)#cFN2[4Cd.%pk5+$勧J/X+6:I_e;ZhLU$UHZBK>mly*V~ZQbeG_;R\[hht,шᒃ  :^h,ӿ_N9ayl;KEx-vp&AE,GL ($+i"G3VEY/Toe91 'iO gW2d.G97bU+OӴ=/&>r-]HlK'UfÞB-BV˂SHTzZҥ0n\5 WS@N[Uw q{@$DNi9QIDg>^%f F6NKW0]0IA4_68[ j_R=sw5زzm!raw1;8lvO+a}Ku o _Ҧ1NZ;>r'>8FT)Vq4{"Zm_?c}mggmYJ>\Teμ0ܪ})N”Vq_߈_rvijW{#oCf},V]p#6O&VK]0q&jMd ##HD]Và8{d;?\Ȋϒ{9S)rt9`TA E,GL ($β4Otb!~o-HLХpR,_tF{b>ADgϡ17 MIUQ` %v rF=jAF4_6$x<1)L dkk,N}Z(B*-g5hZ;Ӯ$@E'VtF6%I1 +bVn_ca~H*Dg~;A4_ y~c|\q$l2AE,GL (4` , tFmBY) Dg/A4_b%1A0E,GL ( *OtF)QDgAV4_ $/ kbM윿"Eb<@Q~^#q)bEqV D|mrF 4$0#:^m R/M;! 3dҠSdDr}Bw dX\B{'Z8𘂢Yv ~,G]Q4o?\_TCӠڮHdM4UXh0 4AtE,GL ( *;*tF+DgϹ  A4_RQê*l6j|| e#R$ICX^YgJ7EC@[V'yǟ)v֓zz OQ:/;d/Ov-h9]J؛Bmڷ7Gc5ϵj{( aeT [L">|GWn8oM&n+f-sZ}䬚υצYG<:s5"i KZClŹm<ſ-:4`Lbd)9Q@09e{%M;n܅Ę usZWdcӁ?v΁7 ]ɝ1EjP:ҼKrMJ{"fzy]D7|;?!ysm磋 ն\>-*,J G9<,}rTӳQ퀗IF?54"@- lz]ͮ"IHm-p%éB Fĕ!#0\waSgguv 1Somn&J;PԮj!~2z^DVH  %]P~,ϗ >vX 9t-5-ԇw_TKp($%!FNKrZs},pJx6ׇ" o_fǧ v3󁲹㡼^ѫ͒l+^Vp*t\;ecNȾ+d d'ZM4 VN48VkNgHՁJh3|%r5z>6h'\AP.!/!ARhs-v% U7 d=-܃f'g'"N&.OI%t, g p57![Q?k\)S1._w);CmAaL0-ߊQmtñf.YGu</ T@ yG% uԠB<"3a{PfJ9B f1+-6] RXTߣ@>p7yo+ Z%Pfxd 8Z{Q[|ʔ.~\Nq`n{OJ<2P2MXkuۏ2&:gfk%W{bq#f9چYI7_#:M'GT'-OCMEYtIIP3m:DmE8W0^NGĸ?%Kv_3Vdɇ鋺xlW_tD& &Qh^Y sF4R|qȉNlH\ ylU UP 6o?"U=>®m tY\ϓrKész_nPPNeV/T!ׁny^zVd :J*yF-Vd7ߙUTeAH(F+@=I)-|6#'| p]Dg@;-,Ⱦ^ؼ P//vD蛛(bjSvYSK0R=N톈Zbm5kOd ӷ؝HlpZ69N@x}خ ~DnlBԗpnM{y$ uA:x^t I9!-@ (AdE,GL (a2O?JI>*5:rwI4(Hm\aW[Bh8yE9^m}%"PMī@v-2nuDM? ZtF*6-sl} 5x;iiIU.ǃ^`7Ҹn˦Vd tSkDg 3$$©G'G[]nCD3/J`6&"#HQ:]qsf;?CR-`WA47Ķ_StOE¾9cA$֓Do#Fڗ@L^j-ϣ#( S*uBJnWwWTbc9E[aPS䛚K1#ij# A=yuGg'qa)h"ašƐ`<ȗB5jQx|8|ѿcr6 WOHlYoſ.}bܳĺ(^\$ɽb<4QA>L X;gCB}/fUͣy>@jMI 'VY5AQ J3$ . Dgm(8ހ@A S8a~ L=#ox 0H105,Dg=0d}A1+%Ѓ/GU4c۷LL# N"w.ҮwS+:˴Mrp mҟEO$({@eZ_WAOEt?9)q~,G<= pyyoG) Ea!==,sL_JDg CK G}YΪ ?t=ds>R A=p/K?.s Wո`,ߥ2~?R skS+0\Fz\sbHv Flʊɲ;S͜{%o'yx)2USʼn!73 KXVY ;^F{%|O= =AE4LGL ( clnu]H d _2tF[}B`M/Dg5O$Ht^85A4ž#0b$rU)Dg^/e/%KeIuQ:7o}C= >t h'ns֗Y{Wv"_dNκ[XV<܌`Б_/,A^:4ZhѺu$hc8wkK/EaP~bsD 6,XK\P na,:EdRl: n04+^m? y -8}w 9&@ctirNKk/V@䆳|p1nS"}9cFV[xRA $_b(@*2{Ѥ4c'Ӂ E%B( .3y:J[ZL+pwA^Zj xC5vݕ_vFhm_kH(QPBǴM6C <djcr.ǛGoI>うzk/yCm`FbNW*7G,K< s;9+ x{)9Nu ȊJKM?~Υdnq!"tqb@ MtqWͥ*܍1&_Pu: c9S,ӄ@$yB"YYP*r ȱI(6 f'GqSϟ79QF r%Of 2釘䇡ZVxine|_=\/s`}jqǴHqtsydqD.36+~ )cikv*arҼIuFpsZ-6=פm}SRB&b',]6mc'HGuf 7/n̏t_ r-|2'㯪Lf"K Y oCCy-4: l-K0~8goF˙]m hmTaŭcuónﵮ bp?860̥(bK&Ħkb{yNJZ~rV:8N;u5͎k=}Mx^ 慲]}juhbO|[j\XM u5X (e+>)22P?'@ƽ't?Ik=͛W_ _˨FǷV~lpGw :6goF͠U;g)$mҢ"sO׮ZF:55kqg:vih\QYg6GV9/@,O ]W|+حEnr 7/_%JfKjUl)&΢H'ӆmÓȩt>_Njq_.&SJCf#E$-c浇|ȮSޒeXl6v-5ҭ8Qƙ+"u?3f4M#Uʬ߹Hȅ*)"Uަ_V30D ڝ2 *77#B*6U%v40(D<2̷%4b`z7])vwe)XG+3? CLȁ\ju6Zwg8).j"%X?( 5`V!n^>ͥ-uE@VXTUBֵˍ!wDu@|x^)7 !__D: 2˓?(ÙB H::&*V2j-W^4'qtJ=l"7sjbmU3ffU>!=f^רܝ@TԽWtΖ485x% AkƊTmd0O$pL1  0^_)$lhxM51q{PI@3`(>wY-+rm=ƪ1SvkgVb d:s', eE~ѣR`bRtI\{"JKyJӔLeDEb-0J! -HO/g6=f"M{b>p 8!r*z&bfwvl U\6ҔV&)O>K鎶 2n4z[ccL!YQ<ҫu>w=d/&"}'a(% ?hYfzKVx8,4eūV`q'F n{T)?.(fy%pWZnB1$~$(V1^yl ~WwD `݌!:pE޲輈!r`趙R ɵysN76Ǭf8}=RGזv "Cd\ vV"f<VH'ɺ!Aٯ`&; M_4 Qd>Np4~x&: *kIM}7xJF'=}nztVd#>ƍ"#[.OiV"U0T&1\0~]ZUetysm$q˃/!ُ. /av' |u3.O0}hIrWBU8~h-c=m )]]ڸ$0 uW`3z dxD"k}>8W jQīytjȯ>2+MYb~UTnkw ?ތŸP(#Ei(ĐL;T 5r .%(5]36%Y?;#9?jw#JRݚd/ 1pRѦGNr!=\H/J`=NYia[ )8oF=\=LJĆk =Rnc.⵸Ln8mby۟&%lT(hsaߨJ\S@d3gB!]]>VgP]_'L&}DXHf΃hbqC}FRfjQna]޳\N1?myoKRCy ^e@@6F0O9u^I ]W{kվqN Vz1}D/cE`Z@(ALmG#IU`1#vS?6R} .4B}@d 5y;zϑȪΝl J F˅d{tC~Xoyh`VaO6Y;ѱ ٵ}V@,Sm$^;9s",bRk?B?/.⪿KhMu] 'qN?''zq&Ǒ}%kJ&b$QC/SF:ʙR?oef?H[&sR Se<7C9mI~"b)B3aHZh]_Kir`|8I=fuֻ9N#RC( @ŝ_%b&QV./b (U}'msSE٩ek UˠC -P.<#DT8/egUoFM`w 7E{A^mL5`eCE> $7v *-Ri& LR;n+`OY,Xˆd:vBSǩ7tWž)6_7fI抎qB2{D,>p O8cfRi Vφo Ij2kk%| Ukz 4i\%1R, “K]IS F7Jo7kCD 'q!Y8Tgcv!6ZeלO? sꝉVInSqX,-i6;ָlĻ/ H(L{;v1u-[%ɝmHێ+L5%PudFhmF>=4 qDuYfMiM_C<񡊊8ZX"ИLtseFkA݈G,y,WF8^7pά9H W>=Ul5DTZIؗSVu]hM67FO#%bS~y#+O'dn6 XqU = @0rSoB;8Z}{ɾsnJsLnZKQonKMI":(> կrwQd_7UYF7[DrQ‰|1GTӂƲu4;64-;pZL?A]Eb'"rs\ $>{b;ˈCE;]DoYpvQΈPŕ ri! ~TU?UE3ż<&ab8́2" h(CS @F!B\< Ҥ/[8z#b[VI i<IܺFFI&׃/>=׃J"횭|%Ab9&uקM9Uj]tV yf5ĖV/@zK%Ia^oI`nL8E2!\~GbK1-v`Q{.|Omu 4ֆȎ6rz5Ӗ ԧ[ʮ$WH {ifYG#@TdހdܥNcU@6l]gZ#Ҳ> ]J7=z{ |e1XCOl)dYAĒҋ2Ot ٥LQՁEN>]KDɋe[z٤^=S0Q4i5ٿ:YƵ|/9<[$Xv3yF1ײ)f>WLԅus9 )'םAU__$`oobjH6#28*]dxkي'套ߛDҔykכ#=f\wiKZyocp Q%j@R&A~/{DZ/!9 I΁{-`?P)1a9'X픵 a&0LN=tfr$\~^MhA9<<[趶y\­,LTUӧܷwlV@;3 y$Rmxfǵtݱ4J4;=8(݈{Nzx7;XJ?L\*J+qϣ%O\9>4fa`A|JF:``@ $~9 BJ=ȩ#  'E4I񙱿 S@z5  e}R !OOjആxqNS<A_ !g]w m5B)kxZrGuO t%WF0MUيAx]ϖ H?Lg[! 9$VnRU=-r%Z:5`vm*g[,Vx8r`cdD!I#N4+tL;Ė ) *w!C=@_LAV=e1h*qҿl]vP-".-q(J>)k׽V0`uDw޳Jφ Ġe VZ-dW*Cq$3o| _A>VQ[Y㬭8ծc5gs n : F'$[rPupJg* Yd~嫸H]YݤI?q^,m_"箥 ^bBo{0P^ūCAER?)S00=T'j $zQKk`MQWg΃/#7^,΋ȏVzbYQ«bhw%k *йۤTNkK0SP?rv|7[uO/z&q&'sH M]+85 sñ'S>WόJU`U?DC̋~S[O+f)]uao^Cw5PPiA`ZMð[CK0"7%T %rxد $ˍ֛ܻ1wp4xTU ,=eΝrߴ6tY0R?r7%K / d;O* 9lcifawJɱ>:* b$g2R2shCK Pre6T./~ۂ}?Ŋ4&LCdn$=~mWt,)483[En%ĞB~;,_?%,ӼM?<xeR87#,prJ?4Jߵ`}[$$׺EB+gYs|E 'v5y=n, c: ~, Y NCA3m N1ncHZj|9h~KL{,9+2Sb'ui|!v*,^ݸ- 5AG4z k'tdSF.8xOPӋHldo3jq7: ~GgjQZN)RӨFyy/).ida Fa`-*kֹ$,UvکDu}LM9ՙ)r-6oě% eI$2i}[Wc4$}XwZPs'k}V֋ 9xo MВ𪥪o"fe,[!η =`3[1ςh |c H3B3#1>41%Ӑ&)]얗 UA-Z +I+n%gwχ¶xQ7a݋AnKII$RA!G8XKy eF_  J=Gw-tAN`!ôQ[k1wwRE)W?6ӕ<`WT,} PčIl %Zɸg@ l Jw2@m|gPbކ4n'W:=$s TfiLY3 D6W: Zo8p*׉[0e {. jdC|e6]j0,xZQ} Q s'Mc܌o(ƌ3zFa( A ~,EńZ 8w`Ul@& 0b]v /, ^3|6&xW?$(i棚3])|bԹKd4ƝBWbu wgd &UasMw@< 6*غdbi~OҌW(NV1 E0](<2W}0[<3@N 't@\QuWQZѯq8qnOL*k^oK,4as=mQs8kePM= ٣*rGWR, M)USH܄f[piݩV/8ڦNL~N՝GLݺ8r.UHYޚ `NR Ae_ ˝̻ԛ YľlO?JKtR^sR @-ujFi" E&S1f OԘ>ފ3J>XIMߒ_$A_bueD4U_+.M\C2}k۰3XW/*99̖Ȣˮ>.@kWɼثTMzJ620M# ',x^\ϬN=:X_{ăjb|0Y1J=,-HSlKH%J4ZdW.:8_BU!èŋ$˺A hGbyQ\[Cooۢ5L&,aYSZy`#{y Ȝn k}~q^Þ"U>5,9DvփG4}%O +/ eպ9Msv|9fiz-wE1e8N?Q9zjȁ5Ʉuo.+'a;v^a>Q1enїa;xP]T_=9O+ҝe_E| \X\$Q6R Qݶ2R6a/:f e)_?ܔXsF~2Ȕ(,'(ux&{{A5Aghex鞸ð_` ä.˝% Di~=E4n(PDwG|?c=Fc(.;wNi5 e=tm⟁5oU pk.9uYHvPY]LRkR^u;d0+?蚮p5`9>*ffKZєH? VWV,ՑO=ojj;&7zT8 Ŕ89J]+2KٿjL؎0i߁X{i8fK虵%jꏸN;w/R-I%u{5Ї>CjKy83?OG@K/mϻQ,0n17\Eugi۾ך: d3OQ&VC#Rrm7B` b )j2RXB\!a[  0:i38137mIo+[v#**Uֿy~W%E E_ Yr#&LӚkrKmW~綧 qڟ?wGJTDE22{w^a q]>i4Տ\VbuűCwZӆn_1YSt__RސӈJ Pmj cH# 6vKO~w\ZDR+IY^,ApTRϥ P3#KPgp2~߭b?LBЭ&P|eؓrd+&DoEUtt$PB;ʫ5U-6X~VȦ8pc[?0veC}܁(bf9 ddE?g K1Yx hX&'mW#xņ 1DIç;xdy-OG(+>{>-GSKJ'G|7gt.&ptRFnkn업ڈ5}Aup_V>gwx:UW鎐G!]Zڷ`xVCYpZxP\_$nzVFN2 1=zSz8_N_`$ZxR&'"U2SγT,_BY=O,0*AA?:9:,hWsH, Y0Ga`.4{V#~:^H=@K9ZJp+[I? Pbu )nQ;8`JvkNj/m/s@+}nV7{xmvKPW J<FσXeK} >%{*Jj2v `YuCΨjauoZ+;h4Ėc/+Q}!Apm[oFV8IHQ82Dم)s17Sl|2'a\(ߥ`)ƣٱޞ YY|wqZMc/qys/O)k"_̬=5&.op'?zu}ј1ɦXM65>މ$> w3U4e'‘,BZ[C>Lwz k^ 0'eV2bYW^pY'~wCa(|4; )5iZù֔Gɺ"m\'0v=vik@"ͤӛ_wm8]v8p!\>VB>?k07q `|p)>;ݹ%ݡr'1 [+l]__V6|ڽXC|lUs+yђ&Ґ:DX[%|"E-iG< Xb* (*A喍GJFx RnJ]L1J[MS6Qq|6R'zSu h9|Ț{Vʍ5egg=r6j-W-t:m|3/;v?K $7՚sko22 zNxqu J.XCSM*ǂ6`cIQ6t SqO0GGhuRy:8uH ЄFf]nϼZ3 _]W'Xv`k=NJV4w͓xGLfӪ8-٩:~xrұrA cg@]T;c%Fa$$ \Xa>#~l#Ѻe(dSc`}_u%2V]w;hO.rJ96;,<^GߡJ ࢑=UigM?R$".vwk;J /v40,  ,7tY?L_,:NZdQ{d /y/b] 7@<+R 0݄1X^{04wwX! xhcG+X{.:9%` NVEX`@Q\tĭ^] |0cӢcެR6w͚#O95i|)!_v\g^07k{+d6=h"1b5ZSD҆9Z["}" .9ew߯:C֯5^ol/1V_V`.o~*$ ~G7jV25dt.BmMAAh?tQ ד7l-"WHXwN#} N[UP":.XBtx:jմΜv\Γ2"(Vf&y>s7iLgqKzTF/y63,S͖r^(uƅ$Ī[#ؠZnQڹ}XҹWEH6 !l`LkŬJ/zV=_tL7d) g@"B=L(L:)O,dS.D!WXtٹ3=Jg(| `bˎ pf\+sTOC`)s6aͱMXmU]*jb C r]¦VlA^|3lH`Ʃ R{C ݒϊ weUDn:#ڎ#C>UEzfB_0sr]j5Lp ؇oTy*ґoPrI C%'R^rgl~Jk BG̵1CM+L)aF6浇I Njj.`ԑ1A|)~x҆Kac%yrq;i{E2&;?tኊSu=[{+[7e09Kp;Rc{]:vn: /Hjk=4|B{b6<Z"c 4]x!1{ֈk L>Ntpqu>͆=1T1lرǐ;uϚ8a+`!KK 5XE?yţzspI+4eeێ M1Ј3{3_Y!rOr"\]7UQR.moz!5z5Fx # KK-bJ49h|| 3rї_ Fo.M4ӭ7"uo(zVCD1Xn_p3ɒ yRM U%'W<=][DȄZS(UM zuzyNhiD ~ʼr.#XE$[x+eG9rnDd,'Yl-&q8"-lݨ'^'TD*U,Y6!wz->{2tjN4ZPrIWHaFyM.<1&{Pp"PPLd%h,_K)V4m|q8" R'H$B4|#'yOEtPb7a`^@m[Vb(Y) s5Vda_]R(%WC}OS :CK41J;ϲa;+bQV1ν6>  X"|iel4p"1ezuQSNtne@;P;> XL |{1RQ.0@}V|'zG!3k̚O 21.;Z99F W%H]\_Cܽd駹m<4~&gsRuTHB% z&?'<:}.!ϫxKE:4`v{]5=eY<π=IGsnRM`2t_vaԱ7ߕ ᪡Α,'!G^2 /H@P^"@C<(X#E#PSixd88?vid|R7g䵤hĂQ١jzuQwHs}J,/fݸcVDuDXn׽F7ZOy d+ co Cld/T[u62@Q7& +j-s\h鯗 sSUgXCxg$!qoU/>9B^v<x7o(vԺ * O.L%ɷiMC]`˰Gs`D@0_1z!IN.V'݋U1A?}Tf=*;68YcDZ#U_2[̪)ll4DfR͏ɿJgProޫ7AڏCy3/=[~WANy+o@ 0q%A;:kV@Kt[ L垮ӂ8 5={rŌYkrȺtW`{5;Q6> LU!jO<،hGi})˛ 6S^%ГpadCV&d?/0(ZSlfk`3Z2ZR0pfDpPt@4K:(QNdj*t.JlȲ6v&9|"W7 Ʌ8tБ! #}K`P.)^r[^^p᢮ ~m_93=/gl̾/Ne/KT2Vx?U]"te8fZfVj{}4Q'H{:i7Z:@}%d-Jqb.h\{@м| H.ٟZɌ_f! }HIc >k fmhk);et_WV$t$MmEHTC )cjV}Idʈ>S-@GkVɑ=s"M]O\eIc:Aopu.?LNmߘUNAMVzgFF7C̣{Ç,R0? ͅNF= S~c(c?wZ~/@X=(0* X!bp@q+*ݹ"p5?] '5DZ6o{$5eUtK84"9Dnz_jsxF XPw[K%QIWvtXQ { wnRkdh>CAaS2Mv1]Ķy˲o-ygzpc3WP:.-SL3]ǮRkc>oQ<$A' 'jn$R)^ B*zlѳ=$r9\ įԶ e8W)߾'R;aqnkk0VogmTJzijH3Ba1[+P:QmAEBHln#cJ{;K)+Ƅ91aS> `F_8W.=j2.`Tp,a8:[PVIq?@*p=Y4A߾-modHb)b)8D\n#u40e1'xQt'(D&BxqS=ϲÊo?jFO&ZBe7t@)&/Ԋ"#4yTv0W.M5ٯ;ߗw,FPJFngH-lcXR̃f_(a h= *8W{.{Sl) xoC㧃* A0^ %pWdn`:ӋdE*)*__SmKzqV :G}eqoTΗ Rʋ}3\n1irBEsN8g*[ۂ:íV`F{^2ҳMy)ӶQ.-B=R/Idt[QH'MA!n69 iU\x?7}ʄpgSB붕ޓ@ZMKz3H_Y=:XYHܓWPzj? ?Sj﵂cHDTwygG^0Jj^a9J-A}LVٗMN"k{ {?fVK˻[;w3@3ۗH%DygޠevL <_ X{ (3< sT\Gy*=gAxM~p5BvbV{ɋ 'O*Ԥlm|^35CEbb˙ٔ;?1=TmeZz{~L@8湘Z:ɪysp;pʷb z 4x|I֙)fYÏc\+q3Ж~>x`i`o0*GvBo5WzR!IJ,SfmJ 9Md%0_Sxvr◽_xQ!%@ Jb'PpzLJۢX& 5!U9^='T$Il6/-zelXBcZDc;I|完&"'\t]r%&]A נN1])/`O n}dSox5i?)%rhqb> CӲY2*y),qK']]qo*eP/Ks悊c("_24I@ ܮ * h66N[A9KZRH(?or o*E?&nn!F /u^ü5x ! 9pTE-L!#a@47' ՊZƇ ^3ĤNzÚK/NUZeuLb:e b@\R`83@ ox 1m5޸$+V^9Qksk4w>'ЋcVN^Fxir/]Y ŭ۽0 m|zMrY⫩Dq#,{`LEDX1 ɽMAU)PR~6t7(@@@+)phw-NԽ9}uKFMyύ,'ߓq͐NwX *J M ==Dir\DKxɁ%O@qVQ3UqO ֕=TLVL2G`YR(sxޯ`rKdqtУ7 ql0to%x+>foPo$rvv0h>C. ZL"}m<ۆSaۡndI |~d~ :np=1vJZl m+Y1jΜy{PQu 8IJ -pޥQ8= Bߍ|[t(b ,'z><rev"z}.L\!a*z%*jJ̄0do'AE/*84S 5?ҹT[=DU? " MBGcÙAX&g},d*'1ZfrAp#f< GQ<"yfnb lld)lpI>S!P׼E9% F'aIהv YVfK9&/.*ȽJ?6YZ38>M mE?%>au6,YlOM{ l4.N6e~.B*pnWH1Q|l$뿑³$zԤ]wM8/b15r BT'VrshlkŒ-k&o螟5I˕͸$R; k B^ P_%!#@ZQ| 0;8)L]/B ٮ9Srh/p .}ݿ;)[9{0޻,j.Z7,&~ABS@{8flEL{ mnO~4<>cyc , ▣u:fpp_E5_&ݖ *wTyh d.P3LT}#w肧ć6]7u,4H%nXvdԌ qaO$`z FH"L*Һa,'fu;z6_1b7XO?ndyX?7[AMRundߋvrkVm'LrIhoۋo!g-rG=ҝa0* !A$lW+0UAs,lVR+6RZ[2:GtMJ&H1wֵ Ճ@] 4|ؗh *ABxsFdC*atF4 Â@U)cDg R?Ah4_E@{@@{CjR&q(+AE,Gr]1*tF@)Dg1;A4_nxEQ;S=O|=( +AE,Ge*tF)Dg6A4_nxEOBI<+AE,Ge*-tF)/Dg6A44_nxEOBI<+ARE,Ge*qtF)sDg:Ax4_?B)BB~+AE,Ge*tF)Dg:A4'C3I&kP,AE,G͜p*tF+DgX#A4'C3Cp+H+j9\dݢ3r4N[i54ߑ9,09iW;s-&Ĵj)|\Ꚉ#K=l{ƾl)/gKf,KNj X83AE,W.ҙrZ 4>Dg4BY!=*e֫ A#477lĜU$J%$󸊇/p"8}=_u!bӲ YVz.uvrn[ܤMK3t f3C+ .bҕEca}AAE,G' ,/ro{^^NR3 :ʲ &xP{z:,۵u5O#ChJqrK; ?ݴle@5`tFk<5ܢexbDg7AԤW{w27|:(*Mz4~`XPp&e8 $YI$t’$+fH2ۨP CAd47-ݱX^ya$Kn$5YBŐEA=u# 9J7牴z#1`GA>LyUQֱ~jes٬/7ڷZ(fTvMxo CA $<ks>^"3hòdyɏœG\p$  5赗N(IpęG@ΔnCV:p猏 F:tB;H-M)Cftj|e5!x> E4?^AE',SDgM&/N=fxUyHvVSOu8<֧SˁA4_sPFމ}P!P&n=Q)>7hsDW8޴d1M{hgT4Xw }mVVsdG)+Xf9F!A (dҞlI;5[g.AE,GZEQ_#J;[w|xc'%|IqB8Ncz}*-Y??C!1~]Ιm\@Gjnh5 ?vibđnotF h<{;<*x!(1SDd[+M6WH߬M> EHlX6We!FX~eiDgi핃߾"pNuYңKf*%~%ܣ`񞅲П= * d3Cm&XIA4_ဣBԙ(]‹v[_^55ǻ c'7('uYۣ~ysHػ B9IHK bdS -:[Cy #ߔrGyܜAT}uݸAiAE,GZ2|נdŘ;6ĵ0 57asi;{&w+KBl3^?@]pQ5tFi«?%v\j;H%#w,CLk`89tـ,7Dgh !xA<4_0>Br[o徍+*RBU!Z[$ 00 "o`w4 [u]n3-AZE,GZ=Q*ytF,{Dgh !A`4_ߤ-q>ʡ|۱= Rj>JmXK e'IIț10eQU< qmjZ˄ Ȧݎ˸P٩P<49O'bnb FsC pKWoc39 fI/S_`%U̱ 6"'9s}'0X$|mσ)IA%-yqX:=]R՞;/u0Wew+q}}Jړ<LMOjJ5;Fj叠/%q D+P*v)9]l t= J[ݥ6J0 @*i߇F ~kȚl mf |LStFA[2- SkY8m.LSos%hDgt JʛiNWD}BSU&.#D6L}bG3F^1N;E|A4_j} n:t UBO4OFT fzY'椼|XMju00** Y?lhT HMV땋_X>cwr8 1=YhY%BDq^ #)W+f2n*9ț؟gPp0} gS3ί #L 'WkоNDK[=(" m[RN@/ i}` cE*8ai~$_[At%tF8A7|Ffk$E-#o>m~^,K6/{l- =Tf#E批Π8'Dg^xI&d”ei.|zU.Òp-mW:4AV\m9PzWX|$cՃdm^NiR1 /A+4_2v+Khbl\pYg[k U]52K.ZBetB7bZxnhOA9 SaSuQت27%FwC24N9 x"ovs΃4Tt;e,f}?!@M*Bғ%YJ@MjeX?1JqR|]nwy:"9M)}$E$,q~gg=h~&(ݳ AIE,Wi[^} :V g$aw1x-QQ[`3 uh q,D!>%|Vsc:' n*2葘 K>5r:>ulzKs.D]H:=vC2G_4!ЊTuw49:0oQ"&,UW=$GGA50rxsq/ {Э8TRQ&EV/K~5}AE4LG9q*/AszJ* /J₷҅6>ʧmgJEu*bԮM&x2I[We[:nVt696>6Ed.'@:]J R4Aoۑ#8Ҋpq T퀵CzChN/ihw9-٨?21XUéN=C[(8o!ug.U[6}2|4F02bSޡ <ag2q {Z}(1J9'\$d+u%iBɽwkllQmb[HR~H\:5Agzi沤ܤ+ K% ~55 DD@c4tFxwEʢQÿSGEY*KO\! ks e,16G% Y Դ` p6DgHY@4+eNc³t NUavS"΍6~ubnP[zPPA:4_̪8Ogx/<9ϡQ uAkXT˞9Qs%04W>˜ޥE֨A5c9d$?nVE ZmvQOB ͪ8 rg:+6d^*DBpGr"~6=5Aڢgfb`|t2iۅ}K_3܋ֲĝZט/m$A"N۩v&qu) p|9U:2^rcqz)1z  Ҙ$8_/HKo+1\?9}߁dj1D4V1zv~0\W! 2^ah͗~?gEeYPrl~AXE,WQZ)J QoQ\`ʠp0yd|(v3Q8" 4f\;\މ;6i hyDg;eAU:cdPYG\#>4g#"Xf"żӵU:?-9`A~4'$!!pI.1*V;CΔpΏ&Ȧs+7o[Ŕ=j #H鹝Bwen`Ibٖ4^5 @5LLI`+"Ůo-zLDΏu$QAO}Oc>SwzX4In,o ad 0gb]jЭ)` gjm EsZB}7r*Sw5I Qc? ;aCZp##41WKx)#+܉P\0uO#"Gf)Q(!iȃkӶ( D(^NiFnH?eA67Dx[RAШ2^N_gg>B` D/~ބȃpAE,GO'vkoQa>N BlwO_J:B}:t<"Eajyp+j+ynK6nP hu rlh,wH ,ڄ!Z>t *#gg? ʨ?t^j0otF 1#y Z?@ &רO/kW!fg7cl a>qX=(V%z4k5Ld5wDg&!hj\vw U^i.>A't 1u<$-\S:cpNTP)aōUB3uIA4_u*!]!P}9GhKɬƮMr0KÅeV{+҆&?eA{)eFP6ZI|o2>E0ʅԤf/I/zKyppZ؀ Ť!uY#p 6U;\iCTH8 E6)DWżc[RA=y9Qݮ \˟9,{C5 k]V)Fٲ(NxJO6þeH:[]&P1 udjQVAIXvp h#8}v#7"&o9;0:;VmUnYwu?!}ӗ!J)¹mWqX#n K ڻ<[8!"ynm/0 Iwp4۾ΈFt?pU|M vw޲#jn,A4_:-Z&Of˘K&A9},65ɧĒ;A$E,G/-%/S~5hgv%ى݇{o .9Da`7~qs2Iz#3Ҝ|o@#U N)YvzGik\AƴSQLģ%UO2 ;?4_Le`< {CtFjHGTwMowxeIH1;ḸfeZ&iժĔRn.* 5)#pEDgI!ÁW4fHW,Wr&!@EH&T/p?Ifn@=]m2$։3؎D-f3!G *g4LT-yAI4_IR .닜B<W]N"hUu;B;@՛3wV̂y"*pKu}X@,>>nUR¢cpBKLk]KZKj"#Ւgn9]OUty E\69YT]X'_k*2 J#o-|>_4B=yZAgE,W xހ7n5u6]~sfᚷ,s%.T͡\~K~CS[p;|6@%+:T qėWb'7yCx ;vCWp:iID W瑹.ZK5jLeU{x_וDgq94\JE4 Rdks^.U<.\\PnHb0խMNFOǎwP"먃=.n3*ssrL'-᧘x3T 7F]Î/$9 &'Ҽvtr"HJzA4_QɌ♩K}v\-K:Hh7^L:Eֻjp*IHlZ0~M?ǣ;,zda"T/') Uklj9.D}W!2Ǖ/JEiH爵xߒK̪iqbO!PR;ݼ7!sHo+jQGWwk4šVI}ٝ(%b+|ĻNH9[r!w+l93X_hE#`vbsL]|y%@w7mtF" KaJEby,VL*v⋳k'4R+6lԬjٴ; Z=ft<~Ċ 3hWu@8D&g|6"pt7 2D?VX.DgWIJdI(ڡ `r@]r/n)!<0Fv[<7Xg/! Ún0"Dk 7R֘cG˶4lb|(;KÍT_*)?Ḷ~.[WA’ Y!8F+UMxG[4%rM1ǰ,kSѓcx`B2]؉": U6>YF$7 oA4_Y6!zp쌎N:k?LP4Y|Ui&||M[ ;C*dt> k0C(+>% Ǚ ̚?n{x=gLO`=-6B {ajl;jR ˠ.3RphXa`x/>~` Ndn%݅@V#.%):)zp>Kҵeg6kGO*0Fʹ2Zr~KaޡΑ 0kS#9R9BnFdu, ƞ<@vg# )h.Ϙ2 EFGBk8l-aKi#,:0\I4{J>- .<9 B-``!j 2O̹Lb#qn@ҍB2XslS G+!);Ƿ4 ʭ&Z4?NG5E?1hX%׼jl+HU4d'~0ˇ`8+EJT(cHYIQZp jUjFM\M* $].@=~36:콛0p|+X^^ ] cdL+Eq5r V3V~uq,&0< "PddJ`OFL.i+e@˝'0Х̐NcIC n")iv1|ߧ> mrbklE~e>=h:w;?Q126ܮu]w6q|_#m- I~[8i<1O IP_ytu;COm$LKr|Nk#jV 0[P@,@~}cJ5/qMn5> g:[0]? eaEK+NuL#u"w׻2~mNݽ1g'ZION&;2ovޯ}^oo5e3f7CQIT)N@ %Z K@2TekXmJqH1Ś{\D0r@ GP0`>IΈYkJ֮ϸO/>+|$yL+m "1<}N_6!黿"ނSG WB78+Oh\?U2?%i7y%P(.[v ` U U 3j̻*l .bXu% PA4i_ |QЏP<_CNVx9, 4N-Ā:#t~qzYmġ #)b"84cVQE~6sU _wƜCլ%]\t%^_J;MP-jR(AY "-8?\ =u>uw LGX 2UFcR>C𐶥UӤbz0ﺍza[B챊g6VG+AE,GfcI:0ʳPB ֆgI}eƑ >E$cCl>ʟǓU),t|a`#C+)9(Íٙ}ʺϾZ[e JPMH݈yZa&=\z[ ̎%FoRN/t vh yV31{'c ^|2 VbBiOcl}N+ˠǴ_AGL9KY0SNQC ߺ΄ɤPUW16YX8aEq.lT XE\*Rm@П~䲖 BBv7%f= Rn$VJ|VZ%z(QE 3mKs"Vc2qDDg;0%ҿX%7qφ!s VitcRWKs/X+I$f@&_}5ر섺brK-,iInYjU $&i+"԰覴H^ eqcQ탗uKs ?MJߥK#^ ^nIHPݲ)~"_gOTH<@Oބ?uwy朄(3R"yT"FV9~9zzH}ެa5'k4*1{V™#B)21 < fj3P W \jվf!%+!Z_&/L:|~#61đٷ1{1,X+MavB&c0\K\;/'VM &! NN‚e}4jHPcNR_1&&;,#QPM7%o`It*~|'{P*_j#QhVd(pG90|hbz'=nvQ!mٝVŠ2&땷u+^7@{ lhx2{քjfD 9t;`i3 j5;rKj[: \a~M7%06ZeA&R弨r̀m&fp *f քw8D*됼$:*01zs/8pKby'O3cٷu"ed@gү|Kܓ3@qRtFT'&-Fr'ʞ/s*ڑxj 7sW$#{ ݄ )=ʠŠ\EOS}iG-گ[ԗqTDg.lU<ܢocmWKхjf-:w>>E*@f?ʰa+\9WQ41^ &S|v9E'zûrYyd)1lah.l+s4Q2thDB p f [8)A _tWPssAY4_Obi %O+w6M]h_PrJ?, Ls=4:%1_ޕE2}wM+f~2ldcGc,T-F(~]|1:7tdzT;_Q'@:$|FsA֑QVoFݚ\cPEJu ~HW{01ۅuCOp#~4JB(HxI=yb@6H3ȝ# Q+9YaFJ!=:,€;$R UI4T :f[%cu)q%—@T2g*-,D:ㅅ@䰟n3Ѹݚr XPsP-5Jh}:Ml3jZiU9H_shM} JF/LjXsw1\J|#L CK8-'$)mI+[ ꈠ'Y[uL0 ^G8u<.+sUo_o81O] `N = dA2 $^Ζ)S];, Z:# m!BP|?vY 9U޸?ZSw,9~U|qwO䃍dV!~PJtaA$N/\G뢉't_jGTT+~QۥhNNز72@3T lDI )sǹ<[*!u(Oߠ%0}NjVqz3en|u*qț[T~4P5RfLX=P8{`Qu>KgQިکJu1o~4LPt&v?)6n715 Y8]-[0`&Au{+uͪsBk(:FT7&d}NCG%[~)Tn~̅"C{r9Fcf>K]laLBIX~傟8T/nJ&+@2JPOIʥE7 '!kH`g}F bM}.jԲFwDsZܚ~yhHLX^:ը[l -:2%XypN=[9/ze1дgJ_ -R"%! 3Q[}j&2q[@XOh 6^WØbp7a5RX'mC -tq_f/ɨP1g 8-Mԋ,!dQ@P`9HҧOL"7sh{FYƣuh_iz|#;WŀA3E,Ghi "+~ŰQNB<ʶ(ąҢ"a2RtFM_@@]GTDg΂0$Gy ez*~jk)z/k{AY4_,$bgwb_C S3i{'W'3g$V8p rRu "Wj0AE,G ]*NTl;-+XPz^cN6,1o5' %5̮ [kf D|lv೟gXFQ b0 ;l,;)1]|??5'磜4}]NM{ vnCSxhJ'|]/-R=vV?t~jXLlAE,GgD$;:&~5Ft|DcHtErټ2AkF' tFvٱ`rW~`L˾qmvZfhk-3!>foLw7F KJurSN^|GLtt .l,Dgu VA4_e@a'Vպ f}q|–^0Ѭکx-A"E,GeDcA+AtFuEK)CDgAH4_=jQ]܊Ҳ5ȨQS5W 믇#¸`=/k_XdуoZdFb%͵݆`tt9wHAfE,GhX֫=^EZ2:H=VB(X?Tp-AE,GhQ*tF,Dgxȱ nA4_5MPZ sx-66}|^tuHj q}Wrw"\WO-AE,GhQ* tF,DgxshA4_qW<MA~#H ĥVWTU vv'*UZYݣay󗀍QF,ؙsIP]I2 yGeZLUR{CŒA5[)a]m8Fa#Z ᶻH^v,xR6K,`'BB~QO; 9ߤ ɰfYo5+'G@7᎑K%WwVKExf*p2LSt%fcC7ұ[bOQ{g@/ %ie盗XZS ܹ +B1Fݐ*2SP'5> I:P$oem(R,wiY+b~x4~]J " rCZwOZmt-Sl6k%sD;bDV.$6|A'ۀѣk_h0SB< *G!G)\Gl{>jΈ{I>-tC`r= q IjlI7KԣD_B%>ť(xX#.-u mPʈB0|-r'?voSafBWWѯOp6UT#Ta;Xs\smA9>P(ii,m|Upg>kJƧMXբ.KgwR,B`6$5\\OsYpyD]TaV2v`*.ab|>8Dlh 3H)~\X!}w#Ǔ|vt=8F3eonW5p\<b2W)I b n~\kGخQdrͼ?:8"8`\O3\BϞgHXc 42l,{?ͥZP] Mȍ4$!phm4#5`DD3/<.CLdxC^hHSԸQv0&N*(ərߖcxܗB]KB@.s|sN [Yy P lr{iogX7- ϟ4'+cdit5t=-pJzyqT́5 ʎ>RKLqWE%͙ouYAn\np۾w soОcH:|4pAb; fxWpyr,7غ$hZ_EH=dyIl {MWPB%`~m;@m0UuiǢʩ&ʍ*iH#XZmҁ|{pju!^zNf 7 :?g5n>m,A1VAh_W ٭hc}>|(v;DVVKs A F O5mn$MAQQcͳDl1r$ 7oR:ѤЂQ ><z? ӲN܈LZT |hU"Afyݞnc(^1MܤT %yp:F0w.78)qϒXCtք(,S0O2}69+#M7ENS+Yz@?!o#~IGma$?mL+{&V |!]BZ"ht}8OGV$7TIYcO iպ%3|ezs] MhCd.=J͵UQ70H _ta!AvE,GP.4ϩ#p45nieoc.>+>hUU\{?G1&II0j>8Qmyf3#f3'F-*z}:9-H]ŪVnP}p l>LtF" v ,.N?4iV&j?K+rȞزrԀ/Dg @gYW`A4_ E6Z_Th .CP̢" dž|Nk?*V?%ưzq'J TqfNk|WqęG}0ag&0C=0ʯ8PNu/fh uf/sWQ[[|]>qɳ]{qm,)ĜPX-9 z}WCY^'ʋCvY6%*ұ"O@1n? vBqEB ߻>"m58sc'"* 0RV-re;ipe5lz>+䆎x5ai\B4ڠ>#r '3Zخ\`#<0>9P6?\AE,GV^a@N>4Wʠt@vbZ^_v"dpVЫ@~|p,ҫ`CuwUN`t*(Vd[#[nDg=0bl6Uƻ\_]CA% ^}A{DTbO sWKNrI ҫޘ&#ոt!1>ptFmhj?xg6Tե9n&:ujiB,.7jhU$Np\_c̄(_G( 0H{U͛هPjZ  ^4nxADgc JfgPq#]#rfx~QAn.g$ŵSVuWD/E5oW_8hƀA4''qNst.6?.^8 @nv醞,Kj T(Y^`1FDdqv PCL$(v_͏ܲP.ktB:")5̡w jQp:;',8Stǘ%AnPښ2^QƋ.AFwNS?1Mۈ H ".$Q{9I:ٷܦbc\Eoٙ=Ikd-~DngKYrϥtC\#0VٺY p{iyԮpZQ'9]Um{y'zw8ONי7m4&XAE,GUn'7/x #n> 3;).7 H boUfN#5Mb5^;AFMK1 t2F.\n D6 1/L= 5b8 EG8˂a<~`ѯ@6t3gOkH!4򁹿Pfn(cj+@[6뽥:ٜ'.S4gkQ23tFcn6S/ n|JSW}-+x\leoZvKQ*J}-?`>dF1d+/Ezhh13wa!h-e4j}$" >jdJ2[xbynD1gҭkS{BZ`VTNUQd{~h nzaևl8ŷ,Y\FF8ܙ~;J.9b L&2Mh-k߯m&8hr@;EH$N #rG@͚KjpND /Hb"M]5Jp7^Mէ,3>> 'Z;.%a7(xoI:>By<-WssB %g|&;[]unM17QڸP7̰_AtF*8@K} A= m  $_[GěU0 7SWV16\C{tODז0!Hbp4;^{#Oa[ëgJGy$yP3W7׫!qBCDgYMsÝ*>S(WGiwGuGIt Bs6+A.Vwn Dz9@j wckYhO-:n[ф |[O-@B4uܳ5s᎘kc4Y Mi+ (I{Ve:Ak3EAK);ɓ%d!sv@^Fl].z"J ֪=j\oiyXSH'b1(r#! Ԛ]L; t`60@G3AE47Z24pq ]SMgAw/ZWCɆK̐\#v(ؽ52×((β'(FZ;zY҃}JrBԍ0y  Nn)Yk!iRƧ:v3`a%u1}Ŏd[hxqsVDڼ@x/c4B:f?!a^5Af=l ms>?1ŖS7Q60oZhu{n>`wSvt[ BFVjcR3;ֱ%ތnY7E̶eJӅf Q||y vބr `0XatjSqnxɝi-7FLr|f있s9S_Zsj|l y dZ^b;Nн*jFݏ4 *Ûh) ʼ^jj'tKP:h6Agnl+=0^0~̺EX\BX~QM.|fq3BsKGK}açym#Տ>,9]+bAٵ߀x8hkɝ!БIE>fhצ/.QفR筥oi>dWg\ԫ#Ƕx&R Mk~LTH H&RoT A>Lo1T *kĂt=U+ywә7rdAC+EN1u[Wo8awwueЏv$ΌI #ޖy0|e(}D/10+ S;H\>552* L ~FXeu܌ +o E{9B"q^ ̥5nVic]v}3^ K/3! {TQǏr;ys$1ejY6"[ m2\'jO2i))-[, 7|ԡ ֞wbb/#D4e#i7B<#w.L?|Kp{gS \I0nF1cm.qǔؘa;xΰVQG\\(7qrT4- i6}u踙 Lb1 .DJ0_A$J}OI4ur͹4^[/k=u F@)cr]L0~Bo  7pF2&֗k3R Uvv|}lU<,NN+o>~qX]gvaVaje#z8|(TЙ䎱4 t*!%@TVmtuv>9/8.c{5?(Y`ozNZsM܍Ć'Vn|IO 6$t3b0An3 hveh.P_ ̐/** vZwt-S.HRkOyVx hut6Ř=!R-isN734Л $%З3l JQ}=UY^ݠѨEҥT J6kDb6j6e ":v\wn`ʘ8Y` A/kYcx`nF5eAHۅysȇd6Mz6@})IVp;x޺P{*MX2[ZZruoZ"OlD#9A$LU쁅]m*K鹧q(]dکfǗ,fWP/!4ޝQkO{ٌx5(=afpRiXTxX1*9ljĝ+cus/;{z,2}@| L5Kŏ,a1K+*gU$ k:NmߠWHv?HRczbD< as`$̑})P1,vz}wMs׌=IFe%*:;,? Tk qcI&%j A#QDQpǹ?D`*Iy2WuwC3UPٌL;eFX/qxԊEWMõ>m>{Z-1kpS=CwTno%E(]ځb&lB0,󮨬[-ԑ Ym yǯ k﫢y[=֑BUt_yod;nˍSw%PW6 RܴpWԋE?, Ih-RʲMޟzdvvpVMoa ]+^aJ#P 祢Ԁ=X`#;Y?jMAc1ӽ"E?T%>:VY8hEM}"sXm"B;`yf:ҋ r8ǩ$89JwePFj֞+l6O k,X`ҽtO|ۥ3ru  Q$(8c']1hPCťJR+( ng #{_w0f$M7a|Ia9L;jAS^b~W%lZi\ؤ±C]ԸLFliC޾;KsVo6U4[iN݆Vso~eQT$-œn-IBZJCx׳ G$ / xdM>ղbB&X}B8}0aDX %n3$5:a\[kApg@˒@/,'vݡ N738;`4MK;+3u>]7K].P*wzx|O r邲ԑUiQJLv|@T; r݃b:mJp.:m_ ] *? aפq 1R'=Xh\cDҕID C?G˯'Oe] $r~+J11R jNꅡuS*"Mz?$jBO R5ΈP$A1*Ke~rJ`H/`aln6{FEV͊.dXLGo,kxoǛat+zv+HvV =Ol"ǸTu2'&dq"sD8L7  ߮9Aj0HA j ݔ3FBBg,wg0C|;ylO=߀ #9wMoDg?0dFNmZ׭S)6-ǻ?^6ToHɌ[9bsfi͗Œ1)q a9| CC>i3#mt%~ +pxLrFnQAs=2 ,m%DpAzV(AҖPxfkQ[iV}@\dg}*4cEc5!F@]A<0^l2kٞJ%*ԋG4]:Li|BJ-+q$]O֋u ٧ mPG;k &uRVw\[ Sԇ}NC5wr.\/z7by*2ipXu]X2`F*e@T.?کs).\,I8IQf5 d8>|}^ɒY[?dz9ݵ74{5F#A`]8?/uAE4LW;^a^|KbB'-tU:Q{kD -eQ_)*g]S-seG_q ɲ#U:L0 yDgCOwЊ"?PorMQ 36\%#kpQw<H`,ٚD˘Uk$ﳢ̲3A4_$HLB l3)YNXXC= ?{0"2n~^aHqC8t*+9廉qWF)y'R(t ,ٮ/(Ac1S2kS+f֯흴G5`Oux6[jhLs'\\RpWrѥ.h0GEF-PAd>޿&xF.fmµPabHۏV"H;ٸ6gE`a"=A=G31$j6]aU#WB[C>3fLGWqQZ,jvBgK 暐E5ḘL-(fn^Ob1GoSݿS.m;̈́_טef9s]Q_[Hіٗ VbpU ^|ǡrx J؇<]ga}s!(3:=)nrc(Z[ԾQ`jD *QTb}_`pS9ټ ;_}Dkc/\Nto3ׅiK`AAE4LWWwcW e}-UgYm+GxtOH_-0ץ0xe+JBK[q96p^äe&BH5D,ϺkJ'qd9? (DgJ2AT4 e(p7c0n 45COrǪꐞL{ב"TSteCIJA4ž|+l|"E"C.mP{DFI%Q8V#i+=t .XIewi0{Q6l<))/y Pv-b{}ȍG1oC4$_q~ ]B4 /A/{0`f<|p<;ԤUI_;~ ')1[K =@\B9r-0a`k8b ge%KeIuQ:7o}C= >t h'ns֗Y{Wv"_dNκ[XV<܌`Б_/,A^:4ZhѺu$hc8wkK/EaP~bsD 6,XK\P na,:EdRl: n04+^m? y -8}w 9&@ctirNKk/V@䆳|p1nS"}9cFV[xRA $_b(@*2{Ѥ4c'Ӂ E%B( .3y:J[ZL+pwA^Zj xC5vݕ_vFhm_kH(QPBǴM6C <djcr.ǛGoI>うzk/yCm`FbNW*7G,K< s;9+ x{)9Nu ȊJKM?~Υdnq!"tqb@ MtqWͥ*܍1&_Pu: c9S,ӄ@$yB"YYP*r ȱI(6 f'GqSϟ79QF r%Of 2釘䇡ZVxine|_=\/s`}jqǴHqtsydqD.36+~ )cikv*arҼIuFpsZ-6=פm}SRB&b',]6mc'HGuf 7/n̏t_ r-|2'㯪Lf"K Y oCCy-4: l-K0~8goF˙]m hmTaŭcuónﵮ bp?860̥(bK&Ħkb{yNJZ~rV:8N;u5͎k=}Mx^ 慲]}juhbO|[j\XM u5X (e+>)22P?0HNE-TKb@vd0X~/HfM'n`g|XJ&݉O ?%VIhؘVo3l@j4\7lok7˜YoBK;A;KܧS[!H~R]J/>mlz'qg\rӝ _#A_ZrwcflRQ q+$AT;wGd൞min4M?,Q4\L`-BG06/iwIs!C_gwta'pmLuL?⥋tBU) ȴ{b>X=',G"@619&}=u!OiQgzqkĿ3 (U ,UiN XI#1X!3|dMzQL9bh97 D8w` $0w"TL"X%mV6db߸,'aKIڹ5v (&?З .7y0_-̫ 8#sypt9%M\4iւit\ <(*3ש|zƁf&ult <(є/]|cagL58]Oq՝M\|@^^t׆c3.+еê!& ,-==[T6V+%!.7a)6wlo/C?xǼ8v+ZAwYJEb.͌P!WʀrWFxaPl/$>`ʼoh^6 I阑w0:i2*0Kݥc/p"d6&3,7hypUqW#@Sl“(#t Z_aZ&y}7g [g}𳪪6!s@Z9@{Z!qq3QD802D[ lܲb[~ zarbyccOofobdAERciS qUxUޛs Քs!bE8YN}^ TDL"jzһƒV[e و<ݒ$0D1_ 3B\YkѺ jIXc'Qz£ǚiܟ6u h|K*ma9z) .A3XfTpѩI[-7y9'2  tvgPHJd$0}WOAP/.9bg\\ϵ([4<V,o5&nYlp~Rfq'72.Mi"FO1y יP 5 @A,k+%MMj-R)YU&0/ȁĬt(H?_1iNI%X?9n0$ %bbf`񨡍+OWSVڤ 4*Q{;EU3tUO&cjdߕ)@<`M E~7#JeiUJV.wQKXݏ$a/:#C2&$nW'E< B'ՒEn`ދ 6&Vlt=)}$)7bVJZOMMKĒEF)r4:؋lV.fy=6gx5Ϩqϋ SdL\@L?Ӱeh{Axyxx2m7"ԖH)ttKFw bRw玢 djz TsEd, $;(S0H_;.ohd?$Or+p*q2Uߊ{t3ԲeA\S}vǓLTj:J?'A)6kwJLe[9JFhʋ~+Y- @oc: ZX!L4ױCtpD,"[lkgW.,|zqUP.gt !Fԙ jCTp10Hȗ]θLo_0'BۗՁzއK*ȇP"RLAC`@CF&9Q Zcو[%)NʑO;ppWU JJ>CO2JoA8?WlcTI`T:"D7S>ETՑ|D:,!;aJr Ҽ,pN"bBz{Wc)+ 5o84kèӕkO_Oe ЎKO$ĀgCv2;iYwoN'n/SiYMn?0]udQ>wh=t;])x1w_$.eu}!a8[*㯰Ҥ γl2>C[{ TK `}κ3Dhw9ě4%pCB@U_^} +#USSk]@tB :um ¨lvb$d# j jit[KTj˟z?^eD%i|%37$_; v[,up]_3r͵X0lhjbQybQ;YpT+VVwo.^444yM-Oٵ4cp:@ 3L+t3odMcyhhxQY#`ijL%xd :_.jml$ /$ՙsgfɳu<%# ~eXwi|D ~ЋZy=􋶗B=#5 Zi^曱)bw~AU:qvۄ|Ywq?Dw" |Əgg 7}Ydžuϐ~+`À~X&ɝz7Fj}B NYIųicC@O Y:c2[˦j 3̡! azR/Z.rՕq>mN`&d ER$TbP  cqP v`a*%f8Gd՛L!ru%d M&7e ί@@֛<67j=ؒcaڀ6iGۜ<Mpn2뒯f}ZlD Fi< 1{YG"gpIVtF6` 3*+4[oLDiKҲK~Rxd]oEir\uuS+hsw{|+uboVkJÿ 81a~ _ V^dкXј.b-IRT&7-f+`2[[g(ʐTBޚVB[?͡):D6CI9'-kpO::9t["5 +y+~I0dpFSk{Tz~GL`,N]>fڲ7̰E$~|k.`$Rh<Gt90X dZ0X?0&sv15|T*I1b" jv "N~0*ޞ%q\h[j:Xz%w=Y2oV\!?Vex` Ez-3F"zmmh(%mħ'RqB~+ 䄉L.=Dž^:E,ٲ?ng«@Ry+9lRMY8OFtMt= g̷ m۶ԡ-1V!Cduk(O]#}2T-ة&*".Xxb3+2na&$)Z~fyU ၐƄZ+|-ç}Hk9vN%h|J Xՙ@{<59̻^| 'ƸeQaaEE"t=XyRqoI,`\JvRBw'k6^ ~Z])J|UonUD8ލ󚷠nϻњA))M@N@gO<']i MW:҉h565+Ԝl_<@rR#}37i|T4mGfpy;7Hpͥ}xփa:}{żYմ@F6^$4k=J#T1bՒCp*'r3ȵw͈Ds~#/f!J:VС 1ǔE\edg KJ%ξӤn&TVF-hv㖄wАA&J0ew.uMЯ7*E81R$-}z.b]{V xo蹔lϼd:=~#"D3ɞx˽8"Z0ˬ(ni2D& 6Kϣ$5PRSzY8#? Д \xق4M/B{+>o..<ȁ A.N4Mk cI/abbcS9$eT-ŠkbÙqx(YH/ҭAry!W(Ψ"~M 5ףu[z*>nSS#}%:u2Wώ7f̔Մ>O. } 8X ȭZI'sNp⡠>Գq5 aښzKXInҿV,|?LM["=VUBˌ}pU7%lqjҟ-& P`3q9e}IDWqzFdxMI !pdD|KF@ƩU0#8[j'Q! }kRwcg-vٸeluR'A0u5F|N7ۺ?70++5Kt[vj? dBy9 GjtctK}E-+EWL16?2)dO ӑ!Y|pOL91VAGZCsv r-J۠a{~g U۪\V͞%c+b枕rIzy^&#*;a#ޑVty3:*4A; S8G@_!H*LẙKUx[p6{O-IRyi 7(4"t=;={N3ů(K4R^|@bȀ%v"Mu]%qs+Su(VV΀=T +je@S7RХg>.~!ӈI8ҟ'?j竪'܄j.HbMA8,x1zw6a)/D$3ViMn@!^dۦٖ |W@bY#o$ T'S *ؒV/ >A`Uc($s182BYi֤KFЋyrKp`#)Ad՞w L^*X$>0jY&[]jtIOrϩ9AsORӭ#$@8V[c}[QE)A<r~2Ÿ'ǁ;a$0 1rAыECxL pi8Q7G'XO7f%n0@CwE, vawTyDIJ?v{ԫbt&BaR'uyOe*{!A 0!m.Lu7 3d[&# hizęԷcE=Kehk^[:7_^ٝ]sіS9) [i7HD-ӣjo|J17 ֦GI,`(BS֭.m1Jj ($.i3%ޖ&u.N( V6?b-% \DMSD,fyćAyvшdAOQd wfS=ןՌ*tԒ,Zm|Cd@h > 9#9#rP3&zNW(sQDiC)E{+;Q@L% jj)6=Vc zϐI0)PC|%8pL2m de'ܤe'A,e 'T* XzsJ Ѧ&yȅ]NL1V O /BCg3t^W6[|AZZEڤnhľ(%핱@l]> H ~Hii[#^tc}iV?S Wm"ȭsΛ^UY:^fx5F*8<g b TgGcåR(ɣ+gxwv ?(/d| BHHO\~JjAa1è (jW*m߫u -Qե̅&Gۅ,oRmfmQuf=rZ=[Oh2M.[t'i7-Xr>‰:Y <KǕ?ˆ/\:F4l?_--;I۵7s X<Ƒ eIPkVT}]< 7Z\.tVJ(N.ar [b5?9Lɖo@q;@x[F*!˵͍LуLq|;Y囐Aus]VҮX/hgSI6r٤r:}@ W>*H3ù""g@tȬTUǛ|4SiD!UUPN g ҇JiPbՂx.h'j9xM2]YZ6R`6Z@"5 yul'볺RYi6z(G>ۤ+g9%s~UD 9GSڝ~'huΉCM^&jG$-ڪ {Ԁ|H@yI>^ YD*(ĜI² pVݭyoJZDHg).QDVrB),邈j\ {/`a(6z #Z2 $EݨP~w[i9fw:uɸQ O x;Į*#w>)Gr:oJ,ؒDQ0Dw=샡>Xʢ5Xsx再OsVrLWu0<50x{^0@5'| 4*0݅jI/e}"vp|vao5 ^ݒ6 UJz1v%"BNVy@nfQefON_ɲse).z ^N9P[b&Y,E@?S!mK1m,".,'Ơ% ?3CݤށY_ 7ʍ]9/Hu1bLy)=?ZwCmBRx2_k9-~GO[7ߐ6&b^B N!f tIh'y8H>|>bsjo !akU\]EbZwsKFFYۖR؊Cj)'u=XLԓq)jiC@@6B띀ÊO. *g8gYS.7)XƳ$=W!hUօAv9:;<Ól,YT *yOXN.f}~a_(jvmqћ k}=~./kny/3 QX^f]éObY!ĵؗC:%,gwWŹdrpGwPjfj B>{_Z$ja|ɥC;ն-RLSVjƱ=@֖ zveϭ5ڛ7tn5L.;iq4V] hKJVTrNf3޵SoZ?^vD;qw^UIIм~o\="*< v!PѢU 1$#cu"v!,5y{ _hO42|qSAǜk8)ƹ&dWu/}_-O Pԃ=rp{6Ag:hϬͱ9+"&@׌3MUYD8si#uTcv{6 wSFfD? g4i>WM3mAI@aݭ\\!U6E-@>cHLT}߻94_ ;B-~H?nd{/T(׼ oƎh8ӧŰZ0˫vgssvU@+=!.FUZ'K@Bt)#9 CMR"6-uq'7Ń{ᡑ&`wӆd/3+['g[Ӭ2V:vjTwKo2qs$c_9NlP16 F\7jIIzwH|\N^ux B'e_a K5%CD˫]ɢ%E-`ۅM!sO 7hW;Js/z5<fٶekHF^a")a-}t-)ex5j'K S<TEv|`;g+ʬ ?G GHsCPqNXd*ap.1d>\|I|P?˫)cd&  f=wF:36Ouf>ꢑ(zޔ`IMf3($# 0:FC>RXXUhljk/ cF|kA鏵M_8 TT6~W)@AhY)]GL֧?v 9D6A Z#fjmҖ#${"9u $GK)C`e`#bMq2&3(Ҷ"8U}hM,u8'O$:1f t/kS)P;#apugTĩ qHrNgGlWf=6B!9㫣ɴ ) ;'a &=1f(V(?y54h 2V-qlqn gU0 5ȟl~^OS%W] 5ǡt53|ȴj鹴T>-7r5h)rb-13IJ{gf'v09呐`?hA )7G͏ RpӿV8 62I2 Lf &l$Ñ9s+ D)MU}o"d6M XxٗޛHي pn.'/TÿM!QZPJw ×HVM]7w=աxg{ϧ[>_3plРrT[pH;đ=nʢsi藟pK!>uсޑXmʛiϠj)ʼ7TnPs8 `Req*;l~&\=f~&%sҟ#?ԫ|bPHR(ʃD(4(n)ͳ* %.%iÐrY=ngS)Ω6M9}kPZ/yۈ(iIY{~*Sa0F)GF3 Z 7~o:'vu\znY?޼~Sj0 X{K):rwM5.| }dv5~q<c[O,Z'YΎ8#o>I*tV0=ͳ`بGU[o5M2=2,ɭ~r@k|mL- sNZ37K PsWGPqy X| m,3vX H/Wݤ?F}ܥ*V*jDsWCVzi&Fѓ -x7q j>=O^wvkX=_) "x᪁d7,gT$X$u83utK':ǡW>z4.Ct~HꦟIX4ź3t›NIJvU. ܩ0k런B0@mqޡfmIO!s#ub-gA+&"?Sw1i J4;z9qY(9?#s~ XJDYJNj6vDZ#}S},>7#GX``C=u2=@|D3ğ7E V8-H㽤 Tv ac?/޼&m 2یtp|+[Md=?F@eXvC睞t*Ƣq݈"$dޣjnM/Ch9[>MZ%,3qc;N _ Pz%tc}6_@M#Q){Dz!r>;/FK(r ވ[yv`$243c!O֊CvEͅ_> ,̛sݵqyF|(p\{ D^*DoVe8 ^v] C*ྟĥڇlhOB[l }I9[5Mkh <„[-N:c7D˽CN(5谌\/S\jY;uX*M=/k6r1v= tenv|BRPxC0k.jWI~ ۊ)rygA97 OCw_:ߩ:n%^I1cӜF,:T2W4>8}BBs`gYS*1ʹntx[&j4" AX8ƧLmtF27"dfQ*6DXveNK}qQnVY>ꐩxVM?qUTxt ,m33d0I^+*ǫ$V䣂{u'{Ɛk tJx0P)=KI,J$g=5B79@N}0 D:S:b"֙HR(;*]UfvR͉vHL(7r݈/+G)ɺZؑ3y]1}-t T  ff= >q?m4OVջ{VwFOF~jl*Zko_\#rmxz0 (rHs) #N|8Pcy82~>4=!}Iظ@ˆeV$(]1t%Ќ]a3.u]O|1jR 8BB1cGk9ڸp4e#Aj<^gSމqHRs.%t=L 0Ǯڸ7~)=$Zk=ARdjx'iV}3t1pNx@o.>N|%8H넏|~DD RC԰𩣩ψ7PF`O_TQNYS+~\8@SC5 t]1Q$iqоsnؚ0z@|$'DZemKqbuё #9[b|5D 7@d ߬ WVSTw='v$\8-ϯ;<[f?sCZ gKHIMOWQ{(B#E ƤE {j׫n`43dȡc_ O`S_d:.y3Nơ >^nע9>oܒna,M~VDu6O`}xi'{Ikp<ᒿĉ|)c\ Nfz ("ia ڥ_xmYf\+s82Π=!ݮ< NNd؏p\,b{׃w~jED{`=D"[X")M/~T_1Nّ\\ȽKv[g'*pŰG hyA <=5I2iS4Ih'cH=>X[.fآxybs?OEfEx-{zZP(5!nDVR p~RfUϳgr08kx ےWxL͹%#W%豓aKA˶? K"yI@zxNҝ@q to"`g*U3|)RDO&ؤ28 ?ط >h.PYtndEc d̔p>ch'>⚜'چs:,1;zHHbUtp_YTN4FYLEv0׮VC_"w&^_LBc̄nbj0d bu<7xb"vS"Hǣj@c@&Š1X7w>\R1je *Qlxp*Ҿű7Iז-}xwlM6klv-Bn`'ճ 06fgc:U9C.Еlqa|v *ۋcB}?*k%vDv|zMu>BrȪE>vS`tM -^Z Sii`gDXFƍ|A|6(L,V^NS_K;_-xG:C&u`Z3QbMq͞<ކw%S\myb۳r\&wYN&T4ʝeƽ\p.d#LzvYI7'8: zZI:88wxD4anLFs\[6,Fc'wbgCfnvN&똣>25XE?Kp -O9tTH)cW>>(cj!ꢦB1=yMJF~'Q|wC|d㓉dgtԵMYјa*JƮ̹ xb~Qo/* )̈́?21"2Y3F)Vщ*Uч2wsY35*jN|1}HLpӭW8pyOgoZ-(PL|[Z;hQ](㵀1k:Al4 +#fSuհ8^Jm 7%y}AxԹ}5}z5\@ ό||_)<u,%ib?낔$8?AjD4!gE04{n#첫kǡ.lRyuݖzEۚSqoF:w;V,^`pqَ?OF8c;-HOAڙR7Vr ⋭>oφAy\'?~_})2,9Ɵ-/U mvEF: P6\_]OZYE58 |X,<`Ip(.$C(K`AtegS~,I H=C'rZ}+$n3#~!T*fȲ n[αS;t̔ 6>}?(9ͪkݐ TT5S9JM@! .˜E ѭT`Asb,xn[OU#4(rQ;#8ys_J.ٷ 2ѵIiB&Y#H-2Ʒ0g l;_8q [cU田_HSf}.=3iN,6F]%w6Ygpq; ,Sa!?41 I[B)";oj!"d(] AE ޘmnr | $10t\ʓh.K܄K$vvb[C墑>!]'7e!&(]_QCc n1"u?: x}]֓A4Y4J„"P?f?eKU]x u1Cc2A&9I#kFN[o"GM|L [*:W=Jv3̆M-~ZOqE.|[, JUh W }+Y>JD$чs3Sy|Kޒ~|JZgҲcijՋ-/rXp‹% *>5G-~hD~UsQs.-}Tf=*S7: ;.<YCō)gWߜd>ߢ)܇4EfR͏ɿ6PS.㡊fg|hd 廙)%rv";/M?hG9fa(~c @,+pȤpjwܤ8k/k40m=`FԍZH] jBhv֦"n`H t)'4^z%4PYr^Ȩ^ Fw$ed.FoO3$,NS@ @l*t8${(,J`?^aZԗK3̈^$gѥ *TBV)6$1F֩cF[j h`6ց8unfJF_@Izv  EfĐo8qhG+``uDD8.cT(Àb3yE~`N& fN`msЃEKM1GH p8*VTAzIxz IvuX\Y_5˪Qۚg*]k_`2anڗw+j'i-X&SOeO4#:MɳM*ChhNo\5h/L"hF!50G'70sƮ[Hv#%~$*1?9\@yχP}`\[aO4Nb&1:{&\6uW|kRl* YR:mP283L_XE6U+c~bcJۜ34#% ߉ )ԇLu}(y9ry%bPF*;%sqcݮ|pL HɫƆ: xPhXIa`?hl=yr x}շ8P1+yWZ;;ZrjByq 1Lh=Oy)byxuuNAg^R6 K n4 (Gx!Ms ?PnbR[;w`>YO_4nM?G|X&\,&; ɋ_ytL^{DU+zQ;{L@%:]Xu<,H{eePuk1+>,)U# Y٣zuJ%YؗHnC~ΥMz_W=-;ꏜmgTܖƒ XfO, M\6F_XCgfZJGsM5 :5EVr9{kk|A=ApN.N39KJ]_A. }O{7SY du+ bvCQ9M܎"`"Torg!uONAn s*;1i>hS2*Bϳ-VW{>r A[d]3\dnl=^eV#$R笉n-PjϹ+mQ.Q1`{M@Mzb@1!Mvdj:5Z䮗xԩ~hv}XzRX:l] i4-)\Gh LZnVcwRl^` D-F>p#! xx p 7$0b,g<Ə_/z qj žGL)tck^)ަG^w,#3,^.6RQkVHFl qo Sގά̄wY2WS%xFE٘r\u ! |5JZ])M;ۍbJvH$3 ĂWF0I#>甂R|c!$PR ZaM'MxfD|ץ\=hYygMe;VҭyN g̔ވsH#&}O(WC#r˧({2i6q"bپ%mb\PS>lҍO멋tʵodhR5cGGNK롎:2=.9$M U=2Vq k M^hpIuP[|4_q沵_Xʼn6LJ'*gؘ֠ 0d_D.GYV5 fiyn[mP81p -2ã8!Y8[@XW?S\IVcC1."dÓYƛZVrVzuyHtNN.`hȳ9 F{"2|V.pQ*|nNLJ=YR0 V,-(%+R{"Ԋ=sQbˉS[؝!!M~lƇ>_0E4K(?w4|u,q?H+ސ~zEC]B<ϫ>jIH3_/@AH2#H}f.򉇻hVfr&Vc*|:qP M[=KzWr9 ,5ٔ94&z")Kqo!:&XG7}iẌ́RZ+FÍ~q8-z<%~yp:gTτ^ 'uU+)׊JV?uԣT,M@O@f^::s!RhQGb~]v:QGu`Ԧ%WR U c+③\ΤGLG ?D1J./`q<ҿ$ #Pq ^"cݬ%L3 | G ܨeJT|u L,+9]ER,BR!u`voMuW|gwCcݓ l# ؟QeG8h !c6Ovm~|{ެB=}J~kj+lj#XOa/sRw+Ha 2BZT g@y7hQ ezW٢7%ѓEB/ v7Pgv;$yFGY)> |]VM&/u_/EJ9TYa2E[ZqQX'VORq{xۿΉ\8 2}6e{ _{oJ3qOV5?EKCv=K"/.X2I1@~ gM_eO-s WS!fK+zgH fH^FVFDŽo`T/eɋR+r_"[|[('y*po ۳ РXGCK3 OT jO"\AcstR6Du8;6Gb4W(+Hr{+@R`e#ROy~Raŵ; |,sMy" Q1cŊG;M*>S9`(6uChgFu[?x!n?X_dYKzʰWCA莽R\QG`Ȟ9CRaf}QZLkqǘzxب~]Q31LqFL!)lZ)LZ>R0|Bya3sy&+ZZUo󢓯);6(E%7YW M)~"+ "oqY_"R?|NFp [0J*m}d'Hc?|`e{]wFbc2fwt}ItϰLn=|'pIK ޠ;H7s8 чzsH 5x>k "9oDh.$hLG1g&5XYU%Fؤ_?*'4ҤoY{uTڃ'`&ȾZ`<+S-"#Z:%+1V}\(mac}Via. Ј?22Y.~ZFqA$?Y(zM1jK||h^f֙zL ^OLR4w;,Jqё#w/?:MhwCab+a[G"+(; Lzu^#('fXjlG4/##3K\70Y<$Se -tVo螟5N˕͸$ ; k _B^ e(3Hbo1zCG!՟+1A1-YU8g/t+ff1va*\wvBjF!^VE,!R5 yEڹ; nQ8H(YjR[sf!"汙r&>/c~5#f m^!ҩp1c@8i)B:SZ2x%[-]A$lW+0UAs,lVR+6RZܘe5Kjɗ4K4/4 ]-Z]N@xvcDg=->̐)1n/nG6m@D HynPIXY6s19b]K2עǏa 7O]J"1bV$mAh4_75_+ ||?Ӧ_r;fr;dJjMK;phO8Uh\xNt=d63Ja໋aikXZ?}gx;4U'Ֆ~f.+RZ= xNMȁujj{%;=UfTʬry]S.)aNbZ|׵d!nՂdFj<$sVؿ !AWp.)rQkdӉC#bx;tpfGcJ']&p;~b!W:\hH,/ sǞ@B`qɒL*<"Scx(Kw %zKrɐ%!ܭaAE,G5GY4uipXi±ڙ.J߮,t#!Lsa/S/:-ԭ5I^1]<= Tҗ )W `)uEV]Z^QO|h{f =iqY3@fntF=Wڲԑ%H$|\xyUDY`6RzFZ8yT{4l/&"sizDg<&+.e9f^ON*aP0',`D..&ph4@7i AՄE_kw!.!bR6]v`AA4_ ?HX0̠op4:#`Ð֟N93`ėUtrKoWmM~==( } (8JcEh5hKc\J| ~@тu TDX$4t*.aqDC$:nli`C2yk0 1/+CBGm_[xm<#8K"O^GVΙ N|*XuFj蛙B,d.8>"4'!ՐN?([Jktw9[J|D3Q:8aGe//K p<Zl3AE,G4jZz r<n_$R8P^y6,`f;ӽ^"fƪWLR4Yaz _!p%[WzG{Xᰐ2tF; lr)CPCJGk%|#l)dhT90ٴ~3*I i8n^Xn]>N jj;aguRlDg;!o VXʋ#rD!TOMjdyi!II5$=8뽧]t B᜼hɢqn A4_ GPS"ʳht=S_6~ʸr*,_d=)>OoaYDtM&6ٱZ\&e .mFĀFu˧k1|-)H&YMdSHNah._e>b4 ߒڛA~-jY?sX Mm,R7ڬPAw=]P]H/%mb>bJzB5Ř0,on?۱!]JMwnP)@?6/4,8R@J,9m7W0%obUWX8kz刮91dSEd<Q.h5\uLωDnf/EWå$6W(b .1wM,RЭ1NbϭV1`AE,G3 Eo3hc4'l5[T'7NrƯ2 #JE]D>!7HI1#<ЖHr C+bz9R-tF;8F1KB2tǩ`}#MM;Sdz>?i/Dg9p5Ɋge9@Z {X7ΐ!N@5ڡ(oѝ :̴]X(4Tx64GvyT8<uA44_ aWjO_H􀇀?;آ̒qnl%02i( . w U? t`_ rÍC %toѠVCFT%}0C XhOf |Jْ]6=Z8(W~oySmr+OsMzܢ*90E[ qM~ox1kƪ Q!KcOTQ #$Qg6F Аgzx!|_WR U)tpAWI!rYUfeAE,G1(xd&~OhFrNZG~uZϡf;_=rloo!A GQh B%S*NUHǣN$pGE'D&G 1b`]j,5$g 'JNXx)`ioVgaXwط>tF7[ (`ZΨK;'=*PDg8D/}ꎷ5QznE!!3U*"w0A4_ t1Ƒ?$|[Lզͬ~"ruVEvsOQo`uѫH77TJoN(/ye8uQ!a0t }16 U~*J4E vB: 8~TÄa̳qGX&oE^v *&ݨ+lZ@xX2?,3`n{t3pk\מ̾ML]Wʯ^[A6mP]Ӥ2LqrABE,G,'ݢ4uԿo]$÷5f|D*SqA0< x-%8 !'M6!6My"KatF5l#O [g@st]`1`sEcDg39tdEM9 6ܲ !IAh4_ ~>  ME:lz>qlxKj]BF<^>y,=;L+`ա/nPt;exț}']ozGNjs$K\.a/W}.pĩ";rq$d9 "a.T=N -/mE' \ssehwLd)~W>`n2*:O$e7ڏ>I&T i{z7EqQq0VG# 2urh85nZTb2 F;f]d y;.I~JWM6T.DEYa]<۴e a faA$imuyq2}J[lH>G̝q%bݷnᗗz:Rw0$1̚6О=?*LgoJЗf8Z*=T4'.?u`xL0 AE,G/`'Ol½;DVn7V\0aV_ gmA>HJ^|!ܿq#}]7`D͊suལ#SzHgzSy.c#ܜ2NQ ׳A\fLTJfŕ݌7M]2]0RW;}Vv)W}~i*@9nTY|/tF6ZJ>ŗށPco&V9ޑK >K[H?\`Iʻos=j!>4N`8믺ԑ6T>y[i4\߃vjHWsg&r̵_iX{.FDg1UWP!vuH5p}  A4‰ V?8y&7 G9rd1Yp;VF| (i=p3b)G[4հm% (ߠLW(QW#s(}~藞!K$ō&\ps"?Q 8ӟ1? iaP'E'w֥s.]VVG5U=)Hzֲ6 \SdtIe`T.@AluPj bT,yd҉r`fG MƩZ["4buze6y56BПUM=Ja%ͨ%jʯp%O? z DgJ[ 뜊=OgPsw3/k+z׌*Ao~ױ#T\D' &L.LPUABDg72v b];]r8A= ׾Iܮ5YiV`ŐΝIi}\E;bDZp__` !t,n@lɷ& Gg _3OvD5= i T_Nd9mb*Q>+'~/9M-J`܏EkҞ*~_"vҥX<>(զ[5O1rR%>.=ؘb-6Jc$n14G|969*zY)IG;ɭ0x=XU5Zpdr3)n=G:6|H2KQK okU2F~saj{<]`aSͭF+VLSp-Ц}gp^2yֶ5HY$ cxNy{0_Oѕ{cE|+9t@>s** '=ΙpjJNϞ '~I<|E>L3KК[p6%0xgF4S$F4~)Cc7{J+SYgO ?h滕O9]s;lxwUQFh ُ':DwOw+DmY[aZ["1n s Sp@γ,N15t` lu@M_}xRrR4!ѹ{#ZohspLVD {IܨI[j8 0lz a&Eޘh=P6!unTS-FdJw,U3m֢Lj ך䠲)s0RZKC*N\l>5qb#^:Hg#wXPG?K344YjNۏ/ P% {6٧$ mj純Nj?A0#q ne6-ΆD-^(RKIM+$nQG}rW7D-nn͂@jIP MD$ȈU)pZ \EvwqN߬BfǰL7-X`kp p޿ `7 7S!T~LO!ɪ0Ü`aqS\g}ֱ7]\Ksq~p GB~8E]PhN" 5%el8[Z}q%?S:;hoRZanjdF)FsIgM٘mqn)#2ޗaUVW&@zt+< +j{]~C+!ϲ\r XopW1zI+4cZ/%`b&Fqj;yDxEt9)!uH&~ 4`Ӊ9WQIf3Y߁߉6U%; Rҍ,UlFS\=\ƴh9mNUct v1{_QFW>JIU g$[x /Р]\RN( ڃ[҅+r;DS"AZOr샜L %ȽΕ'$Q a_oR"MD(|)1PR/\mO0@8֘Xf@e9bTI$sJ|[ϲ»SUNgqj+ƻ?`JD7#S.}ŋ|ԾZ7i}Jn65 LYv[rV%#",My[nD l/NW+,x=k-h5nfԣ2piu}PUr"zkyG5Q@L1z9M6* =Y5Gӵ95L|@pzCEWO͂၈by_ _-w& F*Щ̥rhķ|ǒr31As6{eYBf);F(2KPK h\^pn,{ ʐQ,`D>X'-0Fh-*dEv.~tl倲J +uR!&YP_a;?{ޑ>y#xz>ݶfFE La^_ 3QWcf U+=/Nd4 (QAE4LG/p(5Eh[߆"ՙX62.Ι:'z,D!,cgPyh|c~guk"тqHn4 Abd'~ziX^dO5gds"re̮VO锥]5؈6>600@,n*Q;.b1g5@:fI㘖A+lCك2=6'iNI:e*#F~ߎpSpAwMv^vs ީWZJR["1C&?) 0@[  tF6j#/y/)EaFD|"yOGt"SoW+QCK{:'R;hmS1M"y2 ,wR'_=c:h; T]t= $ᜳPxq nK?7cՇ{yMz<:^q $sWs ֽ!gZ&vM %`@T2aglLrgUG6*+ӒYs6޶PZ Dg4S|\)EXn̮j]K,l|eOeW~{AnA4_ gBn' q0mK,Nd6{,C?5k5^M'\3ixp᣺QdĉsPv4g@Q5㔨#QCb3B?MO`]UGw嘘I.R4[/t8ZN WO ՙR^ʥ"=4[gsR%8CDΠg,FV ZxWNPk[Fꈢ{l_:f!skSXՊ1Js0/ytq VibjEQbG-JTCNz&QAbOBNyYiQLvdث+m'/jҬ o4 Q/T֬[^Bd(w]qg_v R|3EkFNM:z,$HTkSqke>7"9`hp+Un:`l#Y<ͺLWx)rR-2%kg7 EڅS 6sQØ_`\5݉\.LTq X lB˪;/iݑdo`'xS .r譕źlݤ!\{>~Sq0 !_FsbP C>d_@ <`[f+WNHXF|T>tұ76U_2sݙIFaoMT2 b8UZV49 Pއ4G.B(I cPN{0K='޺q L5SjF>z\g~e%E)ZU0i.ބAmB<'J#*A$/.+m@8vv'ʲtejY˜Oa ܞi=LLIp啴co%> Z7PQhIe,z;,/kq)&G'MϊE%6;COtF4,'78 MXke!da OﵟsXO:4q#]nl =}aso, (nE +B58 +{e~ ~fG}ҀwArQDg0OO{Cy, ٧Rrm$Ȇ-=~Q rhܘ<d4-)lS_vk0CAV4_*9ON0b~@4XcO(T?[m,AtE,GjSH*tFz8)DgA4_ RDg{!H/x) z*.lU_8I#wۋ9]NcnUZs􆴶|NASm%Ł~;}LA&=n5&޳.;3$ Xٲ1,- (駈lFKfuω)T Qq#w ojSG®Bن1J-H i,ْa:tk&}#i~͡6.,N쭶r[wZ(|~2WQenB?sJm0{rmo^JRkԽ ۫/!o. h& 4GeZ|6#{T;WdHp66t癵e`~:ͦY2@wK]`p4#UMf0ۊh!D7ˮԴI4忙?9s I*Uk &Zl,!PgK2`#CcZր++*c)cR8OC$;tܤ(/>jl4@e w!乧&S1A4_u8Nɳ g`!I/AE,G jz].tF ͤ\)DgƀQ3A4_[e+A E,Ge*_tF)ADg/AF4_[|<+AdE,Ge*tF)Dg/A4_(d:P+AE,Ge*tF)Dg/A4_(d:P+AE,Ge* tF) Dg/A4_(d:P+A0E,Ge*OtF)QDgfAV4_RQêʰQWPO0,H&1HކNu-퉥[^ݗZ%T+?ByJQM(DžkbkbCx51e_Jz j qs=mN&+4p2W*0CN aM@k:`t"{ `uEcaAax#SG߻˯lf0WO}I #* \٦DVnݩ.__43?N+!]wx qW=) ;YeGT9b*quufjkQc  xx8t< P0zH@ Oa"/j@+YXrqKTH{%g [mQP u K֒ߒu'Ŝſ,?]^P%bRpPʇy]qQmر\ dnINM0a/p<%T2CT`ǬT3B&g%|V b=#MU ]1|`8Znt-kBCRd@@K%2p>cuJ~mIjZ8+Huem%hH7l"zNe/d1G,뇕O>0ޫ$JhvJEэ# ! %c7d}D k"ׇ]53G0C!Wͣ.=֝cR`"~" X$pO⎥B'anh\k,@cGxoeMrD=BRZ\JXPI39V ٖ\IKO_II3êqdmbn*غMU!p~AͲֺAFD\{jhvCIr=Pe']i01vb/p Q'Gca )z'׿hGyhE1+TrDoi{kC(֒EÙe~l` i؇coKGrǹ pZt1N^+aBwa|V~y(Q5JluCvV~X>HaxoGX"4y^坷䚲1C $:dz~pC-;c ȩTrihYgʡo HUc}ި}6ZQxqi M,vy6=r2Ԥ:451@(hZ_ iLmu5=/ r/${oU}52< xѳ]]NPm4Ir3-5pq%I1TQAtE,G_+'il.ux+ p,.y64*co[-tF v>. 8zRDgG] >pa@䊅7q/ԺϻGfDqs&ۄPPFeNsE;¢-LXu 64AryU~Ŗbk2ʖ.Dd[AE,G`%uFh"lOqdEwU#(ubxMG1 tFp]1. / DgpHKx /A4_(d:P+A0E,Ge*OtF)QDgAV4_ ם"@[ӤrHkI\yA-K'=]_-*0Z^tNÉ9w;.>#V+!)C_#,acX&AwZcYBR4=Vgu>19lDlX2Cr%)8e/ CZy94?SpAd]^)Ss'(FǠhɆw L,SG >.AtE,G*}82*tFeDg2lΰ{JɕH< wtDvW+2j!E)>+߶k0/d8A4_ E7}  `y1l2~6kTZ hCA4]`U_ z^V+`A<gβ&U2+yy: V1{&‹ԁFI' J-9"Ԉd}3aip#N`LAE,G*VITϕtOr*px &jCF1`.tF2`GV/Dg1 s"vr@ܟ_"~j{vc8W&WHoxzy:@ۙՕ}hsd#SV,¾KoqnXS9A4_ dj%zpSGW4OF\u5mԣ`sN>j"/@*'ު.R8}v9x.cx l=V<5ʦ:_e𙡴!.U2Cr ~pĖWowp=dQAE,G(AKJac[~`Jn`K}Kz1J-܏#JYRE"'x{/ E+"M~xѽ@C< `A4_:bUb "}Qp'^8}q񡤌okxgj%PkQlPƍAJ`OiB3Hr2H,𤑹dKFSnGr(4 GC D`kA E,Gd/90SгȂ[RALsu(z< @vrv BVW'58<_tFYtQ+tXe@18DADgWIdṍkı>5:ApDf8AF4_]Q݌vyTBDƶs JhG>;z8JcJͺZ HAcBd>T[ Q{a%yl˾Y -MJ# i>4omq] :U4TrՎ,]\_t':"ȅE :1&x9Uzx YUAVAdE,G4s?eYꢝ3Y^+O3Z `}q+tF0JP@KDg%l0}=q khZ Zp8PՕW<5M\ RI8A4_ߥ'*d(PqmgL)M'!\-+tt9LQPHJJMDpQp]H}NeN҄"jjӊfWYTR.B v3ͨvsE5ѣv?U):K#%b8^D/c_tZ6"ܒ ;a}X ݸcd+}HQcX޺/3 T*V:4Xa+z{45Z1 8̋OB,;5(Q$k%*[肄@kx%Gq,5&dπ2U۾7rY{ GL$bʟʁoBUyoT!쑊 2Y-YB|CGy#ʩ;)u *_$W~c;<.nja½("+gH=$-wSK{aRg#P+h5+OFތn<ҠKgƬ0'`szCeg;b.7̒y^F?/_!F zN^ Hih }]RԜ1doi'%=N͖iG0q4c/X\3ޓ-CmfYchITMfÁ .ɉЧd"bhN6uCs ߆vm|ϻm4dzeI|B3ژ]Ss\7V揚˱Jcx)|&|2eS@hߓ )P_Ț6hg6A$wM Gp#^NY,;D؝6L܋q ̻l"Jb6QAѡ.y߷E.FFŋSAE,G#ݪ;qdy &zUqx\帐gh?YARZ+بߘnIwάқ85#(=fu+NߥnkZt\t{uq7Qft ~X 8?)GAtF)_D&Z473Jj%wADg)a^}O/ko"}FWߨq,sBtyp]m7O'A] fMiO D-KB3(Nb!_Vw`!:3'"k"mև DzIA4_C})r)i99NS2*Ϡexă1c6qfulr60DBs/TMHNTB s?Kh?8XG{QE`_v:-MVU[#W_#jC&r$^&.OI N3/.kڽsύs"'ıpBDu׺;|.{B=u -$*ρIvjhPD 4-z*hg֎Ao3wR,˞Ykl +aU9TZ=' vϦ\|eD@{><ĭ`=,&)d9=]gQQ^w3$l 8['+Z3p[Dހ#KAQӨm ӭAaQAE,G軘4 3bL3٩W' $y]L7Tq oi:u}Ɛ^%#PW2_-V1 tFţ1J起G.2tApChcD FlX?J`i5 M^B~ ½R gr\c+lS0VI=ɱͷg&-sC˿@0+ˡ}W>jo>zmz|# 7{k6ɤAU4eHf\.;(' Dg!|{Ї~V rF (2w<–p}#{%.4v;0}7C`Ȥ HY%LPkl+ ,->h V/gđvwKlq->r5e0myݔM?RPKBns.M5CJ P+Gr3Qͽ}t.lǖ ;1OqV_ )lEkj4ݢ۵FH*_?>ah|۔"JҢ)I$Mӓ.`ɛhPS6s6GiA0E,G?Om_ViČ`OxmL%MA&B_W&bM#aE0 ғG nB׉Kj7噅 <8/3VdsOP:H]C%>珦m]@+fAřFCY>ra:lWDПDIOtW@wRQ!˜Fђؓ v#yA^ު/V0e,үN4PS쪎0qBv)~ux0d*D|qѦݓTȅ:dm_KXw1bOtF!$jz(h܃Z*`>*@r X9 =C;cPTA8DGz4}(C#$]e& "S#i!7gn^nV+ g ХJ)DRya@cM#c믺kLF 43x,=b7 yZ px[ ?L Ը>llYɌz0"pF!ӱXc(U{Fj+Xg%x@MQDg\5~x8i?z1}9 (Y$=MF]//#6ܿ.<0ZN.UAѤM,9! ]N@k/5҂:JƷCMWrp5LlsƲ6vD1bBg6\~L}PnߟDR#GXSwF>W :(crc"_}b>u#Ʒw<1G=AT4‰89>j.ջ : ݵ":2g AE إj՜' Obo~Ԥ|-b_(+gT,1\)~ EQς B9%24<ڀf?y"W:_FשD>˔ԕd_n[q|ž%hl5BR$ֹ5aP`B"xy`;\䣒*`3x/^@'wέ N/ew/ {VN]o$3!f{kjx$&R#ST\%˹|=T/nnc]upzVOE5/ BsDg)`>|dr=*Cq%R%ŧ~㔇O.6dϰHy&N0R q&xzI9NaP ^_wRbf ò 9k>.Rkt Rw6 /msuTq> Ax=Z6Y-#@o(,>]ym4WD>>mu-W[Oף8AbGjM f 28- rJ&m $5:99V>DJTvԪ3FxJկ #v7fwRQ2WްILNj|/>zߐ&-Ʉ}X aIg=u XR I08m2ե4]kK #=oh 9;~΄ޏ (rwD :z % +GԃjO&kU< 5z*5 '. |D:ؿ)xRCT:Гf5?fkUw2:1ci/6Hp:U e7A-gi`O".{nx'e#~[eaX~Yaa*֗&jքR_hw{H(qŶmSP~ԎA,a6:{OC#k6a(lU]4!@dGGtBb/sN[O8/Bƒ,{9?%Z$ҶKkՋ*%hNB4h7/=FW?A~VDGe(3.f^{u/N,um jv>QKT.OoC=,ֳ thB6\x yDYPc>UڣB\q'gf&0 ]2%BG_? 3}dHkkgfXlLkȃ#QF 0e I7AԀ|y2hߢ<4^t/Z:)nq"M'B4G P3$"9u:DrwsN{šB"6\t}@'Ifz4J9&>'V> 9Wlnrq1ݾO- {'Uȃ,UŴi L+\7]GmMpC#jÉw(\HCo4OCotz:C+_RSTHy߳ڏٲ񏜷'\Qy{1S¥UO>@lA8,j6鲷CS;E֛ A# =X9Q?)΀a(Q*ڿENWEvtX[- OL3{2=0@sp7t0,8L#0of. 6 ,ʎ iD\.,>(F'ƹfGfe~(VD"5w=;>]ɗlG3?R<~̚Vq? n-QzWpoGt~hp[~)!4cu7[lOd]CH?qguq\P 4h0fp;_kX;[ʱa$Q\'*pvlUf6ar 6c{Sߤar$I\N  I]_&ٯJM"쫈WTa>[?A#/y 7d'NOײ ΏBw>/r@FHWrkYFŻ*m8A ^˽\T,P%||b%:>`+<8buj8ҞN״mѩ)Iy(h=i~O~: ;T?[oOxgQ<w@AE4LGff]GJlX wg Z+= j҈Mk<eyDc/X.~`q X9 10CJU솶dy <e*0ݺ d՚rNX)3[E6,*aGp۶$Ü,~=_\S\2N$;Sv;ߙ2j%Yį`9(pYOdepctܺ:ixH BU֢bM 0gb)iGtbr8@md\dNZSt!F*sOs ^?xA3r>/B@:RY/Df&_E3ca{B-$Q7ƻ~ =#^C>Lz ~tFBXnJABv,8"SbrY?-o{$/(x$曌K1M~҄)VJZnAǟ+0$Dg2G >b|>I\BYn o~X,(8>Gos stEZYvLةQѶbB%<lPA4__@Ŝsq BS;E=oG]E:ZXfK 3~iy= h4]$"M]ɨ*ݾGjK[yrF=Gig+X}񼝨Q_߭ԫ$b|K2]֐',++ڠPR#mL|Y/E0N6:y*IB jXs}_v'x6Y}q֝;tQvQO9eo\-OW ۃIO*جsG_aŏPc74uHKeeDYa.vut.bTeUQ#}{ۈ1ݞypf6۝gl4 \4T$M/0,MO' \p1۩PI(gF֡Y!^rY/Ӥ n5톴-ګ|4[;yΉX%VF0k.f [E^ϒhVK#VTsx@ pdcay=#m%(V<8 fvnAE,Gc|BA8)B)؊bVA\>d'{s &2(>ؐ8 9u]tF hr-rz|ˀ&$%RҺϠ)ijgPF$+eJ zn1^K4YD-/%VDg;G9zR7lZ{*ow]1) : A4_vT@6a(\1Exv}HG`pN=( ڀ\1o(iN_֥7}S2UlƢav͞ Q -'n}k^6Frzkr_s!b YP|6Ʒ}IHu-ӕ-kwy1QgHBsQkA%th.[ށo`&`RXAE,G挢F |W\jOUAW&IR>TUUp y.=tF2h+?Dg8V0A$4_JfKezyn6t02+T -*E{UB*1oK%"ET[9w:ZE|_Q}Ooqx}}* _uqWtdž_K⤽ wq|v.`q@uRb G 3jz %aX+IPNzS[e ]4 qAlL U :(x!:9irQʼm$('/Ȱ*vBEUSA`~ ò^=M^ٿ{c muTB:ԫY3Q~>鰒xMA>;8{;;7ܕ5ޖܡG,%ok=-]q˷ /1Gr%҉|Ǻ7A8bXcWdGԫdF5]_{!Fw5 GI_?riCԠhrOO*ycҹǵm||@{\}ȉ[fC^4Jq?/ e9(exvf?R4}%ULDY݄6ok)S. \8T뚅Bڽ鶒A P(Ӱ\p.7VW3% +V?w6ou%~0trDě2-sT ge]Ru;8׏e .1VN8hzɰIC3&ټ>61 `Bj>cK@|q|$@Mm$rù#`m#`ͮ[0zCKbR wGV %*x :ɉ`1+s)._a>A窟@pW)lQ/̴"R; T\au(AJg@3t+aҐ`Y~ 6Dbtl剟 `ͨ.`0mȰO s=fKk8<,m~)p1Q7kH Ɍ`8nk5T v)& ^'9~rHm/twV1 "t@=O<=s%Tm9@/ӈ&@qJpOM5]ջo Q(qjIv@j@8Tb_%|4EѨ>F_i w/dm78pʸɉ V*v!*bZ9gAc?'IT)A(bbS~G j|9Q?zRg9OtP7xj1Ou>Ifu+ O{ƥsNJ7Kqp6r!Ys7d Y4 Ȍ -@K*qѝǹ-vt "H~AM/af@, 89>4L4 ^-!,>5sQK.m)5,yhʋ>2X;hUP$i95nŝOہRWaE4;p/C.OX4(NAlAd8\#uJdRIҪ˧Ӯd rn`K*]o $_Iiv!N*  L/<PɄX]2I˸l#6 &(Vte ,XB?цӾhD 31'fgc hPjm& tS[+?X\4X {[#N`l)`pkC7ڇI].{SEt `Ԏ>5f.֒U$^}+]̍y OyNc:p4*QQ"kARE,Ghi "+~ŰQEb AFcxxOj3VʗIK/C$ Թ" n_C F5G;Eo,qtF8eJ[=sDg΂ZԠAS@.瓊  ]Ax4_o<{oMPjC%ǡf F5qs_VFT*R&9Fcx+AE,Ge*tF)Dg1A4_@u\x?+AE,Ge*tF)DgA4_ *Nx%5q%Kp΃?/߰{z-`@yr~VBhk2zCYOiU ^ca9.2-AE,G0@ RA,=tF7)?Dg.A$4_YA+ABE,Ge*atF)cDg.Ah4_Y@+AE,Ge*tF)Dg.A4_YA+AE,Ge*tF)Dg.A4_Y@+AE,Ge*-tF)/DgA44_ s_6Tx]@0);e]\yvuN T[NxmGV3?mꬌ4=ƷoM L Ue ߱s>vufu6.bCXqԆ>ze_ؔtO"r7B-GF J _x .ARE,G1B?0 )*qtFFsDg9@G9Nf|^j>ˆL2b ΋'EJ@Ax4_ tT:Mn9/%=\Yyɀ b_)^ҹڽ󔝢M7YCAJJUҠCk>#AJKP}Jh+H`WAE,G7|dzT[}f$fD('3SuVz|k0;eجt+Iyi>=e-&g'\ӈd7?Ѫя@ VdǠtF?3H172;(_bw` 4ˁz): eכ=KX8̡DLw{ 7/xw4CrKc +-`؆T$`Dg>qyL냢_.c[p[Tۥ?hVF؊`c@A4`N+|Q;MxvjQv”bdS:lA'e3`3{0dx7J{JE[ nlowK$(.$ThqVe/%KeIuQ:7o}C= >t h'ns֗Y{Wv"_dNκ[XV<܌`Б_/,A^:4ZhѺu$hc8wkK/EaP~bsD 6,XK\P na,:EdRl: n04+^m? y -8}w 9&@ctirNKk/V@䆳|p1nS"}9cFV[xRA $_b(@*2{Ѥ4c'Ӂ E%B( .3y:J[ZL+pwA^Zj xC5vݕ_vFhm_kH(QPBǴM6C <djcr.ǛGoI>うzk/yCm`FbNW*7G,K< s;9+ x{)9Nu ȊJKM?~Υdnq!"tqb@ MtqWͥ*܍1&_Pu: c9S,ӄ@$yB"YYP*r ȱI(6 f'GqSϟ79QF r%Of 2釘䇡ZVxine|_=\/s`}jqǴHqtsydqD.36+~ )cikv*arҼIuFpsZ-6=פm}SRB&b',]6mc'HGuf 7/n̏t_ r-|2'㯪Lf"K Y oCCy-4: l-K0~8goF˙]m hmTaŭcuónﵮ bp?860̥(bK&Ħkb{yNJZ~rV:8N;u5͎k=}Mx^ 慲]}juhbO|[j\XM u5X (e+>)22P?'@ƽ't?Ik=͛W_ _˨FǷV~lpGw :6goF͠U;g)$mҢ"sO׮ZF:55kqg:vih\QYg6GV9/@,O ]W|+حEnr 7/_%JfKjUl)&΢H'ӆmÓȩt>_Njq_.&SJCf#E$-c浇|ȮSޒeXl6v-5ҭ8Qƙ+"u?3f4M#Uʬ߹Hȅ*)"Uަ_V30D ڝ2 *77#B*6U%v40(D<2̷%4b`z7])vwe)XG+3? CLȁ\ju6Zwg8).j"%X?( 5`V!n^>ͥ-uE@VXTUBֵˍ!wDu@|x^)7 !__D: 2˓?(ÙB H::&*V2j-W^4'qtJ=l"7sjbmU3ffU>!=f^רܝ@TԽWtΖ485x% AkƊTmd0O$pL1  0^_)$lhxM51q{PI@3`(>wY-+rm=ƪ1SvkgVb d:s', eE~ѣR`bRtI\{"JKyJӔLeDEb-0J! -HO/g9!iv^ :.fK{\Mx^U~c ڶ_9d-Upۖ*RX?[/ߦ:T7[0)0R?e-o!_0:d=F$kJ |Os<H__\L,Rag3?-.Yhӯ[ںIZH#iğ7Ӹ,oR"ŹP|Xb ^8P~|X(L^3oiV”0yÅXzc}0-_Y߅|zv0 /zG"+4N޳}fH+&%c:diI^X. n]p7XrQXM"&TKfdo, 8-6y~ .j!EJm8pITNR4E&5g|I*п\٥Ys2UmX7[*)(ըU[V,R WasHujmU1Ͷ`g.H?{(f؜s%̻?'V|E^n% WU:٠U,Wuvsj㼐,}]2`/9Z-QD+^7|-G?&u'"ȯ97f)i#UP< ,{z3y@ SA09Rxs[2O@Tw8ܖd3+=2n]+PVJvi]4wx;'ڴUKFA:=Ȅ"Xs "()f]:dmYl$eHus0"h1+#K l,oaH,-'i6˞䛃2 Fb0#4$1_RoxmvD@1n ]^P<1. pHa D րmtnN!4Ez`3A&W}C آXd6dz?(o#z-?, #wT<SBՁ yy}i?~J9j^Ŏ_;ZE8ŸiWF, %OsFmp>ղWnu(PZV%@/v&~ KTH:  Ri4(SF]d5lXƹ̳~v;Ar: |y' >]h @+oͳٓlchBUo<$GK":vvfO)* &. `Apj塁Y?,gt^xwF$fTgZW$6Mq{0̈yJp0Yg$#.m6!ץt L(:ØVAS@F*G_ PX~TyO*fHz@ͽ8"9nК)Jt.YLrRW巉%Ŋ !G6I-x6Zk"zTy{NP5Zѡb[r< Q:Bt:6Y{sRY PO-Q ,EQԧG dr 4x|]͇"Mkr٣L u|LE-">U<$Z 8I B Ou|spŋ4G X b:2 P/(UMf_ЂeV.9 +@nd|kQRg\ѕU)5tX0 {ŵ2jՁ J+pހ=ۣ2lJ@&0MJW?E<:og|b .Cݐ'a O_f4sE|ne'*:%W+%X*4A>(ፙHn7K0,i[>)%ɭ[,0iU'1pX5H7 M-w%L $))WݮmU'(ĄCMd'D͖yv i]{>߀?:|Gֱ{m1p6jK. 124I۶lo=ӀFKi]ĦԬyN>n.l-ֱUڪAEϪ{96]Ǒ*vq$!2;H5} 1'4cRΞJsLnZKQonKMI""(=KկrwQd_7UYF7[DrJ[B|1GT"Ʋzq4;64-;pZL?A]Eb'"rs\ $>{b;ˈCE;]DoYpvQΈQuE ri! z4TU?UE3ż<&ab8ªT" h(CS @F!B\< Ҥ/+ r`[&A-~$\R]ekn]AxB֢MX?`ϭpvMHoq-|%Abý9קM9Uj]tV yf5ĖV/@zK%Ia^oW֏ޭnL8E2!\~GbK1X8U`Q"F>WǓχGSa? /U<W淁Ccw*T#󜑖MЩ#o5ӻP щ i8K:.ç&UɣP-h{|z*-}mb- ~.uݷf`ʏQF,rQwMYs?f{Yr+WW2RۊMxzXw^ޒA'gwfj߈9:)C-QvD`r[1T ~ӎGݭHxxrX-୬[2~ SHB[?/8&&;[ Z~Z=yiE$b*R:iܐ̓bb,dNs+.(_5TQN4LAMw(cV@j!ȹ)}#J_M%DpdF::oAo8쀠L1Fq%4HlWMW >pfu} 0? ݼfϦihc'Jթ/fZwuݶgXʍ)Op P4䫻 O j^Z4)N48 zO9d<$8_Ҿj,;@wF,~P*Mu'Z'?IOC"9 Jq瞈çOpq]ݕV;.r^̭oHa1j$;%;u٘aL*lԄ)?ݾ;s9u7 bkZ [ZT &W$drRI \Cq }`e_͓m ` u |H ($p;[u"ˁFښzm3b!)^oƭ.Ps> FRLM[=VU@HptY[feulqk>OԓWV0[9}e}IPyYz|O)p@Ʀ0#8Ss[_'>:֤ C^ nuR'A'0u5F|N7ۺ/[70*%raThCvj? B^gL%mDoeяM]c: :Rb^ ;x2Adzd8҅CqM]TiΤM4oJkM@ cyM qTӨBr\bDg8 AK{;a# a!Cdž;{A:9i63=QoN%&!#4?ȚNhuըLmǹhy iW3cIl'iQ_I\6u8OҚԁD4xN<{vKYcy|ĪIk2ҢDCM2u+BǞށ&.wPs&Ra7^X]D;;4TW[ :2vO*UD:?6x3NZyƀ bXw( Mw*I׼2K=GWG]8[❕â4V}/}Jd7[t`{i$UiH?qzc#Kq|0"&\ [X@_9kvC5>e(Dx٪JGs%\,ń˗ZSi(wt۰$CqN3x[BL NuHߞ AV*N{C3ː7JT|AWyٜpSd4w}x r?<;xy}T"lBɒ(3!UI{ 3>|Og[ɾwKM#=iʨ]w3VfAY(В,!fK%=-:a.'%SѫHӭ+z]NilieI sIdy~!EE}5 0t=; Mع FDs%S20i[`B3 Vކl`qxɅY'yӽt:$l>G`um_rROOx2FY; #ÕEOz{X0Ŕ[3n{lKHA`5ltRb{1(9¯ "ڇ~ر vQg/vz"%S^5i ݊K7ǝGsR_, .VrG/POt8 6bRKxt?Ž7iL,dC) &}i΄V2H ۪ZK< @ۺI9׋̲y;'WYSF),I|av [/1/'|֮%S1}|tQU{ԶCn3zV⼸j om҇KsvET.&er7]e8Йn2+d\걌,vAXX xjC؜I02k6'qDX5zo$,^'CCX$ԋlpHIZOmgގuq}[t" ^YQR+P|H/"ٴüs@B*Vo}`spyO/1T{B2mapN "&q 7VI$64.㋭-Ŗ7vݝ|56@x+b鑊MA>D;);Wf6uĒ vy0J f)ˉl!7Lx\ W]P~_,vtE=O^Ds@-hkTsqD6J=dqM$~8>:qzߞ$j HW"Z-rrÞ"O2;wm;|W1au|Ͼ,@}+  GS !aW,kfIxF).D.A3VbG2[f'% $H0p3oΛ?PYbZ iaIW/쿄h_MvkID{E h8HtGpgi 6w XCPcoߎB `8:,jt<(#&Ja/d+' }yaIF1!eYtiFj) } ~R9n> *xWR& &1 25ثx mK7Œ޾_礈/l$gyd~DZL_±G*V(+v T* !";Kv@D~0zϺ]h_K-4nBS׼Z(ɤ(i;OnʆnqvhFv:3N z5(o u Lp&RUڗ~8'Ӷw})]O/V o3JX/d9])9aIǥI*K ́;pӌܾ/]PhyĎO}1#<[Lxp}aSv!7>k2ޮΑ aUM v3B̨NbQ!%oOvqB>3jIZHdm7 4l9FͪI ;|Ж"e9mjҵysck8~1/WDl׹>IZ}6XbltNȓ"@+qe?vhiDJlBVMZ>6D2U*0+m\%q؆F?Yp]ĒױDZ$2\#PpAp,)vF(r,u7R&ۗOyE3h).';ӭy!tg(g8^) A]d"whemta_r!(+RڄyNps Q;圻8π16l;I 0*IA!iI'1Š/z},-hwRbgָU[1Y囧**%30 eںoθF>߇C*m&T?E[E%br$Hҝv,r\j&h$ɒNZfA2!x [hQQ:EW" lBJ0Lo^I6s% ÛyouHr8]^MWR?F,%$=WL.jO)t(;oȂEBhJ_=;{fBPV2rD}A6VLK|Xz p4YTY @Ί}5)ܒS.4p@m1F}j3륝V i`Cgް«ynLM7oVDB|Ԉ_f'ɭBx#nx+0 .J~2gBԢwK#Q\|M :M!NBʴ|6 WfZe ^$wFJSlr4ʹoA>U$@-5,pJp)l22f3c->JX(DtѽLS'91-4o:Ԩo T뭱Í.Cp3,&-C;%Ÿ%Z² eH?aϤ4$3Wٕ7Lߥ ~qsLD%1Lt{aXĘC 4q]4e)雦G}u WG8J?A`+^Bԗ/;WvU9;la |R^n~p/QVrXzJt#>3LgZ]AYYhϯ6yV?ӯƭApE6Bz+I`Ufkm@ 51Ac|@u~Q2g@(GO]E.Y%0;X%궮12ˤm=wҀ~/\x'hf^"?X2P1`XxCDY} "D0iSCAs:8cE*;:(L/7qZz#HXˍ }T3fVijG )Eh*;խ+e8 JϾe?I(gBdoEfM\jo.VXw1# \#Y7BBhp4xILGi+biF^LKw&A`rA2:]Lm`OgnpVd[x 2^v'0)}8xc^w?y[ДHL"ՠxmYIcDͯ\ڶM=H>Ri jDJ 3,EhX9(xW}t耍2ςY&yfeq/5`DsHweP=FhN$̧mCa(4n?RigTk ]ImAZDIQ+_B xw7eSLW*U&oi@Љߡ(b/UcnE\Å -hˮ94o/x#%O Ut͖n1~\Bk5S;jx,&i4Y FƜ<0(m+-t;Q7 c+(J.@}^'nh#OPn~ՇYo8!l+S ԣ=+l3:y_.?FH4K7BEQx[Qʑ[Ws[lHUjƽ9f|# YkN>b,|tweV zqzpi|Ϊj&!~6gb`Ri<zxH~]*-})B-fs_:]K w)n<4sM?d]g eIP Z!Fil Y:ks2r6ZX$$;DR KB\i ;V$_~FSyk RR{lP3b)^<ކusmnd,$F*bno6; :N̩}K!=;,%6{>Lv)]/kOHW,v^" fxNG^^L:&똤Й]"gxԧܺ*$ TS1 M1Ј5QSxl';m,T>eza>Pn<üYܮ8#v%ߤ )h}lARZ鿴t~+ _8:J.ム3WL @9:w4 5п|I*#~c:ҙ b LM5f <8/o^HXr-.ܖ<ʡS IK|ҙxhyg&́h%Pf&nDxDz7@' crGcQb 7ܯoD{ u5GdA{ܵٓ!ёP¶Z\,&#*F+[@9TXWC9Nm-b [.2l~%ǧ8GkgTt_ׯTR}t^?4w=Y_(I3[ x/¶LTixE79X ~.;[AaOeW?p+ R ۬T0֗mצid9c2\Zp!V(5CwVLٟb u"Hd/PBIz.8#o@ǖY) ~L; Upa!^9Ct{f3:6&\t M7(Ɲ',G dt_3O[᱌3( L>qI%nBpE2 7SM;h!KkX^}sGܶM■5z4•dCcTE"N+npM[eTxϿG5irs[-E~H 8; IdAP:Q |`o݇OuPAuż",*\JcrtM@B9m30O[E)?UU1;8qR%,L(y4Q-B˓@9{Q}#t{ $xb6;}OP8VUS^Sd%&9i #⩨U $ݺKȡįNyͪmAnxMf m~xB 5Qjb %iݥfeQ,K(6-h#{pt[}ި3"h<x}æ 3Uk"p:~|661dcvMׅÁPqa3QiA[y& /d: iY-Kj׸<TC;I0Vn`'QW|a_ #MUp3v3NezD㩎LLyZʛ(qͰqpV<zhXahߛR/bhb& >XfI}%Wbz;n'Yb q3i% /۫Ϛ҂^#Q9x" @O` Q_gSbnAXzp_$9j$K@z~I4ڵX}m*,O U$?`~L UYwJDyY3XrOZ%ct;_MRI*{|>+kb^vBsRV#=|R7{I<;4 +fdA~d'T~= fn>`(Q1{Tlgdj4 S_؛u%`x8ҶGPJb5Z`מ!8#ОO󵛴 f3F*iMA9(Q!`NSQC|=lP|6\F1?C(o /38,r@Z.}(^sKlMD0Q[("2,eb$мݪô@ &[K!PDKr >wtɓ!5SN+zaX1w16DnHD:oKb&?H,๗qh_`*'B|6km3gLh{GlQ-Y]!X*p=맖"OݏYdZsrї0)MA=JRQ'n fUZO nO1I?Zw*X&1r&zz}K(|0.h537/5E>ΒEGݺVd^/4qhE#\uDsѡ/c1A1VR 0Xp Jl"r G5_4u.ՂwbwV*EÍDOiܱcC"`7sa'rO! "٤16da_*>S-GC{yi6u8f"$uxrHIIfn^+d4ׯ*%-\á%żpMN0Qk)WjՔ,R>hwYZ`i0:>Ƭ}d'H5>X}3_x8g@f͎f#Ϳw\MiTb#"L6u:0|lf^kefuavfp-"!tnVy3q6;Pc"d⡹TMQm[Q}m_g"uA['-e?ψx3ijO%\`R_kX{Qs6L_:dy)  W0DG 0a@ztodGOS#S[!9vH"dqNQ){Bu{\z E6%"TNgMb٤fI;7CS H͟ru4ؾYT~v Jaw ֞f np4]x[ 7VhSu{Gj_)W_#岏rֲX\򉬭0jyQI07}xޔHd=HCX:X:JXy$soȯ*}̻u)qCCAZ,卋{t%ԩ fSjTiDpɌh׊{ʝ:gF2LW]5rWJޖKNDЂ=NPv#5¤16Iv臧OYO_jc 8\H(3%7bQndPK n6WScxA<!rV23@rsdVx/g_]JXAމ У6.(V2VwL Zʴ-R!:2} crZXk6 g/ T 8Q5́sQk g{əMLCfm=fd{jʝrZ29$|\3߁ . ə$* M1"#WZG4h/,=¹숸$u UCf.=8̩4Ȳ#2F'oc E\?!5q%Y!6%Z{q##=Js!@Eۋ~k*\d=\c!'NDc6hcb~TQLg=KׇOA\ZMƭE+q uȧl @3RJ$~ O%C_d^:3]frx/ԁ_bTG^VSDg~OFp%-T%#\ ׼'Jä =Ymq ~ uʃ˪XJ0Dpڻdƽ3ëBM;rrv1;/flWYQȘ!Y}4˰K{' ,]˘8{;8nx1_r Q3رJMw949{ᅮJĻl%2֘̇v-6j^P2kE?zHYZuLK%0p7UZk}qMWC ~B>G`YTy"S#>C|+N_8&k=@ﳱҋ-T1(tf?lw?^\?`/"=Rb={@b.VxL?($ rFD | 5 ܨeJT| L,/sER,d~BR"xu`um ˈ9kmC`t"d?2 x$6(ٸTfQ"4HDXm6[C7{_k9 R=d.gIոFpz{5yFoǨY ܋s#g(l"kK"B-D^͜9J<iowu@mfLa()n4Fx#c>Dcm~wr0G CON#GbBqbUa7Cc!8_>?5gʡb_7⛼KLBD$Yr䉸 F_ڼ 1>EU4sxkYF{=kUݖ!'zJ\&'όb RWFQTI\0]a ӧ."u 33:"H׊4z8UOGa?*6X'b'~8w-yrb~[ [O>@|Um76O~ջiwKےր^5C}Uk{GH!דjnQTE, N Zĕ*%)6 .9=ʼ䷿eW~?wg%XB*g,N *vh!p? s߹$= +":iaLֹ]v+W^TT2#iÔ [ĎLJ3PYR<`cی*'1:~_Dgy]r8&xF P>b lld)lpsI>S!P׻a>ɊֲU@|MFR]60XG?!/PSe;A_P][b.\e@{v~^. 1;e ,x+ :^pARl x?2RcΫc{!h%`ǮubIdC9%yɴ2u4L^x,eV8EDJE P//4g6W}u%1ʊ[=>+eJxJふb5}G1g&5XPOubؤ_tS*'4ҤtXY{vTڃ'eSҍKoĚjʗ6V:aۊK6CwHD{<Ϲzz$wf}D9r%,'$6ּc;"RKtb V{xO#k_]Q(awBve~ Gt sw{ۆIro9Eҫ,ԃv#xk+.QD]?[&]WKl'I:% Ƥ_j\č;_w}\} |%)JĊ2S)?.WH1hQ|l$뿲3!Uf| wMk 0F-2| ؑqxw.aFTQ یB@8CְER5*WR 9">|2QPĮk*~Cj~T<lۚf4SK>ߝUǍ-ɓ|=>ڛrW>}2S{SqD#_4 ]Uծޓ o&Jl=6zI'\AټϱHOvy1/~=q`͡$""o T)G05L2 *P`LlPr]m*A.7{w$bR+e!b2M\Ǔ_&,+,?w f _XAh47-iň7D&"yy>k}P>c?^c tA`ݓ97"I6b<9 ޕ.A̲cx7[*1k̯+IM%o;M<ZZ0,  AE,G`Y1_0U%Te9.kQxA0'Gkz"!Jާ1vV[%✠T cLd1Nd~iǿJ?fE  tFHCEjxw*nD(qR>35ɕU6-k.*.H<<@D(ΑKRq4.^)$UA3Dg[ tCA4'_!~([H퉮|gA= *Y?YH`Ҩ$̋dRnq~8Ur#F;L3:BW [1t0L{lGPvRA cf "CF~jW9ee4.W{>(X 0`2Dg EZ?#<FA$ZL2%<ȗ)!< *<(q\A +IU? T\g^\4S,5һq Pî lDvuf A1+ 'M`%^)>hnl_k%ruN87~ŽoQ}pv?*-W;쟞Ӯvj?u%P-p(ah!'$UrFf0"* vYPR-݉x|I I'%JhnXo1Zh&/p 3ނKAOE ,-@Ilήx$B2(p,a J7q[\$^0-ki~}jjA?ntF HE&멈i$L%ߤ.ڂ~$P4pDg |+" w@Au4_ A=ji2S|V9y*?br> Aٙ|t2PuhnhQ 2OƂd~L'u\ىnM#͸TUe,_)0΂'ɮ5ˎVEAE,Gfq P =Zǔn~'# 8T6tF 0LNY9c';DgvUt7q3Jm^A4_ A"XYlG8N% MKAk1//NVdN2hǢfķ*R.Tha6ٌ]W|_' zx<6}}SH&ཹg.>InzQ0{JҤ+6P*ٲe=g#[]fey)_9-v .xe55p& ]AE,GiIJfغUsLA_,CJNm20 \X5@rԺ;ݷd9~`HL-lh(*{"i/A>9oV`.[tFxj,_\ᬁxq$CY_9_-9Mt{)Vײ9WY`+0$MsDgy7AazhLWDṒ&w[?_r_>ٍ`Pg tRoVW?=M'*  ځA4_ A"Xx?s]nb=A;W)Qsf5ѐ/& &JAE,Gi+m)`|8C܅O/yG0D;_,:tFw@]**qYtѣIV#JF!'OiY(3k侢}doDΒ]rB #kwe *"M$h{-1[}=$͖ )ꅞ> i<Ùe5Ư6M&=`3ݡk{ d=^VEa͝6~Ŭ?%C-ʑ?KYeL]gx!Xoi3WC6ѕ2=/[?.(q(Ɠ 5:}9=)Hj_'Q32y@ s?*dRD1* nV8Pζ?:qn J[RϩxbҎ(5qEq?Q EC.+, d8a׍٬Oe `]'|=vVՀ ON^h *f+ SlifOCe">ЦӦ+QbwrU{k!\WJ:/#;U,C-SZ ?ix"\BWI됧5H9$x[iԂRᓑ+7e`̴nfIr-=AO-v(g6O]))# |E}ǐFZQA __&kb1_)·QfM8\Ué簕 KU܄2j{WI^.{^Yg3CE20FM>I @ߺGq)_#W<Yvj$]Cf΃ACE"5Iؤ&)(_An ՠw1Z 'uU\MXHU9 *z_r-lbuEo=1SڙVd{Ctxi%,9e/" ci, k* "iMp).-л$bnlt{*6~/u EE|/G~h7ԓ4jsv""v˺)'=y6풾^AUH}11oIMwc8>f(n;$PbT.?E4"5}!§x',/;!}%9 Ňr$c)+ ]T^n1-fIa{X"<,qeڈ$ڴםzr}l0wBA5+J0蜦;O6 _U-hdyry+M8S[&t̻EC{219Nڗ՝/)Q #-N) ] E|x2+unUﷹ`$ACޏ>w &J9\©a,k?} q@;"-m =M%G\IA^wx# Ĵc\*}4)/A(} 7Ax[gkdoL>Ɗ+_hݩ)9{Fu0ȨUIsDhp˞ a5޻ۦʯ}9V/*o~A ~d]0-Ƚ`J{ea9/Ҭq;>OY'7!f@ wu0 #z[{ ~ ¸m15G9ӚCay$ӗVZlG2[hA py4`VnkM#Juo _nyV$0Bޅ;g+3 D4$ieE.4FVp,: Y(_t0n1{V9Vpq7iʐwi7mc %1:ZwxK?˄3 xͲ bV=?[f3BG6LH&z.Q uŋF$|N;|t <3iutk#":;g"[ &8;*ɖ3XaZ+R^8*&QV2n-Q1!TČw!)ݨK@bi:p.\Ժ/ed*sj@3mdPT~n9eGΰ+|-VQHPcwaԭ~\X{U.ĕW;_^1pmJ"f6S6k5ȯW*}v/#W_=#[6@jiXs[,JE`; v9^cN>|9 'vR@ UH=G J|w+ẕ!_c hAnrc[cr#rܲK>NAi`D: (- n,\ɕV6[lΫ%hZz khڳ>Wr FkgKu0q:{4PyII",rd=~%0sB{"4OnǷy?ns'# ]Ds]\F~&#egN LVLoKwuqGߓ/6N|轘0W9]vY"TCk@f@AE,GP.4ϩ#p4;؄{1m]>_!d.J Tt,X6] -dNbL4/ 5KS{B=z_`ygF+,Ãs18&З[f<tF" v +-lgF3%jǤqDg @\)9'_u>w zN8 Eo cGvU?1!{12E=uLez̃PaXy܅m֦-Lo_V謼W*>f.Qv3N[]* KFJ6D,|%ؤ6g8ʊǺzQ;\<ŨFPMXIɢ).EnU9Yhc|ZչMA4‰&L_w^]R";W0tgdGX"¤H{#ͪS]8*Csշ6 xNBE0T=LB5[(/ߏFZXm`OnEV^նQ- 9sO+,۪b߹ E&D:)w*.H *|0_*N]Z91ðwO"W;N%عKׁ U `xA~4]Ga8AV uW,48Q3@~D9Cg3VpVz.qN&D8kZpGnfڔ>E Zym%ts+"%;tʹZQ|p}{(GI. i1϶W<Ӯy|-$:I Pzߠf䉦7KcWS2!q @q~;fr{+*D0#RO%T1LzXf=VǓ3j"ܔrQdmHU|h1Zq~݋(* ZYosuqgIg,Q21tNR,b0L@CFh ]pPrWJ<'=3_ :-LYڄκrB&p;~XohY)9H@!og_CCX\`qZU-+y^ ~{ijqZS@!~ʘ؛椊z0WG??@*2M5YB]B L Dg 2uX9郫ՠdD3d͖\EQ@ A =?Ŏ]Uٌ>wqBLgc_wmszBTB\Og$6i"Dg=/94͗?s9.V"D/w<# deȻ']ĦpݍT=V8`u:PO/Ljv_GAzҪ9¼a$U5)6:dc=ZD3oxNkix*} 0+*fvo+"yQĨp!#WEdl*ml?S<'*y֧=hX_CjcY:iĝ[n{/BIJLtxafdF "wnoE@p4v@D1H!~ ]{ GM>: ;*}3sl({鸇Niʗ/t;ݽmJ>O/6yHv~ZyϖB xn3i<_!>kxMwF@ה7 0).pˬY[S M \.Des$~¢H30BL[^>ZwLip3#xwKMwse70d_u47 MGti$ MP֚Y5<ed~{lk/G 5!m%X+p^ flEWV%m)"v6b n9 V]~Cm7cI մv6=GFVgv *gz-ftr3Alm=P-^GȀE/P(jFZ4">=> DL/Y&zb6Yi _7jԒrH.ʡ&pk~AP1v B?Is yj>j5zS=mxB@cu+m/fBK-\jot xBYSԲ=N0|ٲ7ȵ] n\ I_P5z4@[5*;;ErCdȧ KZ2S8&\i''0@6ű]248 8[)naQFwA΍ĻO QW- :A5rםL`DLUgRҬ6oW vWZj-^jF뎭߼\{%47i2Ԫy;WNn#5.'6ķs@ "1FѪtٔբzA͹ qIwL1h6(vhs0ٱ1p9p 9MVx$8tSwH!Nq2݊=,x$0lW( :}}=q'6[G*/@R*_ 8:E𯙊<L׈Z_Vb(N^'\7j hkoOCϋP A ŌT &<43<noP@"8.ҘZ C~yd wnV-m6"1 NtPElF 2qH} x|bu{d:@-#R_$0bZfV3 o8?~oLF@tsHr$w!'"Lo}WQeq^8&Jb ki$,K⊇&{c$Ӗey1[v>)V?4ANIgŁqsn\${͇퍆a[%ôxŽiZ/ρ#l~6[j)?m%X6oUX cBfgbϵ(Y]CKo-zbF.tsCOa%T~ɺCh$6FI N"FuE:0!>;w0igl ( ufzO C>s.?0Ŀ!3XMQZ]*-8_2[̀۫NTJK@=rŗ-}A3x(pUH} ȋl#:4,ָh,iX\n }@p[tHfnhlkRQ%c}xGھ:,xq*>wɺ ws[?|LN'<<.鲑{UvyM&ᷧ'|1:3d+;/ >? W;š7>SeG+R3Vӷwg@`$A0>L6͏ZPۏH \x@#CoEqꥷ4jOPx pws˦g.#YmNKmjضvmaE8V2S!6#Gjzmrs]{ # MY:23d,6Ҕȫ"FRm` xf>dXe27sVIQ%,}%An /Hvfa(;74FW(BY.@RAnVj /lc;NH>9ɒřj^H/^4@pbU[w yO4U_ 1+))53QA4a!VSqk-.o:ݯqt휄p?\뱆|~ 㓪0:I3T޺hByuO$Dj|q<@(.nv90{khOGRa;J SMw RkÙޭ&迄.M>)O. $*YQH/>L@>" †zn !dmGx\?'~z 9W@Fc/Ym-?Eiӎ@{>"I(KoPŀ5Z.b[{*{o:0bLQ$Ov o^t}"m c&L%xEz̴ؚYoRm Bwwgi&w0=wl1 2/<04ZV/ok~”)\krD8׀sV>G+*K >=V'zp P%!Uiv{Um2%*$!h2'+a0/Gf_Kl@*-wjowoaS-?ǎ!".͌~r!ֱ\Ϟ2~FHu{Trx$e=+4aW v$ :IIrD-k"W|O6@7y;[u$qXdG$,7W᫱٢x8 kwx.1-yDAL?riz(evN34wR;+ ֻ}5*pz\6}lԏT6q_y )dӶ1ZUP}@?+,M+gemdY~պuŰwa83s!ɭ Ь[z q/9>Iy."hO8leA$9%3ȶ~V:6bd?ğQUj1v#w]$Я4k @>8 rܮrϚhEא-@A~6lwEߑmٵgK2{WIږrxj]]gpvh1f7>?\-τ+D PVyΊ.0ӨLc ;{*#ζLCݗbzi ף;Ms` ϧ&[>?H%H"fgqIIn+!nms(#pUU;!7HlNBQ1VjInaJ p]K B $<26i #l``wQ9ڶrW-p` Jͯ8lתYthk.c=s,&%RS9/WxzQJhAhvC{CڎzGkM~o#P~0M%Î(=) OANESxR [UW%g93 x>e4X`#05cZ&$V)9Cߠ-P%DmtFe13J+/Tg hmeDY .oDgp?1C@.?At4_6ݭm&0]j幱|>k*9B_;R vȬ%J39!ڹQ<'޷֊xyA6Gպp/^ x? wܳ߶2dӄ.,KfݏpiG[Q8֒*1?X0YJx%Q#gz @>* $,{Bx6uʍۓ T{å4C9:q N%f Ciw`0Oaѝ BDF$4YۿXΤ<ңZ|R7$)S0*Gt~4(*5ꪅf=Jk,gCMJ$DF t8ѕ&v{X!>}R'𶞬Ko)xpl~[/S`N:;ؐon({Z :™6o0⥸1)E [Cc|"lq08~ԉ@G5k^*svGa h5Ⱄ@#l1x,o!S#;Lsaq\(+U?x!".N)2[ݮ@,_ˠqм2Сa,8|2וDrC7ɇp(vQs)|mHJCh[f Qw[ dh#$_c *GAXoCC y}1}P #Pxa-F7iNa*sY:~O^#[0DL9SN^ TU aWu^W0GXwF#[Q@e$  5Ч໖1eH*ڋZ' @:^%/0Wkê?RiG@\(:2fahaH bkàXD&b}n@!>CPI8ҷտb%va:ȵyF='wh#]LGT[c 5/H.s2x,XY泾`%;KP],:YeyiR5tfEHP3`CtN\S0/m X)}n'jW? ߝ"AX%Q:jxl,a:,LJBEbCʊ@$sGoA $fR@ҙL/o̝F:#^<6]'xXߞ=kMnXrE1i$0AE,G.:o S~5_^7I9Qm&dYZUVH!>i"hleqAzu4;&.qyɝBCkHN׈lH@ &q&< 9PHV\R'vU_.ش!ZD(Ekʧ $r5z3t}^kyDqLkj(%# c"mN~ZY^l`6"vw UJ % A4_6ݭmʜr12 c~h,Q+/{vWxDTtvbZB}3r3S *YTXy)hzU]$Yn5z IyM2-^⽄+6C3"1g;@*vvs\7XE;2+,L.x.r|=ȷ0-=..U<楦Sfq5Ay&_Ezֽ)Q5-(8])bWJhҤQ> M3Ω&2%̺w2@|*|1gtl>0v,D{/'lK1^8OZ-q4Pi!K\*\69\p=%%Ge̳N \p< 9<"MkL$hㆥrQgH# n=FEEQ򁨊$rݺŐ7:ؿ,0żz,S;r+5& awF]SQ퀌q9 m*xxS6cb8=L߻=QYRV6f-zzP!c@3NƳњXN?XZ,ѷ[+ KaHâYX."vtoa4Vqճ-@;χ#!چ8Tv<IA1XoĠC;+`EN]/ vsɰ }1Y5̢ReI^8*'%%bd;0X*b<,r˗z(pQT[8]\җbU̗IUH\qfx@*~&CrYuR<6lN9HfM_u ~zɄHYjWGb?>3x@(VF2z=7a"ʢpEK&(-g.Wg)cHa wҩh~gY3j(0]Vz7 qό/* HĞ:D̎C5A?+#Q#'QH>n🆃/r$zlphX뺵ɚ` ePF[i<7_p:@<5Ok޸V n>;:ghV`vB}8(nFٳ9 M_/K2j uRYvkB 扆N1sv;NVxШqy7X0Gyt`xKs#!b5)FRŘ&3. S%4X^34+fߩr  @ 邋Rd'"X-޶&:G&ӡH֍oc8(ef4W(0I-fT'HDqˮ_0W`];H<l0X(F+@nz V i]W럂aGY{,<6h%а[_:K'ċ=н 1si~:[V-`8vT%;_w,Nչ7UG-Z.oQD9k 83@BbVv0~QK 31AN[71Nh[U2isTP.ؑ>QV#Z:%*T$xh  ˯Ay)6Nk%Z^q,,sUlӅv >zvK%6#lm0g}%?'3g} wA#d*Z1RH5=GXr,9)$ZPªV8DI c,&.W4eQm9n˿r +L(e%WAF#:BC}?%U=wmKAP xİqQH8踰&EGp>+X1@}./EgK=\ /H|ZZB%+޶J<Z K0fT T `=і#;psTVD+ݺGpF-̪db麅ط7\#Q<(񙘰gKɎAD,qKxncٕ x+%ASs.T:|F*%8oZ'X\*+?"3MyJ0cj_1̥KbA 1ա?fhk]u/+IH8!Gasmљդx/n$pMg,[htqbݤp3|#`5r*G\",^^Ȉx\){7WwuX hAE,Wo\kOHz¹iMg.Fv6:T##dӌOMfy["92eDgyy 8nV>TcؘדPUQܯt(SkD06 LTA4_6ݭmʑKiEVJ_#u"oU/^"G`nfqT6LBamDE^FqʙO7N䕪FiI0tƑC (vNI*,7 }lW@<7=Gt5n H*OT$ ӘcΒf'nwn 6>$MNÊ(](O;vJ+WK/Hg΢mj|4hg/,ځA5 2Iu5桛[3JߧZ1{G zFRC`G&*c&BWB.&J5`V/+\"PT []: Mw׶\0gmHAڷ/W)[-r˖}̜_A]E,Gc- ڲP|sCw&=g7RC2=I38qU|tFrjQٯQ^5{pG*:D JҦ] I~Dgo:Г# w9ZziLAc4_6ݭmt;b56wOCi%j_qE'ԞM7_stJF.D&L3NnZ&@Lɱ4];Dݿ EqU qHC W5SL SXAE,G^؁7O"a/O/2Ō3 z< |rg9wۘ0'ԙ<#[@Q*RL[D`| d2'Ö7D!*zc V@Hҹ,a(} u(hOtFm ?DOA!G]ьȺ?[A.TX#`xFDgjRz(CJ*Kir ߥeuA4_6ݭmY(F2n!zFC !u~b37ȞTEAvag͒c`zۂE&&ۅqv߂6Ƣךu_46`KÒ ]N~kmI"qq3iR6Jx ;0wAE,GWUrx(f}ΗH%R6?]eah# Xsz> (M3Vi8@=, V;GWPjf(onfp*`tFe%\2Q. gj#~d4ٟ3+.Dd]Os(|]r,2ŖvNoSnmFxKF]Q0C{nGӬ{z<|NLj5Dgd&9@8]ACB]A4_6ݭmG6+!2qW7JTi 3וY7:Ƣ`$fw1<$.s)K1!f'ʂ;K EWoҖ'D9n_DE.}|;;@rL҇Ldԛ֧vty:GVn(qeH+}&#9KFkvh[99g{ zԴsq~7dA5%\ͨd53 *ܔRONA~\T Z @. 3d#_bK38Qkr*ROɦ$Zy3Ho{nx#Mb5>WIegO,jY',LFjNWOE)>~ex,.r-%vkiz2I a~\o*ҡ>wFt?ܐJV+ @6z0#z \/;f% {W)ԗ0db6.P ':lv /A E,GRʹo>#lRyZΏ#BZ:'ʽkXbā~+-@~}zg6$d (JV*QcQ]ieڏO i(tFa{#X 2D)?26`ސ8c٧xBaXF1g0@{*hf)[nj8^A*Dg^q&Q'ȟ$sVa+: Y´ڐܖ$FBeДEzԬ[z }W4,GK`HFp΃ VcA/4_6ݭm,UUy#Ť\S(q+w%RϊVRwgUQmOO̬DkUHOA~-Cky&}0+{9-c$[@ľ[/l N @H&2*U{lxΊZ2N>P]JLi[,8 Ptc!u)ylskG!F@kj0tgno1ut66/x3arٲ{F9C<'}{l_eylb>hG b@g@ol!_ɡ$Wwn(r`f0&brzԐfL$ H+P; wUK0c,"`;T<)ƆoST5_UЊ/Bqz~3?#\ɠuC俗xnza=豑!~<5+v~+7zẏka;lBByI)6d>s ݟeh vȯ|.YɿxKr8yմ%؁2*?N XiT_v T+9,B\8i!zaBkﺒ,.$aXY˳@c7e "[q5=ʚ 5yکHڢ ̸Vm{}Ck}!q wSfeVMQ.f5!\w!){_]^ IQr;_:-[w W~ ~W~ԎL# 箬~]fp 7 #bg֞@|n( ~cj;1ΡYOZ%:V-^C$"eæA%9LA,h]sk゚4Oo)<8ƽuAKִ?-vˡoq' G2<Ў  |S9B/uޥx*6>lZAE,GJ^B~R g6Ą|1=Zn() t/y [9aB#tP_FJIVPܨ 3mi/YwSA$WF% uYsa.:Kځytst9Z`G]!.!`R\m)<6m1tں;i Xn F_;ZܙCZtFWUEM8}H/6TX93F,fNi}@-t汋 XGBDgS.{%ս0ֹq[jzDuO |A4_2V&&/pNX˨xh~rkK}L`'U>]'[LSMH&$6N[UzT_J:=Q*C]ʱfX *Xg}x-,Z;b ˞`2C ddr0lc?|xIʮ *U46OL^H =:Rh}`tv8PGA=xQ=[<բDchWxK668Q;v:R' _o\C}C~p~zvCv/r.Lny%ZeլqjYUʊNGoh1yg=u)x0P|JaK Kb6Ya>!.obۋ `!udq M0H6,R 0n|H>yyT\? %VC`B\~?db+~G6ȯeq[k"+u`@ײ>h}7:ƠYAE4LGDfkZdSKUGID]kc3Ѳ*.g* 5g63tFPS. > M_DgWɯQz8?\PX:-m}jPnU2~74 ENV4!A4_3 K1>P P |?MDPWG,PkH-ҼZ UmDXhT~arN hsJ9:?sqygg09гT)9)'?Oa|#`CZCil(1]0 wHV!:Wz4gA3g~"rYfS$u-qS;*a1 EMCcy:!UB((mpI!aKQehwf cZk<{LGjp:hs˾ouN qrԉ͒`6JFTt)BtbJ7wTβzTyR&]J>fZZ]hCm Y^еA2جc1;}^!Q2*~FWw `V9u!t1\2ް_#\S[~^t@0dXCcMLm[Sp}/ 4n%V{ ,kGZ!c+\eWv#Vֿ9ӁlSy-YrͷJLP'坽5Bj0O /$^'#yЩ|STMcH BiV@ĉ-D}K<ё(%p0>Qf$fW~umv ij",B3\h^*Ԇbejg ;kĈpؙo\!bp,:|f;y*;d/;J7TN|_Kk8Չs6SՎhih+E##a?({v^rk6FvTP %[).ŵ3ȅ.P3ZBsUJK8AE &G$mp0UAKlU(oORiOoz+d-e;f y_MrcЎǰ Ý-R|z_x=?LBwdsAW%\P.m[FUߧC|2"y4$pǻ;TQg }{à]π~y~rh_ BĮ\^~V0@W?vȮE:6 ktU'la%'0.]t 5NjhdbM9`)>fAE5$SIcypVb]6i+`YMjgWzSF{"5B["6bzW'Fk6SLΐݷ\ƣZA MS[<#LA֣ "XH.7E'u`k.+E"v~bzZJukܻUX<9́A:E,GQ=:_!.I.'3t;"B0:W6"q+dRp$Ӏ :X/H~)z${1"ԀQt,wiϒd(Jݫ& w}'y} ƆZ bCPBg?< )w}8ހYtF v?%5Ն ғ%ysH4ĉzEi֑Vt& Af3B)ݯ0>Gw,0@vv%X]&S SyLoz%&UL4m:H[Dg^(Oĉ( K с% ZM+w[oŤDpOT|N2֦ u89rkQUF]<.K:~7>A@4_V'H;x/fc7Hɚ?ĮK`Y %j6q@ɚb7\SL buJI =. h@6q̲-+BȬJ|d_[KrpI5dAtv0f?w#UHӬ?^|j*Ϯz]?6&P}7jQ',n4 i(;f1m(:iP1h5b13$2⩴$A٢ c9J*gզx/H-ܐA~E,G Art8pNE)wmptjĹM?szu'/7-.f,ms-irw%KNrPۣ[ 5@qtFďT;0C˘M?-xG pO1 J÷ldW2"VJE~z?uqFd}^4 yDgpgL I:"@EǷZZU:>'ufOp ;YM9ZߣW'Fcop\A A4_(?) |J1) =UFu4R+o ߬rs@#cxٛ3ehp|i1ݮ;f^2z~PvcH >{'xg_RBܨ2tw2^gQb׵ݠee`%;1a.y|-* Q**NVLIeY 6b3IMYoUԞ˹iҮAB`5}_g(*A,Y&בT9Zn5bs0X,CrL4Rb9XvV mio^+| ;ZVr)٪UuAz˹M4-#؂1yhկo%+ r=ŧ@cČ{Sx(]cC =@"Q͔/Pw]vt{FB HBd1tZ4lš\ r9KɞZXg"$G\6u-62>p>F>ٵKk_*p ]Z86BMe b28n^/]Z@t1CFPʕ$en6h)-pB5?]TPAAK&;'Q+CvŶ8h?|^Mچ(buk2(#y-qZZiNZWu}جݍы et "TuР.EQ_Wpj,Wm MeF sZܞoށM{NŪϥ+cc="}F@$j˯v>Sf2 `"`m\3|r)7(9\ԭ4"ق%(}+ȩW~p2' ~TĹT+u Kҟ:r@С颙~/M;ŵ4>1Ha\}IX%r vL[*9ͧM3HǍΊٲl*tx]^O S`|BCύ }Wx/jsdovɏIW Mt6jC,jM )@6[`d7v㟍Fli*x6" hwn1ip+ X $^1J->~<p e'('F0S89AEAq2arBhQLD+XԷG3,x MGSݶ,8{`F]o>ɟs9)I%}I@ Ox<:c!3mW诤t]}|[i, i$0 5]*ChOjݬf1Atj֨-]TJV rѥ-K'v}S;P>(rnSv3s뉙l|/Y*0-[ک+|`1*FQ;HEXJƿRXtE4`m ;qUzwCKp>N>:u kנhz =8rWiFT/"ܔm4-<gPcH!QGqJ~F{?'ԛ~5~ZߪpW$XxylCB+]gN@j C73hJR7 %z!6 x5]D"~\!b<:B 9 F =?j]Hh96ϙ8f̑lt\-f}!1YgÀɢk!ɻAQAb<Yz^f),׮_D{qs!^/f-S7151ZMY VR|ɔ_u;U L~ϝD;SRqI%Y>WMgyͶfm o|rVd<2AZ%%iȝG; #;C,|q)M)u̒*>ZRw7p#gN%Q,H(Y!+1[ʽE.$RxI)Pu s^$D+81a& Vm/x٩)8m5Uo~Nr#*vu%%1n&q,=\-L\=Ĥf2GTkF>ݟ#Jè>0QL¨=?KxF]u2Hrj݋R CTH9 L'UWݮUY5.}t3{L8cջ4m@z>|J}Z"<< ; AE,G<胓~L%'U RO%uЕ9)|b'_V[øOMpQ KO z"=D5*&_a0CTHZ!zWг;YpǭS>+,Hlkau (%[ հȡTI %v-u"*gCj@W}rg-db4;1 }6D9Drz!­ԎFw^fo8 8MtF3>w %,W7LBѠ~OIe q@ƀiDg~7P}h=1<Ҹz쳢_-"N#^W > Zt1!A4‰Vi|; \ Y|'B !r>:rqFN6hTmޥΝf0f)%D?D? oBfb07ˡG[?L2kYps$zΚZZ βLf ͜jH6'Ҷ(Q]zOi 8O@|X+"[kg JT| x3: [?{Lֲ͸o?. |׌I[GRѿǴR b,CZO!m$4~D}'/\RMr/Ԝ,Rb?S.cH)9.Udysܦ./(,:{bqUc-qE,{ EQhroK;~8-㣕?Eeuj./>LuJ /ۣA.;UIE ce.԰?+9S5MǀGqUO0Jfg1w[A~U'Ӌ yY!{/YdMPewɖ ԙRX\aR{'ʏ1ܦzzhA[5[ }ӛ=FξU@r 2­4@JjKb#<"J3;%sV?NBBxFq*+*/ag5ͼ P=)ƨZ ; —\3*wmm'`s(ǢFkޞ)6M;HB=;}')*̗pOH|٭1=MlQCs%tRr,aHwal\'Uap:r1]3OW="&2<3Dvp`Up ]o"oA Opc0`+m_:þEPeѿRnYKU[YDr* h]3Nur>A=ӞZN`=\0tc㠛R$#@a̓L*b;b9'2f*T㊈CN' 3uJp=&4N3Ǻ`~Ggkh`Su"(Rc. ~e \KN %NLL1}6MIrOہ0V;[3? }K-"[][YXXA@ث+B1:DuUXɚVgGT@dOM8`)>3& 5XgD,Ț(ĔЌ|07pIa;="nf/v {P}l/jfЏUtvrqL"30ckԗ䞯=_$s0u>)$gzR3E_q B$Fė 6ɾDcDvhRHؓGj^-_p({0b!G,KP+vuŸ[AE4LG AٯV)CEqBKpb[ezS9ˀ}؛'tFwsmD},MnbCo 9)DgO\a {dH}uA.4_V msln ŀ*SwP;\8X+8Lߡ7x47z^q-D|ACLs35gD%7P=]`bSYWCO0? >c|l41Q*HE"{ Aw=(?\T,^>7. ^# §`)?OVO5TzIq/V\$葄%L W)b=3?EgzGaxbxq i<ZԖGL1DG= upNp/M+U22Oϯq B¬ Ba?^ҋ L-}5 "i&Fu5G"ZIJ{lхAwg` )_Yۓഅ\6Xvs:ū5ܝ5ѣ] b<EQ^xG 3]3wlF1 XvALE,G A%OrspŞ[}ކG](ӺUvXV51p6)n ):ktF>zT4\v9y=mDg@@&%>5.Ia 8Ar4_vZ{߽WDwWЉd}Y.=eK4.Ya.?\[,}r]D-lAK+V6UWzh/xj>vq6"q܌7v o|L2'UX9;^|:+$$rˆUhoI=28VƦpbhե7C~|T#1axPW^P( vǁ^7~xdQź,]U\Ucu|?$_mڻɔLDOx :W 摭K NUx:&z'οMX~_)39A=!RAE,G A-/(Y5_Lx6|$w 4tF/m{M `3Dg<]H(FvD>nA4_vZ{߽4?W GS//IB|/6?ed"[L_ß[>i`7bI9@I?AE,Gkq # q۽Pt:3tFApr!.Dguh@A4_vZ{}by{3kF ^J,AE,G".`*7tF()9Dg=A>4_vZ{pɿSb+ ANH+A\E,Ge*{tF)}DgNAb4_vZ{ p`֢O޿*j`sa0%4j&̂V|,UH IiAE,Gxf뚍(<\PAI6lPG%mn;]؝k΢v~'|! N!{0TtFq[NPZ+R/+D{pB&m+#aDgnr̲(ػ?Ac'876|e~(s1 9=A4_vZ{ iCgkkۥ8rŅVэĊ-JJP@%~͂tѫ֝xɾDqĈ{ uEձ&[LBssȈ}R8Y9k[vS_eHHOMN%$"[}m-!ωR5vtԷMgvNoN=FcWD!8DtI4U'Ӹi#󇰙BBp7y]n-lB k00g07 $8rAE,GoK H7^O0e9eF ApfHO8wga3j:zv}Jn_;tƱ֧"x VtF>~/Ǯ93b *=\PTXgc,'P B8+DgeT@ )OA4_vZ{,[{,qB"f(C{%%%01+AE,Ge*7tF)9DgA>4_vZ{ŕA1 1~ߤFnŷZm6@+WƟcFq˟9{{ gt4<'T[uÿez}@0/A\E,Gj_0@}*{tF,}Dg0DAb4_vZ{9jy30)U/MS{Wl7<ٍi^DoZ4`X~i#OWP<ݷ*( XQ䱲w`QcD|uwxݢ!h&j`77%,2pxMRAE,Gk9yi[$U0Y8W*)!NtF}ijv5AɆ6d\O$M#7-ueEDgqQe{etnj*k"TL'/.C%A4_e $[V}_J9 ps\J.so؏!zU5T"/-.i<1r(y2d'i'A WTRi?,-AE,GfWx0tFlNHR)DgA4_0]m4ufMs~@AНE!ʄթ ܵ?@+|< Pt74h>"Z6jIg`7^~>Yd{ ?8/U`%.AE,Gr̙'*'tF,)Dg0DA.4_:-@; ` 'VP |#6Xi3"O?.u&=؝ O&1ҳ'S7+'M2,ѳYcWF/OᆼQrNM+TOMqX3%-JIP_\ %;Sr(H4F"hx.u Dg(]yn 8{8To lX5Ώ9y/ M:`zyan[ϓ=m{ab _ފT _mͅxb N&[V-S1 g+M_05%5 P7nr$TKSvcil`C&g+6:Ub?=4Ekq-ntK;PȜF{Bbh}X--+9/DD2Df(wK%c*`m 5zx^ w&A8Ğ.B z\䘊Hj 1\eTh3aU(%/!}*J[8iYT>γF;Pѷ+-I6 5ذOMt8[ $ BALE,GCk qVY !׹241d6 @@.ktFx z`;amDg ,6kVVlg z~-hW~nJ|M2 {5I>@Ar4_*9Oy=ʥ֫ŧ:b㷠Mn&~Ri5<$X7nPޚ=EQ,& B/FS_]97޿t(6A/TRV Ά|\6?d}?6EHhPʉa"4_vZ{4\pS+A\E,Ge*{tF)}Dg4Ab4_vZ{4\pS+AE,Ge*tF)Dg4A4_vZ{4\pS+AE,Ge*tF)Dg4A4_vZ{4\pS+AE,Ge*'tF))Dg4A.4_vZ{4\pS+ALE,Ge*ktF)mDg4Ar4_vZ{4\pS+AE,Ge*tF)Dg4A4_vZ{4\pS+AE,Ge*tF)DgA4_vZ{W.KU!ߋr:.m;_>*p9VnL%J P6\'!G_Q,IJէCo/J8xL)p h.AE,GoJNV-7tFp)9DgA>4_?Z /7ޢ.}|psjݗﯩр܂~Tt,a9ExvU-o;ZEQXBV>XkJPŽwQ<{RE;2pZdUv@c{](4¬ ؼۂi:0q%@knE_`K[V.W301b۬= T ֌ Fu!]./l^q![ieʚ)+_ 2bDpA Ầ=&p.bM h٘3MF!z*LS::}D3:\ap~A\E,G&_P?uy3Lp'Z>jBW;\dP;9/EL6/0TEJz ukV! ]X @08eT{tFR q:5!AKm.[uY)+ z"w[pF}DgpҴ'UBס1tq0jJAb4_dYq'spCfdʪE44p9Q9-AE,G-)!.tFx z`;)Dg7A4_͝9-rkɝb&Ȃ@f+AE,Ge*tF)Dg4A4_vZ{4\pS+AE,Ge*'tF))Dg4A.4_vZ{4\pS+ALE,Ge*ktF)mDg7Ar4_R?oYH+AE,Ge*tF)Dg4A4_vZ{4\pS+AE,Ge*tF)Dg-A4+AE,g)8Dgt8e%KeIuQ:7o}C= >t h'ns֗Y{Wv"_dNκ[XV<܌`Б_/,A^:4ZhѺu$hc8wkK/EaP~bsD 6,XK\P na,:EdRl: n04+^m? y -8}w 9&@ctirNKk/V@䆳|p1nS"}9cFV[xRA $_b(@*2{Ѥ4c'Ӂ E%B( .3y:J[ZL+pwA^Zj xC5vݕ_vFhm_kH(QPBǴM6C <djcr.ǛGoI>うzk/yCm`FbNW*7G,K< s;9+ x{)9Nu ȊJKM?~Υdnq!"tqb@ MtqWͥ*܍1&_Pu: c9S,ӄ@$yB"YYP*r ȱI(6 f'GqSϟ79QF r%Of 2釘䇡ZVxine|_=\/s`}jqǴHqtsydqD.36+~ )cikv*arҼIuFpsZ-6=פm}SRB&b',]6mc'HGuf 7/n̏t_ r-|2'㯪Lf"K Y oCCy-4: l-K0~8goF˙]m hmTaŭcuónﵮ bp?860̥(bK&Ħkb{yNJZ~rV:8N;u5͎k=}Mx^ 慲]}juhbO|[j\XM u5X (e+>)22P?0HNE-TKb@vd0X~/HfM'n`g|XJ&݉O ?%VIhؘVo3l@j4_4sՓo34qV|yM7Ȟ蚹SպeHm'֣l\(z [40W^9,R1k&Qø;7ν<3[q|#do/Ik#`pl%6Ess<[3|%|meԼi]#+h֥4dW\4#v (zPΩSv7{F (J1 <.qLVƚ f5ᙍ3gn>f?6XB_}#,j4NN4Hfo PkbaU5e]&.dpa9mGy1>9>_ؤdǺt 0 Z0WQz`_It=!/eݝC-,(%b%(FWնGve n]iFW&؁0 -)Iy^V .'o6r< v[g%^,&]ƌI103|F^߉ [# YF=أP1#EFz!fnyӸXew)3ٲIߩTv3o|w!\ "~Chj3 KlEN @^P^cTLYe]F LMp6MG/[E2ȥ?mtۮM+b }N/͂RKwGS׌A/={L*LCoFD&lMFfE@B=ՙb}D-c5tx죇7FBXɔ Q%jms ?唇BaDV ,G3ͺK[9œR<@qR_=hx ?b/xȔ7:|=4#ӫp;o!rX{zG f_8^,E[/NB(0q -KÎ[}.P&?%tuӤoov-l]v[V]7/MT!vL`* Ev4LM줻 9 HR8ԅ n "vn 22|s%̓`1~ *A]UYJ145>}ɒ|ζL쉚_ѻ@˂( ! Ti]'`LThg Y].6V|֣12bHVWX>aEpyOW^mƉ;I,ɹ-Y!,CRT }=3othQ!TV g$v`1+vhtc9Q%:d6Ή_H $DЎXr[^a$_`=N3?P@ )8oB0]gv&JĆv<>:Q=F̑Fs|f5 ⌄9M`RoȘmt9J,n ]^P< pH!p-րmt 3%ߨLQEWVLH4YUŃk@2ã徛.QJ(t {uq@{' GMNJE[v]l{wX܊bO9ֱ]mХ9YRǰxr;/]GF7IE-5ڢ4V#1d  ɫ2it\|`H:bqh2CB$/ҹEծi)G!;$UWlW?| \YlkP=nTwpR!|c-_uĝ8kxٵ!\ ]ZaSk wOvL)B#G k;}ʕ2qNQ"l ]m٩fu +˒HcutLHkqu9AL-q$V_΃NHRfu~=Or»fBbcs:p(ho$by:<9Y?zWXԹy d r~ Y\SkL*\F=˦- iE Fqfue.nhҏfcWՖȽzP27'U+qY.&,}gp@$ v aZC n J!JPʒ"&[_["dod ˝"9E "؇gQM7HU/_|͛ꆨ8 wI]i T J#8ʋ~ AMT j`4Ctp$#r{#gCg`TYP=ϒI +Gq+bI*,PL*b,FGzغqo\AvkKq"?<"QG1@za~D Sf^?rũv<;"@2E6_ !"2*S8֨~޶`x-K-OlcTfI`d(@:@z7ˍZXH\'l)C.A[^^W`iӄeQ@SEZ%w9!zKnq,Nݳbqߵ!rQ]H'9nH`yIK9t"?C3T#i/ n/Sq 슩0=vu*3-~ݶ4ԨXni|f N kXw6l#o4__A™X:{Y!ȿ: V uDea>_ 6v6sN [=:9,U܋Kd hw|-T`6W< ."Ul(qne,Kiv BZu&a%y =3ۮvܡ /̀/h]bʈAITS4=;E Tu[+p Մ(kTϪ R 21ԕFquhuI0wz#`u1AMwh3VusSmSMcyhH P-jL>璿L)1ѿs+!fD&OTXf=DS#Zd :Vjj06+kZCN$OCp.o q!1$_ ROrOIg}.gvͼbMݮ5!KcU&ڬ=n]LnBPh|8)tv[nm0} uT7ns Lq'i\3y&n:O'9PFW_*+xxVt]1Np1BC5ucCDyUMol!c]c-5ܙݚ̗uec0~sOtp1 fR I\_}#ĤCB.B(dGGLfۥ6z[TyDh@cT%u V_Z=5*R^ǟ9JH%{TaE/_wxFr#,0cU'<cpϦLpa2j$#!?~Y7)ɆD 9aY77Bsg>.플:dS}|1mV2G >f3PvRHW\E 5l֓3w 4e6j`U\jrl'\i 6yQ{koQ `]`DBxB,dLo' (:*xe(kN#RJv#$ Nr( b]l-tѹ)n1c xxЮQ=jCk,h)3_p{v4SCXvo(\҃JS'[j8>ˎIFK\s/W Ug ˨zQze{1WP״3+zW_ZZ/IXkFn(BHyt)n%ej)#q@A NgyElF?_Ut oiճ Uv^v,kW565 Ɛ <dbS0뻲bI5(yAr؍V $=-IV*I&a<"͚t`%Y;BܕQtؔ}?'v0ZkIS)>i޾(d mEo=:LeIEAZ`yy0>%#W`Q |VY?qG2By>ljk,HA9wH2B;uҞG~ `1j4Nt= qu,ZY.ZZ,>P 0I7\wH4]gVXIߌ@t;R!K#!^Dow-(|C[_u_%yLxN%d#Z7`lkZ`u2wK|gP{\Dc3zT`p |ܸKғ3ajϻs>yZF?YT)N;y&L?TY vcBht`on:PKS3TBcY8DC$I҉ys4zۉYdݳ8&@/$cṥL<]˰uC(Ab+p6OJ#a3xKFmٴÞ 8ైmrCQl0m:5Χ E) 8E~e=ClMx7be7Ǜ@D3 Qgvr<ٺvc0.4@8$aZ ˦,K*\abbZf HxsPt,\.-j- 6|"{A_dqr=;vF!b*}Ft6sʑzTA.{#(SB߱ :tڙU 8@}.Fa\uS\ -9٩& Űr6,'`W5͌-^,<I?< [hCC :j=;10m3<ٱԯ7VR?0-Q}m-LIMc< \-zU|ꧤ6u!B<7+XQ ~8 Bhi_Xg@>i.r1::2*_~@^fJr'IK*Kfr!{ "0~.VY8߳nG7 XJB¨ѧy vj? !f" ֘J?j^ˣoNJ)huiZa9Ÿn0ߘ0Ðs;ךleebmu%_$T:;gDHfdԍ|,4!4[=4Q]'=ӏW3R1-ŇXyqz3:^!:Cy;qJ 6*@EqY TT'̆%L-B;%~mbii#ug@=W4 &3˥ "1O˃u#xdEE 7}CD"_<6 >dAvq,~dl'9u;L7RZH(Km8VBzV꼓˧ۏB NF<,N@< (Of6SPZk!~-h4c\.,~&:SYG{5VC,(sRdN!َ0?3(Tr]= 0E]s'8Ҕ,r9tp̎'lQ ٝk~mѲlO |?z wqFZ9B68OH-'ctuӊ DnAZ38% Op~=xs}:SLoʄF5 ړPϽO#g e 4?NL={=LSE?yd¨Gr1zSZ;^ I?g Dh\N8a:ޠF5FF\ ;i07KD2<.]פ"Av7pb<5}>Y rH U]<9Si+xRboYuS,\! LTƩ&llG4c lϩQKJ"5?ɼ@Zw3jhfi;o$W(u 7oP9{ t4P|էKw$?6,"y*[|T.tE/Ȯ즳k\AkEA=(Dݟ7!hYyrWZhr WziPxhFEj[ w&[OP& "S!z]jaWnb~qvAѐk_E2#pi6WN;3{sۆ&>@&-+E8>CqYC=z!xMn OQа/8C͒<˵N/Tǽ@ H x 摪W+d^#KP~@:mƒ@ :-\7NAhe(l ~|ؓrc!a^O w;ʭ{5U-6{tȦ8pHZ?h`gl:*<5Y*g+K2ɧI@8)4Oj1a"@,B)hSMJpOGuCϽD[ Q!6_jn6W#Ȼ~[H-ۻ%~c0; @ 8/+ f|EV\eBZ[.[1*Z1Yz@Md'y$z#*Vԝv*Ҳ4_d"hڀY͊ D$<_9)_~mL꡴ɭ"6(u@o :k1j0Gi̬]|"V)=DMGpUq hGzIr p3Y+bK8[ L䖭#hAC+*_ "y9:vLjca$dBP݂,wDm!{.9򫔿iۋ@g,Y/%9 G%I񴑡;+ QLuP]f 깜i,Dddv*D.lCy@{B`waɔ7R0ѿ{ WqU_#r^ǰ>NH!N'Ae_ӆ}#eX2OKțW)!9Vᦟ ƍ6+5Jfi%"ݴkd+x-"':b'Y.^ܾ{T}?5P>1ɓ PؙdGKd1 (RtqYG#2SXr6nԭj mŵwHāĨ> m}#0%1}JsHq3afjcD0B'š;ziXGm$(L6R'>uZab #QOw#s%)T&$D<:R'o;I/Q7yK+W=x $#&C6[Cgq|:9Cޗ}>n]/}Eq lI߲XQhMq̶TNsl5-վ1I@K!l53t|֚Fj)弿+ B(( `% ڣO `\9c],Y Zu@xVv7-jͳ1c +Vv-6a)Xה͖ (?rgfQ4CnKԭ8%KL@f(ЮJfQ1zXvB3|7*Q,a͇q!$ :b6x"F98VƽWCGab\ݘj僉D2?7UDe8\Xo`1:ǸdEa9zO1Pۀ ǟ_Feר 44VyJ gԥᬗ"k`_\\>gj k6lvKU@ } #@ Y@H LZʫ/^3Dq,bt 8hL>A= M)jhKdSL&mS5W+BA9d>)Vu~i=d>!~|9jl7W<}v(zCXYSzs_0@ZY37QV(tl@}R}-!;Ic x-U=>W\cJ ZY8B:52LK8d@]Rbȭ/CŒ,듰058룜;ݜ/\ՔV,DX(Yyv~ ibSa% PmQ8U=\Bӭ2CH x*I [O_YGBc?~6S LrjA!<bOS4 ݒS9[6>u`d+_c˰kjhSgFi1T$*z_Ǽj 32m1qRΫߩJ\q.( +=2̊NzH@(GzG[DaH*s_JvW3}eϞqKyxK<[ gԒ1yW.0p 7o"ꐕ]u3˘hY*azF?#Z5)cW@ 3|f~z;E=,E\~l/UfRZ0Sx^vQ7b|qyB)^`[xd!Mj A69e=B) P$>2ˣCp8kꛕg]yɚAHԀD5f@-88x5MKfܘN H`θ LN7wuYSk0OI]"Ѕx9$\PYTS1V"sww3_XOr!rUQŁv ^B$kegFk4xD90bd0~){s"'4Fw"R cBfҿO!ú߅%7o7>GτZ=GcS$hPaEGKZ֔,ZAlޢ֭tcOH+[r]BF~Xo:A􄻟j }l(JSi{)O|4&Q/N: )F5jB:h<ē(?<6@,e=%5Z+0UL޲k٪jv`MhhMUVa a`o"ز( aE1@;4d`x~T O6ˌA&6~7!̕4(C.ɄmKČB a@ DEWY\#{L&U|%:؈;*bʸΎ TpW¥SQYG&< h!iYKi&,'_<[і $_oޓolB:U)7y<|+R65 E@sYg؝ F!za!&p9BEa}31]IeYR*!ҀVU `B9fd})B)24K$vZz=oۺ QEE_Jw01vO7u}mdXئ[6Ü7+u@z>_Y!ܷPs6^j[} `#^jw'TޱkzXK Xkt6N]MID/8NjdQe_EH{|QSE*RDGal'.$ZXPlv7KMJ(L$ei/^Q!JWH"qM>O?L7υmE`TCz 8$ezU];6~i2x)=곊d;Ǐb$:u/ \>ߢ)nqS,-}pk"\`&ΐ@r8u2'.c6&Д_RJ/$Z_15A-[d9ئ0_(!$%Ak9+lpWW]IavBsB+Vy!#/%bRkC$y?l?6#KZBE rĞE)QMcگ\@W-qWw hZH1,8:g'&d"nуޣ."zI mUI/ЉK>öGK)>(-(ǖVH=&p @Rk_A6-߉߁b>'28,ab ܯgBMAœbydR4pho5z%jE;8ı"]}\fvZ"|\:Ʊ蕌C,7]#k#r ./rR6Nj7pGn{ g19 VI1v,) Z:aMmCMI$ӄ.0csNp'.N Wge`Z?uɱaQ>ʡbhy.uծ br[cYAª%F𔗴SJM7 ceMf`#QW + 5| :?Lϲ0"-N][ ¼^fV2,r i>Gz'X6ecVz C{J)6-_Мb)9QU8t'Q< 0GN4jFH&#[IaIS!V>Bfl!Ry[NmtŬ!Q >hߝahݿx&C'G'}%x4 KUbzgW>?V)Eyn6>!O7$ْ1w*7 {;=&ErUbx# w0jpٵJZhC wIbmw"EkV!`Jy8Eg:CRC^Pή εE lF{c rѩ8)-Z6y#N)s~K] ^NuF&0;OP[RM0v;Vxq)lR2p @?\řU-Y p3EB{0g3隉;[(ucFHs5wIkF s@-27-=;M uٺwH.ȱI<, C4ۿB՚P8nA2 0+ۭ2efll:+@pDWZBY ͐kŲ"vɶNKgyrYWb̷ޘ@zΫzC%4,%q,`mL&ޝwk=B)mbM6t( \&^?1 ob~TM%fvn3jt- x (4F^ Mxn+x:2S>w{5ޕv^T7"k;QSl6vFe o\AH~cv}]M?Cvpd~HwP;T+xjUg4v 4u>e5( A \(WlG33ˬ][#v1_* UL8 jG?bݎG?9@%ֺ(<oĹ&4H][tߵ(BU* `=⏾0fѧɷD\D7L®\/re>q`,qSL\MIHռbFۭ/T 6ri 3Yz M<-M Nh?A xqHzŁ蔠Ƅ˕=ML$61L)נΊ5mEAbdq^ EQe-t!\lv#6E?Y j3w\FJ?Әʇ` Jn[g}"|xEheգ3ȯ% }_]Bq4aR^GA3:5rw[7eX6zr6;CQ~,Ba-g4LYBs;7rǞy 6":;A5:"ߔ$VLMy4C; ?VyV4477nF`ۃ&)F=`{3<}FoȲ!e*KM2Z;Sͩ:i:\lL6]sxv/zS =()]8s] h- (+f9 =q 8ـ--ݪ>+I+Rtet7i, 7OѸY₯.)"'Iaί{"^3:M@l Xʷ VI-iV˛|,\jDv^ϝ3:KuxI0v \*d8+V<@6*Eemd@a$:7<>D.п dZ)>oU{j,0UJ9Z:d]UեJQb⼒# aۿ}6/*eL*-KqXH54O&8(w|R)=<_z@ַ;s4&NYdl2=yn_0^`CW^×5E0-M^+?Կ-5<JSD,+gO1* ؖ#+pEHIgS:S z|1ţDShUP9$JD~!~~wqU+#@(9MyNhr&|'Xbn-bcV@MVV6#7i>(Y6$"q0ql틩'G#ErZH}qCQh HF{zp=¿1.XUcŠ ;9$- 6NPF4ߞۜ(kCK@~Du( Z`u1UǩnMA75 O\XaA˦ {{3XǨ([҇{{ n;?!("piOΞ#]I +:ޡ[-8?' w~CBWF:seK6UPVlB%X St߃ ad<' ^s/jefD%ĿL<zd %؎2 [>m0"4qeVA6e$'](7֐Ȇ%>T"_}M;灼!lu fѣpzP2w hB AyrX`)ؠ~lb>Xqkxa~?&tۋ8f?Ë vS!i+pd$?yC8_ H!,Ctcfs( Qr$YngSrIi`Hg͎)g,3~p~5Hwdo\D 70ES)CĞ\{v_Lޔ (9tzu?/sM14uC@ܜc[Dxg{8C{do5 ZywStG&ɾpIdg+fY~}~>7ۄutf'o1b`fzIb\91|ZC}05j#BaSm~G|ӢAX )Mj1RCʬ"KY$rlh]HŧIbOԃFIayEχt hyU %]XeS^vh6?Mf"* )2iX6x (wXOzђ 1,eSe ÏŻ_>oz؛t:L16ӻ)}/Y}۱zKVڼù\Nf9ǭc8rsjK1%wc.h8=^ݝ Jz-!]>x]4 ˥1/ǿPҧ7A@+( T;  Y-׺ /a׎T9v*v6&h!"{ڶM;Ф~sHE٧tVݕbXm6d]}\?W?ㆥ%cNo3 #oӿG*3kL_EB@ t"]]SWkMVAӜ} rpdz4!o"/5Di1[x#Rti=xk'"wR%5kb~Qap7>߇NQhLhS&XC@ ے8(mdixЁ7QӸ]`g(Tah iE8+vMLCH6L:M]#6+9ە 7> Z>[CvhSD檞m3x66J;Cr%mBl] ́cG.W>Yh$c=Rm=4_^5Q@ߖ HщɈv\fKia9ܡkbB*![BX< &}$' ߩkeK :]R?2\nx4uv 5*I4g6>Vj"~&pCMm娆w=X<gsǡO ,RFX r}HqG_f9 Lcg/A S?Y ٙGV!'k f_RhK4ځ#5>ezѳepxSWʃ׭CFX/mM T7 uZ +m05gʟ=bD:ssH_j/2s52~jQ'Le4(ps+52{iӋ{"Փ)3'CJl3$`lfH.jP](b%ot[y3Wet$ҞY##0%'k3{cAɡy9FJ0Xd#1|M3Bykڸjc+()ǵ0QDJgx۽OK_uHabul9ՀAGޮJ¼[Y@/aDt1l)8g_`*-Jb9엽3KH>݊H"ʸ&˸G}> 6PR*akdRf!OjI߭'y) (#xoh BTEs4u8>OcpuVa(&Z: "Z B93 4W㦨D!⏂& 9p4ݼG&VxOi!0~? zwJ@,eRt𷆥HZgwiWG; 9\WP.YXE嶴wɆ?3#W-(q?:zSAeWrk}qpk:{L$T*B0߰ܗizR'!|t'48r؝碴&влhw1YwY@y6B}O,L svfʟ"Uޠ.oW$p\6i# ,2y>Ze 랞ďɣ%uvY 5͕`j_C?*qD`W9VFix;Nz"Y)eb6I^s;(}q,ϑ?$gS%<ӹ87%ٻVw5Ėb ա}V}-[]&@ 8rs\;>TIwߚGDxcp\ZXj| W\9l增= hYٽ۽frtP xz0=7t  @wf̛R8H}Y 6f k Gg S#2 bVBR1(@,h#;..r;kҬs(5'8^K^I8F(tK8C=bqC{.VsucZ P!ҬO C<Fڻ}>cF═: 4 6C$.EB_stv,l#5͏Bn 'IytT;z) 5qu!Ђ|km0eVF}U$DOQwДGDۗg c$8]R-*H>L$S#kG b F.jb-#q tlD>K೺];9?j+4!x[_=7!MiHP}*{4*dǐC95MAFWSs,7b y1=m5 ʻ(eҀ? 7].NowJ sN_tRČMI?y0^IG :S@#9&R{> .P\"Wchէ l*%bxNb=߭J;JͿj3[YAJ ~`RR]4(qlq[?t .;(^ϙG=A˪=sրh!H~"/;ղa@fRhA),_}}*{xZ{b pmoz Q?u cumaayacX;,[m#[.;ø%pR6F1`!=/kխM\6q!_k.QvU)=1 un_+=*gneu&Rt@୻UJR8 4W*Ͷo5Y,fď1.Zѣp֖936mĨ;/)eׇR, vTKby▍w>KCD\v%&G2Qz}7'vZO\c\ +u82VbV$ÕO7IH+ SUS v=Ki"/jڲ5qGeXxys ~QҮ3i;tz>,{(3{42&guճEҐ 3hE 5ƨo`HYf˓RYL6pX ڄ>65GJX1*D_F` xSȗ D)ѱOO+eRseڜTr-HmR~?]Ɲ{r! 7ij( TOXW<_zd3ԘrG k(g"-4EH_}v@":ibI`h]I/˛!fE,P 㙄?(F,zݰ "NB ytucd+$-x21LqFL;uO^0lIS93sy&+ZZUfâ)?,z Is{x]n\YߢҖwhRCu)G2ޕtf!%?J,UU5TfH SX_q) d֗%MjPGҤ{aNYD;e'qǾR6IE2v&ڲSG]nȥU%W6/BA>#qeY#4F8;3B \Kސd?*HKŊH~HsLKŨ:5P&'fWJ拳"h_"G-ZFfq,T"Z\P^.gHr}LְQqxw>aFTQ یB@1CְE>5* 9+>r&*F%WN}lâgyo`aB0;GBkhM_Caf ]wwo*(]14T,,A 7T81UuǾgm }mH@s=Z9}i9dȣؚkw)0 im > qV743vuR~㢏wmsyef SQ9l>&cӍb5SV$&9_wcpNY >vA57%Zoɕ0Iub;$V8#>!PT Я-^Ke='I.Gn`Viu ~4{ycŇCM%1*kϜډ0QcC^s( P;Q̆OfXwi7!DSQSy:$o+N:]eB _R{`f!dD&4Ba}v9jlpiMu_bgxr _f}Fds#ѐ&IZ⑲EFYR{T NlgHm.sa/]giI&xknj_R9V2x zǿAkYTMJ7@SJ9)JD:ttV.;g^H݆H jE;}!;^B\ +4`c\앟rWӎvgܧ^(*Zyz]3ِs81d_>Wus:vȪl AAVr@sguFJzLpŎA"xCt$ǒ?r)N'3 +:}?i'0rʬ,9ȏnnRT&"b %OȔ"5ǖCHsW ]~ҝ;<+%M៨-o&w[bb`ଢM~ʊEYr8uH6c;V S^ˆ z9I-@ E]!$ߨCy"g)Wj 3s">Ǐ<7Owҩ Eك=l0o"!N\ܗ>߸?NE:"~BEb0k}fCvMxƫ-́wqW`}>t$FݎVAwo38h-|~FVm|1Uxl)Bճ8I7Л@GA)g d@׀/A}nsp%[^,TFR 3NABxk) QxgТP@]*5_u8 p' i.atF1ӆy04,*`@WcDg3ͷ-/X[@`pz]ȼm完zʎ|;Ah4_7'Gmon $UVHb̏qOZdU`5I;Z9sG(O [葝HA8fҩXCzJH%<ߛIZz;ڣ;zl2vS#f{%`mm(%p[~ *N.㏊y!5ZC_+I(CAE,Gu-w"ifN(Yj_J;q=;tFí7<ޱco#v;J *DgyCA4_n遲xb/j)(t+AE,Ge*tF)Dg;A4_n遲x_*Ab7%@sA+AE,Ge*-tF)/Dg:A44_n遲x_&hw|+ARE,Ge*qtF)sDg9Ax4_n遲x_./c ~8+AE,Ge*tF)Dg@A4_n遲x_dYy'r$J+AE,Ge*tF)Dg5A4_n遲x_@+AE,Ge*=tF)?Dg5A$4_n遲x_j d+ABE,Ge*atF)cDgAh4_n遲x_j Q&fPj*Tw>z) nrg3㧯Gг̃2^d\7&]b%\F B&0#Ku Ʈ|w.AE,GoJNV-tFp)DgA4_?Z /8/ |Pl5ln`anA?* *ee٘m;RGoeS}tD!d"K(=0q5r#Pħo2ծ*{Zkdx̷BI@S\b('s4Y M.*j/|fQo2>z~i{$9L6xg+a4Ue!It}d#ޭDzAj$zߧ\7ONQG@6ةԥN;-NwQӨh3T]SxnasE 1\#IVwv[``\vAE,G&_P?uy3L`)1急RG=Wi;9R hGn||<:T02abm0qNtFF8#Lp0Z*wHHƭר }Yzq-=ȱDGDgí<4ӵDp3_Hu3 )(IA4_n遲x_|0 KF;_ ”",AE,GfY H*-tF)/Dg6A44_n遲x_j oE,+ARE,Ge*qtF)sDg5Ax4_n遲x_j e+AE,Ge*tF)Dg5A4_n遲x_j d+AE,Ge*tF)DgBA4_:-@; ` 'VP |#6Xi3"O?.u&=؝ O&1ҳ'S7+'M2,ѳYcWF/OᆼQrNM+TOMqX3%-JIP_\UXsc9R푖vG*y!uӿR3ԶLk#j::VGG_}.#'*K.M /%)Udc,/T,-_ͯvF[/bi 9WB`+[J!!KٰZR6r~s` gǴ_ C&]F,+%`S{BIvlſG{HW Q 9diAip ۷2f&Ȕ8,=^vٕLez ԭطȺֺCIcI8Jڜн{'5<-_~!ZUa珮k(RIKv{(lizJeF-LD8T2F1eE@Hj]Jwl`W;' /Mk })B⍅9 €th4JmfVc^)! l*bi6.[ # zwaPE1 %{ics)Brnb016DNjCb7;4X˭tHՋ>u9Zt |Si{!&7)Vz.aB/縅虷>wIh }a$2ځ+gK1_^ B t/wiħ5~TmbCF? ͇rhA̤о.TqĹ3i9̯ʄ1ã~vV{8M"y|SX:9˨yj"Xl :ojt>Y^*@vkp Ut_g`pt$d&? ab.OoY{ٜbWЛϚJ4L AatFGԞ(.X7sp3 WÅI/cDg[ 5Ah4_n遲x_j e+AE,Ge*tF)DgA4_n遲x_j EՕx3^#da\lW /Lpb%}X>pޯ!"_P#j2 }/L&8)SUjGJF՚~W2q_;K\J .(y: 6CVL*"ljd"n0sAE,GNGZve`z(ݸ5Ho>Qvj#/$k ńn-v:K#>>;ƯY#nQit氝yq-D m D vSn{4I7rką/n( Q0Dg1Ih %7(2aW o6zљOtTlJ Ũ9 A UkP}0AE,G(Ke"qRN-tF/\wٴw5śgi[$FsHM)/DgA44_n遲x_q f#pc/%Y3Ol -+ٹЫ}PЩdٻӀP"w7Zx;v//:\/ :Kp8DIQ@!dj0;j3 ׻ w F᪲8PqWʇ$~_A8`,Wj-3nŌY$a7eIkr[! &`/0֑~6M(\NYrΎ h l Emב'ѿ{jjڡA>7ט8zeVʌtt:jVCL6Z' nQ>k&i_CܗDk ލzdsoS$}/6PQX-TH7Զ`#"XKf{:垁RN26ܐ<"sֶ+ ]tL~deɸ?&UFC Hm;r8\jIkHkص쇏Cv㕉O*\1BN!gVR&L/m%z8z_~hknDF) TU8}4o)5*[54eY6qZ%=8p뛧;6gA/;Wt=EAJS4b䰯Wsh<V]0^ςϪ4F^o yG߉}6ĦVQ2-#p _݅Y7^=7$8Sit`T /R加oT\&-&/ނ"@xEJ+L( @=Ḑ'- HۢBS?|gAececZ9fO|{CcBNW5nܤ %eNmJ_  +@tT+ՋVvSh<%LCv7Ryhx搴swv~߄9ę濯SrBjW hh\}xќ[f"cP x4xOE3 uWFX8XBy{}xD ZZTc0SCl|)CV dY<Q6#!0*vMizcjBTWWMw!W)t%x2.l{~za"]]r(bZhqIRG~RPEod!W'pJʐk]"L#qp.i|X{^@ړ)O9:If6z2jUG;q dDE}Tѻ7{+_Rp5.UUw[ڋTi'c=$da&7B fZJ6"hm&<`e.~f' 7N]`zÏyRd yIR8 N:js7r@;?M :g_1|f` JARE,Gh:;d4ҥ*cRy4%}A*qtF^sDgvA~]=N[hӮ @Q)ENi|*LCQ#'/P >Ax4_n遲x_pڔ **{HyƂf\,cuZZ6 :qv> HEO>~HU24|:C5K՘f)6N׶$=xqh;qϧ=9 NWrv%[gŔsp"m03r%-|NLg~J!obTgP`atkfoS\B2M-KyMKOWPG"O9ۑ)S. z'ױ5Yk1kJOכ\"+8 3ez怀eG2IiJ=cZBX^ni8\R F@8XPm۞H( JP= l"@ ȟc - c_s^3VQ,e^qBZv*a7+EgC ^4U*>[ޫN mv$K$oc]Qn7ۓFEmQv"Q=nv Aۅ+H65?+!ZT[{ꮦ(h\(1|O4G$J7reI?*vq9g{JP z+ !_v& R$q/"`({aȤ K`As& hhml11ֻL?/2j~)z0C^8^z %IĴd.Wi\p[ވ/;tFtR/[Y o_!/I!T`?M/2ơR!E~?y`y,D X>Hq)LT~=@-US 4Fba󡠆.xتǞ7_PTeuH9' ?.q5&FH)KwL[nC`_f/vˁ^ۄ߸G_ ^j<&@ŏqDp iS4#b"@LK<],ѦSO4 Զ<2Tw4pEϿi¢[:}FszWM1e-8^sp [ɇCRrO)uN0"k qеZߑA6%%}#RW=Ue_1M6:B OgٙLBzmCvҞ ~ 3 Xo5P;0Np>d.~g(0t'%1ncrIu.{@6T}К47SUO!Q_W3{7 %>[6mNȢo gҟ<e|u]>=Aw!2\\zDŠ,Gv8|3QUD_H6k}8zAM4zR7 Q;gf-|"( tޒ}lD@tAZz5 2pʝqK֖H%ٵ"qa$6RH?X@|9$^Æi`B3LhƹzBA6g]kf!7v tt/q;%48}@ncY L7{څcS}}rѧ˽VϮ9BfнߢhHP6.u8rcG_CFE$Z[VHgtY 7*w=Q>r%Xj& fm'/ }wdI-BIEJuh#6 AgI8[C sX-]f{dУ2FEq">Ɏ4Ñ*?ZMoNi 2Rg)DTރz`Ux'|2==. rS0&!GAmlD>r نSO#pԱ(^ %\MWwby8Xvy5[ݠ)ۏg.妇hՋ_7n4jbFyAE,GgyԵh]1 9VƇ%m޻D~ <|,zJû'?gNW"5?<3 \:ԂPgc2)<r0[4]i[v++/9j\Ru`DF3 )j&Pzq+m$?(]lNb_ ѩ44&tY +OQww(p##1`\!Dtw_t:ӵ@ٚT) 4":Tn7XLm"Nvl "VaVT&ʷV.g'ڏW)G̗\@%em>880ҊAoJJF w{&-=>9c.y a-)QTtU"鸝v@Jz6 $j ě m3:1(?:lw o@vtF J9̌RI pmSUfRngt7e\BcW<*Fk]pv~gLK$gNpmpDg @HQ*<=g1E %KFlP>[fhϤF?7N\5$ '4_6H} !S"MHAZ,!i#a-A4'_!/ι>km7৛1hB-N-+B.W51hЪ-? ܢ[qo:줾W^DMyi%U`s#jTFzL-9?=]$]( e%!u-9}M+e [7qa e4:ζ_bd꿭Hn]>Y/o5ݷߔ|$>@~iS}T(CdT4p`DIxۼ \6Όgk #S Pœd1٘9cY>үGƮpa+]e/W?Tc>x`W<#1@&%WNF]ᶰum$Tz6`s E|xJΧa_aidƐ!տ~iQQH˻Z@99N!a^4HhSWK tz:n ͛iM,;dnzft"ZqI[gvTb.Ω Q>n.._KNYBO`fIc_^(üabr J'0w6{m!4lQ7G,Q'7 ap&@\SQybv>j+{]Zh0PR$wlY#(pZױa\hxǰb<^AbtFdO]w?QgUYq`#S^oÿ_C|)-pzDg l7Ntf? |".FOdt YoV,v7WsnfnMBfvW4hg#wh$1JKZ,`j@ -&Њ)}Sޫzz<n.헙YlDi:,>3xxL16D i с%ܟGTX\e2.gBklq-%K9%V⣑s.hQ 0 ]Lz2R۷He!\൳|1ʰnVEu{c{Ԃct]A ttn=a/`.rǹDg/ p?`Ri3Qq^+ʗC*ta&P,l[^(%5<㫃U=D<ݜ;c?=Y( (/L#1bBRMU,7UA=n遲y X#㯱png}d}7"bK+]/gbhXXq aO 5Rą KDKy,Ga-gWj'hkv?[X*[[Ȁn__Db21z D=dž%jTP5b"4tRrÀK[T(fs\(*vŔM  r&Z6r_W9[E&M|?AiWIf,?yMAbE,W:؜I՚mE&W!\g2G {v|7Dg~Bl4)&ʉxsA4_9\UXOi/x?٬ءF`y9җ>iPiq! n5xAj+H5AE,W0 k9~j[-͐T;Dg &;d7IY*ưA4_DCJ腮̕iE-=P~DyGtNCK g^M8١m;zm5 Ӝؒ}u;po|^j9M(kǦٙw/E qa=_W w;*dG!ZwΞ ;6#0Ǭ#Z`_;UAE,G Ao6.?ӎe2j0ͩ Uש^ NH?tF  q He NTp Dg f|IJJ!"`7?QRz]!YqAF3b4Z.iR/3Ӈ.zj cS+2H3 A-E,G /`ewݕ<` ŲVv~ F6`.E n|YIǽ7b!FQup g"ßHw vB #~K(%swM?YLtFiӪ$IX A%%J P$N"~.̤Y;l VNDg?&/oPNHN4!/-rLs>JmAS4_RQêʰQWPO0,H&1HކNu-퉥[^ݗZ%T+?ByJQM(DžkbkbCx51e_Jz j _l7}Nm 0:E2 ^X}~0OizHu)p{Xn$@F3 *w>S+Jw7Kս*1y=/C#УTy_I/ߒ0^sS6m} f:wZ7M`πg3җ jωE(b j 8q &iK.#;ekt~ӄ<^fQJ`108ٽHk +~8.63!hZL?\"s}G$򳭦FgNE&mC 7[XDy.e M ~8[ #;rǾHח2Qԕd{YYmâʆX}ci4*g`&<|s4#K#-ٲHwuP92/rc !K9OU`9lIk9Y{|;/6JXjF?_Zlɗ)~$:ϣ=\gߋck2UgS2u :8wK+:ryuzD.2Ib:) a@ ^]&S[u&DjڸʚVzfRRY-#ϾH_J|\ "GD4ZQy?F.#h @A2eOCz2[ "ǁǾc^@ 5 N靴pH\~VFUNg\t*@1WLie 15S?dF&۵{ ʮ$iEi[?qFTo-bى81_^EzBt,5hyB'J46_T@z GKlڡHn `O;(w &ws{Iɋ?' ֌Z ?f P=@ZM8NFՂ>\wxMw8d d\1ݥ ]!H#ηh㮦a􆙁l=ZPhuuH<'sZ~ˇPUb`hɔu q\G>Mֆˑ=avF]P9Ξi`d> sN0)~Wĥ FV@QBLaluhYAi h3MSՈrZkqBpܭO6?n4*ns@ 8%M aTը| I,CRWiM"-ˊUvR]V߯WQ7:]K@^L8QI; Gs{;BwAjM)wG/Ŷ$UοE&?%LtE'OީXלV,\@EƄ# #hh[7uP; &("?ed;{cmη8"Hl6phj~V`P~D64uOVi`Oz?v|-Ln8TߺHaYjܼ<{#_f™xzhU *|})(ٱ(ˏڜXiEUF܇O&hdÓ0_\DyChx2K7un;MVX7)gf~RG`]C `?O`3UU &g ȻK?u'NjZҒJY2.K- ^xp3c( {A܌m%Q}_x.A1QE~bށiB *G ˶D/Om6gE,DcoA|xc+{6?I'd5{b3׽c+ρifZ9 m4TR;Mr~qyryG /X/l|hП(} es#:U9]vIؿқ J(`}p@EQQ+< ZUc?GKUΖאf8Ƙ%ȜzF2Q$?u)h'@6|OfhWb(ZbDJeYG¥)vn"'lfbwd>GkY:($BIA 1dRlXBr`̼쌔gi%I܂{8D? .2LfRHl}DUpQu/T5_:\jϐ?/]٤a8$ػi:O/[ O5c5e\30#T;id; hkdܫƒ.ɮ0h·W!ŷ7*dieGOxxE]!Cij 1zr,qKCޜ/E`bvШl.Hrb˼x!M@dgDbo=ۣnh[\m# 6`ʩ'g*i=8q$CK )l,ȽaSdг`*:9F` хe)pP𷕏׋PV\/`ËV^$@޹罗mK*<W÷=+'\6:D;B[b/}/kwLF̘?ڥdvpop/Uj#QgT~hEq,nG;LL.p߀cWVYoϳ?oH Ys<^) (W"RR%^yY-g9sa+řz"LG{dN{5P4XR9Fp(:E= QLO~!6~[qȕ7H2<5PV@^>SS#T=!)C4D DBL(`JsAy\ǰ7X^{􌛼顈2AwmD0,KtX /Lp<3rj;W>\w'2`{㝬Nš^]g3[(R fxge:V@-?mr!?9.>+8^:Uv|=9CPn,QZk,GvZ6cU iJcI*LƆ$Z Gfn-ueGҹ採,yEs<'`kfzZH>WykIEaM&dFD=8]&j! C8sc.I*E_{L ~i`nH]QJx@K-YF>xf\YSBWXpsPOK,ݟh.f]fu,(l;dɵD\q6 sS,UهiFSyMTFkE(]w4Gw dL2\hVD$j%yשOit'W]j<hyM*A0xW7FEĆ^;sԿň!arYTk1~pڵq.O-=5{>>$ԩqfG~kQUH;eߖ#q nK$"3 th?S8r~KV(|Q?.WCoʳbV$- y`Js92"Xajs*kڜt?+Ssmw/WPSM`6j)<`*ZFoE-Q7(kj/w`z? HFp_i8:llsPk=S[gC0_zTc@ʆJ_Tj&FgmyA71ވy;[_tܬ[VWՉ'~ކ(DʖejV #okW]GsW\} iލPEKz bÁU:7\S k>zݎvwo}ZkӬlWޖNm=q|9L?]ڏ~GBq1ltEdi4͛N` /e/t:Kb޴y'0f?A"!%XMp߉Ycox^DL(YNY+pW2Y(}iCr]/$r~ψC"c\P`=\-p eJ7_q!Du0U(R~ p9&ΫU"'[ڄ>J򏐊*̆뛠 K?Įo) hԘ@+HKn Xl  , #@7tYVT\:Wv4D%պ,I'ԵWV dVփQՔ;p>C;2']$(ێ$kZ̫kh4P%ErJH0laSW)0rvAgL9,J޶՜BEק*lQcAs te`1hkHO>fq`‰#,[͏t !_U]qS&sR$Y@T m22s"N`wBEi<8-[QV̬"8AE,Gtl̚dlgBo|f~?.qϋ \y l%e,2;1V|Ua <ͻ8Pvr{"kj7b.3vQ;'LJR`.AzdHcf2"G Mn(u'H jW0nLhR7q0؃TYf7d\~Nilyɀss,-ި@JtF!=@F7ƀG2Wbp8zh %/1g%A>,2txƩyL j4βTȪ4䭟JQK}xR3Cu)O{dE~f/! `׶" |PJh:?:ՏqC)46&Bל3ok?&jJAlB2WxrFϢn3] h[Re= `(մ>Ce%츖v?4 xKskӺtw8À;b+?*ā~y/~-eJKT/՞%Y[@`u\z"o2ь,+1ɞe-C"#Pw0aD*RX! A2 c`,sDgXMed@ JCksJwV$ƘA" qʹ+`(F0h`ͽ-3cS%gHq;yŸ `A4_-c'rq IÉ=Cvs IBS2[q) -ަQRgKr$$Fb9Vv߭&vZ/Kǫݞ$fe "$k[LPh xsph\dN#t-wr'5fInS9BoʄxpPAgrҝtt Zi>PKkjyxT0 JHzplun70Q6ҎDJ]o3ߍxa1霁%e;d HtՄxy bR0Qxqܥ$y9K~|n̠3(:shfonxȼ?)p3Ӌ>:F.&u!33vjq Ձ񽔬4lc" ,-> vC^D_ʡ: 2?JZ7NBjګV@QIY`[Ká%qϭ$3cvtTNχ*ia6*NiyGuk5(|'G~Z xf\a(.|i6_h ԓ ; 3MBmT;s+:aV!l]I(pnyoetJr8WF=;A$pq5Cl! y}rJX*ZKaD8ԅϋ7PAS_ppp6|Γ"aW.={ބfwK<x&6W^j4w(`^pKKyh0kVC|eԘǢ2٭,S̺(ٰ53&JtPO;IK$R&DM뙞`7"9X25\rHH#v2`e3'l\:Xr,(),#3RllU2eQ?ЈXTĥ 8vT Lc+e鴜z~\ VXaoI'  G?9&mN KPtce]HD?b)MI:ktVb=V悪jL09&>{g4zn_.AO<ۏ}ՒHB9VְJ|Eǹk=;Jx{\* K2]1ϷJ&KL.ݒaoL&#?`q#Թ4j1h !K;>qX*Yn8 (!Y22]ڤxMӋ/ҵ9*tz ʹV8u%RbnV;- 'Ld’)_?)M?Blŀy/p =^H-cQz0Q&Ư 8|a \]5|PbH_RBN"dpǘpQRElVy2=Hf0@=7?psYO|f%L\/7o3:n#GϿ*)s6&ĊK^!OܯXL a\-(Ϣ(5bI-U=&uݹ ?j+D%D!VK~,g,f!sL3Z݂O46`Jg.Uk9iuVМ"ӌ2,U0D>]eU9Ml =Dz(^鹝O.N(ޮ~6IodV14R}?xJ#^S'N!3gφyƏ SAj UMDn?vŝF di2׈*4o! EnA66^O ,z]tOžؼ7O$WE@ۋ!i{J{ԤyĺU㣰S{maF7So:EX`G;?*A>Z~n$1Q**ܓiT(^ NlxH,6Ӷ{d+^RvQ8Tc~6?- b;pe ueAA4˒RMhV".YO-y\Exdj5Xvq&{6/(<;d<jQsxDOF#,d eј uyea7,;D!Éb!KD<ð,~p ?&D$;9m A=U .B)+1"g(y@6?aA:`{/`Ki QJ qv߰н TsVGI(N."?E̲xb~=^Tb-0^nI؜9g*$Pg;T[=V:‹|gbe. $aYc6p w*Y'bqD@hk4_we%FPEblVbrfu+m+|*\.9"I."ʶ5T=Za]*zVצU,5Dd s&ONeZh6쏩~&"aM+tƂwΟKbܳBb`xӮqP7d/!CB'1Hm}]YtOJ-Y'mCAE4LGWUD=;&'|i=LoUl9,9tF ۱Fi*;DgLSA 4_FebcEjKCƦKB5?{CB9g\D ;oBno,2fX_JPv*?P[܆RU=x 0iWBѺQVl,- s. .4wb yVg!BS嗆ë Nwmը3A&aHUC3 ^7I`u]Եڪ[$/߱R>Ev{Ҳd"uG|`qټԉEcDr2/{]ES!eϬMN!CNNw,džG錎e4yȵ7rH{+tupV|jQSVa5?|j+ί@}YIX r &Ŷ̚S T(N=YWTqǖGׂ΅Bթ6/߰Zb]25u-e줶 BVQE>=!E@ ȇnDwC2.p|\FG$:mSE;;_1a|"hLCx.*rbss)O)N݅/YjӼH]Ϟ~Bbo]S%^Eq*/9|G#IVA_Rl}3w~v ]!AzކVj6=7sW,hCr#=E}<ʃl%9u|@(k1;q L?P676ӣكe31~gE+eQet; Ѩژ=^~c;A@b@hH{=ED^.WA^E,G,d ‡nT9LRt Mߕ$*Ei/0rNgly+Τ ,JdUZBpj&n82TۍA$FR ItFgX4]+45 sN^p9ު}/@DDggXkU[H;sB#=N7| A4_ҋfHޫ'4A=Y"4A6eʰGegsށJkj{ 0ŜժC_=Z9rplX^Qcڭ%Mg)7Y=yU%ex V c)fHW*D4YL*=5w)*6Rogԁњ_rri?i<$aS8uOxD KP"={,VHZ/Rs{Fp8{.wp|w{nSO .wM-^VVQ̓ <;_J:YFO5Qh'9ȒrTƣGVK߽qD h+/E^u[1M~=-1Nm_Z1`npK.Vv:pּz`>(F eڮ33c#|AJem%S3^,*?!=Mx=Ї{ $~;kz"GuoIa?ե;hjukuw̆[j[LN:6_rF*=t>&J!"`^9%[")'=VwMsl?#o)>$ ڸ¼#>yNPճc``kʷU784jip C,L$X pLuO#hɴg7W7<8ENX'Nk`dܙQ O P- @wJ {L`?v}bӃo`c˕ٿzv- ~v̺Q/e>j w}H8 R|Yce9? 8/DܐE5${Չ00&!;UjNQ!zJ?ks\IŶvXoqOQ?pij#Ơ4r&Q#qU ex,>E# w딣]4;y mxm$yσب.KxZo'3;,2ku}*0Yw48`<LAi#ޅ2U o$q۸IƉP؝2LӰ1~%gss6iMҖD쮬iV;l{o?\ȟ3X|w^tto܈M^nID260qBVDLC&%9>3!Ouk0lۥ3 u%Ĺkt_y$sZNN]K" $>@S%lxjbDmbD4h%:k.&BIA2󾋶8,#/Ԍ`/B|/BBEA rU+u9'^MPt(FngaAP':7(CS#ǎlHg kuC^Js&}uYjM5~ŐMTk(IIz8z>\ DefPϪ&-edaN[X,<_,DJ7?\X>:}jO 8!vyUP _'"sdM6ڱAr.y9Cz*-9]_h'jciR0W[۩;(,x4aR\ۚG*CdJa ԫ[V8C! HP=5C:'&BRduFU /Ӳ`7w!3l5cybJ? %W99@٪!N;.ΝzzR//"ƻrШQlX[wyn\p-1\R`P΄BjySבO3Pk(n6{ sE$Qquit<JP#8|@w<ؠo -&U[mvwz&?6%l!*(;tr]FڜH/TZͥkeȀ/e=T0tF3yxկ0)dAg*o_tFbG[=o鞓( VDvB7A))<4H#I(,7C`8&=3[ձz`:XS+y53sa>ֹX[潍yV_Tr6؂R.0db3[ 1qA;#GGWչU5+|PR\U_.p. և six*MJ5nKAj=y{o xG $x 1^qQk6=Rjil4K~ 1̽*\Dgdtc[PQg׸wWGl-щ9Rk{`ď҄$fmxA4_rn:XK0s$O[g4~G (R0"uOo`qd*QQeb!TP* Ho/]7^i D1צq 6Ƚ2 3a2*HW~kUIV Ծ\u܂:*-Oc9G@A+rJ|EGgO*:NTHg{%THVlXrd\:5.]=Kżްy1C*)p`VQ9xnڤ򠄔+ ^fLE;x&Li[=Qν;N%a O v {gnOu6~]~F t,pХYߛ}T0~;xC QS΃=&1u^pWN޷*|bXAבLQ(fڴlu $%t$|4GL5 h<eF"0Ա 5%" rtۊЁJSJ+*ow?b80IGRė:+Y/|z:M ح8ɞ"i/mH ,YZI%G pjޏ=&MMW䍳_2Hx,ic=o]~VJ-ִq>,H-n=:7cAGm"\uFUCHZsz_ga$̈In!qtbp}r J.y [<~na;Mb{VZja?EZϊVMa;=3e2 dj.E *;7,wc[o&[s ^sRRF;?]:ΒGeK#}\cmET^OtU?ǫ<:У(&[I!Z@+Dg_Yr%aF'%{1A04_$[xS#*~ų9ERFLvYU<~kc'?gP~B,,+I;G(ɤ g 5l|e\GΔZE+v f^ZVO(;"> 7h.SE 8wR7" lG V:m{ANE,GNaoX9:%CNi0*_tFYY20GgӁZlaX({Y8ahþ㩧fElK7=Nx+W./YaVq@m] Ģy#; mtF[իt\f'NmJ.ȡc1+F^nդ<ʃ$GǾZb%!tf;iIY2FHAYq3&IL8_OU7oDgSuW |cyxvdAr4‰qTӅf :-{k6Ǩj mŕ6*Lv qBRSB@ϛm,P7S[1f۝Vz˛f2:  'Qn[ܼ,>^ 7{# ˂llHlt<S٦^\Xp,5E'[j tD0u[ ;DgR`.wv€1;a A=r_[0|ӋWOUmdϏ:+e; 뎵}`waK6J Ug6Դ[Ahc_QExr<&[^0rҌkK $:qt;Lc TT?AE4LGBS\ ^l:2SmD/|K9tFNV [w nߤ(zʙ`?DgG"N"D?G/CA4_֏I݋ x3!КfQfUm &5Ĭ}R(oVA_2^ zn0ѭ []@2k:7PQˣ<^vBul"CVrda(u%42A/rEMS2")BxM%ϮE1 ?T=ķ##0`t\UToiRša#7ɓg~iOLZK'bkb7&(27c'꘸#Bh((gG?oȑvBE*Ì;YRd5rc,Qk<p[?̑u.!x9|*;(p.)"aSmo!RLLK\xh:x+2[rosvH-]ݑg_*,~nCo|MqΔ,ʃ+d@bD2@hJkXH]mlЄ2[-̪NtNp庢;&r5FML(P0TúSʕYcRG7ƇTG hMf QyhmO{˃ ]tFqj*$ɤt'ՀR.xJo gicqDg:O5<СW@BX(:Vt{ɜkgl&V+@ZӽDS2~鰟#A4_0(zz!Jvu09\xɜ} 2ԗ%TuY0|!(+G',^ڬ]|[ݶ~ 0 xz>:m_ v]?ӳ0{]՚UTD<gwcW1 &w.l`P@QOw70&)'bm:$z&YiB>1<|(m[G/fU/;/aA("{w%g{/dz܉a~N0bNk=+=qJmHam/ N# ڧh Vb;ZnϤы㚱;is(G X/p(ܷDx;JKG.;q *9#rIRM¾ w> eIEDuEJJ I[_jFZ<֭ 廬3/1C7 z \qKLnjZx2lQ n&GGc”U_ eyvZ×f`;o+:,?\ܲ\Oma@jrbr\KJ*^mi-=T-Ҽ3܍-a}cʘ MſJ30]Z^}P_.F[AE,G;ҡ`W4>zw3 OЊy1k,Λ^l-tFDRS AKDgEܭ_~܄1 U;d= eeAA4_ma\.Hn1o&arvYvҼ!Ac*w*Ʌι㥳}ct:@vahi5o0pM4Yq:T^LAE,G9߶&/DMF[]̅1rByq2+tF߸`?*DgC Ü0A4_VZqcpL0%Gvol&b [.F͊UHUpqjq~R$Ze`:YFΘh!D#rg`nQAE,G:2K9%_r?k\ut-gk]p-[+tF8e@+Dghw`+a3A4_ҋf/Wk]zOțEȡkTK<|3@0̷3^t-r?WNܜAgĂQj@/›궽<͔*77ľCƭRA=8[5=]_vMOxy.}?(Nu钨9ěD\~$ƈ%g?H pF5-낆#⍷lDt`s$UG@[* >maF i؂A4&6d{Bqg^7:=PL'1RsZAL*„N4s?@U*|17tCm+u]< $碼X7J9(һe1#p=`P'f2u|)ـ+,A 05L",ɬB}P%)[CБozyR a|cb `MO&(p28+zr*ɨ繮{4HsU\0(+QL<6@U`[ pz"!Y͸VuNGի:6]Ux@?͍n쩬mHBhuWb#5/2#hnUǔLyk=b l2iN}S20GZέA\ HAO}=o/fo"*>!ć]Dgq/{%ND)eE9R)fTTrwƭY [? mvwydQ[m]>c8laqUb}IAzql`0/fbJc˃dJ.cAB4_)-0;K03{@/[k_r!n*C2]5kq'1}_/5Jr#09JjWw] R(6F/9s|3w6]:\!?yNf$Fj]@Y FWiqc.%:Z=byGI#J]ъaaDWy>"#ஶ])dJ_I!N_#*fXy N:/[DPw{E/*0\)Jd2R-?("R`WѴ#[_imW&d}pܖl~Zy{/{; |:-N2'%Y7`` O.0Lғ)̢m!H\Q8 f'>M̗ZMb+z5t<{w|6Qh}<~nZzhTDQv⹊S$4gC:MC^ʾo+~Z!y֒ RC"H/*+Z>5i#QO;fz Jwu$_ q(q*YC?w9X)pI@Ƒs+Cj{'FOܢWAڠ΢&Cwy>4?D^~=㈑"QnU[CzpUt!`IsVȯtB/,P:3x(Q3|FDeԷTȱ->oP^NpUӡ8BԴ@_uZL39;C;72g Ԡ;eojMD2lF%^orGd_ګu*JmÌHx509:8CD^ír!Qʬ]3@A`E,G6t1%W]-C?bѴ@ BZ )T?R08a3b9}a>5I|/'VAwDY?7i <RC' xk鄁c\~R['D ˽Bvޚ݀ztF>|.܂bc5G'n:vx״CUJI|cyzZi;ڲYbȭړj ~Dg$MQG'$'HM4d-_c{}q۰.X٫MNċP`ƭ% t;9[ 3ZK8FK0!A4_ ]fiWUDtB&M6i 9c܏QMf7ɐ0W_Ŀ6@aqH m#vXJ;Rm^H=/2w(_[m& >}ݔtG񉡿M$Z0 7AE,G*ß\V ;P0-tFcRg/Dg0Ĥ^@PAA4_r{2[Mr@[ +c1姇WJu/!"t#.~ZP0%Xk6}> 5-B/`?Tsc Qw oQ͋%wY.3"ײONs/`嬫Dį _bþpu ,r."rA ``C2K&Q5OX_)",?`v }X>4^/"gȢk"ɘ"cF ]8T֖Ow΅cR(+@PkDkҙjLx@kKbAE,G638wPcwx”!7\ ql9|Abp`RCP@-0;tF,I&d@ 6--5 - Dg@GmMA4_r{Po}Edv4e"1I~S$0scȄ `r0Iv5?j}xN DW0L+%;=R/:DKG(HSR%hD1U/4"&[yGp^ WiXF9G78 +PȺ(va-LST?sov-!~)C{L!zS+3f8Lt %XQ.uaiԇwf|7b?T1`\ՙ փ"'~B,GD(JU縸vڼ1FP TAi;SMy2V* @E)вr ],k):wlK/m֤j]0 ^#qFAmvĩQY6m(T`15?quh{}Yn|Rh7Œ3l?$6Dg,Bּק.q:'K)ԁA= $ȌR\f?XqC. 7TD¾sKQ9b-DҊ?l Q銌JdB8l`V6zs挫GA7tFAq ϒPmUp)i5(mY&IhIAE4LG&)ͣn ~^K;hl{`3q}J5Z{GWrNRp9dyOy,|HD)hc)6&?G*@O6tF,!mvEճqSDgxȵRYB@B|} /=3zqA4_%}t}}?ت^=4#q+}~~&pG:-TEgm-eI) ~̻p}la27B.hD2$mR4h2yȿ>ѩ] ^XZ>#}/jd[c 7!avqj-s8a4:-붏AE,GiC#Gf.GE~?{Dd__a4DM%ָ/ɞ:ke_/8 `$gL<'4oy7jlS7f?IG.9tFw}@)j;DgxȵddC8v>Et1d& Oof7/$[Q :# eA5낉7tA 4_%}OOw)3A=IpĽkI?MA$pFLً$"xr P["w\w=j¡vC]T#Ydz%*:LWyڞŸ{m08M&$m"gOhzEшoFHc&U1?K`06)`x: f#ʿm; 4 A^E,GiCH{ vZQ$Ł cO=J/z&[VUɒegT#8ЅDӤI_~\<r˙camW?a2R4 ,s"#i~yAlYAf}tFwQRvw,6(s&e6~@GE".CCHšal> (ifDgxȷ f`SN]=$t[b/-4GIq2x"D3"ߗuHt4Ad4_%z,RG%>ӂw$rOt4M>4ۄr=opw~C0Ѽv26{iK޼ y;3; p`9ƨK`e/B>4;׀z٘ۻk45IHsFh]%L),̑5zR*_!wf R3tcDm~>Ri7^yqӚɡ9Ŗ*Lu~ -qn^I,2~G`AE,GiC7ȕ *ICV0 0{И?vO `"˹; ?4/]:@Ӎis/31h֑=n]^@cZ.YxtFwqAc ǘ+˒f_ vqa>!z̚_gM]n2 ) 8aDgxȷOQ} O%@_W z~!c9$0,!iw< ]d SRUT],A4_%ywOԝJY+YH)nRi/hs7¢ҝBZP@`Ҿ,0e=6Vi!_C3m˃q afX#MĕK,o9w2r@ cA E,GiC=([8ٱt׭D/Z?u-Z.%6J4J/˸b)tFwyck'H| ;c" 1vylZ-+DgxȷSup9A04_%ntSa1`,ANE,GiC@+mtFw@G*oDgxȵ34At4_%n ,AE,GiC@+tFw@G*Dgxȵ34A4_%n ,AE,GiC@+tFw@G*Dgxȵ31A4C̭Psae/%KeIuQ:7o}C= >t h'ns֗Y{Wv"_dNκ[XV<܌`Б_/,A^:4ZhѺu$hc8wkK/EaP~bsD 6,XK\P na,:EdRl: n04+^m? y -8}w 9&@ctirNKk/V@䆳|p1nS"}9cFV[xRA $_b(@*2{Ѥ4c'Ӂ E%B( .3y:J[ZL+pwA^Zj xC5vݕ_vFhm_kH(QPBǴM6C <djcr.ǛGoI>うzk/yCm`FbNW*7G,K< s;9+ x{)9Nu ȊJKM?~Υdnq!"tqb@ MtqWͥ*܍1&_Pu: c9S,ӄ@$yB"YYP*r ȱI(6 f'GqSϟ79QF r%Of 2釘䇡ZVxine|_=\/s`}jqǴHqtsydqD.36+~ )cikv*arҼIuFpsZ-6=פm}SRB&b',]6mc'HGuf 7/n̏t_ r-|2'㯪Lf"K Y oCCy-4: l-K0~8goF˙]m hmTaŭcuónﵮ bp?860̥(bK&Ħkb{yNJZ~rV:8N;u5͎k=}Mx^ 慲]}juhbO|[j\XM u5X (e+>)22P?'@ƽ't?Ik=͛W_ _˨FǷV~lpGw :6goF͠U;g)$mҢ"sO׮ZF:55kqg:vih\QYg6GV9/@,O ]W|+حEnr 7/_%JfKjUl)&΢H'ӆmÓȩt>_Njq_.&SJCf#E$-c浇|ȮSޒeXl6v-5ҭ8Qƙ+"u?3f4M#Uʬ߹Hȅ*)"Uަ_V30D ڝ2 *77#B*6U%v40(D<2̷%4b`z7])vwe)XG+3? CLȁ\ju6Zwg8).j"%X?( 5`V!n^>ͥ-uE@VXTUBֵˍ!wDu@|x^)7 !__D: 2˓?(ÙB H::&*V2j-W^4'qtJ=l"7sjbmU3ffU>!=f^רܝ@TԽWtΖ485x% AkƊTmd0O$pL1  0^_)$lhxM51q{PI@3`(>wY-+rm=ƪ1SvkgVb d:s', eE~ѣR`bRtI\{"JKyJӔLeDEb-0J! -HO/g6=f"M{b>p 8!r*z&bfwvl U\6ҔV&)O>K鎶 2n4z[ccL!YQ<ҫu>w=d/&"}'a(% ?hYfzKVx8,4eūV`q'F n{T)?.(fy%pWZnB1$~$(V1^yl ~WwD `݌!:pE޲輈!r`趙R ɵysN76Ǭf8}=RGזv "Cd\ vV"f<VH'ɺ!Aٯ`&; M_4 Qd>Np4~x&: *kIM}7xJF'=}nztVd#>ƍ"#[.OiV"U0T&1\0~]ZUetysm$q˃/!ُ. /av' |u3.O0}hIrWBU8~h-c=m )]]ڸ$0 uW`3z dxD"k}>8W jQīytjȯ>2+MYb~UTnkw ?ތŸP(#Ei(ĐL;T 5r .%(5]36%Y?;#9?jw#JRݚd/ 1pRѦGNr!=\H/J`=NYia[ )8oF=\=LJĆk =Rnc.⵸Ln8mby۟&%lT(hsaߨJ\S@d3gB!]]>VgP]_'L&}DXHf΃hbqC}FRfjQna]޳\N1?myoKRCy ^e@@6F0O9u^I ]W{kվqN Vz1}D/cE`Z@(ALmG#IU`1#vS?6R} .4B}@d 5y;zϑȪΝl J F˅d{tC~Xoyh`VaO6Y;ѱ ٵ}V@,Sm$^;9s",bRk?B?/.⪿KhMu] 'qN?''zq&Ǒ}%kJ&b$QC/SF:ʙR?oef?H[&sR Se<7C9mI~"b)B3aHZh]_Kir`|8I=fuֻ9N#RC( @ŝ_%b&QV./b (U}'msSE٩ek UˠC -P.<#DT8/egUoFM`w 7E{A^mL5`eCE> $7v *-Ri& LR;n+`OY,Xˆd:vBSǩ7tWž)6_7fI抎qB2{D,>p O8cfRi Vφo Ij2kk%| Ukz 4i\%1R, “K]IS F7Jo7kCD 'q!Y8Tgcv!6ZeלO? sꝉVInSqX,-i6;ָlĻ/ H(L{;v1u-[%ɝmHێ+L5%PudFhmF>=4 qDuYfMiM_C<񡊊8ZX"ИLtseFkA݈G,y,WF8^7pά9H W>=Ul5DTZIؗSVu]hM67FO#%bS~y#+O'dn6 XqU = @0rSoB;8Z}{ɾsnJsLnZKQonKMI":(> կrwQd_7UYF7[DrQ‰|1GTӂƲu4;64-;pZL?A]Eb'"rs\ $>{b;ˈCE;]DoYpvQΈPŕ ri! ~TU?UE3ż<&ab8́2" h(CS @F!B\< Ҥ/[8z#b[VI i<IܺFFI&׃/>=׃J"횭|%Ab9&uקM9Uj]tV yf5ĖV/@zK%Ia^oI`nL8E2!\~GbK1-v`Q{.|Omu 4ֆȎ6rz5Ӗ ԧ[ʮ$WH {ifYG#@TdހdܥNcU@6l]gZ#Ҳ> ]J7=z{ |e1XCOl)dYAĒҋ2Ot ٥LQՁEN>]KDɋe[z٤^=S0Q4i5ٿ:YƵ|/9<[$Xv3yF1ײ)f>WLԅus9 )'םAU__$`oobjH6#28*]dxkي'套ߛDҔykכ#=f\wiKZyocp Q%j@R&A~/{DZ/!9 I΁{-`?P)1a9'X픵 a&0LN=tfr$\~^MhA9<<[趶y\­,LTUӧܷwlV@;3 y$Rmxfǵtݱ4J4;=8(݈{Nzx7;XJ?L\*J+qϣ%O\9>4fa`A|JF:``@ $~9 BJ=ȩ#  'E4I񙱿 S@z5  e}R !OOjആxqNS<A_ !g]w m5B)kxZrGuO t%WF0MUيAx]ϖ H?Lg[! 9$VnRU=-r%Z:5`vm*g[,Vx8r`cdD!I#N4+tL;Ė ) *w!C=@_LAV=e1h*qҿl]vP-".-q(J>)k׽V0`uDw޳Jφ Ġe VZ-dW*Cq$3o| _A>VQ[Y㬭8ծc5gs n : F'$[rPupJg* Yd~嫸H]YݤI?q^,m_"箥 ^bBo{0P^ūCAER?)S00=T'j $zQKk`MQWg΃/#7^,΋ȏVzbYQ«bhw%k *йۤTNkK0SP?rv|7[uO/z&q&'sH M]+85 sñ'S>WόJU`U?DC̋~S[ֽ"?ԘGe?H,Wjڸ͂迭7r/pZ&Ogzf^]ߵO䱺{TLCo '>=v62 r`A`mO'w+} ZEF$@QU 픐ru|ad&r*( 9Y0q>b4$$Im:FKr j󋆉Uۮ΄CϿc/n}׈'Z}1WA;+MH\X.y' ơh# 1Z~V1 ^юZPQO`?-V;.dHF]+/XLvM+ܪ 4@-_C">$y,F=" B..M󔋆2LKchmjRJkV=vM/eekF&׹'7Vf\#_OxbƦ;dN\^Ex?c&j#:o7NxBˮG򚙾S"(i,.#Q_ʆ v@5n`'磮XF,;v).QX&=`s\&bh`M臭Ye c[Jլv!<'mt2"T2{N_HyfL)Vk6qE@v?Z<s?-T#^Mx|^}dsSެ>0S#CaEMuI55cʄv\4PԷ_Qr7$OqQ(eM(Mnj|i%vv),SP!i;{-.#@bR 2K= E}Tx&7hp'l!L b+vHXKE lѺ9-G`m28.۹^rZsUy Y (\ʼn !җ.2Կ@8֙onH/tM3ϫzyRXIRb}lD%_@lC/@)W0(opCR+h:ͮ玳fq-5k1ޓs%KzWg&nuHJMy>b{z-4Ejy`o!c-rנb. Uvi<^'Ԩ"d's%4  (7F bӝA-dvPPHG@ /||}D9C US44{ Gh5vͮeLe@b)'g3jޤv Oc8UЕyyԊzփy)W/W܈X(&-ZCdMYЊK8׶ 1LPU}ï,ζK(&WësT7c,7cʹ*`vDh&ic_Pݤ?nMBXYUy@1:W4^w3ӕ;dp֭ըx^~6IEG=Q(Jl(&() *ܚʧeq"b 7AQ2<a0ߦCSE .xŞFE^(!)R 6'_;Ms3Ć\=24&Р~^5) Zc~*HD(I,uNWwd&!{,3 &MbS|Yp8%C x{I 8&WC`ob3Wlſ~6g٘ z BPOeJ0:"c nJ/c'A.A "Eo/Ժ^x/,?/%Gȉܩ|"! Q@<Ϛ/7zQ;uY:HAMsus6a]|ƫtb Tg>G *BQ!f:*m:8ݱ{wT^@UEmAC YQ*J 55GΡT@-4-14վc#,x F;*M>JAxw>!IMbc|о~=4C.M* a0_0xNW,Yw9+e4 AglX ZۀC:f[1FXcw*~i(;AaƠmB.`*9Qײ;E ym*hG^ol9 fs^큉} S'_~1`Tn/z`"OLYP7Æq5+$q=ppFo]9&6fEO/5w ^١L%kɋaSZQݩHjg7l0xIʞþzR0BK .'FV3x 9T! xXggW :P-)kPZAU'+o/q<_q7P,&MQ96G0fGDԝtŗjΡ["6YP xCC#:7S(R{A+MV'|VWTM#)Ur<-C S,-h ͱ}PlQ {q?M3(;"z/s#q^.a?EnC7:'3Fp2s j+l4A>hAߜ(:𼇚LE٭DɎ_HS3@WGB"9sU[;_>cCTb " 8 $kJz1P1ѱ| t'.SkE>ma☜w{l`ۆ[y-C@OmLX<4-,% i%t ln'ڏQUmJ  .D/|NWBPxZf*Uk\ 3|bUˏs3l=VZy3I0ՠ1T`F'zqԁ@ Mvψ̮Nݽ{M ezkօ/Vvj4X""kJ񡲆h(˱Pݴ9½:9%Z~l6ga{q2ԇHb`ˤ.WestTCl/a {g'1ɢPZVmc%U1STT$-o`JuTv}_6CY 3,"$kԑ E_ i`1j.J/"bGh oM0Yde;Ib7]rOG팺atǂ:A%BO{4 <081L>wa&t#0^y_;jm=98WEN_89$˖LV"]e]By R/\0n !y:8xªҐU3\mS߮{P1' 6[&- hh(gtDbظܭڑXGϔli2,+[e\!ݛf~nB&^HSl&GO=bF]!pSN [5VdG# %PS B \hRH,|ptH&2^XsDv߳o Xz 2&'H.l ; r|.FN&Gy;q$`bytY8gθ&{U앎@{HZK=ѝRfu$Ul[ ,(xEk&3l'/; eY BQ8O]Di+/aIKY$,+ J}4A{J"l;OT@Lt0,Q|k 4&?68ϨnJHޏR[fw ^$>h:Ɛh;P51Ds.~tV6SWG6`?Vmk3Hk;.|{/\G4Y{a}L;1/<<x82^Xv/|GMX4#VS!q XJ8IV dQsVN5+aZԞ?(A]'$ l Bnjp$k2vR6n۽8)c3NdfTs/7 Io:pzFS$ {EVsVimKSH!`O5AT;(~< u43[Ex (? hŨ+6dl]yVG4*,dzǔVI@ o)1,r']g.Ц5qJnA(W,SתR,lU%sq$g*k3>*] p1_*,~ :0є|=򶛰>N"1R*- %ƅLG9 ~/2M"3P8>Zꛍp\Qͧ ^"_ãQloVdQX'N37'5ox2bujb|^G(]w"q Gr %2/ b:8Nd0yuu8'_'҆W~tH;>ބ-ú?H=HA\2߮W܃s A|(dWPCáz{\uUicvDo?VA*Eݩ32% .V{[riOuE!6ZL2W8Dݺ=|Pr+ڷQrX#&q ƌ'#L(D,rlHŒET8h2 4w5$~Hǜ?D6VFe|LeW/ՠ΅fJƍNcdqv!DQŏa9piJe"n8t%CM9$tfnP[䠫о)i>^٩UZu0a]`|)sW!"Kz*F Q}0;$%>Ze|bOd9D O5F%GK//Kæ#!vA7^[g;̴&;2c)tNKAI/u,<L1hԉE^`-ZI36] kT{*o=IMl=?U63^o7b^PBsä+м ?>|8{U @\H2i<]oB\p}Z&9qz_U2ďF0i˂`n??( :}ggbd6tY"S3bG{KkW1pr6%<\2plRcMDIФǥJdFj3yk[=Qtܙb1A"eDsD9G/:NňD+cݺ@ [y^D%ЅSnqnV_p"i>3[[#5O̖6 DX2 O0g0Mik6Z p :T4%&k[<|jٳ{G\yAЄ-%Gv;w](&$t!)_zi2ۿf*p,\"$ɒ 8 2,:E. ebgC%܇pA͓u*;'LO(8KiZ2l.:+λ*ևChdh#!"1{~'MMmz !UH06a)޾'<rO::E3Z %~?]=n2wnkޒf,pi_n|W Y&bչ6Sog¯0XcDwNw4BlFe"4ۃXF`([%[_Ӷ*ZHTcПٛ< 9֑G\<(5d dH87OߧBUHK_4eIug,.1|C`cQMLm{ڳ=v<$="-/++V @~X 8l:?G(Jٽ)sٮj=̓h3{큷oK_`r mz^lfM DWTh]~Nh:zsa澱.G\|t FI P~r`YOq4"."[w$:Ա1ۈƷ|[2۱&86O 9Vm$$ #Y*0iBY _E1*c\Nv)iLH"s7Y˟uSLw ^qhE K2ܑ80fXrmn)2~ig$PaܔM$ Tܑ$ Mpr4x*6HC!"*5,[;K[/xӐ1ρ+:\,SGN5ۄוN|A-+*> Di tK٧t(ܲ@UUQl-& 9Ht67~SKdi- Bzg<W^чt*h9ش-}=zCUE B{N>dz)$Z.KNZ)Ɯ gs龈Aj5 z4l[\*@N7souG{Kiu-`FeܹC dw۷&V3-dɚNn;l 6q؇pU"h7\Fs5)[ى2vQ3}XUV0n+.a,V)u{-Lm OG~:9( R)uĜ?E{-੃'P8,ПEƿ(Ȼc o̺ee^aG9cL˔D@ۨilP'c,O+֏8 -&^&ܐ quɗqᩐ|JW*܊?qM*D#hB08:i@< p67.XM_[jJ$;M "Ԫ1d^n,~t3A*pݦDl"H~pK;RWiR- bu?ڵu'X-|LhE玑E[D1۶x*'Ɩl &zպQ<ljX ' ]ʆ9V:WsIz VFk!'2 {)uJJY0WdB8Am].3цF=Գd:GHe_8}9:|yJU zX&heev IW ^)$gra[Pq?e~oZnVԼ yAO]eNaaro{t-l~l:ih4kLgҼsZG2N q!~@n;P:.Ulc~a8ͳ۬nH}wk1n*C ͎8z.]wRV*gC.HbVHPU"V1e2[0 }D]X0/7(US;h"K\]aw*glÍv8*hFҊ/ri/c˻vnXuj vS+ LP,o"X61`s @&)I ߃O %(\p0QWU~ S׷nms,# 7 V]m<}y!aօџݮhyn<0$)pB ݫwuQ(~?$ u.ccl᯽0ameGOv9nŷegYtjw:~o2Gûz?[F7AczN:܉L25Ȣtwvw,[FxP \,7m[2dW@#?+K -Lt?PP>J?+$g^nCV?7GcC.7M` TZ,ٷ'rzbrS c UC`dቀO m_OD8x]gsRMjZ3#mect㉖DpUwN4РRJq`%j^@) vD 9/$nx{J NN"U(FnFO4>WȕQ3ho e4:m6)=ڬ=\VfsNA.Rjvr%k.: (jW׌Pǵ Zj͒*"A`kR 9{~ɾLΡ1=m^Knٌ/D&A% $^K>mB BϐTAh&Wi~%}# Q}Zϓ# &E?"hHiuLQcJqijT\KD1(m?~rJ wJeQ;XMV8jQ봑>cn7 2 80ݵ-"%cqXqo+ܣ²xBUXˣUZm冹')C1V W~3甊YiL7'jc3~+$~eXJ9#^%:u(z(uۆTNxÔ Z I`wU:sߘ>9Kk#u|mW=,!yqA%6O=P=8XżgΪ5URIIYD HE0?Z`A5ʰT*'ͤ&ܪ*Vh{ ò6C\K> z)fKc謇i+< zrx&"mPچ[i':| &eI%ۑQW=G?_tD t ,(a}> mMƬfɦ±|? Aq!/Y\\F9Mb۔!d7pC^7wʊRf'(d)GijE5h_@g+X, HVՖl_ ;I#[A1!sp~{|l;e'Jﲍj dsjF@c?Gg+p;(dz$& "uHٌFe(n| %Uqax%`DQl] F<7d/ ef]!Mnn|%fݲeChd{&Y-SMpdi4s\&F<*jpiMt8JJ *4W:ASDkA@-_W}vX_JIH~'4?s nH?"]fu+V= T"mgT91Z1֘eS5%ѺpF1!8$XQJm7.Ņo xX h6;q39}uz5pm!wɾW֞5ά1:ڊ:u)uquPp`$3&]UqUPMf"ja %+`ǚ(`#p2޴V-B ĩ#LIC6`n0ѲY A C+eE/ݩU% @Bu6kYXi~PNbi㛏u?$'j3 *T51WT}m<}W3ޝ\yNYYc|w hH. [UtEDȡ\0Yg*c 1>x{p(0PȌk)Pk6^7]Get)*Na޽̛>J}c,qu)aZŇc0_>V)1]]]V2 櫭(MHR| Uq rdYc.NAImѣvpxY|:4B^8;ˑ>T2(m<.]Aw~pئ|W_py][aHzilj[Ǿ&JBC%󇝯t6ji SD8NӖА/t`XV?Otn: 1Hjj˞=#Gtr(}6naO:cY3H 6PW#BNhި+׷GO)lcۓ(v)o=Mi >@rnK0f7ok('n 2f7.bU7LkUG\_Y/$Q-W1FŁvjHވDl@f=VDkpJ%acN[)WB4p߄=RږsJtZhpw8}S F5}:ѫtX?':k m^<ڧYYjmGgD~W] ܿ]ajL̄ 2*\dۺTy()@alt s*rzNJ]rwX !_YC5?ˏQJx(C1%7 Uߵ_[?`6iE?J5a+{7ƧvNXws[ V! ex,ͩ"gku:o6s?npvkpWPaY9.@8 =&LзUzPHW+LƟEk7ʶG\S#OUltQ{ݶݺgB)u1wQ0S D3/U~~qoRhEUz9a}F]_,G@JƱxlUmUhxZ9fcu A U:fy{@l5N`R%}܂l_2f8=܌t~F/)<'[%ܸf=\Ƚ!Z813!ݢ:F3»mdb2*!9f_׆LC (AR=ަ%nvzg$Y̝͋Z]il5ԥVh X>%EW7@Id5Mx&d˚&r{QYw1i7J0Vt˸ F499bd ۢtLi69G)(=WRʓh.K܄K@o$v1Zz=oۻp/U@#q> ,1]18*znJp|F<ܩ3Uޘ\vX(qH4L`JC tX( /ē8۰ͺUIw1֣NZLjU1N@`VTJI 5TY) *f&\‡`( ){!ڇd"LW^+^.kHر,bK Ȓpv(/ *0JG EukN.^9<| EߙUKgu.f(Iv@=,<ѵ/.tǦg0[1j9ybp eVV֛ fjZh?M[둾zR薬@l>pEx} ?'t%aDн(;W'Mec  Z8݇"UA\p߈՝Cߢc= ʛ8HZ~`uХ G'u+,$&|l˲v/eccS?Շ,22sɦ//A_|3OxipkFVNVI|w/7!(wE dF~F`Ym"&ю)ή29+jT,v7vQpLTjIژ#),-2ԫpzH_b L0MD *o#a)FXfzK?RПEghEV1LI4 .߹E+ؑGWf^+=vxzI{k 0:Y ;1 J 칈|jF| IuW:Prx{&B X OЮ țq|V-:/j*.f#p\*NPՂ76H9}F%㞅'EӬsL`[ٸpP'n@˞Ί#=Rb_ r=1RK2QAo#jHo0rziHT,[pC9?LRPN!24Y/뒢z ~ӟ>F -K šC켟W 2ӤLX0Ð44ymx@S[s*"?R`GM8+?2*CBKTmԭZ!VDo~=d"` O7*c(*V3>X4 E .:ĸ~l_"")ǟ<9V%9PWh.rTf}ɞqoaUy^ةQRܷP#K&*^$Z,ˎb.emeIģŵg{7!IUs O_\9lƾT/c:/FS @wP[\^=wGәmw~l õ4|)}b=dou]*]< S`5z{coRyXw@1E!z֯Xsiڐ}K|wY`T[;O[]>˱mpa?COؙmCńmu뉧o{B/Ѝ CqȐ:'Z򖛐zk0F*mE,nf^"N#4m-ْǜa{?gգ;[]"KZ|K4~ /v*HͥiN qbPḆRwS"_(URjΚt)Ը Vef/ jǴ)~7Mg犮iSYnا+#NCy$'97K-@Y 8p pLa7?[oD _0wώskA \0c~G|4M-˵78ci>̰~O5;!`X7tڝ!vuf9p mGѾ2ֹxbfSdnŰ{'v3ֻViLVp`G`Yͥas@22tp/߀sf6}Ogz #Ď@N HeZu9@޶A$WU[veٯϯ|?M];2; BR؂/aKLyJ U:=5-E4$"^7H6w4Kcoˎ)5OW(P,9e͑LX(P/Uuh t)YH]ex` Al}Fle˔]G8kLrw[;GJ:R#qpryĈyu:vq -f).WAOMЮUzloMe`y?+2ĒQak(ypQ|Hl$i3!UfLE~j!”ej.\hoU(Scjt.moMh𼔊(d\Ga n.Xo~QBջzPu>h 5k%N{atF =\.W?%׳+FdG1oTq=OXRH `j{ &_Rꆬd|',cDg~8PW~1Ah4_ ³[rFGmCti4@qw!TǁFe Ңx  @3 &,k\;:l:;YPsuO>-'N4m+-otkh\PHB?7E!eH/o([jLNE#)"h_fi>Cl}bTd{gxVA;!t#gy3/L]]I0 iybQ'E"=QA=K7, >2 '7x 娝Z pe-וFQr ܍KA˽P #ăiE;K8Z ]>b^噤ǒ97Iɿ?{f&ZI\hCy"Z@e$fؔehP&: tώv?# =*)M ]a|EL݄㯠}1ѹmAݜ bu-j+1U?iBȾ0 5joɲaY2uȵqw9J¼=޴vjn:`Lݮ'FIczɛ:y"ӡ!dwt O>qX΅~V+-i"c0jC9\Z˛2^.C veRlXހ lC!.*Vx}yl0yH"@ r&_A\b qG젥QJ.f\`܈.~Qt~7;ޥRX5k<)H EOHA&\IjjXktLWmtqy\2 f?4+\Lc\n9@IT>%MTn3Op!y}͜_BvOvPԧfe̸V#@w mJ#_ğ+V ǯ?lK}oO%JL 21F0 x0-tf7>}R1i+(˝Uc (^,V{үaךB auR5qL  5,C,j5 2@*7<R6` Un@m5|:'@Dž$bh8"4d4A+E?"tzU'*D!1`!8}J2rRT4+qD!kG ڽ>o:>7TU5Y s-Hd3LbS!ڎggEn4 f]׮`VE3RS6yhX14)s0d='Y|(Z=|=ݔC@5gXRV,r7CʄԞu06qpt 'whu)Vn1jOj5rSQYEC~H8^h&w-BIDzFJa l YVR0gBd+%TR灆Q3إO02͐q _3`:PYE./((Cjf:DLz{|Dpsn@!}FĚrkާIh7–~dZq\/hs}˗_.)v"5tI5|݌$m*QI8X۱z\{) UR4dk#MR+|']ks _1t-pڠ)uo+kpþ}1Q;=7Tn4{p]0YkҎKRAE,G>EB M"#MsyPo=},?QlXzN'h?®kݾ%žØ pzFCާ4fTX8:0"($9^FQyׅ1)a}m28T 5["EJf[0&mtF92H֭{Sy|֪[hy(+/5|7-)(bZlEBzDg4 `d &u㒝%1OIM~#]v扎O5sf҇㐜HB)*R{I8ۚ'G|#,oφ}qu]qP(>)GNwM sY)[Vǔ2;+< @kA4_WqS\rK%նNlz1fyE 6* >8"0hscK?hx)9@EAj-58wo!}%n=0b}ZU-A4m|,+$Ft4nq%7:[WFOXg̸Fգ$]ev%r#RuqMSFBfkA[M* 4t&@rzRFx x|AE,Gx'q]]Wm ;xqFCF7va( ~ Jør.?ڄ,$r`Wo*S-A4_?:ִ?pu^&0`KxZx  {4/\#mH(PƖ q~LI[ؒ+̌wYf1nsvi-2 Ә  4X(d՛9vA70B*yR9=k=n VD Db1! rvs&DSw՜L}pN#0U D\8 ~95/љB8G oh7^ 4ނNڤ\3od<ï-cLc}XE50pQS.?QW7^-پ9wXE!!,'`+qss:z*y5(/hqTZ ׃sTx3hA5Qk(Y-ЇCm;n.>A&=q5I6"(v}H.f>Ԝ; > C`UKχ5.v "쟧bD4j`.1(Be ry/uKlhPI/Dg+V׀NvWQz K=E!FZtzjeo6T nWUX콛pj$5 g^=( 'B4!N5,Cn0q A34_֏IE<QG1 9mi |S*C6҆cDJ`U]YB-1m&Ð;;˟;9Fv >Q6t/pi}XBgG3`1l`U1IEސX'[nyp#%P~&loM6f0zj0#'ci|p7W[vTIK o;R㉗xMuX\1O+-5ފ' 뗾tPۘ\`ùṪx7^ё9&e"GuۃGO/ko4y?t0Gm1!΍\IT h<3Wk${g:4zv sY -ir7\~h{ߗXd93d7hkWΞ~D3{lt hݳ==W{ُhoۋ'QxFmȺ cE;|aN-7T@S잧K[F!O*p DY%osvd c~Ô ݵ~[='xH"پc5=C4m dk$_  n;o -p36ԻƎT $$n GЫK1d0Uxdy)^{|&*X|d%=_?/_3USMFr}'A5"mb{b {::L-Rê;AZSZZ^\A I7Q{"GŸնmB u9ɧc2}NB.'^=$*r6ELU!&%L53gc?n[ DQ ςH}A'6)ֹ`l|t^-̼m ƑҗC!^zl$SSE/Ӱty¤p )/F_gO <#-b|=O EiŶdr:ޫ[Msqn)>DI㏵\5p_#˨YRYz> 5Oڎ(G! o5;g~OǪq=EY Q^<6=alkyeɻR:>R:/'9E-\Y\ yQM 3cDK i W!oh{@Ƅ꩹j %lO}s [tH r{/bEmᆋ%CtsR!>N!S[jxyO$4 G7hxρ `o'5h#vt#j4<Fc@vw;UCoYG-vs+-P}K rFGAWsCEj1exkh&W@yXhPZо({`U0IdtWQW"ϯ@lr5Α~/hASIddUK㇦ں*j2)ӎ &oEf!Kwg3D~tա x̧53F/ (w.Dbc^o3;;'\ãtl g!"qK&jnwW' HV,=ED<r{x (rå#ޥDq Wt#F<\gxF.$XCgte;nNўajb9=_ϣ}jV7(#[]h'bUᖼ~#nA~wΌcbO YĽ4?qY)}gmA 4-x˻~% <͸><@Bt5qYyy(lhdϩܑν WX[ F +?YrzZ81I, 5؉BfwAQE,Wj@TCGj2? cdȯU}tx}v;^Jg>@X:W3w|bn (GrDg:OgTDž[?YK C^W1kAw4_ 1PtZ W; |'iܫxL+ߛB0BPIW[E÷5n'+If.A[*;FJLo}` ˗rryW9l  CΞ.a.b4wI%sB^`CLFVnFa)|8J#߼b|_-|$oMƮNfekYB:ejl كs4/S8ԖV +55YRShyPza LX$='_E3ݠIDt=8xC.ÉjICv= c^.zG8g# _B&l1C5bx kpcݒupE<)QfA*̥m(^-R9=fOR!QO.^Y.C/I1x?j@aAE,G1&vQ! Q+"+ NE$~X_-fy[q3:9.tF ,+Dg9.t@A4_rDװxʘR;3-02q%2#M4[JpVO6y,}ܨr^[Z7S }c26£rHrsk'ֹ;_SmqobpWPL}o'G:MFZagcėN3IU.5zV YQ͏*ɲuۙOsany+|=R9o/:p5|9xJV낤CcŬ3g`sӤ~@NǛ7sWk͇٥1Db9cD =%TCJuק键#u%_)!+r?XC6OG>QCc"f wXk'on*  RQY7p.F,zQhUZ==+f?:^5?ߝpJuMxΧsw\k E Ȁis/ŵ#؅:(UQ"N W@t>EɄ=$_/}| 6/ߒ)?O^2/B$ittkfikq z'*/?YM YcK3b7WAE,G+^?3_yKtǭz_sI+R?@G"TI]c2HVtFܢ AD6|/ƛ:6R7S~2rSd0 D~hے Hٰx$w4@zfzu{fBlu2s@ Z~OHRs+4TV*hct׽=~qm~}|)'[dDsxEHAE,G1/VKEg~QXOn7#J Y.>Dg9G  A#4_ F29QpAUZvrÈkvY@3C8 f&oWVѥȇ6Ơ#`/mPg<  *45ɨNO 宏MQ,eJvzr4+!^5jЋE7j3a\7Ӌy=ei Jc(X[q|PbPoLyB J<'#ʷ&^`tF9w xnk1F@b1#0l(Fh`\*lWs5G?JRv'@ӊ $qg'BF?UO_JQQA/S(m.D`0{x4&SAbAE,G-$ XQQjsU<ԥGXaSkKD:KL:| ctF5CO]^A`Gmsc]-bЖut>1J@yc&u%b@fLDg5G2Yw{zY ՙ<& P9mڶlKA4‰ lدupDH[Iy9QjɃ)T/oJKWV>mp(PMOȠLNP8,&b0#::IGSSHw^{ҀJgN'<CDg447Zs[Fl˥ &zG*A= EA+_ ) Es#$ ԧqױiܟ]-h81ҧM`ن<' AI4°8C:ĵSnxp `JS@\AE4LG,s>ݶF 5=VԕaV!l^ldC&G^IB`{K tF4@b)W|&5ۘF {0B Dg3ʀ w/*-RX.pA4_ a !COɹ6gG =WlHSYBczu 3Ad&`Wx"|]DA/E,G,n#45NoXU&C+l,NtF3?J% 1*PDg2lr${AU4_ *=U1SUBߌoXP1~k,೬mgDC\ +-OpMB+ PRK"gD-AsE,G.>h`V*tF+Dg5DqpVA4_@>C$^l<g|WkѠDiUxˠ1@&Cܼq^ڬl[fu93g < R1E5y^oscO[+;AT(Wy D{ʕ($$oVrzNBjrَJaTsj(W6j7xBb6ش|$hBЋZxy6#6E紿MeFaA(_}#*= [Њl}7@@mX٭^. C?Im7zr`+AE,G,4 I7tF4;Fs8>BT1)DgA4_ "渇[ SZΒ| Wfp >nb%bdt2538%#xy|jctވ@(l{:ӕXaFMJf1& s3׷͍xạ ,Py|I@/A?E,G,8"a@*^tFV@Dg2ܹQ]ɑkY0mEDyp?C;좜>20 AE4_G R־eF|/Ş * Ϡ|@2 bll"qD֛X>lpoj+[!H 9`~Px`{'É"=4Vn=x ۀ)2){V)zO9de}9\ѯD$Td3팠z,cB2g-1§=TBީ*nWMN+*KO~rsр_C.'e`zN'J,8Ҵ FD{0Rj*}#u\ U#0mӉ{vv5+)Ӷ3<`*70U N8eC"Z*6wJ RJ}X۪͈+! [I}g$O@Q&5G6?JlS7BYv2k'(Ժ)wDMC` ZE mܿnM+Y`KALQ@!WC:1uh)1NKbfErRX`Vp$^W!$efʎ#cE uz`v_9( {|@s5i6Q[ qi#:“idayճɿI׏R8pgT#O.>\{- ⥵xK,3lo\15tDM H^TТw.N,P){ r@x XǺ2r_U٣d>ߞrn4en1]Tã{x;VZY/e,ew8) ցke{BAlEc!=.q$,?iƼ;](+&Je `X֤z%Ŏ:Zp(xdZ}},6YL2`1Uv.kg}GN,n΀9Qrj꫃*I\-?CErW5GF=&)>Y+fݒeͦ9~2WS:_{tN-Zs5]3^ mͲC.Lڧ{" Yk$ԗ:1  hJm\"fGe"Mh,Ev{#ݸIC=xJ"/7FHcDiATˑTNwpP Pjǩޕ ݤe;?ץ#힑bƒFJűX݊X` K'1"ՕuMtJ.[#IMRwz[f obW&bԿGJ zm9#8wgWQ!V..m*Rbi8%W=R^,3́%')Me8*~ ФVQY+e4[cTG赾A;/fȍwp8299BP˟,AcE,Gw!%dB.`x$_%w~,'3ބ]`j`yH2}IÑ, -GzQU=툍?:.U8d[]o}1ctFC|u=Tt5 eH\2ڶ*vj*MC;]?Ғ DgɬȀ `+e٢ߣ-O"帇Ɔí~ [b[ 'rXp+*@O[L S0y4-hS,?W"V)8ϧ 0!1A4_Z k:FS.R G#Aw>JYNydiWwߺ\7ѿ`͛pLHg H{A}-<[3Oܴ{]f?J6?o kų3zA#h|IWBgg?U^ݏ;AJ$ku K|lM 0yڴjH;ԋ뇁9}LY{Y0/npTAE,G^RL{YvFs%_B`Kfn6 'Si'R:~_(Bo6{#[}!X#BK{N\ iٙZIU͟GcaDtmG tFdm(aj~o{1_%Wbʼn/= i0>]fMBn;|I4zkö/8яlOY%gZ;W[TCjpP9%7v#|Ay Ȋyw/2$ 3ko#Mm ~GSlj8LKHYN|H|5,4Inz(N s>Vv"}$u7=lWxʉ 3b!5c\ Zc9onJ\ `֖7.Kk0%ʧ'qYP}Y ]{ҒhURGfvILL]erYF0B8K@Ғ~ EMGv= [qܹFHY}p+V`/'?wFl$> _΀Pfx BY%܆ȅfر./RVe۫fd$ iEGE+>`,8ݝ9Ԭ/HdDp~kqG0Q4vվhN~HD*_>" ۺ=(h:\ݽLDM7sΐy6 ~/r()%@j?Om-}7AFN:;,&//xS\غE[E2zrxe'bn{.olԹQ}-*.e,iRh=:qƼf!l&n S ڲm^ e@1#]9v{.=mX)2;5RQQwa%,Y ;},<) ev2#DBήooTW;^`~?k;J l/#Wfb+(&EFj*6<|Tj.Jg v[_>ȩB, ݊j7R:S&Bsz@$m̙}*^'rAZ\;9o~o ܱ-F&8 /_ȷJ"~УNT`*dg:Ls^:G@Aa &tRF K:if>c[4‹~yۨŜA3VKQҎyh<[a,'60~8[>OҤoG$ ERxFQB{'q̈́\X,s/&2uacptqg?`WLx[c#G ;hA?XȎՑX|՚-?z=NRH{3ܼy*\؞, KoeW(趲 lt.IvHkjtOjۜTU3.oMȂnSvgښ@+5w?`zrkl- +g_26!L202=o `9{=۹m&v'Z҃H=1cIW7vv7Eb O#p<*TR$Z3~ɱ*Spd yoO欷Dz_8t=& ;9Ö?lě} nϐKO+p G.YDRo@z<栶pߑ̿XA/E,Gs:9S420sMJiBC}ORs=TV68 s"-}cO;=aY.o}&p\n▪Ύ|\]SU+F_NF"SNtFt@xG 6X΂n܀dadq<\`M"[AOPDgZ$F + 4V %]_U`5MxEE7  H 4AU4_&X<Q_Ɓ>8Ŗ\_="!V\!Ӡ3/Cnq+7yttQ)9[i iyzgXnߴ!dL~t2sbc.5a8{#,rD"U w4jC(z,0?dp n<07h0lMSྂQ\ěК+W>&eYwyq>#6K*nw)Ǧ/6JP4$a= J>X6pz~gpCk&ȮkYچ5J}:DhTf4&m % х,jSG͡&L\g14_؇[N:-w(gN@`ϯ:nJBk;JULB6/-^SR]S#KxMS~GȣFӺhp&z_ /=+?9rQqzR)`|[e#cɩ^㱅aJh^p.]b4.3*x|i%wR˒9r%;5u- E.B6Nsdy($qR%V{2Oۧf+_֔}Pc07ClMHk3&\߸b z1 ozIRGXfvbڟ5iϨk[ܽxd<ُZpk@'YR'cD`{9_5[ʑI3{ L; `Awj%- 324`Co>Wu!$"VҢ_Qw*P~惬z}ԧ]L FmG-?ps\# ,qZsi3hV_pӈz#0{Б\PYlF=)xF_nah!og3 a^FSR(P0Ogm 64A)ȉ& jXTλ'~MEr{IDՌRϒq}k$ o`/8[?P檐 :d72P[ K qW~\WyAWkP?y*<(@fZB*U6:ᇌ>ro@׾@ cX 18p{iY뭬9hI7 ]:0p,TK[U%=KЃiB Ϙ.xrK?F)NL;S"M:5[&@3ټwEM>RmU%Q ^ M# ^@s6e'xTvr]\9+b!TTyY|h0``\VecD0.ㅌ}[rZOSooiab,=y$ǃ'(FM {`܊-Q3uIcٸHP$ݶE>;^ŏ~jKN=B~ꎪy@dAT0m'! MT5#F AfTqFT$HjShյb;D0`x+ZZD7jr(DҜ~:T7=Oۏݍ]& .y>뢈{7\JهVPd[m[r(+SilN6$A~d~݇6'v!399;o*1D+eS{8"nUAsE,GK\>p{>bPQu+U3\4I7V9=~$$db R1,h XLIڞ=4\/>,]l͖3. Ju~eaZ;"95Rb}?]9'Mbj,a0Z' s*瓏{F$"GF_ !/ |iBهH.\ùc;RꥄcK^1ˢ n?Ѻm*SY0Guox&UG@9%  ztFXg.F`U@zPnqP᧰avjn:ac~AL@J/tXA4'%-M u1=vXzgRaWafAO,)V4Fb.+iL&AF4NaLv 9*oAn\@Ģ 択z,LAQz:]eH&=,Rcg$4w!A2Y7J `+HYBCx>%+8C\Hj HI{vɀti%Q;Pb:qU-^jy6*&K/!{?7g-\Py"u ]>Zzȣ;/y&>zǹO_Xќ~'D$k&C.o~ƅDJ䶑F(j!{JODn(\Ȫ?JmQ1a"=ɛ)FnPBU#/D̡3f pA]qv}󩅥rAI%1 fCkE-o:|Q+N$ 64:f Cn[IMYln S =D%ע#rݵȍ>;y3 נS]Zm}}/!mڸMe$d&QUGc=(.6ur@8(d>7Eg)\ZZށG%sO- "`5.ȇrHRs$\u~WLG%ɺStw Ӷ OŠ{1|P ߐ;7*~0f)7D=~nY(BlfpԕVͣbБ/" 5c25`~MУ!к\HK>:¢1@7'zy3, A=;_aĬ{qv** L1t%D׼: )r S]; m+7 I65h)D6%a}[HQ("=Wp0q/XUW7bwK疸c;ӳDC bINZ=\BQND@_]vR!rywPD2cOf]yCjlA"$oau![l3x6|u1+) BLlN[=.}AvwwLKlQCHx XsnuzMKm2ѳ@KKj,gJѷd{$7oO6p:iYXNDGŀ>ʾW(ɓ+s`+n~TnB;65l=F/ں+KJ]HJaLrWGiF` cFj'~*=_RG\J}5߂+TzwZ)h }I'=l'.]gގF-STp]!W%Q0xz[+`Lb}HWH|;&TPۯQ[$B5B2&!Q<6i-"jeΪC2I[_ ZYBMIj3C䭦d7rE0C1(u>N-)=_$h#|~>Yh~l&I-+m32^ ~ NC=H'bus.C-UNFF3u7h 1v,5PnD6i2oK{%Np2y.t.H2qh8?jt%|wpzA/xʡ Lj =jNRM^KQXݰYXS=,xʈR0/1RBlGyg,^㯿HY~HvZ˻ {fl R:f%wF.]=};k~ szh*Pd;۬B"5N-+(n/l];"6)Z^(T+@3i)a@eOjT3\+ QfϮ<d+']cQS'$t>Hsnep{~Ghea)\a$Y<OKVaL,n]%vfRX1㽹.x !ԄDqŽ}ةOO {޺ ܔ{Q{jMҥ@ ,(TίkUZQ͛r5~Hcc $̓,W ЩA |.%&-qyIqw4{Х{wWT 卙ܽz2ĝs&2,VoxL!m]ʶ[0׊{jB=!<}͜^iD5;qCd޺l|SOjJ/Yv~dR58c'<ة@: Y5+=$[3l]j4H4|Zَû(u&/=ylAeo#O>aGKYwn`J _p7ŭ -H[X}Ą'R$X$" Ѩ(C JW]#CFb~CLu&: #2`,fzlC,@nxD%pi4"ZSph>btS`AW6wXl?Iį0+f*< n!H/^.J, }IX ܈ev.QRԄذV_$`aAE4LGw^L%F0#hPQRKdDγdĠT)?pDcݓCcΨ ֚΄A0<Zh]P4#w9wI xZ14x5^qa34eAUOL`y\m'Inhs04XCf"a>Gܔp_03%;iBLA+erq% %Ho1[n2_~n ?ʭ_VKK$+|iq9)>O9)i".q.Y4z{l̜ʜ*^_6+1Kk'tܥ`+Ton/ڌ/1w{ .qeh~"7kE'grd&!x}f"Pp;tFgzb;ܼ[ Uey wb2V'Ҵk~>8QO &,6uz q TKF݁ߕ XK%&^q`o@)b"fG2F׏蝽A= mV_>W j<`) ?Cv :Vm QCO͞%HFNW㐪s* dX 5KN&yo@=Dggzi!8 p0n{ְjŕ|p^H*1ZRriQj6Qɤ|^J9;5t4;HgkroA"4_;]Ȼ$2|G \1;IQ& Z)K v].¯0Οk61#!k@2 (mnzcҴZ(i (P/6b7z$ Zn0]iߑf"SK¶_/{^rh}5,7I*$N gAwed, '%>% [Ƽ/ȃMgGnޯI> RsT06$盱p%U=W^bhR۶ڽMX@h9p|Ftoy\ ;yK/P'̷Sd!CGexoF+ 4>yk$ "͎3+bBA|me.ɓĝbI~]2qJι?""Z?fȱX#g'HDF1~Sbhi03[JTxs $.龆h_T08 '%#f oi |j|4H9+*m+Yv3bV6HpJxtE*F\T ?@\RΰqE9[e p뫖g0ñn '2bnP^Yӻ)܎Q>:~S]${7,wo!uLR羸ss|RNJT |uɠb50F 7dߔ`p3^2U<8h)<+ .(N4wxgTo dz5z`}H,f"1?|e!29! Z7n7fR5̗!Zd-h.̬qJv$Bꬪ=؁/mwLl0x>@ZbAGF]o`oNZ1D,t|2+L}k-d3occ1u?/%B0-)|mʁD-b!]{} 4 $|ZHy\n;ԊgƏ_G+䀓|MxYRLCadpŧtR ev]P@C:$#rEU,H6{VxNVcBߺ˗9WԁTH"ĸElx`25w1%\ !JM[#RSPǼ: OucW[MU@p\KIJHhUd 9k\lLZq8tF$7QTDaDgQN >@ ]MWTzi]GށAf4_>{c۶.P> s bK6&%M~qh0S3i5sZQ!>Vi>ao!y(m<@: LV؄1휷q~O@ RE1Fgd3fC`ڝ3El:BVc)ٌ3I;*-D#ܶӕj,$[9s=NWԨ׿뎅wT}50CQ RI#cQ-i G*Vm>.R3 BFArL0ky^6iqa@XgIVBaA'w[j .#ao Z*I0I-CT[#;یy$!1ކB53MFC@.> z?g4f 8o27.4 OEt2K˕L7nDƠEFED$`lg _ힾAfAE,GFT ׳@+Z*=3lܪ1 ɰɍ]c{YÒnO&ly,?MgU%_0VYzYGrKm^%{&1q{Hl(t[2{ mx6%LȲRT{jRJIeshv$zlPOxF#r!JZ>bTOtFUn-iQ@,15G"Qs(n3z@8ɱ IY JA;Dg r.z҉+]V|W\>A4'so8|G 7gE_&۴Tsd #:um55)4/sa{h1UxW+ݥ27;;vhV7OuCQl1=C?c1'`Ϯn؜ Yz$-5W=K]=gh_-.&!AE,G% PhCkDˬ?B*|R"i߬Ǥ}d(#ڽo㹳 6lSVf ɄO]tλ# }KhSD`Dp`17tF Hp}jPR xDg 'i%DMaKq=O;w jqgߧ޴j!N 3(`=Zc5yҧ.b?F?RE0x[TA&+_=2ƹ'1`A4'%w_smW`?le8h)Sk7CT25 5̩J!C2aSѯD/̝jx~60X9TAXp?Q>Y,o8@M0$. IsC-\ǧ9MFIe?kϰDfªw6}E0;]VEC|%W-b-d=hRA =ODl]^}QVHtULA4?:%iȭ/C@_Ry~Cg^T`$ &1XZʵ*T1 Kt~FEF0ؗ5whsy4h?0n ?)>h|HSU +*lٽk"v"'˺1ҦF&!o>Z*0{0'g%:_vK8TftE8|$AsdLџ:kz<976>?(@ ,ḅ ̟@6 2ss\jg4buvшK>~7$K(77O=^Z ["8d2sOA7?*b˅0YjV1 _%4}AJ#~,첛V Ы/BWR7lȂT5`X6+tŀb["巒Bݜ׫1G@o{H"ЋpQQ؏D Hku&|)D_i'jzQj-9K+vϊ Z} {zlNA^[|'K ׺]žq fܣu|qV /~Ȇo76ANE2Ѣ*@ GxN&CZe! 7j3+AE,Ge*tF)DgMA4_DաDiǰjMyA fȖ_3uS G]/AE,Gʎ9-RA*tF,DgG3 A4_{.`sAGlG}&%0mREo {/ܗ{i,ֺV-) پVӤb柤bZf`'[%ή hlVZ ϨAE,GN:@kg6D.-* ~wH+E ,|0–[LYf{|LjYU2md/"b r:ӗ7oNi 019tFok w;DgsVt*7`lRtjS3)t)">(OSXǠG1KʶX^:}Ej3'mM^kbؖԫeA>4‰e& P<ijmG$#a'?[26;}_w~al4 ߔiMAXvH PZa[ZTm&]~rsmlcm{fb }Hq~yMMX0BnM.AMB.?60-35.-8./ `X1H8.-92L^oU92D9[6:NA639-^3..-C/.-?/.-:/.-:/.->/.->0./789|GIKA=G@;Nb3WsmmU0|1.08.^qWlx3e)l]skgtls{V}//FH/w@>-L/.-</.-70.-2/.-2/.-2/.- 6K/.-H/.-2/.-2/.-2/.-2/.-Y2D6/<p0Z1/-L/11.0r1.0l11- ]P3y8F7cvO}7Agavzr~pVmos/j>[BTIhvOIMJFU^rvG0.-:10B32-7/.-3/.-3/.-3/.-3/.-jU1V@/.-3/.-3/.-3/.-3/.-_533/.-2.iP2Gpo@HZ/O<Emf A rZ\2/4/.-3/.-3/.-3/.-3/.-3/.-3/.-3/.-7/.-?/.-6/.-1/.-0Aa/.-5/.-10-2/.-2/.-2/.-2/.-2.JV>7G6J`C8I:?_wN0.=/.-=/.- m@P H2C8 liXcAZ`cYMSJ9mg[TI^FK]7cBu} $Qm%dBB=z>AV87rC72D0.-A/.-R422d47A2HXCOmXeAvZ/S/.-3.0VRI14-2.0F2e0>-:/.-8/.-8/.-8/.-8/.-8/.-8/.-8/.-8/.-21-XJN12-;/.-8/.-8/.-;/.-8/.-1/-t<?R2[G?.G/.-?/.->/.-=/.-D/.-9/.-9/.-21-zRKM0.-:/.-9/.-9/.-F2FNE39/.-4R-N.b Bz1fYQ;w9?YCt]ZqF.K <w dG0.TjQYMH `oD;?C=CaueX/rdc0_1O2.Lq10-~1..P/.U//7~;13f?1?2/Sa@FB:W2njj8|e_41gf1=0/.80/.80/.5se0qbr Koe2/[Z-L;2bTfgPG`OFtH0.1./Z<.A/;-3.Zg5i6WS 8Y~hp;  .<HS?; V:01b/.-Q3.056O10-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-7/.-5/.-5/.-5/.-3/.-1/.-stco0budtaZmeta!hdlrmdirappl-ilst%toodataLavf58.20.100RaySession-0.12.2/manual/en/manual.adoc000066400000000000000000001406671417052567600177120ustar00rootroot00000000000000= RaySession Manual :toc: left :toclevels: 1 :imagesdir: images :stylesheet: rs_manual.css [.text-right] image:flags/en.jpeg[EN, 40, 30, link=../en/manual.html] image:flags/fr.jpeg[FR, 30, 20, link=../fr/manual.html] image:flags/de.jpeg[DE, 30, 20, link=../de/manual.html] image::raysession.svg["icon", 100, 100] _for version 0.12.0_ == Introduction RaySession is an audio session manager for GNU / Linux. It allows you to start several audio programs in the same session, to save their projects together and thus to avoid multiple operations to return to a given configuration. To be launched in RaySession, it is very much preferable that these audio programs be compatible with the NSM protocol, and many are already, among others Ardour, Qtractor, Carla, Guitarix, Mamba, Patroneo, ZynAddSubFx ... RaySession assumes that your audio setup is working for audio production, if not, fix this first and don't waste your time trying to use RaySession. Now let's see how to use it. == Simple use example For audio production under GNU / linux, it is highly recommended to use the JACK server. Before creating or starting a session, make sure the JACK server is running, RaySession has no direct relation to JACK, however the programs you are going to launch in your session will need it. Let's take an example where to compose a song, we will need Ardour and Guitarix softwares, make sure that these 2 programs are installed. To create a new session, click at the top left on New Session (_or Ctrl+N_). A dialog window appears. image::example_new_session.png[New session] At the top right you can see the root session folder, this is where the sessions will be saved (a RaySession session being a folder containing a file `raysession.xml`). Enter the name you want for this new session in the field provided. To put your new session in a sub-folder, type the name as follows: `sub-folder/my session`. The session template multiple choice box lets you choose between * An empty session template * A template with memory of JACK connections * A scripted template with memory of the JACK configuration * A template with basic session scripts (for advanced users with shell scripting knowledge) * All the session templates that you have created yourself. First, keep the template on *With JACK patch memory* , click *Ok* to start your session. image::example_session_launched.png[Session launched] The session part of the window becomes active, at the top is written the name of your session, and your session already contains a client program called *JACK Connections*. This client will save and redo the connections of the JACK patchbay. To add Ardour to your session, click on the *Application* button (_or Ctrl+A_), the application dialog will appear (more details in the <> section). On the right side, find Ardour (Depending on your version of ardour, it may be called Ardour5 or Ardour6) and double-click on it. image::example_add_ardour.png[Add Ardour to the session, 640, 480] An Ardour client appears below JACK Connections and Ardour starts up (normally directly with an empty Ardour session). Do the same with Guitarix. image::example_session_ready.png[Session ready with Ardour and Guitarix] In Ardour, add a track (Menu: Track → Add a track), in the Ardour window that has appeared, name the track *Guitar* and put the multiple choice box configuration on _Stereo_. [caption="Figure 1: ",link=images/example_ardour_track.png] image::example_ardour_track.png[Add a track in Ardour for Guitarix, 640, 480] Now use JACK's <> which occupies the right side of the RaySession window. Connect the Guitarix input to a hardware input and the Guitarix outputs to the inputs of this new Ardour track. Make sure your Guitar track inputs are not connected to the hardware inputs. [caption="Figure 1: ",link=images/example_patchbay.png] image::example_patchbay.png[My session patchbay] Here you have a configuration where you can directly record the sound of your guitar processed by Guitarix in Ardour. If you don't have a guitar, all you have to do is sing out of tune into a mic or tap a cushion, this is just an example. Now save the current session by clicking the floppy disk button to the top right of the session part(_or Ctrl+S_). It is highly recommended because it is very practical to assign a global keyboard shortcut of your system to the save of the current session. This will depend on your desktop environment, but just assign the _Ctrl+Meta+S_ shortcut to the command `ray_control save` (Meta is the Windows key), so you won't have to return to the RaySession window to save the session. Now close the session by clicking on the red cross at the top right of the session part (_or Ctrl+W_). Once the session is closed, click on *Open Session* (_or Ctrl+O_), double-click on the session you just created to re-open it. You will find the programs and their projects as well as the JACK connections as they were when you closed the session, and everything therefore works without any further manipulation. One of the advantages of modularity in this specific case is that once you have finished the guitar records, you can stop Guitarix so as not to overload the processor unnecessarily, and it will still be easy to restart it if necessary. == Overview of session tools === Top row image::session_top_line.png[Top line of the session frame] From left to right: * the menu button gives you access to ** *save the current session as a template* + The created session template will then appear in the multiple choice of session templates in the New Session dialog window. Be careful, however, all the files of the session will be saved in the template, so you should not do this if the session contains a lot of audio files. firstly, the copy will be long, secondly, you run the risk of unnecessarily multi-copying files which will take up a lot of space. ** *Duplicate the current session* + This is the equivalent of the well-known "Save As ...", except that RaySession has to stop and restart most programs to switch between sessions. Avoid duplicating a session with a lot of audio files, it could take a long time, but fortunately such an operation can be stopped. ** *Rename the session* + It will then be necessary to stop all the clients. + Alternatively, you can rename a session by duplicating it and then deleting the folder from the initial session. + You can also rename a session by renaming its folder, but BE CAREFUL, this session must not be loaded! * the pencil-shaped button gives you access to the session notes. + Write here the information you need, the physical settings, the lyrics of a song, the recipe for granny's cassoulet ... however do not write a novel in 3 volumes, other tools are much more suitable, and notes are limited to 65,000 characters for technical reasons. The pencil is green when notes exist, it is orange when the notes window is open, otherwise it is transparent. * the name of the loaded session (here *my session*) * the *Abort session* button which allows you to close the session without saving it * the *Close session* button ,which saves and closes the current session. + Note that you do not need to close the current session to start another. Some clients are able to switch from one session to another and it may take a lot less time than closing everything and restarting everything. === Bottom row image::session_bottom_line.png[Bottom line of the session frame] From left to right: * the folder-shaped button to open the session folder with your file manager * the yellow star-shaped button that pulls down a menu containing your favorite applications if there are any * the *Application* button which allows you to add to the session a factory application template or that you have created yourself. This is the recommended method for adding a client. see <>. * the *Executable* button which allows a program to be added to the session from its executable. You will need it if you want to add a program for which there is no template. see <>. * the reverse button to return to a previous state of the session. This requires having the program `git` installed, else this button will not appears. + See <> for more details. * the server status indicator. + Server states can actually be very stealthy, but they are displayed for a long enough time that you can see them. The server status can be: ** *off*: no session loaded ** *ready*: the session is running ** *launch*: launch of the session's programs ** *copy*: a copy is in progress, for a session duplication or to save the session as a template ** *close*: the session is closing ** *snapshot*: A snapshot of the session is being taken, so you can revert to the current session state. + see <>. ** *wait*: The server waits for you to close yourself non-saveable programs ** *script*: a script is activated + An information or progress window is displayed if you click this status indicator if it is on *copy* , *snapshot*, or *wait*. * the *Save Session* button * the trash, here you will find the clients that you have deleted. You can then restore them in the session or permanently delete all the files they created in the session folder. == Overview of a client image::client_carla.png[trame d'un client] A client contains from left to right: * The client icon that you can click to bring up a menu with the following actions ** *Save as application template* + The created template will then appear in the <>. This then allows you to directly launch a client with the desired configuration (Ardour with such tracks, Hydrogen with such drumkit…). Be careful, this copies all the client's files so avoid doing this if the client contains a lot of audio files. ** *Rename* + Change the client name located to the right of its icon, it is a purely visual name that can help you organize yourself. ** *return to a previous state* + Returns only the client to a previous session state, see <>. + However, you will not be able to go back to a state prior to a session renaming, so you must go back the entire session. ** *Properties* + Displays the client properties window + This menu is also accessible by right-clicking anywhere on the client. * The name of the client (here Carla), which can be easily changed by right-clicking → Rename * depending on the type and capacity of the client you can see here ** an eye (possibly crossed out), this means that the client is NSM compatible and is capable to show or hide its window by clicking on the eye. ** a *Hack* button, it means that the client is not NSM compatible, or at least that it is not launched with this protocol. Clicking on *Hack* allows to change the way it is launched by opening the client properties window on the Ray-Hack tab. * The Start button which is grayed out if the client is already started. * the Stop button which is grayed out if the client is not started. + If you stop the client and it is still not stopped after a while, the button turns red and you can click on it to kill the client. But stay relaxed, and only use it if it really seems completely inert, it could cause problems, even if nobody will send you to jail. * the state of the client which can be ** *stopped*: the client is stopped ** *ready*: the client is running and everything is ok ** *open*: the program is opening its project, please wait a little bit. ** *close*: the program is closing ** *launch*: if it stays on the launched state, it means *** if it is a Ray-Hack client, that it does not have a configuration file *** if it is started as an NSM client, if it is not NSM compatible, and therefore any save is in vain. It may be practical to launch certain programs in this way, such as a patchbay (Catia) or a utility whose state you do not need to save (Qrest). ** *switch*: the client changes projects during a session switch * the floppy disk button that allows you to save the client. + If over this floppy you see ** three red dots: the client contains unsaved changes ** a green V: the client does not contain unsaved changes ** an orange exclamation mark: It is not an NSM client, and it is impossible to save its project, you will have to do it yourself * the red cross which allows you to send the client to the trash [#add_application] == Add application window The window for adding application is launched by clicking on the *Application* button (_or Ctrl+A_). image::add_application.png[Add Application window] The list of available applications is on the right. If the software you want to add is not present here, see <>. ''' Top left is the filter block image::add_application_filter.png[Filter block of Add Application window] * the filter field allows you to enter a character string, only templates containing this character string in their name will appear. * the *Factory* checkbox displays the templates integrated into RaySession or provided by your distribution * *user* displays the templates created by the user by doing *Save as application template* * *NSM* displays the NSM compatible clients, or launched as such * *Ray-Hack* displays clients launched without NSM protocol ''' Bottom left the information block on the selected template on the right image::add_application_infos.png[Informations block of Add Application window] * at the top right of this block, a star, click on it to add it to favorites or remove it from favorites * If it is a user template, a *User* button allows you to delete this template * the button at the bottom right of this block allows you to access all the properties of the template, as in the <>, except that nothing is editable. |=== |*Tip:* This window is designed for very fast app addition, and behaves like _Alt+F2_ on your desktop. + For example, from the main RaySession window, to add Carla type _Ctrl+A_ , then `carla`, select the correct template with the Up/Down arrows, then Enter. |=== [#add_executable] == Add executable window The window for adding an executable is launched by clicking on the *Executable* button (_or Ctrl+E_). image::add_executable.png[Add Executable window] You will need to go through this window if you want to add a client that does not appear in the list of the <>. This window is very simple, a field to enter the executable, an *NSM Protocol* box, an advanced options button. Leave the NSM protocol checked if: * the program to launch is NSM compatible (if it is not in the list of applications, please let us know!) * the program to run is a utility for which there is no need to save any project (QRest, Catia…). The state of such a program will remain on *launch* and will never be *ready*, it is irrelevant since they do not have a project to save. If you leave the *NSM protocol* checked, it will not be possible to use the absolute path of an executable to add it, the executable must be located in a location provided for this purpose (you will not be able to launch `/usr/bin/my_program`, but `my_program`). You cannot enter arguments here, with or without the NSM protocol. Unchecking *NSM Protocol* is equivalent to launching the program with the Ray-Hack pseudo-protocol. If you click on the *advanced options* button, an advanced options block appears with image::add_executable_plus.png[Advanced Add Executable window] * the *Start the client* checkbox , if you uncheck it the client will be added but not launched * the multiple choice box *Prefix Mode*, this defines the prefix of the name of the client's files ** on *Session Name*, the file names will start with the session name, this is the default value ** on *Client Name*, the file names will begin with the name provided by the client itself, as is the case with New Session Manager ** on *Custom*, the file names will start with the value you enter in the *Prefix* field just below. * the *Prefix* field which is only active if *Prefix Mode* is set to Custom. * the *Client ID* field (client identifier). Enter only alphanumeric characters or '_'. + This is useful if you want to catch and launch existing projects in the session with an executable. This is useful if you want to load in the session projects created outside a session. There is no method to make it easier, it depends a lot on the program you are using. RaySession will insult you if you enter a client ID that already exists in the session. * the *Long JACK naming* checkbox. If this box is checked, clients will be supposed to use `ProgramName.ClientId` as JACK client name, else it will be `ProgramName`, possibly followed by `_N` (where N is a number). This is very useful if you use many instances of the same program, and you want to identify them easily in the patchbay. [#client_properties] [#patchbay] == Patchbay The JACK patchbay is displayed by default. You can hide it by clicking on *Control* and then uncheck *Show JACK Patchbay* (__or Ctrl+J__). The patchbay contains all the JACK AUDIO and MIDI ports that you can interconnect. Obviously, if JACK is not started, this patchbay will be empty. It is advisable to have the A2J bridge running if you want to work properly with MIDI. You can configure this via *Cadence*, *Studio Control*, or via the command line utility `a2j_control`. RaySession does not include tools to configure the JACK server, *QJackCtl*, *Studio Control*, *Cadence*, or the command line utility `jack_control` do this job very well. Note that this patchbay also works with PipeWire. === Overview image::patchbay_base.png[Patchbay overview] This is what your patchbay can look like. Here there are 7 boxes: * a *system* box with your ports corresponding to the hardware inputs (microphone, guitar...) * a *system* box with your ports corresponding to the hardware outputs (headphones, speakers...) * an *a2j* box with your ports corresponding to the MIDI hardware inputs * an *a2j* box with your ports corresponding to the MIDI hardware outputs * a *PulseAudio JACK Source* box * a *PulseAudio JACK Sink* box, sound from firefox and all non JACK applications comes from theses ports * a *Guitarix* box Here A2J and pulse2jack bridges are launched. You notice that 4 of these boxes are surrounded by a decoration (2 *system* and 2 *a2j*), these are the boxes that contain the hardware ports (your audio interface, your USB piano, any controller...). ''' Some audio ports are grouped into subgroups, which we will call portgroups. These portgroups are mostly stereo pairs automatically detected by the port names. This is the case here for : * system:capture 1/2 * system:playback 1/2 * PulseAudio JACK Source:front L/R * PulseAudio JACK Sink:front L/R * Guitarix:out 0/1 These portgroups facilitate the connections and allow a better general readability. ''' The blue curved lines correspond to the audio connections. You can observe that : * hardware input audio ports are connected to *PulseAudio JACK Source*. * the *PulseAudio JACK Sink* ports are connected to the hardware outputs * only the first port of *system* is connected to the input (__in 0__) of the *Guitarix* software * the audio ports of *Guitarix* are connected to the hardware outputs === Make and break a connection You can establish a connection between 2 ports as long as they meet the following conditions: * he ports are of the same type (you can't connect an audio port to a MIDI port) * one is an input port, the other is an output port ==== Intuitive Method To connect or disconnect two ports, click on a port without releasing the mouse button, drag the cursor to the desired port and release the mouse button. ==== Alternative method Right click on a port, it will display a drop down menu, choose *Connect* then the desired port. Click elsewhere to make this menu disappear. The advantage of this method is that it allows you to quickly connect a port to several others, the menu remaining displayed during the connections. video::video/patchbay_simple_connect.mp4[width=640] === Options Right click anywhere on the patchbay to display the menu. This menu is also present in the RaySession menu (*Patchbay* menu). It will allow you to : * switch the patchbay to full screen * Find a box with its name * Filter ports: show only AUDIO or MIDI ports or both * adjust the zoom level * refresh the canvas: ask JACK again for the list of existing ports and their connections * Canvas Preferences: display a window of options + All changes in this window take effect immediately. Hover over the boxes to see the tooltips. === Shortcuts you should know * A double click anywhere switches the patchbay to full screen. * __Ctrl+Mouse Wheel__ allows you to zoom in/out. * __Alt+Mouse wheel__ allows to move the view horizontally. * The wheel button is used to move the view * __Ctrl+middle mouse button__ cuts all connections passing under the cursor * __Ctrl+F__ allows to search a box with its name ==== Burst Connections It is possible to connect a port or a portgroup to different ports quite quickly. You just have to end your connections with a right click. A video will be much more explicit. video::video/patchbay_rafal_connections.mp4[width=640] Here we want to connect the multiple outputs of Hydrogen to the Jack-Mixer tracks. In the video the blue circles appear with a right click. ==== Passing connections from one port to another Sometimes it is less tedious to switch connections from one port to another than to undo and redo everything. To do this, start from the port that contains the connections and act as if you wanted to make a connection, but go to the port to which you want to switch the connections. * This only works if the destination port does not contain any connections * It works from port to port or from portgroup to portgroup but not from port to portgroup video::video/patchbay_fast_cut_paste.mp4[width=640] In this video we have a rather complex case where the source is plugged into *3 Band Splitter*. The bass and treble (_Output 1_ and _Output 5_) are sent directly to *EQ6Q Mono* while the midrange (_Output 3_) goes through the distortion *GxTubeScreamer* first. We want to insert the *Dragonfly Room Reverb* before the *EQ6Q Mono* equalization. ''' Note that with the right-click connection and the switching of connections from one port to another, it is very quick to integrate a new plugin in a chain, as here where we plug *Plujain Ramp Live* between *Dragonfly Room Reverb* and *EQ6Q Mono*. video::video/fast_new_plugin.mp4[width=640] === A2J ports image::patchbay_a2j.png[ports a2j] The MIDI ports provided by the A2J (Alsa To Jack) bridge have a hole at the end to identify them. Their real name is a long name, but that's about the only thing that differs from the other MIDI ports. === Control Voltage ports (CV ports) image::patchbay_CV.png[ports CV] Control voltage ports, commonly called CV ports, work like regular audio ports, however, they can control one or more parameters with much more precision than MIDI ports. As their stream is not meant to be listened to, it is not possible to simply connect a CV output port to a regular audio input, as this could damage your headphones, your speakers, and maybe even your ears. + If you still want to do it, right click on one of the ports, then *Connect*, then the *DANGEROUS* menu. + You can't say you weren't warned, and it's almost impossible to do this by mistake. On the other hand, connecting a classic audio output port to a CV input port is perfectly possible, no problem. == Client Properties Window A client's properties window opens from the client menu by clicking Properties. The client properties window has 2 tabs, a General tab and a tab specific to the protocol used by the client. Depending on the client protocol, the second tab is called NSM, Ray-Hack or Ray-Net. === *General* tab image::properties_general.png[Client properties] The first block of the General tab displays the client ID, protocol, label, description and icon. + If you do not edit them, the label, description and icon are taken from the .desktop file associated with the launched executable, if found. + If you want to know the .desktop file used, type `ray_control client CLIENT_ID get_properties` in a terminal (replacing CLIENT_ID with the client identifier). Then comes the block of snapshots, see <>. The checkbox *Prevent stop without recent or possible save* concerns the window that may appear when you ask a client to stop. If this box is unchecked, then the client will be stopped without a window warning you. + If the box is checked, the window will warn you when * the client is unsaveable from RaySession * we know that the client contains unsaved changes * the client appears not to have been saved for more than a minute Whether or not to check this box depends only on the importance of your client's save, it's up to you to judge. That said, if the warning is annoying, just check *Don't prevent to stop this client again* in the warning window and *Prevent stop without recent or possible save* will be unchecked. === *NSM* tab image::properties_nsm.png[NSM Client properties] The *Name* of the client here is provided by the client himself. + The *capabilities* are those which are transmitted by the client at its start-up. If the client has not yet been started, this field is therefore empty. Editing the executable allows you to change the command that launches the client. Only change it to another executable capable of loading the existing client's project. This is useful for example if you have two versions of Ardour, one running with the command `ardour`, the other with `Ardour6`, and you want to change which version to use. Editing the arguments is strongly discouraged, and is especially not suitable for loading a file as an argument. === *Ray-Hack* tab If the client is a Ray-Hack type, here many fields are available to you. This is not necessarily good news, the idea is to be able to load a program into the session that is not (yet) compatible with NSM. If properly implemented in the client, the NSM protocol will always be much more comfortable to use and more reliable than this hack. That said, if we can expect the NSM implementation in all audio programs, this is not the case for other programs which can still be useful in the session. The Ray-Hack pseudo-protocol uses the attributes of proxies (nsm-proxy or ray-proxy), except that the client is launched directly in the session. image::properties_ray_hack.png[Ray-Hack Client properties] ==== Launch block image::ray_hack_launch.png[] * the *Folder* is the folder name of this client in the session folder. The program is launched from this folder. * the *Executable* is the command that starts the program * The *Config file* will be the project file that we want to open with this program. It is more than highly recommended to reference a file in the client folder. + The variable `$RAY_SESSION_NAME` will be automatically replaced by the name of the session. + If this field is empty, the client status will always remain *launch* and will never be *ready*. In some cases, therefore, it may be useful to type anything here rather than nothing. * The *Browse* button opens a dialog box to find the project file and fill in the *Configuration file* field * The *Arguments* field includes the arguments passed to the Executable command + the arguments are split as they would be in a terminal, don't forget the " or ' if necessary. + For example to reproduce `my_command my_argument_1 "my argument 2"` enter `my_command` in the *Executable* field and `my_command my_argument_1 "my argument 2 "` in the *Arguments* field. ==== Signals block image::ray_hack_signals.png[] * *Save Signal* can be only rarely used. It can be SIGUSR1 for programs compatible with the old LASH protocol. Otherwise leave it on _None_, if there is no save method, we cannot invent it. * *Stop Signal* will usually be SIGTERM. Only change it if this signal does not close the program correctly. * If *Wait for a window before considered it ready* box is checked, then the client status will only change to *ready* when a window appears. + If `wmctrl` is not installed, or the window manager does not seem to be compatible with it, then the client status will be *ready* half a second after it is launched. With `ray_control` you can assign signals other than those offered in the multiple choice boxes. For example `ray_control client CLIENT_ID set_properties save_sig:22` will define the SIGTTOU signal for the client CLIENT_ID save. + Type `kill -l` to see the available signals and their numbers. ==== Non-saveable management block image::ray_hack_non_saveable.png[] This block is active only if the *Save Signal* is set to _None_. * if *Tell user to close program himself at session close* is checked, the client will be considered as not saveable and an orange exclamation mark will appear in front of its save icon. When closing the session, RaySession will wait for you to close the program yourself because it is impossible to know if it contains unsaved changes. * If *Try to close window gracefully* is checked, then at session close, RaySession will try to close the window as if you were closing the program window. This is very useful when the program reacts by closing if there are no unsaved changes and displaying a close confirmation window in the opposite case (most programs react in this way). If `wmctrl` is not installed or the window manager does not seem to be compatible, you will have to close the program yourself in any case. ==== Test area image::ray_hack_test_zone.png[] The test area allows you to test the start, stop, and save settings set in this window without having to *Save the changes*. == Network Sessions A network session allows you to launch another session on another machine at the same time as your session. This can be particularly useful if you are using net-jack to unload your machine from part of the DSP, if you have greedy effects running on another machine for example. Network sessions operate on a master-to-slave basis. A session is master and can have several slave sessions which are themselves masters of other slaves, but such a scenario seems completely out of the ordinary. Organize yourself simply: one master, one or more slave(s). To launch a network session (therefore a slave), launch the *Network Session* application template from the applications window and follow the instructions. image::network_session_template.png[Add a network session] You will have to start a daemon on the remote machine with the command `ray-daemon -p 1234` (`1234` is an example, put the port you want). This daemon displays something like this in the terminal: ``` [ray-daemon]URL : osc.udp://192.168.1.00:1234/` [ray-daemon] osc.udp://nom-de-machine:1234/` [ray-daemon]ROOT: /home/utilisateur/Ray Sessions reseau ``` image::network_session_invitation.png[Configure a network session] You will need to copy one of the two URLs into the network session invitation window. The first (which begins with osc.udp://192.168.) must work for sure, the second will work only if the name of the slave machine is correctly entered in the file `/etc/hosts` of the master machine. However, entering the name of the slave machine in `/etc/hosts` and using the second URL is preferable, because the address in 192.168. will move if you connect your slave machine differently (wired, wifi), or if you reinstall the distribution. You now have 2 RaySession windows on your master machine, one controls the master session, the other the slave. You will recognize the slave by the fact that it does not have a toolbar (*New Session*, *Open Session*, *Control*), nor *Abort session* and *Close session* buttons. image::network_session_child.png[] The slave window is hideable as is the case in many NSM programs. image::network_session_client.png[] If you run `raysession -p 1234` on your slave machine, you will have the slave session window in duplicate, one on each machine. *Tip:* Put this `ray-daemon -p 1234` in your slave machine startup. [#add_program_not_provided] == Add a program not provided If the program you want to add does not manage a project to save, click on *Executable*, enter the name of the executable and click on *Ok*. Otherwise follow this example. We want to add Audacity to the session here. Audacity is chosen as an example because it is known and generally installed on audio distributions. This is not necessarily a very suitable program for the modularity of an audio session given the way it handles JACK. Click *Executable* (_or Ctrl+E_). In the <>, Uncheck the *NSM Protocol* box, type `audacity` in the *Executable* field and click *Ok*. image::audacity_executable.png[Add Executable window well done] A new client is created, its properties window opens on the *Ray-Hack* tab and Audacity is launched. In Audacity, we will directly save an empty project in the client's folder. The client's folder is located in the session folder and has the name given after *Folder:* at the top of the *Ray-Hack* tab. We will call the project EXACTLY like the current RaySession session. To do this, in Audacity, go to _Menu → File → Save project → Save project_. image::audacity_save project.png[Save empty Audacity project] Click *Validate* at the possible warning window. + In the save files box that opens, you will find the session folder at the bottom left (see <>), click on it to enter it. Inside this you should see the client's folder as it appears at the top of the Ray-Hack tab, enter this folder. At the top left of the backup box, type the exact name of your session in the *Name:* field then validate. [caption="Figure 1: ",link=images/audacity_save_file.png] image::audacity_save_file.png[Where to save Audacity project, 640, 480] Close Audacity. + At the top right of the *Ray-Hack* tab of the client properties window, click *Browse*. [caption="Figure 1: ",link=images/audacity_load_config_file.png] image::audacity_load_config_file.png[Load CONFIG_FILE window, 640, 480] select the Audacity project you just created, its name starts with the session name and ends with .aup. If all went well, the *Configuration File* field became `$RAY_SESSION_NAME.aup` and the *Arguments* field became `"$CONFIG_FILE"`. + Check the boxes *Wait for a window before being considered ready*, *Ask the user to close the program himself* and *Try to close the window gracefully*. Click in the bottom right corner on *Save Changes*. image::audacity_ray_hack_final.png[Ray-Hack tab of Audacity client well done] Launch the Audacity client and verify that the Audacity window has the name of the session. + Click on the Audacity client icon, in the drop-down menu choose *Save as an application template*, and enter `Audacity` the field of the dialog box that has appeared. Now when you want to launch Audacity in the session, all you have to do is launch the Audacity template from the <>. Note that the client's save button is behind an orange exclamation point, this means that RaySession is not able to save its project and that you will have to do it yourself. Depending on what program you want to add to the session, it might not always be that easy. Some programs will require an argument that precedes the configuration file, in this case type `my_program --help` or `man my_program` to know how to load a project when the program starts, and adapt this in the *Arguments* field. == Import an NSM session To import a session created with Non Session Manager or New Session Manager, move or copy the session folder to the RaySession root sessions folder (default ~/Ray Sessions). Then click *Open session*, your session should appear in the list of sessions, double-click on it. RaySession will not rewrite clients added or deleted to the `session.nsm` file, as long as you open an NSM session with RaySession you must continue with RaySession. If ever you want to use another session manager, you will find in the menu *File -> Utilities -> Convert the session to NSM file format*. Obviously this leads to some changes, such as prefix mode or the way the JACK clients will be named, but nothing that prevents the session from working. == The daemon's options Daemon options are services which can be activated and deactivated via the *Control* button at the top right of the main window, or via the options menu in the menu bar. image::daemon_options.png[Daemon options] Here are the details of the different options: [#session_folder_shortcuts] === Provide bookmarks for session folder In audio production, creating audio or midi file with one program and load it into another is an usual case. This option offers something purely practical: a shortcut to the current session folder in your file manager and in the dialog boxes provided for fetching or saving files. It simply avoids wasting time browsing through your personal folder tree to find a file that you have put in your session folder, since that is where it belongs. + Of course, this shortcut is deleted when the session is unloaded. + Technically, shortcuts are created for GTK2, GTK3, QT4, QT5, KDE and FLTK. === Auto Snapshot at Save This option is far from being trivial, it allows you to take a snapshot of the session after each session save. This means that in case of a technical or artistic error you will be able to find the session in the state it was in at the moment of the snapshot. This option requires that you have the `git` program installed. See <> for more details. === Desktops Memory If this option is activated, RaySession will save (or attempt to save) the number of the virtual desktop on which the client windows were located when the session was saved. So when you restart the session or the clients, the windows will be redispatched to the desktops on which they appeared. This option requires you to have the program `wmctrl` installed to work, and probably will not work with Wayland. === Session scripts Disable this option to not activate any session script, and thus open, save or close a session completely ignoring the scripts associated with these actions. These scripts are used by sessions with <>. See <> for more details. === Remember optional GUI states This option only concerns NSM clients capable of showing/hiding their graphical interface. Without this option, some of them will always start hidden, others will remember if they were visible when they were last saved. With this option enabled, the graphical interfaces will be displayed when the session is ready if they were visible during the last save or if the client has never been launched. [#snapshots] == Snapshots Snapshots require you to have the program `git` installed, if you don't have `git`, the reverse button does not appear and it is not possible to take or return to a snapshot. A snapshot stores files and their contents at a specific time. Large files and files with certain extensions such as audio and video files are ignored, otherwise the snapshot process will take too long and the size of the session folders will needlessly double. This is actually not very annoying, on the contrary, since your recent audio files remain present when you go back to a previous snapshot. + If despite everything the snapshot process turns out to be long, a window appears and you can safely cancel the current snapshot. If you cancel it, the automatic snapshot will no longer take place for this session. The interest of the snapshots lies in the fact of being able to return to the previous moment of the session, before having had this brilliant artistic idea which turned out to be null and void, before having attempted a recutting of the samples with the microcoscope which finally killed all forms of musicality, before a program crashes for some reason unknown to the police... Don't worry, going back to a snapshot won't stop you from getting back to where you were. To revert the session to a snapshot, click the reverse button located to the right of the *Executable* button. image::snapshots.png[] Select the snapshot you want to revert to and click *Ok*. A new snapshot is taken, the session closes, the desired snapshot is recalled and the session reopens. It is also possible to return only a client to a previous state of the session by right-clicking on the client,then *Return to a previous state*. If you want you can edit for each client the files ignored by the snapshots in the <>. With the *Automatic snapshot after save* option, a snapshot is taken immediately after each backup of the session, unless there is no change since the previous snapshot. To take a snapshot at another time, click on the reverse icon to the right of the *Executable* button and on *Take a snapshot now*, this has the advantage of being able to name the snapshot and thus having a more meaningful time mark than the date and time of the snapshot. [#session_scripts] == Session scripts Session scripts allow you to program personalized actions when opening, saving and closing the session. They are used in particular for sessions with <>. + Knowledge of shell scripting is required to edit these scripts, but anyone can use them. Session scripts are located in a folder `ray-scripts` located either in a session folder or in a parent folder. + For example, for a session being in: + `~/Ray Sessions/with_foo_script/my session` the session scripts folder may be ``` ~/Ray Sessions/with_foo_script/my session/ray-scripts ~/Ray Sessions/with_foo_script/ray-scripts ~/Ray Sessions/ray-scripts ~/ray-scripts ``` The advantage of such behavior is to be able to script a set of sessions without having to copy the scripts there, but above all to deliver an unscripted session when it is transferred to someone else for collective work. + Only the script folder closest to the session in the tree will be considered. Thus, a `ray-scripts` empty folder in a session will disable scripts for that session. To edit the scripts, start by creating a session with the template with the basic scripts, this is a template session with scripts that does not include any particular action. Go to the folder `ray-scripts` in the session folder, you will find the files `load.sh`, `save.sh` and `close.sh`. In each of these scripts, `ray_control run_step` corresponds to the normal action performed (depending on the script: load, save or close the session). If one of these three scripts is of no use to you, delete it, it will save time not to go through that script. The script files must imperatively be executable to work. You will probably need the command line utility `ray_control` to perform actions relating to a particular client. type `ray_control --help` to know all its possibilities, see also <>. JACK memory configuration session template uses session scripts, but we can also imagine many possible actions according to your needs and desires, for example: * define a specific order for launching clients when the session is opened (an example is provided in the source code) * make a backup copy of the session on an external hard drive each time you close it * send a _Ctrl+S_ shortcut to non-saveable client windows when saving the session (an example is provided in the source code) * Turn on the red light at the entrance to the studio when opening, turn it off when closing * Start the coffee machine at the end of the session (stupid example, go and press the button on the coffee maker, anyway you will have to change the filter!) * Make many, many, many mistakes that will crash your session, be careful of course! [#jack_configuration_memory] == JACK configuration memory It is possible thanks to session scripts to automatically recall the JACK configuration specific to a session before loading it. This behavior may remind some of the operation of LADISH studios, much better done, at least that's what is hoped. === In which cases to use it This can be useful: * If you need to use a specific audio interface for the session * If you are working on multiple projects with different sample rates (such session at 44100 Hz, such session at 48000 Hz). + This will prevent you from having to reconfigure, stop and restart JACK yourself, or even avoid forgetting to do so and being insulted by certain programs. * If you want to avoid loading a very DSP-intensive session (for example in the mixing phase) with a too small buffer (128 for example). + Note that on most audio interfaces it is possible to change the buffer size hotly (without restarting JACK). === Usage The Session scripts option must be enabled (This option is enabled by default). To use the JACK configuration memory, create a new session from the *With JACK configuration memory* template. It is in fact a scripted session (see <>) which launches a script supplied with RaySession, but which is completely external to it, so RaySession still has no direct relation to JACK. Read the information window on this subject then validate. JACK restarts then your session starts. === Working principle Each time the session is saved, the JACK configuration is saved in the session, in the `jack_parameters` file. + Before opening the session, JACK is restarted if the configuration of the session is different from the current configuration of JACK. + After closing the session, JACK is restarted if necessary with the current configuration before opening. + The configuration of the PulseAudio → JACK bridges is also saved and restored with the JACK configuration. If you open this session after having copied it to another computer, the JACK configuration will not be recalled but will be overwritten when saving. Only the sampling frequency of the session will be used. === Special cases ''' *To open a session without reloading its configuration from JACK:* * disable the *Session scripts* option * open the session ''' *To change the JACK configuration of a session:* * Start JACK with the desired configuration * Disable the Session scripts option * Open the session * Re-enable the Session scripts option * Save the session ''' *To make an old session sensitive to the configuration of JACK* * copy the folder `ray-scripts` of a session with memory from the JACK configuration to the session folder * Activate the Session scripts option * Open the session *or* * move the session to a sub-folder containing the good one `ray-scripts` folder * Open the session [#under_the_hood] == Under the hood RaySession is really just a GUI for ray-daemon. When you launch RaySession, the GUI launches and connects to the daemon, and it stops the daemon when closed. The graphical interface and the daemon communicate with each other by OSC (Open Sound Control) messages, as is the case between the daemon and the NSM clients. Thus, you can connect several graphical interfaces to a daemon, even remotely. Type `raysession --help` to see how. It is not forbidden to have several daemon instances launched simultaneously, so if you launch RaySession while an instance is already launched, it will launch a new daemon. However, this way of working being unusual, the use of a single daemon is favored. So, if a daemon is running and it has no GUI attached, raysession will connect to that daemon by default. [#ray_control] == Control RaySession from the command line the command `ray_control` lets you do just about anything you can do with the GUI, and a little more. type `ray_control --help-all` to know all the possibilities. In case there are multiple daemons started (see <>), `ray_control` will only consider the one that was started first, unless you specify its OSC port with the `--port` option or `RAY_CONTROL_PORT` environment variable. One might think that there is no point in using `ray_control` since the command `oscsend` allows to send an OSC message to the daemon, but it is false. + Firstly, because `oscsend` allows you to send messages but not to obtain information in a simple way (which are the active clients? What is the executable of such and such client? ...), secondly, because the command `ray_control` will end when the requested action is taken, for example `ray_control open_session "my session"` will end when the session is loaded. Remember to assign `ray_control save` to a global shortcut of your desktop environment (_Ctrl+Meta+S_), this will save you a lot of time! == Frequently Asked Questions - *Is it still worth running Ardour (or another NSM compatible DAW) directly rather than in RaySession?* + Except for a really tiny project, no. If you are using Ardour, always run it from RaySession, firstly, the automatic snapshot after save can be of unexpected help to you, secondly, you are not immune to needing another program even if you did not plan it. - *Can I launch an Ardour session launched normally into a RaySession session ?* + You will find in the menu *File -> Utililies -> Convert an Ardour session to a Ray session*, it creates and launch a RaySession session from an ardour session. It is adviced to backup your ardour session first. Obviously, Ardour must not be open with this session during the execution of this script, but you already knew that. RaySession-0.12.2/manual/en/manual.html000066400000000000000000002176711417052567600177500ustar00rootroot00000000000000 RaySession Manual

EN FR DE

icon

for version 0.10.0

Introduction

RaySession is an audio session manager for GNU / Linux. It allows you to start several audio programs in the same session, to save their projects together and thus to avoid multiple operations to return to a given configuration.

To be launched in RaySession, it is very much preferable that these audio programs be compatible with the NSM protocol, and many are already, among others Ardour, Qtractor, Carla, Guitarix, Mamba, Patroneo, ZynAddSubFx …​

RaySession assumes that your audio setup is working for audio production, if not, fix this first and don’t waste your time trying to use RaySession.

Now let’s see how to use it.

Simple use example

For audio production under GNU / linux, it is highly recommended to use the JACK server. Before creating or starting a session, make sure the JACK server is running, RaySession has no direct relation to JACK, however the programs you are going to launch in your session will need it.

Let’s take an example where to compose a song, we will need Ardour and Guitarix softwares, make sure that these 2 programs are installed.

To create a new session, click at the top left on New Session (or Ctrl+N). A dialog window appears.

New session

At the top right you can see the root session folder, this is where the sessions will be saved (a RaySession session being a folder containing a file raysession.xml).

Enter the name you want for this new session in the field provided. To put your new session in a sub-folder, type the name as follows: sub-folder/my session.

The session template multiple choice box lets you choose between

  • An empty session template

  • A template with memory of JACK connections

  • A scripted template with memory of the JACK configuration

  • A template with basic session scripts (for advanced users with shell scripting knowledge)

  • All the session templates that you have created yourself.

First, keep the template on With JACK patch memory , click Ok to start your session.

Session launched

The session part of the window becomes active, at the top is written the name of your session, and your session already contains a client program called JACK Connections. This client will save and redo the connections of the JACK patchbay.

To add Ardour to your session, click on the Application button (or Ctrl+A), the application dialog will appear (more details in the Add application window section). On the right side, find Ardour (Depending on your version of ardour, it may be called Ardour5 or Ardour6) and double-click on it.

Add Ardour to the session

An Ardour client appears below JACK Connections and Ardour starts up (normally directly with an empty Ardour session).

Do the same with Guitarix.

Session ready with Ardour and Guitarix

In Ardour, add a track (Menu: Track → Add a track), in the Ardour window that has appeared, name the track Guitar and put the multiple choice box configuration on Stereo.

Add a track in Ardour for Guitarix

Open the JACK Patchbay, for this go to ControlShow JACK Patchbay (or Ctrl+J). The patchbay appears at the right of the window.

Connect the Guitarix input to a hardware input and the Guitarix outputs to the inputs of this new Ardour track. Make sure your Guitar track inputs are not connected to the hardware inputs.

My session patchbay

Here you have a configuration where you can directly record the sound of your guitar processed by Guitarix in Ardour. If you don’t have a guitar, all you have to do is sing out of tune into a mic or tap a cushion, this is just an example.

Now go back to the RaySession window, and save the current session by clicking the floppy disk button to the top right (or Ctrl+S). It is highly recommended because it is very practical to assign a global keyboard shortcut of your system to the save of the current session. This will depend on your desktop environment, but just assign the Ctrl+Meta+S shortcut to the command ray_control save (Meta is the Windows key), so you won’t have to return to the RaySession window to save the session.

Now close the session by clicking on the red cross at the top right (or Ctrl+W).

Once the session is closed, click on Open Session (or Ctrl+O), double-click on the session you just created to re-open it.

You will find the programs and their projects as well as the JACK connections as they were when you closed the session, and everything therefore works without any further manipulation. One of the advantages of modularity in this specific case is that once you have finished the guitar records, you can stop Guitarix so as not to overload the processor unnecessarily, and it will still be easy to restart it if necessary.

Overview of session tools

Top row

Top line of the session frame

From left to right:

  • the menu button gives you access to

    • save the current session as a template
      The created session template will then appear in the multiple choice of session templates in the New Session dialog window. Be careful, however, all the files of the session will be saved in the template, so you should not do this if the session contains a lot of audio files. firstly, the copy will be long, secondly, you run the risk of unnecessarily multi-copying files which will take up a lot of space.

    • Duplicate the current session
      This is the equivalent of the well-known "Save As …​", except that RaySession has to stop and restart most programs to switch between sessions. Avoid duplicating a session with a lot of audio files, it could take a long time, but fortunately such an operation can be stopped.

    • Rename the session
      It will then be necessary to stop all the clients.
      Alternatively, you can rename a session by duplicating it and then deleting the folder from the initial session.
      You can also rename a session by renaming its folder, but BE CAREFUL, this session must not be loaded!

  • the pencil-shaped button gives you access to the session notes.
    Write here the information you need, the physical settings, the lyrics of a song, the recipe for granny’s cassoulet …​ however do not write a novel in 3 volumes, other tools are much more suitable, and notes are limited to 65,000 characters for technical reasons. The pencil is green when notes exist, it is orange when the notes window is open, otherwise it is transparent.

  • the name of the loaded session (here my session)

  • the Abort session button which allows you to close the session without saving it

  • the Close session button ,which saves and closes the current session.
    Note that you do not need to close the current session to start another. Some clients are able to switch from one session to another and it may take a lot less time than closing everything and restarting everything.

Bottom row

Bottom line of the session frame

From left to right:

  • the folder-shaped button to open the session folder with your file manager

  • the yellow star-shaped button that pulls down a menu containing your favorite applications if there are any

  • the Application button which allows you to add to the session a factory application template or that you have created yourself. This is the recommended method for adding a client. see Add application window.

  • the Executable button which allows a program to be added to the session from its executable. You will need it if you want to add a program for which there is no template. see Add executable window.

  • the reverse button to return to a previous state of the session. This requires having the program git installed, else this button will not appears.
    See Snapshots for more details.

  • the server status indicator.
    Server states can actually be very stealthy, but they are displayed for a long enough time that you can see them. The server status can be:

    • off: no session loaded

    • ready: the session is running

    • launch: launch of the session’s programs

    • copy: a copy is in progress, for a session duplication or to save the session as a template

    • close: the session is closing

    • snapshot: A snapshot of the session is being taken, so you can revert to the current session state.
      see Snapshots.

    • wait: The server waits for you to close yourself non-saveable programs

    • script: a script is activated

    An information or progress window is displayed if you click this status indicator if it is on copy , snapshot, or wait.

  • the Save Session button

  • the trash, here you will find the clients that you have deleted. You can then restore them in the session or permanently delete all the files they created in the session folder.

Overview of a client

trame d’un client

A client contains from left to right:

  • The client icon that you can click to bring up a menu with the following actions

    • Save as application template
      The created template will then appear in the Add application window. This then allows you to directly launch a client with the desired configuration (Ardour with such tracks, Hydrogen with such drumkit…). Be careful, this copies all the client’s files so avoid doing this if the client contains a lot of audio files.

    • Rename
      Change the client name located to the right of its icon, it is a purely visual name that can help you organize yourself.

    • return to a previous state
      Returns only the client to a previous session state, see Snapshots.
      However, you will not be able to go back to a state prior to a session renaming, so you must go back the entire session.

    • Properties
      Displays the client properties window

    This menu is also accessible by right-clicking anywhere on the client.

  • The name of the client (here Carla), which can be easily changed by right-clicking → Rename

  • depending on the type and capacity of the client you can see here

    • an eye (possibly crossed out), this means that the client is NSM compatible and is capable to show or hide its window by clicking on the eye.

    • a Hack button, it means that the client is not NSM compatible, or at least that it is not launched with this protocol. Clicking on Hack allows to change the way it is launched by opening the client properties window on the Ray-Hack tab.

  • The Start button which is grayed out if the client is already started.

  • the Stop button which is grayed out if the client is not started.
    If you stop the client and it is still not stopped after a while, the button turns red and you can click on it to kill the client. But stay relaxed, and only use it if it really seems completely inert, it could cause problems, even if nobody will send you to jail.

  • the state of the client which can be

    • stopped: the client is stopped

    • ready: the client is running and everything is ok

    • open: the program is opening its project, please wait a little bit.

    • close: the program is closing

    • launch: if it stays on the launched state, it means

      • if it is a Ray-Hack client, that it does not have a configuration file

      • if it is started as an NSM client, if it is not NSM compatible, and therefore any save is in vain. It may be practical to launch certain programs in this way, such as a patchbay (Catia) or a utility whose state you do not need to save (Qrest).

    • switch: the client changes projects during a session switch

  • the floppy disk button that allows you to save the client.
    If over this floppy you see

    • three red dots: the client contains unsaved changes

    • a green V: the client does not contain unsaved changes

    • an orange exclamation mark: It is not an NSM client, and it is impossible to save its project, you will have to do it yourself

  • the red cross which allows you to send the client to the trash

Add application window

The window for adding application is launched by clicking on the Application button (or Ctrl+A).

Add Application window

The list of available applications is on the right. If the software you want to add is not present here, see Add a program not provided.


Top left is the filter block

Filter block of Add Application window
  • the filter field allows you to enter a character string, only templates containing this character string in their name will appear.

  • the Factory checkbox displays the templates integrated into RaySession or provided by your distribution

  • user displays the templates created by the user by doing Save as application template

  • NSM displays the NSM compatible clients, or launched as such

  • Ray-Hack displays clients launched without NSM protocol


Bottom left the information block on the selected template on the right

Informations block of Add Application window
  • at the top right of this block, a star, click on it to add it to favorites or remove it from favorites

  • If it is a user template, a User button allows you to delete this template

  • the button at the bottom right of this block allows you to access all the properties of the template, as in the [client_properties], except that nothing is editable.

Tip: This window is designed for very fast app addition, and behaves like Alt+F2 on your desktop.
For example, from the main RaySession window, to add Carla type Ctrl+A , then carla, select the correct template with the Up/Down arrows, then Enter.

Add executable window

The window for adding an executable is launched by clicking on the Executable button (or Ctrl+E).

Add Executable window

You will need to go through this window if you want to add a client that does not appear in the list of the Add application window. This window is very simple, a field to enter the executable, an NSM Protocol box, an advanced options button.

Leave the NSM protocol checked if:

  • the program to launch is NSM compatible (if it is not in the list of applications, please let us know!)

  • the program to run is a utility for which there is no need to save any project (QRest, Catia…). The state of such a program will remain on launch and will never be ready, it is irrelevant since they do not have a project to save.

If you leave the NSM protocol checked, it will not be possible to use the absolute path of an executable to add it, the executable must be located in a location provided for this purpose (you will not be able to launch /usr/bin/my_program, but my_program). You cannot enter arguments here, with or without the NSM protocol.

Unchecking NSM Protocol is equivalent to launching the program with the Ray-Hack pseudo-protocol.

If you click on the advanced options button, an advanced options block appears with

Advanced Add Executable window
  • the Start the client checkbox , if you uncheck it the client will be added but not launched

  • the multiple choice box Prefix Mode, this defines the prefix of the name of the client’s files

    • on Session Name, the file names will start with the session name, this is the default value

    • on Client Name, the file names will begin with the name provided by the client itself, as is the case with New Session Manager

    • on Custom, the file names will start with the value you enter in the Prefix field just below.

  • the Prefix field which is only active if Prefix Mode is set to Custom.

  • the Client ID field (client identifier). Enter only alphanumeric characters or '_'.
    This is useful if you want to catch and launch existing projects in the session with an executable. This is useful if you want to load in the session projects created outside a session. There is no method to make it easier, it depends a lot on the program you are using. RaySession will insult you if you enter a client ID that already exists in the session.

Patchbay

The JACK patchbay is not displayed by default. You can display it by clicking on Control and then Show JACK Patchbay (or Ctrl+J). The patchbay contains all the JACK AUDIO and MIDI ports that you can interconnect.

Obviously, if JACK is not started, this patchbay will be empty.

It is advisable to have the A2J bridge running if you want to work properly with MIDI. You can configure this via Cadence, Studio Control, or via the command line utility a2j_control.

RaySession does not include tools to configure the JACK server, QJackCtl, Studio Control, Cadence, or the command line utility jack_control do this job very well. Note that this patchbay also works with PipeWire.

Overview

Patchbay overview

This is what your patchbay can look like. Here there are 7 boxes:

  • a system box with your ports corresponding to the hardware inputs (microphone, guitar…​)

  • a system box with your ports corresponding to the hardware outputs (headphones, speakers…​)

  • an a2j box with your ports corresponding to the MIDI hardware inputs

  • an a2j box with your ports corresponding to the MIDI hardware outputs

  • a PulseAudio JACK Source box

  • a PulseAudio JACK Sink box, sound from firefox and all non JACK applications comes from theses ports

  • a Guitarix box

Here A2J and pulse2jack bridges are launched.

You notice that 4 of these boxes are surrounded by a decoration (2 system and 2 a2j), these are the boxes that contain the hardware ports (your audio interface, your USB piano, any controller…​).


Some audio ports are grouped into subgroups, which we will call portgroups. These portgroups are mostly stereo pairs automatically detected by the port names. This is the case here for :

  • system:capture 1/2

  • system:playback 1/2

  • PulseAudio JACK Source:front L/R

  • PulseAudio JACK Sink:front L/R

  • Guitarix:out 0/1

These portgroups facilitate the connections and allow a better general readability.


The blue curved lines correspond to the audio connections. You can observe that :

  • hardware input audio ports are connected to PulseAudio JACK Source.

  • the PulseAudio JACK Sink ports are connected to the hardware outputs

  • only the first port of system is connected to the input (in 0) of the Guitarix software

  • the audio ports of Guitarix are connected to the hardware outputs

Make and break a connection

You can establish a connection between 2 ports as long as they meet the following conditions:

  • he ports are of the same type (you can’t connect an audio port to a MIDI port)

  • one is an input port, the other is an output port

Intuitive Method

To connect or disconnect two ports, click on a port without releasing the mouse button, drag the cursor to the desired port and release the mouse button.

Alternative method

Right click on a port, it will display a drop down menu, choose Connect then the desired port. Click elsewhere to make this menu disappear. The advantage of this method is that it allows you to quickly connect a port to several others, the menu remaining displayed during the connections.

Options

Right click anywhere on the patchbay to display the menu. This menu is also present in the RaySession menu (Patchbay menu). It will allow you to :

  • switch the patchbay to full screen

  • Filter ports: show only AUDIO or MIDI ports or both

  • adjust the zoom level

  • refresh the canvas: ask JACK again for the list of existing ports and their connections

  • Canvas Preferences: display a window of options
    All changes in this window take effect immediately. Hover over the boxes to see the tooltips.

Shortcuts you should know

  • A double click anywhere switches the patchbay to full screen.

  • Ctrl+Mouse Wheel allows you to zoom in/out.

  • Alt+Mouse wheel allows to move the view horizontally.

  • The wheel button is used to move the view

  • Ctrl+middle mouse button cuts all connections passing under the cursor

Burst Connections

It is possible to connect a port or a portgroup to different ports quite quickly. You just have to end your connections with a right click. A video will be much more explicit.

Here we want to connect the multiple outputs of Hydrogen to the Jack-Mixer tracks. In the video the blue circles appear with a right click.

Passing connections from one port to another

Sometimes it is less tedious to switch connections from one port to another than to undo and redo everything. To do this, start from the port that contains the connections and act as if you wanted to make a connection, but go to the port to which you want to switch the connections.

  • This only works if the destination port does not contain any connections

  • It works from port to port or from portgroup to portgroup but not from port to portgroup

In this video we have a rather complex case where the source is plugged into 3 Band Splitter. The bass and treble (Output 1 and Output 5) are sent directly to EQ6Q Mono while the midrange (Output 3) goes through the distortion GxTubeScreamer first. We want to insert the Dragonfly Room Reverb before the EQ6Q Mono equalization.


Note that with the right-click connection and the switching of connections from one port to another, it is very quick to integrate a new plugin in a chain, as here where we plug Plujain Ramp Live between Dragonfly Room Reverb and EQ6Q Mono.

A2J ports

ports a2j

The MIDI ports provided by the A2J (Alsa To Jack) bridge have a hole at the end to identify them. Their real name is a long name, but that’s about the only thing that differs from the other MIDI ports.

Control Voltage ports (CV ports)

ports CV

Control voltage ports, commonly called CV ports, work like regular audio ports, however, they can control one or more parameters with much more precision than MIDI ports. As their stream is not meant to be listened to, it is not possible to simply connect a CV output port to a regular audio input, as this could damage your headphones, your speakers, and maybe even your ears.
If you still want to do it, right click on one of the ports, then Connect, then the DANGEROUS menu.
You can’t say you weren’t warned, and it’s almost impossible to do this by mistake.

On the other hand, connecting a classic audio output port to a CV input port is perfectly possible, no problem.

Client Properties Window

A client’s properties window opens from the client menu by clicking Properties.

The client properties window has 2 tabs, a General tab and a tab specific to the protocol used by the client. Depending on the client protocol, the second tab is called NSM, Ray-Hack or Ray-Net.

General tab

Client properties

The first block of the General tab displays the client ID, protocol, label, description and icon.
If you do not edit them, the label, description and icon are taken from the .desktop file associated with the launched executable, if found.
If you want to know the .desktop file used, type ray_control client CLIENT_ID get_properties in a terminal (replacing CLIENT_ID with the client identifier).

Then comes the block of snapshots, see Snapshots.

The checkbox Prevent stop without recent or possible save concerns the window that may appear when you ask a client to stop. If this box is unchecked, then the client will be stopped without a window warning you.
If the box is checked, the window will warn you when

  • the client is unsaveable from RaySession

  • we know that the client contains unsaved changes

  • the client appears not to have been saved for more than a minute

Whether or not to check this box depends only on the importance of your client’s save, it’s up to you to judge. That said, if the warning is annoying, just check Don’t prevent to stop this client again in the warning window and Prevent stop without recent or possible save will be unchecked.

NSM tab

NSM Client properties

The Name of the client here is provided by the client himself.
The capabilities are those which are transmitted by the client at its start-up. If the client has not yet been started, this field is therefore empty.

Editing the executable allows you to change the command that launches the client. Only change it to another executable capable of loading the existing client’s project. This is useful for example if you have two versions of Ardour, one running with the command ardour, the other with Ardour6, and you want to change which version to use.

Editing the arguments is strongly discouraged, and is especially not suitable for loading a file as an argument.

Ray-Hack tab

If the client is a Ray-Hack type, here many fields are available to you. This is not necessarily good news, the idea is to be able to load a program into the session that is not (yet) compatible with NSM. If properly implemented in the client, the NSM protocol will always be much more comfortable to use and more reliable than this hack. That said, if we can expect the NSM implementation in all audio programs, this is not the case for other programs which can still be useful in the session.

The Ray-Hack pseudo-protocol uses the attributes of proxies (nsm-proxy or ray-proxy), except that the client is launched directly in the session.

Ray-Hack Client properties

Launch block

ray hack launch
  • the Folder is the folder name of this client in the session folder. The program is launched from this folder.

  • the Executable is the command that starts the program

  • The Config file will be the project file that we want to open with this program. It is more than highly recommended to reference a file in the client folder.
    The variable $RAY_SESSION_NAME will be automatically replaced by the name of the session.
    If this field is empty, the client status will always remain launch and will never be ready. In some cases, therefore, it may be useful to type anything here rather than nothing.

  • The Browse button opens a dialog box to find the project file and fill in the Configuration file field

  • The Arguments field includes the arguments passed to the Executable command
    the arguments are split as they would be in a terminal, don’t forget the " or ' if necessary.
    For example to reproduce my_command my_argument_1 "my argument 2" enter my_command in the Executable field and my_command my_argument_1 "my argument 2 " in the Arguments field.

Signals block

ray hack signals
  • Save Signal can be only rarely used. It can be SIGUSR1 for programs compatible with the old LASH protocol. Otherwise leave it on None, if there is no save method, we cannot invent it.

  • Stop Signal will usually be SIGTERM. Only change it if this signal does not close the program correctly.

  • If Wait for a window before considered it ready box is checked, then the client status will only change to ready when a window appears.
    If wmctrl is not installed, or the window manager does not seem to be compatible with it, then the client status will be ready half a second after it is launched.

With ray_control you can assign signals other than those offered in the multiple choice boxes. For example ray_control client CLIENT_ID set_properties save_sig:22 will define the SIGTTOU signal for the client CLIENT_ID save.
Type kill -l to see the available signals and their numbers.

Non-saveable management block

ray hack non saveable

This block is active only if the Save Signal is set to None.

  • if Tell user to close program himself at session close is checked, the client will be considered as not saveable and an orange exclamation mark will appear in front of its save icon. When closing the session, RaySession will wait for you to close the program yourself because it is impossible to know if it contains unsaved changes.

  • If Try to close window gracefully is checked, then at session close, RaySession will try to close the window as if you were closing the program window. This is very useful when the program reacts by closing if there are no unsaved changes and displaying a close confirmation window in the opposite case (most programs react in this way). If wmctrl is not installed or the window manager does not seem to be compatible, you will have to close the program yourself in any case.

Test area

ray hack test zone

The test area allows you to test the start, stop, and save settings set in this window without having to Save the changes.

Network Sessions

A network session allows you to launch another session on another machine at the same time as your session. This can be particularly useful if you are using net-jack to unload your machine from part of the DSP, if you have greedy effects running on another machine for example.

Network sessions operate on a master-to-slave basis. A session is master and can have several slave sessions which are themselves masters of other slaves, but such a scenario seems completely out of the ordinary. Organize yourself simply: one master, one or more slave(s).

To launch a network session (therefore a slave), launch the Network Session application template from the applications window and follow the instructions.

Add a network session

You will have to start a daemon on the remote machine with the command ray-daemon -p 1234 (1234 is an example, put the port you want). This daemon displays something like this in the terminal:

[ray-daemon]URL : osc.udp://192.168.1.00:1234/`
[ray-daemon]      osc.udp://nom-de-machine:1234/`
[ray-daemon]ROOT: /home/utilisateur/Ray Sessions reseau
Configure a network session

You will need to copy one of the two URLs into the network session invitation window. The first (which begins with osc.udp://192.168.) must work for sure, the second will work only if the name of the slave machine is correctly entered in the file /etc/hosts of the master machine. However, entering the name of the slave machine in /etc/hosts and using the second URL is preferable, because the address in 192.168. will move if you connect your slave machine differently (wired, wifi), or if you reinstall the distribution.

You now have 2 RaySession windows on your master machine, one controls the master session, the other the slave. You will recognize the slave by the fact that it does not have a toolbar (New Session, Open Session, Control), nor Abort session and Close session buttons.

network session child

The slave window is hideable as is the case in many NSM programs.

network session client

If you run raysession -p 1234 on your slave machine, you will have the slave session window in duplicate, one on each machine.

Tip: Put this ray-daemon -p 1234 in your slave machine startup.

Add a program not provided

If the program you want to add does not manage a project to save, click on Executable, enter the name of the executable and click on Ok. Otherwise follow this example.

We want to add Audacity to the session here. Audacity is chosen as an example because it is known and generally installed on audio distributions. This is not necessarily a very suitable program for the modularity of an audio session given the way it handles JACK.

Click Executable (or Ctrl+E). In the Add executable window, Uncheck the NSM Protocol box, type audacity in the Executable field and click Ok.

Add Executable window well done

A new client is created, its properties window opens on the Ray-Hack tab and Audacity is launched.

In Audacity, we will directly save an empty project in the client’s folder. The client’s folder is located in the session folder and has the name given after Folder: at the top of the Ray-Hack tab. We will call the project EXACTLY like the current RaySession session. To do this, in Audacity, go to Menu → File → Save project → Save project.

Save empty Audacity project

Click Validate at the possible warning window.
In the save files box that opens, you will find the session folder at the bottom left (see Provide bookmarks for session folder), click on it to enter it. Inside this you should see the client’s folder as it appears at the top of the Ray-Hack tab, enter this folder. At the top left of the backup box, type the exact name of your session in the Name: field then validate.

Where to save Audacity project

Close Audacity.
At the top right of the Ray-Hack tab of the client properties window, click Browse.

Load CONFIG_FILE window

select the Audacity project you just created, its name starts with the session name and ends with .aup.

If all went well, the Configuration File field became $RAY_SESSION_NAME.aup and the Arguments field became "$CONFIG_FILE".
Check the boxes Wait for a window before being considered ready, Ask the user to close the program himself and Try to close the window gracefully. Click in the bottom right corner on Save Changes.

Ray-Hack tab of Audacity client well done

Launch the Audacity client and verify that the Audacity window has the name of the session.
Click on the Audacity client icon, in the drop-down menu choose Save as an application template, and enter Audacity the field of the dialog box that has appeared. Now when you want to launch Audacity in the session, all you have to do is launch the Audacity template from the Add application window.

Note that the client’s save button is behind an orange exclamation point, this means that RaySession is not able to save its project and that you will have to do it yourself.

Depending on what program you want to add to the session, it might not always be that easy. Some programs will require an argument that precedes the configuration file, in this case type my_program --help or man my_program to know how to load a project when the program starts, and adapt this in the Arguments field.

Import an NSM session

To import a session created with Non Session Manager or New Session Manager, move or copy the session folder to the RaySession root sessions folder (default ~/Ray Sessions). Then click Open session, your session should appear in the list of sessions, double-click on it.

RaySession will not rewrite clients added or deleted to the session.nsm file, as long as you open an NSM session with RaySession you must continue with RaySession.

The daemon’s options

Daemon options are services which can be activated and deactivated via the Control button at the top right of the main window, or via the options menu in the menu bar.

Daemon options

Here are the details of the different options:

Provide bookmarks for session folder

In audio production, creating audio or midi file with one program and load it into another is an usual case. This option offers something purely practical: a shortcut to the current session folder in your file manager and in the dialog boxes provided for fetching or saving files. It simply avoids wasting time browsing through your personal folder tree to find a file that you have put in your session folder, since that is where it belongs.
Of course, this shortcut is deleted when the session is unloaded.
Technically, shortcuts are created for GTK2, GTK3, QT4, QT5, KDE and FLTK.

Auto Snapshot at Save

This option is far from being trivial, it allows you to take a snapshot of the session after each session save. This means that in case of a technical or artistic error you will be able to find the session in the state it was in at the moment of the snapshot. This option requires that you have the git program installed. See Snapshots for more details.

Desktops Memory

If this option is activated, RaySession will save (or attempt to save) the number of the virtual desktop on which the client windows were located when the session was saved. So when you restart the session or the clients, the windows will be redispatched to the desktops on which they appeared. This option requires you to have the program wmctrl installed to work, and probably will not work with Wayland.

Session scripts

Disable this option to not activate any session script, and thus open, save or close a session completely ignoring the scripts associated with these actions. These scripts are used by sessions with JACK configuration memory. See Session scripts for more details.

Remember optional GUI states

This option only concerns NSM clients capable of showing/hiding their graphical interface. Without this option, some of them will always start hidden, others will remember if they were visible when they were last saved. With this option enabled, the graphical interfaces will be displayed when the session is ready if they were visible during the last save or if the client has never been launched.

Snapshots

Snapshots require you to have the program git installed, if you don’t have git, the reverse button does not appear and it is not possible to take or return to a snapshot.

A snapshot stores files and their contents at a specific time. Large files and files with certain extensions such as audio and video files are ignored, otherwise the snapshot process will take too long and the size of the session folders will needlessly double. This is actually not very annoying, on the contrary, since your recent audio files remain present when you go back to a previous snapshot.
If despite everything the snapshot process turns out to be long, a window appears and you can safely cancel the current snapshot. If you cancel it, the automatic snapshot will no longer take place for this session.

The interest of the snapshots lies in the fact of being able to return to the previous moment of the session, before having had this brilliant artistic idea which turned out to be null and void, before having attempted a recutting of the samples with the microcoscope which finally killed all forms of musicality, before a program crashes for some reason unknown to the police…​

Don’t worry, going back to a snapshot won’t stop you from getting back to where you were.

To revert the session to a snapshot, click the reverse button located to the right of the Executable button.

snapshots

Select the snapshot you want to revert to and click Ok. A new snapshot is taken, the session closes, the desired snapshot is recalled and the session reopens.

It is also possible to return only a client to a previous state of the session by right-clicking on the client,then Return to a previous state. If you want you can edit for each client the files ignored by the snapshots in the [client_properties].

With the Automatic snapshot after save option, a snapshot is taken immediately after each backup of the session, unless there is no change since the previous snapshot. To take a snapshot at another time, click on the reverse icon to the right of the Executable button and on Take a snapshot now, this has the advantage of being able to name the snapshot and thus having a more meaningful time mark than the date and time of the snapshot.

Session scripts

Session scripts allow you to program personalized actions when opening, saving and closing the session. They are used in particular for sessions with JACK configuration memory.
Knowledge of shell scripting is required to edit these scripts, but anyone can use them.

Session scripts are located in a folder ray-scripts located either in a session folder or in a parent folder.
For example, for a session being in:
~/Ray Sessions/with_foo_script/my session

the session scripts folder may be

~/Ray Sessions/with_foo_script/my session/ray-scripts
~/Ray Sessions/with_foo_script/ray-scripts
~/Ray Sessions/ray-scripts
~/ray-scripts

The advantage of such behavior is to be able to script a set of sessions without having to copy the scripts there, but above all to deliver an unscripted session when it is transferred to someone else for collective work.
Only the script folder closest to the session in the tree will be considered. Thus, a ray-scripts empty folder in a session will disable scripts for that session.

To edit the scripts, start by creating a session with the template with the basic scripts, this is a template session with scripts that does not include any particular action. Go to the folder ray-scripts in the session folder, you will find the files load.sh, save.sh and close.sh. In each of these scripts, ray_control run_step corresponds to the normal action performed (depending on the script: load, save or close the session). If one of these three scripts is of no use to you, delete it, it will save time not to go through that script.

The script files must imperatively be executable to work.

You will probably need the command line utility ray_control to perform actions relating to a particular client. type ray_control --help to know all its possibilities, see also Control RaySession from the command line.

JACK memory configuration session template uses session scripts, but we can also imagine many possible actions according to your needs and desires, for example:

  • define a specific order for launching clients when the session is opened (an example is provided in the source code)

  • make a backup copy of the session on an external hard drive each time you close it

  • send a Ctrl+S shortcut to non-saveable client windows when saving the session (an example is provided in the source code)

  • Turn on the red light at the entrance to the studio when opening, turn it off when closing

  • Start the coffee machine at the end of the session (stupid example, go and press the button on the coffee maker, anyway you will have to change the filter!)

  • Make many, many, many mistakes that will crash your session, be careful of course!

JACK configuration memory

It is possible thanks to session scripts to automatically recall the JACK configuration specific to a session before loading it. This behavior may remind some of the operation of LADISH studios, much better done, at least that’s what is hoped.

In which cases to use it

This can be useful:

  • If you need to use a specific audio interface for the session

  • If you are working on multiple projects with different sample rates (such session at 44100 Hz, such session at 48000 Hz).
    This will prevent you from having to reconfigure, stop and restart JACK yourself, or even avoid forgetting to do so and being insulted by certain programs.

  • If you want to avoid loading a very DSP-intensive session (for example in the mixing phase) with a too small buffer (128 for example).
    Note that on most audio interfaces it is possible to change the buffer size hotly (without restarting JACK).

Usage

The Session scripts option must be enabled (This option is enabled by default).

To use the JACK configuration memory, create a new session from the With JACK configuration memory template. It is in fact a scripted session (see Session scripts) which launches a script supplied with RaySession, but which is completely external to it, so RaySession still has no direct relation to JACK.

Read the information window on this subject then validate. JACK restarts then your session starts.

Working principle

Each time the session is saved, the JACK configuration is saved in the session, in the jack_parameters file.
Before opening the session, JACK is restarted if the configuration of the session is different from the current configuration of JACK.
After closing the session, JACK is restarted if necessary with the current configuration before opening.

The configuration of the PulseAudio → JACK bridges is also saved and restored with the JACK configuration.

If you open this session after having copied it to another computer, the JACK configuration will not be recalled but will be overwritten when saving. Only the sampling frequency of the session will be used.

Special cases


To open a session without reloading its configuration from JACK:

  • disable the Session scripts option

  • open the session


To change the JACK configuration of a session:

  • Start JACK with the desired configuration

  • Disable the Session scripts option

  • Open the session

  • Re-enable the Session scripts option

  • Save the session


To make an old session sensitive to the configuration of JACK

  • copy the folder ray-scripts of a session with memory from the JACK configuration to the session folder

  • Activate the Session scripts option

  • Open the session

or

  • move the session to a sub-folder containing the good one ray-scripts folder

  • Open the session

Under the hood

RaySession is really just a GUI for ray-daemon. When you launch RaySession, the GUI launches and connects to the daemon, and it stops the daemon when closed. The graphical interface and the daemon communicate with each other by OSC (Open Sound Control) messages, as is the case between the daemon and the NSM clients. Thus, you can connect several graphical interfaces to a daemon, even remotely. Type raysession --help to see how.

It is not forbidden to have several daemon instances launched simultaneously, so if you launch RaySession while an instance is already launched, it will launch a new daemon. However, this way of working being unusual, the use of a single daemon is favored. So, if a daemon is running and it has no GUI attached, raysession will connect to that daemon by default.

Control RaySession from the command line

the command ray_control lets you do just about anything you can do with the GUI, and a little more. type ray_control --help-all to know all the possibilities.

In case there are multiple daemons started (see Under the hood), ray_control will only consider the one that was started first, unless you specify its OSC port with the --port option or RAY_CONTROL_PORT environment variable.

One might think that there is no point in using ray_control since the command oscsend allows to send an OSC message to the daemon, but it is false.
Firstly, because oscsend allows you to send messages but not to obtain information in a simple way (which are the active clients? What is the executable of such and such client? …​), secondly, because the command ray_control will end when the requested action is taken, for example ray_control open_session "my session" will end when the session is loaded.

Remember to assign ray_control save to a global shortcut of your desktop environment (Ctrl+Meta+S), this will save you a lot of time!

Frequently Asked Questions

  • Is it still worth running Ardour (or another NSM compatible DAW) directly rather than in RaySession?

    Except for a really tiny project, no. If you are using Ardour, always run it from RaySession, firstly, the automatic snapshot after save can be of unexpected help to you, secondly, you are not immune to needing another program even if you did not plan it.

  • Can I launch an Ardour session launched normally into a RaySession session ?

    You will find in source code here a script named ardour6_from_external_to_session.sh. Before to use it, backup your ardour session directory. Download this file, set it executable and execute it with a .ardour file as argument, it will adds the ardour project to the current session, or create a session if no session is loaded.

RaySession-0.12.2/manual/en/patchbay_manual.adoc000066400000000000000000000155261417052567600215600ustar00rootroot00000000000000 = RaySession Patchbay Manual :toc: left :toc-title: Table of contents :toclevels: 2 :imagesdir: images :stylesheet: rs_manual.css [.text-right] link:manual.html[main manual] image:flags/en.jpeg[EN, 40, 20, link=../en/patchbay_manual.html] image:flags/fr.jpeg[FR, 30, 30, link=../fr/patchbay_manual.html] _for the version 0.11.0_ == Introduction In RaySession, the JACK patchbay is not displayed by default. You can display it by clicking on *Control* and then *Show JACK Patchbay* (__or Ctrl+J__). The patchbay contains all the JACK AUDIO and MIDI ports that you can interconnect. Obviously, if JACK is not started, this patchbay will be empty. It is advisable to have the A2J bridge running if you want to work properly with MIDI. You can configure this via *Cadence*, *Studio Control*, or via the command line utility `a2j_control`. RaySession does not include tools to configure the JACK server, *QJackCtl*, *Studio Control*, *Cadence*, or the command line utility `jack_control` do this job very well. Note that this patchbay also works with PipeWire. == Overview image::patchbay_base.png[Patchbay overview] This is what your patchbay can look like. Here there are 7 boxes: * a *system* box with your ports corresponding to the hardware inputs (microphone, guitar...) * a *system* box with your ports corresponding to the hardware outputs (headphones, speakers...) * an *a2j* box with your ports corresponding to the MIDI hardware inputs * an *a2j* box with your ports corresponding to the MIDI hardware outputs * a *PulseAudio JACK Source* box * a *PulseAudio JACK Sink* box, sound from firefox and all non JACK applications comes from theses ports * a *Guitarix* box Here A2J and pulse2jack bridges are launched. You notice that 4 of these boxes are surrounded by a decoration (2 *system* and 2 *a2j*), these are the boxes that contain the hardware ports (your audio interface, your USB piano, any controller...). ''' Some audio ports are grouped into subgroups, which we will call portgroups. These portgroups are mostly stereo pairs automatically detected by the port names. This is the case here for : * system:capture 1/2 * system:playback 1/2 * PulseAudio JACK Source:front L/R * PulseAudio JACK Sink:front L/R * Guitarix:out 0/1 These portgroups facilitate the connections and allow a better general readability. ''' The blue curved lines correspond to the audio connections. You can observe that : * hardware input audio ports are connected to *PulseAudio JACK Source*. * the *PulseAudio JACK Sink* ports are connected to the hardware outputs * only the first port of *system* is connected to the input (__in 0__) of the *Guitarix* software * the audio ports of *Guitarix* are connected to the hardware outputs == Make and break a connection You can establish a connection between 2 ports as long as they meet the following conditions: * he ports are of the same type (you can't connect an audio port to a MIDI port) * one is an input port, the other is an output port === Intuitive Method To connect or disconnect two ports, click on a port without releasing the mouse button, drag the cursor to the desired port and release the mouse button. === Alternative method Right click on a port, it will display a drop down menu, choose *Connect* then the desired port. Click elsewhere to make this menu disappear. The advantage of this method is that it allows you to quickly connect a port to several others, the menu remaining displayed during the connections. video::video/patchbay_simple_connect.mp4[width=640] == Options Right click anywhere on the patchbay to display the menu. This menu is also present in the RaySession menu (*Patchbay* menu). It will allow you to : * switch the patchbay to full screen * Filter ports: show only AUDIO or MIDI ports or both * adjust the zoom level * refresh the canvas: ask JACK again for the list of existing ports and their connections * Canvas Preferences: display a window of options + All changes in this window take effect immediately. Hover over the boxes to see the tooltips. == Shortcuts you should know * A double click anywhere switches the patchbay to full screen. * __Ctrl+Mouse Wheel__ allows you to zoom in/out. * __Alt+Mouse wheel__ allows to move the view horizontally. * The wheel button is used to move the view * __Ctrl+middle mouse button__ cuts all connections passing under the cursor === Burst Connections It is possible to connect a port or a portgroup to different ports quite quickly. You just have to end your connections with a right click. A video will be much more explicit. video::video/patchbay_rafal_connections.mp4[width=640] Here we want to connect the multiple outputs of Hydrogen to the Jack-Mixer tracks. In the video the blue circles appear with a right click. === Passing connections from one port to another Sometimes it is less tedious to switch connections from one port to another than to undo and redo everything. To do this, start from the port that contains the connections and act as if you wanted to make a connection, but go to the port to which you want to switch the connections. * This only works if the destination port does not contain any connections * It works from port to port or from portgroup to portgroup but not from port to portgroup video::video/patchbay_fast_cut_paste.mp4[width=640] In this video we have a rather complex case where the source is plugged into *3 Band Splitter*. The bass and treble (_Output 1_ and _Output 5_) are sent directly to *EQ6Q Mono* while the midrange (_Output 3_) goes through the distortion *GxTubeScreamer* first. We want to insert the *Dragonfly Room Reverb* before the *EQ6Q Mono* equalization. ''' Note that with the right-click connection and the switching of connections from one port to another, it is very quick to integrate a new plugin in a chain, as here where we plug *Plujain Ramp Live* between *Dragonfly Room Reverb* and *EQ6Q Mono*. video::video/fast_new_plugin.mp4[width=640] == A2J ports image::patchbay_a2j.png[ports a2j] The MIDI ports provided by the A2J (Alsa To Jack) bridge have a hole at the end to identify them. Their real name is a long name, but that's about the only thing that differs from the other MIDI ports. == Control Voltage ports (CV ports) image::patchbay_CV.png[ports CV] Control voltage ports, commonly called CV ports, work like regular audio ports, however, they can control one or more parameters with much more precision than MIDI ports. As their stream is not meant to be listened to, it is not possible to simply connect a CV output port to a regular audio input, as this could damage your headphones, your speakers, and maybe even your ears. + If you still want to do it, right click on one of the ports, then *Connect*, then the *DANGEROUS* menu. + You can't say you weren't warned, and it's almost impossible to do this by mistake. On the other hand, connecting a classic audio output port to a CV input port is perfectly possible, no problem. RaySession-0.12.2/manual/en/patchbay_manual.html000066400000000000000000000353721417052567600216170ustar00rootroot00000000000000 RaySession Patchbay Manual

for the version 0.11.0

Introduction

In RaySession, the JACK patchbay is not displayed by default. You can display it by clicking on Control and then Show JACK Patchbay (or Ctrl+J). The patchbay contains all the JACK AUDIO and MIDI ports that you can interconnect.

Obviously, if JACK is not started, this patchbay will be empty.

It is advisable to have the A2J bridge running if you want to work properly with MIDI. You can configure this via Cadence, Studio Control, or via the command line utility a2j_control.

RaySession does not include tools to configure the JACK server, QJackCtl, Studio Control, Cadence, or the command line utility jack_control do this job very well. Note that this patchbay also works with PipeWire.

Overview

Patchbay overview

This is what your patchbay can look like. Here there are 7 boxes:

  • a system box with your ports corresponding to the hardware inputs (microphone, guitar…​)

  • a system box with your ports corresponding to the hardware outputs (headphones, speakers…​)

  • an a2j box with your ports corresponding to the MIDI hardware inputs

  • an a2j box with your ports corresponding to the MIDI hardware outputs

  • a PulseAudio JACK Source box

  • a PulseAudio JACK Sink box, sound from firefox and all non JACK applications comes from theses ports

  • a Guitarix box

Here A2J and pulse2jack bridges are launched.

You notice that 4 of these boxes are surrounded by a decoration (2 system and 2 a2j), these are the boxes that contain the hardware ports (your audio interface, your USB piano, any controller…​).


Some audio ports are grouped into subgroups, which we will call portgroups. These portgroups are mostly stereo pairs automatically detected by the port names. This is the case here for :

  • system:capture 1/2

  • system:playback 1/2

  • PulseAudio JACK Source:front L/R

  • PulseAudio JACK Sink:front L/R

  • Guitarix:out 0/1

These portgroups facilitate the connections and allow a better general readability.


The blue curved lines correspond to the audio connections. You can observe that :

  • hardware input audio ports are connected to PulseAudio JACK Source.

  • the PulseAudio JACK Sink ports are connected to the hardware outputs

  • only the first port of system is connected to the input (in 0) of the Guitarix software

  • the audio ports of Guitarix are connected to the hardware outputs

Make and break a connection

You can establish a connection between 2 ports as long as they meet the following conditions:

  • he ports are of the same type (you can’t connect an audio port to a MIDI port)

  • one is an input port, the other is an output port

Intuitive Method

To connect or disconnect two ports, click on a port without releasing the mouse button, drag the cursor to the desired port and release the mouse button.

Alternative method

Right click on a port, it will display a drop down menu, choose Connect then the desired port. Click elsewhere to make this menu disappear. The advantage of this method is that it allows you to quickly connect a port to several others, the menu remaining displayed during the connections.

Options

Right click anywhere on the patchbay to display the menu. This menu is also present in the RaySession menu (Patchbay menu). It will allow you to :

  • switch the patchbay to full screen

  • Filter ports: show only AUDIO or MIDI ports or both

  • adjust the zoom level

  • refresh the canvas: ask JACK again for the list of existing ports and their connections

  • Canvas Preferences: display a window of options
    All changes in this window take effect immediately. Hover over the boxes to see the tooltips.

Shortcuts you should know

  • A double click anywhere switches the patchbay to full screen.

  • Ctrl+Mouse Wheel allows you to zoom in/out.

  • Alt+Mouse wheel allows to move the view horizontally.

  • The wheel button is used to move the view

  • Ctrl+middle mouse button cuts all connections passing under the cursor

Burst Connections

It is possible to connect a port or a portgroup to different ports quite quickly. You just have to end your connections with a right click. A video will be much more explicit.

Here we want to connect the multiple outputs of Hydrogen to the Jack-Mixer tracks. In the video the blue circles appear with a right click.

Passing connections from one port to another

Sometimes it is less tedious to switch connections from one port to another than to undo and redo everything. To do this, start from the port that contains the connections and act as if you wanted to make a connection, but go to the port to which you want to switch the connections.

  • This only works if the destination port does not contain any connections

  • It works from port to port or from portgroup to portgroup but not from port to portgroup

In this video we have a rather complex case where the source is plugged into 3 Band Splitter. The bass and treble (Output 1 and Output 5) are sent directly to EQ6Q Mono while the midrange (Output 3) goes through the distortion GxTubeScreamer first. We want to insert the Dragonfly Room Reverb before the EQ6Q Mono equalization.


Note that with the right-click connection and the switching of connections from one port to another, it is very quick to integrate a new plugin in a chain, as here where we plug Plujain Ramp Live between Dragonfly Room Reverb and EQ6Q Mono.

A2J ports

ports a2j

The MIDI ports provided by the A2J (Alsa To Jack) bridge have a hole at the end to identify them. Their real name is a long name, but that’s about the only thing that differs from the other MIDI ports.

Control Voltage ports (CV ports)

ports CV

Control voltage ports, commonly called CV ports, work like regular audio ports, however, they can control one or more parameters with much more precision than MIDI ports. As their stream is not meant to be listened to, it is not possible to simply connect a CV output port to a regular audio input, as this could damage your headphones, your speakers, and maybe even your ears.
If you still want to do it, right click on one of the ports, then Connect, then the DANGEROUS menu.
You can’t say you weren’t warned, and it’s almost impossible to do this by mistake.

On the other hand, connecting a classic audio output port to a CV input port is perfectly possible, no problem.

RaySession-0.12.2/manual/en/rs_manual.css000066400000000000000000000051361417052567600202670ustar00rootroot00000000000000/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */ @import url(//fonts.googleapis.com/css?family=Noto+Sans); @import url(https://cdn.jsdelivr.net/gh/asciidoctor/asciidoctor@2.0/data/stylesheets/asciidoctor-default.css); /* Default asciidoc style framework - important */ /* CUSTOMISATIONS */ /* Change the values in root for quick customisation. If you want even more fine grain... venture further. */ :root{ --maincolor:#cccccc; --primarycolor:#5E5E5E; /* Grey 500 */ --secondarycolor:#ba3925; --tertiarycolor: #186d7a; --sidebarbackground:#232323; /* Grey 900 */ --linkcolor:#808080; /* Grey 200 */ --linkcoloralternate:#d0d0d0; --white:#FFFFFF; --black:#000000; --gold:#ffd777; --brown:#4e2b10; } body{font-family: "Noto Sans",sans-serif;background-color: var(--maincolor);link-color: var(--gold)} #header{background-color:var(--brown); padding:25px;padding-top:0px;max-width: none;} #footer{background-color: var(--sidebarbackground);} /* h1{color:#ffd755 !important;font-family:"Noto Sans",sans-serif;} */ h1{color:var(--white) !important;font-family:"Noto Sans",sans-serif;} h2{background-color:var(--brown);;color:var(--gold) !important;font-family:"Noto Sans",sans-serif;text-decoration:none;padding:10px;border-top-left-radius:10px;border-top-right-radius:10px;} h3{background-color:var(--primarycolor);color:white !important;font-family:"Noto Sans",sans-serif;text-decoration:none;padding:10px;border-top-left-radius:6px;border-top-right-radius:6px;} h4,h5,h6{color:var(--primarycolor);} .title{color:var(--sidebarbackground) !important;font-family:"Noto Sans",sans-serif;font-style: normal; font-weight: normal;} p{font-family: "Noto Sans",sans-serif ! important} #toc.toc2 a:link{color:#d0d0d0;font-family: "Noto Sans",sans-serif ! important;font-size:13px;} a { text-decoration: none; color: var(--linkcolor); } a:hover { color: var(--white); } .quoteblock blockquote::before { color: var(--linkcoloralternate); } mark { color: var(--white); background-color: var(--linkcolor); } /* Card styling */ .sect1{border-bottom:1px solid grey;border-radius:10px;} /* Table styles */ th{background-color: var(--linkcolor);color:var(--white);} #toc.toc2{background-color:var(--sidebarbackground);color:var(--gold);} #toc.toc2.a{color:var(--gold);} #toc.toc2.a:active{color:var(--gold);} #toc.toc2.a:visited{color:var(--gold);} #toctitle{color:var(--gold); !important;background-color:var(--brown);font-size: 14px !important;padding:10px;border-radius:6px;} /* Responsiveness fixes */ video { max-width: 100%; } @media all and (max-width: 600px) { table { width: 55vw!important; font-size: 3vw; } RaySession-0.12.2/manual/fr/000077500000000000000000000000001417052567600155745ustar00rootroot00000000000000RaySession-0.12.2/manual/fr/.directory000066400000000000000000000001531417052567600176000ustar00rootroot00000000000000[Dolphin] GroupedSorting=true SortRole=modificationtime Timestamp=2020,11,10,10,48,39 Version=4 ViewMode=1 RaySession-0.12.2/manual/fr/images/000077500000000000000000000000001417052567600170415ustar00rootroot00000000000000RaySession-0.12.2/manual/fr/images/.directory000066400000000000000000000000611417052567600210430ustar00rootroot00000000000000[Dolphin] Timestamp=2020,11,9,11,28,22 Version=4 RaySession-0.12.2/manual/fr/images/ajout_application.png000066400000000000000000002130471417052567600232630ustar00rootroot00000000000000PNG  IHDR=kr pHYs+ IDATxw|E^I.@BHtJQD E: PU|E(Ҕ" ^DEz M$B@BB|?hngvf6anNB!Bb+!BQH-B!D1[!Bb$B!Hl!B!B!B# B!(F` !BQ$B!I-B!D12N^:B +;Çi+zQ`4ݘ !D,Ŀr ԩ߰޹"#.>g{B!rW¡CZˉ6;ݠ !D5u$-OOBq$&&YO & {l!B!B!B# B!(F` !BQ$B!:vyhP>^^=!DɁ s-\Æ d޶gn בbkNBT@UBBiР/!D6dPL& }u@1ӬCvBR{r Zxx8͛7s<,,֭[Ӻukjْ5k{wߓ{TfMtz]c{a8p]m!J^ڵ h4Q+Fw ` !DERUciޢ;vw)߻gCr۷_~˞={MشiS;w.sL&rr/B }Y}, ֣i|hƙ3gصw͛W#Ο` !D9goq!N($k r7,EQϮݺe,^B=ZWUUfϞŚ5yr~Kcٲu+Vdmk, g9ع;w[oiLJ?.o~EB!DIعc'-Z`ڵۇW_y0&ЧOo֬YC֭ٽ{w)$Br`2֤>Ikw2M@հe[Կ(U{d"6lXOxx8+FÆ qsss^tm|xw}/w}d>D;nۛǓ\2L:60wΜ"\$DGAyj=h}0lp>>Ç Gl!(çN.rBqAȑ3'ġCJad'kRv]T]Q+0 n[c;v7q4w4MfSMPm=eu&VϫNBBBw%""G`۝\*ULfF۫woF#6n(RBNtQUn'66'OrR]$BrNgV@UU+߁g0ԣXÖz_W>as`LLvK+IzyyٞAwI*og|GmYre zɦtx___:D4֭KHMI #߇ׯ[ǬY3=g.BT4uj&!!^@޽43g@Z+!^UGrSܸ,_KS<3vwqu-"9V8n?( \d;Qdǎ8tr|E#OG:u5zF7#_}KɄlvX,.垞^ddiz>}:ˎ >>J$%~qa>8IO[׮z%v:DEE}viԨ;v`֭=ī*{ᄇW#.bjEw pwM@;Ͽ0B\j\kf-oمsG=??oڬŋ1bHBCC9x06֮#FrٮiY/zf:4Gbw8Tu2ᥗ\ژ?-Z`:tl_/Dj*O=5͗:DEZj)puȂ?2s<Ƿnۖo `+7_vfՊn||IO/uB#=1..nmԯf_VF =ޭ['NP6jura<TUuP8~K>;!n)瘦i\FSt%EcT_}1%#yz(Gc<;/Z7aɢY`BCC9~Z#1 1 n{Ү}MGB!(JYf Zfݥ<+[!1NeyP78qfo C 'Q3+8LF Q)5 U=Xx6'<\ #,  A*V!)ȗNRh F #4P1MZB .?^M;ˋ[bZYje)))xyyӧO~:Xd1>ئpĽѣGٲe sիW!D9x CaQyƌ˓O *;l!( Z^XܸkAhZNWQ2ٺ 1:!=Jc}kcnGh!)ܜL=eMp8ZWޅԩ]D^zizF4fΜIbbj"5DD!!ΝOA=6#>I z/֟GMvg?fb :bA6s(ڃC}ștB$ر]8skEg͚5of䫯t)w70/^@hh({/kn%#h4ҤTT[nnQЮ]d!e!DI]QQQԩ[>{1h@ZhA6mYVi@2-NGN2 k%\K-=z0~޴Y/bȑpsal6111]+#G ==ٳ縼1v}++Xti~SSSOonbr̙3kL:l6;Dq㩚SO ff{=B(BV-őآp3q嵝*\Kj,(eu5 Gz0c\\_ԯ.ƍ{[0CǹsX,ŋx"/´iS1ͤioEHNNf8>!Dəyi+Ja4E'(3}JkMfM# ˬ $lS ]\IMM-T}͖op PA8ٳg $**/2ߺBQ`2Z@k5D1%ʋ7|[IIM!0˗/㧟71 Er!X }ދ/0#ݸQ#2ФqcN>MRr^:ڀ+~P_?]V'GF빳iS}{INNq;PUեooo631 w˨Q# S~FTf_“"ōC>ܙ%KKlB!*6 8ɓtڅFi11W㏋`-T ZjDD۩]+WfϞlw:A϶mqF^zq|,=6wwfy4JyS' wνfՒ"P!D[T^SE f/{ì3hܨ;{6pn\r%TUeȑüֱlL6GIJ@vV^CΝhxۭL BJfEzjكzu&FAJJ {F@s֯ɽH]~mMj@i{}ycٖBjfIMB`2CqX<8w>@)zk@WfVӊ`"zл(F..ηi-! !D4lOOOo^C)4 E(Uvm)Ur.ŖZ"r>}B$2t(&B!J\5Bx2=϶?^EUTaiP[GiGqZkn'""C El!(l٠3ƗjP#OGEeā'S~>7ִK=&X-jJ 7MժUKyTB)!C:u*vgǖ El!(49 /U;Zf}K&0` 6iӦ El!( U:;ilVbH8x{H$%%QjUVb0ի7ݻX Χ} b1㥗&1Nd2MRRϬ IDAT￟k_lGGzr)6l?%KX|ߟ_c^'((mNɟ2x׋ !YtQ4$ǒÜٳ]{ðy|@>\J,|䐘,?t;=ԎE~tv:u {Jjծ:~{qufRP+(^d!9*O٘1cyAeaGBrM>ÈNspLuNN6'GKO0n.%%Ot  ^Clw^~±hr}~6{NVV6ypPU~}0t0/^yHHH2t0+qMc߾}6]d{vmTqmӉ> @jհrIΞ=[٥Ol!(܍:Mf @QQ@Z9[] z^&#v7͎^t?`xW˖ۏv%==lRGwJywyWy 8gϞeӦtŝ͚xѢkア>@)(9uj&!!^@޽43g@Z+!^,BrݠèdfPP.Q(x200]wy4 xxz2{`6P OOO,3 GΝk0 r-deei&/n>|:DEѲ,]gvMcBk!**:uҧw/ H-hӦ-5k*Hf2T: `p:LQΨC6^afOf@v䤡SefN8wqÆkog@Qtdefbp>mV^{uvIRR?2^|9}_ײiFf5OQrTM婧y&޽CT7Az EƀS%J΋3PeDO1+i& EQ+*V7.fuOn?g  ʹ`[,???v;./z߾}4ov˱~}8CQRRR\inwy1>^111>%mHﻹi$?#~`_%HP4@,ϵAS)G苯 Eo0`_z/\[=z͍ _S7ÃRBeF*ECժf%Z5@kp!eZ4t:Ղ^^OS9,5;zՊREQPT;9e\gyq/ c:ٜL`@Q4777t:3YQzf3t~Yhbg{-$VZrMlÃsWxd2\=+nKanxbs9E/%46?XG$B[V͚Ld^x E y?\ꇄ^EaX0LLxUm5w! `so&'D{AT+FZz:}/8.͟OHH~1|)o){F]@R ڶiØgFd| B[na܋/9`֭˳=1]`Zpssu ^[b*z󽽽rlߘPSj< ъ*k!YH-pq{yq7.vɊ;ˬ( wq;͛7}T'V+e#11?~777f}7v,], 7wn1jH~] z=eѹ@jaӛ.]v~sN$&&r)c'99,ZKXl9?.3[QL+Q.||}\^ZNjٮώ}`0=v͐a4 5|66orÂk!Kl!S\\<~ۇ X,?~_+K+ٮSM'Z5/$'pAF#7\׏=ڏΝ;GbB#F=՚;;>>NGʕ$55*__DusiԨ!^lܴԮU epvy}q UA{xKx8uCs3q$'_:{˯.E!D'TMu*UOOԓOrR/>n硶m1|8 $'pK[8x۪T);w⡶m>|%]̙뺞b,[LyDuINNpޏ?.fSO2g\ڷgXV&2[Ï&Xbe̚ӓ^}ur1v3{J`@233ztF[~5J}!Y9Q늋آB#"z=A$M9s/jDϬsx76b$UIIMغm[2CEsM]!IyDcLKΝ:l 7oFϞ=ҵPmWVI>$=- @rrϿ0 9oO%!!Ty^~}> &"V,'55ooo9|˦[o?+-%99s_e/J=r$!'OÊKϿʳc% ||M^G>t2K,B3slg@Mx~8yMztq&^-6-ZL;[o3cDf/ !DYԩ߰Pq;;v(rEyyW^~7^vԅ,Wv|tcYk6qwwwy&--%wĤ+l&ם l&{wוb]OKթCJQp>hy9???4U-L[h]Iw~W~p ˭R[G|6!'܋UsWóSh`'gn.r7b - vX3 Fъg B=-_p8:BrEU 8&wZ,3hUK,B $XPw_l`Yh6^[43)dz__FOTot/'wo{NJor՞̈́i8l|+Ɍ\5>es#ue6>_@+ݔ_EnER7ɱֳӧ&B ¨xQp=wif 5jg/<4zX߿ΥIdOOqG=ʭuGG^{lvTFwF³O0j^|!unw?;Uj7vR1cjBEZI;m-r5[np&dpk4/3dp ` !Dj7/ ;Xh lVZۨ{]}5i(2;R:#mx}^`ɤ>uo] F7<.lw|ث/^o|+?ifjB'T߽j 1r5%ȷ/~@+BT!nըwGذnfYm6+F}i>׶0q7{su8llZbs/p2>a˝޾s߃~-'w?W@u8B>eSڱt漩'5=OYJ^Փvʛ홝MJI+sPl6vA*(VQhGfpb7| o}ί_u)q'] "=_묔T;0g\8{/|Ǡk>e׹l=`p=fBZԲKGW.5k,!9tpC%݂H$9l :dLEuR=G2K^5foʜ[F9iQe?pB7{VuxVutYzB7Ā`%9f@7 EQ q'1Gxu5M+_B!n աLƹlrZ܇+96`E|SU)RO|?4;z/4{x'voBSI}ТN B6}Pt:q^ޅQV ! xuިp_o7y e}=BrW !p$+ŊjEo64E}j3|P5_f99o<~~ƛg{kN6#%|w8c=%;[N zԹ&{ݷiEokТhoL鯘;Ù)7;(:Z*=J ;1!ί4 8BMG=.1t4ņfGY1j n~Ji4Pι[z*eK1?sU>h빬|ˍ&3z8)o Yig!Bsb > }!9qbUMv~۫3o&-` !D9UIItz2ٙXmV VG:tUf(`G![EP㙞Xz%il9\i{MSJ- ! j \& a_ %L5lc*L89z׏Uu6wΙ0e{ُaD#W6(23,[!!՛8(Y$TUю;L@У !G΍!I-P.STL+ !CvrB!z[QnfsIG!G$Bt `׭SظX&}\!ESreիˡCBl D,B x'BqS&WF B!n,yQ!Bb$B!H!D9d0uڵk[oƍyIOݶ\4l6YYYB2-吇zqůlv{{YOUUz=}YBqS(3KX!ȥQիoޭ[+H/_>֭[j*VZn:Zl7ov=޽HvA`` B\jСL7U}S?hi!at7% !DPߋdɒ͆ 4H4M̙3;+劣^MU 3{fMŠ Yl!DŦ*DNNNc4y'hܸ={&>>Bm2( =S6 H֮[ϪUپc'cƎӎh/~klظ <.׵[7l’KޣK~:q]჉ >[nc5l޲]9Ǧ[Xx ;Űé]SM'44 7C ( ;wE]}+8 IDAT ӛ5kЪukv]ʣr;݃ƁT H%7Fjv_6%_BQQ\X`Scѽ{wf͚œO>IRRjsoI?{U>p{NLzBzGJPY @Tm՟kþ-]X Lf=ǝ $$<f;d&}+yg}t222XYO?oEEEdeeOykl&0ct{.?,|Is_{{]l^~FqmK/mf{WSN]O:$M'KϞx_bÆ[[n#i&n7~u~ڤV#ņ ld^~UB!^?1s&^rqmR"ߏ)$~V OJm=TEQfQj (((wWow- c… =7JJJ̬`~>o48w8>kl>0`@6oLjj*)))q@yWbȑgܹ U+/9,Vz\fμz[eHQ~oV^xv z.25k4 {锐4~ &)~AGGߪՇ(?&M"SQQw߽6~;fΜ9r-;vn7L_II 6g䈑?49{,ӦMhՒ6LL̄0~;wn5 OO&AIӃצ#@MH$d)%.=](?a`B}Q ]t>w}7G}4k֬_~AJas9| 6vcuS`駹0ZIrxHMM%..X*ĨQHHH9,֬YÏKuwe\t?t=nzUVVrudis1sn„ p&`+XM8ag̾.2;閜LLN'o~9f4@դWF[bcQ?͆Knt}[墴N*Hbb"a[&L9眳O&!!r>v; EskKLLDӴzsÇd{5=wt}vov O*):=qZƂkiצN۫*A[REWNQg|0Py˄֞^x1e~/'V{9s0R`I0Էb5 or*깽t9dP ęgۧc>T è7=?eeekHDE=25͆q RC V-A;n)pcƪ < N_YlEQcjstBO;{dq駃@l6N'_p`5}_<0sϻd7-/̜1(`;]!5 )nM  AVN8r*0X!Rec+r`9vYMpHF,ew :ƾD"hƜ7a0se8כ7N]jce 6MZ=DYC.֛Ӛ5kZ| \EQ~Z|=*=MZddMP-bEi tp ']|Qyl8ӫIIFJ8 $b)DUVFχ^^ l gZ^\߷/7Dۤ_/d03q:~Νy1'؊(E؝^OBOtVz`\(ҪïZ9ASKw4RM)(>iYYNZAZIFFNve8V q-[X(my uo-lU#?C:R?ZbD^ڼ) (vf+Wh)qq躎;VE9[F:]!j,Ctq6Lk0SsmX.Ats͖NEQ~Iw**t"IZZ0SIvv1Uc 2y7ee?uFdIa/lRk(g-L߸xx} %N7 v;R $;SBluMkʈUaDƧِBLŞ(-XYy^t)$%i׮ ۠.Aǎ,I\$VEQW4mV>6Ѣdd4L&Z[hʈ&=\qIBW-E'e<_;p9N9s9-J).1VQE9rDNryHi3ZiZ3Zk+ЖXG2Nm:B 2$t*VeߔD&PLP7ߤr5wGEQhqfXu{i 0el#\hKK!@X g00"DJ@\(/ ^z94vvmINNa$%%qt߾TWf"Lү߱}>j+1MRb۷og֗Ν:ᏏgӦMn?\n֭[GUU={Mr%=zsNlƲe³(8m),Y";$=,_)8ݮi;e0tsV` HLv~ڴiÅ_ªUyYK6c}b0 FxaUU)Snf5M#^ث$[~66xt}̈!U5qu`3luRUfiGVEQC_?,ZTCif5̔XN>4h6cUChGɶ;`5Һ^\5"5m%ͲpMJL=v޽ҥ ۶O2b׿?YYlۖWgӦRPP…0CȊ~o݇N<~:ut_v:ߟc9xqM|Ɲ aU}* @㥈JJ/K$5 &nMӨ qzvsUFH _m"MuUΤI\d<uJŽiiiIg kIr@@lӄfA&"bD+Dk$ؤq!㠶Px8\t K}z|M_}m߻>oZQ#6[4hNSaO8bMTOO'N[4xu|g\r% 4o3wu>deeӾ~t]tz0]Wpy^ñ[4 xu)$nlX tmc&N>P!mZUA[a %A +-D.h5wYH C.bqpC ;c(q^/ǟWVZ1p/^6e|􎲲]jkWTU*/ >޿qj Ж{(-WDm܈ϩY};-zlٱH'D"gg/[¾袋?~]x!Vp]Lv u_  >Nc+rxJ RSѣz_p6=6;\llc ~ju.i۫霔b>KI'?ZZĚ)WGЈ0 \FL H^.N"YUO33ػVQm֝|mX 6mȃPcxn8{:j䔔:'&&Թ^XTDǎHo^VX9mɵP*rl 0.] Xsrr,r E"$23qV9lMӘ<2{:5۰aøO7c4|>xu1^-[ưa0p wq;?F]cO+r2 ի\w]%qqa\.3\x<*ʪGoh54c}z|"NlH)hÅfa"0Ӎi`C# +#*f4oۺ?{]+5IJ!MMI}j:uH>zg6m0hI(WlMi~-'5ڞ dD"Nvǣפ+ؖYkjĂk+Ж9 "cC&8t"pO>\lٲ?JJJ̌~y>E9Sk츸:93~j54"3RInNUz3.e]+F))᝝ױYlk^2m5ϥV JuD4p;z;fL0 ?Hrr'p<v@. aƕWL'{1ۗ. )+lf]iSSi|>bܔ,eǣ;uRPPfYe4/.* #3mZ>s^.<W'Uv ݾ(/). j5 Fa? xg9]t!vn"Z>)2)b"QFI}L&A@ڨ?n0EX-o<-Orx'|Ywֿ>//f%??4yuۑϵ]%))z =<‹ Vo6#G5+riX5%5KLo79$N'.5֠;tg G{ȱ 3rHVZ?I.Cb O;&(}{n6 ڵM{{vHhdkZH:{| A3X]mR"@XAx,nS3VHw^ktƚŶKɱH=g2hMت*nݺǕBv E92h605uO%4|n7RJ6a^"Z9駹0ZIrVuT⨮& 0jԨ:g+rxʂt~g4*+mMC:}C )$q6VNZI*u'f0MD:m@bL7M )JI]@u}uͿ4;I8*"X钔CEQaB²\x"|wۍf-*71zb)^,rOp8\}51kx<.ϟo_~I W_5؋.ܯEit]'s啭X0/˗2$6[.yl0ԟo- ZY&RX0j 4E{BZ%j#$Qu'4)p;9{(J6H׮_^k֬Sڈf36cT k IDAT45oއ̛!x.^r1Qoycmݺzt4=(4M^}p>`-:C`dBbw;bӚ)) ; L3wmDhQ'o(H)I6X[ƀh@msVVc*Cšh7\EQ1$ǫِBtۨt*#bwDHi`ZnkF*gh#Ym Т.V.1f4{u.ŠI+SlYlEQl5ʩ(0vrPQVEu0B+0Lnn2z&>EQA6k)#bKFe$bU&fMjLXi"2Zi `G#Sd^B5XنٚY(1$.uOƕiڈqy{}&cTG', a&b|aɥEQ~z}7 m]q4%ze$Ly8°Vվ6 j@bGèI E5fT)5kID M5#Z uEQE4LS#Dtr 6QG{,%DӤ EQAyH;VK80%զAX 0HADV+m3B4jѐiPiH) JA@ 5\^"bz"RRJ7E_mg@}lȴ,(&jM_.CQEiA x!B# TDBR##Ш4JL!2 V+R&7bBfTJ3@ kĔ.}R}[+((G`wpr!$v~*/:bP#8:D4BPPbG8 3V.vQf*i?GѠYU8@@ *< %XwEs1Lњ#6;6EQEQ%ր!^k1LPR V $$LFX h;_ӄ&" $i4.hн AX4DTII$&bat<)w V$ѾN _QQEQEie^o j#qsV]k KH 5(֡T*FȦGHRbJRLA)I2:P +,\W"D'CH*f_iG HչfgfǻMr\vB]QEQEu4Nǂk EWXp]b rE\iI.{^MҦQFn=2MBd& DgWI#Vp$G#LH~&m5ej`&iN:LlZ+((:q.hS6T&6 \i u$РH(丬=d,Si8$l.t,A$#x_Vǎ aQUpI+Sgj(J iZr{{[{?UIDQhAxw\4CRaXiF;g%6 uAGvR$ I!I[=۵Ȯ!S-Eiu*Ip ]׈|nq>4Rŕx|S1a* KBvۉ(JS$O,Ҩ&lzOQkԚyIH$!I$CpHC3ie (-]טЦsJCgI lnr \e*Wb/#1TV@]ven߯(4Mco0 b*7p}sIT(rhV~90kogev""HlTF콫}E1~.BVZۜvv' 68_#sxkqWǶ4 M(l6]=}dnx ].a`u84ơ('.Uz:~W_}aÆRuV.7|G\?`+4D@8̇KVS'"PPSkYF`Zs5McxgH%n487x{ {e˖1l0 wΏq ,v1;u@_gϞAEy9^{ 7n_'==~48aqxonhk=ɜ#X/« ,^˯ʗ_~+/ܤV/W]u5?^nK.3f9$*[Qfh`j)IIE/) pty2Xڟ&6͊~by8S;f4'OM6vn&>Csugc;N<#3|:=qŎE~h&N6lXeS&3u4.x̘9ɗ^ڵkaMlEQ#MRRTRB~q1L-v rC%WTP lִ_>ٞGII |>JJJ̌7}WN{oǟx?FGUVvС;v㱆΋/@ii)ng} @yy9˖/ClW_} @aa!siit}۴᨞=8Q|h SQgWfi\uջwuseSXfM3T(ʑʦaj >5!+*|8NLDu*Bl18ѥ];L"&`IIII\s=_6lχVwnn4MXN*^|NJnݸ{;lڸ4z}{^׹nF4]trqG(rrU=zzϑKS۶m1 <6nHaaa3q*VE9BiX5%5KLo79$N'.5֠;tgz{ȱ 3rHVZ?I.C(//No9iVov1Mz1Nk}."vF_VVFZZZgB OJJJ멩@q9{6/*i|{|,E9u҅nV&LW_}|:wۛ{{RDEQP LͪeS 5 ۍ@ @ii) Fxivj0E}i.Vq\U#558 B5&Mӌ]z2+P;6v_86mn?aev{+Hn֭[3x`5j4_UX~=7oob޼c FHեKWFAn8L̀8!tܹ(5(rҰl!aYn.`m~>;wFJvqDsYp|v€}/9|'8N5 <wu~/$KcAfS,Zp==ĉ:83*K/;vp<ЃY***  ;chcҤ Y$$$0o<>`n7*BHԩWobM0#FzJZףoZQ=`GQE0`?oɸs횦+=m%$^zNzzzj#BY'ic՞u~'uj\ݓrQR6WF?>EiiiYD hRv(**6=qqqJJ]؃ {5#⊩S;f^=( ˚itϮ`CN`+$V0vcFc PV['u Hi}rKEy9@ݿ60X# &v{[t_EQvR(HJIEDGO2Dj+'_s"KJ>6zZ90^xodgghB{(MlEQ#Զ2Exr* L4ݭp9\DTUQ1p.̪* S۠s,@\n.7 zڲ+2[Q1$.uOƕiڈqy{}&cTG', a&b|aɥ(`+4M45rKt@G+`;@0za@M g챔M*VE v>9\ZjuIt35cHqqqLa3}ӹN<>}zQ4axt~CN? }p~=w3bU%\t ޿?7-ܫK}PEQw'{ӧ3KbV4I G5Fo:u,Zt ~޸sIIIp8c r1=:l߾c os6yitlڴhP8lٺ5v}ןy=JINf wSEQ4EuV s6x<`'*]zut|>@3)q^/Pho~sm] ==ky?w,>P(fx,T$>Oee 6v˅N9\ÍM:f:v4x}7h.r) }ˌXf 3f^Řѣ˰躍|+?5D?0xW8c\>]Bnn.8ӧaIIIfϹ||<+Wo♧2iDzu3+g2b;(,,lp yXO r:i![9zՓD^y_c}{/7Cmyy<r˟D^z|BncB.2]iժK/:jh?_SmG}4\5_O:d>7K2c4*btm{ヒ6Frrrsۭ']a۹ip̜1H$‚ټӧ7M$'_߈=wBHNFc|mۖnN:byWIIIa5{|wp8ޭ9+Wᇥ{|dG 9N=dLE_ pM7X-?7uDv{8.l =] #>kVlp'3uL1n!y'yQ_E^~ ߖ#FZZ)Ϸ뼿~ݺu[o!%9϶my\|d.9.4o+W6(O^TU1bxo۷o';;sגO=ɣ=adMv>XC808k&NϥS.+gફf2yt҅|o?-[Nvx7yFhn]BeZsۭƓ_$>>B}Rz5Ǭ6pl50x04H7ޜ%\>?DĈēOt:yg\ÍVΦ[.˽SO9Gy08gxޞ&w߯DJ=!W]I~~g Zn֭[_9oܹ<,^CrÍ"''SO>{Ouuu]Ⱥu,mCg3O?9o1m N'+F_[nݨ 뮏v7݋¢Xp ;ݺqqu7| ZnͻokSpn1z9A.2;nQc>q۷/3Խz^߯3Pܕf#o6j.|`ok/R_>×_~idffy9S5fllV{O (ի >]lֻWO|꯱ `0݋K0ky9$&$Хsg*++0cTf~e˖if 9gexYjRJ<^/N3tcL{眜9tw Ⱥuʰag[oӮm[:uHQq1}O:vrk_(L&6o5kBrrYBMx utKJ[҅ +joO?~HHYB'N`32j4ls> IDATB;'Nuؑ|F<=ur^f rϢBqƼ m4C%|XNZۻn@R;vDR3󤤤pr|Qni/.,!W^x5űcN9\Ҡ~}P(6twtęTrssi{|l|mF<=;vʫ'Y)))䟛VV[8pW7nDNN.:t(<_/ZWڞ:uժU+WVeڶY/7aBBWR$iS&OZ'u*D);ٱcWWHHgˤ/[BӦM &pi|/𼮋/~! ֢?GICd\9!א3zKryq&5s;k,^TTӦKyuHf ± 4@$?~m?͛ya8?AAAiii< ZyNݺu:l63iTf>x';ޥYB|<1)w\y?u=tk]i{FEEZi4iqCsޙ6 /֬Y3VZmc+læM2{۴?IMi݊ OߟH223; &^_>:G/|n~mr}HHaaa@韧}N~>@jڅ еK~]iN<ɘqߔO?={~Xb|\E 5Fn4.JNJ Il" A~Bqlfb3[(pH-PawA|Um)" QJ%F=<=p.l,AJ5kYT6h@LÆPXXE bJNvGhJק=wӣ{wƌ{/' Z-םw!߲7Lmz@/VQک4 Jp6(Ey ]ܹ ݎd瞕oGGו7=wA)bе˅*22ReWE׺,/ Zrɩ4Dtݺrjy$I7x/0fh}f6q:p'$8QF)!RRpcvԱ#ڷ+Sߪq\ ϱ <ԯܾ/:_NOuLÆr}ZjO=KG6l 73,?}mؠ>қ*LITJudf,^LalJ6COdLJ>Otdt%&"1%PF] \Yx7oƶ-mg4kLI9 <#.o&''NǪkx{df3͜ɓ8{,gfQXdf Kڵ3+f3 ><.ԭS?.b~BƖ f7V7F{s̙2ud2mj˜[CVs1;~;|ǟ|BV^Ç{Xhӧ˔o/=v;}2__NO3wq*:ʯg_=j$]),(`]n1 \Kg>;vow^|m{ PA׵k]i{~ɧD),*d_9|_ZB|bgϖQBral9‘??_(%ֵ%/j1L痙7[`0gO?W^+MPb)3R$00L`SɄJ"??SѣFp8L$ay}-_v`@Ֆ 3Lד[z=sQTTT\ZWڞw9^+jC67sP_LѠڲ"Tl6W:He֛$v!J@$>lvWj/ Wm۶{OD[.I1F+!CD 빞}B?JR>c*ip9FPPOÇqղ;\lAv͛7h4m۶j?w԰~<} ]*=ZVW6xn9fp0{O\. ҜNAceHVO>|v_u^i///PQIIIgysWt+mϊwqp'lR`@rTSPemK=J<IrD IE6Jɭv9JH{2W..B)" \CE_jvy>={Cvv61vܳ׼gv3ykZA<'H}5klNOt:1  R2ұ±7lO$=٢sv߿?>ؗ>ʡC"T'p``m6Ū)8p{e˖- 8[@Hd$![9ؒ$1'k@/kel۾.HM:{~7m]wFE+p8ؽ{<}Jbٴy +WbeGGG3g7l߱;v0qe4>_J7\Aʷcڶm/?'LࡇrJ:vbpMA*)I(XpV_,ۍZ($ |L '""-[6_}MTT+VbRxy2)2sWT2t̟iӦW_ex1=~=6M``bbbOxyx-ر< z6o6|8 VID-pΥnss B+mso߁fMIVPJ·lsTߜB <<???rss͛7t.1V˒KQԄ3g΅:^VZdddжm;ׯO8TSz6Z=io6mBꑜСC裏cǎ"A^)$B r^XӉRR'14C'01<)9ЈK>jhzşǎӧOWxKE v.BvmOct ~7sƍ8uTj'O$,, 7}aaRTTTn=}9F#i5 >+((رԭ[AZZ'NG uJ“?bCC݂ BѠj9|0<% %Ro ͇2:177cǎrWH>tv?Bb.[;;**>ZмLѣ?͘_z 7?G@^nF??t:}3NroWuxAiKfYƏ@~p̞=g3!ASgbDP"Itnf3yyya:p/P|zOKryL"Zhjʫs=|;NQロn'+&^{1N>m!!Y0>{I4ӊ mD=hԸ1Ѷm[:wBRkjn۶muF_iW=O…df&&ۍNCq"%Wg8P݅tl V\ZaQ^kʲeK믿X믘fvu|>'g3Yt |_~P*3t |5Sү_?.k„~'d̙>EKs]<`6n oAA˜$5jܧ[Aj۶-S1oeKDBRsw rT*T*;ww^3ם=Jhr2&AohҪbVK^^m<9u^~a\~'r,UA u*5_AvGgHj NZAbwAa~1VɀΠYlVTBX\q pASvٻDF:M*4F*N'17P_Hav>.$8ֲLl6%CG"ANI)q:W ( $H(98O@*@%H[ׂ U lAXׂ͡ U#AAj$lAAAF"AAj$lAAAF`7mǭZ]tf *l_-quԹAAשYDF Ntt]32mJ0x< dee]q]BiպV@l6e﯉P$1 F}[Ǚ4&épq)3KHXD8#(+bR_DQA5 ?SF` _ͩr9ʘHKK/wNbt;D|||Vnr))))Sb @Q0>Oyu>bphl^CP0\ʮ)BrHۄ>] hhR?a.";;VÝq߅ N=V1 e9ڷgK vTkVi8n?/fbՊѽ\N:|>3֭]úk'Δ6lHlL ]vV_rO>!;zL*Z$yգ+eh0`ZX<zt&wmU˓O|||ߔVZEРA}y[WG~Fb+<Ɨ^l-<|Jy!yB`}=onZ}PsXê$y Di,FZ-owD4tK: hG`Vp/o VKddD5Š FB.gϞb=x5J$C2sLf͚O]*Z{Gx#.FP^=^2o5if6lsϿ^)֭l6{UqL!!!8-\ȃ}CDEEg3:u*&O&;;ݻsNf|۶9r_lY3!!!jƿ"I??#+W_O{so$I: 矓3zo1iРiii 8y}~݂ \F|,>|V C ?D԰~<} ]*=Fv-7+\^syWnsr| N'YYY>ɅܾԵ SߙڵСtKJ4tdD׫ǀHE^@VRzTjrZE߾:tuh_}|ȡC֡=ItڕnL&2ҋ,YF>zb%_>/j&B;v(O<> G-C1lp=6뫩F؂ B$P*ؠ@&Q+<IRB$)QUdl$W?b3SRPSsQ..`;ԩKll,fͣRx*-B67˽ ڋ-GNnyyy;Ge˖g˺u?eN<) Ps6G4jܘAh۶-;wAkFmv(**cCDCUoݤIRYJ9N9/kelڴrڵknVZySVÇ2y2ӦK`` ?,ZHΝY$zFr]<`=6C{o <3];d5UOA(J -""cԩш$g2II?B%ѸE<%c_`ڵW)` +HQQȉoq[JA^il?T)@^uRIbsǪCQP+z?+S2yyyu-AD؂ !ɄRdϾ=j9LTdZZAuh۸hܸܶ].t7#/Կ2I>LZjHtY ¿AC&T*Z[oV-  hСVl%N9˙,rs[.Z&55Ry_ BwU옆 8xj^ADzz:VUg5; i@hhYYٜ8GHDZRRR"/6#lA'nImVy= O>7ެS >r\j`CVV RIff&lݺHqӉF IX,Z-J9 t;cN V{}}2i֭__ݧA.B@y=?IuvT} }k1qM[8xf[oQQxAuԡuV]~񏋨SN5֨|z:w4KHAAɪ{DG%=#C޶hIM-ڬ$'Ϗ:t`7bVoKy~N~L֭XjU;f4kKbU|TTTV`z *w!5- @ Vׂ2slA6l$YYY<eh4l˺FAP`Xmק_;D|||fۧw*MVرnI|p%iXEJayQ(u:̗9mkx7xqlzAA\Q+>3Νgeڥ3l۲I4LL{g V,gْ|7ԋ_V'3..իVu:O|U+|ޛ1b6gŊ_н[G[R"+~^3إXgztVP(XgOslݺ%KѻW/}zfLgͪ$%&oiz uw@Xf5Kyso*ﯬ˻fnٻoAAJ츸&]~u637 DEE#NkR7v;cFqFHpO|mBB{`!L&up0eی9x7zoԨ6uBBBx73vC||S5V-mr9s6mzws. 4jѣPT=S2jX^|yz=]c=j$A>' ^4ﺛ3O^}X,qy|W8xcnj-HMK峙W\  XڃݠAnA~TSN|wvWNIEٰa#uҰA~۳[oiso@ZZ:`HOϠuUGek9HH˖7g4u6l6׬.Ӌu6X)?Ա#sFN3%%2{JJJO~\L{&90/;'|!R Nll,7&&&*OWjteoܸ1 cTk+LhHGft:/y#!nv,o;| #$$g'oKOOաw^rZN'3{_ϜI*56 jčLB˭m\5%ď?-fJO_r߽}Hh;}} \8q-cP(l6\.* NNCN>n)Jn7U]=AYX*=775^\. CCCYl޲岮CjZ*C?}Y嫓hK;2J̟~:u'e`j\½z䠼6.OJuG jJJ عs'}A$$gϲk.\.JJZpwAUkRDȏ S%m޲~}k3ƓV>^W\O x\XXHPpW>raa6n$6&]"""Y<0U|[R=ʞ={IMM?-^B^=/Y|o.j+V#ɳ}W {*or[n[niɇ+-+µs~0o9y$Ǐ'552bAUk=rl۲I~ ϧGY`>wգL>YGt:T}!}?.bn)>cRSXl)˖5HJ 8t(?쯾`UDGeyMꦖl߾/T* "++r(..f׎m`?N8xrs.iZL&^8CBBϗ琖$@U rU+݆T* ˾>_ڸ<* Dnne[ڶmoTxLk8:E큁6a8]v&t"/"pX!z̓8q0F"?Ah5ngf]A^^z e(J&OvѪ } ]*=ov:@ ].99pV+CٖvWz+w ̬(җ6. @n\Xmdd樅Τ Tjٹ2Ai+A:Ξ$8: ͉]嬽iݺ5aqaN:Sَ:QXPݻ~KxGYzvNA&Mřq%ml_ՈA Br:pjR} 5S1rHޖVpl_f #$>Z$QsNm>{#<ʘc9~8N$88olIGСo֬9rݻw~eMw|߿O؂P)Jyu߾6̀0rݎ鼪Wٳgu5AJJJX$GcXAоr\t:JJJH|ѫwoFaعs]^.> Ʊm2$Ih:,)J F# :ԧk pmT*zѦMQQBC +@ҏ ?`^nN&M8u1Rɷs΂n"""PTVUXt111DEEt2:u-[1o|3R۶mQ*̙ Æ ߝQ8mtPDԯ_(z i2X؂ •np8nǫl?N \.N'vt:/9pbaaaDGGqÆ Sը7QZ-ҹ^v3wd䘗Ç뮻mYYY:u+rP^WXa={/ƍeʕ>=逸p_*WT*:N6r挑-":Z׮r[:u~0J`0L&raXU n]ŧO@vV6Պ$Ijڴ/>ŀ/y>͆jNݺ ߳dWޔ'мys }! 0/]v/?EwY^KcFތ]V(T*qBίvq\r"x~_srrHMM%--"y_qq?ⶬ BMP`Ӧ Yv Cc%,_9&00:P(Z3z̧nnƒݫ׾{y={{3f 7wXr9˖İCZ/,#xyK]K~b7j.űzՊ )Bt:q8h49>?[JbA= B5v:[9Zj;S0}tIL➞if~Jݒ{&ugQ<5IZhAKb7ۧ:p\̜96n^zxR6nD:uU*cGb~ÆԝIh4^=|ztnܕgiBB!-uk  eUkT)ٲe+׭gK/ߡ}{N:MLsGHIIamݻE{Pv˯R(e3ٺm6kV޺mW\XSǎyҜ9x-)ٳȷx-7_SAA($NygO$ ulzF!N|tQ{ߟ+<:Ɍޗ3gRʄ!?NFfW̌LB˭D\)  U=3e4{v^ޞKXxױ(ۧ2t|wQUǂv IDATǿwzzO TI*@PH 4O">;JQPA>BKhD{r 1$9޻'99L*nje AQa!r%OT<=+}%4$1!\UUt?[B!\O1"նukl!C3rdk;Š8p :F#܅B!.,x*-疝ͣ>ƿU_z߷e>a\t:qq:nZJk|u77x O/OY5kVӓ f=yUorϨj+ξ}/op^TQ:=;B)Qm;*tmG碊B@?yyZn" QUj=<<0 Vt'ɵhc)WWۧiFB` ?Ji^[ۂh 3"< nRSlvMm!e/ꭃU-D4rrr *7¿碢mUU//B+^aX"A2 t=وjǮ7RTPBII9" lvJ(-/C[!jCB7dsۉbFR|P`֊G!h8@S>!Պ$Btkyh(yz=%![PTTlju/~w?ىdB8sHGŃ3f믿rq暎3jtnfnTu+),,$5չ[o) EQ… ;L0aՊ$Bl3I7Rnr8-wp\7?= M6FϐYT`m- `L<={vf3gQrE,^ a},|:od:㒥>>>LJRv{-8w#Fs.:wN%-[6i{O>E4RRRػw˖-k'EuBp&V+eSd??svIIQ1~5nLPϛlDDEAC )[oVJWrƶ;ܹ L?b9#G:y۵kϮ1;z4UYa'Oax6oʗ_I&ݺucoYf-۶sw~ ;˶;ׯYQ?v'&::M61bD,z 9g;ӵ[78ў` !+Pi+GYfu@%9ݢiF ;SeHHH͛7g[|ǤsqW;0q"E|Gg=N`6+F#eo޼tz:W_{ 'Mpp0/)S&wG~RRR0 <}&MX+_G?n,2>JccL~xUgmaVEa֬YX/"!?LzHHHqg !%%c!NTd$̚5aÇiK.%33:ij!pSF@REbA4#//r;x7w`lJnr|#GrL+⪕͉~~'xט7JI=u 5t 88}:͛u(jk8Rs!.(bbbjݚ7v,ًV ^d[!ܔ3V5IXΑ :GDi±G-#=o0&G[6|p5<<)((d㦍nݚOlp|1={ḋxx޼l(}cbhހՎնC*tmGk(^DGGowghFNJ(T.jxzRp E׻Ɨmd[Sڳ{8p$W]uFD|}})**NǞhӓs:^QlKLBC[Iݫq2-nJùьnł"94k`4 kyUlsNY}fL!$B7i6='">/mGP-{s,ޖBw' BS:;i/0ӁbT0X& f36 K(1xb4()ZTݡAD# U voCl!pS6ҽfbnS'OoK^n'_OJ )GA㚙+3Z^O!.w` !RCdУ(PZ8M U($BQ` !sPKBԍl4#B!D=[!Bz$ B!Hl!B!$B!B#YED!PksK[1[̠ih@444/85 8N[q heeNNwM !߄$BfTUCTT3avh*Z\MUQ5 UIP5z$BQ ` !eij*^ hT+札vh84Tp%^f=~[B B>ք$tݦr݆b^x}%%CrEO&M0OEQ… ;L0aՊB7^n/9~GLfw)BPϟφ^,1hj_Q|}})((p%:=ˋR燏jxzzbZ{xxp89Ν @/lٲMݻ7|)޽{XlY glR""nHQ}Y͛Cס)df哑U@qIyF4ZsuÍ7yVz'~vF#l۶Mnfڴ锗~t:~=[ѨQc,ؕM߲jdl-nBlvYf,[7|ÎxPwKkƍ$$ߨ~NMtt46mbĈXsf&6v8ׯkn8p=3B7A(ɗ>'7_Gh\ڵoG+[naӦMٿ??9 Ov ?<&gS?0sClyܝR ^(++eKزe3̟[:W˦Ymb t5kV;>mӧMח+WѻO֭][&G?n,2>Jcc՞` !rX5!neS؎ܼb~H:eзsVk6b6%"+M_,˿ ndN?LZjklvvGuO~배0*DAA>2]CBQUzw=̬gۥDD 䣀nʱcjj& B!b؎7?:?:aUь̢ݕM(wcVV[/:w$999ίjLfsrr qXhidgglvrqlv6:R) 3Y\+*2Lf͚Ͱ4KADDi@}[!ܐi*x{[o*ݮ,{kt:i4;Ԯ$e1DFFԓOu(ڱ#Fx5kV3zZ5`:}Q^^9rK,`0p!cW~gf̜=ReZqqDFFCBBÇaxsUWȎ;:ij[!zwںvu@T,fFFYFgBijEvk4<=LΆ;w'ddg+3W߶RVZɉ'z^}۶Ғx`&G0r(6uixHHMQa!fG~Xl!L8mÆ7&& Y(Qm;Wfk;xBQ!::};Fs7rtUg~}Ji//3y%Ov^!\,r)9b1ӂl IѨgc}?^~y6n8cFu<<<0THQQ'1}T/&3-|Euٽj'3B4@U5~=Ʃ>L6 !໇0h rrrСC} ~]!Il!pG5!T:]u-7 Κko3-V,rk֭iG`oϡC?}Qk瞝K/?vB& BrTUCS5|J]70~iHUlV[p8ȨsՅn[+[!P-hdt&8guԊ+^z 1T<rBԆ$B~ڻn0ⲤkB!p'` !BQ$B!I-B!D=[!Bz$ B!Hl!B!$B!B#IB!GB9/|B62ˍ$fQl7tXBQ+:tˋd[!\tp>6#SBȷ.h萄&q߄ F B,J:ֺ-GzLfF+WW_fzW_} iiWj|A( \s [C8q87x"k\~jc &=#}{bZ>RVpU꫆EI`@ 66mpVd[!\f~xTs4_XVWDIII>ٌNjLB\*FI]  dlٌiݛO>MHIIa=,[#$BzM hL&?#Gknlݲ~<쳮6kO3qN8Q_QƎoU),9UUd?駟!33oPyXXB~~>ﻏ'QaCܹq8 6. 8cFͿ| ___, 潄 <<Fa49uSBJJ !!!̟ -Zt%Ç #;!L-bE̞ cMXt)DDD)BepУQZӣQ^W ^X2RRR\/P:vƍ9~&+J7o^9?C{EQ댪XIl6Ε7k֬f1 @[v:&M׹R`po7m\zzzV)//Po7e,>>>1u*[VQٿ?i4MBFdd111DnMa;hzEF` !e`媕<3u\}i7u튦$$WVVʺuk{ƍ%#=ֱ{^;pw.:Ù"3J3{6ﻏ}cWB"f^{U2ض}̄&Sm2lgӷٹ+~ZU+Wrjlg˖iキ a+ iӘ;Yٸ ldϞ=|ᇵsW׬a֭$%%깅Tĉ;f4b} 6Ljۡ;,Nv$11B#Btt4w1n蔫k;v( [3g,mV9DYY翝/*yxx`0)TbSF#U<<<0W[EQ $//`dߟWlBY[IݫqR-ոiLF6E[bMu,jg:p8Ȩy`-PuGRQVVVmfr6iZ׆jןDD!Kb~F;w4hծjW 4 r!3B!\wGYM!d[!Bz% B!Hl!B!$B!B#IB!G` !BQ$B!I-B!D=fMt:BB(u.FnfQO ![!ܔpQQDj^_Xjo'Nd_B$B7e4iղ9))c<:+/1:!p_` !EQPU_jV0?F󨪊re&Bq[!. <'X,뉧j*l6G]]B4:EBBBCRk` !e8*+i Vi\umBP&axlYO!ܘN@O?ϗ-e).*h6a1Y(/WSVVaWͮ?ꫯq\ӦM֭xM\sMG#Gz^ !.H1iӦé5IM) F#CMphA1txzzb6[\RQJsyŹ&EA׳fo:5jlq\ߘ.ﻯJ5tdEy W[n];B\7) hB&L!՚!R ŌΦ`0a40[L鍀Rh47/ElPVVZmɾ}{.2?=x`sMӹ===Zg|BT5bH:wBX7Mɿ$ef4Mw|ɧhFJJ {aٲe qd[!ܘ`p&&0&`ԣiZRbz=z .Z;Yak֬%""ߵkW6|A Xm۵cӷX2 999tfxгW/6nXi[Ott4z?ɓ<U5kƲe~7عG{̵O?àAywٶ}1FQDGGi&F_O<9 3{6Y~=]u  B1h4Lf3:l#t+Cžٮ7\^GwKv^?ChƓO=ń y `Μ|nU0g,`/W0p n@>ٽ{7ƚL&tz=ٳg_yfݻwM7`k֬`4ȣ2g4G?n,2>Jcc~8^dܹ̞=7oAvؾ}QQQrwtuYf9LgD\$N}Jߌ3o8>՞` !t5 F(ΙiCL_zzt:8^|L֭yg0 ?v4_z~HMK:ڵ;4oނ۷ӯ˿`A֭*=pw=?yd1 !]AAGgɖn'55cǎLl!pczN(zӏ?4^Nq:"gl[o Qp{#$$yfW^/ ??M&(8U+WVL&NıcAYlt:?:[!D}$##Yf3lp4McҥdffAZ->x7$IY&zJZWzפZ@CQrN Y]PZLZ{ǣ%774vv /0edlټiFСCjC;z4 ߟ{{믿?3cL9>>>X,233 (bbbHHH v0,{q*ٱcGCxV` !/Ρ*uJt"x >^χ}e?>fg/WT:׿/Ǣ xMի?c/{_xSNq)>x}^zi#F2}4^xwSTXbᑇ[DT&NxWaCCvjnk;xBQ!::};Fs7rt5kAk"-=݆jh|T[B9 Wv4́f=ÕKZٳf:%{_Bڐ[!Ш{Fг׭~I𤫿A#-?>MH9K~O!ZyHX%ZsgNfGYig^`ʯ7gܱQ!.BStڃ?z}]ZJv^t+?Lv7ޅr~woVu/_.B˞` !:O݇r `ڠBZ҂=*C!a4 : J9}:lvWj)7 !D-H-n(-JιݹCQIUжNRfGSU ~B7 B\4UŹ[lM,jȐmI B!Hl!B!$B!B#IB!G` !BQ$B!2}Bqt4mڔ~?r(Sf$yRlSj>B3[!.zN:ѥK, Q_ V[yB643}VS!΅$Bqgڲ *fLZ͠>-IlŨoؗalpoMl!ps5 8COKK㇬,TI~U>À|%It///:Z[!ܘ^g亴ÇCuV 3k3+.[`&axl)B7֩S'WYHii){\0Jp/^]Tkoߞ&M{BQ!"2@F#mڴipjMl!pS:.]β$GǕ柸=Wb_g̤w>B( qXp!-d„ RIBMJC(((+2U8M9M-$~faVv.JF^OYYB\FI]  dlٌiݛO>MHIIa=,[#` !jވ(deeUol*mUUyӮ]{v%$Vjwh^ᛍ>6o;yw"_q۝h6mĈ'49g;ӵ[78ў$BF/ZYAc Fl̏F+cRʽ\y\ZRNl6Wހ\DQ5kFPP]oo^C?R/BK_rQƏI9jTᱱL2cFsȑv$B7u5 V}ֱYez򭵪ѾЖ.] je%ѣ^$&1uUf̘}q$B7 dd^~!ĥ4k֌ƍ%kǎR# Bڅ*'J=؉a :Ε`ٌCU* 2ϻM7iBnnnB\"#d֬٬Y=Lff ^$B7n"kg̩,"/ɵNCQy3wruN "FOOOh4zFk8}.7bHIΘcؼzB\"#!ukbcرDGGӳg/Z lYO!ܔ]7buxANGv\{UlvΙ7®Θ3f^,y=ӱm]W\gPU͛`0INNy_j*'N`[|m􍉡IxxFV;JTUfFk;X@!"::};Fs7rtg75g}܋JNeF469믏*rGm~zv;J6i҄a6[B6Wd[!XCa̦ݙMY%\ؔӔ]]K51so*=w\1^kp2mv /$BY=s2Or[3s$M/7&G! +{U!̿su<LJޫ8Vpq봴4zq?η_!.BDCx'/Y6ڡ1DL#Mu8RRR.XB\,` !eƮT;SBڑ!B!$B!B#IB!G` !BQ$B!I-B!D=e m߆kw :kgwN޷c2ߺuHE^!$B7Խ{wf̜z]\\LVvvog|ǕNeSrI- %"B!B#IB!G` !BKV::l!BqɚABBBCRk2-^oߞnݺҭ[7 r>ĵ2/"2@F#mڴipjMl!3Yλt֭J_X.C nԨf傜[qq)Bܤ8.\ȢE 0abCTkR""۷u˖J bwbbxxxPZZZm^ˋ‚W78Jc5UEQf ee՟b`ZQUJq9Ν @/lٲMݻ7|)޽{XlYG\=I0 \Í^s{~~~ЩS'JJ9~x3fd໱Z1穧ذa=_o=ƍӓlz5k/||;wlc>{ͣ=NQO>/OEQ݉:/Zŋ*͙=ѣ7y2-lkEl!nF33񧤋rnڝm[ܯZ/??]># iۦmW7ߤ~xlDnOv.#G?p-W_>sdw҅}RVVʄyy+C&;;p~ !|K)+/??<6S0f9rVBsCFF&]GFF~~>hn:( _ɭ`(RilrQM4FW_甗p8ؽ;~]vb6 qbҐ-ZвʴTrss ۛ\5|=!DJJJ".nS>Poƌ7~[K` ! y{.7SQQQ\uU$EjYGgiӦ G^%v=w^vJ+丞[V  dMNwKr29x{{ 4k Njj*ǎ#++$B׊H˖-]Ξ((8g%ξ*n]v֬YAꪫY[Uƌ????鍦inݚ}VSY sɄ/YY\ 1oJ{yLqEEFɬY6|8tR233 --C<+I2`4gZ4oo~#U;vDwV vؑg>ïJfر#F_K).*bΝU),,@4z=#F5 ĺukZ9~WZlAyy9eeey/22> ŃDv!$Bq0kߎ@B~kT:iۦ-MI–-]O>fŬ z%KWZTUe횵 p8x8ooƷ7S\\̞={,#(4ĉj>l(}cbh^?.$IBԫ z*3gomzDAAVյ@V:vɒ,Ypж͕׷r|XrT]^^Θn<ޥBz7iƺk [!¾tiV7-lJ&I!$BZvú:q{D!ĥLl!ZO&6iU2.Bd!so7^ɲBqA BK d8>{II 9Q2 ծ*}ыoLl!8g/DۻƒE#R!TD֕E$ P P*`T $aߡ@@5h$@&$$1#8 0Ʉy=}̽g 9| ߝN: ےl;G6JkSyY܎```8֦\D:C"""""Nl*""R)۾DDS-"yIDATc˖d\{ȭG5""Z-_0DD uXW ""Ulz 6dWNSεiݪ%iӺC֔`~$X;8;TSV-vPlp|O%"r+6|8/0lqmҶmb6lHVUdq*$McUH"f͛珻;[vu8S-"m]iԣǼªҴi"CC‹CSN%&or۵jՊ/dҽ{wƎԩ*$; [V`2>l8-bE VU-"bW}wo)os0ʞWooo\Rݳ>Gl6?~1xxx`2-bfZdZ9h`oesnn)-iL{֬Ifff&d]BAAqqqFaJFl6HU:wBpP7n0 BCCYC ٳ߿5kָ8i[D̴R7na] GdfdTڴne_,Aׯ6ݻw-[gOG`Bd5qgtޯle̿_ R%K=.vwA|Fx;wf͚kb 0-E;&oI|6lv{@aBw~F }%K a-ٻqcXm:cs˯b̛wu[={ a˖-ߏɓ&?N_9|-VED];wҵk76mR)Z3صk'&L~*}|&Of9l۶\ df1rGv`*<ȴݱ#+W~ xGҕGЮ];MO#nvf̜Ɂlfi#0Lٸ1?<E/>ԬYE=6U+ЇWl ~XԨQ#v<Ã( ̙3xyy l}>gey.5K`1[xGxy(^5 >t}iFbE*7| Yl999趨}cȑ |Xsȸ|-ZKrr2!!]YnmvHgϞ޻Ջmڕ]o^^FIÆ n^0 l6gWwwwLKl639ʼysKױcc2t0֮[Ͼ}N:N^cѣ;v$==$իGff&&'l6o?3}Ҷ];Ν;[Μ9CTd$rsrX0Ac3<ڷo֭xuX(((`@~dX3XΛGеӟW)E%?O@@ \WܲV+|55~$%%qEW`H|2SVϧsYP?}w ϗC͜9s|2 M5z*PAJJ2c֭XV9Rv}KXpk׮b;DF 6d޼seP.\@zz:S3{6&MfFPppsꑜSMyJZ4oNj"#xo_ `\JfHΪ/H'O9|8ƍqQd?mVZlAXX\ {J[33Q"ؑCe 8ynnn8q¾dbalݺD~̩So3k,ԩSͽ;SF Ű>a?~V={ǎ燛qdee_nݺf͚ѵ[7piӦ2$rj޼hْ~}!b`BBBٳM5sux T_6 Q_8Ws>4cLbѢOHHH'b[oٺu+O<$w(f̜ɓO=lDENp8֏>ZCHHoWVl޽{cZرO;ƍdwȸFŋ(Yt)&+WQtE^5Pvm6|iT(`!lʾ4x3<==j*^ژ, ~pʕ"d2qҥ2cߗ/_.ul8-!9W..#VDD*\ݠdee!sO7|ʛoI`ݪ0 Ҋ%6톓k '\pԒdHKX,ZZWM&ZV7/++DGx!x*L^m!ez_)!NEDDDD|EDDDDDĉ`8l'R-""""DJEDDDDH )q"7W """'D6]C%]O\[-5B{]YUKVk&v6ӥ7fDDDE:mgϒPnIhxG;l)]nHIM%5b%FWեn@vQ|JDDDDEjծ&$ez{&5`踉#55:>7(Vy ǦS H5yK%"""nJR-""""DJEDDDDH`qIH+""""՚pql.-""".941&B }&j@ҷIlc0ZspJEDD]wő#Gm˽5ޜ;c{E^7~|E\!*^Xӧ-'N+iiyWdg_%̙ fz)ۖ3gjNN y饗HLL$%%-[1c8u5j$002Bw#&ȱmӚ 'sOs;m/{'bDNx?Jo>s?_@<==ޯ̚7󉌌,mΝ=z4/Š7~#L䨒5\GXPX(qn//Ga,{].O>͛_hޜkVKO,]KKfMbɢw҅u\[yo[DDD<=3{6Yٌ;6m8\B I^^'mbƍKpp0'O)8̣ɯpiLz-P_ӸIr cl_m=qsدӳD Ɠ}Èa_3Kk<<O׺tчyq,7mfr4l؀(``Đr%""""[#2rH4iR䜧sj2axbYj֬5#k֌ jլim1bmڴa+wc(#sh`y`a2_4i܄㎆ a֊Ϟ75y6}"""r;K¢eȰ$}-^^^̛;4"'F'8dz3pif͚ӧSǧNŌ).a=m՚Y3⾮!O!18I\Y7Ӎc*vm.a\7OOIOA;;vRzoϞ=ٽgCU}Bgΰ*U&:uꐑP\:u&''5 1_Ĕ9ߠlq]pUz}XMmL0ԩ#6'1a;~~~r2D^?BaUgon:vP ZoR)Q;w$$Һukxcƛtg6p9V\}XS<=c?tJEpÉ'ux{{7G0hZڷԔT.^T; A:ɤ,}$)t*}ڴWԩSХK*OX*bt'h"WϞ97˙8%uʈ$nrJݭ:Qb?# %2 FMn޼ WV nnn۬GѠ)..W.]_c2YO nn

ӎ}`0XgG@$IȈƍ jْzoKnn^mBIK34J_S2o[@ܪլs¢yC6u @BT2ad oE0OBBBhc~}ĹoٲG??G|[+m)2]iԏŋT(hԨ'yq1cNFF|0/R_'OʌŅi_HFT̙o~o#.ᝉfq1Lt:&<,gΞ%55Y]R(Z޹GG{DQ,4<RL=ooolNAh44 :dVZDvvN _eQTxyzRח.,dC؅>G4}+\έWN|˦J.,,PTp꯲ 2uzK#S.D^P9Ӥ/FYGMU_!Z؅ '=vt] 2`.c4J%v; n[;7)rv%U-B%Z!h!pPAIB%Z!h!pPAIB%Z!\-ٙQ#F'Դ4>]PC-697f>*VY-FaP7 .F~͉'+@ϰ09j$,]VgZOuz,B&~Q H-U 2!좙 gǏl[ Px4J* R!,TNuЁ+W,ذaٻ zI޽xy+'XR ʕ ,eWhhޘL&rsrtrܔ?44RS,sU]˨t/Gk|UmA:2u ݺuJ6:ud~=-g42?ݝW;א_1QQ^ z>{3qxvٳx~L& ;j4C]h!*t<=yr]pg<={䓥4c<5rEV3kzG<$"5ǎC/Y;R777kc߯?k?pjjIn9r'/?[}iӺ5ώ~bt_Ts8q$?Z Т1zz &cr ό~}[7K,\Dqq1ItT2q-j'N9Sj]M4fP@ۉ3gϖ֢_RRtFrr2^^^8VAXgkI^>:RL۫, mn@&kT*FQ|FVKNN7o޴(UU } }zJIqq_MrF8iWY '*h5=v]+Tcǎz9-*3^.^XXXf0"`S~Dޗ£ *m+_)uؘhv]-JFʙeή} .>]GA*T.5%+;ժQE-W+TN4 k^x9E$77jHva4XlY] 2phJ( zcG;T-_UIvPZ\޹IYsdW_7nܰܭ>?y!pPE?uc-JB8( B$@ ! m[mBɷ/WڼBm6UN_B!*m87Le8\!D͓9h!pPA??gڡ]EIENDB`RaySession-0.12.2/manual/fr/images/ajout_application_infos.png000066400000000000000000000444711417052567600244640ustar00rootroot00000000000000PNG  IHDRdp\ pHYs+ IDATxwx?ٖ@B"$D:  ,vz bg@@zV@ibZғݝs~$H zy̜9̙jNP(lW@P(^ + E=A BP,%7L&n<[Q(}H ֭Zv$O) 111{nk(v*1V(3 .P>dB'(AV(zdB'(AV(zdB'eY) ߕ wsxٮBP}sL]!BrߘFDXDjpP(uBdLMR &M BQc꽲 mbA 1gZ BQkA ңa1H]'IzGVMy Ea1|XFn}Q7&2EfJh ueK$/l;%1(&`p8 A3|?4bM,WNYf5ZPYf<g7 fj ش)g9rϚ 2Ȋ6N)b,ue,KDax#2YD)h$!A*IV(,OΌ`Æh +aCAz-|Vn2ѧA+>Խ#v^1[R "7O s靪S ɚ;  =[oGJyR"<ʫsĩ[~Ί o@Ʉ`R3^)W} #V,&B A!%IP(lj6:'NOBQ3pQ)Hhj)/.1y>aו!AѤ(!:R>_D7EG ,YN'q8?_߾|LcR-LPTMӈBDtv22ĸRҠAh!1YJ4<+ u 麷C/@Q'ƚJXlH!pꂔc&?,_IO<""iݺqqP3BQL&')HKs4Ѽ,^٬LhF\jap "һt;EI1Bb,@b8!N@|Œ0b7&ұa#9<,`ȐX3[BqX,f mB }YN&ފEiBw[с!Cށ !a9)|amRޑ-;;0,J-ui3cCHεY8fǙ[u!yڵf͚͞={(**dM躎S a/TXc󈌈ȑ#l۾Eb"aadff۶mfg߾}瓔fb]iӆm:hADjj0FeqǶ~ wDHw/l1^v Cbm  (ƚЍ5FgxsvkII[`Mm:3F 5jD ;Æ/0qx, ={q5sF2e"? 7NM{cϞLs*=zt+Wf>M4{5sR†|w6- _73g9w{7v<)pYEk!>Ս 7BO| ?/~ص$H U&%] u>uֽ вeKRSӘ\ D.]#55- nlܸ ]O?5v#_} KLL`'Z|>vBǎܳsʫήQ4FsNvo~MP)(ԁ2O/5r'g( ^8b#bKL$㉋{'/a (Ԟ},q2٧' nX1s݊Flr Yn=#xWҞ8c%77aCѣG !2]:w2}XV֮]}<koNJJ C ÏըV>~ LRKb|_I gW|?JDR,#<ς S)U 1hݺ5l5믿8/%9/7l0 !/SRN,PbP%B0,0)$ vMcH5icp8B &44ǃĻfL\/ _ϚL#h#n)8?N~G_paÆtލ͛Nfeq8?٥ YY٥ycsrrggZi= |Y'ݯP(:dfWx׺Dg/fxdhm&&!]p594i…EDOfΝ\"jrۺu+]:wQ#Yb%EEE3d ?@6mXb%у v3A2[R`싀 UDf¥t+B&פޑwFJϲmlL0ΰ)!bo&+$p~ίAfܵh%_泎WY KN 2<6n~#KbbpeE 8p7ڴ9HϚزe F`5Ws14ڷo?[P])'CJlٕ BftII7fi16+IFS;vJYCvɒ_x1F0äSg8fy6 ]^^n7C eOp$CpOy7)**;ҡC;V^]P(jUvFz;?Ymm R`Dψߠ o\Gшs2cM!؀r2'ccA1zڂil/ƕ,œ+%+e!h(&t:9v^$22 Mc2 S+Onm@,4``Xo I㈥ȣ&8bak%K9ԋW :ٺ7Oob ~t,R!5!++ϯ4GV EP.vMl64: 1>Ro[:??E0{G VR"%d Rqyb7YDm݂SXVP(jZd?4_,h5XJl\EBG .x%|4Jg"tQxS|!pIAuF${TtB8]jU:BBme*^Cd]t,<>O)dݼMZDÛ {=J1,c?m4 vߘnXE  LPki\WAK{h!Ғ| oT. ( WB7C]iHI+wYORP(UQk|Qp(NBkf6rC=nA׽. !uEO1nj2ڳҧՒ=rb%fB|2P4(+YP=jECMf:}3IZCBcv\1!ttB u㳮}>R$ I##%O|w 7%,@ڗ* Q+|3 o6'6;D:"ȑq!N(Nǃ[\=GP$?At,iAޥPVB8Ü k@?N Aα|< M'􄐾aœI)p CRijR1hy>ާExr|F/%nB\xHҤCT4$sN<R(3)eb0( D\48S ҥ C 34Cfd.W(̀CHRKuA] @Osls}m!ֻi 344"JD,).6 Y&P( $f48 1FHfgꂃAsIR6yb&\4%$D IG'#}Vn12vJ0qߤNSfH "?N3LKCt)Y?'R(?NIj&cR]7?R'/ld f ;m^Au ӬiʦѤ ARb`k]BR#AAၿWiEFBQQ BQOPP(% BQOPP(% BQOPP(% BQOPP(% BQOPP(% BQOPP(% BQOPP(% BQOPP(% BQO8%An.={5lذV-ZhAJٵIpp07xٮ_Ӧ cZ+Mh. ժF{y婙OGJJGaA@z:qmO~UޯSgg? cknբKWn gES?~/Æv4^\ T9ѝCۥӹ}8`)Qx񄇇3bWpxp78Nrrr}!!!!e՟N ByeSTT 66ɓ`%$$B#dpWWFXX(yFm6RA駝L~wZL& =n*<^US- g@4-7ᠠ~ٌ8K.{noO/1UiJ**y=Ӟ%iJrAHNN?IƬX*xEmXO&mۿ(;T_> t:ILH`׮]@@Y!!!e.Z67n,iiieJj rrJ2Gbk,_S3$5-sAhRɣ<*,N=6mC>@bbwyh[i{6,8ukvmUچaaYC }z3vM\wލ{+طonr٥0͸\n8gOz͌:#Ӧ"dγsIjۖ'9v822gEwAA}}dRZnC>@tTq7#dddr1ڵBM j,RcȐƾ~Ƒ#Gh߾= ;pAz xh.ڱcǏ0ðC8v'N4i"7-[L~۶mfX<.\@֭Br!Ѓs9v8V0N86sI{k׾};BCC~dbx<jֽ"n޻o3'?vψØtD^z#vpXͳsjK/ѼyL~7,_]i߾=[dYW IDATо};^~:tG> 899ɰe4&SXT 7w7 xf<Ͽ"s{ 9ʰ+ӄ>dt!W/\IINbs/UfI JIIf-ƛx<, SLa޼DӲE rss `mGضm;'Ǐ秝|kn8NV+jr_$~ڹӸq:uV 8?^@MILH =#r^ ͛cyə\.7|N;8Bpr}ZhALdeej\oŗ6[_JE}~瓛3xx<.3HLnLhժ%}07n.=}D6lHaA-[@up8K]/xEen{1cǎbޟ +Kny@qEm.%Ÿ[nf޼l߱øtv*$&&0?yQC6nDƍ1DMq"eg%IhO>Oӳ甩Kyuv)SqĄ4Mmlv) _Gdd$gEF{=l2e0ӧ?cv* J[-%ݶm[NfeƸ7ѡC{n6mʰCcSOo qxf$'_@ZVN^n'Qy_ݻ+/t3>>gpp0ڷٳۻ4)))].`M7Pimۖw}HߵKg~'58ޥs' 9x'>>ǎK> ͛7nn\tAtt4111* B\8:WԴ߯miIJj˫̶mrYz2M+jHNNf߾fVѻ _v)Ɇx;K|NM%1!ƾ@NNӡC{"##2yAJIHH4kƮ] iӦFiGpQHh@b:vTuf|Y,7n\aݯ=Xa;4SJBkFRR[Ǫd}F Ɛ:m:oHPP^\r j|gakmP‚J).:wƷ~&44{l֬d䐗~dBBsNfddPXXH~/a\\\޽,y*+t3;+gPP}BӸKJM WP4"#"p8uL2xu':*ɓ0\%Cs^Fݛ^\;L}k,DFF MN暫2ڷ]x-Fݯj4 6d%#cǎqg(%&4'3V&5SRh.7̧͟&%%|ogE{ng̘yyykS39~8Ǐ '7dҎIƍyݷˣBٻMt"_ iղeyt[t6=<.S8NQ]Ql6[K 5o~AAA嗀/[n؛o%''q>1gγzjwvݤiT:ltDGGӠa?}9S&o#&&Ɨ6#Gv:Yv˗`Ls*ݻw'd< k:߆f2qQnilm]u+2prrsٻKDZڑιPJ%K5siidggNfe^7dӳ8vf޽Fs`ڵ+֬"''éL4~1Yسg/~K>!==?ڐh̕~?v-Z[oj2 H?ΤS)xq4htlV+~x?RM+VmAץz6P-[VN'YYY,[?#$$&Ȉ ˄f"""ʼb!++\wx꬧24M#*2Mvv⠫{~Mک:8Nl6[oNJ 33L;;V+Y>q-22JcyˣN=]Fffemk`jp8ڲ2)((rͩN^^^P3P;'`!^ \ӪGӴgXX.;UUM8u?lN!.(** =T\.nl~ض<N^mjil6^~jWH)+=&T+ ~ʱuYsWWֆ@Qqp 5ɻg$%%+6 ۍ"`pTkZɄ$77Zu !//)eՉ+k UV+]2L&j׹2 řV|Ƚ.U+@x֯]C۶mٳ _g <8I&gxfSsM@9VZ2x@LAz O @}Yl -37hЀ/K|º8`@tӍ7~j~<֭l+{ӍU|AFssWϰP ֬bŲ%LEEE9v֯c%̟!IImڮM6v6mXvue*3K-6meȐ-[W|f^A7>{%::Ok(LBqfEza^}fmݚgJN_s p!;(,vt #^x~.6py5~ŗ$$$oGpp0?wLZiۘL&Ə K~6oyᅗxYf\C_zz~֮^E^^.L^ç /أah& ,CP(,Z`NwL5M#22c|$"")Y˫0&6::,xxx8BiDEFyd~f3U+nn*N]#$$!;, 99ed2NfjI+[n|6}U!4d7?YYY曞^RJ32*MG*̬~HUu-T!8(BQɅ YP( J YP( J YP( J YP( J pʂ"1ڬBPOsJɫpT(Z/cY|嗵]BFܶmzݻˣg.kd7*W_I&t_xM4^0jR(6iD5kТEسg/&^xVG+\s5|EΝXv]}:9u =wc!UVX,u;i_Ϟ=xHMK`]uZBH,,wM͆M A>q7W&E b5ſJI%7oW/CRRRB^^^ \"ҹ|-`EYXXh\ +d2ɫ`^Gaa!aaxq{A6or)OoK箻Xr%..7K2Y]˖p9Y3>tmڴ1lӦ ֮6v;=kWbՊe<7waaHL+x7[˖0އ$%5W9x`ءX8Bn\ lloٲMv)|4cV\@||V!Opvv:e2[2VrZfI&P aq${ rs7#F]foժ q{Tذa#͚6%1!mg> {vlZhő#GܹsQoN{{? xUC-ӵkj׿tQQ>={п/+/HpBQ;B^ju>hcŝ^az 1|5jCtt4wMf;r)uF$,,5W`:s{ÇSΉ P-݆m p1c%ҔnL,eH[\~٥$$7Vr E58ckeff~cpp0f8.d*.=$IjS*?##ԴTOuLpp0^„'qKӻȐ2mtaff&1zll!Uqy:t+ l6cZ?]NN.M76oF2+>J.^APP_~i5k2nM^?6''ȨjNNN@i٢35jV&knjU4p g۶K.coC_Y W^õ^cDa :;۸ڸ<˗._=>HvvNU͡P(j֪m;t~GSl6ɉ'*L|f+W ZDD8'+ Fhh(YYYF0\n!@2bx5M#22S'IVVBZO6,Áb!'UbJff)[P[n|6}ȺW*@hB22*ዊ*]f_zzz2N3!XUuDA*Muڸ<<cQ!+ E=EYrYB7UANKr Bw@, YP( J YP( J YP( J YP( J P#An۶ m۶)?>>9ӤI:wt/]ȘZP O8x͛׷/7\}m;Nṹs 9XxBQKe0V anQNxSv VDEEҥs'[ Pi%E׿Z P&!-]B{j,4jԈ+4]:wbYd1_~j!CxG3i/>[m˜kfՊeZ}Sdbꕌj>l[2J^IDATleeVC2bp;kW3pByv3[]d憶<|~˗-aIJjkuiSrjӦ ֮LBq樱 Ǟx;DÆ 䙧g1gγ0#Fѽ[W\s5f28&s-7ӡCNx<\~Y7lظZGeٸiM4 [,2UVӽg/V\ p88cZ(nyiøo>7sfz@,M& [/T(g/rj1yK2{]p'7}ɓ'y \;GHp0[nrn2V[Yzݧwo{}c-{? xC-ӵkj׿t qNYfт 8]/^?.66cG=r(QQvzFFq]:]ry#F$,,5Vfã}yCpN 8'::#Gnlrрs=FtTTu(.]B8srrVVwMt323 H06%&k _Kp$n&n&f 99ӻ233.tpeffpNll!BL 4KR(i Yf ;wf̘k}_~39$$ѣdͺuWӿ׎SeLٷ?۶m'55[tF6oFW^yEUpÆd2}kv .W({8='](&D&C"[jL4D㎊q7¢q?@\4" $jPKE,R q 4=J:~=i퓧So׮;599Y;v?xFѯ3uTv]v=32r^{o駞 vWoF`;wn}^u0ھ}oܞǻ?7^VG᯾ӧ4Hz#|:u ;e4rd7&d1ff.W܇kfzgBxmٲ6n|/]4]'OWZ=/@V>n[Uvo 4Jq\ a dyvv=revÏ>6wj#6ʕʕٹ;v@C!!{LCIENDB`RaySession-0.12.2/manual/fr/images/ajout_executable.png000066400000000000000000000150651417052567600231010ustar00rootroot00000000000000PNG  IHDRW- pHYs+IDATxwx&NnHH(I&(l"^ QzI(E^;V @hһp@ڦlGpILY3sΙ3|3眙ݣjO3B+BT,B($"B,B($"B,B($"B,B($"B,B($"B,B($"B,B($"Bvf lGeW^%:]:wFaܺom5ƨ׸`zdu6Z5kgYzZEΠW_fҔ2 ///7kmph̴z{:XV^:_ff&cO"&&ddd(*cG ,4Xd2[n2~Aɑ۷KގZٙ"hZFz,jˆ?_ "#mZl ?kݒ?۶lbۖMM9|ٺy# '{7FNn]ٸn56֮^l`:|W`utֵ}l޸KY|)4lXhsg`޻{_Oqyjۦ@9ݻu#Ws~z9{ڵkW@?d;llRh 3q8Md/xt^%mLl th*U LrV͔/}||`J2r0FfO>`0PNmN wg%={19t*&gܻKFF&/Bff&BØt}SN홳YEcF:Qnٲ~}fՏEWn*9~$WV`{ :hqVssq= />%-- N: }GQk4ڽǖ**)UE"JÃlK3)/wL&3!rwww.\΋de;ET*$%%xWOOҊ|.@Ŗ% !"B! !`B! !`B! !`B! !`B! :{FeX! Hb,d[ Vn.!|;PT~<נ$|eX o$" uhkTYPHE$XPHE$XPHE$XPHE$XPHE$XPHE$XPHE$XPHE$XPHE$XPHE$XPHE$XPHE$XP`1^H6e]g{s6avx ^m?)Dy0^;Gqm E I I I a;; -[­[l`H䡤m۶%6.[岽սֳ>4jUeH3LT77Wnr^ $XDŨٶJ QAb !`B!ۆf~FʱB7E7=x|+*Sn,$T֍yZlj=P@}|+ښ00'Dy ;s1a]-o2Phd6kW};ꖋ7Fƭ[|RsuuxSϐo]-i22rM4?L&K7rjmΡG0LVaz7 1lcǼ ?oNcú5bzꉫMe(N5ҿPE 0n{wz=?,[Bܩ#3ߙ?f)cyxkz2Z-.+KJ KLgooOppPl8ݰֳtʴiaڵ۷-i4 NN;99iwTՌ>#G)ppqq!--zX|JZZZtԑ[rB *{ #,4pDE]ϯ/[wԑ.Ҫe EhOF%''4p:{Z*3th/˖ҾClٴ͛c2֬[73Ph4 z=~VSzuyYb96wm:::0vukXl,._mӚ?H%D_KEMMKO>#t Mc6 4_Lj-[ӫW4Ŷ;ve3cl:O&Shs]V3i<=1k=O -[At PYӟg?ÓtdޜY (O<4Zϐð z?$qqqiݚ+ңc7 N# V~ :t0L%Kb3ؓ0QFU?q+>aCfe;_{;;6lgIVח>b7+##aөU&_Ii: F52;}M.;0>p3gS_`Cmz ))+tJ\ ٽg/!r!v7.!99n)ʗWv툉`0P^=FbchѼYuh4L&ޙ5OL3c6S'--IS1lA:tEe0˱'HJJĉ%dWsb+66gW  myyyW|yyt^)Q|RB'W0GѣP^=fzÇٰ1G{bՓ7N(v!%CY`.iϧRhټMRnrYoب(mbb"|˪W&6$`HAqJ/Do`ъ#o[B.x0feg͚utpu6G2t`tD||QQQZ+E>1)1{x}6R7Jc e@uv0YDFnGny=wS^s8:vu:/EڳwգkΖe>>8(f9 |yrjiҤ/C̙㛘đG >'3vdeyU;Ki'0)t*Sæ`6qqq&bs$+Vl6,\07?q2{YפĂ,ME~ěزiiddfз_uM&Ne{wAC,qN9Ok23@0)l0Ķ;Ņ_a#[\4Z M_+-cRG6^U*$''i͍Btvvё|ezeggRlgggHHH'Vҥ xti݊-i;l:S/شǷ*Sd];_.0Şogxm&;;/gΖvKbS3˪j:u|ӺM+AjWKFDR:paIOÌ0s:e*x3cYy_SZ^lEVӵsGLf3+6ԩ3?qgs/ݼ?|ˌUW!83etNi֛L&;4fm۴իՠNZQTYFIK4 eTɳDХsGٹkO .6LuZN+4_` ?_3;K'1s6 g1ջg;wa=|<,_ ~9—Ѫes׬ Xnؠ—Y>O+Ozg4_|ŧm݊~\G,To֪ri4tHvVvU4+wf5d2ku A ݮ*.]@.^9~3fκ0ʗK SbyzO~y'[m{.i,ҩ Jg#|JFxV%fZ Z}:]׶u+ӋACaS3*ߏO>_a+K7T;K&qV-2FC1ڳOWBeeg33upuss`V f',Ҵqc;%3$aHI RRhӪU)a݆oc6QT N]w؁ͭu8w5kٜ۷zÏ0RS{ҽ+[];w vWaPшCyr˔y..\/^TT6@!˲c'Pf3c'N@CD?R j"iB!ٷߒ.!,f9h4#Rn(:z__v* sN9pFLTV*m\x L]NZ6oFZz:{/󂤤dz=\η\R[QcV'NJ&U&Lj v5bs$>w'03g¿ise5k{;{^2ܲӃGqVsIŭ7L*2mRR2.\_XSH*UeC3^tcǏӻgiiٻTr]+uAQf $99N?7m1,#gϝ% v*|x7Ec2K L*uDnddfqSdeB֭Z>_S ֭L{#&fMͨ*2펝;#$߈\ZkK CJ qq7~'iؠ>&';ZMLl,{yRS /ʲe7df33g%lDΟCU\?Lf34s̜=cFvmyuȈ"6EK/p&_~M Jb݆ .4}S6]4]8sæz^~͚5OHqOVcggGXQz://D;tiu^=Bz+DltT*INNVT/F;iddd0:wUd20l̆%l.ܫ8999~qݰs>9eǶcYiQHTvrc);7t,K{7쾢a.;KMCr+/r+,YYE(JјYweRS xv}{bHIV?1[L9aȍT[߯ l6[+V <q. ʏwlTy̫&9Ε  I I I I I n IENDB`RaySession-0.12.2/manual/fr/images/ajout_executable_plus.png000066400000000000000000000450351417052567600241440ustar00rootroot00000000000000PNG  IHDR([fv pHYs+ IDATxwxSwFӽwKٲʒ]Y` {*D("Ȧ̶(e#B$6mR <}s=I?9^!6~oy f):CBQr*{!(Dy f)w(PB%%ZPB%%ZPB%%ZPB%%ZPB%%ZPB%%ZPBjժɲWcQ-A6 wڝR:d0 |eZ/8= AmjQ@f>7\Ãˮ{,*JNNv !;( 6եc5,k\SԮe6lmmEכ, ۑYvJ%YFcQݵ9F 77W ߱Zjܠ>k__} ic[!0ŋ;b'#v2afΘ+ݻlgWvWFH yg mZbM :(8 ݴkV;|eR˓.cmB֭|Lx[YzkW#-7kR1!Ŀf͚kbȑD:̡G3j$&}&vΜ9Ӧ|ȈQc9~kbɗ_'aS9 2 6j5*d-J]øϨ(zOrr2~~_͡[5mJ~ogTTCƍr$$$ҳGwO._)?6n-*^TDF ?eyxf *oqFƑBU!..g~xzu} ! *,<Tff׬a58內{X66.4<=<<<᩺uդis@vN7mH-5:kSNm=V1FM\qYJ6ṦMaBꝁo/\%)))TTOOgzJ"HƎȘ#9`M7͘ht"|8ȔizZ~)B7ÑGxqҹ37#a_Wزy?;Lڵl6[ ..̜9WzJ,]%8::r >PRbwRݽ 3@JJrWWW3ۮ:]q+yyyEk) jΓ7JE7`o@FU;q_J!#A !jI@ !jI@ !jI@ !jI@ !֝Oc盳 YB(sHb <"x!M@R@]h*`0G79c8MmQ zE[Z5qwsCo0Mr23!IHL(U='''أ34u}?NIVV>'ڵk:}^ol#::WFڵpsu豟e|B]PwAoߟ8f9 /:oǾ 777WrrK]rJ̝3;vi&>dћ׮ѡ};Fx~FPPf ]6Sr%gW7Mh43\\\h֢5w8[#Je+[ @HVL4}cT*I-t1!(J |l@9::nj;;R7'''Ӌ=yfEcf ߏY}ζ;T*K.OժU-7ٿ3W;`hll Ϗ5߯qDƲxX{6oXǏ`J%*Z.[6@]߱ kWs:ogܦLO?bͬ_xHZ\ nPЍXJvl mH"˦Ţ?fvfBߕJؾIN۳{ϏEn[k@nϐEtt THxKwRRRpwwә4#"# ѣ{7_o3~W7A}ԪY/X/rAAEt:^^ӃiS>dĨ?qڵk/z߰6x|^2Çɦ͛ju&Uj5۶`Y,bz??*Wc?"@Zh&Lh2> lll9k6)))4j̕W<VcŎVBڴbGXׯGp_?pZ`+ FBEn׸Q#bcHIIZժd3O?eO* ^3 >AMl۾Nsa:oᣊݦSغmEe2YM\\္%)YO1uRRRܹgZ62̢q+VҲesz:9f\o6os5)ngX8o OILLҥKƹ7!qWJ<@'f]tf=撓C`@NxxmۆG>UTiǛmW{bgW0YaQ8IUiղq/%>Wp%#pxʠ9` 5KU/Eϣ!PpaI vT*pBS~W3P(P(E^@!JKDa$VKJa$VKJa$VKJa$VOT*Ԭ!C&=#g*E8j<11$HӦ!oooj֬3gK]$Eqe<’9(!ՒBX- (!ՒBX- (!ՒBX- (+QR%ڵ SԩS۳_>wf ~z+$3|4+ӱcG5k/bq;O>k2Dƍh4w B7!G$uӛ'n=z!9;w *T*֣͞{7Tb;!!}F)6 NNNf)"[wa.bRT Y?cfh4"hnJ%]taK1.`9lo;lڸ;wf-lʆukU`4rpZl# ۱֭ZϑC7/s;?`pww7nst֍[Cٴa"h0JŤƺ5ٻgqj5 cwD6~T DJeӏ>JŬٟqifΚEص{ E?S9} -Z-IIMIжmvAv\#SuWYڶHܥ'N^yyy_ڴ%]8N޽ѥp1ڷog,۪e c8w|  ݝ!miѪ51 (׬`"7mFǽ|t?@vKhќ!m[8;;Ӧm;Z!7'!CеӦm{Z tGϵ( AK1>%%Gqf] LF%E {%_/`0%Kiܸ!ۆ IU@llnINN&f;s vvvTXu+۵3fvݲz\񾋇!BM4ҥ˄GD`0 =# jժ#G^I F~!mڰ*QJ~=~ |2}֭[R~zXv_* Wү&;maP,>l(_~$LŽ#uiZ_@9wɺkJnn.'Oi\iWWWo $'%섽=@` _9z t&Lʌ;Xk`e}Nڵ ?p+oZo/B˓Q* 9h/Ye񒯉1glRt:T*5II=P.I(UJ~X/^q_|`gk˧fe6F˔'oҰeI$$$EL?۷jqvv+Y6io'6.7779ʁG/ݻ 2ODrrr2* wwwsuq!+;Q%Q*Mzzzj5nnn$%%-nLNFF0gggllhBmN#fC't:Fxߎ\_deEnMVE\<Ņ.'%}ԞWbʳ-zDqE."srrqF#ʇA !}'̡3 D\| !jI@ !jI@ !jI@ !jI@ !jI@ !jݛ/ k8}, A/ #xCpx:A ׿T{rgXk8Z}!]V8UߢF7|PjڵڵkǛTRdo8p _-^R[_-]B^*5Yt -Ӥq#RSӌ~x .XgP={q9d* r=:uꐔT.Og-@TI6oeU8::2zHZjr#aa$'k FAVoP(ptt,f .Τlx;RC(888S访899e%}5zt%D=t3m :vh)UضysoDO 5?۷;"s>AlټM'ܸ bwD8֭awD8-[sMSl޸ҡ}{Əo `]9(cú5lX5jNqY|6;" -rt܀߹CөceN87]R_wlڰ]a4l iٲG$lvw'< :q=(~ gggڴmG!2d`Sj4Z]<裌=7zu ߹3;Ѿ|:k6#35 J$Mki\sLF&eIHlܴ3Nq>x:uH;^x%ZhNې6y{{3k',XMѬE+~qorjy?KڶmvAv\#0kg>}fѶ}vS'-e@hZiӆP1(U4 n`R~u@}Ξ={;zƲ^O@?iF7+W}Meee1kgé6m8rnTV(*UhsDZ59|իUۛ?8IpppM4ҥ˄GD`0 !mQ, 8xN<sPTP7 n:^9{֤7GGRs\?… :~z\6Cۋc~F=\;x{{yw`&<=5!៛fݶe@UP =vZ-|MCEֱdK/w`0PzuZnU>&'%q)Λ_RdQ hu:{{yzp']4 @]೔B`̛ǎWP!1xP^} RRShҤ=-ŽgS1(dyӦѭlw].~~UW* __ ёhlwW yO33*!&|}}Huou|7S*P2wRɢi44MA[mi4,jKTXLXT*+ f;L[R%cb| :O^^E۟ϦP(,GŹz#{עl;;bG(RXhoo_W+uRԶ G_uӌ7gllٴi3ϝ^GP%2333T'O^ګ撖 9_G'Sqf{1qx7j2iRR izV7식-IIL>gΜߟs?gLCrWxe ϝGV-:d>Ζ[پ}FMqFL0WzV%0 oÐC9} 3~Xj5*9e7M M_56ЯO/؁"n8;9e0Z^OV-3QfMazѽ+[GG3v$tɉG#'';LqcFcΰZlݮR &Μ?R( <=<4a,J2}OOOfL'Ӷ}7'M4;s02K0 E@~~͝G7e 2e$}^7zSuy*-u]zd ZO{=^}zGo7ХGOll7G]ߟ0GХGO^՗&ҢsE>[2OUxO7+\Nq]{Jn0r8ݶwŰzo^曈~}x^<߹+ϛP666 +T {yKw6meGlllh9.=zfzVoǏhbSu0.7i1?^~+, Sde吐\C۶ԩ]@Llhތ֮'33 nI~~>O=m;H`#G_si0ŋ8`u>IݺO2pX_;Q=qݲe+} yNn)TLJxeqqxxxQQQ&oۋF ǎ̼qqƿLF^^<ߩ#[4.;sl/)9{VVxzyr5]~[?;tDvߋlv|z5cnjfzÍecccIKK;vbZ6ofOA`R6 On Fv(J2]ww7oHNN6>f_:ZpufMЯo/@ 8w|r%++W{tg[o|*vEma#xWXB8HLLy xyX,XQfYhHH0ٯII׼~R&|}|$IIxxxwqg99)SN1w'(x9:8/OOhlRR2J#GaQsss_>]acdggDtL4ozm7ǔ,ͦ$kx߶o n;ytx7pp7>ZJ>"336mm5L7?胉E?yyǙ2}]^ⶵ:˿ew?f$#F#??7~&^ԑY3/yyyيo'2:w i۲uǍ#Zo~TBzDu֕]9PpnٓONN6t:}h:RSSMNq(i...(:}{{jtР~=v؆Ji~~Rk5 &|cpK~~~#[J@.40GR`PN}V{OO/,]撘h~m94ˈ^/ +#W3%yN3xן8:H:q$(Q4!( DIkD$Ľ'%J77n x{{Zybe%%Jt!4j+ 8| JP"ErPpݸH@Ggg\\=IѕOFm#$H@ !jI@ !jI@ !jI@ !T9] ܠ>jNzLڳ'[C7mK(j֤O^m!I^N?x{{'bǎS(;yr1 *0d Vс&Mrw#U*G7b*چ0I>222eT*P(53cLڪ\11\rNG~K'''1_K\PHZZZ^Cǽ{h4khҤ1{vEe|,]7l( ֭[1vh*T lv |J+y`5bmpj׮@ÆlkAvmw7Ju'#~g"z4nU+=xŗХO,] ..Z3gΰ3,\ Hn=\2$2Ǝa |8֬]gdi >~;N:YN{QHrPUTV ?__]acdggDtL4ozm amd>t_`;7trrˢO{L_WF֭eW^:ڳw}4jXԮ;{ع}+[6oJ׹KTT 0Oh96mB| F˰w+"]a,Y%i܀ 38{ѣG˱K=بjuƹ;P(pww#//WT*\l[^^\(hAUPoKݮAYO@RRK '!'9BX- (!ՒBX- (!ՒBX- (!Ւ%~wCX)GgrE<(Q7O<|wW%E+mK@ ܭőCJUA^8x2@ZZ/^"--Tv֍ʕ+Y %!!ΎW{²oߕ3sx</2o|lΜ9KzF~3,|NFFE:;;^}uss#''(8)IƬ{]O~i""vG7CKFղ~F.qYxg^ڍ=_V͚La:S6V Xd1?~ͤ ȡư denp6B[|jׯ vmCچ!lvF Vh[{T* C{gK/c&|}|dcg/( 4IJ8q`0RBB|i0/p1cq2mRŊx,\D^^$%%['((ZjrW7q`c}?ʕD:V#00Т>;wo[#ĽAT FB===3YK1wٽ5)Ԗ'iii[/oo/z=l`.//>ڷkF).)9Oe..o?(6KḿoKC;*OzĤ"͵=V[>-fI?9%x0H@ !jI@ !jI@ !(QzZ~}YjwLKC΃%:uuPΣ+ uϻҶ(`TTCSg{׹PJJ*5ŽOVf6999+$[[[4R,L\|< wo8t(m=l6Nw ;;FC圝~quq.q# *,`n\~,fH@ QɧS}),?A !j!362HblRFPBS Bh҆U*p%vG}g82P)×zYK]TI%JMvvZ oo/N:s7lTÓFagkV_@#e7o?%1)6ԮEFF&._.ǞlޜY,zF-= ͚RNRA=qpzjԫ,N2J =뿥$ GX,f9G#)9$9Q8} ǍB{hj)g{Z六m[7 (QjJV-7w زnnnTV'8~wN:ñ% {ћ_}puh &Ϥ&z=˖@,8Dp\r*U 2[FPXd%/RT89϶~u{NRѲE3riz}G՚,t2JO/OjլAڵJ{]HV~}̇Ԛuo88 FX!1tTDz@ڦiFfcw_mpf2M$3:XQ %9BG[0M,w 3@s~gy~>>*mcJ i8ƏV]{kvR྘EBXU+g]5vl9 ;[]֘6^4݄u%z<=4fp3lg``%-,pfW՘3~X0(ZTy$HI~AY]i|Y9FLOII|Ƀyf5{bN7LNZL)(E XHXzu<9@f?^װz3c->Dy%du-vs9tm?;jAׯ(Y8Y{ǸqJi3lza3o@iIIpod@`*m6882躊Rp)9s\au`K?ǟbS_@rsgR{e8cL3ra[Cq8F>W8t^ wrҥIObjzV>N:r;5H1u~l}5 LSo-cDfffmtty}[ai9٣PKJ7~ IKk+Wt ԌRqsE,4fG [31r:#Az /VobhxuQ󪪰Q/?;g-[6)e~< pG"n*+l!#yw>x.| =4@tu}1>tu}Aq=|I g"Ո[,5VJQ%6>"59~{WO=کR6X,j{FΠĔ7ԕR=R*l^Z4>o:D PIhbDl'C !B sB?eYV RtD"8Yu:,}a#0LA( \{yzAYӦسgCyשcL2 OcbpƛoAEk1j{y ա+0%|nݺ ڥ3F,\5])"fLǫ^37dVIkׯ2 P?o(((3rJ h4TV ?S*U|"\|z&O58?~WL&ÊKq-L4Zdv7t;\7o}{mYoΖC!!ɫ{IF sf+aINuc+dX`"G@1'b(PmXxj|fco::cо= 2: scN G!ōnp}Tox I$hb[,^~~Ա&|2'R.7w&1eDrYo }x5gnݺ X3‘ׇ S"`E]& 32>#p%7󼽻vƣzjNk\/쁗_qMqFn]aycз!B]bbڿH%_;v@V-TG1wuK={MVpssCzuTFFF \c¤HBf!q޻j;ǀb8wU xWOo": @Ĺs fn5ޕ=KPer<זȲ,dR M7Fз zx{{CY,ˢ{.ؽg|f˘Q#Jo RSظ8 {//W_~܉W˲ѽ> &Oƍ_GoeYY9ny˩^ݺ闭v[թ] }%rN7oN8p0 r ?mٌ!28Ge/kԨ!.^,~DI8zt7JHHsA!Zٚsqk^1NQ=sf@;o(˳  \V2;etL:|vBCClӭ N9 O/Wk׮rJXxR? iiv7o@!rP' 00d\u?/OO ~5+, h4|J zvߒ= x8{EECl\,gt}rw+V0:uK/Cc;:\t|^:o;RRR[v"+4(Js!!1_ZO&dzemVU*W54Fǂs8cUvt4f͞gby9."`X7': K[x !xA]aǮ־Ξddd@c@~3L"#3eo޴Z@: V ,9td^~-A81ހcȫ<{,qqv<&.xr?9{`c>6ٙ.1)ټPaRRUy 5-<.&%'#0;.[osy@@.^+]Gn;f4~O1\FuLX#3!+&,} 43 v[Mtz=fXK!g7.JvXFjJn˹?eLx,]0ytD;{&fdM?77owʞ5{U㱵B\)*Ξ=:kc`YN=QrR >&ZzjpW*+ə0ywcYrr ? 66b[tSRRa㷹])fO 6Qm!0vpAlnd\/VY a 8~$6l xmt euIQ*P(3GVαͭ[15|&*Tƒ1$q}ܯ iŭ[}:!ŗyֵ3~y.sغu|??_4lP6lEK͛߉rHO1mz8{u28-T٭Z6*̚=sgDV-xh&;JJו*n:v߿;wb̨=<(DD;իkN \.O0❷|}HHG lf,wxgwQjoCGXgo8xCHHE"|2 ~uwy'QfMmei>p~UV6/<8)nHKO7_iw'OYk{31zS@ӧOqux{y9Yߎ/2*C~~>(ug\:~]lO^&Oo'ePBqPv-zP*ϟ /… x1o܈Q#9'"*:/Yժˤ<ύq\r nn dd2yJ%y&h6ٍsx4n tBi*׺°l"p"N=c"lq§NsZVFn-1ett0ѨhLN_:! E tZ0}`=s 5{.<Ǵ0 8#Ʀ#V3fbUh[oX3sl"cQuoۍHH +>޸i^Py7:ؾ )P¦NßjnQYyghGO`9}*LW|%vp*U`_!33??q1w>u ,boеsgu+>_ ;NN{usbwhh(/Ytp$L>өvtl5@Ff&4 |_w΁ey]<b.AtÞ}`|*1Vt~~n]:c̨剥ⓩN> 뾆  P*U.QSR%,[b w_a HL4vZfպ?:nn Dy6NGXvL!ZU, o="qF:3H$x{y!)97Bffs׹eYSX2mR6uIII:&鉌td2THNNq\%ӵ,!T4n;HOOǤpҥBH!Bʇcz\ه~₈!WN';c Ӧs%,XT B!BYa`Z@.]дIcq%:|Ϝ5@N!B!R B!B)XW@!B!R(A!B!rB!B)W(A!B!rB!B)W(A!B!rB!B)W(A!B!rB!B)W(A!B!rxl IDATB!B)W(A!B!rB!B)W(A!B!rEJ:zA0 8 D\ !B!BJ7@,u&45-fR r77)tL(x !B!BJvtZd"3# , uuHKD* */(=%ಊyaq@yhl)kqN5!B!B $%;Š#59 iPyz2Ȃ-,deA޼i]QmLh$ Rdr 7)r"мYS;aB!RjF&YI P3\" y ˚o' Qk9O 9,ˀaXy 0yLdA3&0xAm&0챵yYYj'@Jw!8O*BpJsqEjOcbHB!B Ǧb)\@K٥3I  =-iPyyCU%yP!8%Oa AxQB!LR\R2ӌfT)ӔJsoB!B#zfl<.)+m߄B!G(2ӐSlݑ!B!D:I qƒB!BsH:ɉV%B!B7W@VFz2+:B!B)0___^Ԕ$% 66))h3b%;ʡd(Jxxci Bp0׫u錫׮iLL쯴y T"AlL,N9ĝ;w\M -8NUEB!8~hP>ܕjxU*T*Ԫ] 矫`at^-Oyά*AA9# Ǖb-(Q<<)T!8]tơJtkЫWk=w>Ξ;F߬]Ͼݵ (lR^\*#bt̙OD!< zc[DIq٣;?yoZ&"!!Pje{r%fy^zmWkĬhެ)e战5ǎ+\0݈0ʥ4dBP DGI&#*azc:wB{;=wYYY}n߾ݻbp|٧hD$<|}1bp|nݾ7!1)㰥B`]PƒB!eJq{t{Y£0-3JU͚\8cui{JřtWPf*ab\ԼYS,? 3'=Jں qY%T1Ï!"&%1=xDDt x~[B!eA&IɈy @bҪm{SMϝ`sT:73ufZ(\0) S#|LϘY" Jxk\m؈k!Sm8eQ1"t 5j(lB ٻ)))سwjP15c:߲mmv|e f͘^B!tjִ).0]{{?J7u[?~&sǙhp9̙;c(cvsZ Ш3!+\JUZ&b0ebM yEjt69iL O?X;xWOٻ/[]3`jN'~:۶ED!W;}"ڶNtEY*eDQ"T c((:F[5 7i mVd2YFV8:qqAZΝ='_ۖX皖&ee(8OruViKtD`lnV-<7kvQQкUbȱ7!$$K-@HH6mDoш!b<y|iKJVX==UdaK}]\\[S^2s+IQt@)-9lքGIu4h`ǠA,qtkdGNp" ԮcFݻXp>j,YthѲyי.p#BBL9_5.ĕɐE61TPdAoÔ 懽{L8Jr^YUZAiKxX"ghs/܉o֮{kakojEXf-nܼޯG#JKO$>\z'BHfyܪmb" eZV#Pۻ)p%aKW£r&6=%  h԰z /UU`D~Z:#b^iOHRpsʓ+~bKi4ܹs?yc̘1G%e7 "vP燽X~t oݠAي%#!BJ۲rj 3PjZRj %9~-açΝ;q-D*š{Biт$lf gLfn&:L> |٧XV !֬ u])еks2oB]<k 1j!BH1矫ճ;ӑܓ_=eX R5l9 !!?3v#_-31dG^,ih{M^K3\ W%B!Bq JvC^޾pS: BW>R,=ΚB!(g}0sBV^ޠ "`Y,A*B*ApM鲸mQpwwMPVdB!W(G<<^oL&h5t0u0~H(K!B)8Jvar^su($NEff:ԙd Py׿Ttm!B!M($R)}Z ٦j uY)v ^^^HeB!BJ !R7ntu(vQ;L7V9SU @ɂV8npPAò%'/wOtddd@~R4 Ri!B!1ԫ0*{斷$7z=u_)%z=ApuB!RT PZd@^mղKYNxd3 {#׼_}/pjݺujs4ţi&4hϘUdgZWK.eQ9q;,$#59aQG㣏>s=gN[Sw6m * aaa C֭Qjb/qh0` t??bُBUb[.}9RbEԩSa:婎WWsuNYl9S2 BQ^=WP2!]ItU5}ER^IvX>DOZXo{.Lb۾Vr'l%ro|y.ԙHKuu%`0:28. `عcN`!,\(ng=^O&aذ٣{MJIށ @i39Tj~okLaqgwYCF6ST6ϧwv/s:خvڙ{}OOy8f ©\.kC{u$ɠT**pr%{ׂ:5?22Ӧ*#:H$VD"{ y8μ{?8z?QTVQpV-CW<:uBll n޼!}WU̯^Yvx6ga⅘=w.N>Sdd)]˓YVZujۜ,7a2[)⳵msC~h9˲xwovi0pyTT g >vǮ]FPT8u jժeVT3Z7ڨT~e+?cO`)2Qؾ>snjhǎp |n=cWKoCBBiӷ8'N⫵kZٻC šÇ{^D;0y#*v؉'O@ڵȣ>=z3H c箿mno޽`Ix+h$Ng{hiذp!8pރ͛ǟ~ƞp9 <ؼ}Ϟ=qٳ'O l^p!_ϡ:X"ߏ>CjZb;{EdT46m:wLGudo~W_Ŧo7wTG=z >#?DHHcQ'Qǰn( [o+WYr* bl0 &M'NžjjHϒOLڷohd.\~q֭ 5n_!Cbvwxw̯?I/!^TUVbUDTR?L:fBa?Nzub%3oN<]eJI١̀:3J۔vUXjSV%y96\V 赽}{D]"g٦yՓTvmƍ܃7:u_n`LJ|b_Q1{HL:GhB@=WZyA37UVɓVW|9^X)Ν=#eY,\,ѣ wo1]L ze˖hӶ-:uN___2.@ƍeرc cƌ3gРAGs2Vjk׆f̘hӦMqn@e2u^z`0``ӷ1r :uϿ[nt2AHLLDŊw~u+=zdu~116xc[R%$&&shAU ־=1s&xS`ܸ1bppk!>>fd2uDZud:^_oeŗ+ȑ?~I&ېdoxW rJ$TϞ=j~ۧ7bbbСcG|7nOU1c: 777L&q}fGŒгGw1l0e crydDv#"B);u]Eܚ0\?%aiXx?Yr^Q[6V|.Ɖ' ۖDzjWP &:[lhݼZd' g߅ә\ޥKWlѪC.c]سw>}7/v* VX 3knnާOAԩSXص/l PrԫWQY&qo>Ę1cFxݻw1hkhҤ)DQǏs7$$75!"xիѱc' 3233Gʕ+}rեN;ɓ'HMIA͚5j֭8,;'G֪U A8z6~Z,Q855ׯ_޽{dH }-g19Ց+HmڸɼXtT,h4s6PreBHQLx6ѽk]Okת.…K]<jAMru.q(z܊D{ΰLX8J~66eѻOzz<N CP`8w9Zja޼H%> fs$$$K8wZlSwzz:Vk~Y w@'Yy!oƨѣ}8y$ϛ8̙3o6V| Xp.\`UFpp0ӭ11O,|||nVR7O?Ajq5KrX#SGŽb탕_>Kk֬wB6Zl|8HR| :˔=0gvDZt4m6ODVc5gbO]}䅒$ߴZSƗoˇ+{CrSu=q[aB (u/Yxoz̊GfjA8{aF߾}ǏY@ڢ՚5>|jԨx,clِ ?̙dR xǦMwa&mctDT*?$!"bcc?\ W_A}{V,V'&>||5{/RmCУ{708t ZjUV޽{HJL,8uԑcZWG[ʫ>^B˖cĈ8{8ٗ+%xc[S !HLJc= $%%Ūm6ȑ5kB8*BHf/a0"Ac?#ݺkي0e$|g ^/>[e?9Z )8^X{O}(,g(I9-r-w.:u?v?z=?͡;R7x* gyx+}zΝ@*֭[{.n޼&JH$TbljȨHxyPCq~Ow]f~ 09}>|Z6󇗗8\];wY]ȑèU&^z% *BP-XNU {vٻ8;l !P<"fA: "$QP+& PBI6lߝݙ;cÖݙ3{=wy^9GMz>`0 {WfZkz /Vbe;,3uO}r=]}FUUU:Dxvڻsغ뭧:>oջloiÍ6ʜ_pQ7p/ɳ j7ֶn+IJo[[jjj~䓥ͯ~Hd6{=Ъѷi GsN:䂌;;!&`.}t|>/OW\.RO>UDDe4M}1x ʱ&)UݑxgEsu}Y8ˮ:W6MS7[z=C˵hywܞiDꝞSOjO?-B'tR,RSSN5+SarYK/]^O>T-^nCE;O<$mŖjhhPuuL\G 6gK/>+;K3Gx}^{-]s_"ӥUt≳{_,owܡK.Tヌ:=p:q,stYgI.~9G~Xx@ yFSz'?т'RSS/ף>9Ci;PSS>}>Ou9s$I^O mּ'>'Iwi΅?^,鋪8m0 7Y9Qgq M[s.*=ɒoHy Xkwy~o~CO/7l}\MRjll,*)Z˥X,ƬΞs֜ هT4SOOwfUUjnn0N4ajnn>( Ii{Hd/.uttվzBaZd23 "kkkҢT*58F+*JطQ4Ukkk֪rJh{]?3u<>@ ϗsQϾ\z<ájuvv_$QOOO{#:J?r(`Rͮ+}3Ŵ;ůp3N+VH$;0&3YW>uGɎhnnΫD z뭯OG?\`$>_nz{=v@^Mv؅i,k|u<':uwhʔ)䏗`^w}Yc3yXQ0nGn0J*Xp\Ehjj=D$קJeƆdFBI\.|>uvvʤc<$Ffm'0z_](@ 0`{FplJv2![x@>Hv`TФLvH/$aFe8t*(b ˲W(\vVǫ@(P8"p%KTOv0 CaLG9S$+˪ծ\nZ[evTN<>|\na`*&џeY+> IɁ YFo)?fLÍ]ﻦᅢB*EkK>ns=[c>Z;gNdž~ssr{?^O@PnGtZ)wQ-Y*20:ylp`HR"g]1K$LWg 9} ^*K- )VSWjwHn-OҠ W>fxojSkLtH!g ,WJ]?$W0Tgko;=*oDRmǼevu**4䮪W/wd²ZqRdG#% 0O_B%w[ RubSPS|%#QOOɤRT{ao?SOV?]+cNdG9<'0&v.6qyQ2Jtu HHv`N%❒> 0r\rr{m Ð];ьSμwFI[3|~}1%|Ou~W1W%;,|F^ҐB}ko ;REډRW">bʎ_8vo'[qTΫ7Mm&ExU\c^' Mcp_I,hpy_UzjgY3NS᪪BNg>Ox^\ P*k`Pn;ʕ+uk@;3lr)`pt\7dןgZwu7 C>_g*.Q}bhS1{0eWWd'vg?;D/O#>7\wzztf.ZSzK/SNo]]n=1ASSS+I9sn͝_~siA>_/=8Iҷm͝7O>_􂮻IҴi[og2ӧO7ߢg>E/kUWWgΝ7O{~fzw>}ivs/Ï<xPӦMpSNs/#>_wE3λ3~fvuW\.]ÍzE;o~UQ M=XM[kX)TrܥRXl|~G;vuR)[n~[mJ}2MSow566jڴiz|Sw>}rJIҒ%K>j;!˲stt5W˲,Zv$|͙?^ka6>h$?O@ijjokԩCI|>YgX"3PZU!~1|<դ vnkG9xFE9VVjLjiiJ$)3Md։'?>ԨP(>C':ꨣߜ?O{5e)JկN~J:u̱׋/fVCC9lrȡ˴jU\p^}L:UǿX~bjfャ\ِ9Lte_O]m/paE"UIkwp d*57`͞}\n~Tuuud9Y}cOpGy59,d|zkty&Iw~Z0b W?VSc?I>MMMuWw.bven&vۭ:uM7k뭶pmcc~eYZ^k{ب귘/?\HD,lv-gzf3%.`.;*&7`br=#ԻfD:m ݝdR$v욲xbկXh,%KN>LH8V]]\.^wJIgg>PXL2 x'u?X<(IRGu|IuO6/Hl6t3IRMMve~%6Y%ө:hm1sfAe?јcP8e_ ކWב}V}|)uvvW^3O?^ _X,_i{YK/]^O>T-^nC:3{9$mŖjhhPuuL\G XCN:q.Rr8 λ:ߎ?S{ٺҬxg\YgI?~F͝NnF|q.Rk ө;]b0~x'Dq=κL=>8nj6( Ii;v$PR}k455 cjjj֦;NUWWg\u\bjll{\Y7U掣T_ ךŤ^/`:544<߿!xu>immͫ]өx`%KY$ӷ}`eiժ7}w?T@ wDv oij=; 6"ف WPLX&ҽ@@VE2~c d*B0VU$6kuDer*uUDZ*HZpdבɉdZFQ_gibUCL[#فըv 1Ӥ`R"فp8V':p*;`"فV+w_$`r"فW6TK[>;&VeriMu[_gy ү%)]W*@0m۾(L@>ѷ%Z y<!U׭!Y-Mjt/Ple,7An! C%;R';/t,5_sh\.)*Q"aYv/4[Kv{3 Ca 2R0xF IDATvϓ%t rz?WӳF4~nwP1*6i.0 9].9].!{p=O޳; *>ّlT;>|v}"p: TP&|ch"P߻|>;?\ct Hx!+/?@0$cwXĄOvHgL!#-+? WN 9N\n@1}TTM|Qa yxlS .3(Ov N dK(f4? m>Njj*(TOvءHROwZrxp:%RfE,!C,+~+deyaqz}x}uFe';*qtTOnbp:r{ CĪrٻHi:>Kt0LdG9VqT4e&JҴJ@PX*CLr>فKӊw+ٱңFPeYhWW"HFXMf[J7QijZՠnŪkj߯}?$c577+X/@tLT];E`p$IhL'zZַg^$;PdxV5p8/ dOKҏOHx@ 9_"ީƕJ&{?g?}ޅvDg{Z6$<tƂikiW*jke2.SZ4@ɤi(Nm~~9vTgGZ$rU$<Hv:;v{~v\CD0l E@%NwFY 7!a0!rM(D (zvdC}mN0 ۶@=]vPV~s͑@51R\mG ёb'Iad2ޭv/ $mN?~ ɎLm,kH8'rʥ=X>Ѳ,KiNdajooiVa4MI:WXE^3R?-9ܘ#up>\,vRG8j{plI0|xr'!3 QVGK>e2/u`ȶdG91 Cn[a ةe /$pHvP5 I l!ɜNUq0 7+?@ uY0 jJvq #׶v{|= QBM+,|~U(+atGЁ?=T{Z<}xtwG뙗>iλ'ѿyBO-zM<Ԭ>=>:IҌkֿߣ{RO,|Q'j/{3/#$[?@w?$IkNx76}6=s+ɴ:zXӦz_ǿ#O,g)pMW?teWezpS:G ޘcT2TKsҦi[ ْNvOkr{<~ǝwNR?Lx.<_үN;3SI[o~w{O3kE}vnk-uqJIҜK§J?ume=xvN;m.I'Jt{nojgd_vf m7ڪϞi;sUkmҎleÎ8:Ys듴v[kں)y=%IC^j ) 04}LUhml!ӡN~_dJLԸrꗩ+aw8ޭnW_yI[_\$ǫZIҊjinRݔ) Bjinє5sK-λ!˥>D4sFzo)SohlT*e}#M.Zٛ 쫯o Ye6digkn,R*IlBp(˲d=P3Z;sҒH$3gje暣zw~$[rGu=ұeYERP&̟MTkK%ɹN{P-PM *HG~}zUz_TmMsHÛ/V:/~v?8yσztheC.k%Wq.<}1u3Vp(˪&d̜:SaVkuNhhhMsSSϫV(r)J=Hv6Y>T3L[=`h*Ivrzzz[ҫ'K?RsSN~u1}uɜٺtڙg9Q*7ߠ;oYVo Qp~ 5NeYjXQY3$-}>f_t=PZ90S[74 WS[>ԻGKK3L1J;W8rITAtdv>m(fm;s3;bXQH4?Z??̢pXuurZku$IN-ẑ_z+M?WgȚ|;:58 Ϗ8Z ZC<n:$I_^w=me/[&˭o IIw}Hx<:0-|jA^q(=*;`O.՛w` RyṅZ=2uvvj/빅Ogm;f~b^\|O:^ιDO-zM|:7ůopgHu6bKlhPuubXCN;>0޻蜳N9D]nr_uMRC 47랻̴mii_RpVW2( )F.HT]*|Ūkڒ?9GQ PkkˀӦC_^N:#n:G7/͛?s0NeʂeYz UeLk|ʆF<ϺG6idG=9wŚ(>[PفѮH&e1P݁hXQvގW BeJW"xG!ŖJ(@I;PHvtu$`lIv1ե,ۛN'2<%\ J`RZ0*%q&=xE5,'ֲЧPQ^)/ߥ3Jl,T Kl{D@*yò|2tޟ?=uk33ڎK!NdTkGnvuW 3,e({ |/pIp 867WܖeeM06a49J%Tg;$r-oXK>߶OvHO?+a1ѼP,iX;?\:dJfYZuto;$e"пܪr)+F`Y U^' 2Md4;X\.<vb.2UNUW_'cR`x3gjɊ\ }V>SvFg Jtjh%w41]D nm,wzHr=x|+u#]^F~teԪ===:s&_=Lr%Mv v6ߩO> wmT|bp1sY wO#ŜO<#q\Cc[wwfϞ|w;$<I"`h[9|0>x\g}vuwwIE_@y"ف*\[[$;Pr@PXf6n: ʓeYs귗lMM^z )0X%v{k(hC_pdԤ}Gl<@}_U"ȴ09Qفz} /aF£Q{キn6m:#ItP W ?ب=#9otrtv (mJdɒpt]3tr`J#[bd0<^|,])HvL`tt8z+/ C.Wo;ՄJ DQd!F0 9Ny>=/NdL.%VlNdl ÐPkeKٓ6wHo]Y.jLe T̚WTJ-͍+ + vbFUdC!^Nd;׿#{H)DIW"DBM2ǜN<^>>QP:S1\ɍ?盜 ZYR> L3%3RW".YNK`PPBU>Z$;ZY1DGߟ'RB4SjokU{[|͍U*T;,bV̕Z_q/T-]Dp(IvHee><%e)Բϖ~LӴ;$ 觘Tz%F1MS͍ZNJwQd13~-DmGǚKL,u%jXLMvپLhϧ*}H5W:m*VSgw8YMcA񘦩ƕjiZew( 6M57R{[ݡ0&$;0D*TkszQ#فN`)@N`KZ@e!فL3vTVgGq o$;0,3R0@%!فuu%J%TJ=v@^Hv /$@yI)C /$;+;Byq8*oȋ;2a„v{T?JXXUK5V9rx}v@^ʿcuò!R̉>C /Vv9H)0ciW18# ec9gT2?QG[‘B*C 'ۧB?r2"״lɕmG-18+12J*ަDS]ZnC`[?#YH W R UZb0f [Ju4MUNQ ;2*"Q.SMgG!&9(xgqLb$;PP鴩Hv CLb$;Pp==]vHv==Ja&)(t:-d&$;Pq]@y ف0!&)(8)ewId o(8gwId `#فr\vJadߡ۔F-8aj?`H^/X[f*r2 0ɕlKJH|!TUPU0\*;r%I nHbײ},k':˭H0(i,ْ NX?>xMɇ cX}=OtUјa G%fKPb$){}% GV$ǔ5gn y<ނuZdD_D!DXGnPX:9NC@r\`JhWwW(T)1a*UNaY@YɬQC]%4팱h^%QX<^Ng3RwwzJ% :^!TEc"B@R*pUTdRɤiSep+֖a+@ U1ѷ0G WYP HZյSr7ԠSL3U*SFQۈ8!1=^4RgGk ]l/\nEbՊ4|JRLTOOq%JNBUU WE:1g<ZRS-U0V$Z`j:NyV'"j%=w++W2YćW T0TEPƜ$ۭ)S֢6(gWZUEb](Q$Vt:.%{zJ%3R:V:m4% $˒?t@WO R R"ҩxGNu%Z=y^#1U},!? ?P(GIvԕHK==IfoeYeɒdHE?琪tڔJ4͢R,>@X"1C`(h?/_>quMdRX9WYU ;&%;ozFkUmm-JeۊW IDATS0V4VsYP|/TQ*T*xgquw%ݭt:]N<^|pAc3ddž ع%EW$uLV($`B!&`B!&rۢ!r{E h[S3$oӌu7Ҍu7;ykC]%˲ kvSO-0e+fInPVّmݎp8Bwfau'J!=^Y=^9Nu'CA%=2S Ð?XD}H@HdRkZWܣҷaJtgr+9l`1"yͿf~qjk^/?,M|qZ[$I~Oxr!--_.of ?Zcp&;=j6ԔiksUryZǟϕeY'??Yɞn"1=k͗+m#θ\N[PWu)v ]|"N]seZ{?OR{KjiWS=zvp9]n5LWsZLF%Yc<\6[LKWݣKK{C}g'p z;d)}b}jk^:~\ɀ~wP55,H4ejmZ)I:-W(Xչ7■WzX4[=h[DOPDѧ;!0T3uF@␤ιV.>q?9Nq:uo Ck±d͚s ߔPيfG!<НJt+6EZb-y I;,UNԴb[*0FUO6|7F[9.5,[*IZcƗ_/>_Pک߿_׶Nϗꇇ5gK-+z[?mW%˲VbԮ9Sn2Y%L.fLVe)6KOkʌ/0Q}e$59mhk$9NwvG_5?14hNĵ!t/ֿn>wEkP:mj^Nk1?;Y:_nL5׭<];wW6߮>x}TOxGۀu8W|.P8Z#LIZ2TRNgE( |qt[w!o~w_[^[6 oVKּJSW󬋃4=P?Y4Szj]ioKрkۚW),Z=e,RS2Ejp^ i,BRwWBDhֶk\n$o G|1gpJ*Ek֐ԙ_$u; O*$M[g}IR:mէ0f'jokϟRR.{2K?77,`t*f|⓪C]~kw7^gmmv֏?UM TWɴGIr{}/봫)p(.ϯ"Iӵ7U GkgU~kqHҟ:BǞse-}m]I}0L"}ms&64WX &LlQ8R欕PD.[M}|ښW)6;XUK=]ka?ϝ=95waRU?RvY:6T~UPDDcDEAcC5]Xa0,HD)˲̖؝q{c ;_3;s=Ö;9oY\>崈5;jonNͅ$CATu P: ]rnbjS;@L!1SֳMj@`d) vBb a) vBb a) vBb a) vBb a) vBb a) vBb a) vBb a)hvn-/7(nM_s7ش;m]s7#b a) vBb aZ<*RA5w3 Չ#e 뵯գᦁ4V,Bs@LP' y_Sb a) vBb a) >'ν%~_E y_xV}M4VS?E]W}Ƃ/s/1{VLKzKb a) v ^hb vBb a*ջw/ݫ;vThP;1Wݺy;M^rq4 Z @6Yw9NeX611A]SRRqq()1:~~ p‰:뽽>| Zb|S׌JH9昣5*5U2u7yaCA~}*99Io77O^ru-j uGdY>U@#7NM|-_'pbt[Cbd亮y1]7efM6zчӓ4dع uq4Q$v4dYz5tM\GqK=\ݰ9O>2Qи/_>q,3tQ>W8dJ-ZDoO8^lѲe%Iwj;!eߺU+V$ B!}P(ի?WN+=  M|јA4O=wu<׋޾}vY;Ԯm2]SnRrZ_D?N_t?6J!vrssO[n;}=''GeʶowDd/_oQnF;XP+Ӻ8$i:5c$I)))_j rSO9Yrr?[QGyEڕqwݣ{S3JNNR֬zx#;Wh% R`s8 O,R֭+jޡ%IՖ<}3J^Zo6N}mwYف}fQNNN[S@eXS;X< vBb aZ֯jy @juH^Z=n=@ū@ n_U /a)Lc1S;@L!1S|`_ٶ=+99h @@FƘ:K؁gFmn tY={І _y_KNI&ǭJ~S;@L!1S;@L5w׵]W}zja*ݻڴn]6o?ί}(k,Iҋ]>hfsJJLtۊ+ :t?|K:S6Hqqqp:ēmۏ{ճg/MQͷ??>_|Ν;v4H;,u :w`옫.^MS*//Ost4h>C񒤶m꘣k檌=Zc9V֯^I_|F=8ԩSy9Çcձ1С~'/>'@tH~Ϸ*?SԷOJ˲<c$II B U!Ͼۢ_z~}2elVbb@wGIIIungRR`,K) +*_ի?޽šy4޼ RSSUPPPi'&&k׌Sm;*,,M*9dzSYI}SAan: 'J/_VaCoC믽F:S3}n^tQGwRGSپ:wW^zA;Y>ҍ_'˲*ya4Lyv> Ɋ7cMh;OVT߾ˊџ,]i>'+VO]thZ1n\sZd>pV}/]3vlofp;o.ZSN=U\xhN:IsӢKz9h3w.Z"I3g}֒˴`B= JKK$uIӧi埬Ի?4FtiҤgIzSO*Wg'pƍV5vWx}ѽZNӃ?}={qVW^KkPV/k =gn:MzSn_رcuSOQAAFHyu*,,P||l ƶ-v AN=E`Pm۶Uaaa|ɧ4<=ߕ@֮Ӝ9u]wk ?JLLq?= I=i߾~fnRbbb0iР5ry {aC%pI 7ޠV:庮z꯺t}ʲ,uM^zurss5hРzSԕZ=ԓ54G4n#k Ե׌ ~}֫V4rAիV\_z2W_A+̳Nh 9G/Rt:;LV8_?Zn]vRRRjڵKGj߾֬YN:IpX[lرתs*,,Ν;|Nv6nܨ3dQ~~~9L}hBu֭z  [n:C>I'?I}tq '6j!1UxWGu!׹[~.tزkC4\233}۶2m߾MUZ͛o/XcVW~@|j i^[o+g}&to~1\?+W?΋gkۏ?Vt 唌(/##C|}֭O2[l~]м&MzF*ru+..NO>Dek+xq'QUkQ999m[q *_)egg+33S6l>3!_^7\:wgW^oUo.ٶk[騇l=CSO{ĉ/9޽B;KL勞=/^\c׵?4p8\f1FUܸ./_oQn}*LcAۛN;V[fwo7j5W˶RRR^HT]qԪUFi$M~weC2bHَߒ^T/:$h5W%O߾:S$/ڦ̘\ϧ]VY>`YkLr1Ke֭]ۨAD؁2gnbGvmƵRSR䋋Snn<Oj<1Gs^IJLL/.Ny{Tf۶ڴilSGqnFEEu^H5U+┓S[n-˲S)m*DÛf BՖݗ]WȭN;c:G؁o_aX@L!1S;@L!1-^ PԱsg׾V>nФ,RϞ=M4{m1F6{b a) vBb a) aۖK)))ݔio 5_+5`UYs4*'+t]GMc4 9_omٺU;moHNZZ9Se?^wЎ?5abOH˪0))`mţbLcRSScNI>ZFvРDNp5WWx_ҳ{vժіei!:d>`IҦms4cls'<}@?u6m KR߯LޭO?T{mV搃aOocGtם+!>^o-}7mg}tG׮]o/ЦkĖW /֮kVi,ZhEѽZzuGM9h͚9Sr/LgҰa͝;wրj3,}:okZrsr+[+V-ߩgvYU|>i}!#=] ^o}ǵvbgDzƌ'Лo_]pƍK;y]sXNJJ|>.[ -RZZZI C;Ouud^cOs w7sֵKe,RrrruԴ.jq4̱#T+2jc_I:쳵'/OJ/^KjԅJ.b=񗿔)_ѣG+--M˖.ݖKg4bMz͟?_gs ?-?u}њ6u̙}::dxm}s=#~CתCh%ZhI}^Eqz57u܀cj}{oG=w߬-=J^{9C%IwҳO?Ys+@߿VG_}<ϫ/P~$I>Q\\\qqqrGZr} IDATr֙g~|8O7|fdei>clǑ}[om۶vM5L9X_$k聇. <(S믿QX_zz[yZ`̛g!ωn+Z&Zo˶%?T~v4a__Y3uwJ2$uI<.WpnC潳GRRrss+ݶ'7WIIgi>|xtɰa4eʔO>D3gάxC|M-[^ZmUeEs=ú#%wcC+'o~iq|n}}op8ZK/>k֬S,d۶ڶm={ +-T`i~~~ИN>d-[J>gqV\U,C4!%w]f֌kzҔ,RZZrssk.q:-M|똃sfWߕad(񾹶E]y]K*Sك1FӳfizVr1ڽ{w˻]ٍآf jկ/ ;@L!#]-nn8zS߾$o}2pYHsbd jh:df*/UCy{^w##=Cy{rkX=Nx:oo$%7wSZ}n,˒c;U32:Jmڄ={ѪO?1 a0\ϓaE=XdYrl; sC}WĚp~D XS;@L!1S;@L!1S;@L!1_v1qƘ8I>۶mu۶mcy8eJXU8N7/aö,.k8>c_R1&F<˯_+WkU ggu2-6˲ 1Emv'yg,,2y,2G unBU òm۳m3ƸWRزORA㺮8]M,˲T1(f~?,*2Ƿ$u]$DZ=ϳ1m>eU@,+_R@RyEm=s18yeYJ]t؏엿,˸kJ?Iy8^ܰ϶۶C`бmۖd 7lc'p#yIKu]Dz,GccL)ڹvZOЦ8@ٻ7kjc!q$=+,+dvH["V|Q)"c,+8o'%%Y,q kMHRbb~n4H?E-<+..< Ömv|~߸+˲lIN8iti@‘G# ~߳m۶뺊pj8c⢿7xgv8 ٶm%o#wt|ŽjER% :cK eY& gaq8q\˲oP=۶wm; Be`yexH7??jPI|& yPH`0vY*^У ,py3nћo*>P(X|>ȰF䖲$7Nyma_3%T2<;2<(%2STT%%%cÑ{ *Yw#Ge;cL#11Ѥ)kddd_~$]yZ#ʇDA%  u;w( @\EFtDאP;M0J?P#5+DFƔ=֭[gu5Tjj|یAc1X_6|^zCݧ8ZaþV :L(2%SY8u]IkBAG$PVU9$PH(T:JIIQ4XdtyQ###DB`HӁ֮] hB vR09@b aGYnk.h.Fĭgh1 cFFv4TjD@ QSrf(,, 7ܠU~0b P@l`dG#0aׯo&տ?gUf 7ܠ= .q4p@1Bzڶm(mޟkevN;j9&lqj䤤+1)I RWM233$ڟkN{fϞM43Zwէ*!!2gqSR4rH+I|D4LJIIIQ 1O:99YU. BUnOIIQaa$ɶm%$$(??_xm+))I{>q}:7˲j ʟCiԦo+3FP}~lVaaa}>_q?|N?]}vv߫4bԚի5zk}4Hsf֠Aj7cǎ[o)~eK/nOIISO=?Xg 7ܠonݺICiܹ5k&=ҢѴi3fzՠAѴi:e͝#^@W]u^|=ZjUYYYzU !Ctmi?EJ%eEXdee7Ï<@ ˲t9hc)];M8Q7xg۷^}UYF?ya-^D<󌒓5gt%(;;[;vԴSh֭t7kĉYgs=Wm߾]'t&=f͚%I:S4j(]p駟t%豉5bHY.]Fwrss~߮Km޼YJMMPGFF?9sX;8"K5n8ꛋFo/T7oV~ӵsN;VII?C!vիW4 ;vRSSuYg)Ϗ?oAO~:3?@Ǎo/T999[4kt15~~ =l ykk̙٣Zi?ڶ۷$頃Ү]joN+Z{F_zcnoz:uꤼYB[VW_[nܹ$)..N?HAj-UW]N:H?Suo&͚=[+D狗,Q.]j7 .͛%Ik׮ݻuAI*_WQ0(c^y2:{-ZX]vաN(m1*77Wׯܹs#IZb:iu=+s]Jgy6mҀ8*b#;!xZ2w^K//LNs9G0az eFW~i4|pM+wƌ PzvۣeܶM{UFF=HҎ;{ر>|6nܨl%''˲\gk7W_ytPN\Je-YGvoUy.\W^y&VZG'NΝ;ԑޮoV1J$pXD7;˅+Ў@Hv]EuyRwY~}Jp]WKDaוԱZ?zmWK{ieۖ}m:ԩS5i$=CwlߡnMw}q$PwߣѣeY-Z?\2e˴i&R~~kɒ%u>R_geG}}57r#-x=((99Y}XU?*Sݹ矗eY JHH(^`\o^{oẗ́MMV-OߔoҤg裏hy*,,ԢETT${==kvޭT?K/UOU~**,v_I9sFӧkҥڲ{]sm۶M[֊+d 8p理 &Xk׮viܹڵc'!!,y^{8N1&󼶧7b/֌ pt*YSGUu****fTGvmgO%JJ:ɩ˲ԦM贋ڴi@ ;kȟGx)Y&~_U.48Nu:;4YݻwW[mj۶:>}SZrriM+V|맟~^#r\Bz#ݹ JKKӞ=?48l*&_Ӧm;۲֭ӔW) w3gsP(TaJ#Z ׇzMN`vB3 P($u #;Z.`@@ 7Pn:df*/ 3ƲmcT<jzַzMbRހj,qeYu]cc4Z۲Hư,Ieɱ -aG3rH#;<3*^W@,9܍Pp8,˲dY)Ɠ8A&Bl b #;7qqqQmBȺ-eYB%$$DBP3aGIHH0)))&>>"c۶|(r=g۶mE7)))\@#c~LaivM$55լ[.qeY&uBkpg~7֭Sjj a~nǶm/!Vd2v4 &~EShveL~~~tt88y-y8^&///-ׯ0a4Žf$9c BGؿg'>d vƶ :qctwpgڟٹm+SyӐ9/7u֩k%tBGL(O >ԫW.ϟsrNOd?[mΝ٧L:+W^k]'""??c4 *T\g )F2#N7o2t(J%\\ضu3vۼCG$<<7+s֭0``bc~?}>>8v5 egni ߳7_QN.^\.gunՊ(T*j$=-h6iLjUS6+ 233Q*[TT48:8`iiIBb"N3grܺ}7ZN Mjլ[V*+WQ?q}>4zMq*6e2j'{ndT$=ΞG$''m,Gѥs'R#+%$$ԏ!G;88:PvPd˦g'Ã&/6 :mw2\ %--x>0):5k3372jI-ˋG&yӏ$zN+꼶+9ڊW*u6+YY /><( ߳7;vEK gİ2;;;#hܨӏGIT|daaAZz:iOW'֭Z@ww4pxQztv[6oI gǍqcY*ի1s.^ 9{WϜeL|MaO&55a#G?șw^339|9p+˿X̾;IOO ܿGӻ7s|<{vm'9%+Wq9oٺ_,EaB-Z?cO?XZZr &LQW:l(YiM(ɰ%##C;|ZJYnccCrr2kooGbJ[nccCFFFI2+{ThKrrrXqm S2F#1æ AH H$F$A#DD"hA"4 aϞ)̰zEA(>%G0l~R⎬')DZQ(*ȥA4<3q'F(7TZv5 H$F$A#Õ\ ^^"hA"4 A\M#TV뛙3fXd2((WAꊱqbmиqc^y啢(133әS SSSmcbbkL&B 3KLL _;{UV%5h8v}|e+V|!Ctze=YB]3;~?&-vjb?q3gqO:Ԏ9B8~$.SF *W̵߮#˙O'//gB.Rn]m\͛urXo>kז^odذTRC-SSSdOH&ycnnA֭xu+ ں>dʔɼfkz5t 1b$~@&Չ0d25^7o h-vɉy>mtԉh1tkDFDT*qrr RK)rӓ5kVk3^Z<55?VFxC\ߥKvɽ{aFS𜈁[ѳGرC^Ŗ5`ӳaeeQ>w988S۷Ԗgɟ,--133׾-˳2hFŋ|bv݄ -[ٳ'NNN;wB#mxfiiIZZNU=іxx4U%p{a޳Ns)*W7l`{ ))'S'O(#ge p 8:҈ѣ4[ojsWz:U>j 8K7oPR%BYR$_nJ ju8ׯGE[[ ǏS 񄏈e-WʊW o1u3v635˭wP6#ٹƆ !QՅ"P>O4eF@>#cG1Ofo.t2hsݺvʠ6akkCk鏇UgL8G ptpc˦kۆ\zSƲ;gv6 +˖b4ui۠{311A"fAc4exuY:uǏur9$ed677#--]Ȉp1RY ,--INNεƘI^↓HNNwXAvm9t.Zg,K?],@XT\5k_۷k˝hTN:MsOĩ(LLZJ..n@Vop>~4i/ص9Ĥadd\.g+qtp`ϫؿg'NNYׇ{پu3[.m,N?=Y;oj٢9wBػ^(߮?ߩZGfS:|]ѽ+Gse܀8Wdd\FFFNƮ-s/>hJjj* Q+;}^TX W_յ}fZ.pS [w:~өG^SSSmAl\cnjεΆM3aC`kk\nl̾KfₛB.KMMelV¤>˚U&Zŕ3?yzW3h+Aپ ; 9iLLLXd6g7Z8{ nݖ狀W8ts1+OYħ cN^zٵnՊ(T*j$=-h6ikr9j-w+ rٶ}'>S}izCIt2;wT*iٲݻwP<9%OFC)ΘI3 aǎƽ~="99E"p5Mdd\%!!W\7-d=sQQU̳}''Gܽcg笡]E%vxO|_Qyf{0֮ۀt Zf Dh%jլy1~\Bξѭ+J]gj,TIILHL&ãIc&MEOP[ݷ_JGGeNNDE|?L)uT$?$[WIxDN~dfz<=1t H_kڴy3GCA= 툋',,L{-W$~+6X D( Ȥg6sSgR>C 77<6Tק7G -imPa:wҞ!jp7[sm3e]^vgRfM:x.sqvT[[13BjUx㍖ܼsbeBCC>=z~¼6iӉ+mW?HLf@`iiCAlݶFMYt11L63gϱ%6]MңGtrkod?ѣdRRݧ_etNMjjF+ڍرk7nk$TXsqqUݷ<]~#`\3|1BY<6ve2$&& ވ(\|I:!!A͂˭_&՗+KB|C͛t8cysE2sDd${{᫄? Ch4ʼH d {㧤͂˭_E0W.<3#~݆ Пݻ\9Vo܀xU>>38hԙYFO h 4BR4O9ddbj /yyn9 BIA#rzyʣ]qJͣ$KjMIR $ FfM=Jpt!/h =s2F τ#·\Di2 wyEHfE\D"hA"4 AH H$F$2얳_pWDy{O$J: 򋪨;D+I<Wr՛|hٲ%QDGǖ`^8\C{;{fLԔ7s`$nڼ޻kזyIIyL]Gղ%gnܼUGB`%0 &p[.fffLݻ[Xo;%MdM̘9Wq!2|`fLeʴzqll#"0i{ ^{*ӔFPldddo]&MĄ:lӧw e˴IJ^n]051aAꔫj~^QM-[4p\ժZG&aiigKQP[r+V~)_.[Fjz*SM####}\{ŋ9y*8:~^o`5nGwmBڵԮMy}ٱu3kV}USVMXwlތl曯o0PZהf,KSR[`4pwj.÷tn߹CW^Q;m̞=r ѭ4\zk:n lʉ'9|:zbl,זٮ GܶǍѻ\P9 l}x^ֲy3ޕc^?p3 2յ2yC3dpes񸹹,355㫯R1}:z@DNϨоdܸqCzzzh: hd2W1yQÆOxy q]TIIh,[jqس)h*W$.:w gVc'''._}]n]ݹt?6x?W40,,zukWL?~>WQnNL&WGl*ذck֐Ғ]>{N[/>yLrߨTm{{\\ەȌdh2_DDdTݳm۶QkXL{1̜5KRɦ͛u;k6|8k׬aA[Hx\3 ?ʷƍ^؄iUhW˖`Oll-WVu򬛐ݻ~9\sY#NI2=<ؾc|k]Xv-磏>ށT .\tI[WT4__ƌCÆ j0LCiqj́sIMKc|ً#Gݾs߮c"oDd$d z~ɓtsZßr.܏$ܹQ0s,232 FdD$ÇqF>͙`vIXX>95p=-E bS>}>5 ޠ>˖,ͱ-[4gܸu=X[[ӺUKQv`];ww(ZM>ٸg֭]P9+l˗q-{wncхnQ #y!ftd*.ī.|StKI1%2L&ƆD%˱!9%Bm(Rk⒖NZ'}@-eF!!!AcSi(/Ïe~ ayc"Lbe,e,(alA^v?//758eAg'cѤsQcٴO)pGI*J$UD@16 %bWME$Y5hhC0J"E4AY АVSRy_4yǹ(Vє<8eF$A#DD"hA"4 AH H$F$A#DDo,'IENDB`RaySession-0.12.2/manual/fr/images/audacity_ray_hack_final.png000066400000000000000000002276371417052567600244050ustar00rootroot00000000000000PNG  IHDR"! pHYs+ IDATxwxUlI iHA(>6,XرE*`4AjH'=[fc%NH(}HvΜ939eFv(TB!fMWtB!BM!BQK$h !BZ!AS!B ~ljYYYiXVivUUie߫Y) !BL=8?VU Ew\i4V0sss۷/k֬)*'‚%??_Trss)zTMTM4M+ ҥ)BqQEx\ҕU!!!iR4MEuUUU<٬i}=fMi֬)wlٺϿd!BQ[PrO,Z<an^ذ*;se)+B!]}-/麮x<r)NSQ D{ՎaEa4С٬i2*+88LdCN|Tcuvv Xcu !B*Rԁxܽ:˕%//OR\UQoOjZ-n۪iٹwZ0ex5m -[ػo?M7.HMKQFl6<.]vLC'{s]gnݘ6y=b}]ڵmC֭p)'R.FRrO?8fw+4XWd6v%$W=Ž GRr2͛5Kkwĵ}$$W-B60q~8Eqy<O@@@#* m:Np8pРArWWk{sϥEVz_o&x{60~I7ƍɰF3ь3t;*SxǸ~5Wvն-[{sXčM}6ڴ)UGy ((FϳATvL .z#q'kӹSGG~yK^LӬL8ƠrۭaJQêRϕW^ŝ;1aXF6Xc1aX:wWQ=N/\NkNd׿u{n;&nz֭_q7v$ݻuccoyj^ #!00Я(ԫBXVl6[Zv{5MMy`{1d}-4o޼T}PU`ܶ/Wt5q;e_7ldiv8sYUevcb`Vo6TeFQra#ؾ}͛7ϭT]B(ϙxEs4S_Y!={u Ə}}Yʟ9`c 7חYn7vFR%i7 2etڜٺ̐y;K ;n"Ǝ^v-Ǝ"&&]w0etFFQnTEaٺ56)8r5W_fo__l/MđL5jKӧ[0v22λynSxqe̸ .z1R:wjrkgsin8NMȆ( zAnm,K1׷7wG3u~w̝_6nè>,._iӋ]mz^C^CEj*3x+Vܰ!qI׋pGs=hŝ;ռ: hޜqcf} 1 YUvm, /LB6gxaĨw/DDD`X ,Y>_x ^|~ Dp$%'vYz s2/g}?BeRǪASuE4_o&9,5*9bX`qeL_UȄ7ظظa(dȦMV^atΔ)ә0~L@f}X;uk_QȜ6e"Æb>b47R:pHNj.CsÆ0|hvǛl޲'zUU9b#eȰ((4!<L7~+3g<-_pytBwSon7aaa8R2'w=vOew߃ UbgXT1S&g?yIz+ުbEOː#ؼy gko`?ILY~i躇Y|H.g9/[V+/2YYQW_B˖-ضm;͚6%&Qf'&^=n##G2+u .~ ˖ 990ٻw_Pjoִ [wgue?%tpa2iٲNd.|_ٵ~d̤qL#J^^Ng{Cz!4iI4hUsژo65mBJJ* 4Lu{1M2l.J2Ĥ$~߼#G2ٲe+99~e:(**}'%*aa >)juS~$5m@U}]QOpl}ޙokSrSΊac""#%'7u=H"#"x}N";'W65-XwM+HJJ*4k֔ҹUvmZjɈaCX,H;#"2rUֵ/(`p}/^*=?B+4MEQ'HѬ7-[K e9%s^6: Gv]Kwc|hF`OPT ~-: mv/^ZqŸь#h NQ1M"##PI4j؈#JS l۾7|#F݈i'sg.|_#DG^H8n&wmdD=kTn _GHL<웯Y>fkV^R+n7fO< lQ:u_έk3}+/ LU︲,X3^Kdj3EqйjEӴb+U~oKWZUqz-]#Xˋ^v0gu]Qc1|(Wݝ:^WwY3&n=sgAƑ#$$k|mZOpC/̝MF:dь3oC7X~=&O-u=ONIṑc6d0<$N' |k|z̛?/+'}λoAJJ*G23`oέk3Ï9||#2{\ LS$MoK%K!~vy_ɡD0,d̨xM%DV2S㕔%%%Em֬hX ðl6abFDbJª,o֬){cx%@vv6 |}~IӴBJի.݈sK˰hJNNs+iaa咟_PԴJ˫[m[μ"6 233^tbsT+aQ0mK2dff ޶d9R澕[EbJzFaڮ*a,WnW暫{#8L$:*FUUEu=OU|RUm@oРo>3**ʈ2۷oouѬ}0}jfvv6} LQTEr+~Am7 *v*'dBf#Gʯ,iqLVyWέkxTԶ"x}|'8퍪f-l޲je>TB!NM/8E}d7GQjg1e QUǎ4MrJjKQ7Ld_6Bt]'11d7C3?Uq:CB!)B!jM!BQ+$h !BZ!AS!B B!VHB!B !BQ]l)=B!VHB!BB!e͸8%>>^IIIB!L)))J||WffM!BQ+* ҫ)B!WbccGS!BԊ*XgS!?,22򠥶Rib:i즜TU]6(wAU ]q"B)TДy|jזdRSSOvSN+QQisfkvd7E!SN92O``jHII%0 d7C!s)h뺮*aB!De^wJh !B㔚)B!N.4FFGS!B B!VHB!FiJx)#00]+&M&UW)'wL׮]sg<5VVsY툉.CQUgr9gWB!yur1P}xGp=x!vd7OPPG n#5z bM|ɧ~2ff7]w D!B԰:4oy~~frUU rrrʬb`Y/s{pp0eh^QꅄnXP]ӫS=϶mx`2}j(v LAA焴G!Sh>8~ޝ_J{KW+ڶi@tt#ΟDz%YSa߮]x˾u͟5\p> aoiذ!gт/?%bޘ*v˯Ҹqc=:V,g_݊\u|m;oŝwQc[,ޘ߭Xs3+8o{.,_-?_p}:ڵm˷,t!Pz4ׯO&M+,׽{7Ijj*wq;SN[( M6!<<{^(0}ϤSd<5Y~bcb{yJf1fH2]v`1j4 {l|y5U6X,Z~7{K.ݙry5<3)_occ߮][zz|_{<f&7i2rp01c㈊1~$V\I```|qF ^y%MuC!ǩNh{/nhVXK;ٰqanՊm4o֌11>sL0 ~yM ]ڽ̢uV.NC/d8NZM4&11F 8S'Ob׳YJč۶;!0&;'OO- IDAT^b%cbh׶-]ۓ7lY[/{ٱc4o֌wƿeI^^yyƌxŗ 5vmBQ}uG3== >gpETT}bo b:_`x|\k=ABrR[4g)(7"aw ƞ= `Q9 w(~Ă]o?v<7]w-o.2]tŗ^/`KJ-쓏}_nݚ1F`Xطo?;~d$='x#2B!8Td5;z2ٶmz:baP!Xdۙ8a<8/>K,e}nBr1M֭[s=|͝;w~ ~d$k׭੧R0܎Çǟxw{֯/W]z$3 VL2;̬cB!Yuj7䞻_>l6!Xɍ?&-Z*֮[GVWF]c۰Zd-ϠStN'Νoyn0{UҷOovf<,]ܷ0 t]Gr{Y ]?Ѷm[.1 ,,̷=9)yeVƏ]!Bl5?gXx!?g?YS29zqϙ/)++>ޟܯbsÙ3w^oM{ͷh۶ ɜ9si׮cтڽ7^dytԑE9c,=0sf}GKJO\\(J˖-fia֠ :L 1M3<1%cauKLnN‘"Nnn1#RQx((=c:αpхo<Avvv[D\۳'O۫[, aaa9쮪*}=;v[X}B!(:*FEQ2E6 #(ZY$h !BZ!AS!B B!VHB!BB!4B!D)B!j)uRUXnB!D%>>zOUA3X'&5%d7E!VEEE۾=urNˡsGCBB!RRR>MGqOˠ)B!N}4B!D)B!jM!BQ+$h !BZ!AS!B B!VHB!B8aڵ ]vŝi׶-K?Ep}Z?. EQNvS*կo_ }?jB3hkƍX,4n#>֎8&:%v 88ݺgt:Ovs*LxXqKzz:lo/ !Nczф6I'm1p\(MÙ3uMI d7&ASPNG}N6e2&&_Y*U(aOO(*gfmP/$lGcGUUمퟟkSqv]l6_j[PP. SS jӦ_7`o߲K{{4Mc|b__I׮]۷+->574]߫]va̙+-u͟7 .8|6lȀrR_3n~E 3ol?|> aV_W]ŷ,d9Y=:zׯ{E fYȈ7nb|b9O?o軼qp\f߯\믽 @tt4~Z~,?eKeoψ.8_~K/b15v;ڵc+qL:W˙W|DGGb9W]yo[&Mx滬YkV}Q#=j$=8V-[ƌWaْoYy( эPoeQPsPhڴ)\ZEӸw@&MZ:ȈQHH؃f㓏>gkXTUhVS 0.'M?__t|EkOUL~*7oGa&ǰXX,NH`Ҕ :t+{ڌ+B>4kg0{,"D g6iy!z+pGtm;9"4M 7дI2$!aѤIci԰k.ڵ6кjj20 hsiXXwfhs晼[x<t]'==cK/bƛx< _|)+Ӧ@JJ߱g;|˃V\}_ΑL4w~#Hؓ@zzU)ߒ{0'y,\=W~-Q2uw~S'O"-=^x-[ѠA ?]-=JU<:h)$'%ӼEsQu,=22$+u836gax<#!77cg<|Z-[V;86V/Ply:0x0s=`qٸqgk9 @DD8W]yo{PP٘۷-a8[RMxDAAA< }SOc>>x&)9r9sfff;aٲ4o Η2yf*GgKh̻}Μ>5-j|駾[KɐaØ4aʄy=AAArj%(0̬H}E!""r{\0 {.7]a,\0^7_ !N]V'*ߩNqlhsqXӹsg~+TQ7*(Ja@juUUu;rQQQFBBbFEE۷7JͧMq*/ỽO}-iUaJȄrZT\W*`*SUvLMf7rs7MQP\Q{ B› N}j&}^DДs{9BQ=Ȓŋhݺ5/n85tw^ř֏iu&40=!TIBG3믥'S:@P=aI]ɑׂhe?&M!(@BuD]1@\IK7|mqLӄ'ا B!1Wg ?~`V0N{~MB!,[D[ﰹNb[Szp[NO6 B!,gz4 v=vjO~+_> Cǭ~`D]'AS!uVnN6Y9j92 E5ىJEѫv[DV !k髠Zy82b{Qe [ J2Q0@T<(fFdM +z:)B:K@jU0t&hv+ tRϹtsi\𫧹MaͦW %~T,h8 `n ^{)D QUسQB!/'7mJ=z'm(g܂@A-׍WVv;%NK2K., D{֒ʣfC -DZ:_9oBTYgž}{HJL4@UL#<^ʖti @7 vZs۴[Qj7?t OB!,=70dz[ nz(>䭪мFZ٘Dl@nZؚ@c$7MRcy{7-z ;SM笳ѵkW㘘*uXh!ׯVUW)n';O`j+i֬Y䡇.$u% s4`L¼AsSB wE5ٟ [o^ӆ~Fs4 kss>ȓ YNJ7o|:T龡 Fjjt_VlPP`7,, 7nRCB)(( /tVBq*r$-!+рi)٣,iVҲ,&ϱڲu+}&--ٳ9pVnGQ >ѭ%\.}vAAAga]l6f=^g޼\գwu';w$**Tbbbټ(Lg}ʢE⋹L2ٻ訊6ÿmIM!@) UN轈 'Mct*]CJOiRH/G%K*9gޙ;wv6}wҤiSS&~a'c:<Ui{4̈́EtVNS`\ 7LVSz9RZ#Zc4Bk~htJ(Aڵ=>;vr~;ڷk7c`6[6DEFY QjU6i̢KLYm """(T~}: @hh(۶P^tdW紮^%Ks]T憭-vwѹ 5bɒʐŋ-~{߿Gahт_fZf5۴Q恶nݚ 6 !ċ*o]0%l&݌Cp'qynGYvO1MiQPb$ 7ݍpy*t/ nXIppJꊳ3}<itrr"((gR[xh7 `0N4<<"PV>86mr5BBE NB`=͛7g!H%t+ϝ{9sаa#OU{_|!ċB˭):"4:<PknXYs.cʽGeL7wěhͱyj^hST|>t7oui7n$,,' uhBTj[oUsNmמhիkɲ>[!Zn~]U{Ki^,>R  4}:cnjfߞ]Ov8x0m/mf f]u7r=~؟ofr=Dnٺ.]:3bpٱ۶{!Y9Z5kЯ__V^A͛%66SJK7$!!Çq5%}ԩL6C6o۷ㅿŠR氆f-6oL2eٴy {nJЛjL2o,X0MNtt4_ !d@ $gQdHaa̘1*???UHH*::ZUdIUHHJ6L:^KJJljl6ۙfǀMLʕ8qDW|ߥRpt,Hrr2AƆ=$S{,2`oObRspp 99888l7hϮjt?TzuݕeS\Ђ Crr0QexN`DDDd&f;99Y,;n |;ibM!JFM>իWgr}wWǶ**\RELX ^%%$`JLL4nܸa3+T`3fLң)LXXXl\H"iTGfz/'y :Ll̜GÐҎYeRRR+FEOҴiӆeyB 4899帹1ϻJB!^Bh ! O^DGG*BB VFB!)H!B 4B!D@S!B 4xFbcb(^yWC!"E Yb !?{yQΫB11_|$ψlyWC!xaйB!h !ByW$H)3V*_B(bbcl:YA!!\/LrssV:: 6K)3R|yn߾IP@B(  lގ ~RDZx*9i毰YVL! '09i1%B!ȯqK#B!"OH)B!B!"OH)B!B! .GyY}4Bqξ][b5.{Fɟqf 4xxjW-sev>__BBB2=.uLt666ӣ;/r˫<_A^yٹjԨAPP'Ng)|v|U=yƍϜ9s+Z(%J ..;w 4sPzun޼.Zos%2K (S,qq_ܼy3]}R)>{Pjnݾ ;;;jԨ` (83OOZoѤ \z@%JPkhZ]ŋ-]hQ ǎ8nkk'O5۷{q/ Z7+˵kWӵGh4ZS7{Ҏi_sge}xY|SeJ{k *ޠƍ5:c/!?ʗfӦM]]{ {.]V\x1@SJ0֖:k|Jy)T3/hѢ9^^ع Zʕ*RrhV|Mt2ɳPhQ} 5ģ~^ۛ{+/)] w/GX|)[,a޼4m7bпGJF1f86ii}Ə@ 8q8vvTXݻquZx{}+JGv=z**T`^e˲xR/Bjt:EArz=$''gX'[[[3MC&+?'ײ٦R0 X/Q8ΟWn@}ܧh7 C|ݺvJ{V)`cCl\\>mt:XMd߾}.TV9,e6ի>%OΝپmw`?c43{6vRJ9sZA9cFvKUH:uLF w`}9{E} ,>F@|9bզ=k;vb5JOGbJmӚSzxz=fa RΕ+WJ0nnn8;; }Ç3un߾a`n޼AbEcVVVn݆sfI:ui!.dQ۴Aղno `2cMrd2~b88ud2V[SfjuΜٳ R|ݷ4m7779q8:G|ҷ&ҧ{+W.|:wfvCǎwEݺuqppPURXne~fGղ>rvu6J* ;nݛi?MÃ]A߾#Go! K]Aæ>rbo)FG}֮d/ذv%u Si"?Юmk rcMW_yYb֬XF֭X׭򼴧'׬Tfu/_UCy&|;a,׬AG[ sNԯG^ÏS>:t@ Օf-ZҨqSCyOʜI*妟8pMm4l؀RJV㳃jmiZͤ9p6mT\"OVg9Ԯ[ o/&L4lܔz GYKMܥM_Дe9lٺ-[ܻ%AѠ{zh7ma_Эk%]V)= :VibŊң{7ڶkOفwxjÏ0t &OʥKad{dޓ~}?W_EV4hԄk2}Tlll}O:|nNʕ+,\b=T Oǟʱ&Mr-_ƦMөc'%mŔ(Q }ԩSo@}|||Xd)m۵˰> M6ʣt,ZQFѿtUhҤ &NdɒYB ̙3ӥ]|x*(Ǭm?noתEF,;#ׯ_e˘0qR *[oUc۶ml޴m)="##8~-[RuؑףQ/NݺJj:&''3mTj]zuǟЯ߇@ߏE~FNR(V~mjլFfr8B(Oxl+Xlf]ј?ӯ{dxֳ7zb|Q?>4mHQʱŤ1'NЮSW|Џ aeSε"%&MyVc/9v8gS h=|iު-U{'6|VM=_}%~JzΝp͛[?d̙L6`AC0{,>/{Nԯ@yZ8Vd@TV9j]pڢR  ? xޠPa>)22 +)s[F32pu3.777-"8(g''yn_on?dET^˖ҷo_̸qcϸqc)] |3S.Z(իW\r|wAҶm;-Zoe,Y8G1L_ѰaC&OJPPS3dHyǏ.]F{4֭[+&#ƍgt>]aV*T4FKs1ׯ[GV|0V^ך*!!GbٳcV*:#GSNw_}7ҥKop1|HJiӲYLƏV߷RnYt2[HmO h4'^ay,]4F [, :RJi QQQ;~ƍU4iԐ9+ٙXiIhþ[`] 4lWvFFFizF[=),,Z͐χYr9+++eiʏ9kZ,qssl6&0p,P6tAKLwwqw}Nf<==i '4[eZ6:٬WwΞh^X^իWi֬Æ/cN޽KY )VFx>|}q1*TxM 4sի]ƍҿ7̞37dsU4iʕ+W,4lHRR"gϦ@0}f._㺦:u$[lf5jDѶmgVXIB,Vٺu ;t7dO]=0{,z|M&enY*WWte(s]=!<<\Lt^(fΚ˧gݺtގ^l6SDq'|vfG}9yz='N {nڑ=Hko)MEDD$jQe2^yN?pV-)|Z*PSsu>c66;wr=w Ruh.W9revZ@ς rm._B޽Ogׇfi?~ypttTjyׁ^ƍSWfj5]:wHh"c']{ت7j:%+|S+ѣXd)^*0cLڷo/ gᆪETZFCXz S֭7+ IDATJ*eXFV<<<,P꫼뜿p^9RVZkkkNwdV i4Z4o_?OǻeKZ-jʕ+3̝37׷of,%KRw:v7Zs)ڵK#qF:uL>gZ:΢S{GzCٲeȔQ;;;ڦp>:Sg5oΓzxHi>XV f~._B(mZYs };ν{wۦ|jl"O@` +UT۴z;ܼyQbLXʷ=9}==Yz%11(`C?x}}1cpw/111X[[3rC1Lf4NOΝ0|^{"߻woFe̘oSؼe+ÿRϩ\|1c?L;f<\x)7HΛϜY3  !99;vꫯdZu9g6Zò-zW]ˤhִ),3Ϟ3Q#dbccx0þ'Z5kЯ__V^׮ѩS'(Π7o._~a̘1L:,?dmtܙ3O{x0s,z=j,oeOݺu9{qya I&QHQ"##ÌRz4iBTT666\p^Yd)\0nj!yTf݌ҍdA|IJp/NXt -3Ntt4Ǝa欔H5nlћjݺu|6p ϳ8~ߟ{o+WYwڕ }Nʕ+̝3&ҭ[7 ˗JGdDD3g`Ķ[)fC$L&t\v)'?uCm,M[÷Xtj5kxZ{ֵ3}>02f3oF~ImP:,Xwf*6oN//%}؉|l1X[Y3 1rEkgEaa̘1*???UHH*::ZUdIUHHJ6L:^KJJljl6ۙfǀMLʕ8>tO^zNHr]: ?)udfuis/V'$ɦ g@(XЁSu:,dERDtttF1ˀ@hAZ,U^{we[ސ!CYbPRG*2S^OXXX{{{Vm;NNNDFF*jqtt$444ÿoN^OxH"ٻ*xammF E:5٬y [TuhФSψJѱ љ+sqqk cz:qAfӬlm h,<b^9}WΟ!-wWǶ**\RELX ^%%$`JLL4nܸa3+T`3fLOhJJJQcv?n9-d2e84{Zʖ+H&YȲG*))ȧ`6 Fc۳Cc2i3ugVVv*x;ޭkWbcc3]XoI+!!!o?h4)gܔo,3'4999vKJJKܾ}KIz*\pN8AttEj۷{q/ +VH7M\pSPyo=aa;{,ۣB 899Yy&`\B hK|Ylo! 4RFu6&&&yWrvrJ*ڵ_^g_|ɧz* ={K oof3oU-[6s<=KpE (оwޥjjtøU=;f4[lQ?g\ݻGmHLLTgٻuFɒ;o>aiڴ:wfٲeJݬ9r-'88ERX1ԯORRR1h^}UopvZLf}6x~6+W0h=ʢE ӕ3g\]JllrlرeB!]h #ժVS4o֔u7dx ;mlljJ* ikkkKlll ٹ +]ieeFÇd$DDD111$$$FDD8'}NDD@ ,X0~<t:(X 3gb̝;GV y ^˗㉉|'4mZLHH׻;>w:u)7GUދmZs}%uAfիVe<֩SpͶ |ŋ- [!ĿKMhݪǎg=קEۛ7|0zz>;0q|<]:;woGTTÆ+LN5k3N;`08uV^ȯF`SfaGpyjժW#FjhLi:}R7nXkݫ':T*FѣhѼ?Z5k{n.[w&+P5<H>f.}z~}]>F1Wmk2W_uF|:QQ7-Qk4|;idJݲ%̟?ZruΘѣNȼ c憻wcA&[f-%Pmۆ)Sq?zHJkh4j5mm۩S4hPmZӹkwiPS&.i5:5: +Mޞ~c}}/,egϝt:7oJ.݈׻=|:ώ.] 2n`~EId>r Af?2|{.&LسwE7^?3B ?ɔ.3hmql&NkT\P.續gNݺ,Y֭)S2jo!.Yu.T"ǎ'11{vӮm[[m'00^vmJ/^dTW\aϞ u8y"ԭS@",UĄDZR}4{a-uoݺ[ժҤIc4ME^%Ku=)u=>}ݷO8t`ԨYd)<=#<7^o 222ôH 1V̙3w>W@Ν{{;-#G8|UҼ'2tŵxlH*U_7^z[!ĿKz4ڶޞ;`cmMg(Gݿo1'Kdy*F#i'c&ggg>:DI ;AҜ>;x!ׇ!2w6mޜevg8:92jՒP gz^h 0PB>xxBB_żٳg7'zC>|Hzuə̵ íZ5kʴީf͜˕qiׯCv)[;yzg4yoض};>DDfM1|5{![[=J=2 )Ac9kvu,^8f\z <`)DDD0a$ށ;wM|05kNrr2̛7A3h`%߬39s+W([׮;J !Ȝ˜1cT~~~Uttdɒ&66Vm2tz^dبjl3͎!r[*+qĉlU^=GĿ @xx8.`͚,J^LKRXd? DFFDFFZldZ!봪W [x{ǁ3Lh48;;O;::K DBlo$/f4^:>z:UT**d2:.1...IV' Sbbt \B1c_Mk HLL_|r_\ Tfo-110Llg,ӍF#Y?`Ͽ%}**x;ޭkWoBI)rё9g[[[&OƝ;ww /gI!D&ȵoݢE١iQ/B! 4?$BFB!"OH)B!B!"OH)3Ca"ϻB!^2E?}@B<#~W]!//>j 4xFf3~~gB!#d\!B 4B!D@S!B 4B!D@S!B䉗2ЌyWC!"ϹrRnoW ,UyWE!"OrRf/g !BWCB!'B!h !B̚3ގNaNmĀY0a8vg~> {th45=vۚUMZ5[ݙeMvBoeߋ\Fu|oERH-YĦٳk' T"dמYݝukPNm%hҤ1{vdokXj%U&[7ob5ڱ3l>{{&'+͛6ٹ{͛Y=Y}jJ,5_ ¶Mmկ,[JE7zTڵm2rp|=Kiƍ_x PURE|9Ho@&sPZU4*-50#z4IX[YQL%Pjtҙ_iso>h|<WWWQhܛfͽqqqY(PMIXYY?Ύ[ШI3>MWNʕxj4nEЩ gϞ˶nZNgQVCpq j*JZKooGrr2;ѤY ڶkOÆ h3:TPXQztFvб3?v #G}M->RzWׯǦ͛)Vʕx*+_f͚9jRz+]Ή'@ungR$&$Dժ0^ zS&11ݬtseŪDFFa6Ã)yȗQY8xcGuG{y,gRRE*UȀ?dyl!|0w|.ZL޽On>]>aazB!&fΚMrrS-B͛xB&} \zʕ+a2Sճ=w홓:ݽw/M;9ggg>:DI 03ݼvv[H 7]09iw8ptt$88$Gzrg0F::(hcڌ>-2/@Ă_nw(Y8߷HIys|󶶶fq SN>ѹ8;9sk@J `_8rheU>L+hB<ִ+]έoQn7oZfÔ'_Wf홛 }aaaO?ɲI^^|W5d1U/`1g7:*gg'߸aQ89YnN>I);] #D C/r&]nZ-׮HtYw1ױB2dV{Qu;Yܹ>x{;VNN"`{-WV)R-SƢ[кUK*WĎ;v:~ł 5M{8qH YM4V.\8Y|GJ~/\$0(Hyܥ,  7Pz#;\t1u/u׀@J{7^ R%s]Wuj΂L!D!=/U*' f3aaa >p \$2{8;}CʼDEEtٯ,^"""X~CΝ9s6~r݇ݻwY0/ٶXW.ZlQNbŘ6m Qh4ZB6|Du;x0m/mf f]eع!%8Ə߽`mmQ_,37u=fLNddquve{ppÆ/`Mt֪Yw\U׽\.p/e\i,3ekjΆJs9ɝ+eܚ\89RQU9e{ W. פgsKO?[| (?~lkxt6eXn#ӦLdOL~7d(̽DRv8t(䧕?GTT4kndP< VDDD( U*j.11Qi05}ZZpT*ZѨ37c76ȑ#VkԨM=i(])6ݯjh$-= Ν;6K@llltvv`0y2/7t:PTZ4SRrZlYO~Kt:*s[R}K^T(&==,)ιRJY]9;F!뒺#qqqfqrr 99/Dv5$$d vJW=iԨUz׶ "VP$ D྽}jRRRRLj ^o|Qzv\;9/ӕ+WxS2[ois IZa5jb Ce[a^Ŗ,L}Y*#h$&ri0 e0>xj>?II$%N&%BI4@=,#F ~r2J3q*)EI#}Z@'Pضml߱RJVlB!$O%'>(iO Q"덄B!DDS@NF%\:ĐCBI4(mo oIa!$Biܸ UV~ܡލСpODDS"< F|.J Jy@'$BrPBo#G&!BQ,$B!BM!BQ,$B!BM!BQ,$B!B^o$D Rhܤ)...;!Y|]쓷 QH)D ФIS"9qq"#Ӵ+V'$B:#>0(QQQTVE~J@* QX4ҧ($c(iO Q2H)B!$B!XH)B!$BrG(iO QH)B!G+S ?WqY +Wڵز5cX[:mΝ\"OemVUnGGG~M~=Fc: ceO?UU+q5˔BrqSfTTʕ+V&l|HN3/OO&~1c bСڼi+W| >:@vyrA ӑ#P*|aoss3ܿlq OWOOR.yTT\a*awЪk( J+p|*,fzu,k8B@j 1?/\4ͯ@.G1ח ί}?ɢP ԭ}?E_ͱ'I6(~?Wϧр~̚=lރ(aQQQtfn߾mzz:vKZSOs%Mg,qww'=֫{`08`ѓY㏌ Z'+;#11@$2*G"pws˶އOZgҸ-F#! F&;jѷEvqq]Gۻ 3Mmvܣy%[H*~TӅmAGo+FkӺſ2//q/SI4.^ĺij\bbcqus5ˑAfvK)whzsڜusw3{XJ%C aҥK뽞^~đ#G w~劏G^Ekbcc{rE0OOaK-4~0O䙧3<~$#Eӑ@zz:o(D8))+ŕ|>cvv{=ޥ+/\5KœL9^`}9)D K ZMݺ/Nt4k֔3=|0jgy İ:wh|Gf<\z\iZ\_\x쌇Gf1nhvŴϧs% @ZZ+_dw]N>MuF2!аm[ZT*9y^:VI os(_<4ᇎ_3eb0+W2 /zPզOӲ,j -Avq?qa@N^`[)(1f dR>F;YWq&SNcǑ3Q`%ҵkױ`<6o\RiDz+HHH:י:m:f7)9-[CTbiςٻgc+/SR%>5)S?g?rA+; b'Nc70 ݻ ijL/}ZKƌa$ >C(ԫ6iLO?[| (?^L II( VGjWݫ'..:&}61'`0dԘ5`0Fsm5wocOsMŏ?a; my^=vϦCNh Q2(|+"""ъEժUJZm4 >--M 8*JhFכѱ ̋r5jȦ N 111VR+!Kbi6GPFBBB_T*q-]Xu:*mNxP(J.` ]0;;;\]]k*ʦ;?JRJkA$?98B3vvv9M~󹺖Ɛa =|h4nԐ-)e!$>5Vˏ޵BU( !oooT*ӴZ!555C._ltF^o]1888ׁ\h`II,<-DI w舳MمB!l!2ǻ"rG4ҧ(FB!XH)D 'DI#}ZA. QbȡY!Ŀ$B w{艎~ܡz= [!Ŀ$Biܸ UV~ܡލСpL%%DxAr\ (O:I4(!,FLB!XH)B!$B!XH)B!$B!XH)B!$B!XH)B!E}a/LfKQ H-B!Jlw>{א|b y~ ׻@ !Bs%ҹ}g d$ۆB h!BGTbMdϦqԪU~xaJÆ iJt[\F)|7|XnnqOž;^ XT\Aof׎m4jЦ(JV,?]XKGiذA1Ef]Νm'[لRB TR1G$t%:|Fe.Jڴٹ(ʓZWb[~q 7U?Hٿ#-ޞ)'| 6nIP֛]5.eMٲeM /ѣ6g\x|HD=~fm/[,̝`7FB8} ݺ &&ooo6_ˆ  SO=Eҥ0q p֝Ȩ(^~:vs׷}6oӦMQ(2ͻyeѝST*2y"{c888`\;GpEV,=ʷK +V,m3WT>XݝiS&?~Zj%wS" pe=- JsNtѓJZj~ IDATlBtt4}|N?tf|>>SHR.~+U$ 5ɼF{~16ms}T*h[Kdd$zY33{\ƍF׳~^X_^ ~*.;\q `\N>õk \GymիW_~bOP0e$vW_/vp0-SVvR!۾OmoRi`qߒWl?,?^CHHhhڴ ?,[nGZ8A 8v8n6xx"ܹsS3l-mkٳ888PZU.\g{ a\:/H2Z##G)]իU#""J+RlY4Wh4b08t0W2ϼTZIIIauֱ|JSYBjxCSZ5z=NI&{fܼyw^)ܺi~,Ĺ׽U sOrzݷo?+Tj*;qM,uadۖɒ_?p"W\e[j8hq>[hͫ͛bJRS3bJIII39k@Zebwy65::??l ?{gS}\/ڵk?h426cK˫*UO=łIOO'##eeٲ[F֯@zF0{'22t5kMuxeʖ+[ 7ܹ4mu s5aʕzj,SRRXvM΋͚ÇS:T*"ׯ_g4o dæ Ү>>eVon9s-B,~}+EբT؞zzz?xo(J̧o߾m*󛵻; HLJ2ε׮g[Msm7,OΰCLoݺef-qFg[oֺUvp6i4X\7rĐdlڼ6oHh dX*5nzp@CFoP(H9\qUeyyz.]fam>Nʴ)̙)m3־ν{HLL5ӓ(:2{Ν;gddDZZú0} +A};ww߅899yxxp$+?͚K/.>,-Zʁ9v8#%B:LxA݃3g"l%g%1)}BGjذ:umܽ`jؘΞ=ys˺lN+6&gg-jtEgq}11(J n͋!À]=tÍ7ӯ`oKHH0Fjj*?mvھd+?%W]ڵٵ yY篿K Ģs;nRx̃KVl `TV )SlFEyٶm;z4%*t'!!W77mwٷÇ 굫\|٦ٿr:N.MשS3>[e}tDnV̪Uм+fNXn={pppѼYf ,._µk~/Ӱ3ax7M}@J%'OvQt?LԠk~ݻAF}`N+[+W:&&f ?_-ٴa 7{m;+VpF#Wd/Xv5*Vdϯ{Yr/-ٻgC|l cƍc7&6_kv/O~I5ٻg[aKr,XFaǶPlބFurg̝KRrwng{X}ǟi 6o\W1c\ӿo_d̙;t8-LAhd%Ş];h@EΝ;l e/ѽ;C0{Wq*~`x8 euL9LͳoeyoY}Mmޱ![6aZ.\4et{m6o\uk8vxWjlm~ZnaݚyxG\;}ڻoU*W[֐P~ia![ exټ̩AsOcm3Ett"!!AQjUEttRV%&&* FOKKSJRk4uFftb9rt5:]I.I4Ei=J"==={ M||<'''ja|+:r={ut۫ {{{4NNy WҤ:eyqpp@nJfmmk˒`z)R9]FNZGGGbURu-4 }6S~gTtiCm JEBB`K}4,8V\2]tfՏ?96R#IIyΫVHMMs~ZR ̽{Y8ggglurr"99j,e)6FCyiiiwvvWu.xH)D `0dJ;ӰIf*:y2nnث՜8ːaIII!(0MV /qr#|2S222W.ǎAR8u4ÆkYz v{G''bcb0i |rh4̝ǚpttdQ4{%FϜaxxx0oxyyH|w}2e7.eM6d0Zh4}6MsLݺ/ III1ş_ii|.]ӸqA$W_e̸ҧo>zߋ*Ԛ-}b6'''| @VhL/<=Y0nj/ CjL2q1hƍCٲ޹enCCl݆֯3c,a]( JmmMʗ/ϳfVcLh6EUB'\:0 lܴ6W2y"QQݷV-߯QQDEFQr%= pme'&SAqww'22zp3l[nq޽\ʯnZ-Ǎ駞ҥKP(r͟Eq?pv)|1gz= HvokTTzC`@\&&&VR|7rUԹ%%}8oԬYG0i'9s-=+YG:uȢi'=]l\_/6cix=piޔ2k5S2]xbbcqsw3inܼA~'n7J}FWO+|~ܬl ?DC8k<n5J+EVVs6oذ:umܽWX,_Qչ%΅(\+PV-"""ppPcoooJVbl*U2k0ؽg8::X&۶mWd TT gMh6~MQ*<;ڥ3JenS6Ǔݑ#GY=,nn|i^YbXLrY*uhHHHh4T*#oаAx{{{:tho6`!y{lb:h)׮իtTښj4p~<򺩢s!ēKh Q)3prr")) Rarv QQűvzݿo_^"Ѹ2g>dl RŊ@៌dԧ#dxK߿O=͞vu,?ףTڱl E_I?]Q(]:?oo0JwѡSgpK2vxMLΝP(۷˜`!nLRb"O0U !\3Ett"!!AQjUEttRV%&&* FOKKSJRk4uFftb9rt5i:!K .:v*;bbbsh4888{5FCLLLN,,t:#YŅԴG Jee`0xS*.MLll IOOW 777MATRt\ \]]ILL /0bp4TRh΅/5iԨ&Uz׶ "VP$ D྽}jRRRRLj ^o|Qzv\;#9)D a4-0)))525)))e)%y=ck< ;h4_Fܹcq, U^+Wk$;B=es!ēGM!k:m_oCll,..?>cKDS!3gfy*U*KBQh !0IOOx^! B^o$B!$B!XH)B!$B!XH)B!$B!XH)B!$B!XH)B!$B!XH)B!$B!XwFWؗ{@\QdS`B! %6;kH> Ba|귀y 4B!0Wb/ۗ{I&@ұm+XLq !BWD0%c&##֬YMдiի8Q,6o\OlyP*R^leiͭP\2\^:u .;3aaj%B)Ȋ^68ڸk+ھ^˵dKJD_}ز·=[Z0Kk ?_stt{=媧/`T߁ǰCx7:x0׮ŋ4q+ne˖E*;'~=Ο罞=Neita=mZl\ٲԯ_?֪U^ȒdzNj֬HxT:3] 5o𸱬Gڴm8 )6ήIо];4_d˶ɺlGA$ ZjҡSg~~?åK\N3;d)f[S*fENyշy3Iy-<e)>*JwJ~Ǜ+Je;;;t:]*WL.-lI}rұ~(?C;VnBγ<~ܾ}"%%l:[G[$)/%&&2yT֭]M@~y5=f/h3;wE  c7jO?3zH0 d$:h׶-)L9v`jNƠP0>3cBp0u@jj*7l4@,H:CwI_JeN+j5g#2d\aNqqqSF /O/֛yyFoY22 tѓz|ط_3(z e1T*t:NfAt!l7f̚=;wѴiFJNs];#Ο?@5?o>60qE7:r-}|Z1bp22҉3f-?KU?~,?\Wӯ?ʕcx{{cof̙;1)Z| 0q4']V˖@ի0pqqqV㳥͚1c'NjՏa{v>}pYTF>vhܹCW^=h54nVe݌ Xޞ,)|֯eŊU{8:8L/cؐj @6gPjM^'%%}GwԦm|vm<0ղzZ,\Tz ,>]*G:_~}y};T*/7{IpAzNw&--{5z '̟;3ψyxx0oxyyH|Ϧ*`kHHڱ~(ÃiS&SbJ;'ӣ{܉Ν;ѻ{Rt)-[Βo͆ukh -kNhTN<ɳkзχt:|hGZj}4*TZ/Ԯ]O>ƻ=ןаmianC`י1sC|lߗN+6ti|}qrr/\gy,jgN[J2nܸɨ1c?| ܺu R뛺{{t`QQ)WVRۗ-'M[hɔiӬY9wg?0;wδ)`a1-j5JeF Imoϸc:|6˕dyyz2`F_@M㭭?˥˗?` E~|ۏ_m۵ZT* $44M5$;;%~^ ߧN:?txMY+6Gegg6LVT(sqNݾŮRF{~<V\Ŭ9پ-ZjdIASO7:Ңw`I=X"Ai҇~^/f΄M4}Т:vuKy-3tރ6tym6ʖ-Tuˮ([[h1l/l?0Ա_@7ldڴ/q}!{t `Ϟlܴ (9bEM6t Ա#Veyo%K-w֭֯[q|1>^/[r|>z|k/ g}hTR^(~e/mi߮=b0(_z|ҹ3vON_YI^^>VB^^-OGթ7}TMQ5]J 7MIKK]۶`0+X7ľ炪`ךPC=>'z>q)Eɱ[]|LXulmb;zreOK~^~glCYfW:C=BĉSǗpv˕_Rʱ_.{jl'ijw>b}hт̬,((a8y!ʮ]9}bA ~+UsTmmV5֭NnڴEU|%#G+ uqu v.ص&P ~/[no ]nyO ^?N*IYGп?Myܼ<[].2^itԉC\Vnn.qAIKl.k &g~'L_0c *U8Ke^/?1]ܓcACӲrrr8~]a|>T6$$$T+Μ\˿)***-;'UU%UNksm⫌-7(b6|@fKK: 5SuK?uf9QbV\ZX[Z$[InNF5*22C }Ϙ11)(0hE!H}s5=GܖÎ;xe *ޯ39 ryÊXr9xP3;5&O~5Oxl@Vk̤E!E ksv:d.]mBTTI^f36 MPUck׭O0cN[6LF Bҡ\wA(32}vOuoȐSIrTrd9$?Xd",Tel$'Z5kԱcde˖G+q ^{uܸqݺvgϳe𥗄`8={8av2Lmѣ\χ-J_u{M.7+c8t0 8%K?Q֭8|?A㵘͸NK5ren[[MQ=-]W^?Aɓu)>cو+7F:Ǖ؎`ך=itm"6&:z=m۶J] t-!-5v߽I>xY[򈌌[u}̙=_GUu?o6-̙sM㻥)**f9r?6oM^^1Zۗo^CVv6%KҮ][Ny&;+K'}7}Cvv6, lU'~ʳӞaa{|p>4GC݂dWyq+QT?s>;8=sOg+o.]ے:<8y Ok*V,ģ=T[t}1_y%r~_'cT~KK9٭:G&s_{}eKcRTT?WOsӸ~Ea53pk׭C,v_la͏kVsTmm+VCv, {&W! Ϥ`ǎ,K;Z:Qյ&| ]Lbbbظa ۶WQT{0z WUulSN3uT%--MVl6dggFQgUg0mTUhiZlzv5 ϹٸqcׯC5IC_Z/47LDFF_nMu)B\\6ߵU]|l6c2Bz/f sxxc4˽.f3999|>UթN#66IPQbccx<;RMnn^ITU%6&JPDFFb0/Wu.::ATױx e|Ϳ~-[Q.<<^f566N^|rAMƎV%WQp8ܪ-ryVo߾}ZddfZ=zhSNpj-c3ߩe:t:k*r:M MZn*vrA.**щ:PlUթpi99|>_i|u`wTF]^)nw@PNؿ?[ՐQeBjzH] Tv^:Qյ&PEvv٪Zw:/-kf$CTk9סd:BԇF_+ 77hvg鰄M\M4YwxAܿONL!Dvmw{Z_m͘/2Z Bm %cwPZ3B& 3+^x<#eIj%B!$B!^H)B!$B!^H)B!$B!^H)B!$B!^H)B!$B!^4ߟ4xl IZyd7YN@ !BFM4M(ڲEQB^g89j-'B!k]熤j'blB!_l[4<}uHySzA_yt֕rLl6W{d8o| !{$9Ν*آ&9ݻq혱Vǀ6t~'<<ǎyO@P;j%zgϳ8qR& B}N8ׇe˾k8j*xcbbp\hСCիFE)Dlgw[dDDDTXFQ"##QՊծ( aaaՎ#кJt:"##._\j |q,=_#"""EQ0:2LƀV y7&}Eh4\lYrunU1Jt!r2 Aо=۶on_8w͝wcػwoHP>UUiӆ.Zxxxwytⱘ͕wm8N.bWiUmMrߛ(Aӏ`:/7_n"&& !ʒ:x)\r N'aaa<[cpmt?ͷFʿ_kT<6[!NLvq]5w/O`]2fpyjՊٯ+gENn\;\0鞉\{[ڎ @5t[dB| s_{ .#ST+./SO?''11;n'N0袋Eo00uS |)bxɩUO7׏"--ܼZ6}*X5+Xr%h4ЫW/lذ<0?LL\\7. ϹC2qҽ+ė_|^aCw=t:.0/ޝ!z$''L~ga%\w5X,6o??}d ah>>4m۷<~ ~Uy^dm1?"thP׮57ЩSG=.rh4?1c9t0&7x\vލi<n7'5k+ҿ>Ν8B\w-coǏsӍ7r5ס(ЦM27F_uu!C_嗍b?YK-w3f Ӹ/[޽&[mرtO<|p?\{yWxɩXVmj_l(.\Al-^.Æ'/N[ǣiQm+MŭJ-NP%3+;IIIeʕλDGE1oڵKө1 L?@^x7~ TU7^kw n#P/-nfڳ3cK,>3-Z\aıcl6n"&:N;FmIj(yp<4klrL/ IDATr梁AA~:vtyyRV!׍6g}hԺNK.ۅ`U3_*`}|n []kۖ.;3x֯@6U_ɾ}"99tZӪ&PӝOR$'Wx@c۷J6UnrA.[i8G?pgD4n*nc͜n/x.{l6sV9~޽_Nnnq&wqWÇINNUZx 0q'w~;]_}͜Wx;[yl/8l:u=^С$$$Jn۾'nJs{V+Vk[{Ӧ(+z;䂑OZZZϲV~UV++PX,*m,z/]5썒A@̄"+3v۱sWh&PʔݧBRr $Ǘ{1x{n <4N0cKl۾=~Ul>l_}5;wfI۱~1%u'oJ_=^/yez=PvfKBTN:Ciݺ3^θ¿ˋ3f2wkLOk*w#Sǵϛo%! |/QFb&q&2Î;xe 1nݪg!..gQQ+ʲsr8~O+Q\}uhFN:tyX,(..Q]SSR b*V\y}0st:DNN.r8-)UӄRu3O?&/[1.PTaȈW: myXO/Bsu=9rU_eeULfoȃAb8NV^E/u$_wY "tu^C:SU8J;NZZ111zڶ-鲳;]Tl(""/z.ZĹ{1bpԸ˖1+Сk3j@>']tWYCI@˖-kJ@jkgϳHMtٌfC4TUeSUϑ#%#JşVwzFzY||4GC>wy-&neq9_Gzzt?9gf+I4MɓS\w5|>VZԧ9|^?x<,Yvp;$&&6ǵ<8y Ok*V,ģ=^{6O>g=axvJ+(?ݷ$++dgg˯̢_Q~բ\LK.cfWq-OZݺuXcyȑ#88q몪#qwzϫ8ԩ2:2!D)'ʙ:udgg+6MIIIQUѨ3f6aZ4M4-6=;l ζ_~UΗ<}u_9t5x/PtV7(WȔĐSK{aNf|4NGll,vj[@'ڔ( 1x<U]/}p띷3.[p~EQfr*'&& A J7DGG_###1ߵeCItf3&GCl6TUqq,K{!lTU%66QaZxf3f¹ܶǓ_!j*qWYv.DJS:ϿT~sVъ*b|v`0[UUb\.j۷OԬV֣Gmԩƽ4M1e]n|((x</fSR5j$/Nz5j*r^XjSiA 5/:* Bzz:.=Ϣ[׮ع3r{h2HT&Xn2Arήtoa r_]t[U^˃M 9`1|bxuUUY. tUuu?3%5D3sx!GN2_lJll,o ^5xX^;@qQ̘o>|CG}̗_~uAw?%5DSȜuGɋޠ]_ƧNwƓL\]<ˮww˫$1|?BԽfhB+ Աti ]~B!Dsլ<}A!DBS$Ѭ&9!Bu !BBM!BQ/$B!BM!BQ/di۱&XQ!RXhzFI>uF=HrCB!Wv~;aHL45M#YB!+d׹B!h$B!BM!BQ/$B!BM!BQ/$B!BM!BQ/{4UU{X,3B!Diڙښdٽ[w2238}L"BQV+{h?V$-I2B?!;;&ڋ$M!BI)B!$B!^H)B!E|\фH{6j-_~Un݆Ƭsۅ<أ?~, o_򷌻&n7vy1v{wԉgyx<_/XPnzRRM{VZa0z^~eZT[obZz}<2ƑNm6"ƍ[nҿ&M̗^u !Dh !ǎ!!!Wlv-|˭=z]^g}ر^رcy-:tݻۅf sݵF?M7?\Wnݪ촧Yj5} ĜٯeʕλDGE1oڵKzذGכǘ%3+;PОa̗8Y|g,Z]!*΅JRR&gԧp:G η qQvŪU1|U+Wqav //$ƆSǎѮm[Z))w%t_iӆ]SYa:vj} 0 {y :NV!8SESl2Hlт]ʏO$1C:ǏxtXVZj埾ifz||<6[!vYVVVk>I'[nm!mc8-^BQQ2ﻗxBB4$I4Ƙ1ڂ{&WaZNn-Z(YbdffTvnN;vY/"‚h*Sq䢪*? 2hcUXa{I4c\O`އ8'OMeՊb2x9~Z׽vrW^7YYq;$&&6ǵ|<;ƻǷ դZL:UIKKSͦ(٪hvfv0UU-EjuMsno6nX| i>!D<}u_沇_ ^'**-鈍n{Oeebcc),,vW:=22AO^^~,h$??8F#O_V׏RƎV%WQp8ܪ-ryVo߾}ZddfZ=zhSN`iB4(1%Z2\wɇsj8Ʉ_f Im8\.>BI4 *sx!GN2_TB!I4 JȜu-@$S!I4 NQᡎc!D$o!BQ/$B!BM!BQ/$B!BM!BQ/$B!BM!BQ/$B!BM!BQ/$B!BM!BQ/EPUI3Jr:9r PDEE5PdK~~~\vi"nB=Q[h* N lg:&d2ܶD ra02-mgF|ha /bAY "Dm%`r0,ӉdB-2*l@eeeYe=r\7]S-i CeJJ=^uAoXMA~~3ִ'$B4#rݨP0*&[Nv9,DESwCB4qh$ih zCM26q !-ǵ"0)B!$B!^H׹h ՚ThlnOZ4hVQ{RBQWESDrړ:3vSx<H$ Çuv222k0z=MK:a٢tب4͜ק7k~\<.ygY~=/RiL&g׮]df~.}DFF믿i @IcO_* U~ )4LDGGP\\DAA} 22Ν;/[l AEo$&`!>Ėk +۷k;SPL9|(Ss{q-ZXǽO*.tQ]P}ס(JkZIMM%/a}YXF+Wȥ ἐ!՚@nhպ?6OQUL&;Q[Ң)6,Q geEA|Zt:*x[DGG#mNɻmdڶm"bҹ(w~2g?oÔͷItt=<-0 ,^7|K/oNGc}MZjYKڎ x!{̗g?*oPPP ֭mڴϓ͛4mҭ[7>vZIMMEQZn/‰'ʘ4J2<IDG[rg(ܩ#7nƒڙ 7* ]R;ilڹҡ=Zp(<4 CZNaa&z<}ӭk*.Mbн[*ͧqp0uJX UUI`@ɐbcbdffղ΅I4EèN8ٹsvUU9^ha%##EQHlт;I۱^睋՚@VV6 i̖۱F\.Fݺo;'22޽!bTE%53nluX-7j0~9'Ng1t%k5璋kxH^uVҡQxezͯۘ=u~:?STTD\\}!>>EQa֭XVzIBBt֍Cgf3^Tݻ7[ƮV:V6>B1 KvUu,W(tƐ[2 1ǏiSڣY~#ѣ{7RR:?HHeD~3N' գ;'eMؿ]tm6ڵP'9)7xPR9~"*g<\ݻw)BQ:t`Ϟ}kZ*M?aw80,vvkJ.^ǁc O-V223ɢ >>bǃbp:D=rH̐ih!\be&.xK~gԈq:3 n3^˳_AVܹ6Lv퉏gǎߧϩ˔Yl_pW_EQhժ G@Ix)Ezz:Pb(8p,?hE!))IDDDmCC:z,~M#:&ҹSGT2Vձidff()JH'#&'Nl&/?ظX dff{$?(WN9<E* :bСm:v,?xx8bX0LHhRjM C{NNpsy2y,U:~h4Tīhh4ҩcb'^ϩ[Eucqɠ3^@UuDGGڥ3JNjrlgY_Ʀutؑ={t:&P.*]رcƽ6:tCyڙGn^ݻҡ={XL IDATgFF&>=$$$(*䍠deDrF%yaXHEU(***8({.0 xHK(n7a-*K&srrztڕc0x^"##9qDJ@dMmvg_\L˱n("!>=yrqArrr+v1˟>ԥs'rrr8pII&$Fףly.v}HDEً7233Y;/]vrP|^(ө?UUJ hX'p>=qZ& ,hO8b5?oɈ*Am/$i&Ν:%ddff!/S%x f~8eXVZ<cr %%ǏSPP@޽ׯ_7t :NoNTT}wzoNtt4}O>VX~V2*DGGQ/j:bت<訓 NAbD<+;vmU4N8Ab +Ј$"T:dxI-Ov:Q\TDrRkZw ÎNJvh4TM"iRfff`1?m8t0{tv9cbpy}xx ]кu+=j s.uF֭"##AOxPU;wsZTxkԩS4%;;[lJJJFnW}>l6nSUբiZiٹ_4>fƍUׯ_G)57N`UQ x 3 ךV|\{NUjlظj JZ WKA\:ˢESu4m:tATk?yt:]IKaO v,$WU佸窪cݫG%++(I nZ71}zQ(x/{C;ZQ\EQl> pX,>Z}ijzM:(-^m[|Va|])W Wʯl\řJX]תZ>_ܠף)..Edd6۩ `mp$A4[cЪO*C~\ 9lEسg/E:z0uI)BԀQKUKz08$B4'DQ{RB!^H)^u(\{ԡR3͍%2A״'t !D5O\B^n tBf@M`湡HM7IJ&FEp~[XTd,r>-䷔kK+|I C%u9EڒM 9L6DDXt(Mؑ(ȫӿRR:4PdKAA>ׯE 9P)BԖ$A(ʱ#ѤTNuJ=B,nd_ AM`0ECM!B!DDS!B I4B!DDS!Bԋ&hv 3B!DRXh?aH|<--=z1L"BQ vè&hjFoM…B!W4ɮs!BI)B!$B!^H)B!$B!^H)B!$B!^4Dp`/!BTq(Q}IMBJB!Duv}(Q%kW !BQ3\!B4h !Bz!B!h !BzQ'((Z]%B!iB!BM!BQ/{4B4cp| cRꙎDfudYMBsʙDS!D%WE?-:ӡ,Yο]=.t7u.AR%71hj%'Nt:VTTxD!D#' !VGZQQjTh !Bz!B!h !hhܘV#;BJ4wAxxx\!B4uB%7B`1!DcWefddB!ڎ;BES!D ~MںeK%3i$6m\WA 4J[4NCZ+Z!MWW^{ӫwoZnIxat~et:ѣx jvSi5N:d/bU}^z5ȺܬV֣GmԩYZ4B46ofC1k,p>o^'eKZje_kV|BN 7&$IYUILLd25Ⱥx;<.]zC3h !h uԲif‚3x`,\uUx^z}$3<<:v;Z%X,LxM&n;x<JXXWۨlt:fVmS?dm(+wJ8JF|tYшKꙒX,5>hK/=zTH4MF#Nڸ:=B![j*J&5s?,_Η :, '8rū1 @oWˣ%!P C k6$\ Wo BC!@B\tSL!@;(t{$?eY+˖%s$|;xUZ?kË/L:/c,lٺK,A"%K`v<~]|+ֆSbK/_G}e[oŋqS!ds9K/޽{/K,gy&̙Kgƾ}pWŋY +E_>g_o>p7&DQ$nHRo.lxe|iaeWϛo\rɀesyԄz<3Xz5ZZZ0|$կ~a~;. 2|$I}9}~<.vލnGq}zƿ}o"BWW:;; -[b>67oFSS`ǎHӘ6m觟y낈OO>YҮ;oق3f`̙xO*ckс;wbƍhoo8pL:N~%9h?}8pB)ݻwJ}4cK-v4o1v8p>(q\{5xdR\xrhhhq{Tʕʕ u͚5}T Sjkqm۞=8pR2LؿK\]v DB~R,dNw}gLRHR8#Ÿ[oA ]({ 4o\sw{o]---%ۘR[{}(`[T ͅ0a]2e .bS4Ν;KW\EZ#]}a=Woǩgk"oZ +VyQ pd1Vqz kyx׿Ƽyp̙8SQsaƬY "s18scJN#׭[[oSNgkֆ?#Duu5 u?4̙3]|18묳ܯ6^_ﰢmaǎx藿s 7hoo}݇Gywq.\Lc{o|tl^ގES[UUUxl2l{^Ӏwf[M6aӦM8S+  _:g16|s+4qYg,{J$d@DRbΜ9%GtF"\z%wtt`˖-?Ƈ~-8KB?iDQ|hjjܹsG x׿H۶Ⴏ'OtI`Xaf͚:*Ql}eY1c|7mI7p_hI=<`M-[s! ٳgܿ~|;a L/\v?X}d2Lчӧ#yݻw@ǬpE1 }cN9tMT6mmmX`ڱ/?#XrxgSc»1k%R`G=K/K޼ ,wމcjpŋܹs!믿O< >[]]]xukᤓիV6 &<(?z;j*0i$8mB!jkKłj[{{A_B`}?[lE'w`֬O*555}dLlF<uPR*|Ρ׾@t:68: K$])o{.e0Z׹6@LE:a6jjj'ߊ<\-qjj7mBֺKJu]וRzDr9]WW(J^V &c_p"šիy.]} G1FIem?|ALTL&3ˠl֭[ ^FMM d}z}Yԓ}ޒ6S McaPz)ݻ<$ؘi kBTXf1V9-DG}c˖sbs W4c:16:=.yJla[&h2!!xcɒUFΆ;qE1ب> N>ؘ}{/O.k ] }jBP!A)\>hyc1ǝwމf  rmDȲ,RJr$Q1cсGy|*paSJ`krE1cl R)|!_9&b1h4Jm p4+1cKRXp! 淿+ :~AR ]$)ɁKP2cEeƳ- p@A3LRcccxf?}Zsd1G]]~Ͽ"=MhfGӶmFT]]MXl@oX&l/jPcc1&*rʒ xK*2@Ji1>)Hk=vGCCS*" O3Skk+e2 J)21;$ \vUyp1㨣ɧD\}1&1(L.d2F$IJRT__O V7G3⮔"u<2hb/c1ظ_JR $TJ!UW_O: _~9>#U`R}c۶0(˃f> :ml6KeW3ysc\R濶q]r˭òeY&Rdkk+fnDtGu]`ZG"\.'Z# ""mYcU{ !|u}˲B+L6`DuuuqR*\/+y<m\.G=̲2ʠ**lVr9w6Šf }g'A@.RBRJ߲,h)ecRSXM>J9Q~B8AKND<AESJIDDL]]2זA^͙3gx!L8@uu5e%cX8OpT2C FO&k.\8 qD2h4*RB)en00&c3RȲ,RJFM65D´R24dxbT*:\T4a3L&I tf2M˲"` cg!T<.% @A fPA,=pnM'tMhiiA4hT .IJIƘ _:g16%VAE3f!˾cqX/~4lrX+A,BclBKK> bƌ;&I,+|SJ/;cUe=#!Dp霂 +S@<Ad1Ɔ"Ɂ \@"0O9plfYddmmux<2c=)"mҒdqJab뱲9sLqf8S8c ֒F 8UWWScc#9pzlf2 '8p x2c#)766"Q$W2'nMd2r x2c#$W2'nMg 1H e Js%sb`qh +@yd1FB,\ɜx8XZӃ(c16@Y pМ08P|{ 1P(q`8Pug1V8hN08m30'(9 `1cMc1c1X9h-cIENDB`RaySession-0.12.2/manual/fr/images/audacity_sauver_fichier.png000066400000000000000000001310161417052567600244320ustar00rootroot00000000000000PNG  IHDRkpG pHYs+ IDATx^|7B RDEPAEQgA )bA+*(]AZQPPBwރlnd?+ΜdwN]N)   Dp    `*@@@ @@@*@@@ @@@b+ALĜ[ڝ)1 )4@@U`W|3K *UPsUxn'!  J &$]1DP_Sj+תϒ (+կE@@n'%ZZ)R+ ;   ] kO+UPY/ ڏ  Z2Ԣ  T"JtmKG@@J&@PYN8E@@B)@PJMB@@*Ae%;4@@Ae(5 @@d~={t.ƍ^\os}巂 @@"F3EvJ1rQ "7dÆ ]ћA@@@Tj{.[.woYjbcc#Z1G*U۷^-)))ҡqR\=nRbbbߦu+UVXi4h`Rn9NRNg=SǣcV-[c=#8٤qbUk'GGEErm}gz.^mMNNjذaXm@@"K ,^&<@xj[0BrwkO?8Y|t^vʖ6mZ&Ʌ'{1 RHzz1{#i9?d{sJ/>?Q[| eO=-]zmS#xm߾Cn?ϗAw.Cׯ/999@sVjժZlێ<&'M6IBb۷OnNcK<7ki'<,skG%77WM]׫' .+Wu}rI'֭[3gs/"  @ Tj'=/~DV YByK.P1TQrc[HQq k f_A^suoaAgdqUb=,(SE䪁Lj^hFtΕYuNiƍ쾞ݵ43Lyժ+\M]PhuA@@@)oi&rMƌÆ3čꯏ:P j[V ~ 4Y%~=,j L?i op?$}da5kEztJϵas\:lshH1 @@*@T.X-' I9}MRRbdU#?t =O{!sEKf gΝ1:K0ﺬfz)333J8oh\B~+'t  &pwY K 鲀Ny zKSs(=]f)<-?|\VO>G@@|jN   @d TFyU   @T s,Qk@@R,) @@0;4@@(KʲԦ,@@@ *UPY.1u#@@@ 1`W׌+UPo't&@@@*1Nyy%"{E1rk$DJh   R3r)/5T@@@*WN7   @h*CIn   @ T"   '!  JRn  V2  T*Jui,   Zz   P*+馱   @h*CIn(Сq*  @h*CH.   @T"=se޽O m ED$:¢CmE^Qm9ڱM<&mv͔a qn+2Fk5+M+syv_K!m>uJ8VT^])4@L207B hkgdgInN)u-z_+$Jbr\] 6FOV ?_2ҷtٕ+anlے& 6]DG3s^4@<Tri ;$c6ٕ)MP?;%\D@@*ޜ@AAlۼIvl"C/y2={L=~j#;%ש HrrTR%Gk&~̔-[X@Ui8Ael@ 항i$PV@=ڼ/ߟ' 6Xn:PahРԫW7̥} fm޼%ҚG{ʩ~_U^M~_N4 gkIFeƙNyF LPn7e|}v͒f~ZCNNMFR)~*i?lmMa(jYZsM`(4[6JYtҷo-ǘ#9%\?C[{(]u,-H_O*+5H+-L ZȬXn5s[I  @e0o(' '6FΌtIF@YnY,)۬ KB@* T3N{+{ر qȫmAT @"@PV2E ~DR$/g! @*C-J~A@{(w1_/ 2;+Srw>crD@ʩ@XTﵶf9m6 @:)# g1*] R6dgI|2h@@ ?$3f_ AyON;8KmHtE]nzs5WKϳKBBoԆwi:dȕ- O>.TٚT{+2*vϮ|=6lvVիKժUֲ8iܨ$%&n+ay.:q+ռYS)B,GQw裂~w9 rsCWJю!Ej''uqݤ}cm))ˌɅ2wmڔ&99a-pMiA*gwnX\{( |>1n̞zM?w<1n4i8d_~%&dܘQԗ卩SDPQ= zs Ip*|GIXE8'7ziP~jzuuVAѵuԑZj_8sB`Yt\rQ/iѼ\Jο?H1iߐasg>HbbhO=$yaq&YGļi&RZ5}Zڅiެ$%%;dSZ3w?ZHv:3TJ%Ru Wؑ.5k֔#h!k֮cdsҨaa1*>@Ԯ<I0_͛7[-[&>Ko'e-T}{HaaAU y(ֽY,K_ U>AU"k"ǚk +BUk;CA~-|^JYpnn:kBRoO;|}΀ҵժAN(7%rŽAe˖GFH&Gk{/զu+=AIۼE4gn:<Ny5-$>b'J'uLL2}iT\_ elܴcKpˤ [y+Sm*so UPj5@ u6߀ulcKu]pݱ%]Y5,=ǽ&qإ rJCJM,3Ç恗k3摇d9š5jMi矓[oc=F232UeuAgdy5ى폍%3Q6nd&i\;/,Yss߻Yݺu샿g󼤧XS<w;MjFvC𬭟V}|g۴j׈S~2,ց#os}<5?~[Y]ceq-i_>K9%>Ͽ0,醲<ĝaGFƁU^7uh\;oRݳt;uf6F{hLv _~Ow0%:*#[*'˯K>s{e {`֜Cƻ!/: _=c5;۶AhFحb66.8O(w|9yӡqCb}̖gn]Aeu", Syl}A#{PE2LP{~}Ao9 >^(o5n COmѧ Pcv$ʴ7ߖy̷ǎ\mds۝w/ :ʣGRFߛG~!yZbn37ꙧt,S7i$k@m42Po#_soz羴d=VVɺ.N yPi<Ō~߽rWQTÝG<!J?N;ݮyj@Ry?0\;mj{gw>Hӧ=1{`_}剧&Z/GLPצɊVʞ={mZ˧4`jGIlXyǤk2j8sAf1Yz\+]5U(kdRaWkm6Uҋsvޯd6|$[l%J052#N8L|a1AcDOyvMf^!wǔWCS*Q[m< \{./~<׽>ri;QTZ`189:Ց=Xo˩gHh!#ޛm3md3*hrSL]B;Lt)T6퍷Bqye@lF@;|IAϩ/#Z4/5RH>EΛ!͝bއ >m:5"w SKo8uhacSp]|Fd3ӱ>1,-|VZ@$2<ߛΟ.^է&kVm|V}Yʬ5wz8}vy+硬KiyG}4̴nfdP{~3=; OLLZnNj$6hO}{#L?\tL4^hHu= $e=J'=mwm[#& vgV jx|_P`滳 [Xhp={ e &sLOb.6 Qi{Mo2j/#s=/F^c~ 4Ӟx]L۩_0 Sit!/הcO{ʾ|GhTn]{_PCԼ4(:Qܺ?vtfTazγeVYS3bZbzaG}|6p?ӗ6s L hաNz<:H}ր>=;SMPS=7trieժu`~`KN*kʿ{K:z/ks=~>y!{LA8ڵ헫HzSHH7C`Wȋ=#S'O_uL4+'*U?T:[*9Rote@Tozj}p7OZ_o94ח;K%Oqᮋ?}K;oz0fБt9fH~g874o[**fӺTK{ i'ٌl'Q;F?c^n7ͨikois}ion]mGr7-:/[/ekX+ߨfxrHx\]b5񮣶~d?e4{Z8<֠i?j3= .ttŭf(k7ez:vu}6sϔlF!&} 8KڹC݆=f~NѠ_~QaL}K P i,">[@y $n8MCD6LsvO;GDcYSRRst }e6N|AL&"o>z(On9ѡ$=2kox>BS`"X_pYס>^e:"UJYq/3DUm,/~VMk IDAT8Q>^]XGodt>emobޜNdo u8~;Sxp Pu6iqw]HjO;3Ro0~nLqKLH,6YoJw@O[JsrWж]s]ag nތBq5Tk{){.pLiѢs6=k̔|̍7ݕͧd^ݑ~NОҬ%}i6Ge!pWRߙ7թ 駝*=3^͐Mjjex!k<?֯ѤO}:ik{t?ЬxRt ӹfҾ~Ik/+mlhz?[nݪrRϏy0HS~Ŏwץ5WUV+>]~kyҧ:±.tXjUsSs9J&. 9.PXoz"uX@sՕux {3u5fik̐=}tYC>쒋/З2|(rk]@s]b5AYo I 5;%/}]ޔnP~t.]t0i]]fy:ۗer魍x-ZlH:N7s]XǑJ[mt.H:_dk;[sc PC@jQ$=J0?]T-2˾`F'#L3x |t>A]!Qj!&#Gd]5F =&۹)W)ͼ~qc exj֩4i@r#5 ,5V3]MVyq_u Kk,-rkUF%oMaF`%_|]C-ö4F > [|jqM:CsO9?«ҥfAsA#P[cckQbn;Kᰮ5ק%\îs]:xNC~͖>Us 櫚 0%$v>w7l2ߓ_y\p3mßuywC_7[H]Kim t tX]hG{%%]Rҵ8 +M!zs\+]PtO A7^߼+Fk IOeE_O(҅$J&OݕVOɼhh92ߓGm(y\&Ge'Y۶%È@OoĘ=_$ׅ\х9s[w 㞶+SYS\o:KZ%)mė]נ,/-rCw wW7h,<-/<|/)-r\sfk )~#! ,>Y$lڀ@yHHLZIkgp F6FJ\Ռ<vX'׹$@ ;5&Z}u | *=x.'$%TXFEEKbrCURʗ|@L4sj@ 0rk`*_G\ߣYjGm*@rJ]TVz&ԑW_ %cr(E (.,W SG"PAJz;7[B2h%-L_!燄 ϗAe,d@ T:Nʎ|B$+y vUl@@2 ,Sn C xz Xo(4 id Tʊr'0 HmZkB{(4 T aH*"כ#R\\ B*qqҰq3z,ChoV:U{'<0=_?G< {gky/u+_\?|Dzmzkڴhe4iT3$5q'n}G LX6j<۷xOe[j5KmTR-[mQ˴G9w\?)\(.כ_uak\ʍ6J9GPՈ@ءH5%}V̈f+CR֗ZI巒 l޼@,ڸq™RʘpB7C@W 'c6X<Ո2%!)I{B! PalW"+0,) 0 hԟ];3%{W=sE_LO@׈VB"=7 T"JtijHHJ6=kɶ1?{J]y`.\?3Z{_m6t8@~m6 w=n3GEGƔWTx`XAz.:챚?uŶly.M+v`(*qUZjgN@@J A V.CB@@ R$  Tz*+ɉ th\pp4  *@P'fV`C!! 8~$oEjJ^ @@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@ 6)g~   P1BTjSl={t&MM{;vwK]vU ]j  ]NΑ}{\hWlݶM)-&&F:c-Oiִϗnw YPȽQ?|3I5dO%11Q:p 6|Yv]O#>U+^f75tYs-#B@8D.Zne>Zc3{o.|\^|ops;:fyOwU'JvgyTՔڵ_.RrrrդV|<;aDGGـɧK.%>Vf͚>-CGbcc>PZ5}ZٿsWdiҸlذQ32ӣh{kw/ @8}BjhkQ u1s0[bH:S5o[G|+szTwٲvk*~R^Ѣ}vaդyӦT;Bvfeَ>^TlygƻN; }Pcսoެ (NѵF۶ow" zL{m| 4n#r}d⋓>_},s7cĽ5U{p| ,^Dȭ7'අ-[)#!n:2rX}lrءlӦL|a\xyʧ!k&! P~][eOe(Jo&u齕cȫ|u4y+?|tC_iղUfڠ L&wo9%5郋f\oM]rхҧŁ/T-)Ѐ~7;n3=Cp7I?g@8˲(vyh* S:V:J\b 'tӳ;3m-n0Why쉧>q?6=W /MyU%39A52b7*&Jפ(wsij֨)~'LO#^rtl+,.@(?KO^{ {Rjbyy>\`&'Hۣrn˯ K%##9~}=i&II]~NM@@ h`ҔWePj]NJ'3˟MtHGS\3-c3T,YB'uksH L$mS<5\'T.:1qW75{Kf,ZywhT^} .;U:ydxwW1+oio|Kvui넄x~)*,2Ce,4CbLKB@ʓqq;v]ȏm;w,#dM9:|G(ӎtәpI'@yg̱ZdvY(kgV@&Ak+HF۴IScGdޕռamW\NW7p@?ygb):599.Cn_5Dѥt)k!"ybh])%%Ź]r됃-[EDi Tn@-ooMގ/D5#(kLL'c7u.)1)1jk.,W2nfE sd##_8I/M3!y.ѽ1R~=;{xuҡq0aWLc9srM󂏃.[<2֮Cޝ5Gg7ZKIm]]#@(CoAުѤchҎ&}HUmu}'?; '7Zս=v IO{)xث_ugٷ/O|qm[nw}erb)sIJJ=׌82VJC [riikG|๳g^pe9QK3G< D@p1[k:\;|Z; v4=5IŲN:-O{wder[G/?ԮSTTh"eב $cձ)E1TաJ8>p}j&@@" s#wMi`UZ'uZܷo_&$=Aה DTfT@@ ,@OIq]&}I}ub/6!SJ   @ 8犚"  Nܝ*  Tʊs)   P*)B   @ 8犚"  Nܝ*  Tʊs)   P:v9Պ !P:?Ն   PbWu SϗϊQ+@@_ x@@@" TVG@@@,@PyO#  Y"=  f|(@@Qw@@@0 T@   @E g#  Y0G@@*AeE>{@@8P<   P*+٣   a <'@@@,@PYuG@@@l(_pOt?|c'@@@!R-`5te٣4in˓۶wK]vU ]j  D@ȂJSi~-t>nRF YjII-]: wS{~|0Aĝn"E @@L)p rUo:O=$yaq&YGXiڴTVM~_V_-0BrM^:udmUjFF=|ݷOk~)?ܯfԗk;vSe˗K͐liӦL|a\xyǔ&{lhm"83CGHvveҥ 6@{TFi{Qڠt>x;C񱣥f|dff@tweIL   .Ԗ/m#wq}ȂoM.BypPF?l|2u_Rʍo= 6tի7IɊVʴ7ߖy̷7>28/??_9<&$s|p=^7yj& @@(/"ERjUkCXux{s9M}@lϟm0Uf;To'/ra]vdddڀR={d=r4nlzwJNvav-Vħ؀R/&&P['m56m]fic3V]rX9   N mn]Rj׶AcnXƛ=gxu:4v]i,>^z]p_C'   V dA%_(ժUK.ؑ.W,<ի+ђ"')kt[ۣHV-%&&XkQmGC>|7jhׯ_>UTcn+ZN-_.;]M2IrɞݻAjIOO;c͞ݳ O/[ Ru:G_oիO?,dY6@@@*ᯮ%>W]auڢOz4ky֭?ޗۿk 9Mikd~y|͆ S.vjҀUfْ@@@$J $=WPgaΩPK{)}]~}ɚdS\\Yk`y:=zH…+Qcdؐ{dv5j&KZfImP_<zw^9ju@@@" DurʁoLgY{RCw)99,G^,^xoHkCU&fv}7f,ȗ_R~*DM@@(GAT _?O4jмr]U|۳8jY99daf% @@ANS4پ}ה2j츊$  @_˴a(,!!ARj'۹\:Ȳ 08  P&R,u A@@"D $    A`   pP@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@ 6];   T rSٳGw%11ͪUg}^-={MAC   @eiOKO 8nҩcٵ+[ޝ=عvϿ> mڔ&99A   @eyPo }+szTwٲRn]g $==C춨(i*lByf(۷MiivG ՑW.Gh.YYYדm۶KQQRF*Uueu8   !*CS/_ajR֬]kAj62u\p޹2er?m5k֐ק,W]s%-5%33S7o&g+f'O=>N^|oCKRz5Yl\zq/k$''WJ+cҦu+=AsIUKޡ#$;`mB@@)2ԌgyTj%_HAAݶq/}`{36xcbb޻3fʌlwvhϣi{eڛo˼2ƍyDL|qY   Pa¾POȌS%m9=ϒ-+7l*r;qF6ܿxyrEf~}J+Cw|x6;{]Fɒf^   iQKw\'r?MIm}ґΛ,:lZe[E]kYZkWTVM2͜MI/>_Rq@@@@= UqǎtiϣΛ%9D&Kpm   Aϩdچ   PA+Dz L.(@@@AtL+@@@@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@k@@@ `ʀ8@@@ 6/eukִϗuHvv۷뾞*)6@@@ &R$K\q٥P!-\df͚>-CG^233m :fJ&   PBT6ȇF豏+WS8cBW`7>2ɇQھzÆȂ9EHu֑"f!cn+<;vFL{ޚtAn=\v]MMtm[m "ړH+Aۃ`砻!Ns7AV/azR5?6 ^c9Zt:k`~ҧ |Ҷ@@@ dNj1rlHPz 6%׹M76=e;A||'ٺmkw!Yz۷ɫaTl籮h?l 4omfeYM:Djժvj'm:һ."6nP>χ}:v˯Cb׬]+9M6IJJm;O{ncIпp۸*r;~VTr  D@Ⱥ#ܿ??z'&&`ӻ_eޖLMLHAcvNS˹9::~@ڵssN;~:5%%%ٲ3BHo׮u**,9:R13+m݁[n$WB^|Ye $@@! *OQ]5ue(SYF:K+۾۩7l!?:7RT^} xt\j33lYI&(vrgGVW }ί-~=;b[sFI   P9B2ՕNH &Pj9bo1 sGn0֒۾6n?ʦ7\]AU-مp'u=Ѿ3eVXU/i`|%9VWouczpu[GJII1&ٿDz!$@@AT.^8؊Jwݾ?|o^^=j-~}M7y#~>>^6+þdO꭮Zv՞tb;t1hOrfğc<[˼ڢZji9 t_ӹ:w^hW>n{cz^{e{%O|q &?;<شsO.ڣ/9ԣӡqK*j7  a2A-v<-S2/o،4jм[s_{]x,{k8JunH:7k%!  *tP :n;$>ᶣƎ=D@@ʙ@_Y{}ukLRj'y\:Զ7,+>4 @@ hz*&/}Ϥ&;@@@%WQ@@@p TS@@@ L@@@p TS@@@ L@@@p TS@@@ L@@@p TS@@@ L@@@p TS@@@:;›HR`Af  D={ni   vʰS   {ni   vʰS   {ni   vʰS   {ni   vʰS   {ni   vʰS   {ni   v`K۽!Y;_^[l_FQ"uFERTFeR   D@Hz*/ZW?}''D˿ZVxỎ"BBVqQUF5d  @%"puAiV3\5,)mOW?׶\7x~jډ  @i75-bjTZfhfhI6=jt[kزVL5MY()Q;*uɶ,riTcBG-$T @ LǴ@ jm\e˶zzsF땴]ݻYڽwo6)Š6^u\5wZl{o}Zu-3LL"638v,.5{uK+[ž-3dּfOݚݱS&)5^S&զ&C\Xdb T&306"ƷGnnc3㳷G9gJq}am4B  K *IeKZ#I>̌5ٴ_o.m!},VKwl2?UWGm6:5!d):6:ԹYl!O,k&/7ѓ[6 PӦ֥{43O<.&v84!֢4}ߵgx|" Trf26Lk.W\cx+A9רIfnjBK]u6WuMߵ}=Rf>ltF9G$m uJO WMHӼaY{SnhrYՕ:I Twe׽z_1[F{M{='nKo)   _.l3ٌ37cxL0Y{M(M>ez2*,vQM=9U?]}nwI7kNu":z(nH3i3/uUC}V=|;Xcуؙpk$4M 7;K}Q@@H>Tw.9դ߾IGfj׳/X}Jv}Mj*Es &) 3 O wl@@'}]"" \dnbX   $Iek{rqDZZPC@@E$.d EI   $@f&o$}MfϿ(Sl*I"GLl_I΀~iXM2hRcJ}}l:yds̒w' ?e 7M">{o%mmmAۙ>m?4ɲ>{tcO$`s>[iDj9$ƠI^}^ 4/4m;YJ!2Y:yΑ9YƓ~  $@TLx44IOvU?,gf4堺ttQ2U=s_{#&ǍJafvݪkgϊtf3ħKeo3UjjeXAAtmI_zy8^_E|{ar}CͦL V\e4c{gz @@#e˖ۥz(q\z"͞^Mt,7Fh2v]2URVV&8l9WGYHA~SRYY0v^^MP}nx/u>dZ ʴ ˛xI   X>'J}lT~bqqK^Qfھ\}gY&zsrEiPMrXiђoM ׈ᅞu?&vWT¶ӧ=ǜpu&3sOvL;=3RZZf-,,4N%0/otoM" c2$}@@HV>/}2b9أp12|p{MEL|u]w|)Y#s}WU`9ɢ&t >N]&zu,[`jу^8n~v48k=)V:xa ćA=ƪsb(3qe&G{NEz*7~''xgfsҥ2^EBy  @ yRO$y,J}lS̑,lzҪPjBD;Flj{2ڜyKӨEqUإ^wԄosݓ;,{JzZ<=YskYW]-0)ĴF $N{wE7{)dy'jgf=k٭UW_'A2"  0R~{ѓT>oWM e4D@D寑q    䋀   @.M,mmm")&LM萔LIKK3ox/=\jOvs]Gujm{;l}mf    @ /{i榦~Djb/=E_?MbSM⪉^Wg2j1 s&uNҫ?ui&q5UZ̦|Zd$ joo={Zͽ)   =ҫ*cP: ߻f-Yјգ!M$51uMFmRkSj2nL'a߳%=CϴDT_MFuƖ  $Sp=F;ԏDs pkK33:38Π4+;e~& M/@@T;!1{WhYQM:5Ͱfv MЩ@@*@R(vؽfVT T0owִHmM+g3g Ď   ijL'fÆK~A}n'@@PJAZ\*ʥ؜8k a$A@@ Lzيu.ffldfeE=*D@@w T{|\]9eʾɲ4vh~   sRP=2pZ[Ztm[cc_Qcxd S@@*Rz&h+wh!6ZƆz))kcSd)   |QI*Y@_$=w~s̄,kKVIEyw9l(6@@H>Rؾri"JkS==vbYvy,@@G *I5,fD}g\cvf/;}iAV,[,|+M}{@@@%QI*{$=Z}u{yglLoI͒Rs@O(W}e   @b D%9Az'sۚ@;y'1ri$v%v沱Q  sR; +Pm;m6# gщ+Xrjߓ:K.)   xQ?5|=6ڞ k8 g&x*M:Kn^~Z@@@g* "d_.% n @5p\ښjY]$Cw  F Ie'j&{%}ԭ_X] gk2ZKM(WX.-~U@@b,2Sd%=z?#3Nu tlݵTɊ]!  @wW' ,f5   &@R`62s*ley@.}D@@ tR̄ S_W= l@@N*'n/s,)   ^J ҵEA@@w Ts\K@(W6L@@@$.B.P]Uɡ=|)@@pIKz&   H*]8([JA@@ Tl@Ƿ@kK  . tـ:x@@@e$./W  Mm#B<~A@@ Tl@ǿ@kK+<   2J @@\&@R!i   H*]6 _ 3+ @@pIp dg  . tـT@@@mn x'PQV*ii2hgo   n` @ ! ʚ+eOK.{@@W}*?I}]m?N   Ie8Z\rYj456&&A@@` TQO>WVڒ$ @@@ 1H*s܈Ktm+Y  I2N4=ҵ=NjB@@* IDAT ,ʰ؍zl9  p}R"+UeV&0C@@ :\.d'h 455JueE>@@"҉]CΈPTW%~'   &I?Sg& Y3 To %j,  bTFg}znj; z0`_] B@@ ǰ7z'!/i صh @@$IeށI}>!'vE_R@@-Ie$,)u2l{"{b+i @@.=>S ϲk[Z?#  @wǞ'v5|\-@@dpuRl9j${-˽%Hdff&Sw   H寮'~z@@| TH*A?t@@ Ȥ2زZЄr\x@@@ 2/MP`HnŰEB@@JI!''E_  $@RHE~ I^0@@@ $1 ׂaã_15"  @PʠD\va#%D|  I*@R;P5$w Y4PK?@@pI놄BΑEcgS*u  D_2,5zƠ5@@@ h:C eQ:"  tT&ݐ&w2EQgHcCCrw!  T& zF)[5jSCJ<_  X24=vukVIn^c9lHIII^CԄ  ~H*r$@GGTWVt*~ˡy\& @@W CpTɊeKdHn@@C2 ,.M{j2)i&ND  @ T&؀nxkKVɪ˥-@@B YtmH.;   tX4tuf֒   'T@O-]W"5.@@HL7@A֭NnA@@$|7@eyTV >Y@@S?uuRUQ@@D Lԑ#++6@@ Tmp-R[]5M@@N*SRR$4.jIq  @ J%'a4LT -$cAQ@@Del1$I(I,nSS456l @@Hws('Y{sùλkW@;}Ǚav(?On8,9M#  1M*{&;򅒔+}bd:K_z5姾XzQ[Ku%mmmE  @ ~kKyw錨P:W@@@\TKNGg%ؽ\  z@;_(KeVߛ] ~@@.2c@{yO6c^_hY,7EL  $@ʄmϳN"MúGl|fX$`F'ȬΎNeԂ  A=vwsPN(;%wK^pguf'z<^ΠtnkRh,yޯkNwv6=s.'[OWlf?=s;:/KT{NT96ioi7lokuո狡Uc14^zFdfff]g3kE@@pϤ҉I.:ƛZꤱ^YZ[=sl3G>}ӓt%:ޮ$3DK6ɆpLtRMb 'ZH9IMii]_tt%ETu*mms!KOϰ}U-he=Zu&Cs=Ku+FW[@@!0tդgHn}QzE^5_o  $K#v@@@ $qG@@Y2G@@@8 Tyh@@HdD=bG@@,@Ry@@@ H*y@@Ie@@@D L#v@@@ $qG@@Y +xɧλk܏   r>'ڿ;sTM7,vrЁP_/ELӹ&Sd2b|477{ʔ- 4i<̜dɛ+.UKdhn4λb+~onye7+.XL|kck?S1c;Y/] J@@@E *IeKZ#I>G!?73O7&F<(SJrHkk'ӧm#}o6QFɱ'lLV ϓyL^|uW_)'z-o}NZLrkÏ>nae_hWbj_wͼ455S)   W.k0OˏIyyM(74HqqY۹,feeefm] +(VO+VJffOgɸqcm---2qx?nm+o;]֬]+[m}ntQϽ_+C5xx[$@RM2:bxaR'   '՞vwu:n4Rg)06m {{Auv}$Cxω'zВK}@@@ bqQ>7{.oR"ܹjat()Z劫?Ϻjs9O_ $NYjyćUW_'_tIj{k=EHAU   @RعK'zRlY5~\ZZjM\]ZQY98G?w_yt*DI }n71%J@@b,21 99 " $@L sBE@@F2i    9-"  I#@R4CIG@@@ Tޜ@@@ L#   @H*coN   @T&P@@@ $7E@@@ iH*f(   {؛"   4$I3t@@Iei@@HʤJ:  ^2洈  $Ie %A@@b/ԭc*-"  $@_%EG%?," $_a   '8,   $0@@Iei@@HdE  I2N4  $Ie2"}@@@$@R'xE@@A2F>   q <"   ߟ֑    H7طJ   I!פF:  G2>  $IeR #@@@#@RwZE@@B2)N   HO  RRRdtQKFFF HyEO$;!  ]Q- -K>X ?b7V;zuIfYQ@@VP +VP}~H*NJ   ^@g;-v wOIX7@@7 Љ-9:$J&8 @@@ .$qaQ@@D@ ɉ~'++KFobJ!  G㏕s>C:49d袈%2d=ZnP/y9g)sDuDiiimv&U.(Hov4}]#=TF@@{&U2th}ٔM@C8ץ!轧{0~|z^3GrqDŽ}onHrQ e}CL8ArK)//2*{{ X i;W̐rPOLF@@/͗y󿲕g+@= ya&yW5l'ӥYtFo=w 'M+Vțy[ ӧm#hr?̳цvARe{{W^{Mu3Xsq婧xaRZZ&,1}J7m%ƎO?ıvQ#F8=>n& AcvwKcCG69Ԓ)?? B:\"s2l0̔SχѻU}=9%55UλxyG?P{|~bsnf4y_}%ݧ/'3}f@@%2s%̪UW4hߟ"=Gvghmsζi& *xd֥3eժR\&JI&wMYӶ&LN{=dͧ_~MDI1oNl_h||v Ekmu٪w?{e吃ܿN;exJ`)SLZ%ūV>6'_yuRkqکrV3fcnjDzIM,}>_SnP?d2T)C@@ 4dm~- μRMDve9l3WDmγwVg};Θa;&T<rw83eDg2Џ>TMl3uk3[hv7(w{Utz5a8Vˣ;c֙G\f)MMMKS}Mnu6Eٗ%Kɬ.zֱ%:hђnCeI\o6Mb=X_?d'I|,;e…ft}dssQoz>D`z־:}jTE{@@;l/m?'4_u'2fwoSDٝwQn翥sob}CdjRH{S>û謜iLK|9;̐N\ɖ-s'￷KKN=ꙕ=ߙP5P=4ksZW_o?ŘL޾$hP:m2o#  ~8-nY]{V8Lflm=)_s.G\v9<ǻ^9`7#o}{vFPTZFnb{:φ/-T3μjBɕcF9r65j}|-{>C,f勉1W@%65P6s.i{==0TWWkWl#Q[3 |  @WΖ l0S5IDAT֯;;KF/7Ϝ?IsKMg<+]|=FOr¡&a},^~{[`gyq3\l)1 &|֙I7r|~3<;LMZ'Mh?t_hRogh/u=׻x備O?Oa^t ΂[Z;$\0‱jﴭI}f 3czrpDsm8_i3v}o85p-  9DA3 `9~Աz]~~IJ^J=HH֘S`uLӡ?:,&ԸSӳ8TTTvHYS q,m3NC>Cׄ^x1htf8k ;㢇&x9ɬw[>ˠDz.$fHu@@ĤғPj23nXi3#uL(˺dI4NPjZR?sbmY^3kug؜h6eʦf^‹/q]<~%WI(>5PuθzώF.\ԯ e_o*u  C@я唓OM2R r_3kߓTզt]q91cZgk7{sT{_W71   C.z,HZ`9寱V=@@$GhDJA d K+aOeȤ\  @l+*d„qf +΍?b TSQ@@()Y#EEdXi}YrM(Ws.Ie<@@馫ͳW,si@tRʴ4X  !`R/.u"{*CQ@@@$|1@@@" @@@H*   D,@R17"  T@@@X2b:nD@@ ;   Iet܈   @Rw@@@ bF@@b," _222b:ͅ+"RRF:::X%Ie|dž@@(*%9ٲpbѿR-qcEmn2K&X-  0Ȋ$ -_Kǭ[Ԍe bWƒ2ƒh@@-%P&W@Kǭ[ebFo,I*o,@@{*9ˁ  X=|Ic_f*b   *   $I1t@@{*N  .̐C>Hs`$eͷޖ_+~>RSS+MMM.<^%/%_|9?\8R   @ /.^}4ojrԑGȁ'3/%e{fSd}<sλ>y۱hph? +g]*.)W_{r߽u uuʜ^ Ƃ0m5T  :C ps_Jcc}k3uٳD T?h9WGʦ7IDo\/W_9g?c7f֒yĵū6` I*]9,  k],]r\:"^!<RT:fg\F!g]T`]dL=)))2v[![llƢz\c/}9odeesws>Y2d57vmkԨx7w'I'ku\ˡ=;^_qgk|@@ t.yսxW^}\vEOMPS̑dy$#o~W7p|ɧ2cv$:uu`sǿ備|k2rlovo/+kI*#>@@tttK:;{(/'WξF.d m˾8t&uo[n|ʩ*[lr䁇$>׶={]?ϼXe҄R`Ȉ=U<8a=FgflZflngP҇FRa7yfXy'׾̾W0<)*eee?%}q-2uÍJny㭷zŨ^j+Wz> X=)fj>΂:ey.R^^aOEN/q|}jYy02s.alDŽ|12[uٻ90s[Ɲ}q3  @\s H9{u&&+ɫ/{>{eQ.GihhtŬx*q ՑYΌ.0_<{Zr!1cƌKIq&yjH:̹d{3Z4?lP;κ:;~]ʄ ݟ髒`D`Ts@@!"]|nrUdyCNN=sُz}nÏ>TH0c8~=߾{O<"s|̊K}}Ϻ/r)/><㏘~~TJTKJ90ә)@κs?IyQy񇥺ݞ.%{^qo Ư+BØ8J B\l 稨hTצ,r6f\HEưp9> 8Vd^|EdVz"2r0Z-GZ 2222)/ć Yd_۽ߜ7^CRǖx{{3x On;x79qZS}4n€{.N&&=z$?QDҿo>3~;Ən*drreډW321b^/#G ۛ Gc-S9~Ͻ2(xB"><Æ?HN>Ç !/?}7vi18{컢9oחoJ?PQQA]x7سo[Y[߱́C`\=DFq WLf*GES Dy T՚0 ̒ KVC5:@VTiMeXwvyyyѾ]%%TUUfJJJQ(Lj$pL %Ŕ[WP(K!1)+,,||}ܹT(z)((,FT `ܩ#zSU(t\ƙTz}ׇ;L>>>thߎSWDޗ˪5Lr\).&DFRT\l&,4JڶiCFf&v)z#&:sr͵6 Aϙ3)6j}ءyyygdFNN5v?lѣ{'`{LfN{Onn6i&i]N?-NۿcϷ-eճ$y^.,q\/S fux*\cw;Ͼ39'\_1 22BtV}Z5yyN1 ӑ{srZjy 1 "##/@6deg#zզB/ٺ7Tuk}U|l`W~2R3CIOtL(#_'O4#KNWs(ɮU "/4XczΔy =CFf&Og|ŗՓn]Yfz;ر/{ L&!!قw={@nn]:wb5,z]RRYv܉W_z̬l|}<}p]ڥ U:UUUTU8vDׇ~g,z{7%ۜ:}u 0n?7m'-5.B!'e_3p@T*%z UyqyAN&&d2Ï0lf}yyr*f1cnjf]3IIM%44rz z=%l^^9zqc`Ҕ[(++Wh ޙ[V1Wj),,$..e+ygo.t0EEt؁ U:vhRRRBhh5Ͼ-_Xh]9 0kf;bS<9gߙwϜ^Gڰgngm5> ǎEZ=㤧g7Ǔca8~a7rmӸtp<SsYoKr;']Vjij\/5_L8U~Y,7k {(-dUjk/r߭$BWoSc6z(!Ȇ BS|T3{[7ޗ[Zk7gyчX'G^?|={tg㯛Yv} 0ٰWrs5WOsm1-ej߾HxݷY6n2^EV^˚uʪR,{֬] >f>:i9 +=$6m*_ճ2QSƙ9֙9 p|aCK_|2 ?wX 6[owQVŒm?Nز шB`׷{ge,[`JҚn}EcWdߵ{฽wJxx87v'(" E0־};kfƫ/]/O; ex|}}9vݺ-`+vtV} !((ÇkLrl6[ϝ~rs`LN{}z{ Uq]ٳKErN'ǤАH>Uh4v6vqq.q7p,_sXph_^ u#%lZ[5 %f6>m/XF`U"lE[fl VkS*$"<6Xmusҏ .6XY???uj[/'N"BC׋ea/x쑇P*DEaa3?ЫW:i s~?qgS辻ei/yor9„z}z@VӹSGMYyA m֮6n>ث{G[ϦR)y9DEEE۶c6[R'Ӱ~~uSpŨLeeoM{Yի3T*&:3sA}NfMKVn:k& LLBSkr(WR8pPiB9\_|W]9;nVcUolya{ =1~ʲkoyykpϾƛ5c:=<^\&g݆,X5 2oS=\O+~Ͽ(.[+<dXL!Vń_y@N ҥBA`@y_~9{+AJI~~]y|Z4 EE p6 LFAaʖ5b^݉c]ﲦ?/u6uӒuJvGd2066KYȧ_,`}SP`YhH?t{ Gs&vtVCh4RQQqcUC_,c39/lhs{xyALݦ*OSVZq8&@pptu'}[\/xLm-4V7жM2.wf=ޗbhMƒo)!!( >=n˖8uhكDcM>l(yh> F^y͖KBB_K?K׮]HOǟiiq$$"JHK#8( rsY%7/KHH46m"+OiWB_JII %%-o#\IImi$$7QI\<4ՙńJHHHHHHHHg_ B%t 6}DĿ@Aa!8{DK#!!!!!d(4 I EBBP*DGG΄1#ZZgɒ%zO .5`PYD W/ywSSbk3 7M!ت!$$$QK@ZZ:;udǎ--NSVVX=uUar 0 c0 @2BWDb̂APk4h4؏j|IpYj5g5z}sv!>nӗ=󦠸9ry6a{q<[p3f{--]Z{ݵfZJ6JHHE̟NPBC^sѿ%m2l "<|0w*z]Fd`8ޟ;}qY)rYݟ5RI\HHHHx'N0tz{APPK,^F WO2u#Iz^^^6$WܕKwO \!+捻͹uFY/~`^w4_Z΁8]kd_ KΨ^vj h@|t[y9BPQP!1 DA7 Qԇ.x|"2 }m]YC?4j6|>5yHNmQ(V~  fַKp>zf^#I?ȑ#[Z!ׂ\BBŠ o_Dn=h,E8K=`+*jʽyʽv6YCLg/yťdfFdQ)Ǎ|~32 0 Z[6F[;Ũp{@b ߦcFWˊmGmà˪IBI":-J3HϨlеbݜIIusj$OLL4GHFNt&t&J/,s%yc<04[`& o 55vO%ףQ (ez>yaA#n繷ڇx x{0d2 gx VGt /Wna)r?gњ8hsmס3?uN֋;tLo.EUzz%KQIe[vg[X A+#G cxs_m"#fU+A.3vhBC9q2|ҹoQ9|;v@LL4>szϗݻIoo5f x^ yrm1d&K~^LϛOo]%o+̸ }(y䥟yu.t0UUUe+vP(8~O>u BΥf?=Z6ցFi[^\S4c{qY#c|QE8O0x3hLtvaTTزdR~6̜7~XkɄwWTZAED@\`ws[Ss(-w(fPXNwd9*ti5 ogqt5lVѯ{ ǒ39b1TF뭡oh پ? f"-<؏^q(rOLFJFwdWPXRAv魱䑓__X&#*" Rsq*D6< ?K^aY4k-W얥m"ʯR~[r  0ٰW,]u\>ͷMhS6~ԛ&[Ç ܧ`w߳fzA^i7g_㯝eFB_ӯov骐F!\MDx8'8zͽXrUJV,ϑVKPP Y T2m۶sӍHJN;;,Q?ϯP[rJ?Ki䍇& g(v;ͧL9ITU0kڐ:/d2eol@݋7 ';M[![7`,9NsTVկe9>0cڴi6Oeg\֯ atiJL&בl6̫`1 R!犡+CEpuQ1_'Y[%Y7 1{ү#f_ŎɈfkFkyHٲ?ٶ/њ+sHR]E08~:]濏ŏ3mUr:iՐ cr}x".i^Þ#)TVw0>]z+ݑ^=vN9KʪTZ.]3=b"B)qaJ6OYDoD^(3\jgբo{3oVSPcdqfC滵Yj`ِ1lݛXgdpUSfKK1Gn`ݼ76G*o}Ƶr=yl?k ^mТ#1ػƯepPFF0L秵 ,VVV=ĤdƌUl:||:̞>@QQ>>>󕐨20j)++sږrvYVO)Ǎ㤥9}}:vhIK8viV淬ː7"ZߢV+=vgִ!ȅL&㵏6VwC;4 yJjz.6.,df F"-%5Uj, .&m~9w֜wo'Dpw: ҽCUڶ/ѩ $k*}pL6!~69cw[v<햬dpUsǁda.rزf6:)5]EQdԠ.t[Ch6.}mТʯlu#@^^> `uFٖYɄ\^3VMyṹ]訶l;YA)(k+׿__Ǝ[*!ZWB@דGΝrӈm۹kpo@e4?$W/`$%bْonW{6luD5gލ`;1w #Gֵ LCR)ݷ_/tR>3>3.]Gp'Z oA:WܦW6ߺaw+cFӘMKJg܈L2RaF`}N|-al؞U;kb'W]fp9k?}=ȏBf}sKۈnj.[c1Q);w\{9I`!9lœJee22wMj5-fk# sV,!1Atk>} 8x"_nG3nr뇉3U=xFDGY6Nhr@Xٚ}w\>.kyy<ؓa4,sL#88Rt:k3%KYEܹ~I|Z4 EEV'~vƶ3k+!Q3)>ZFTPUtf1^^^tr8n7չf2ӐKQdSW?"eqA:|h$CG4t^c Wos3/'P?Lf3 ~7ӻKH֧"_5EV]w$kHྛs󄁔W&1ͭ47^:V|p/fȆ TjXj'o=z+?(²{k:k?;2^;+U-{yR{9lY)yͼDV~x +~rVSXRwc7p.JɺmGrzل{h@BBbOK0Vѣ;)""%7w02DAp׸8*g{ ٔ ML`/k _&z}4((%KXՋ;((.`NGvvzfM€Kb.P~-oV痐PwXhe9Rr9ՙlyeεUxˍu¯AꖪeF4L7~Z Km6w).[ك6'd!WY\kGCen{`qQl9LJ+ll|C!STgU]qa=أ1t^7v]76RYYI^Oш2#UQ+WpN˫eͯF-GQze/tzU:#:cÇgQO`/P(w=LO77Hu꾶DQq[oC0MBaI!l9e9}o6Bd6;#;G;2U=gT5$-IhUfe3E.h&L@Tw%VUCI p yw} nL?hQ >]qdɨW+ռ>3 [2;B&Hr>2Y _ ZoEsқəU:7$gs/rR鐔_ VCev6OɠL@D` ,^n.9m nGl⹶FR~%$$ZQ.K]dxGZiL\۷mGR5'kYVdql_qW_})ꃽd5 uh2SXR,NJ'*6W$$JHH8(c0Q1Y)EJ%gej؝ӫwo<5kIVȚb`eeʯ>l>X$$$IhqdH >GE[y9F(MiVYSR_cfL[k~K,i3]eڴiHʯELrKgٝ!'skbSB⿀JHH8fA@qҌ&0V6h=X(V!k{yj $zG5DzI0 >}K%K<5Ih=HʯD# gJLFTnN *uܡ5j4bbb;H.DR2Wϝ>,MED_Ky+^huךk)$WBBEu:bdAc^Qחw Ts9:s&Q}l '2b2Ϲ C}B9Xt ۜ[Ga4w6;-Kkiuךk)$WBBũ&2U^T/>Zwf?1X4*=O}H/yt؆KqI_-Bjzn֨oG]]:+uzpDk]huךk)$WBBUE?QZ-aaU*0ȑHYl~ez_<֝IM⤱u_M@=U{ir6opZɋLO7s.x@d2WT=kz={tg,]zIo!voGi f_DQ$L^+_MǸP#Hj/(C;,^9v<}Xv8Ê ). e҄es}ִy Ngݭ-WGf31QaeBFj:MrJ6Fr.>~+Fd.J+V$M>^jYs٬0Q:qZ68ڜ":IC= .2ٛ=y#w<ZJeIVq_/qёAٺfKbD2sRqU$f<Q٩e Fzun*dtI;s%-BJF>wM+^o.8OP0rp~'[tp< ?.;Yx7_S=Or5W7>t_} w/uFB@n]:/X԰0tȑízڷcʍr٥jP*]RN IDAT&ѱC:\qܹ3={gϞn۠`ߑ[^:X2&kG\tpV|>i[aEQ$=u$`0X \ֿ=>1qûK^eFVo>̳׸4{pC:!6̌ Y&SG`d{+BLNmYlV|?>]ͷkvze-IfN^jhq~~1߭ބ6c;w$;ns/~V\EYYݕJVkQJ%Z-AAf¢">>(Jf  Z+>wWUiШ(raŷ &Vn:̎ Fd򄾘ky8uj6kVz,qC 3fDQ@&X6"{/3Q!n+*O1%kRONA!(*>TTز$O=sZV!mj>c#H.lq.! 9z e/t b;e؀N]ҳ [lcfm2;Dbs}NA) թ-ǒ"ՇfU~U*ˢ Kjj̹6;u$1)Q#Gpq22kZZK֝0 A8@߁ɂ3IrP@k ֬ۀ\ny_R`&Q?bwZFtEY̞;,Р(lmkWP'ӭSS'MejNfȮ܆ʄ-Dd8::cϵ+*).s>m4|}}nSqY.xӥ]4*92_GٴrtL/3ʂ52dJ+G m\(i &5 ˡ]瞴ksFVoǦ!D_޴b`0R!C&~Q)dq(2* z(2h|dF!ѯwO̚ _=R׫1ҬoYhh]3,,C;CngQ$&%3f(VZm>/ wHH4 zntf{Ŋ>~;nh*ZL}=h]6)~sO2ec!{3oVSPcdqfY ?1A|Jiy=:g?Nͻo1:džwxپj^nYm@P_ B~ ^Bl*ɲ-Kd^V;k%<~rϹwΜ{ι|7ҲR6n\SxjwicmV-?s܏~w~HLN$:ROcS37\D9fTZyoD[h{.:6n)b"(YWBeX6:-o?LAKEu!pí-** l|A,@J6oݡ۟Ǥ̄aO.EvZЪU7 oh?}y,9Ͽvίn9?x:,:={ PT\t),ڇj/jzv?>{PSLfSxW쒋پc'K6a|3immx\.ZcDvbccnR'[oISSex<ĚL:}%e[0wx\ygȝg?W 9ӖL!*ROc'_ ϳnZ:n:V-7,V7*Bygr$0E%x2w'U?eqhdY#DuD5Ƚb|^g_́Z%qR{MWfNx_d:_VǗK/WOŐy![4ꑚ@k7X\N1ԳG$5W>s I t)jbMptG$l\nQ`[In8ёǾ:*:mꤠnD`MȡdZ_nԍm;vÿګ ÁZ惏>gS{g_f*4j o=beYO>+[9dj5WR(Ks%qs/E W4G,^t K,rh[PȖ((Y8L`ނ?TZUU5[ϒEpSq\H*`ѵpNq8S1#-">6l-3/mz5˧qΪDuv_2,ˬ\7>X@rb4q&W57+;owǁK$k_co)&;o.lvKFMr|4?{!Wo9w?J*oՋew*:!6[8vʫq'@yzpu+,T&f.E.NaRfϼ5&Ipǵg1oF< IqX 3`2mz-UBTd,<چ18y|Uf.?o fEêǘd|i _oBTT$z>%6v_FBB:%tcyϸgeB=ד@`UU\x<,}_Io|v;cF Y=o:V-p"geg|4|Or;:yُg*VxYzAW?E]ɧVɷgq@pps Rqs珿m":^zo+ T/FÙ˼3e~.ճ4w0\Eoby6~hn7}UDnF"=# :Q0n܌D^zjl'6xӴ.KvzwG3)X㡽Mo Tv;v{$ 3aT%ߞ@-ёzt: ,ѭĿ>'~LNKij[%1C up=lYNFj,&PSf_IDJhz'`ַޟ_^}IDVz"+`oMV>ZwP^O~wse8$懿zxS$ёzZ-&ucYp˪7Ea9f{ONӘ{e$6HgY'^݂)H}SǨ ᡧ>W &@MC;(A!j (bء}M?Zɔd`1ё>0[lþlp0[{gW0~111>w!Pno(t[_gyg"&r[Vꖐ6z&6ڻnp- 0tXm^~kv =rMc0~~+tjj1P9Pp<yS8>s #<8Õ r?Ui *Bܬ&lW 4p_>Ky&F zFL@ a 8x5|7l-`7ss53ZSZEr|4L3򷵟I<@ a 0ѡ,0>^*l۟PkXx.N JoXIQ W  f4m'FD #fW{we Gh|/;g6X1H,DEEutᛁ9s(ivrPTTt]9s=jW [;;hU:8Ѯ@p2 _@G~~X0*(UJJJꪫ}饗i@!'%>$7x^O^`059]ڟPZ-YEUU,WoY"?'&p iƯ@ ` %%ůdBVc6q:ï%K{{{,YN =C5)))\V+0L,JPJ*+\DBeJO݄+a *UVojjb߾}YEL$?/,ȲhT<*>Y3f 222d]UO`Z:T\.˗/Gn%-+\p q=9QG8z 4s< S=uƯ@ … 1 Վ;… p`4IJJbƌ&;呚|...c}dYf!W"NNSh4\xᅊ!h8q"_~97oVSTVV+ HձJBV+/=R#M(5obbfsנ@vV&NbHr5W3ώˏ^˥Npݬ,j5۷n9s&))) 1cȲ$ITTT4|V hٰق[G!%%vǃboO+dŊXϱ7|0Ê` ==/fq~dLX9p>j%!!At:imm}XHV{{)qjt:㉏vD[[[X} e10~\ m%%ظi3w69x$yb ;;?g \|!Ic& k{ =yH8@ww7---tuuGdddٳg?S:;gFIPUWT*)Lilj ؆Ve8NJ$[d\aX&6DSS35}t\Vk7.P5&:lW;[PPXDyytuω:VV_ak72ł!%%Y)//gʔ)ʃpBbbb eɬIͱs]NZ|9 w٤a9|0uuu0c 1͊A>o2x_z6fBvv6xYVObcc {7Zׇz\SBOo~46Oo+W뮥iS;_ƴSx'&:/٬sÏj~E[[99ټܲÇ_uv-ZHSy=~\wU̘>TNY_}uP0@}fCV^^d"..4Ҁcޜŋk.d2)l)S–t:q\zr;rrt+evl-䙼bCjO#yЫ]̎}b Z`P9[GA4.Y[5| Aё')4 &^l6+/*ٳgFee%l޼Kb2Z*?|555} _@O4 NGJJJƯ,˘L&4 6~Z>|'*K@,v:T*"""B5c~9S>wY,~B$v>ߧQ3$))̼? c'LvcĉVbȲٳٻw/š騮VV;^(((]DWyHʻɍjE 55hfRҙ 8[P#y}LlOQL&233)**dB=- ]]]lP0HD^^Ip\РPTL<0ƯoJQy˲V{Add$111a>㰵uvŋÎxf1>{ɷhC8hx-:^5t9OϿP>gee2aBowc_(_QII T{3$3#v-\@Cc#fkozN˭xꚀ{;@ Vuw8<~CÇ>1k,4 Z9sk.Ott4cLPpD G>Z}4#}WW$6mʶ0 }ӉᠻFDDBnnnD1i$&MDKK 444لa֛}X) IDATh{XBy "''͆BelNkK$N'۶m ˰_P0>#2ܾ1UUUW*%z>/p5ŵ 6r0::Mo8JiU۾ssjKK 7x3?<[XģK>w0=w8؜Lo&ycX_g }5?زe z*`s#MO7(| Z›cHP`IKKS43""e˖QUUR,yzz:~8Nv;$RGV+#]g,6mBѰ`9trX˚h$::66n?ǃ,a-:_zp6ZbccQTlA[[ dee"IJJ+2>_mmh4bikX hmmE$Sg DcS? sG0d2~NN&7+Νc^N.H%Pc1{ldY&::H4 g1:Qp:U\Kw4˃WƎ|ƨ,ˤ+˲墳{*h42m4eymIp:Ayc333[1BWI"'''`eɓ'ȑ#a`6x<}}\\0a7An9ZUUtEZZ^$D:^K/?v>x-NCj>ĝ~LDD.:C5?ja_ړyQxH,/=>ztl3vkjjg֬YJ… ٽ{X;:fy~uS/ @y~rH==b]%''JԩSٶm[@#uɒ%}!%7j """F=ppAHNNfٳGE8q"hZ),,Obb"/l6{nY>}:QQQȲLSSZn0aL4*LLL$66V_Pd5446:::HLL`02]͇4***Zxrrr|Q7~~x5U\y/JV{wk$Q6Vu*DŽbCf2?>|5x9"3sLt:jYfQTT$s`a\TC89%Y\z  T*hZ80`Ryy9,մiPȲLcc1jɓ'1fuuu rss,Yoڊ``͚58p@ 墬F#qqqYO,l6`-((9^'h4jxjL>ǎ%^{duttDzz:K$IDDD Ӊ'++AL1=+`\x<Z)m2T=q\418|XQ[̿ $#nTm&D=%,==JE{{;fD~~>zo:{2o<4 z3go߾ƻXt<LhocS-a4x;n׻lxQ~T7:*}4wp.v36NKKCVSTT4Z[[KRRe˖>l6ZZZHHHS7L4i6_NrssJy<vSN!&&ӧrhGWW7ofڴi'ܹի&//lx`dZZZ$&&]O_C>}:T<O^ր$**d9HIIaڴi444v&:/ƷMRRqqqƭu~`8꓉yCܒIv${%$b8x0۱Z>;;;ٺu+˖-C$ sa݃>X|Ӄ'v36}kNTkPSC%ޒFP>biv-v :Ҝ3%aZill Uh0- ;7:5n7uuuNB8҂VU ܱc ,d2Z{HNMt~ZII &M"..3faH\z*"VctAu=1g#*N'Z3f$IOM}Bq #jzeX,, jX&rxd8?rV5,zIrr I7jIJJ & 簾&l6[PvE_@0~=*i~{n[NNIDķl66mҥKQTjN9Fi :::N^{'CW24[ϑ?b10h.Y ȸd,S؞}uy/6b )^G0 N8ArCodYfϞ=̙3Xf̘N",9,4eɓ'G~~>A\/ءZ4o@܀Y_s$j%G* -- Fȵ"b>jvpU*7/#QUUyeXQ[:::1Vne@ MU~_gw`,\+Vb .\8fMjj*yyyh4LBDDN3Ms8Ũ._\*NaQݮn5nVډl0*/!S O=^7A\.vޭ$]p0jjj(--UQ̝;ׯKo$ɍ$y G vڀJ:jJJ嘪* OLLT&"s|$ȶ|w (Kb%޳V XYc BAx~ -pAZrgasfCv -Shٹsrf3Ť+`#FOC{f⋕mZV]h "B;I序};] =>xY۽2JBZyy9'OV*3 ,Id@11E;mPC%%%twwզlii ʈ.oP~K DqAɨV7MOsc'lܸ_ 3hrj*&>U{Cd<m8~ABM3x2$Qn\,{c{{BAӽ>`=e/ވ_@pbvxHHQ]]=20LJtx<=ݎh' WMvp1҆`Jycz葨S << ٭RG0U*"VyY8*z_(@!Ϊ HF@&#B`r\.$ե$9 $ȑ#+Jw _X q=9Q1Y^y.rr#T5G t+Dze7p[Y) fSat(nj{n0 #fZ\ $npڰaCm*k8KY"?'$kt܀bBE#NY6c.|OMh,"șVcT(**"??_ **J $I̜9sA iƯ@ P;g6X!!>o@ O(Y=z#@pӳp֠xϯ@ #w n &e>|O#$dyKD\BQ&X߂ 1 ?}jdfH[KSPF`$9qP @*c} N,D؃@0[1l,p:TU`c$'N^ܪfhU5 1 Qf5~JJqVE Q232LǠ7`Z:Uz-[)ikoERXxl/V˼s((,f \7NFFV1\Sjrm̝5_vmf~7()f͈Uk4 b ]uJΙZVIY D  j5<^un4 ӦN`bn.99*3!>Yj.X0eKc4miin D7FJnJkh~wuHJ0{ހ:5N00&;wO2ud'ee lONNH&MPiEGfF:UUմR6u n~S%ay$&$oaT*fMVl6v(, :x[f+zVV]Si+OU>zo ++%H0ZDˆ?.ewȘW¹SMktiM '*m)<}w܍lO</ŧLtt4۷C|sض}˖.f/hiiWFA򟴩CGkk455SQYINvv7K㞼Ys% :ٝ{{QRV|e}sɎ0III:l Ak4S>wY,8㗼{C$Iw+.'r5Wv+Mٞii\u Ȳu\-?o¢""F^]sfb=C# Ddd$~oڼԔb_2‹NYy :(;kE||GASs3&Fvf&G??SVVFfFmm,ZFf_mͷ Fe*Pi)my}VjjjHH';+sHrUfzAaQrRb"@DdDӧMtP]]C +&33m2aBj Kw7and_~̑>."17|,ᙧ΁i3IJ0qא,x<2'fQ _q|}+))f L1â7>}W^}ֶV[ȲG1&k_;{V>,괕~hPT=2n##˨U*L&Ӑa ::(_>L離f 9) ǣÕGP=B^,S'IWĜ*lx<;z3<)-[sAϛ˙kV!2mm;9 .?m=MDDDج6:LtZ-_lsbRNBk[~^ց<_~>'~fX㬙y̟?ocwouSbYp_F:8p#I].7tu_\`te)̘>_twDbp޹ɧ`y_8s V^){1@ `!p:Fb;N^m7>Vrh0FDىn'666ivSW_\>bHjp*A466CsK K-\bkY8y7>NsV +%E/!-ɞ>ӣ{eFכO>`„׶;WX||1+W f˕pdT*^}Mv @ll,>[Gp>]ry$`߂5Oc!6f"""SvtNNTUgY.YBѰ-[QPqY?`,&Q]sx%64bV+ܜF>YIW vX,FCzglj[@ħOvV&U~uK|Oγii¢b%0҆ 2*'j^ _=*%vޣ=sn~utX'ӦNe̟7mw GKKKYd1YYTUUs-fԍ߻?྆FnDGEa0hkor)x5{_mˣo>nχ,G .@ףj=VU]ͳ~Hᗏ&&@[օ؃s~ @#p2aLL nvF19ܿ'*s ނESsAz<v,}1ǃb9WxPf2uf#.o8HMm&O1&VsSD IDAT{^z,k04wSZ^OCnꚺtQ#+2Xmh*;k /Őak\|lڼYٴy K,"%%dHbͪorիسHNNR!Itvgo U؃@ 8Z孷p:QTr/nܷ~Z~u=aYX;~ Fcav_A~uۭXmVL1&xA;oy UMпE؃7WlcAoh9S5#N Oڶc'?<҉VeVl@L1 ̓{テn"""e,W0VH-?\O lΙ$f9ܷ_U?K$bcM8ΐFW"n>&'IO?7ԿD@@d; !k{}~9c7]s̛}ſ_4vsxOKHpEre䶸X]]Úy2]TTD~~~ϯ@ vdY=l6Erw'bg`io][l)%% G}O߄A5,$Ibru"XMNws,AW*_ᶯhxssϿ$R`lƯ@ '8]nnjIcW櫍_#Bcs;a}~freD$ WpCvBqr:M7}Q 8Ư@ .7njˉUwv8eW  D+EUQ==wxcVr~WYPp\hZΑ/&8`AӒEgX|<3ߓ `6wnK! Nn8$NW 1o\nΎ6ꔢ#}Ƃ&b>mjxc߂1 ?wVs34ȲL[Km-Mc`߂9Z@ V3@ *b @0wl{獱VC C=?}ѱVA C~U`ĐN}A=@ ԏ_<*ί@ A@ a @ N+@ 8iƯ@ A:@ !Ip٧z4b4y/8P^ش$?te_A"<@ ?`?[x]h *B8IxdN.@$~ư9Z0~G  iLKؠIڱVA1p"U5q}mW縹3MO]e<xs.ƂSnz؃NgNP39ZUJ&V6q,JY^[ONKQsCoϤH1HR:?jر`)^]U^Oo\LH:B6kv,CFnu+'k8bIKte7k;7вF_i)3{x**{d~ǩ sUܙۃQ-Qau+6z$y:^,sq f'Ay̜8k%)P<4O&7t8d&FxeOVqGn /A/HSNwlu }aIEQb~k|Y/R1x LQp *Q2efgkfqlp+/ѪFtOn zNj z3% -oqV6{2N>z;ד(7n㑽oѱCMW7:7Ps{k6qRq }-ub]jCnpzW!1N|"5 7ۚ=$ets ԼWwVDoZDi%t ao3'@posݗZEW_]{6]d>P'=. <|7SߗhX_'Nt<&ecO29ZE:}\ZTk?C GJW\x ,dqDk JK,<ۊIDh$D8e`Ww ̏UqAC2[}^T{rY1[ltdOH :CO}~) 1-60"m dFJ<0G4^⺩ZNIN Kc{lnއj>8:emQwp6i?{wD5$&m}qOuE["ǂWW. ^_w]AQP@\>PnZM^ik~IgޟiV .'|3.}/6kڬv+&Ozo{ΚHQ{v~I@UYԚx騉o~(ԟQ s2hK%l:wuWqM划z %6MUo+Jje*Q~e.uq΂u~#=J8JVg%@׬g%6졣V S&Ppq_}ȊPvթD[ $Py@tq4wɯs4oaoX+gX$Ԅŝumd4K.P.tޘB,"j5>KDFFb?z ƪ`G稨u~{nͷߝ稈Qdo3NT nhŌBHi))+a68Ԕ"99 zfhjzJBnN6f unvnb$%%\^S\ #** ݺvA^Q"""еKgTUWE_]O|y۱HKM`4ڶ(@Dx8b۾c'k|#"nݷBmm˾uʂNEyybvvŋ/Euu5쒄 5Gq$$$Ӧ?ٌ'f=}"1n=xG/f?9yXrt9Ϣ1h4QSH9'}WqQ[[5.ǃLEUu w=v sO?bС.}v=՞o^29eXamggwÜgfdfCBN3%em|^:e2z联d 27mg!Ƃ!J`@YXZ|1x;Ok=KD7&Dƪ*\/}l܌M[T~o_| Qw1hO^ݶc'Ə#': 4o,\xoشy+A/{o.BŠU|*︦L3tJ%fLt-&Ɵuv ys?2mUr$&=Vx-~ }z;iIIIp$HA b1.]8ፈc3#++˗.cNMɄ0dcЀE\l67HLH@nN6ઑPT\ d`0bؐ:xNo>Ԕdbmr{[Ҿ֮[ 9) msێ}]Omٗ_}-o(/@޽~1 {hDTT2 ;_kucə[Z$aW}N24$CqUT]鴰ZqUe<;WL5?lr|qq-fCMM-bb43^c{^}=8'uLDvO~G .ˎ7}ޡ]&D OwL 4׌wMaCl6(JN.mmt'{z6o݆4|JgWBEZs+.w-ζ+@8S&zxyaxx8xMυt{xa>cukw+ ]}?^ATEz_?\viжOt>M7S0JINFnN6 PrRBVfɷ/1YY{K0b#T(cm.m|ר**#yyxEDDRSSOc7v+]_qSRR1~ۜSZu^㸂 oZƯxSi)8Iw)?;'q+(8ZdfdV||?E<5s6[DFFߋ$aWӳ0z(Hcg{e׸ܑ$ _y>$f4$Ɏr-_ ˗.nJ¼ Vp6ŗ1ظ#v**Ɯy^7`γqaؼu<p\~Pg20gK~<ԮR=wMDtKF ǝaO`p]RpH^ :a˼ojc/}H~wūC}ODrR,f=8˖z-͊eK[f(xu04;k[!`|>\5пv{r!™*-'NwfgDLǡƥ5`4 TNX\wӭzV([l)-y ? Z-*+[obbb`Za:D:T̟xDQDN  bu:XmVTUU<ԮNEMm-l6 bbb-:QрPw(a7Aۿ__5qw?Ç`Gkx0sƣd&?pP^S9rJ4/׳h1%vںQG`6OI$TWLfx|$Iߓܩu$-5%%07t$ke0xZZ.w)Jh4QmvG[É:UW܋V{wdz*Hٝu!`b:^o_L i{"` T*"""Mo({,{o؁fΐKRv%vںQ0%""j)(W~'?o)#+#s_t{gXbᚏx/HgJu!``KDDRk IDAT:k-x+y㉧;m]v# F3""xXOky*e(2旈(.+m]Bu9"""" =@DDDD!/ &DDDD2Q`KD \Nt>#:/MXrfx~rtZm:wP:sE#s<,L3"_Z_|H>GXU(Qǧj2`rrCaP_" tyk>^ēu4(]vq] Z-,RSP(0˶/RлWOdg Da@~HOK$%%)( DGGc@~_@^= Rmz[6tZ-bhNE{Ddd]wPTn~}@ӹ}NT+[O, i.}+oSW?[Qq7K,B漝sΗ@v>{Pe> (PztmOqnѣ0osֵ n:\s(sl6|={851k hZ@nAbB'{`?_Cnnj$|70b?^Cn]qѭ[<>߰fk\Jy{a00hWѣG.F_}Ґ |fgLumL&,^RSR0{'ݍHnݻc?_å ǐ0+mdgw?^C㞻&/| :a꽓гgϔ0%8q񄅩ڂzUnǡCuεּ-/Ej{wO={Wø;n>~1 {ht#0Q___/5F G1zUdFV$Iy.߳w@jN~yx >㪨лiaZQ4xvB<>i<)Q(~ژ;͆Zheuuu.3VUH d:qw8uܚoDm]߾}`A_ٞ' )ƍ "'NDVf&kF&_Æ׵lP* ]N<,l޺ io -Fe1WBEZ91r;ʖmjug|r]1 FX BQޑCAi! q.$'H'eEX=۷&^=C(rsqwM9^D]VT 2?K^ =bcc'OA_Y B9l8z6i)8qF˶DQDff"q$/_(tyG؈o{GAA!5* 90-?z/Pwm5=DL p\\,y10Rذi 6lQW,Cm]b۶cozFvzL$aw=6q>?E<5s6[DFFߋ$aWӳ0z(Hcg{e׸ܑ$ _y>$f4$Ɏr-&'Ü/Y3eǰX(((fb/cS3qG8UT9|foXt lvT*_VǓ_xug*444`ܗP\Rզ'c l\2|6o݆-ι@3·&|x=k"58xw\2b80k}݆{JGHI8vpĽ]V,[wQ]]spbt7 ^͆˖oåhDNv7t֟ח s: 6 :aμG+-w_;= 7^F#* lܴ}`ޜgQ\Rh4x/;֞ȭwΊõ^a;, ::j z}e/ENwf`/YA46,KFp3G%[MSɗs'ƠT(Pi03゛Zl)-y ? Z-*+[ģP(jE9VlMZslEQDN ޥ@v{9v>m|~ifB@LL|!LӡZOп ;LxKIN$I:e2y!L>GdDV|kRz*RVVWy,-%7}L$sbN: YMmmI[ FoyG]@b׹@cSV<-WV}[ӧ[Պ򊖵Vi9qs|P*hPN5',:w &I磲Ҁ}L(**rp!aUrTCn5eDDWrƍW^q9+DjbK/;,ƌ0lWT<ёt/C.נ]tz좧+Wi2z|b^oq3P^^m_p{%Bv1wcu8UT,!jO& +Wi\JuDL|[{j]}jh0}":.'y*HyΥ QGėvM~G<_sjʇä{r)2ŗ>†?Ās_DRR"6[V5)vėv/u-⩼7mQZBRgDDYOٕ֌k2DDDD1]c~uA^ 2DDDD.7JQ"""" L~(d0%"""䗈B_"vP($?23fܤP䗈&,L[o 3g1fܝ4ܮD!=-f$ f#NMIAIi)hۉZR قGvݭ***pII(++Wbb**􈊊B]uuutUhhhhWo1yk}b6bѹsN.CIi14'"uR@AqL&yyff"q$/E?bcc'Oh4ʯo߱5A'#= 'O ss`pXl6_{;N9+ :(*.\RÏl@=+g' Qq7`(((DUujk]O !Dt᫮]6f(?aa6tĬgo@TT$_6MO<(~eV~'g"/?K]97Y"&:f3r6jj_ Ĝggpqk ^w_;;A๧BQq1qaSμ e6l+=7l؄YW zt?F444?a3Qg2f!S'̙k ^7~K/шnxk2߰Q~%oox~޵ Guu wEq ףdBrJ2z=~dl6_;NƂ!J`@YXZl޲}s|+g?'΋S&gHIN!q|-L䗈XUV㥹㓍iVͷ/j(X޻4p~'n۱ǎX7.zqlڼ _=wN7@P`aŪXZ>Jw\S&u:J3Om:SF׮]0`ZѻWOV~FbW~j&},{O^&f=1>݁Vn&<;IL{2VänA1|8},}$`}@$L2<M}#2"Wv/zDRR&= $A>{]Ͼwsn*qg_.Z;vbqͻǬgGVV&/]&'& aaaƠQ[WXm~oܜlU#YHO`İ!1t .+C߾})HOKlԥ}_q]%IMIArR6o9;SϿCB) Lu5k$IBJJ2:geᓍ囶lCLL z!/~ ӻ63~|9sUB$ ٻ`Z] d3 K:V5Nvg'S8& Bw iQ%lELF^|EZdPgr.IP*K_7?NC0~`Ͼ۫{\@sw畳@ oD0%ѣ0I鰡Cum6JsB'RO?݉瞞[!#= _}- `nE:VN}厾eZ6}/_aS 1 FX **Eph1(-=;**$'H3@})+/?.ef/߇W^ ׹ y^9 tr雷}DM8쁈"%99PCPհlKF GVVޢH: sK@}}=:_~5qH:E^!?$i=v qO"+.wJJJQx8Ə#ySb}M 1KDAsELt4LzT"6lڂ @EP[Wضo-3Q#!*E]&S$Iؾc'tMe}O֠͜%(..$IU<,5 $ޟ5.w$IW^ųO?k Ic\nz_/0gKxzLl1,+ 0˘Ll\v;Ncμ.W~7,_6 * /p[ ۗ$s;Ssq?}Ϲy՚qշoggðy6x=k"58xw\2b80k}݆{JGHax0?woAUAleΌk)PSSR_ a0[(U"Lztwປn7Mm666*&_uNR@rbΌmdŲX-/jly3@&~gP(jr_3o禿չoMS3&"bu:T$ :5lP(t:Gf5C݀Pw(a7KDA#I˄ {oֶ$i(.)`  [\8I $&> 4O1 j;Oߙv++^=_w :8)Jh4Qm6[߬VK =ϓ.Ӆ/qcoǕW\ h4QZ(̘> Æ AyE8p"aD 8:ŢdByyg.P^Qq>rB|kCLt4Nˏam,!"""PR\Kq: ii0[(-= FII)jV Q V99vB|kc0}"jv/u֩S'"!!kqHKKERbU?(01DDzT*,K8R`4")m⯼rXggFFFBp x[7,, @R9汝uj5bbb&(B *2k} k@Dt* dd3&" Q*  AP&ÜATT0DFFĉHJ: Ǐh4W",3"##QTTh4 Evr{׺{h@.fs#4 JJJqĉm bATT8R@bB`7!Lq}nCբ{7AT ]Z-Frrrs łJqDN$ HJL lj% /~5='7'NBi8^={"#=-gݨ({7$IBtt4鍓NL;IDATvqiѳGOTV}e%+eAAja4ѵk*:b@.]Hڂ$IHJL'9os e)^~abbNy~z}}=An]&`X,t:t:466"&&E۔831Sn4VlnDLښ(hZlVU*!<<Oo/h}mm-f baaZQWWf{EZjj=zN]֯r3SuNۦ$9k+[]tF\l,k`XT*j $ a0;m3>z]l8]VsF3AY8y }N4~HEOuldXX8f3t:ˮ_:NiR]Sc,acNNrɯZD͆:( 4441JE5Dnrr P.bcሣ&SRSS3=- &* g_KOFiu.VAkX`noУG*n~?|96t(V+J% Т@G $IP(8 uu& 46cH漼|tNfW)22!El\,Q\RI DDDD\P7n* yHEQBb8@d(<~*pW*7{n٠V1h|Ï.xSRjʕ$DQtBQ .GZ]P,$Ir`6 n[1hhh_ONNB]]]Sf8a"""".bNh(*aK8찈.jL~{cp <#"""tNZ|\1Q; j3""""䗈B_"""" L~(d0%"""䗈B_"""" L~(d0%"""䗈B_"""" L~(dtZ$I8yT{n99())Emmmn:vQ)"9) 55ퟀ67jvchl6V FQ^AVZh(vT*4."11P*rXVm բoIDDDDG{w^0VjBBAa!`ق}C$ bATT8R'OsΰZC] {B㨬 x=ztGcCDQnǁ+ɞIDDDDGH~ <, D.]TWWCTbAAUU 2*IiѳGOTVľ}hnmdS(=}ЫgOdPnϟmQtWbFuu5fA =$IU03oII$mFDD <<:؈h&OI~-N$8OWZnX :m4NBݦcLN]^:(M"""" Jn>-|:plο !rE$( yW|wA&&LDDDD"""" L~(d0%"""䗈B_"""" L~(d v DDDDDBܽgoc  Ŏ(d0%"""䗈B_"""" L~(d0%"""䗈B_"""" L~(d0%"""Q/(ߦ(+={",, E(𻍧ulGcD.#=i G}}=N*©7߈Z_P[.HJJ(#kM.~7::o*& yĻoaCNQQ1jkW\~p٥.[FԞJ%\5JlvTEss]tAΝ|aaaT t?v 22|{DDDeJZ| xGg>~;L&-[aX i$I()-Xxl^_ InZ,3-J=C`0Ėh45X,{"2t`dfcu(<~pIBPKGjTg$ 6 aaaHJJDcwo8u3<\}H4ͨq.M֭߀. ճvZ>bP$&&{nF[nݺv;n.U" _aBnݰ{^&:-""PԮc~:uBddkj' h[ӻ؉M>`֓㽕`/sD^g?㡿NGYyy:Ip.sw$>6ldjk[UUh JBFXHv (T*T-ka0wԮɯZԛݾnikYHO`.+C߾}\[n=_:gMfsݻop9|PNETd$ztυb-۠T*p"CDD5tMH6LLLo}  V I0+\ٻ犊ẄUo25=31_*2`'];ɓM?,5Q FAQQq@]L5ő|-nvBLr*Sv%I򹬲 `Ũl6э5ͨ@\vQQQnݺibc'N[B) 4 Ʌ޷J222p#,i7LZFPuP hZˋXjP(pww'))ꀢʷא#,]̞E`@l߱?Yftr7jȔIQ(*,B(S43Mgg^~Ǝ~JEF ,e "~y}8ڴnINNwcb3w>.]ݽCӦM͍/׬aٙLipb3gCbb"{gkȝP777ZipϳyoCD\\3fWt!#3'GG.Cw jق2{s^77Wz=II4hNNܺy >>ݴ-Z y̍Ŕ+ L͛3fkiӨaC&88Bvc=P(3j$=w#-=KՆ1HINfڌ\O|}}lʖ)(C !!:>q]Z2?|RLk=0oM&**ZX^4_J/̬,Z-_>8::p=ƥVTRl4B7~tysfQD t7'MFF:q( ygnKcav7n` >-JӻO""#-:DDFr!}+WqAȱ^ |} f;y)zժU>΂wr;NqqqTX//O_A3eҥ[ѽ+.zZ=2n޼Ejr vKݻG FC]jY0.cFdxktޙ=ԴB$oڷw3|PΙMjʪ/VImxmXZfܘQb^MtDvmL4ڵee:|=Q*|Rzt5kAS$bR{6գKdfeQˋ RҌn?~,|w]qqv{{(Utؑ~_"**MMճ^|wcЯ/ΡwуhF:^F,oN(UTO;K1jj7oƋ01\v __bbb @RKQ(,|w_Ă޷i\||Nc7yA̚3 6s7nk\EmرsJmƛ:}&b%W\a}mXj0yT^f5~trڌY|^4۷ҫgʖ)C*9Txi|}7jXM$11 O?MfF&Qԫ[TX埭$;;VK\\Uck׮ _[?evl׫sqn޼@إK$$$Pt)۵m')[,O/ϯQk׶ UV%˾z=eʔ\ܛ_ANN$%%Qߠ홳?z޺}3?|}fEDF))ؼ"~~Dݘw+}||rnkR_~ %y0x$%%MddޞBJv:م$ܾmXZm 5,Œnʫ6t۷b۶| }}}~|} x:V~@RRm;tǛa EGGϗ.P*JZZ/~c/ؾsuf{O?kۛ/,}ߨmW xɨjn޼\y Zjɨ#&**rAAqԮU˪rsۇ9ִA)l (;~UzRɛ޲'ǝpF}PO?+6_􎋋ϏW~~~DF{Xe<>>U_3ʔJ%Oc7FZW<==Łwt:*V@֭̏c)?2ނy2/W-T/..'!1u.\ iw zct˖=vu㽅79yhi{5\'k.簠|}Lߒmꚜ-:uU_ iղUsrrbά:;w &_ 4Wni0TV |re˖zj\ _͵k~ЛTxi%qrrƍ},o.)9R/8:8Щc*%nsBd˃qw;ZL RW_Oא1؟7oՕ{w(Jzaq=퍇Gvxx8.~-m~N>CʕhҸ̽< jhZӧо%rPF *W6l28{~;;QQQxzz]GK;ԫ{ݻY5w<9tAgml+II:;vGGGH:_%JйsG).KsIeJɀ,Z0WWRSRQ*j'O`Ә5sCg]HLy{'Mdܣ { &=9fгgwrZ?;%4{dwri}A&ObϮ$)o[}˫%Wɓعm k4|n׬!33[2l|}~/^=}1uLZ-}7R*zl5^1eJ$$&Vcn?oa;1m w􃏖snٻo?5kڵ 6a"͂2|P"#䇳?ri^:Z-3ӵk %mʳgnysg>*Vx_d]\V,`\oMW(UJ6}֭;2NJJ⫯O&>>l3 Ы'o1ww .Tnn0TJjZ}$^iJebF* UIND}|IHH4y>J>pwאh>wSmyrh]lOP]$w=LKoJƮ{-~J%%JxjN.$$$-WT(EJJAxzzHffhn{T*xzzo;5AΡEZ˓8{K~VΝ҅WFӓ4RySۇ%Em$Ѹv E+_:\11F_ LU r=,KNNN3ֿONNNƗE` 9絋{8̭1''{R<92:?ְf\EȽcĵKLLX*ۇ%Emyr~@!cͦS^oPZฺbRL&E!Ӹ)/!!E!} !!ʗ+G' ߼ݲyS~Zjɶ5 ǝRd헫f=ꌑoި[8PT@խcS8&5/Dؑ'3oM5ֳ5ZZV`/kd#RX#ƿǑdG(R@>f}TTk4f8;;:Ic1=gR}?@]ҭժVur|Ug] ~{ҽ]⃏XF6_ϟYrt ƫWˎ9k<:w7'1)%\2]{胃q_xx8f΢SH7:u醯/ڶ8ׯ`E s >kTp[(\{ZCSSj>w xu+8;ӱStW}cn˟1{OoWG 端ӭGoZϬSH7w a1mlv3.zO$d6zK0)l>/e*`&͛_O`thx?(h.#ڎءcvl߹^; A$%% )cbk1?K'ˎ i)csj5*-K?l:..oo{djY[3hnZua7ݳǽk4zwvTQ,|TcOTi4^ݓZf@n`jӪRFvѼy3ڴne@\F{%;y9}P1u+5eHNNtNCXgY1ϜdK0qܡJJڵkQR%8u }^ WQo\m[?p_EZ옛sfѮmkk,X2k2vK`w}'^\'Oq1۷l&6.(BX+lNzZ{rmo-h.e:b8u%))Νf,ȞQ5jCظ[0_ kÖ2?Meespp⭓*jFh [3 zzzb򂰭63ohid*c<<<4x 52>TR&kh4rZ}eΣ̎₫k̈2ScJO"o/m{@7gAK!&).Z~zE!}t"BmE !y䔗B".$! (B!BB".$! (B!BB".$! (B!BB".$! (B!BB".$! (B!BB".$! Z~{?Q%&&q)+ (A az(B{~4jԘSNRpU$<~pQC(*Vx tG=0v-åݣ ! [Ks!v!E!]H@BaPB؅B. p{Q< vڶݪ]'t*Dq$䑐(lic*Plit:HIIΝpw6-2exGr՗\FPٲTZncNɒ,d }՞6Q$''[דss'G=Q%[8-BU5ҫG7۲:5Nff&Wjz7l۱drhH@y8880d ڵn @^5YYY6y{,ʔ)͊es懳> ;;[?RIFF~j&FJJq}͍Ttv K+8?ٙtZ|QVAkVIKKryurr$33`~h]cT,=u5Pg{P(8::lVqppЯgݻrY%--4eђ2x˕cx U[n\P?+o>aa<,jsIx} Gå?.3$%%ѶM+ԫ5k<3? 羋4IQ IDATV7UZ- \~m۴F8t>ZBuym*5JVÅ߫gwjլs͙9_m;_~嵱)Q Z}̾ mӊƤ,l &6'G'rrrX&SG e_ %K8xΝpsssmL?gggrt9̚3axY0#_BՕm;v5x޽گ֙eiWDEG3f=j͙IJfg¬wns_zvJ&**3!"2ѯypSխ ag+9z\f>ޔ *_PU:L. CBF٧?YYY!RIV-8t\7k aʛo0o{fΦiF1JZxƍx{{1),x} 38a<% JDV1f,V}^}BAp}'GDDDҿ e?ʟWdr c UZZ:iiVlaP0 ouOO?oNxgݷ9/_8pM-8uJ*MP ~;;їGDp t:HLJ&,JBq㯿_Ս؉?w_FF:|lt:hԠ!Q$&&S\y22vZFקޛVƗ_ ͛<|iӼǖصG̙RT"gCX%׭k5ݲ}G:$&k9zt:sGFE.$$$kt,OuA+^щҥKsn ~~jssfi 55Դt ) *z;xIއK4a<(lJrR2HIIa aǛҢy3s^;6&֠~v0x{ *:ڠ5$ 48㍷w ƌ.**d3_S( '_~%JuתeX&&߲/ǛW 5oBy\\oVKbb4hۦ?quuE4h也3qkU*nݾwS|iǃʝkb/ӥ@nY"-2*:{Y]?!>~ W!.>o//5ˋO ""RœBV/$||-W PTL9@koL\mw @ƍLַu~ƍgٽ+͛0ID[呐S^,V~% W"UeЀ@V)U*Ъ?++Wzxyy)ԙ3PTVSkݺu#7 FkaBˋxOi( <==fgOݘm %HMM3{ɣѸV;` ;;ݝ,u+V 6.HR4x<=ILJ"''dF /tj3?,Iqr" eddQgNG\\m-W>$rccmm$'[w__III+}_GaZd3Bzr 塐@!.y= PB؅Avx=HH@BaPYܣ!E!]m3 !7 (ArR"~DGBrUagM@QZBX/11?NCWo?$ @_B<` B!{JBbOBB".$! (B!BB".lmXEį G!æ rAH 6_n.IgwנAΞ}2r !Ŀ]Ɂ3)9y;W?rpLB>>4hؐӧOӹsfcY'Fh4$''[OA.Rprr"55<jDvv6Ze;vcǎyB/L8?zxi`.5 @K~ڭ3gbq>sSP(8MN={'P;∋?t|8xȇ-FRYk4wB%>}.,T{ ri4hP1zf9r0AAAP PvPV3bHKpӦxMN5r888JRܩ3ԯWӧѾ}{uNא.<߼DǷnb׮ue޽4 nJ-xvmڵoo-MB<S>PyoB`N\^=4 'ODղgnzylS.]ضm+7o ,"s.\p>yw|iV۰}6"""8v(ׯ_4hm 11_ϝ|6B<P2cL̞mu<{ӓ899jyѢBy } bs\@gn2Fԉ4_ttl)/k/O  *oL@XXچ4 w`!D_f-۴ahsrP9S榿`^PLl %K4xd@omewKwec𜇧99:eEYB<maaa6ΝO?qm-O{oݺE P޻fKMsNBvTXVZw^}_իW#7 ԭWժc 銷7k?GժۘR !G(Wlڴ[|1c(]4]+?cdddpq]j#Ge˖$&&y [~0{ݻ̎qԮB˟ɾ{VEYB<4}NysT-F-///6x `j5T舫+E/_!)?qg8+}SyyIqя-L}q粳M(yffɛl%DQZD`K!d>$%&2|0_fNɒ%f<`gG_6*S(<̂ 9r!K!DQJ9x0۶mgP^ᅠHƌuPgn@lLlaÇs v|Crj VtiFy.K!DO̯ [+3Ev<}^MLL JbPݴ[njǥK&qɲcGx дi0>[1zJ-bܽ{תuB'PR8"<R?8|2/_rSϘ9R(=1a /G'Bb (E5nxvƵWAѠT(f͞CPrrtFC2ep`9rTgK.CFFIIIl\BҨqc HmHLLUtժUvڄt JVʺm~ K,ͅ/ !ēX777222HOO $$OOO/r4iڔ5WӾ][F%5s&֯חT*.\ gr=E+wy8~7npaҰQc9b7c̘rMDVP222xyKxyyMrrUj>j-!7)֧B<<PB؅!v!E!]H@BaPB؅!v!E!]H@BaPB؅!v!E!]P(Xb%ӦORq&8;;- rV/N:Tn׋=<[1zJ-bG^Q<1`VDx8J4 qqq (Eue._ 3f`+]a /G'Bb (E5nxvƵWAѠT(f͞CPrrtFC2ep`9rTgK.CFFIIIl\BҨqc HmHLLUtժUvڄt JVʺm~ K,ͅ/ !ēX777222HOO $$OOO/r4iڔ5WӾ][F%5s&֯חT*.\ gr=E+wy8~7npaҰQc9b7c̘rMDVP222xyKxyyMrrUj>j-!7)֧B<<PB؅!v!E!]H@Ba.WDF@:~٪.^sWZ ZrǘGR|<,:D- Wŀ~gB<Ɗ@2R2.)ŀsNYLx \=n^8QjZm7"B<}@ԤbgřF%as? plҞԄBe{+k8z*DSn䟿qJ;".x+''W4h`]ń#Ć-IMÿ,// kHP6&n @6MMO'=9w2fWC!4OD@9{ukȨt6 w .%Ơ-c4ݿ.rvO!DOD@MNZh\=P(zXBQTyjuIO+_aG<*!(Eyw3H}p֔r|=Cno%BXn_eت d%sIn)W5Nם/ !ĿM(ٙlgworYd&Ynqoe?l*_-#B]Ms;4_ axIPJڿ.GKZ !xk(B! (B!BB".$!bwzB$G(B!BB".$!PlI%x#!va׀Ҹqc7nl.QnggFe\\~uԱK_*MУGO֫g>%{΍1 zӣGO5nRiI{{{B.!{x9;ТEKuN m0L<ٮAɉkhѲNNNvprv~T*_}cQr%&OŠ|knqwwg L:u2e[qppBŊ޳6mҩs'vE@@TzuvW+W~7m8~Ӽp!&O潅 9}truu%##N.::AjJ Zgggt:j YYYFR8::j|Y]8 iii&)33h;:uRtiZlVёNSbE\bM2Z-F5 &ۛNrrkGRFRbrA]N ''gӍύBÃDQ*U&$%%ӏ?;$8bܸql{.\yyu(fΘ7?n,.\J*lٺϖ/'99l[!qvTrRremA} u 8f͚q!vű' ۳w/dڽu~7ٻ]~:̡Çٶ}UV5nzݷǎ -z'NrVX @FF)))ШQcݣ/߽k͛?@zz>}, m=s)yAe̙TwnA F>С7mBW GGGc}1r7e5,dahܔѦm[9۷o3q4oLfѩSg}AA(]fMiҸof+K?a⏨[964jԘݺ,)]Ӧ>h1YpSڵmC۶ܹKyv~ ld|:fLN\\\*.]BصsMԨQ:oȑחM+L>5jk.u+((gkbϞ1edZ<ߜWGrH IDATё6mҡC{6i̝;wXf-ΟGLxu&Oy 5hЀ;Ҥq#v~/wttdy3ڵ%<ƏݝfM nڄLxc-jիɓ'pssÃ;ww@.|`ޱcG~gmn+POΟ={пʔ)KŊYa}>tpN:ի)SFߵWlPw& /WjѽDVKȮEբh煶gL6CZfʕ,YX/^˖-[.uΟG^:upIr9QQQ\~*4K]|95V F[sxϙ{h6lrqq!55wEJlB>~q常^&EvtBVkEOf?F;^sɉxӑ!pqq!''|kkkjuT*Q$%%=sF[{i!?HxsRX>4a VK\\c1k4Qb[G(I)vfffZdi %@@ (U" @ ,0(@  "" @ ,0(@  "" @ ,0(@ 㐥޼\efLRiG߾}YliÖx 3s%~hy ̛&-RiGFprvիUO4iN*U^'!!#E~Y&dRn߹͌ӍkmmMfpvvɓ-1k&66'֩*U"%5S'OT ^ q)Z;ͱ-OߏdPߒ˨^bxzzbkzҷo_׫ϲe=f^JBwѪukwhϮ]!xzzSN߰ \ZXt:FMZߠA*vlڴҰlٺM:pe* ƍϦ[x&}\5k:muw#|^|}}S@R*g( {{{sT*.<rrrΖ򲵵5z\r Tȃ:DA|7w.Ǐ7\|大Y'JEZZ< bn {J"##ШZ"ɰUi L#)))ΖΙ/k9b8 A,Y4FA̙33g1dP\Jשsg;-&,|'NdاҧO:̡Cٲuޑ "hBBJ|vIaA;¼9b# 8_~YgC>}#Fd턄8h^޽?$haDDw`Mt]/F@@ou·a߾ݻԫW6;,SгgO4hȁ9p ;vRZ5կOXx8DEٴi3{r4cǍC&Affd L&ܨQcvCCBhmi}}}ȑ@Y,o<[; ߣlq.={(_<*T0Y态9B@s?~:@.WmP&4f( 64+^Z hԸ1nFvv6...K/\{MXl̝;wPt3lի/Fxx84\κ_~GXd1͛CϞ=ɟX`!70d'LJMp o$nh UV^zp+k+zУ{7n޼IڵٰqAAҴiS =?۷Q&~]!t.[6oB Z#F 7Z7ZnM۶~d2VYK@\xa߳yflذ!ڵ#331o:wD`ccÌ3\z-[>,Y[mҟصkQk׎3gptt$=)<:XYY2֪.}/ ?ƞxy{{ARR>ʡU-n޼ ŋIJJ|ҡcGEKtБK0zʕ+ǝ;wCHHH0ZǺڶu YYY}>\Ox43(<1#3ȁg1VVdf7#/_Se^r+WYlՊ:Ξ'u j ֭|;Æ1Al‚eȑtԙxT*|nZ-IIIu&U|||ǎ!qws~t^^12(^^ѱC{~'칳@֭-ZKWp 1EPX||siVqww/RJX|ӧkk뼺E߾}֖޽?o,m\\gNGP\9JiSg+dN;L&9u &ˬZ*gRjGGj֬)]ѭk7Ξ=k2@]N޿σR5Cy ,Z$ +9r\~ΩS9|Pٿo+UfÆrPq9۷6u ˖/'))  bŊf+ ˗/spA֭[K``)))3kL.][֌խ$hZBvg/ZF/>7#8IZj*J%cF.ׯ?^^zW,_μysYz5urX|YiMO?/" 7vvv,_S EFDl9s۷gY=`СR26}Æ˺uFugT2pw'1)WΜ>ͤIL#"nԯ ܁V̷zm3:&5lذDwv.CVVf!3%K*Ņ422߯)BBB|i ''bion%ZQjGGlILL,spttDѐ^촮n$c4^q-;;%fP(prr2[T* wyOjUJ F-UVQcZmr;bn(Ϣh4_zzz @_RP@" @ ,0(@  "" @ . 2" @ ,0(@  ""P>˕^f3|^[nv椦=jժ+ !G5r3+rԮ*i?vЇկ/W;:@&Q~}ʗ+OhN8ckkk5k3'O\6кMztfPJR:Ύe0O4iNRiGFprvի&ϩ5o #.e\,tzZH7hPlll?Ur42NGđ#/Aw0x}E 0t0Zlɶm[QT{wاruIGA̙33g1dP<׮3rp^yYx KZCٸiݺw׻믿y4]! Zx{{gC #޽{ѣ[MiVSi߾Afݗ]tڵk\p+V#-:vq&gbPN&6&'G'{wx@<^dwss3>>ά \Vɓ%cjJEsOQ$}%}v:uD`v:wb暬@\cl5\HhP(<>a7;w[kϢjר?t^˗׋V{t+ EPP^ZJ] D۶mCYu IDATp}^~,mۡr)))h4*Vh4zUŌ=T۷3v8""R8r0 q"sS*j=>>W77{FHG.3lP :+@^emU۷ocmm777GZo0zy-w']v2zkۖ^̪2UMZ04I(_<gn\;Ћ[А ]XH/ߙuuVqrrkzJ%~7Ik2?YrŀXfMt:7nܠ/|VkRT\e˖3/:TT-DFDVdPQHhwBʕ*U2+cǢY&uu~mvW^?:Z-m=r?-|Y"..'3r( z. 88ʕ+ӨqcI^̡C8Kn޼?mVJ͚5N+i '+3]xzK4j-ZNdd$,[ϜaŊRNj!v d2̩S Ͷlll&;r*4jԸd4i7;::2dPɷ}bee-{(UT+V2o8}T0yRf(|<`;߷ʕ*aFP98{ 4۷6u ˖/'))  bŊFӍ19bT2fh0@JwyzΙ3gؾ}{E\ OO+W!)1M7HOd vUP#Gr4(ΟgԩS'N"ˉb_xzy)XyX6iVmos>ZYcB iiiddcr9eʸ_,kk (j5Hב1,NGqdTPխ$8;;av=cee3 ŮRiDn `,{!F)u.:ILG,jJ ģhVK||~c0#/񎲧E_V2i]1FffY/>|D`H)n#YQP@b" @ ,B .' F,@ (w8mQ:Rvzd6a$]v&1s>̒Xb@  PMXCeE A@ XaP@`AEE A@ XaP@`AE(m wb%˾{i]@ J?6({͟ؽA _4@ x1)ڻj @ٽؔ{X'% šDk(}fc...4ڷaX[|bZ/DvmM?1<= ߽ ꛌR_>lL2nL-k99Ib}&bLФɛfG/*QH% oDӸ9Ꭽ-^ԯWdq+w/Ŝ2WJPu8QǎR$77P‡d2/fYT>ޭ+G|ۓCvN [f>ݐ|ˏた.Ύ̬,fe#;'Ǡshr/'''Gz+IA.cooOZ3%,Rd*l؀NGvNAW5rL(J>|h0d2KFP`ogGjdT* ERw,:d0N)S'j#cyؠP 4W2XEʦRxh@F6,ݫ'+W3&};?t7ܺA9Iau_m[ؾe3!;ya)Ǜ˖l"Cw2rELxN6mНx7,jle˦ma)G>k~;m7on~ܟztcgvvd8;;P^D9(Wˬe-6#p+ڷ#8pY{U+m&rmӣ1??۶ldo 晕:Zw;Vlt}zM~e_+{劬u-۷3h][c2M0X0;BvЦuKj5ncdJ%ӦLfwvmcptt46[ؼW=xyy Ğ2Β~׳GwMɦҴɛٽU+ eg6K*иo¦3~msV-Yt1nn]xxxlt>;uj IaE?msqqAP0i8Bvu q7q)ݺm7{~k҄q 8ukVyoܷ}zPjf(nnnxxxp) kܘLf~3cTBά~/>w@O|?`i:5kqttd\r={ +WM֭5r8VoL.I~OZ5ٲuuf)8z4 gg' i͈Q_0zx^*Ḱ}r9K{5kg|///ldd2fLÇYbpagI=tC_LSa}oז<SLJ5k0n$6y.GOz0k4 _y4EboostkL&+++F|:y߱N]{sr>lvvR~@RѮC'r5fϚC?ao ƚ~mڣ ПӦңWo4 3}͹stgr4/'M1GߝR;KvNeʒJ C{^ʒE?qu2VVVt> ;Ԩ^U+ƃB, J@RRb6m&7od}t:fdMvHבGQ\9ʗ++TTT w77.4(ȵkjxyyJGܺ}GHJJf( ݻ?qs/ 4 999={oۛʕ+ob@hn7oҹSGjתN#:: C~~m8uĤ$ڴnɓprtrJy* o|Ta͚u<|-[^O3o7ko7I.6lҋߦuK""R|y^XgѨڱCrzʕᥗ*E5Yj :FUifc*v<U\:Mp~ )))TTlbbbZ7}%? w~"++xyܼuѪe  w ~ NN ڴ"4,LJwUDD׺n߾"99ou)53pBy888Tk5CJflybc݋"uBB^F%99%W?xH =K=$ݜAn̜1/ />U&''y~mXz-m?y3d7w7̄N>\&7[sdw޵ 111uBBFvuucltJ7r~gff 999dA.Knzwpsq?,t WW>lt~} (]j8xu9} s-A\Pr_RcPv:mZբ~C$$ZdDr9cN(r1ё=zR޶WV"ͭhyÝ'8옒 888`cc#-%htodt}=~~۶68vҦD.?,rnK$\]\Q^'ĊU nZ1{;;OH 77JYNGLlr;gW}Aqs-/!1{ >X̣v)HbR|;s|%Æ2#>Aou6_a܄IxyyI`KDPNPj\^Gnn'wmg{ u8Tƍ͛5,-NT*ޞG;Pr9]~^4Y/<--'S#\" ד}oRnC`s.wޣGn@s'gI=~X"7u;v%4,Lٻr!=);w-onKޭiOV2ɿW@@On߾͛u6W\O%`LG}?HD$܏ʊڵjyUw,G""i߮䆲NIDQ*Wg\=˖^(<䐝wXʊ>$qMQ\9i  i@͟Oxڶf$/\fo5ef4Rjf(ʊ0nhRSScwع+twcLr"[=BBM9~LKMZZ:|5eC}̶p۷nB! z[ ^_ENl |/0m޲ӦЦuK֬a%_NNаp6𯛋) y)Li̘6n]Gw/5kT7~cI뗟!R<3?ԧnCV0>@Ov>+rqpp?rssIMMKcySbccKrrrxEc0[T6899N$owK oVuşd߽d-vےs4M7)\ZY#hZLG,L-Pe "1ƌEQ/3aH9=g) ;'^V[hSMQ16(KG:h]+],\|iXN؞Ĥ$r*,,N]^7jtys.o (0/ښ2.ewJNN%JL%3(@ '5A6,aP@`AEE A@ XaP@`AEE T}mX _A.Q+fl('-=s\z4-VV oQD$%%cǣi_3o πWkVݻޏ1YPe=)͹}Baƍ%6tᎻQQGMyR cϛݙ8B@V=:J['~O񋍍Q'D "J-&7_W0(Ea ] "< DOp" @ ,xE x& S"!f(F3 ,C2h׆/WCptO / @?55j&:;;S^=j59}4F oݪZbRg+'Aik/mտA.o>օwiάo#>!^T82 "0^LP(P,S1Aǰedfg2fXrss޽;wԩS=NǢŋoJ#ɘ:e gF./H;6~#=ϴ0yaiv1+8t$C# Yj9vg/kXr6azfm݈o*ҵo*l۴HYz~Н7fVXJʕ([փ˗l߲X`Vݞ$bak IqcǙ4&5WXvv6]L5 ;e2ydZEd/9?|X\zq9͜ȨտyK&sssΫ9x{MXY)pkkkZ6شu+Æ 6;Ɔ<w-u>5~!;g!tٛL4!||y۟# @Lx>CRbE{J~{RRR0~<ԍaooOJrdkFÐ!C^:}9%iѡ?tɤϞgڌYL4ԑkʯǎ %5._!%5F >)ر+tpI^;ՎT|"]Br>xD[YϤ֓6,$A ˗-eOq:Jx&~9Iow)0gJUVz9sƍ˱ҽ=2*_NdڌY~<ժr[2~qrtb<7q4J(?7WBƈe nxz}Re4y"::YaP[Xt)>>ElbӧOӲeKoؠwՕW_}KH׿?k׬9hIDATχ_,RcƠ:4,wSz9=2> I0y}5x^2`.nnm;6SXV[rqq)2nRR2W\eU<˖5˜Pŋnc׶yb֮]KLLl kV~Sˋ9ss)nbb"Ɍ7SN}j,Ðh:>o [=sYY7W~+\~[[Dk@˪SE=p4P0(3 d|Whr5%~}Nđ#DFDȍ7 ꕫ,XoL1o^ FoJ7z?K1oj5M4&,|_oƨ{\\MU[s.ybclٶ_ֲ3p+C?Tr-ař3u8_QllmmP$$$绷jGJQge˖?qҬz}[G捛Od2HNN6K.BY2ѐ=Fmb E x&XdeeeG)֡NcWhBt:IIIfh4'$@jj*mm456xF#(sdb~z{{)1U'5&6$M2%Zme"5/)v+ݭXZ<8$%5婿* P(bIqVLTbpvԑиH/e;Yq='JIDV!ڐDÉύ?$)ފS"v{HsIlsuX;MB`ނE ~*gˁ T"7HKP(hjl !1x='&-BWg==#3nʎPpI " ~|@ p~d5¯>_{]U,j1M$''Pk4x=\.6.k\bpWRPP@ff&fسgo6wނE45>vi .XuuuT裏裏F/sx-!1V̩tfP<oZ,4@(#|D4CCϬ _+ LF!7FlV+---8}xj5qL&srY՝sn~"RSSY~=K.^x:::0tR֮]Kii)6m=66s9>>sӎUWWx|ౡ,Ys= 4p95f32£!Q5 $$GiT*TKP =cycʲXFf:V>q\.. RIVv6\BcX]S~aa!7n䥗^uuuձ{ny׹ٽ{/f A(OBBgIFaYGA.BBLIR8ATFF&Q@ @݉X8Z \'>+Wdʕ>|86~7|'|'u}!rB}}}$$$ӎv32BJQwSB)B=A@)I$%%Kr^ZU(hZz=Z6bbB-Sp;q:~`0% H&8Ka|3gq)x<T悹R^fT6l+"^I{{;k֬grJ} HK[[+K:Yz m3CRHrs1qu5]̹kXVT*Vl(dľ$H %%N dɅF@ gNc֬Y̚5+wM2ϩv;mFfڵ)_]vnݺ)%Df Me ijleu@ @kK cVC H@SG֦&=\^̘DRNTZ|#ΔxnC5j0OMCU8or<__b7>7||KLp$ItuuٱsSF%h;Y ,Z~mҥK:muVvc=63梨ߦDfrtuvb6N:;:ۣPGR_/P/,N!66^L&6-; jMU"{r^Zo`+RRLl')+3O?McccD} HLLs} ={6lH^ 7̷-#1) BAgg'%wT*yg9~ﻗ#GLzT6-^0Bjcw@ jd4PXXHiin0R{졨3;kurس+{~7~ .ntg< i( 's8A)++# .0*2( ·.~z$$i$dv"9TWWo>3we˖-za2s?mgM?k\w͓O>;{pEAk֬׿5W\+ٱE6n+/ju˯N+:ꏏ' 7 $?ﺋ6oēO<>@OOj¢"f?RG}wcrxa^[Xf񝔖O~r7]jeժٹs'[zC<{(7-F-O=5ju:ξqϓ$ ̩<:g__DU999L9G̨;lfw:okKM;|r y,\9^k9t}_d bbMOjCOVT\}Wih??nOOvW'OTbJ~r ."11&4V{AXx1k֬o1ti!TUU[oy"g)--?ط/Zp󱤧S{86^/zfsA4uvvK)E37n;ស/x>VOoc֭zqz=EK?\zj W\Q[˾妭fy3H d$*jX酡<^^64g $ uB°,8iNã.nܱoMee%HFFo&?.~?iiij/bbb~#?2oTWcΜ9 x?|G;vyy+++&寸ʢɄ|B.B~?tww3ٺpsq#^cF> 4X`$&+T:+!,T(IyϹ: )RAbbs6o4m$텳ֵk8z ̝;|>*ŋ3o,hBWƆxP(l8i%i53F|\o0+Iyymm-3m }5kb0$;ueG7o&))|R;eӟ,Άs\ƍdYb|h.d!mmmy5NO{)..砱3gQYYIjW5콽TVV"n NNJo} ӌN<1{Jq2 q?U8NXh_W {|dg_>ȟ{Jŕ1٫^x۶˗#!q饗[yNjb2,"jY=~|BSD& w^.]"<ӾoR|9}O=fRٸAJ%'O7ʻ{RQQl >4b\DiAicdee1+'zV+zJww7 HeG9F g aP4~x?_Bmm-\Pd_F!11n{ƞG{3Xss37+X!,G}d_p ]]SIKP^?66m_筷ޚ .b-[6~"]8l0ςS b[ C*!+!߿?Tix%YVBЩ<ψtn5YSm/gQfϞÁh4̞=cǎNv>q/_>*֩<{⦅Z%2FFԠDxnJx/ wi(뺥(ea芢4M:Ui!T0p4ip|>M-Z?G^DӴG!Bwp`0 EJ?ajfal6}>fy}>n{x@pR@ZEqiuݩiò,(aiieYijifʾTB!D]ptKe+bij0-,cYVZ* TE@4_[ !B!#!>-r\ *:@=j[9"P\\0}Q5MEuYw,B!(r8v4a=ZTTiiij˖-<%--M8q/+P68;RpHHPUU5a4Qm)B!`4MifBBBT׫x<%??_)..VJ_q# )ʑ+ {^U4C !B!j y^S^RTTtؑcQᖁbH躮꺮) !B!ͦfT_Wu=2 *бcGp(aH0 B!D QUU5 C5 C5MS1 Cq:jxx?8ZlU)DxxbYz@,K1 CUURcB!gi e)pT~n*ﺮ+a(i*i3MS!B!jH]i*Cq:a @ W#ZH0 B!D ,K90bЪP0P\\F :N$Y-X!Be( z(bR$(1;Zɗ@!Bc4ܕ&zUURrJgR* Jmpݕ9M!Ds.,/¢htNM|R^Ź?P!ݎa*Te'=fdmӆ$҃Y !bcci׮-;vYqQB3央Cn*>͛61rd СxwiP6mtܼW\ʕ+ s\OBC @,_=eѧO>S,lf rO-iBQiz 9PPTPп[O̯(כ_q1MP[c|1 8ǚXt wu khxkբE^޽Ӛ7o3X~=֯g-_xD}>ÆU5at֍e˖1tzID O<8C fҥ\rlܸ1ȥ=$BQ)6X;Y Biިڮ{b\/͛Ӯ]?ЩSÿ`z\q9W\~9?O{Iع.ùkfɬX3fT5!1q7w~wn*>xFmΝ;P`@!Dv=PԡנF²YVD8JN^\yƚ5kz,^脭YYYUT0HHH /7FТE ڵokAFF`2&~ F1(.SrlXd( X&p*_Ĭ _Ŏ;yÆee(ڴi˸{awywҝ.nۿxCCŲ,4McСOd=?4$#brr2;w䕗_^k%''R+[_~ |#.W'Lsά[5kAQGӼy3SOG7waY3_70Mn?X@gϢ[n+9p$2Xu4ƒoФIK\6z|!s>Ӧٿfrرc(D1Nnn BQ97 *prr2g;a^guTkЫgbbb sNzј y>',y,E_}لǻ{W{qe,Y>p~9s?cEǓ)߽΅ݩә,nguVߗBhېy,"== oVw:MS;e/^6mſXaԓOILL`ԏ~r>#"#">}*;v`yOFM !8ڷoϤ7$6!{o#\ƍQ#w5JL>4k֌/ҺU+6m̅^X&(((IoTB!j;v0d`r uUĉ[*iiiAO{5{-Ot>:4g؀cd6"!JgBj֭ĉ8qbeWw33PUzj[!B z@epz{;cnjFUK06lX؈pv"#"jB!BT;wž>لgүi޼ G>q@X2_̥MVekڴ)GY5Yl!B!N uر#?0f=`!,opsRR} &&?ۑϭAxx8vL,sܶm}e?ӥOB!bbbLP TUFFFx B!D]T !B!*F!B!JuQ 0 Cq݊[4$\{Wk$_!'&-B!BS !B7dYV@/]+kG!B!) QA~>'BzqByy.Bz:u .v1j:@0lݶ;Ҿ.g-.Bz#F  vQZ˲,Gem`C!j(koY`(@CʡKڧ(+y4jԈoڴ)~:>]'5%={9.fӦϯuC~{Vp!DѪukD7oߞ;vHibf'-B!*ŲW0U/{lUL,;*erzAt ݫ9ՆBբGŗ\LK/ XAo~zml۶N?tOvq{ –-kAqCR(1ɓ':wu7>@T !0EӴhZvgy=($Ո-hK'3S3 ;jE׎kn~I@M9r2t0y]n6M6U:nǃa,aYA:lߕ8Od,>}'bY`Æ5kVK|jb!RڵǦdpyd,yɳ+D\K16|^Z6Xz5_<i2}4.]wu¼|60a£j?;? 7[x۽zf,^//`رS!DuZn=ݺucٲe :|P'!CtR.R6nҞz !M'):f!Y-C;6TQ1|| ˎ)`tKA:]@7˿yktiFW`.bK~j2Ǫ glvbccyW0."ƍM7OBZ۸{tSC0jhnvB!*g*50ߤqkсN2b[FJB8{ hWhg. e ,>.GXXk֬xdeeVk߿dbW\ѣb۷og;L?wH\]d̀B L9`vEt.z7a 1n_z6f 7KH{#[n#BzVdʕ8. ߯=y͚7'55BNMIK*trHqq$'+2"By !jFnn.h֬޽{IOOrGԭ[7֭[wE ϫnŶ/^E٫̔i(\7}`)722CHη{w3겻HϩX0o$|L=YhQl6 +*t g jФ ae9PFF bb#+T!DiӺ5i<8x0e1uTRiժGtBQ! }]#g'$4]1Ucwn[پD'tThæ$y؜fGb;~w.;rmXpرc?o?e`9]8|Gv}t˅w\t )Av;g} 6ϕW׬Y͙gIAݧ߲n݆~Ѧm[ onݺѣGOZj !0UPWS퇷5 V4?7V2{v٩͛˘cIHH];|Y|:mЕHqꙖwŪC x}#I ,$uE7'x֑#yI[cPcE5@WX=bMz11=|à '''s{L~uVNȑ#O7o.ooqo޼|4hЀLs',[eYŢ Bij D? rV̡ץz+҇o2.yw ݔrܯKJdggWxWn СcGoFzz:111׏wN !D0I0 4{BJW, ^JաC{oGIƄ{w"q^.7'';[6#::\iөәf#</|-/>ӦNΝ_zzhZ[؆=cЃЃӠ;?^9\٧8+P~~>`_Ƥ׈ 8fU4iҘ֭ZѫgOܼ֯Sy B!D1BTQRR27 اiqd31 o=z߱gff*<0ZzOg.?曆dd,^әg0OQɅB%-BTђ%Ka@ڵm :3nؼe (t:q޽{ILcF aÆu+ҒKٲuCk߾=1 wF{ʜ`B7n̺uOIB&-BT7.#..wyUQ a֭s(njE󺐖Ftt4>JI?gȊ'y>;2p^s;f4>]"33@VVVswIZdu(sFk 5Ǯi%$JuPeeM6ϳ׭2+BX:nٌ31s&x<2xzd}'bY`Æ5kVK|jI0 b.,fY``xu @AӇGO@UB䓙3ϒW &&cNw>\|%tR&LT F!**>x7/г@ .WM+.穧IZZ6{=ͦqɥdbMav ~ s=8x`p!DuXn=cǎH{[9j?9E * BTȮ:q-:@/? ,|>/iKڿm A&MXk̞_nsGrRF7⥗^d„űhΝ=-[cӿ__ۇ"<< .cٲe j|>6Æq طo:uOg_pڵkGtt4O9T~OLiӦ=z i̙=~ N^z3wk,[-`dggӬY{Gn ֬^EZT~k9cǕI@biBQ!!d;epd @qq!{wm{D |g5w^ٲe?2麎vU<ǧh_%[Q5$&YfNRR{%==g] !]E4 ZERThޘt沣8P,MMz\x!Cwp=TL9^5|)^zenVYrgܹUFNBԜ6[c=΍cYSN%--VZ"tBQ!NJ]eWq#V V0 ӆ] \nv& ġᴝPhh(?π=l6N;4 Xj%Qٳfӷ_?."ϟ_|srIhڴJeB[_~iۖ!on[nѓZxA#-B!*Įh6}UMAvM L#oof@qW?￧~˫vv;M Xv 8דQn_-\!Ce\?JB2Xroo~$uA$uӨqJw0)LCO-Qo`OhW<$1( &lhɑcYh6P48a_ƚM%SFxPN΀[?:aB-[zy |(deegY .hذ!N?39 !joUfeY, `@i<M[P'ҹsgne8a''~䬘CѯK+!~LKW R-X:Q(X U5@5Q[dk$[JeggD+Ap8,*[! !d̀5nT@`ӦM4iPlU:(y)fyհ|jPMyԔjx,((N~qxj]v9/c#BNZDwRo d*rչ3,&bddf{ލ7wOZZ={w<2Q\.ÆÏTi֒y5}y ,#jyuОh,"7'}YIuС=999<sN$''v3O%%53?9bV4;6* \KxW<'oЪU+ٶm1!/j,؁ģ3ut-Zw'ULO>_tlٲ46l@XX^r gBL9zѣIHH 99(5kʤ7bZGnzN \r3kl/XX弣(,,<"V{Z%~;nL?NR2&Ǡa\:#-˓Gs{&EG[ %hT0 RSS] !8$hт7P9=6==[o#`r`l6E XXr8꟞4MvWk+]t!^{EܓCBB(: ZPgV~=Ѷo)tRgE`+ [zIyDfY$/mo]RB``@ҪeK&*,Y)))r̛??m9ƍ39\tIwEG'perxɧXN?/< Dcw8ضu<0Mʽ㒋/ƲL6o“O\Bs?60kl7no3O?MfV&wSE֐ ~FUU7nD^^={AUUBCC=3|mFANcq]mۖz;f4^s ^ /IJiӦ<ϧ8㌎|h1<\[|`gj,bՎ V)'V p ~Bw QC~߳^x <nGU2+J{EQ8s|w^hסx'س>B>?A5r/K/2nX}yln(nGi25k֔Cs͵בsh׺`UW޽ؼe 7r+Y4nܘ/~Ƽy_0B>3h4WǤ70/qFFeYDuIjS!$JNN!*2aC0{gs{<ȈbƐDcէwo&͛5_#\?΋/\'oƀWEZj*c݋[6AJJ Khh(7_~__߾̘9Ν;Ίy֭Za?*  }l6M4&/?Ciۦ w5]/'3WU6o;W-ߋBK!ȴLXUP0o~nN-ϼ/ͷFuzѣIMK%5%Z;WÆ1\=*z߷cc_K8pRS[,Z rء'=j$e{"44U)q̘9~W^ɒ%KzLzU.BWY,jQ3M O=A6mu?RL)(((^vV^S}_L9n\ !{;+im'ULV64823N:]v#iҤ1~enδ3x1jX~WK'+;&Ϛkˤ.7R:Q]AaspU,]gР\su &ˮX }ٓq }?Wf-o&2"eYnݚ^zChh(.܁+VO?'i&6oRC!EDŽ%Kpàk(g1deeyKI-// pݕ;A"#J<֭[t`֖-OkwK;n#""_ΦMڷsˊks߽Nۍ㡸d\FW]rgl^c&a`Fֆ(ɲ,TUAi{:]wY*A甔vN' S!,ivqqۨBHH[n%޺u۶mg8xoBy7k֌W_99h ~dy|:>Vs͖|`>$km[^={W SXP/Zμy_pۭW_?k$1U՘:}zS˲xxx{_ 0M+V2_1wKI;u5Fwscر՞]ƇJY5;B#L?0 ,ĕEŴ@$2Z|;<Bѯ3r1y37OGMVgZňwBE3˥Ŵ;3NNi-8sv/`~ @!'!fbyK<^y%DtbKn 4'?FKgWX4w#Y5)e?;eo98ofb;,1yK?;*BB^Eh9J^ϩ5رsڶe,B عZr[ ih#NQOnQ>#%gRQLLL6h #;&U>w8m.ϟ6r?֟{^Qn:Qq$0Tӄ[bazxvF.hdfkPUpj>$"IV=}7`j$PfZS\ =^}>xEE; IgƚhR(;O_:9mm˦sF  g_5?72 wg@s81ߴCPT 'e;w'y4NWVٯP4;e/.XhMkBijWh]Q_יEBTJјx-(`WA.>E>ô,,˂&(fMj~VXQwflZ:fp D5/E?bĔ]?kgLzav*si X;Y-bk#ܨOA?;7"$"t,6}͟^5O%Âg2gn}[>ryq]*ȥ4CzV`@!D%D͈BI$ٻ(ߪ=ʮ 8(" 283;踌͸눊 . d !d;T:MBTBtWUԭ*"f_SCQEìY yir}1eY}2@>Ӥ@.](VȎ}oM(웜uժcKŸ뮻:u*g]7>۵:* P&]&S(R\\LmQ(w}7d#(Jˠ )(<&4O8fԩ{、/74UbHQ@((`0ȭ˛z8DT0((-@EE=7xJ"W%I-REQp>gqw}w͛Ǵi]? 0MWSNN]w{oSEQPEQbe1MO䤓NJ'0 ^oSVôixGyz8DnԤVTEQa#F3g;0_l|/akgΜ9񤦦`䶓O>e˖1h KesN@YYY\|EQlWNU*npj6H)Bpr~{vqq_x0`#F)Bzz:mڴ#z;7/q 'f ۿfɟKKK9r$=z`̘1ٓuܙ̌LN'ݻwo49u!yx!NPSڊ(~]׉{G2e ._oNc&x<׏I&55M''pE3`nfy^ 5-5g֭z3>Œ/b 7{O>wLyIMM߮… 9ζK&L`9u㪡:7ZŎҲ}Wۗ>cp'n1c.`0e˖5h<53wVRH|l) "i+A.EQZe-xH$Ro9׿_NII :u⤓Ni{lK^^_|h|:$%%%0kǼl޼9O<Ixgƻ<̞=Q}y#/d6nݺfz humK.7cұcs.yIsh6mGױvZnV >7xرﺓnAgިVC KD^ev1c꫹⋒[ $ o)%RH!B`eY1HY9}kSUQI,7D"7xW][og袋:]SVVF^~~``YheGrȑ{== o~Odggq%X+&9l}w6m`̙3!CfشiW_;e˖7EiiVZŤIWO &O.իhtMK@ϔґ &pЄ &`8)"t9ǨŪ(J3vXbL6>~;7[nI6e\.B UiI y5s9#G$--yv{,> Xk׬a̘ CyrK_d>omy^k^/oY*)-UVu^kǶBA{8(.;}{1r+3?f?tԩdZ|0pBj&9^/BHr]^|!,4!N2]._YQPg&i"ࡇ3f.:(V^?˲e8s9餓4h֭$ǣ2.QQvz&%%h4\3tP~r6W曥KٲeKD"s]pǔ4 ֭[{*n{t%G}~k3z9N;s)0k,۷  1|32+g+JsֹsL]sh.0}rꩧѱ-zK8=!$M )XɁ VE ٷV9(rpH5]+L>MxS{ hฯfϞ)Srםw33w.P^ʼ?Ϩ}.oԯ;w\C֭ٲe ǭΒ/{]nz._OMga}套^wf |{=\/鄪xq,_,_?-73z}lEi΄Lx .=uAAi`Ԍ\NR <~h $$i$b$EwakuL7n_EM} ٟ|@aa!LJL:SrXiMJzѭU+6ͦMh?f|3'<蒋/"==4<1|n?5%ã>۶mg#WX1xHKK# &;>[д ֭[GAa!SO= q YXmkǤ!5l޴~7|QE9`Zd0rx4V._wHAѝ¦p%u,BHEQ~YNTqNɐ!|$8ƫɠA Xy?D\{`jx"^Mi4z@ǿ'Wn5EiZd0047MtY;iX|hR"-+:|UfvOIQCa8A~A2H GUI#3;Kv5\z 9O> pCwo_7^YY{晸 pnN<|^{ (( t8<5!~A BK&_ ֲ{ %" Ֆbi))Ie+}|_ VEQvE0ݡ!HMv1"tLDX6vq,V& 'Zt(G d#LeA<.ɉzSҫW)UQTW<_PMY{o <~}yVbEQicSRi󃔤<9H)\$gj] D6~MG ak-TRN"##Fvark5  xq?> (rhj1W:pV|_!XLK4 @Dr )@)@Ztw 3 SCQ"hr̙M,CK:Y0{K(7-&蟖NӅVn/>݁X;4!=#՚ Yڐ]y("S7R'0EQOy_Og,"ݯD̟=SREQE]܀`dr0HK1!@ǰ!DJA?(?JJL! *6m 3iءfEQEe)iI%~)$ȝ]Ztg `/5ˍfiN 'B-F(?CVXQv`'&(R! 9BHCB[g)CY+I,4)jRX=]^4!Bpt\lف|^~N=^y뮽(iKHrrLvx()qSR⡴ENN!%M;Ysih=EQsȗH!hKŐMɞe%~/kv5!#}L@w!'%=o=[t<ׇ~{ѵk6l NQuä>Nx<me8yy1t͞<Ф8 -Is C7p=8ShNrBU2R1c1*w EMEQ&vHN7G#ĭvZ@Mՠ@@&Vb&q^ܨ&\!=~Uąw VD߸TNo<,Gbnla#?y'B4>Ӆ1qکEm0 8 m8<4@H4TÄQU8WTG E=xcEQ! bSѤ=CY)-cgL^'%KK&ds2tsY ŋ%qsg@KX]A~Q A ,?0Kl !`f,‹ԼX E*7Sӱ5UFEQt]=^:B7亽;Q{Y7ЄIhJ&۹$ٳ jRrx\-&-csx9y ~N`K/eC&p80M~'c####(' )|m֭Xj57L=ߏ‡~K6mwŬ\)a\0z_+bs^g"8>/`6A il; jUt]'55ؙ7 X> '0P^N"3߁.(бzaªJ;$ 83+'Y?ՃDa!; a7~^5Kc mMJD,>@Ϟ=ܹ3[#cYgr\>uka}']9b,X%^>p?|,ZzIOs\ǎq}r|<֬Yq}pGGfiY\0z˗/gʕ㆟U(JV$++o%&e̲\hFU,pؿW5 aVS A?oӾm[ UvEQa[ ;] hg2n2 g4_Fb928Ԛ5Fk +H&a%$-r-Ưoa?s&H?Ç1sxɧcG *;>{`)**bWx'cǍ:|\. 7r+Gk}J?t:]3TR )R IDAT$\Rt}0- X : W6$n!pK^% L(=Z; s͠LZ䙂vq_IР3N'`Ԩlkժ/'_+k.]TTw]PYYwm]0X @jj`vE9x56Smɂ>Eۈ\O$>"۵P\ [3jhƏʕ+;u 5x<bXw9{;^Qp0l>}((0ҽ{7~[9TwyHe5C*iӲRHFcEj(]=)TqB[BȌ%&I@.MY]i2\3?8}&?9tPO{x=6mڔ|w^ 8Ç vUs1U:wpam[V9KsZɊ4_q` ҥ@|: đx !?We Q 3i.'N $g4 č ]HyWxxt{~- o~q|w=(Je&VŘ<n ^A[o9[T X0pjj:.tF2!aYQBfA A2ш'.q*88$૯xݻwgp"]E98'+#t+AԺyϽ\*)raaeBvwϨGRRRBAAf̛o͛q8g4r"[n4o+WƸL|@~~ IY;>dL vD(M'fY,{RC i/!&3s%IŨY$@&g @[wUX4&ffN yf~_X >k`"~qց7^{իWӱa֝xͷ8sq[?ҽ{7222Xv?ŋ3|9sݻuC5zŮSCX"$Niь Zcf.&.Aۍ 僻eg[a!溺E 9>^Qc\l+/pՙ|} J >3- ]JqIr4-V@ĒdZAJ<,IYܤ܌@\'HF  h)s^g̘aviru׳o2G +X`!999|?|WT'~Ƴ|h41M޽zR>58eEQaiv5]hML 'C=T&&t.Mi4BiI yO>qɄ :k/ܟEiB!RZͥ ;v8(-=d.!13妛/)ntyDO lEGwE"X&JJ`aJ1ea jD4vɠN6c!1Un_)͚Gf'OpՍB&^yiii|>oߎeYku+ھ'߀###I|irrr'ncjr!Cw(rҰ{sv6_z)23rvY~5FQd p=fW:Ⲳ2֯_ǐCXre?c/OKC8S}N?xEQltttBƍM=¦ iI'$h )%R DO0H;@hBf| 6?Z~CJ8CEE{ٲe+r!(**J4,PTk~)%PrˉDMO v1b<(n7`W9&%%h4J$`Сu:=^Q桠rs-:Irl.@۶qڴi3~fp6n7RHRtV./Zaضh\Åx., addPH&vGa!%RBa%wP P pK*َ(JSӰ!M&koONH)xɏ?Ȝs B|R}y{?xEQ~a;ZpieN;-4'2 7`@Nd%H')  KvU~vq\vњS b , Rv9R&fVsg~@C9X/-"H:-r-F_(J #YIw+NTT5L2땏v_3Hepx nʊ0Ѹ+sc#ΘСS#2^qS(J,np/1+ %]=|,娔4hTve aa,ehpbLTW y`JRBio`ثc{iH)ŅTEi&䥥n->WϏeAya)f4N 7oJ*K* lnxw;򢊢(ʯYRqH R֝[Ӑ*#u4pi5M$K$fҠDL4{ Xd!f( KaR閤[bYoP4 TfZPmՉG @08˂4M@@Q ֨:!0w XeA3 B@ $9YqBIĴ#Ii!Z BR%`geB ؙ0RDncv^FQj (t]0p/?ۣa@P",CJAЌ!d<*,!&UW"dS<ʦ]kv#,RP%ž@J,i' &FRLQB'/WtMEQEQЬN7n8LRqX );-)ER *Rڹ%˭8ai__:q/< $B!)b5wlA$W Q39+fUwEQEQpNB=FJP?EBH!av32ΟkTkM#P"@XkX/ڳsjHRO,B)ؖ8v3vᆤ>Qe!%DZn}[EQEQi4՞n7yMe+( DjņFq;4! !0~)qI 8%88V)P|6U[BPDb{ ۉpW`Na(*+MBUaqHiG<~+,u0> W"#AQfhhRSJ\\bTEiA&,q%pVXQI7yATTLio, ckk6F(ʯ$IƒF!{:4M#8’́wvw@uRSS1Pq3N pq: +,2hZL(ry䑤dɒJ;EQivE Y MӨp|8sYM7:*Om@CrHEQƕ&xU0@3j:( 4b KOgʵ2hFNN:t[nՋ@ C:E:nɱihW%++N?Gp 'r,l:30` Ohݺ~ao #~oWa:w&3#Iݛz8MN ((]n.A '5P,F8 M,fa&b<-ƫ_rٕL} 4M/bl߾]brn}>0(((:vO>ŋz>=󥐓EO4&]9gy2⊉74 EQ} n؀Ob޶~bY>mE.'Z(J֣`5ƱrNgFX;}Cջ_#qz/sW'4 C$t]g 7dz6$nLIJqi CQZ^H>*7?"dРAkH)ٲe K~믿#>T0(4C;bt)`_._βHvrx7xAf?/_̚5W^~9y/s^hy+Js՗_q5g|ζn/IW]ų>ClR*g@QE'AN⑕='pۓtI^>F.%///X}{F?O-ÇÄ ҦMNF}݋}w0s\֭_g?ӧ8i~+eY\|E?<~{@mn}4p}_4>yce֬Y "[>(4({,.O<⬳sgq3ޙ#OOAA{,~AYQq٥x\8n\UW_̈́K.f͚5M0¦EQѴ!!%%eel/-e{i);ˉ'aRԩG=RFie%H$ hzJKKw϶BSVVF^~~rE 9>~W.iGƧ~7yLn_r:PTT:묳x(//`m[lO>  eth!}|\vSO8>CZiGge…vҜZIkmKYzueB(J5!VYraYaPd Bʖ:kvTȔҒ)++kp뮿sSRZGiӦ=~ջ7*߯/eeTy,_ڵ+w= A6qFVV۶6x{iYkc;^T{ry1mJ3G#Ei 3xm۶4M ٰa;vh5 ((a@l.R*+*x7efvzjr@z. eee_!jzkƌw;Bnc iii̜9{wkUBHĉW`kYz? 4X9uTmŊZqqVYYuQ+..]. t!9 躞" H)3 i؍c9/<EQe7v)]uMc2*D/|Dw 77zص]sӲudZ[a]X{^ @j*:w1MQspAIII^/9HIIRVV> h4O2l8٧Se |u.Ƕ[O~5Z !*, kVvp8.0ҬX,f2Ȝ٣G 0uڿtPEQMb7LVB^TT$d%^x.t]èS P_i{S]]]Y(" n{kmuEI(JH):o!k#Te@|?J#<+2zz… x?i(҄T0(4 >|fb ͩ8.n7qaqW GU1-wQǿ{=\%$$ $T@PPP  `A"A PQl?EAUTIQ: ]ʵ}C1u>sϓݙۻGqӾL}rr[^ %2  T.h`?`F& :O#d%f`/a HAv.8v༬gתVGS ʀ Pm$pH\Tj _ 9X[$ɢ" P+h*[nU^ZIKDx8zʹ&OOO RW2y".:vZECd<5ޭs@pp0&/z޽\֥ϤC IDATCd?Yk*/A+*o{1G3lU^P}vTc.>w݉dRtyšJO X)ObZ+{;ɫM7'))ڶTJӟ>wy$Itԉ'|sG+<2Sʴ pnB!!з_,npEZht,b) HAaay|ūWv?~k׭/7-^^^*ǫT*<<<*RWD^EI^GeaՊ@ӡR:K3 //|UT:F!$ OO (3m-wNlw߯R>J~=?s+ϒitT$_}ubɒohʺ WqӠA(SO5c4 kڔG?ϊxyy9wy/NZv#X&Ϊ~Aj󕁨(Ν;_nE`aׯOpp03 zF /;vQ8qnj_߾|tZgہӟn/ Gw?m[7!\pؘ= FϺuټu+/"&//6[ѣG2u}Dd˖;?8'лWOj5IɌ0 ^}ÿN t2<0h -#E_7o X2>x!k׭GR1wk$$&2ﭷ ":* _t2b0j5գWX,StU]SI_=ǎٿԹf֬]y|(}X9j4 /HePUL2#GmкUkjGG[nf㣱ll\%|Uh~jf<| ;0mTYSNa|Z-=FVcxt\ɽеK{Q|hǔq:ez{>-[NJJ*~=p?ϳ~WXq8Lk4oތgg<DBB" Ƭ^GndddЃ2=zAA|eUtzl;p IIInݚMĸ \po{yoci*֭Zqn;{3hAZZOyc0lDDD0wl&OyѸQ#]+\s07o S&..zAA<;i))t:IKKc]deeλ|[d_⯿0T*.`y妽"/C,^9s^{cԩsc >Tl6,]Ɛ!n?5 AҥL2յ﹩}{vC֭i,s^g˯IWUKSi[E;}˯]c۹|l);vdX矝A~^hݺڴi7O"V/U(yRhݦ5EE 6OqOn/ٯʻϏ?$Ij2o[tv[i-7AA:?f ** m;+/}@HR"@)8GGG_ϰh4&Nҥ!"<1f)GcǐeNGLt:V.:*?Qi&Fyؼy3bccX[5lHXӦgd]n+ӴI 6Պ餰/h,|eʦMV9sOVX/ߞGHp0=?}ރZġC'0 L&:?}{NTZtt+V~ǡCÒO^^o{ ݎnjyI|  `0I֭h,>ބr3xb Dp8jxx,/bᲢs]i~ۇTjrI~Uűp[wUtr]c#ee:|Xt- kJL, ˎRYP2]ઘZB*/]=P:|IM4`W_SҾg>fhk.eYiŊ?*qT  BnPմ:ɉ'`2رse8~>:*f]zںu+<< 􌍥gM#ZNnaGl6+(^ϝ;Ǥ)O2~X<2 ,,̭ sm]t!+;Oq?Pn+z6i'PT<>zwJ|Bt&>|6O<={2YdggE\\snkZ:r3GuK/ ##Ν;,/u+*=וg׮]ziӦ*LFUQQn]xj5-[27ϙLO;`}nf3))e4] [{e˖|-#ķlru._ T*? 1|H=FzFƥ!(d%߯Q0qx֬e˿wt_oB]"IR)Bk6=hpbF!AW+""$gΔͩS)**rvߟ OhH_1O~t:|ڶ][nU+v=楙//;h,B|Q(~󅄄xc[eR^+*:tlXӦHٳg/MTRh^`8<1=zxiАxs?sspJVo(O%]̃OkKe˖degȈhӦ5<06 rם9V\9X,̙|ƛ&:*JiWyNSZgy1ǎU~+ϐ`Jܟi݊7*Ңټy۶aCT-[dѢ7o%((IHPoזB.\+>OHH0))nv|kz/4i^ӗ~7nV%l6|^ݔ}A'!uޝr{׹8y -!!;(jj4BCC+L*̧OأK=$ȖJEdz޽z1q>>Vwܮt0LJW,VY$%J<9.MUرfa2xjJF*MNn.< p4mڄ}322(,,GK`e>˒WeΡMkj6INK2L4jP^tQey(I~x]f3'LP3łunA%?qq\ߦ]tsN|2ht*۪T|MCyxXAP^=_ڵ=T7%%ƟŕM̼ŭ߄D 9qLKgtNwoIb`\:L Ğ׹4bⲸ/?Qu_ BnUhvڡl[lsAtt2h(Cp <^;Z leX,>^ o̝Cjj*iYttTIdddEcX(,,'Ntrq6hWtٷ|b""Y7ȖMHOOG;_&!!L0﹯L2~ФIcZ-Ϝq;m1 1rssټe OM>}Xr%o6ϝ͏?lqŰ٘Ty* _:JOY:f3\:?m~dq 7's]$&%i4i֮]C2i";vW_СCl>9GBRHNJfȰuVv+~ī"6&ܼ\m'.U*HW,ռ>g6 dgpqWeO?cB\\<'NP1(Xl97t[6m 77ƌKjjٖ Ǐ_zwsIN:6DE?H(}q` "<9֭!tƎ@nnn{d@Zz:zxS@o5Ex&%f[k7Ԃ[_DƁ䁣@o,BL6Bu<_T9AkG*~9stQ)55U͕¤TNS[,FfJ)˲IeU=yo`OYN zDvvvu t:Fl֬fL;ZJח2Ӟj|}}c2h4dggW`qZQD$mToꆯI>UhDח)kÃ2N#`{1m~~~U:Wy*;ו.#3WeykA4N[^VLJ*t>>>X,*C@ynz*1={Z$ʵ|||$m=: WCv`e+Ǵ)]$=A,J7jZ9fa at;EeWX'p6sEvcAǵj OOOv}y<Iѽ3Ngȗ$@ۜNaZγg&I d3gѕtRTT6\]ZvF=6,t@Xv$IB׳Ï&rykOՑ_a!Ւ_ue;˞۽s]i~Vv]+C҅5QM խ4\]=PnUEuQrE]\HpVN$IYF4  9,[#xxѸaC $ P;FqM*6@y?}!==ȑǘ4Zb%2s_V KI $h# N`c U,*xT\ K惇nz P5I=j4 .3rcL)1% Pr0AMr;qVVN$%p8FF#qI؜A:a)H+ l3`@?0ǎ]j8EAY|<&.aUj2lP5ȑ1glW7O`pU~Azo^Pg=tv x`6m*+AF8$ O8Kŋ/-wQ<<XP20idF H,* B$8q=o$)7///t:ZMna.ǜrg'WC2 +\c ۏ?Ϝ!=#///WC .Tz·nӆ^}c5f`I >3~7A͙5e4Z ϝ'00׾@rs+7ON'IIA-''3gNаaCv;;w?=<Ajpw >lY?~~~t:z='Μ@FF[Bk ̙N;VfǛo"Gwrnnվ~0mZ*FeNv*ޙ?~}`xg>x}~x011defQyo`୷w_ӵ8ῦYD))< ,,ZIVbA$8$ `<@2eBVVYYYّS>ؤ xwyxF!^Vӓ"e>}S p8Wyf 6GėTL&}r… 3Ff6('%%|2<9sj4 hF޽iּ9 aСݺu' :2СCN ¿֞={IʀS.vN><Y1  7 GHmL hj0`ӦMh:ƍ/@nn.⋬[m?ba߾OՎ{/\Qx+/⣏v>\^~ARYKz Z&`РA8Nm< ?ϊ1GdjE9e'=6_oW 8^{zPg+ p[@3ojN8ZV-;7^ Ʉ$ $QA֮]ڵk0y{cR:|}}e?=}zi:U,|iܧܻw/7\pO#==_}{I탟NS ەc, = pu\W,ˬ_RSwʀ Pȸs0pɺ{7 ,$ebܜrٞu1^%vRSS+=Ђ $QAEermj~*8M¿KRq-Rf < hŹBeAvʀ Pm *ۛ0sMu i%45Z^ LF F=ByN*or IDAT~?WW\ADe@A6]f~=&<*6o\O^= 4ӅӶm+=;7_˃>vBf˄2y"ݻucݚU|[~ڶOq _}U߱eFbcb*aCuFV,_ʊ˸y*ARyzZ展ggзoޙ[myoe֭YGQTT1 LBB"ϝ͡CdYVFv;NC%ذq͚5חfJFF&|[{]0'$p}6|}9RӭveIKKdW}d'c*󱲴j4&M`ILjjeqF%QF. k}ЕwKOT* }q+P9Aw$ 7j$Kس ]7s`n|N¨@w>A*7mڔ:wV^>ޮy7Qk|$&&CDx8"+IIɴk׎ƍѼY3{vAFFe-99l$++z)oE):|cǎѩ-e≍aѣGiܨQK/8}ݻٰqk.,+e\_36E+ݟVM72-S[쭬8Ss\s_#E 2gulH [( %* ԖVZѱcNFP[6lX^OMc)J@f3OND^^3yyyX,j~cM^8Y222D%]_efe^FlۻwժJk|{k6p;=#á "9%-LJr fr/Q6/KSM%9Ш鄓#+~~xصN<8 ~?}{QTyF#R@aխP6jh v]Iuu2P___F Ʋ2q8KQQ$$&0ze„`(3pt*Q4A}?99tr1~~~nfvL\;v[_ꤵL2319hD]Uff&AAnAAJtR]:6wi!!j;0y>tZN?K*~9stQ)55U͕¤TNS[,FfJ)˲IeU=yo`Ϟ=Wz$nWƔt]9f3~v{$IϏ̬ HVbֺꊔ]eIkyp:WܲyR!33 pmuЁl6e70֧cX;"<7H5i&0@pp=dYFvʠhTgq!15k6ْ~5*͛77l6cYbsN y73w.Փw}}/x~ݽCɓ̚2iqG7f3ZgNLL,:w˓M71}S##I/ Ĥ$yjT<&NIL8MȰaiԸOO^ED4cї_'駟{̐!CÕy<Iѽ. gd9lÑ/IR^/Ϸ9Nj:gϞM&(GEE3g,Y(|7%2VT~ygggWZejiiiծ~uNZ˓WaE\˫k@FFlhZtF<3 $I*6'ٛs\Ai@qrѥKW7o^Joc۶zЮ"4jܘGyݕeZ-{^W&gh5 8ѣGqkN|;~[;w"6&=zp7Iӌg~JExxC,y82~РAC"""dBsɒ%nhZ^zEktM?nFRb"v`_ŸgРAxɸq㉌bO`Z9y$gILL,m۵CO?(- \;ǏgQ;̾I&فĢ2  ԈJpht>v`Ü}[LO.:=ZI4z젠,5"@nn[fJrr.\(;&3F);n6Mfw8Ph]>4j.UaٱT2 .p<F2\\\ߤB<Ȑ]l9223b<1v,7pO?̌g9Q#"{Y<0h Ç Ct֝0QA*8eF=I~Z>RѨloPSY,`T3֫qe)((@VW{IiӦ2p ~#6nbǎU[焆ٲ癊a'Nܹ{m|}}n uJ* uSvc#6tǎ4pSLPί3  :?:<{o"͖J~~^x5$;<mdT CC y̥0V/:~?|'77_}@||<-[\W&L||ƕ p|eɲuj!5u  Ւ̞s#jhtiõWMIDt^z)("=1,+^P=<<<*25uYA/AZL&jj9q! ۀSFv:1nLVf> pqF* W  b2CѠ뉊⛥˹喛i{C$Ax hV,.ĥFff6 6$''D5jV%!!Z]ۗ& Gk;) IIII)|ٲe+a7% LZZ:q).\$I4i҄"233)((PA?mEHZ=R-ʀ}_y"t:jk񞴴4T*jRRR=[p8ȲNC$(,,DףVk ¿Eξ Cj;) w=yu~N T*  $Z,-VEA-,a9@_ger=v -LhHH F &TAkï~% 4)*vu' _T[ƎCF IJNV\ \ߦ E"?v⯾zA|fڶk[Ĥcbz&//CBBjr喛y9p b  5P+˿]/>hءT:|Dt:VίPT*ۚ4i *ޕr+^^^X,dY4T&qѾ][G]㼼(,,T)GRa0`yKW_a33صˎOAAZ&T'L[;l\ݻ];~&yoXf#7_EF-hBElټQyo0xyKl޸ &<,ߝOHHׯ}FL?1l\)''kWeKټq={Rؼq=Ç }_͚븻_?}=;}غy#11x{x{ޛlGrku1 ,*  :2ТuKy믻yyn7˖~BB+<> @؞l6&NO͐+ 'T'd"g/v;ϙ͸qcyWyL6wߣ߬Y3|}}yiff 'ODFOraJ8N~);v7b< 53h4&M`ILjjeqF%QF. k}<./8G1ioӆ>^ uJKAA(η 4mڔ:wV^> ׵kWl6_ը211l 6$iS~;x[nXڙ$rsZd%))v(U_(pxyzXVlRuݻٰqk.,+_36ESPPsn}_fO/p̟|xP{"""h޼9ne*ђ/^`(s|͉Aϫ-6l,w@UfS. k.΀T&F<$(0ȭe"((P@T剋wn[UPPnGբhh4n-Zo>$Idee!I߿ӉZFѠjJˢ P;|7!ZNS^ 4p;wbJu폏O.;Z{Ӧ͌1 oo~q~\溭_Gʶ-s5<4kVyS{XN>HHHT^V~}+ w1/pM<lCwJšC"AV~;N=N";N@S-y46&u.W Zܹvz0ASB4{ gd9lÑ/IR^/Ϸ9Nj:gϞM&(GEE3g,Y cGN EEEhSf[zz{Y<Ǖ' U zouMH߫Z ޣYYYC!JKKx6ُvJKK+GϞ;Q#Gi@f;i2nxRRWIEfTi2s:q2rĈ- Lvڴ)~}?jUQ?hQ2 …pw?lJKKU !Add$V5Po0(ajtrp:v, bX0 ATTAn$9jCR"ksϐ!קl .`gyhhL& |\VNnݺ]ݿcҥ,Zf͚P~}-ZLǎ7(_U-)) 1rziB{v트<4qCI7W\ǭw=+֪d@!o^>/0-CzlBh4Z\\IN>e;łTfT^-{#hƐ{}xCL6v׷ټe3C{ 7{[:ѭk%M&4Mc w}BkۖΝ0 !Ή]Ci+0bD,?OV Bq掍Uą^HAA^M\\GQ\pl6:QQQ߿?p`=8q\/@x5sY]vp8HHH ##ku =L:)S^ g 枕{;63rp:+ogԨ>!6 !UUiذ![nl6c~"K֭[{v1 MHKK#11+*m uR|i/̌f0aNIɾf-[dg1[{{l:Xi먦+8cWӧwoƏǒ%K>aÆs/X,VzSN`6df9|Ij\BGzBDaLXX111墤z:TU%""@/a5ڈpidQVV(X,@#GЦ5;= 9^/eee4lԈtBs~}yǁj0|x ]at#H2 "habpϧiӦtڕիWӪU+ԩömۈm۶QVVFll,eeeUvt?ի3aqmq:(,t|r>}LVNksŰeƌQ#֛L~9j21{ҥKP9^2/NѣG9z(>/4|S!j;Ʉg桇X֏`v;:9ZπRdҤIΝ;,v+M6UTj*..Vu]Y|>4 eFtZV`/~ՕWaÆy?B!N!))-[M疳weUʣ*L&"""0 KLL av|Xfd2vDDDx(++c,ADDEEEWgQQQP:l6[ Ltt4999@?3|.\k'v }:|] 4M+Qft]GFFj^Wo\.#..hݺ0iҤe B4EQ4 ٌDEEa(,, <[V\.& Ill,fR|>EEEgCii)o(~lN)ğԩk'd@!DЎX,(Bqq10|cv;Ұl^/&)T!z5 /lŅR^~=Zh6lW]u/r 6< !h à ۍ溺<:{|Gnn.x<HOO b!:=j3&MT*t́#E͌X^}e:gt|1CI†azȑ#՝pnn.G%--@]IIIB߃u2p!Ԅ֣v8o}M&aaag%P zh\}7nK[OyVk{t3ѓkaL*]t>]5z Æ>e]F.~uo7u!y͚q .bڵ4lذҼ ̸com;FppKҹ+VRO q"]ƍ7|+ӧVZ^ UU3S5B!OLf}իV3oOVow>̌JdfdR'&UB!8~=i{ cNz\^^uNHaa<+H t]GU=[$B!΂?L2͒%s^_Дp/K- UՠOBΝi^mѣi ㎓d}T7K4h@`ۺwCUUoMX,Ǜ!BgJJKPOb/Y8 nʜ90CUUFm۞]Ϟw`* .WS~j{7 sl,Z009Ն2G{"0X<-[^! N\XQ;BQ*^L4IٹsniӦJVVjZMŪ떰0vUUa ÈNʛů 6lpvnDQ"?]ODtt4ujf]NUU"˗D@߁$lv6u[QU[gBXHNiɤ 7a cqXfS[DXt8:^yxK)9Zh7$)Bz-ANAoPzi%lHjqqq e[6&Mt@|:a0λsEEE?զA]25,w4=~v͂n+oPTXBII"̙|~J(-Ad]a#Bҟ&BqձP1 Ht  @+4hD74ԃwhʏN{M!$B!( &s.e JDDD|~K4?ZP*M&SRSόxe⼻Kp::d@!D@4iحVEl0R=@p-gӸQ#t@GAUpkX!$dIBԈWQQQx܅|gDjnk.TZ=N+CQPԚOv8\}QTTď?СCՊQq,g 49t 111\~=x0v=_iOUT l={2vXFɦM6SOB~Y,fx-[0?}fVIYv\t墴_k !Ah>VZatܙO>a͛3gN#>dB)*(O^n￧~য়~b|wUHzsD4oN0!sFz7|R"֬]G6}>A]Ԛ)gׯϒK9rV'rjr> 4o߾=W|EI^o=P7y݇k֮[A߳ظa#IIIX$OMȀYd ڷg!!5W@SDG?aCA?~Ζa`Z@ÄHLLdMrIddd0_^3t0n>S[Ul6[2Ɍb{/Mvף*C c?All,/OΨQ#ټi_|1?[bgeaAݯڷo/!2͞]5{Ï?(CGzBM"9yyd撙Kv~>>@SˣhÑ+2vS>X&LO;z|3Cqvo^5j'--$B4:<6!ߏ}a11DGGcZlٷS S +@'gwΫ/Ý]i2(L0yҳW/>9?W$':z(⪴;YCnN.w߽A݋"tZ4oNff&L_~HVV&͚5#===! B4EM)rQ* v;aP\\L~~>xΨos|J&O>xA+##Ok2u˕꫓v(/X:wt\+W~K˖-ڵk^!8?7oAnhѲ%#))oDfB^HπB)'sIf0 ݎn#%vfL H^1c&L ??3B7W,e˖<4! 菦i||͌S^݊aE~ŋ/ * Ǝ?&=ħC~wx?!Ĺ:Æ A~wѵ[7ԯBK!e>+V0LٳhZ !<˅F:(=iUXj(.._sM{0xcĈUzMf͚IXXRSS>3>d:|111|> u{ݣy7W IB͠|1崙ݎV1((8]8P1*>0(TSrU|*@M,$ !a}&L*X@Rÿگ)ߤx" hR/B3#ɀB-Pi"_;KC(&,6+f |~0a6ޢIfuԽ(odv֓d@!D|~7ۨVOt:0i̇+> GDn9~?(pаL^-EB !(h<`B)T u ɴf($B; ɀB9qB !BQKI2 B!D-%ɀB!$B!BR !BQKjBB!;xӍ60 آ@^/8o1(`x|ހBTKp::d@!DPtC4Gx te3бsx|#@`BoGnwH2,-*"HƱI*WT'k:b†-;_tߨ8&knݚ T)+HHH8Ytgt⏫YD`XhժU 9Bu_?ޛJq2~M]x9ԍb[+3qYw;ʟzi>=/WiРf6QG0sLC#CVHBE?D诞߿]ڵf̰n}@(ԉqx6tff0 ^oAaaa QQUAqqq8NJKKjz;4M;iLBfAis yV0 :w'0HMMeM̙34gsaBB!bU[IAb:Gb6L*]@fv!%eUzum۲rjL&Sk%yZ, [Y߮d̘~jYk[vgO֧l`oYp_|qf͛3BoWbveQF̙)K.cwy'P;z३SyWY|9)6kW_qvlܰ$VXO&Nd,Yv۳}G{IπBP@33 gE]u3󉏋E/;T 4McǎX︃˖&pѮx^}1Z:ؘ.kТE پ}ڵ 9rK.m۷8q߇"xwfĈpqgϞDz3 "(;W}xo}AC:bo! Sn4=ԶcҭT2`/2'ϝ9#FNX*%=--6''M#+}NHH #=RYFF:ubPXX$Px<ȣߺuk}VVV:/Ä8 ٷo/P>Ɓqt#ɀBN ֎M,uof1  $'{n\ݦ _;(RN,P>t;77JHOK#''pl6[`q؜TU塇FUJN${,q~hޜ,&LH1 ?L5kFB!A1 ]p;F* ~NӁ N;no|klv 0[g924oނg&=(ONNfٰ݃|nO{E2{IIIңgOT-[PVV4h0f; ~~'ƍϿ^xMp\*=Byt֍'K/eÆ [.!$B!rlPWquv#t90 ƈ!)UL.O CoP0^Iظq#99ǻOƴI^R,ϡCNyW_yg'k֮Ғ~xt`?Ӧ3h`V~,p1cR6lfأJ2 DΰaCY(.vFCYhI2 "8t)/hFqQ*/(9KB\vavaF 8X㉀;+iFffY9WMZ>O!AI^ CQY-_>_ <(/g`T|(?رuCHI!j;IBeܼ0a!8P B! IB!$B!d@!BZJ!B!j)IB!$B!d@!BZJ!B!j)فX!D9I|dYؐI간"(\r NPr3 ƒb (YXGBRlaCB 1 u 3 l>R(.pүe Wxc23`> >F׻IOO###R7 ''1p嗓ظ1evСm{=@+<~jcS'+pg8lټ[Mrɥ2/C!լysbcjՊ={:!5Ufb:Fs0Dž.8w޴hނ1cz&Lm+]p[}=U7oނԗƛջϝKÆ xk 4ih]הqUΥ( 7˖1!oߞ'yq> ܰaCB( #`̙̚5; =B!jnCv$I 2+#N{LvVO=Ss wWӫWo^{U4Mt2sLV'ɓX,j{$n&=";;Jw]wٵkgbTj*r(..F[VTՄSZNQ\.n0PUqǓ>$''\XÁ |f6ZTlJii՘8hm\CB|<~ǪU+1 Ν;'0 RSSټys q$B!jo]jrw0h@7ڷgUtd$@e]?'Ofذ:tJ(w曕g;ۄѥKWt]'++ {~ɓ%++:@\\<֛sdnt];x(((dذL&E]}y爏i5II՛@RR v>SN} MӨ_>>_~%bpQF?4T6m:4 $#'j2%DmܰѣYxYꞚ8!Ceȑ̚53! Bq^g`o>-y>;Kٲe eeet~뮻.fŊyϧQFAw֝+WҸqc6mʦ͛h׾]v/য়~ ++ 0N{:)yyyrWj޻an'6_sѵkWL&>5ݻw3bpF~JݸqykDb&$⌌;[лOouMmժ kѣ'99ԭW8q"|'__zխWjϓ@Fzzt |1LAѫw/tߵk7q|ci֭[%4ԉTx1cZp!% 6_s8!ΧB @Fqj  !8#=q>wɲeKyqʔ@ٍ7Āywظq/k '}f]L}%^|i*={Q //}ҽ[%%!!Okry7O\\)]*%ԭKzzZSŵbrV,_5\믿زeKc|iѼ9YL0~c~!YY4k֌_%ȵ BqN97ͥ_ n\50L՛9CjjjW\9xZ=Gfm¿PJ믽l6POll-dȽd:kƋ#(_l6ѳg`԰@eee4232XWlܴmw🙳Nr!C͚7gȽV[d OM>ȖX)^}Yv+]ãr>TVNfŷ+n} ݺu`,? ju2V~{ˌo+1cxY|K-gӦM|4{vP1xӍ|>jjv n 6®]غu #^FJūI&);wTۭ4mTRVXuf|V0 aiYyA/qՕWaÆy?B!N!))-[M疳we=baرq'bįfֹAL8i_SUyj֬YqPޓPN<gf#??Rł,\:vU- QQQUx( 111tZDEEQPPpڕ'Ot uzhV(Jf++))Լ^߿p\F\\Ѻuk`ҤI'3d΀B3xyn vS]FɅdYkt?˦Mkidffa܅Tݣ\ii)ͷ<:WeNCa9kV2LH!9!;Hdi[޽{UBFzBSubYR!B!d@!BZJ!B!j)IB!$B!d@!BZJ!B!j)IB!d1!ASUxLf (o:ig):!5%ɀBEѢE37mtˆnˡ^B!jD!AXm4mHj~GUUؘ?< !)IBEAu[g;X,=(qBF!gFI|ߟ~/-Ǔʄ"T.N')))%$Bqك|ɌUW&2|v$ҢB!jHUTUg|6g.͙KqQ1݆nCQMiJIHHMq'\vmװaCڷoOLLLm^_fEQ/0aڶ7^n]l6iu֍o|J_Yxeڷ͉PG0sLf͚СBR0!!5`2XhnC0X,*6x(UY,LfoDQx<ֻ\.JKKhգ-[6s=h'ЧO6(9bD=i\%n!DU MkH>VZatܙO>a͛3gN#>g@!D&z͎^Z˭6Gl1aFDEEŘL&L3=l63s;]K.eѢ4k,P߮];.[5l۾={U9Dž]ĊoWtо}?Kev;ub~0L̞#G =L+4jԈ9s>een=?D`5ɓw>Xvݺw?FQ IJJbŊ 8?4Q>驉0?K,]l߾=ў3 FTEbV tg?MYF~w7)~nw՘L&3\V3}4vޅaLzƓO>A||<:O=5 Qef͚[3xjvl/ѫWoVZ@.ٸq#JmV+ɄiL8>VM]qLoV,_Όosk.-Zbgep ٴo^>C=R}9j1DQ !դb61-l,C*a6Y3͘&صk'v&MAzFWc%%%O`Ys]W СC"+Ӈyro2uTLy{'Kbbc."֮]C-gmk.pukYh'B۽{7#F g臫ԍ7={ Г!5jŜ J/_0̘,P@;IEQ-[2y-f8H\\]qG{ IZziIN^Mbbc֭]K ;sF?0YY$^ @|B<#VjuÇ6&!ę+,,d߾@=OZZ ;;;х$B!jd2&E|?^UU_wUE}y; ռ |7v|Nz촗bۙ>ՓS^/1bHa&̰a9pݻ7!7'UUyQngKb„0ʤYf#$B!jnb2:À>TPE0]tRXP>nrѣgOJK$'C$''c2 //t6n,L)S5rd Ϊ+?'3x`icKgEdT>7obO?rdee [Э[7RRRпv'|K/ 6nݺP !7Unc3z>GQM&f/]tʇ<< lv9b^sg/x5sIYp!_|18e|̋SpQ=K/Me3)/N!eFnlv;=$B'3lP$'ݺѠ~FZJūI&);wTۭ4mTRVXuf|V0 aiYyUW^ !8$lv6u[QU_ר1m |~n`F⽡FE ]GQU׫Gѣd>xxEad85kˋFGGUQU)-~PqED`X˫6v!DOt uzhV(Jf++))Լ^߿p\F\\Ѻuk`ҤI'v3 "h>o"bcTz7tko;Q<@a XED CCyOrC^/6mSvBௗ&BPd@!DP=;9'&1uʤ@}cAWqiP?ԣy4͑\Ij^l_֬>6~˖ta!gNB9ow?[n -7u JjZ)M.z[ùkڃ0oFX_~ם;w. !ʮvrS.xHd¯}i@+!$ɀBYQUTEEEQm]xaz ۻ(lK$lE@TN=OE`9OEЯ 7Nv`pt| H6ɶfBʦJvfv35yS׏[AI +8U%%"SpE>X"Q=Q;`b0@DDDDN1 """"j S )-JDD izݺ`R}9b`3aQN1 "c:N=T >NBqA\!-;NuM2 CLH$ t^x!:u[5 $`lbcC|gGq :v+NBnn.:x,oƉ^8 IDATo; C (~NM>E;6"":ѣGyPnn. ˭xi`Cn/{`lHvH ºf)7l6躎@ $뉨e4y2 =٫Bff&,Rؿ?lٌ_=%n^ QBۑ*qСJڋX5BUZkS<gȐ ߰ܲLO< ֭>S\{uX %%QQ˷i&1+VIq߽Bߧ{fĉ|rvhl۶-Υm~ &uۇ arP*1֠6$޼6&p8_7`EF+BgϞHKKooFk(뉨۳[\;\?}:&_ye&N 7ވkݻwǡ`N]QzkP@GnAN} ŋP/"(5uclj8d&XJ8]n$e򐥇.yy]m=|س[@Ϟ=ѵk}l^0 ":RfQTZ?Wl<w0 łٚ,)ioevegIֽ;9R.cD yy5k6>X ~OC~]a0@DDuG[ǘԟ08pPuah!$ƘԟG6HB6 fÁfï~u2H=CN4@d´\UV6z"jc8 L1cƜ8ТDDTgnO_Aᶞ_oOC@dr4M.]⶞_AC$C0D~ǾmL6sfOŗ^aa,9vpRJZ fÞ={أ6z"jiXzulل+.Ǹѽ[8, QߑKq|nb<9`5q(vƶ1 #4hH#v1 '^ǜvݵծ{yX`> f'>]u=έL)eKơ4-""%p,;ߋD7G1+®C;1I)80ʝ|"WURRҤ뉈Z#DDTo uO9SLhP#ƦXgv1p|(3rgI'^{rn eEEE ̈́)DDDDD""""jWN^1nb|嶝yK a;p_?^xW1uTzq߽3zDo`ɒ% 6=0N'qƮ]233qǝwAIIX5<4U!lڸ 7t3^X/ܺ{fLr5fp,""&2jop0?ݱYo~{֬ΆVGaz{yxW_r ~m 4ܶy?7w. Ɵ{.X0`qر8Lg{/-\ɓ&b83ēO7ވeq!c< ?e᫯] ׋nݺ7O?ԼgϷv5Xh1^}r'LnWO wS)-Zw7fy!9 FsBλ袋 83!Dme{Kֿ֛, 6m_۷֯_ߊ5Zp!z>s#G$9r]?Ν;1ctt͕͜y;vj,03@DTQ'oq@̪U+ǀpI'a(,`΃4hMRp7eZ8zhiPn#~B(,,ك[n\{ߞ=")) ZQbϞo={i8pۇCŹt`X@T'6?!!'`d]ZZZJy}>.btP<̼JLZ$''c9PJa7n\m=IMMlѡC?FaҤ8{Y3ÙQSп?1kl\1aRXx1Я_?ƻq`f_޽z}ߡ_~8䓡'|2݋^={Ofkq}],ZEEXn]I 8iRy%cٲB4y2ߏۋ}z# "?|$''7xDcÆ 8 8.y]8餓qF|.b\0 "cb0$cRR_ -~HIMAN0x`tޭQ3'Gv*ג0 X'u/BCKJ,?eOea5r*c->%A*믟5WǖMr?ݻ5ߧֈxӮ.}3;w}gAZZ  b3(_|/BeY1 "U|"Q;`!ůbU40#PcEQ-|,ZjADD3DDqW]""j 57iy ܵҲryU:DDDǀhPJ~]"r'"116lwQ}JN9*nwcǟ`WbѸ;5Iz#F4ɾZ!fLc 5;s7p_ jnEEE嶻? ;{vqeB  V^u$$&WXX}^}5l}]eQ\9ŎWnIn7 ^Wo˅P(˲,eYBu>/b6l8:dgR X_PJaزe3^8y13@DD|Bx:y"@3<<4˹ t|,+P Э[WL8mFOW>Xk=k6{Eg1~xlظ ' +V{5S1w3"͑^zi!>[o3>T@nKqg` x7*ݡzL<:)%4M/4ZIu` 1zh5kƦ[pÍ7.E}1>|7mƝw]cGSOO?ņ'j-6m܄#F`Ŋ4i"XP}٘8q/_ߎm۶Ź͏"&~:9 }i`uM~v7e?$VZʭԩefp xװuV<jP+xw>F 'pJJJѣaLĨ? c-_`ki|!<0gn!Ыwo\uU8{Y(%$$`,;Zy-YE_Fx΃xػwoΩgϞ9jNiBHMME nǬYqqt:vn?>FJJ .Z?—^8q-[nA{#sl5={ŵSE+r0q"nF\=*E`0@DԄ֭ hZL5k`Ŋ,̘18?3 ŀ #Fwޮ?_1cØBU1r$ ͛6׿5wCkNR eaܹbl͆K@@4̝;_}5~*k;b͸{{@etSK^{ č7zI߿@qO;wطo>9r/'N—^OB|mz]Q˰sN̘1=S)9v\;ڵ+Ny "j!4Mj@Y=8't=gCطotχgss@4Ɩ㏕qń 8Yp#`y?|?\9'x"V\?q À'MDAa}x駑^V.]`nne -S}~~~iZس[@Ϟ=ѵkW}pСx- "Vѣxp̚=rlaa߿\su!/ƍ)֭())O>Gb5  RVJ\tԩcZ/} _}Us{#G`3@Zi׮]ѽ{w|Ι'x{yoz޹setAn/ͯjMԚ yy5k60J),^yׯr+EDDDMnu~5K?Ɣ)WǖZqb˺vC=icŊRbgNlqaڵ"O srrbC !pӱrjGݻ ?8+marD:;gv˲j.2h9=:7^Lj#3fL4رcQXXӉۿƟx{Իw/{Y:[o6 /-\!4r{fW*ӡCp-`Μ!DRRJ $~֔^wcޭ[K_UNVVرc>OWkv]/..֤[8pjr+Ry?q<""#/kܦ˜OCk&j5qmy'=yrp8 뺎Jm*99` p8СCVmt]Gǎ)(***;B#Gx辏=Z<Dt Ϫ;]ਔ!pKJJRJ399 B{Un[y< ++l?fB%%%1y=(..u; t򴜿J)xJXú4z `6;,˂{R DV7yPRqm&k78~@׷AKch|x"::_Z}$Ooj}ul%"jT(LgJw%D)`@)U5@!xA4B(!#""""jE8(Q;`b0@DDDDN1 """"j*5 }x S ^]וWq!""""V* 5&M8aHJJwQZbloN'2 ~=*ZTX JtL"V_ 8aq~wQZΝ`h`l۾Wݰaq0/w4cڞtFu>zׇUnw݃4 ""6#1)@<ɪ[Ij+//ܵ^T` ''.ځZ+}643''n[y<w ckYk0v]F"""ax fک*GRYYYرc35XFFʪ2áE QPl@~ Q=1`h< Q*jB !pL<}>|c,p9To|F"Ql6 2_}Uv>Tn|l˲bǞu:,y]MY&YwN/|- .gq:|yCBI K^S?Y """jDv=(@Ip7c׮]8x Ӊfݻtԩ9^guy-Yw c }}/bw6mڂW_Yw:e _؀3?ONp8xEgڎ8׬v;0MfͪqaÆnͷ܂wu.,_O<8Ng3F˄f܇{gݍ5z)%^\iFTF?ݺwUn#@bbbm}}Զ/]ב8j* ?@(?qLӬq/~!6o[¼gn]!,<д]y6^~_WCovoqgiD5lM,~q>.XB,zyk>:[€c_ڲLp9yc .x/-xt?Q#7`SeZÉ'x%%;k `VE3P(vaHFFuwq:wRF)S5| /ms, N*7|}z׺NR1jU6>t;g4[KIDATl69w:m:.0 u^o"5 me˺Q#uoeewPw/=2SN!M[ѧOr'zIYoMPXPP‚$&$[noG(:s]]R(!b~A7{N:4*+Pefb(a(0r_ 6[׮Z_Pg;lKЧwܵ=ztG]ToOEaġEZs6}}N'~iz1FEzzzӱ/c/oy4}޻1lҀYuW4pW@B9;?.k>_#MӂSǬNZZ*:Kοۗ 4eE*xN-""":z뭷‚m3gbې{^lٲcƌkK[)- 'tyزÇ㚩ShB\?`/7:<^rLlܴ\rÏj)' 6Æk!,%#zQtꔆC"C6"QM륔aVѣؽ̜y{> f7x'GAr9:^ZQ s}9iiiHIMŨ#pԫߜj|bv7 -Һe.sήIO]%\~xuыX|lz;+ͷ?|y-8c:nWrYYYbǎ"??_kzyyyԅfRJ J)2@#5Ļpvq𑸏4|&znj 7iBDNfADzc4XsB 99u*蘜c:ñ5^ﲺtx#BB)e15M v|xQ*++R3@DDDmG˩WK0B0w1"*J)=z[MXר̈́A"""";VOj:7 S aXըQ Q*pu̍RJӴF-03@DDDDN5iJv6M%""""sײLvAf`%x ۗc 躮Hf@JYϩ*uc%4M~:9 ""6;ǻVΝ+.4+mEEBx:ujٞ_aA׻^ݮl6[4MS@v=o!"sv!0pxUcs DӍ7co㚩dmSaa!6n r* T8E뺮J[D[g &""6Cwc !k576l@p2MQu NJJJWv]B!@0qR`DDDD'kz :K4ná\.Wg5Mdى:Xۭrrrb P Pi*˲ 5h  `$%%)ө ##y3)4щljRJiYB(0d43`1=6R( or)׫|>*))et]K)%""""&m t]W>` ++uǔFP(ᰒRZ[Dz?"""""RFė>W%%% ^or#U"T-+0fzՉ" RZih0nW.Kv+ǣj ǐp8*11QPZe0m6ifNj LӔaH˲,!K'Wa` !8P8RJiᰦi Ut:M) v]9W홁=x<2 Y211` !†aR&8g"""""`R`0 0LNNBxd}@,uY%5'ӵGjCGdc#ۅN08R6 ifYiRJMu*w2k+W\:gkJ~WRBR ] C)p *?QWO=BR*iZв,SuSJ)RR! 8yk㊴dob3GDe)MӤRj&Rel6[@R- `AG޽{V~,{U`(Wkv]BJ# 9 ðK)t˲4]cP2*--\mMUABJ)BB ]asıDDuKO@R* (0RRʊdYV@ip.7:ðeYAz,MӢBa@8n*@.2-??_Ԕ!p86F( , J)aYlH +TtC0b凜BX @& !%H9wSOJYREnY%5M[ѹp82N AӴX0`"iኁ?mί|͊~2{jǎ<ٷo_O?pTKS&]4@aMJ)vV+oZzR3mf]_),+!iiZ4+HR*H6""")eHӴR*( !b*&6iT,J!FRh hPyY B T#RZel0@ ##C*O}+4ڱc(!ӝNnt]P(vͲ,aYR !V+V[z0@Mn RD_v]ik0,˲kB$J)}%i_DQRJa40MS3 C BiB4a8śiiF8ھ[BMeۥi*Z, At)j_~߿f.p8PiZ@@!у iii*2f !4fD۔0 @Lu]˲RR4wQ+,0L˲*#""jV{RtDtf(2 ÐBKu*Z[RR`="i ð2 tc DU!"4@WoTi !!DRJzthlB40 CJi4MkcQi90X@ȈB B& ڰh>6M%''+zfɎ;s1Cзo_r B!A_E4,B0v;J4-?DDDRZWVd U:%,˲t8ѱUXH-{/ $wD D5(3U1Cw^ 2D@QQhp FT _beiBiFl\ǓtYR !iR)%u]LLL~t\nh%LFvv\.WRRɁTn@5J  2GmI`PHP($ᰈTHB64B R)whBDDʎ&!q1BeY%JaLeYpJLL^Wvp8K%0))@;S}4D5Jf b *z{e $@LP>On +..N"m6 K;ŝR麮LTaH2P(R*11QP^Wn D_ R)Pyvbp8"4MI)c3LZUT(6iJu @~n,8NUU%گ Q/6`ǎPnڻwիHۭ È}ʢz, kK'p8aXuSlP'~D+5v&bW$2I"-HJJv]vUPP4MS 4M!iL QPڔU)bCF'6R*˥rrrP62HC=*-P4uCSeр ''GՋ""j|>_tx}{tj䘰[iK:NUvTuDaƣDDD5ޣާrrrDR$ kfBr.P^P^^r:u]~e+&ԌE&""Z~RJtU𡼡Qafb0@-A6p U %5;DDDDDj33n S  ð,Y"";fa0@DDDDN1V̎|CDD-eY*GT )*^)#`f DDDeYD- """"vv]l6eF iJ{ų|DDD,B3PEԒ0 """j$|0E jNJJJ*Uui *# =*gf)^FOF @X QދZ fp8nX{L%""zO4M*On[y<޻( Pm"dRJdDDDTRJi؁b3!jTVVV999ȠRe)MT?RZq3 "FZI)2MS麮RJAFo |J4p8X%iY B "$"vDA! AJu]J)V̈́Et:r)g@u T8VRJKuK)?L QSJ4M떔Ҳ,K)v,))Q>/8N*++A3*麮~2J4R."CJ)KJ)u]I߯a{^|>_I$ o ##Cy<vURR*; neYLf0Vr"""Bpnas DG`999E eif a)%DDWeB)N e8vr8*'''E$*D A4;DXz< Dh0a0BJ)DDoB-˲lI#(f(n8 dgVV|>HOO׎=9~/eY6!S4ەR6!nYEz4MӔR"ÈtKDDKt迦iƖ}SJC)46-`YVeYAB ;ʼZٷlUQP]0c(,N*&iRӴRʬG 0j }Ok躮]ahRJ}9NRh?o i** aRJjE8J݋tuQp8L()) BPHR Qe_"K?JH>7 *2 CN)MӴD5@FFz7dj&:رCD .K3MSX%GQ,er\]^RRrvjM*5*Dn- p8,AAU|_1( ""*W èKHLL>O! P JFfpB!pw""j0ͦn+zvK˥ֆ#jjW /  --{""7[.p8 \.JJJR999`FZV56CĐ!CEEE >\.W|RR8Nv3ڰRDY|@AQ}{]v+ 230RAAE >]3#@+ET@4( &JE ֈ"jK S]@DDTV_Ԛ2DmIϵ DDDU_jRDmDD ]""""">As""j PQ;`x3IENDB`RaySession-0.12.2/manual/fr/images/exemple_ardour_piste.png000066400000000000000000001533541417052567600240010ustar00rootroot00000000000000PNG  IHDRXm} pHYs+ IDATx{|?3%$dSh.JxB-jM% b4h+(gPҢRS=$*DE%Hh\6$1^gGi6{|߯׾`g<9X'K!B!EnB!B+J!B!PE!B!,B!B ynn.-A!BPxE:#k3X"UTTD !B!CL$^ut*X"eX("B!t(0ijx5I:,KXK jB!rE| hLrWG%8J;yrMAuPB!ɓ'ZVɤ$U$eN:4e94&Uzvf!B!J`4e7&[/TYVYDt2p\ի%^B!VtRHVh|t:h4eeed%Y@;I'Ws:rI7rݔHB!B: 2DҥKdf$ɺ V3Lbny<f2x<?E/B!BH<0!RTrӿ[Vٻ`0HVUٳtEfڕ`R?t:0Q^g("B!!o4y^nhhyU*l%N'9N166V쨙&0W 4\ee%hx*i4rq:DQd$1F$I pB!BJ|8NqleZ-9NIH<-$Y@+6%Xf\.@>j@!B W;?arM_B!rut嫜,B!B `fA]0!BP`B!BHE.5+_wK!B:NGxtKog}رcqF #GbǎW3TZ]B!֕W 'Xo{k>ۧO_o۪t:ӕ i&ZFFFFX VTT~c޼yHLLDYYY!s-}!BH\W-u{c۷/m: @ !˲߾kom1@mu]8p ++6‰}B!` > wu2tw`޽xr#Fɓv!I,Ygƍ4XV'rj"///@ev;;ğ'<#K/R֭Cqq1GA}}=v؁#>>8|p}B!B.?< l9r$vޭ`EFF"33ܹsa̚5 )S_ċ/ŢӳgOdddॗ^ /gb„ >*Z\t $IQPP /4ΞyCBB /_ǓO> JV<B!`@UUjkk1`444t$JIII8s SO=ш~Vp!I};T wW_}ɓ'C``X`0t:q)7v ..x!B!]5`#Gn?*Q$I6ǣ8TUUaϞ=6F2 [oŚ5kkq!?73Nzo 'B!BH`M^]7|!C`ذao|#)) 0x`\pv0`Z- %%ŧ^ll,, N>ӧǑ* 'NTʺnt:Ν;q#%%'fA0p@@\\4 ,KXB!B%ffN';Q.ڵk`Bcҥc۶mXh.]2e ?>`4i&=zTi;XTcXp!>իW 8rOuuu?~4nJV###B8^tXhQGvēx M)vH!eXXQQ +u{\kVZpP#K=V+ ӧOWSTxWQSSS1d0k %My<@ Eձ68~Cy$׶|Ӽ,GUK񊢈4̟??d-}ߣ .ktt4L{Vw_r7!J +y?`Z!77 I{7˅$j<'l722GFTT"##a0BΝ;1a̘1| r:8uv111ř3gPWW8tz),ؾ}{} SP]] T'ؘmoߖ\.*++2| v.~ǰ;v,g,4?-Xi=@ߣPb;v uCA!4׫W/ V?Vȵl6wjyyyp8xWqM78UUU>l馛|{ZYYYXz5}WM볦s1c ]Fqkxgx8+vZn_a 6[귥>ԻyjϱjWv ^g8֞| |}B5wXoB!u릴Gv Gvw^xcԩX,N V Á%%%8rA7(++ Z?XłL `8uh`Xp8 ͆… e=zF-*--ԩSg,u1\C%.P__ߦѼLG`B#n` :6\5Kvn7t:v{?G_EEw,%%%Co 'OB:ELv  x޸qp=' 0|TUUh4bӦMسgn݊?ϸx",Kж͛}B$|/_UUOY 㑞ٌ+Vvk׮ł P[[ ^Pp8sN꫰X,5wylڴ q%8~傍iϞ==z4dm9T^uII |KkMK;`l߾ .Çz6}}Bc۶mXh.]XηlFNN|I%!$B:9XV%&&2©jfq$ z^pjZ,$Ieys{|_r}y;h4f\:RqzQ3`2`ZszsO:86 ~FNk-*vmĭOTZ>]ʽ۠WxbqwO_Cwx }1ΜAo{wxGSeE٧q/A0P]r 9v< !B!%^[c HؿeD&&㇯d0p~U_:N%w{էYW ӷZ+tƙ*|)U Sz(ްztN;B!F]3d9IHjSO K2?Y speJol9J6q[ᬭfwIn{qM[DXB!EW;IncNL\:uepid=bPu(&7^Az_R~)P#`xY!,'W)DgOzc5QvH3xsi!B!׏9?or]u˭DDc5ny? pdBD%݌鈿W8+DDc!{ N|k^Y/{h*|h"z$FH3nH^0NDPm@iǀR"C!B.|沢"fXjebpjl$I^n8,&Y#eYޠ"&fvDD&݉NJoMeInJW. VW!pmKn8_M@xk!c% Va_q?n^r?󈏏GiiiX !BJdMd0Ƭ$8Ap5449s rfY*++M&l6唔977o&K`]`ƅq|#F`pݐ$ K,ٳg+`֬Y;pW_JBnn.V^%^#>>8|p~"""ς1^ݻw/۶k.%eO<邔 IDATɄUVѣ~&55'NjE^^j_[lQ //3gDMMM7B!k]K>S?FϞ=7xG` 0jԨuSRRPTT!1੧/c/~xf͂jży*sz|xrp9#??3g DFF"33gF]]Yfaܹ`)3`_}~c08yOr4$%$$`ժUX|91w\̜9&)h?C Aee%V\ R;oVѣvލSN!66/ggϞ@vv6 &bߔb믿N!BH =XF?0^qzJ?ᆱ$Kǎ3f` Z;ch&˕$%%̙3Jbv!Fѯ+V`„ [tԩS vĄرc0`f̘p[sn[髲111>e!I1uTqqq-/2xB!Fnݻw1㣏>رcѫW/1шM6!** C~~>?ŋǴip8PSSj~u}h4裏`Ŋ| x≰b?<ΝO>f֮'gϞ 7V t|DQ{ 8 yx<zxgBS__9s`1c em}Oj8TUUaϞ=6͆}B!v3X^fŋ434ޣr&M5k/ DQģ>ŋl6駟⡇BYYNnscºu_`ԩA9?qqqh4X,!$a߾}Xl p[sj o|9}4,K3ƐҪ'!BHw-g{=HӧOc~CٳSN… f*DGG> {Ȁlʕ+v}.aBAAϟ*eUf'Dmmm!BHw-Gy$/^Ĕ)S0zhwyǧ q8wnݪl צM0i$l6lܸjHII%KZ];ZxסRР\7m4o⫯VUV /?le?0׿Bt\NjUfaΜ9WӸ(Fl6uEwB!붗h "mۆyeo8r~GѣGq٠uٶmRSS1j(رU1 .ĩSpĉx< xT0(vh2p8sۍ::$IB]]mKSrE!Ҳn9ՒӧOǹsp 7o`xQXXEaXf Ν;,_ p૯(~ 1;@rr2N:n:偯|rYYx<8xB!\AGnn.+**bYV, VyI$zvh93Ȳle9R mj5F#jkk}6k+"""|fH%r?󈏏GiiiX !BJdMd0Ƭ$8Ap5449s rfY*++M&l6唔977 ro{}}{QK!B=XB!A("B!B W;Vcƌ>4 Faѣ W^կ~զ] !}QEk8p`oF(} ++ <_9Nr&Dy>h<WKq-xpܼnGVV_7u{wZ5 cCi8ۛ#B!\hAr]ڷo1}tj,].\~jj*&NՊLVF(1:GFvv2noGy$q0#B!\("ץzᅦjСC~FCC2331a|JQPP|bΜ9(,,Ddd$2331{laС5kΝ[jz-;?8y444 ++ v݋=z`8ubcc/⩧c IIIطofΜvј2e {9XVw}sBBVZ˗#>>s̙3F 2Xr%ƙ9QbmnXn ''8qDe˕[:Grq{߿{ac֭~B!%XURRG7xc!IrR>}K7rPTTDDD )) gΜA]]СCxꩧ`4!2N'ϟGEEޅn7N:p8,c_~(..j8piiiTbnWb:v&L3fO>AyyyxΝ-֍ѣH V uZ#qk~!=PE[Mѩ qž={m6ͯ X?M(8{ԼvOpbfA;a9s0|p̘1~믥GVVV^o111~S&9j]Vki9"BH@w^Lqq1bccaXpi>}UY… ~CDVc޽{`0#+**0`hZ@JJJ,*c\\4_9A Iۇe˖aذagt:]JJJq LsT__=z(r->u!B/"+Zر} 0|TUUh4bӦM>TWWcڵX`jkktVUQQ{0Xr%nwc>>oI`;q0l~ԅyhڀڵV zSĬR BP 0mڴc:VէN_^1LiWsh IkSጃB!w%~ 2&2jcVIl ǹ rD,&I6rJJc`}I`۱eW9*h4b̙ذa 6l؀QF]5IEBv'W@J‰7(14O,-ؼL^0p@\tɧ\s; qB!{v hDZZjjj;v hZ9]:\j0zZٍ+W;61h ,_jB!\^䢪 .\ qFedRXի}]ظq#}Qy_k׮Œ%KRB '%ɤ̴=܃͛7ׯGbbbGBt:lٲF޽K.EYYB!׹n7O?4n7#G`޽ӧ2^̙3x4ʕ+׿;`ذa׿>} ++ <jjj\LL fϞɓ'#GĢEB!Bn9o>|/ك!C`…4hPWbbbca0bq!v-܂cǎ) ^޽qqqCm !B!]GM vZڵ &M򻯪ŋ1e|{̧-܂7|gΜAAA?(i~A>pV*#B! Z-܂/QQQJ4bF(ضm͛ۧ޽{_b(3bqĉX.\_{ʃL_xN>B׏D 7xmQQQSctHOOg}VyZ ر#>~ӟ{Qlk^wy'nF]6::-Œ3ILL k`iklB!%XwqG}*|MȲ ӉEn݊;wh4>Ľދ={璾`m߆FA}}=^{5j??zX9׻ѣG#%%vjYYYS8}ohLd/d"B8/R1p!q~I{ K.mW߂ @e|Wxװk.\p!6v; YYYx[lxZ!BHgv VK=@r) M"IRCUDQۇrL>jK. 8YO<rrr#F`pݐ$ K,ٳg1o<"..& ֭Ø1c`4q,Xw)q㐖Պ}8q"\.V+h?1Z,^'KHH8[ږj5}Y0Ơ{nlٲ_~%F_둓r`0 ??^+Yf!""¯=z 66/JKKQPP0޽{+ N!B$JuaZ1tP_ޯJž={pw{?e_dd$2331{laС5kΝ j*[;v,q<3hhh@VVn6ܹSi/::SLs=ՊO׳gOddd ;; Ą |.]lnXn ''8qℲ?)ܷbAee%V\ qf[0ƐUVa刏ܹs1sL0ƠhC kSEa!㩯W`B!\Iz r}+))M'O X1x뭷p#&&Fl-)) gΜA]]Gz ϟGEErvׯHz ISo߾ 9H!330 ~mرc0`f̘evҥKtԩS v fSi:F!r n* Y6liPQQqV$нJ(8\.͟Mޚoz bǡ {QlYYYXz5Dh\C[9s0|p̘1زeKq^Uj*X ]wݥB!\)4Ee;v 6lIIIq…ERQQ@RRR}ňbӧqiX,m%%%8rjjjp7tfs$a߾}Xlr\f3A!Xn[yAxB!\)4Ee,cJXv-,XZzZضm-ZK.LIBAAϟ,ǿi&Y|WOk'XlB!W 򑛛ˊbaV%&&2©jfq$ z^pjZ ,dYeys{:~x{ ׈<}. 3<VPT!Lq0l!z/3LZA/G}$[t:AxbK>] aڴijp:!oڦNQV O!B]W cl"c1f$!q`0H.K4RYYl2d,ȹ~?xABZ b%W@O.3$ uuu-&W@[]]]{VXgmv1dlܸ1dp8BԼM/Ȃ@4O[b#Blt !ױcnx<8x`LB!J,BH9N,[jA!rQE!B!,B!B `B!BHv ֧~O?[nG}o_޽{<mۆ 6 99'۷cƍx'*OZa;nwС>|xѣGK`ԨQ^g3SW ƌt!Y]e4{ӑaÆUWV1džh|&Qbb"~u뭷*u>c8p`XoO1qnI84`2XB!Jzvѷo_9r{E>}|z@jj*Μ9_~@x͛|rX0i$7|ɰcs:8y$۷o1}tj,].\)ӳgO~xꩧ \.\.zdggĉ5j~bĉp\Z˃n?1Z,^K/Rlܸ f͚1b&O IP ( IDATd={zCII ףoƍCZZV+JJJ|K#''刏`@~~>> ^g}1z޽=z[AAAz e|9r$}͛Rd2aݺu3f F#8 P__^09V}-Xhdgg#;;[9M?{=Z6y䑐RSSۍ]h4!e:B-}}C=-[(?ٳgN b͚58y_Ν;ł!Cjn cY Z}}=RSSjbСX~O8;wuuu~cHJJ¾}0sL YFFЀLL0~!6oތurrr{iii?>`0@"##ٳgCŬY0w\rӂ#66sK1eef]xSLѣ?1y着moڴ &Mf0\Z)))XdI_%%%8z(p7gAeYV.dHԧO\.?vG(DFF`0-)) g=,{vم,JF>FښZUHL1VMcK(ߨ\(Z1 ATT²\vٙΰ**9sΙpffݱc0k,fH!`^t ݺu_~(**f[9sPZZ:DDDモo0n8L>vU+WBry)9vJKKQ[[+ i8kljǵ/8p8s|~4]^R{OGDDt+u^СCqATUU!,, ADI`` {n\| ݻ1{l444x}=z7ę3gpbUUU/_={"(((h4(++áCmvGrr2_#""ؔr\h4hhhh /oTVV"55>}:򐛛Q~+J(E˄yqT+#~>EEEZZnoz27s[S,FF \GDDt+u;7mڄ?_qdgg[nENN># 8P-c=۷cժU 6(]__ǏGy/ۓ6oތ}aӦM?kJǓXV;wSNuK,n/**Bdd\ܹsZAAAN8J2qo_S]111opu{ZSZZX!*kK:N>qN(8|0֬Y#?uyߔ+//bQb~7ql}/tdbv}R;!!!rB3tPTA[S: +_]\\A+nM* ѭVy}Xr%$IBCCx;wb޽0ͨzYYz,XදHӇ _v<ʕ++`͚5Z0 K+++Cvv6222PVVٌ=zG޽!#كEOpBTUUh4bmڵkؽ{7,YrȫJ6_-j}:OV#㐟'>c޽̄jŋ}ZUҖ](//G}}=>QgMzzPXX(XVf тjzn׈3:өhL$K*IҎUPP*._բO>nmoFz\"ՒFln/lS 466tzԥj_bt^Wmd2aŊxWG 웷Ұm6zԣl2,Xej8z+7rHLcDX_v\`` DQz-5T=ep;> 0QJAl(t:GmmS8M&p8\E,))%" בUזK][KJSVaEE566ѣk׮!++#GźC.jĚ5k:; """{ ,""""""?aEDDDDD'L Auv:cǎ%uܒz[ӑ>ƈ+aEh 8Pq~mҥ auYzSL{Abۭ=}0`fϞxG //cS]M+6""{ ,'3ЫW/$''g8h4z&߿j=$4巔NدTT= jm*ӖxNꐜ춿PS͡~_"''Gq1b>6F-ǵ~Z؈e,'>|.\iӠzj\~MuF̟?gϞE߾}-[ //رcb„ Baa!TFɓHHHq9p:EV˗1,]3g΄hDZZ.\>}d2a8~8`ԨQ8q"l6VX?< l2*Էgy6 x衇0w\XQ-6ٌ_ h4b/=۷#fPSo1 u%۷/ŋ0Lne=`OYstͣΐDFFb(..Fvvx{G)6"" ݓjjj0j(|l>|8lҦ:A@tt4~zDFF"55# CRR̙͆'|REØ1c 44SNܹsQ]]Çc̙7oA@``[ MA@߾}a]}y0c fL2)))ԩS1n8vuǎؼy3 --   s=7x6 O==k{^ٹsx{Gt}7W}QmAAArۭ͇Ҝrxɓ' @QQG9VGxP;Gϰa5k`Ĉ^5homGsX,>_ł2zΑxtsOQWV+++סгgOZ &Mc۶mxѣGfwٌ_^'77YYYxw IF2\pxOQ__'c3fᅬe˖z)χ~3f`رp\Enqv܉~7nhCyEEYUUшիWynݻZxۊKuu5|I$%%b`ݺup:(++Cvv6222PVV&W=wEOnk׮a׮]Xd pe>rJ{FI& غum&m-hԩSni}IwȐ!)#WpϞ=Xh?,4_؈?ܤ jl6-XV^v(:Ѩs:zA$IR$I$hPB{n8NX|9z>O= ֮]#g}>M6a8rQRR,<#x1yd?/_WXx1TpSݯjѧOԶ^G@@jkk]G@@4 w̙3G3xt.00(ʗ*dŠ+ꫯ"(( ai4fv`l6l^ŋ=[\kN`pm[Kmܖ~4m۶yMB߲:˖- .i4|zyFDD㳠 A&@Ns:5d2eXĒ)88XX,th%Gx8pQzC0l0,Z>{1׿bܸq1c 'i)11׮]O?*^&IG}AϞ='NhR/kҤgQQ]]Hjet:zZ%6۶3퉹-hnݺux衇|ne ۷&0JRM[-PRR>}h4z|Ə~#bȐ!E @dd$.]t+N˜1cjq){G{mt:ݺݎk׮!++啾v#j}GQW%&zCQUU0 aȑqMO۽{7._TNŒ3/_'N`ܹXpj1~x@ff|¤Ir[{}a߾}Y斶ݎuuj q'""K&X6m(W_}l8Nlݺ999r Μ9#8=c6m^={Zonn.222m{JJ ӱ~\|& K.Ebb"m۶>{ァzi!y\#(ʕ+!IdΝ;w^fTUU)&>9>sUUU/t:wӉ{[ZZ1cƴwDDDDDԙ\՚ǧp8PQQѡNg """";W| uf;[``ۗwNk[i6Nc5&Q׹j=z4&LЦk4/ב%""7&XtO0ͷ1"eIIIVNa0so`^o9aaaHJJmѭѼ/zSLiWzn6`u.yšR+no̾裏^hs;DDDmIcƌk( xg<3 ^۩Nk-VAVUBX5-tZ9V8nj|틌;NS嗿%rrrjLxwŗZe[͵gSDDDI5555j[l6 >[ll1eSNŸq?Y>FDGGcÆ W^ٳQ[[d?ıc0uT̝;>|8fΜy!<<'Oo͆m{!VQQAoS~zDFF"55yyyb~1cbԩS8{,L& 6 .]sUq(**j8nڴ ǏGFF|;yf@ZZ  .}ibRkw}' rj}vcڵ(--U7oBBB~9sx71k,[ƣD|;}4{9DDDYgϞE~~>jkkq\nРAEQW^p8544ү]RӮ]󨮮;v f͂lF~PTTCG̙3-%IRW$8.]nݺ)Seݺu@}}=,X1oq0}tڵ .\p744TwGDZycƌAXXBCCa2K|j176ozBTTn>a̙3rhӽ\M欼aaam-`=XwUU4 p!yn8V?r w5/K -h}:.$Iߧ|Zerr2_#""k\ƧZ[_sjU{Zv^jjsv?!D-!22VΝùs`Z]WLLׯEPP`m勋1h ) ^Jdl޼_~%^z6NQqaY#Fp_^^t:a0\)(('PYYikֶ|i歰͕^X=L&XV $$DNȆSJsfXPVVv+LDD$ uyK.۶mCvv6222PVVٌ߈| .\*F^wލ%K? IDAT%%%JEYYY1|NN~m/Vb޽;;|W鈏ǩS|?5#FIPVVplݺmS0nܸ={h"?~vѻwoӧOw(>=ڦ|i:ox1eX,p:p:ػw/233aZqVWlȐ!%DDD?nӅBj 6MVFkvFEh9N= Fc$)XPIvt4VAw8Z}qOm?i4fv\եj򲀀t:2F6MN4mg{t0 nj.-- ۶m?pg t:!kk|j1-_[PP< (m't:,[ ,h%DDԹngAA& P)ME;zN稭uj4db%%%RppdXKrH(Mr?d666z{ԖQ1jWGƳ=4(Ynx 9j86O|$IjSZO-k{y{k9gÆ ۙ\-{n $&&vvDڵkw|u]n;ݬCnn.>Ca61c |g~y˭`fc|ؾ};~_x /`׮]ƫo„ _7O#++ 3fΝ;X7 7|0j(Ĩ! 6 -ƒ>T!Cرc۷OCAE̘1=E7onsCoAEE`BnZmO"""""R%(>,'CxgqFcܸq'OƘ1c[o/ >#y EQ~QW^Ν;mlUNy%I\.Y-lDDDDDK`5:t(nܸ*Iȑ#r{n̟?=[=gΜa~N8~ʕ+G~~>._jlj|ױc0l0q_t 555}~.i&|WΆ֭[+W̙3yZ?H?nӅBj 6MVFkvFEh9N= Fc$)XPIvt4VnAAA$ nz=f3.lN!00555Z-u6ۤTl6ppFl6/8Z}AqqOۉq;> 0QJAl(t:GmmS8M&p8\E,))%" y?uML6zh !99XNצќ j$~_kyu:jR\-/ŭ_[[F8hZ׭oI[[VXki9LTVV*iybΝ8p [o\/1r_yRSS)o7 x71{loCJJ(|[*ODD]S@g@tѣGcҥx7i&8NF,]3g9p:EV˗[_|X`O`l޼cǎlF… !☴ߨQӉJPL555Ϟ=}"<<[lA^^ymۧose_?ͤI_F~~>?D,^"%%'ODBB֯_#Gx'6M>_Z:veee[qTzn߾ݧFQq^}&Xtzq \zOF||<:A懵Sbܹ1sL̛78n7mڄ###ãpL<ol6~ӟw)S %%:u*ƍ?n6lڵkѧƠ73fpaذat}7rRjEEEӧsyoǎؼy3 --  ɓ'w},8v܉hlذ|q+={6jkkꫯė^*sEEApLGU-#22S=oCPPbf Fپ};vZbjMGF^<>c xQ__ 8*wM&?浵kaEfCBB:vLLL Ο?j7K>k,vۯ_?fcAAE^zpxЀ3gJKKQWW|w1| ƍӧc׮]pG=J]r#,,̣P3aaa djuL '{׮]Cii)jkkM eL⋍ř3g>K;.]nݺ:FJ﨨({뫯:z~^rE$ {9& .$Ioh"}D^I5DD0{d!CpDGGCEDEE!""v]>N)]Զ EQ~$F2Dy<͏k۽?HMME||͇R}*(w5Fyy9x>)7Jose_}G[oƱsgT/q. VUlBtt`Z5z^k5(Fti4$I$JAt Kũjӧ#d2aŊxW z9T`` DQeF[l6n{~+ﭯّ󣭔޷jD󀈈5LK2d|A$8z-oڵkn5;kL4wbĘ$LKٿ?ajhh5k:;;JW;wbLDDDw>EO` ,""""""?aEDDDDD'L 0""""""&XDDDDDD~O` ,""""""?aEDDDDD'L 0""""""&XDDDDDD~O` ,""""""?aEDDDDD'L 0""""""&XDDDDDD~O` ,""""""?aEDDDDD'L 0""""""&XDDDDDD~O`I@g@^j ݕ\.aaEw """"""&XDDDDDD~O` ,""""""?aEDDDDD'L 0""""""&XDDDDDD~O` ,""""""?aEDDDDD'Qgjp\~GEHHK\.l6?D>!!!:`Qj/bX|9V^#..1{l?EhK,;`Q+{3gv;z=ݎtp:^kZImBqq1ɓneA Et:\.urr2̙Crrz'_'&X%t?0f͚p8p8#G"11N(bժU|2F#ϟgϢo߾ǖ-[I&/|?~Xx1`ر0aPXXÇ#55HIIAJJ h4bҥ9s&F#RRRpI$$$`8r䈼R&l2L2X`}vX3f@ee*""",pU'bԩ;w.1|p̜9̓ Fvv6֯_H"//۷oG||<֮]R 8:$̙36 O>$BBB\jr Ç1c ;v`4 46m㑑0Lr=SsV˗/WMU"""0L-bbbpy9:vf͚ Ip8PXXtuj{1118{Gbĉ>*I-44cƌAXXBCC[>I#GSn&X%\|={DPPiZ \.h4444 ]ccmzuuun_Vۿ}^HDDD| u VΝԩSjEEEWp%%%%EPP`РA򾚚ȗ :Tĉ 8N 2 … QUUшիWw7n`Νxq XVy_}}=݋LXV\xQuEѣ?>z Qqiyߞ={h"?~}}X,HKKïkTUU,QW%珛tPZfժZݮEQg4uNS Hј$I $)T U]"..NuVE>}ǠC@@F#jkk.j hн{wȏT@cA@pp0l6ǥ^hL&dADDDw~Fa  DQtZFqL&p,XRR"KEEO` ,""""""?aEDDDDD'L 0""""""&XDDDDDD~/& :;@pp6^P N`Q_ZܸqLKI$& UUUQ0"N%[h4#"""j&XDtGjJ&LnєH7DxxDDDDw&XD 6 ,YuGGGw:u*v}[l"I7 11QN6L:`(..FBBt6zt:4Ϸ/.YzlnS"IVZZ ݵ` =z4֭[x91Xr|ȑ#; ##oz ҥKF#/"22 ,sQ;=͛шtL<+VC=cDD6l؀PվY^[M2@^"HDDDw&XDƍz*N>x7@7/!:u*2220o<|g9sq-_oڴ ("##޽;L w._qAncƌ8r[V˗/Geej_.\q!"""ED픐r<ðlHHHC܎Q]] 8vf͚K Qիٳk9I<;M`` V>""" ,v0L2d8h(DDDniZ\.z^=F2,Kg@DDD7LG#GqFy(O~?\VTTSd2n#..ׯ_G]]$IBHHЀCt:a0PWW"KZpjIp|Ncq뾫WW^9""""cE=֮]/ |'Xp!`4zj@}}=݋LXV\x r={`ѢE8~8 l6#''qZ,׿݉$IBmm-Z-DQhcB""""5LK< IDAT!55cիW1c L&yyy8x .7b֭ENYYYn>3/ln꫊q޸q/G޸\.G?j8kzR`j]hh|"HDDDw&XD~ԣG 8n].b|ժ:ע(/UgkZ2Lp8E#""""j&XD~4d<T+IEDDDw&XD~~߿øxߪEDDDw~0u*oTlڏ&N5A ?žn9DO` ,""""""?aEDDDDD'L 0""""""~Qt:r BgB0V ^V2L0 Q'?QQ[[2l6wvH ADDDD](j Ĝ9s I~o׿A `XP]]٧-%珛tPZfժZݮEQg4uNS Hј$I $)T U]"..NuVE>}P\\|":>#3s0g,[á;Puu5p8:\$I(--<СzQ T `E^9jkki2DX,bII,Y,iRzzԲ>`uq 0[7,""".N$̙3NgBw0IXir~1""""$IBfffgAw&Xoy $!%%K.p_ܴ{)Z-Ə[:}Vѣ1at~BBBnk{J~}Ç#>>Aնzܦh:,wɓݶ 9rd'EtiӰ{nѣ裏UK,ARRo߾n V_|W˱zj$$$tqqqߏٳg)ZDGG6 XdmmD,_˗/NJ+ЧOq6 CRRΟ?j;m9ZcǎرcUKn3F{ _5[^G@QtzCr)&iiiHJJ¿/[!!!֭4 L&p8ja4ЀK.a~:`08s vЭ[7\z8L&v"44W\ftW^Uum w9snC#00~vSll,>J ш̞=|'X`?BaɁ$IXd 6lOKY /@eȲ|>}˗/M7JYaH>q";;ǹs0qDP}֬Y8pm7o>C̙3Gu_AAΜ9}C8E</_*hDqqh8r|IAev.^SNj*7| ZeBc=Xt:|WAٳg!2jjjPTTޯ_?=T>S#</~ W]u|6(:T9p8 FhDaa2saL<9XeY۽^KJJ­ފ]")) z,xW0h L8w}7.]ڨIgq{Le_|EFR9z qqq^2\_"HDm}~ԩS1vR/.X}>ׯM7݄O>$/ɪR x'&&Il2|ذa˗k߾}i7EsꫯFLL\GSnovꗽ pq 0k,_@ݛ[/o>(233{RPVVoVy3mֳxFC|c4hjjj)0 8E(vF#FȌFr7sСtl6[;^o0a<쳸[0p@2رc1rH<~lHKKȑ#={ "z0@eDII v{E7ɤR""_3g_dBll,{=9r$(P7Ҿm6\/_@bΝx饗`2PZZpDXp!z IO?)m߾˗/ѣGG)n>6l|A`0;vP\b9#''K,lF\\lقQ&~-rrrl2֬YӬqصk>F*¿yYx+L&biiidRiZF%IFkN@J2Ȳ/r,˟6YP1tЀ}*KF QLh R @ףQIZ̛WTHLLĕ+W~ՓjrNS"ySZ^BYߗ|Z\AX,X\.. (6%" Cs+NJxTWW79߶mQhXV$''+}MfjY.-6 A"EaZ*i0$NIIJJJx9%%EȐ/^ܨq)DviN>(//Y8,TmmCɒ$YyҰsEDMq\je9 &L@߾}qW׿5;ndYFUUrfͧ/g4-S$7|m?3j_n3 `q Qn7nV<ܹ3!,˘;w2eȗ.-;XDDDDMصkv0T4~)|Qeʕ+ E֎`y>E`E1A 2;W͛NZG,(ŕʈcXr2;{Vb \.՝ e)L;QxvTUU!>>7|)\., z}e-""""b: $;Q(ZtpӦ""""r:7z  """"" vB,"""""a(D"""""" vB,"""""`E1I*JnJ( :1Qt:j;uYQ$ @NQHÁjvFE& IhjYP$ VfIII wHm,(KV,3%t:aX(HQ>! RRRP^^u> @R"%j*$''p:/V GhZW(:^˗/ 1`(ƹDG '^^ZQJw::^ ^'a($ ~5Luv Jw:2Ax SPx`_T(6lXh$'RZGe6Jاh&", v6MY"Գ4ys\kmȑ6l򣧕شi\.WjcƌAnn.N{=L&l/K 4 2220zhvl۶ .]c=?ZPPn5 C QVaOZ"UW]/6y1ɲ$&&Be 'b„ Ej& K.㤤$^8}tá%"ƏرcGԗuZ$ 1N ^^ZH0,^+ ))QۅJs[sLt7o HLLF`UT~ϭ4(B$hF Adfe={*\.\bJNCNNjkkn w}76os{1"==999X8L4 Z.,˰Z=z4A'PSS D߾}xbTTTqҰh4p^uFӢNXt-}ϟcĉĺuB/ꂆA ~H8FEdff@];/ Xu!2$IFUUi$ t$ Jkn 66vzj]tQVVV*wV_n+@BBAnGmm-kZb1K $&&5Mk8555FR8~8{Be 2B\$_ZVO?c=>}CV Þ={p9uZ;v;v,uΝþ} Iƌ]">>{U#u,. z+L&N8dyyydu 7nyTVV*{Fz=pqdffbڵ8x nFL:U)_֬Ys!99YYYRҿ⋘3gz=qIk׮ѣGcƌɓp8`Xzjl6%ݻc՘={6\ c_Ă 0NO,ӦMĕ+W< Crr26mڄ={4g뮻PQQ\ >͋|={`п9aF׮]NOYY jjj "m].jkk n. . ]tFj,Z:Y^lBnݠjNel6t :p\9_zF$IB^^:\p$aȐ!ؼy34sW_'| V 'O/ږwJ#;j0L7\Sm) .(.] )) @]'KF|w={6)w3fܹsQUUÇcΜ9?>ANS ׯ֭[7|}1{laʂjŌ30i$|J^& V۹u 2.]瑗#FoP73~ݺuS 99 6wEjj*͛ݻw{ҭ[7L6 aX_ JAZZ:tMظq#pM7!66(//W>+~j*snKSoT*!Cp7cxWQRRY}veшbTUU9'|RnG~~>ԩSl޽;I0m4@=zkܸq(//ǨQ`X0n8ϠA2eMq88~8ٳHLLl̀PPP8t&Ou|_|hDQQ=rzgN'Oz 2SD?<`ڴin8rn7 s{a[nJPEll9YѣG1m4c޽A+u sbccѭ[7vmvy/~a/dZV7nҥKQQQ^^{ P[[;w⥗^dBiiNUUnvL6 )))x뭷t:a6a,YfqqqغuHKJJ +2n8^ڵ ؼylFii2ŋغu+V\rb~֥Kcʕ0LMvlˑe˖)y͚5ϳxݻ߆dBNNy޲eK&;;ۍ]va„ ۷7Yu¿yYx+L&biiidRiZF%IFkN@J2Ȳ/r,˟6(Oc:C|_E'Nhjgu<^5jFLr8p\j2QznZVV-TըQVl/"Zg3Rꇧs/^OzOl+dR,rQ?Mll23VY!!!A9m'>>^/lQUI8MOeA(f$ISfz;_{t:X<{qƌػw/Ο?3n$Gm)XV$''+׫/(* 45]k8<ӻv{PS<7|M1^[F`ի111>sr\-Y熟bQ }j5T*oy~W0s̀9>>^Y*[a6tyٳU1(dA`$@FqXVJr pSRR9>>^NII322ŋ7jLqgFg](k lEpw^ 1Ot:t:_bh`x~dz2͍װSSls;_z]QO sL~0L^1&%%h4tŋ:7%=yږ:(llnoG1_KGrL3n %%%p::utz mu/Ou#X`p%7`iɹ6MGx~]wAw_#/ϏښÇ,p \.?* رcGv:8tP8vB`Νޥ%"jn_wasNܹMaەgZ,(;QՒޢ΁%x S0But)\(z敨Dõ,(R`Me;XDQJ$Ne9E'A`0NC4u`E)AjYBUUp8Z^˗CQ>kE1ε'>R8 GVK`: ;XDQ%QhDa ఃEA`AI".QG$8|Z$CBBBCh8"bD5鐙mPdh4?~|à ;XuDQ<^{ Vk1{ll,^xᅰꫯb͚5ʿKyk׮Xl`ԩXjVZիWo߾A埖`ASyE Q1~x?>*{F?cfiӦ8 ?-+:r9ʸ^}Us=^C`iZL>KԲ.\8E̙3{555joxh48NEQ$I>(O͆Yf5+m}bccb4zoơCoYYYp:Gmm\.%Yfli4A<kQ@ff&Kniku-AгgOtrDT?[V\iuݐ$)`> @|C-˚گ'Cÿ[r ?* ƍÁpiuڻ(__#VT^(2ErY.`QTILLĨQOp8u1uTW׬YsAc…(,,D~M6aϞ=1c`p8X,Xz5QFᥗ^Zŋ~z={/"̙x޽;V^ٳgʕ+>GƊ+J3֥Kw ؽ{7Eĉزe pqdffbڵ:cƌit:qxaX6g}s@#??gϞPh߿? Y]/7ߌ[n&߿SLQWm݆;1Nl6mBYY|AX7,S<7㮻BEErss1|p̛7z^)ZZۯ''NO>|#..* K.EuuuhT>z>PTxٍ:;(_e{}}aСx嗃#˺paJ>}pTUU5z/)) 3fܹsQUUÇcΜ9?>A@ZZ6l؀k"55Þ={ӧ#++ V3fIǭފ塰AMki ш fX|9a߾}T 6 gϞ[ow(N<шN[9,[n9(++SĮGRR^?C8q"fssڊk3gδW8ME{رcꫯ JNN=܃X,8qwr#PJ_o>۶m X{ʔٳgg׮]6m{9X,~sW (e,{s)˖,Y,kj׭[wy&L̙3Ojb֬YpfNNW\>PopM7;g}Y!2룲R>͛>4]o6n6̜9O=V+fϞn;v֭[qFE'OOG+…`QTi8 >шbu\uUP7ҕ 8{,t颤!IMz={D>}o&Mk_C,8xsOnn.;cǎ@]뫯R}W;`ȑx饗b֬Yׯߩ,/ޠAU{=zo߾A(ٌ 80Lʠ@>t萒.P(}0*dYۛh4P>?'h, f`ەFŋq)XV?-<;뮻н{w=ш"hXG* pI/\tpp]wᡇBRR'u"Hԉ;wW_}5bbb=3ovCRn{* f~gjFJF(9hM<{Mh4{ymWPP<w̝;_=x |Of5:v`߫T*5: 4555ʴT Fw{髯رcaٔ(ʠ7{Oa/޽{7PW͛7#GO<={n~(lZK-ᣏ>o~:u =ᩣ|M7 0fqNEPֵ7`QT1L(**Œ3VQT(((h` :.]j@s 55UoQQL&AY믿C=3mkSǏW*uVmah4$ 믿#FN'bccoqq1ӕ}ϣ={l:O^1x`FF <ˁ0l01z/Pt) 8111 tʽoN>OIIW S|w*ZKۡj1rH@~~~L8p ?cǎzjU~:BY8EQ/ fΜ_& xplܸK.EEEz=^{Vl6cÆ Xd f3uV$&& Xx1F<%myyyIIIAvv6qTTT^P@FFϰaرcW#GĔ)S`6ѭ[7۷cŊ8r>裀q\x[nʕ+Q^^Z,_+#''oٲ|nڵ &LPw75UvpݍFA/^_|^xeee())QF#{Gb߬c ϶m۰rJ\|oeĈJY͛7Ӻ\VV(0 >Th4bj rϪ~> PTGuur(TV+H||ς?={ Y| Rh4>G-)oN>ZJBbb".Ҳ$ڢ>h:Sdz Xօ(dA`$@FqXVJr pSRR9>>^NII322ŋ7H9EQr\Mv3`6i[{v7yLNgãSH|}V $Iyغ4#n2rL(}s |&L'OtƱc|mMY[_\mQE)rH>sj_ %v Kƭ Q;w;5Luv(*ڵ v wDɰEx'(4B]f(r>` i'R B% >R> GNJ5MC!t:׏rDm5e]p(JvTWW7=Ţh+Q{b}@%Zʺ}$"t:X PHHHN w8XP{,(:}!GDDMc}@:"HDDDDD"`;XDDDDDD!QEDDDDD"`;XDDDDDD!QEDDDDD"`;XDDDDDD!QEDDDDD"`;XDDDDDD!wDM9uDQ wDDDDDMb"FQP"5tp@ĉ((|(D"""""" vB,"""""a(D"""""" vB,"""""a(D"""""" vB,"""""a(D"""""" vB,"""""a(D 8NnPENZ(;"Nu8Q6;XtB$h4hZT<$ VfIII wHDDp@`I "t:@0GD 0 HIIAyyyD.DDp@`AjY( z=._D'@nGMk}%,V;/Q2V;W8z(..Fiii;GDʚ`MDbp.--?e˖rsd.:@u8QCQ VBBBk/EEEx}F7+OQ1vXu]HLLD|||(Bv"bD5-@ >#G yޑrZ~+m5\;;`xW+`…0-'66/wZZ%)) /|j1}fy}aСr zꅧ~:R;EǏ""`IIIXnzEJKO׮]1m4:n 4=]N]Hkې-=޽{cԩHMMŤI[z]=҆Cvbcc`<ϑըh|h4"6 fRޫ k*_hՒ@i;v,N8f CĶm۰w^hڟ(DII JJJd'!Qx[ҶWh4ArSoGyjKrJizb<nꕗnwl&հW5cwV\kע@y?u0o0bg?&R@#GSd6q7bԩ/YΝC.] @cصk^|E̙3<RSSh"8q[lQ7_^ Crr26mڄ={xٽ{w^gncǎŋ/  ''ɻ; /2n)Sлwo|#..* K.Euuu\9@G>}SOy2eJW{bر_"EwAQP[[r$%%aƌ;w.0|p̙3ǰapYz111/;Ē%KAy/P -- 6lڵky5RL&ZoC KpyaĈo}w֭ظq#`ѢEHOOǕ?c9oN:th4%X}]Xv݌OBPPP3g+"" ate٫mQYY-͛絝 6;?r"++ V=&Nm۶h492[okG%&&ݷ'o}񗕕)?6O[,Leχ,>Geɓ~GvWs>/4]o6n6̜9O=V+fϞnnk9|K6 b?D^^O!ҥK!2N>˗C$F VIDAT @֓O>84ix ɓ'W|eY@nn.ٳҥKʔX t 0fqt޽mc4hjjj)0 F(|555vjfV)YZT*ʼ:pl~%Õ+W0w\\x'_ロ/-- $5G՜Y_O?=ϧ~p߾>_+P(mGZ+b𧠠F0tP\t 6 $믿#F4Jt:}.(` {ӣGƁ{)vލ[no8vѫWW\\h4h4bʊMDD-, GZ+ٳ'f3PTTԬi?xQWQ6HOOWFI<#m@+Xf)))~%(_ϫ-lɱdI^"z˗rlܸK.EEEz=^{5#0ef$''c͍o߾˗/ѣGGoRRRMn?n8^ڵ ؼyÇcΆ$I駟#E6ۍ]va„ W_w:q"*P+#''˖-Sk֬bΝx饗`6QZZZ%۱b 9rׯGNN,Yٌ8lٲ}1~9rҎ֭>CL&oo[nʕ+Q^^Z,_`)˂:f|H0笹BgKڐ-ogLkFy\#R@¿yYx+L&biiidRiZF%IFkN@J2Ȳ/r,˟G,9j4b s>|e0|u\!"jErr2ϵT Ο?={,>""֜:`0W^̙3-t:$I&i^QTGuuuPCCٷmj5zWm\ӒvT0ˆZyE-mCdh4x嗱h"APA,A,$h4TTN 9wJJTRR")))rFFxF'Í`yn_<2灆,iCÖeYY:z֭ӕE<-=W԰"IDK~׎ fq\ۖm~&L@nniI;*eC"ϖ![_i0u]-[4!m8Dz "8)322p57`FϟǺuw},"""ؽ{7WjOEzq"΄u8Q6P[z9Q(""j{É"O$'9NQi$IBee%L&v트p,""""j |"&Dd<[X,mQبT*İc… m29>>>9EDDDDT `u|\x62'"""" 1vX9//)))M^""""",j ˢ,^XȐu1CJJ!/^g\w(D;XDDDDD͔~zR^ҥK[w~ZGK/+ʿ'i,;XDDDDD4zh8qcǎU^3_Z z=.\~O?4> b[gC@!Qcƌcܹrl2<nկt:!I|M?ݺuó> WӧgϞ|5j.8X,T*~!//cǎ{gÇ{+ɓ`c駟0w\O>͛8T*X555-> Q3˸x"1b߿@4An %,HKKÉ'PYY 8z(f͚^ﵝB$L2pWt*رg5WCF|ꪫAe8.\SNpEǷ)DDDDD^ |7ׯ$IB^t"ɲ Ip4>Jre Z#ԜtMYv-,w=W-=,"""" 5 ƍdY7ߌm۶)׿5 jjj˗/fAe$$$@nkڇDLL jkkQTT|f:oZ6`5?-`[n;W_}yڕ+Wi&OBee%bccoٵk/_ٌӧO{uvv܉Kرcذa>,Zeee0 ~!`fg7ʿ)j*36H{Bnn`2ɤݻpe1&&FA-IFj%I&7c [Uc] O"eA4(*,!; RGlI:Uov6co?CPsG:1GUŸL[H~'9,K(DU{{UU~TZ+@.//%z]믿iƘZk?cf!+kiZU],$|AGQF:lu]9>>oV>~x½J^U$(>}zzsXMNw}'o߾yc;Dݻwݻ}O{ Xv`cWk=XxyDܰTUbyy!dF{1ƨs0c$Kc,˃\oR׵_wUx=)R޼y#L}O0He)rӹceUYٶ-)ZY;1FCemǴ@GXiV1?M W۶"rdYkU䟬 ,ȓVQfY9bb=DkRqhku]mz-RXN:E,M1Zj]LN"`xMn2Lg9fk8d2Y>^݃_m!W#mj(,K 6:;֮N(:kmLQx}L㱎F#އUUNSfzuuls9c,F1:v+fǓDáF#zvv`۪JG:ik186>8B1b۶((Oyukz2 S4s:5˲f'mj,\s*"2N{ګ;d<*R~CAD<۶m ^T۶>VDZ},"fY~?8 d=I,Z?I{꺎EQc{kmfm>z^:z[V_Whzh4(6M~ADZcϲQպO /@U,c~ )-6l3믿lfNNNi˲tr}Yq/1,ˎD"YkmYkuUW?6p{ \:Hz 1&+hTuYE۶W3%ںW_}p8>޳^,!\\\آ(\4)HMӔY1 !X2\|)`?(s9/%v'9@85BHimۦ(:XZCZuT[;ŅRUe."Y4.2BYU5!T׳[ T1F SQAnqy,\=0N~<ED<.eYuh1Fkm+"ZkDxmEaRZ=XjՖ>*UX,$˲xo.rySG=50륂߿7Mz.ssMآ(lLєeiVCz:ZZߋMt>,prrviuqqa fYڶ5u]ۣ#BHխUU._ΤZo}C9͚51߾mɉ,^<<hkǁЯyRqhNfMԯWʕظ~-'a˦|R @u(aCѸQCj5Æ f?8po,k6Yj%L9rp?ϴ*W,ˎ2ݿk'.YHJNfEpuqa!ٷ?F 7%M5ǧ23Ab <}ʊ'@|HHH 1{Q~=@`htЎcٴe w7)}^ /@j_0p@?lƕٝS&ѫO_ƍɓX{< E8OJoۆUkrm> O>ՕLڵklM4fԯiڢC JWW jVzмY~Ys'͙EQ/^dJ+ЮMk;Of` 1!!#ₐ aaϗ0&L^mF׭Kbb"2"EGףT)0h0:o}MM%>c&^X'~q!NлWO&CN_jm5!!!˼j<{ܸ޴B!ϰ} zₐ%5mLpp0',<|` TJP`̞;_ҡ}[^Ǝw2pP< f>g󈋋#113agO%M3?<< 6oeۮC'*V#2y"0ٿuoܹ1l 7^lٺO>M^x)ӼR?_>/?<ȟ?u@Ye .fxy}6{[.ƠٳwT8q$[ 99nݾpRRcnjҥ<{5HJz=K`0w~|cܹRkeY'ORz56iL|\52۽gǏe1:|J%?/c@9@tt4m̧~B9w<$%%C+&Ou")W,˖GU0yL2 ۿhۦ!!/UW?~7(_lϨD O?lܛk~e_(A\̨ODEEqEV+Wk xxбC{ZhƋ?GB^]9p5kTg@j{ 1sμT*TJBBK~^ΝΌ9N#GUڍ;ڷϷzHNN8y` SN7I7>.F ء\a3zxĴ'pؤk``PyjkkkT*[Lu3jl)X3o\v;vh @qǦ BFIw\.ގ(++5քGd:[VXؠ鈋OUc,!uzL&NTIIIƚH$888dr6f+VVHte&vO͕ڵ9uL|O<35eOevٍ\~ B.%''U<%%/Bm5vr9 .̬izp aaagT׬z܇PV2_ZAA9NNqA7rVZcv_N{9% B:eN ,A\![ϢQ7)f^G .e#S!d2) VbJv)R$ Ri>DrrJ^W& " oF"Pr%Ο;FZ55fܻ.cBv,%䲜 '<"*-綶-Z .RPA<݁'/>zy:-+|A\x)gtBE)^[y" oQ?֭g(_/Bx sv^TʝQ*X9V+)T {{ǎe?-YC+ZR͛7 qىÆRk5ǘ0i zujӳ{7rkg̤D9GGG66<H7ػw:w'Opvvb`~T1j++ t k׭af4h܌.QfM<|H⯗2kݪ%&DEE1o,J*iOTwc z=QQQDEEгG7l_ <"k׮S@{uv.\>.&&#%%Nݫ'ǎ@Et( 1qM)]%7n+텃YŶY`.?.Zl$naooOѢEPՄ>g֭[-ZH}y_򍎎W= g̝q͚ŋ(V(NNDEEjBTRv-J%IIIgX[[Sqtt`0Uڛk׮c0hЏȨ(VYg|ozĐa#*ŏ pEtio8 j>Wztiovۯ[[2r0FΗfX7 눋3;ʕ\zBkcCLpܻw‰R @cG˪ՄGDP7>2qPiP/gNBBq˕oRlڼ |TT&'2"PX[Yqe'\rMS?˸`!ϞYxٖ*>>PcvH6sjTfIkmlprrDPP.Dl\Ex̽{POX!#Jߓ W] V Ν {he?{'.d+mZc.&۽ 4ytjNJJNfƷ=j}{T*Xq[48997J{ꉉ|3sCgnHӟ!2BVyk/]:zDڅv}{qMZϿ2Y`0pl פlK-`0pŃ`!L}{ >.ZfƦ>'=>#S:eN΄T*=w>O>ŧr%2k7T$N:KT*+f2+Lio<}JTTujbܘQPȹuҊ%Ko QQ5hmlM2 {bbbIXSh3gZ.^ύINي?VVT*mhXv#njK7,R֖Ȩ(^򓜜lT*ޞtHrD=9T(tş \Z[mɭ(Μ=`@&" 8;ۿbS3%d2L@.mtz= @"A&z#b8Ex=}zAybb2e2ӏ )\ǎ3o3巭ܥ=Ro[7ÿO\xdl݆N#99/lվ57fz㾂 P:}bE+WZ'z%&&rlmm(@\Hf z=N`l?3;~߉o*zuԭSc)X E<=9UQ-ڵAA\||iJDRQ@l.]|K="E<8p`u;VK.Q_>sֽ%ƈc;fƚ?vaæy?)ص7ٵ{/O>59z,']ĢR7q/^fftt4VaO?BDD$[nUdd$ !%%={QP!c? 88WWWN:mO?1jp~߾66Z+VfZWAdTrаpFe=Sx= @tt4ѽ[W?q2]?7zrcbR[1{tC,Qzt̙\z- %7H$^Ae8lAP(k++T*o\P(rz9* ֆ(_^ͫR)$&&4XnR_BQQ$ j\.G:釶 X$ oA(A, LqA & A\ .`DA`" X?;EƩlKA'M– Ĭ6#AܩlB"̎&!g[1fop£ o(o( bL\ .`DA`"Ο? {JqA & A\ ڊ={!HuQA2$xZרJzEA[2 6d2j5RiRTXYYgmm\5 :$$vmے`rR4r, B^xkA|=|e'?}.*Tukڵ3_^=<Į]9u 6 Vf''g ,سwOd:p4[n?*g^~;Odse㇍˗N<ŏhxxx@HHݣeV+WӧOAٲ1 t:{Un0Xlqc.T8T!x"]디pEhܸ w!4,ffرxz#X;6oތ+z!C9z=ڷ?[nS|=e L4N:3g^e̗/>G*NZ`dr yqlWjUڷ@:fZ`~OʕY{}zW˜6u*cܸ̘1.]NceJڶm˖SɹhZR` ((g1y!{A+)DLFagggB g;w wnb޽V\N©C 8Ŋ@ӱo^O"66gfQ}#09?~x1sN!&:ZͰC9w/XD"%6&cǎI=g@*W!88GGf(n3klZjT*k=m6 B$%>@ݻlޞbbb2=NTbooOddٞBAxx8z$}DBxxh4tmggg!;Ο?O} -%~Hڹ:_%$%%M?..89:NArGqA &?@ .`DA`" X\񤧷8/"ciS_ Q(A_'lHI ;'A, LqA & A\ .`DA`E!r*VFk`AH^flZ*AxE=ꂋ3'NG&|ֆWb x"`]Zg"d}A<D mz# A\ .`D1*.۔# uj *dvW)VA*]^^XlɶS0n̨tח*ly:վS2ZW{~^X0wAnU ggt۫V9^ԭSj_|q_cmmmr|,P e21&Aӳ0sgS*|7oFR*}Rɶ)_O`|Rv{{;lo)ҩc{&LJhX[˧%(Z[K?_>7^2Dl*}l+ZS'OE&,\eK1fpV^}?0mD 0ϗQÇ IyEp}5s-*WTZ&..lVV$$&b0sR\|4 111J/3* ʈF!..y@bbbi( r9@jMGȘq 0= qqPb0@RR\% Vj5q/~e5f{2+)J 9ogsr92D ԪjL5kژSptk4IIIVZdUGBT*=w #ԯ[+WVV|3m2Ϝ.֣j:ٞC2>._s/jnQJ%ٻ~~,Xq{~$j OZ5 eӸ~ŋc89:o;vΔIɟ/Jvd;ѫVarR[={tڅr>^=!JX[}N.[An]qrrdYc x0TT"ɑJ,ZCQdI?Musse֌i?pF h9w"[ng~j='O9dJQ(̘5/>>Fc|l 5A/>ǠYsy1/^rԮIoo#"hӪ%bkۚ-LLlS{XkcCLعk cx l3n۶Weҹxnsf~ÎЪEsTjW\co[W.II( }=Gǿ=Յ-*U~}ppG.3{@ُ0x`?TJz׹9JbȠTAL1ߜ/) jתA(2f+U3ԨQ T?.6 W) ϨyyΏ /gܗ¦L.[q;|xzzrYc? *H&ͨS6nbη3QHRL@@15yʴ) 8v߆iֲ 5Wn)8y* 7c=ӏ-?q˖g3\q~hۡzuϰR$[&ўqGYnߑ1'0t&ݻhФ9~( ZmO_UOhӎNCy26c l۞2e8n߽C˶O(S 0ЩC; xxЦ4mن۶3uDT*1=LIԨ^  `yTL~tOv.ƏevZEvlBqusJ%RIߛȟ?vhӎf- IѭҶcgvѻgw?.;,GZȑGqrrd1| 4I;ƫ/˕{޴l۞M[үO\ձKh4lӞۑLd4}gx!~]R%?$%%f(TӦLdYܾs'c?Οŋѝ˗5n|ٗ|1Οw;o% 7n"<SXѢ$%&L ;Νeu6jj`OPp8::ameMdd$ܽ{Gga0@ҥQ*<}*} &**ž$&&BeX",YRRtG`o;0Rgy] <":wa0i'Nm`/ByRӫY:nD||ع NӃeMLL`?5WϿΣYؓ7nR1?VʆM[^WM[M~+J66or(_7l*U?xNՍX\\\2LOe=~́CG o"<"kkk㷒]{QvMvGڵط )))899@=q^3u:QQQ&S{d1psLVMى y|Dڡ/''Gȗ͸ H韧`OpCxxxߞ$̟BCðE&R>dŊI ))#CC__ERe!qr4mܐC43gDDDĐKzzZcJū^,ie+"#qqv2svvv2 DY[tYrtpyY[[C^o2*Y!v*\BѶuKlmt@"TEDEETl~cdD^3f+W|p8?z'U}hҸ!7nK6;;[5sù}.?-1ӭGo""#sTs.0e nݾ >OFo4{̞h׶ J?HeR.^ȓ'OymZR7mx{{Xmll΅ 8vbERVM|nnf+FvY/Ϩ}HJJ"e]ɇOtt4'O_^<}p)1 TJ>|ijgԱq_Fۜ,8p-7CYN-dRi~a|ףpm 4{3ҬicI&R=͚fӗiHRZhƉSiLL TJƦyĐ?>gRx1|*W4ggge9GؾZ o$9Ruc.?;wɉҥ9v$O>c&s3J{߸v:#ݭ۷ywwl}' }ݿhBCص7oD/;2bhL4M}&6_ǩӧM9z,^^8w;ma+V,]>!!!=~}{{o~Xf*U*ӣ[ fٿx ׬dʟ\9UWv˧Te׳c^e+lX˖ k7{VV &LJغ|iegn,[ alް_W}֌8%[?[X8.׬dMKʊֲn LfGlڼ|j֮Z>0uH$,^`(Q5+eܿCN[My1u@Ϝňٲa-;nOk5YɪK$00 Vl+5W0=*UޠO7&11:#FE(+~߷mbۙ1mJiϜ=… ѲES{lVVj2q퉉%99~ rH\Ws$ d8 K*bgkk2>jNZlmmIII8v2١KI1vvlM#˫77֭^Az PTHts% DGǘ}*sڛ^2sJFcCdTzJ$6[8s6gC/2 {{{!d_ٻ'W7w㷼jv\oFYi/&` "3̭̩7 Xz4wfuCPN~$@i02\:'cbbkȠp')9Et:BCCs|n56"r]N9SxCA!/^Юr}YF xmv{C!CAA<DG\Mb6AA<bqqv1y B^pqq!:*c \Z۷z MQQQ9{LE: 1"BH$ȤWrD d$W o"`DA`" X0A, LqA & A\ .`DA`" X0A,xQZcJ$) LLfOՓeTXY< EEEsԉ-G >?yd=b4by BUV%(8`?.8s\=-U GI@QC;ֆR.? Ve{gDq=$\l,"9rߜ" +"7iKA,'cB - LKٸ,'!e}[e sW"<]{s 17_ \x1cXZgϟԮMڵ1r,ky؆NN5 JŪ5u6H%|P8m[FL-aN۫qq*[=r\Δy9y䜋3**Ļ+JΞCJJ GJ]IDAT*1p@taȑ4oт={0o\j?T˛6l[B7z˕5ٯYdZŇស… =F"h2L#9UZ2 !)U*͝KBRÆ'%%%[nͮ]8{q`DTRZtH$&M7|TWUkL:cl[G8|$ 9,[B&Xj+^k\Bo+%7.Q8ׯͰ,ڶfˆuXKx|"Tfu|`nw »FR?oqq>"3-III\qҥ1|8nnn?^'eaw,ɭ[/\`i/G&ݺužLّ}ȡCٻuB.+ jըF=iٶ=7mlW*~.JAT)}U}*ӤzӪ]GvcF$;͛5ct=ₐC{iMR`|5r$)i.J{ V,,ת/"AZ^6.Ҧmc4HヘX>QQ**B*ihd}pMc.r].$̜ap]%p:9eYFVV㑽jzzz| $ɵo 庵HLHptUVq pvt 9)rtBO }0ϯ*j̵jC1ohԩS !sXbHho 4s9Wbĉعc'6WUfCddmֺcccٌNǡlxbhZ1s UY'ݰ kVJIjX]?-q mgtg~wOF3=aplu$/~MM͊cLDCt1^}Xhm뇔)))ȑ~z̚5 q4=Ƣ"|x1:4,y܄~%MXч(-+W֜?n<2eM< ; !<\7J=U({vpmQQRvBcnFhD\\VXpA~~>, fܶ68|f 233cƉ2^% xk{ع9/]8QfRVZ'qe,657cNl}!=?NTC g ^-3)x`L䬇|OMHODT>3V٫>+((؎-ЅFh|L۴š`f<z0?y>K_#oV/Gme&᭽a~<u/ řӱb|U~8lį%Ge>ן+~&rƐMZ-:ִ Ӹ_qMIIAeUW{}Z~ pz 1ڽ$Itp8^K`Nw˧{&K7b8݃n_=W!xX @{{˲ >=R"ؙ=d?P-)0ϫ#ދ'K LL8Ew%8&1C <@: hLF ^oou8Xގ -"<Nx76)ADdlŸ)3G+s7$߅&' $}Pc]q:>Bx$NH@?>@ z<&NHiFCC8\'"R1&q""c'"R1&q""c'"R1&q""c'"R1&q""c'"R1&q""c'"RѻbݲHIENDB`RaySession-0.12.2/manual/fr/images/exemple_patchbay.png000066400000000000000000003735031417052567600230740ustar00rootroot00000000000000PNG  IHDR3= pHYs+ IDATxwxTU8sL&3ɤ^nP~W@,"ʪJQcQ $LʤLzaHcd~y|{9Ix瞃; -Y]k.c`JJK=݅#9)],`<70 G`<717qBP(gr`qh0[C:̜1#5%e`l +D"P{{@Ooh4B$Ɏǎٻ1k׬>qʁ65ӧOCyv]]]gk׬.,Z|PZ[A 8eKGEG#jy( IA QT>gXJ%I<O 5iD$1 =k֎1w?p9N\Ii /a0l6[.;17͜lG}_Jn8xPTe+*+}I]]ݚu!Z~7͟7+L&BH}iOZKdn^}BSNǎ9cӾصjD^[h=줉Lfm " KNN'N㏹Ycv}豁^5\bn0D~QѶ!$E"ՓlX'de!ZZ[m;{&/ &9$$xgZZZ7fRBVmw fϚ:q7+{̌Kjeܹ&N?^['&de>r姟z駞jhh,+/UUJ0awz@Sw㶁0Z(}L&Ddfj *NІI;U( jϝ3;#=SΙS__Jᬙ3V\颢"\.a3g@:|l6!bcrys" @ Y,_r^ddZ¶]]SsiB~bʷ؂2 {MJJD;vxe˳g:zX?q2=-=+k_8w|RR/o۾d.\`…z~0 F%KUTzHϙ5SUUU]f„C/YS*6mZmˋ: y8+fs?2 L\c1 >Q ɚ03˙zp0jvCDg\.KPFa8Kޒ$I:.}W y%ijڝSS]=n5k"9_巵;Yɷ_h+|JT">χoXJJ+BAp}{ӟ8>y7m /<Ī+-\`[oRվ317ˤҶ}h "~`(i'Ir\f&GV#bcb^}eO>]ZV. 2 7m ÎRS.Y\[[{aGG) TvY,Ǽ{l6J(]!T^'t{nsQñ|왳BP(L>І00 9}j=vĢ Of )ʑGma+g^f-7>۶c,C5cǎm=#K/RAB(9%Z@cndPpʕ#G.Z`;*2 !t^qLvfFB/uG^cs3^JJJxXXDxH'fdd ^o?n\FF}sFV}VV^zO!ɧ9/Zh2| 9 WY]zL椉Byg5sƮvWf7!+V0{g}̌W6y:αZ*~+PzZ+/#.6{1A![VgC1!Zm{{BhO?L~pʔɓ FMmmq5/[tƴiٳoofF{3r>No֍ܴqk[hZ{ӦN]pa~ԔPKK+BjՉ^żd"իENz{JwQ@PPT\lZΥ˗u:]Td$u[ O4J" ì3B?ٓƸؘ«W7oyc͞9s̙AXl~ݭϯ[5~ܦW6uͰU*Ѩ=mmmݮB?q2 `т6n=C=EGEݿ|yYyy}}CxxX=4uIx-jK>?Vs6VUװs07ddv< 54sQ$ ~ l7p7bA^$ykz#q-}8NP(39u@0sƌA4apfΘ24[FWe'\S塼œJOƠF!H8z؞*v'O^hCϮY3}4Кg9yVXv«׮ u `s|2g(<::-fhb4!{Oޏ=iB oێTϏuk1L=,kҤ?gͲ.Cޖa,)-}?Ǿ` Xt4#?ޢP(<[6T(8|ٲm~RWWfs?Vy|G1a{b [lzMGg'W%I27/Ï>ScO̜1}i_eZE"Qh}v &%''mx'O}\׬1 tv>r>X17鼼\pL&JQ(4*з9 EC#ZfMMu5a~~¤ĤgΘL&'kHIIXB-+ ϿF'&ě搐൫iiiƛI OZ)Wȷm߁=k&BɓެS332 .]꫕ysN8?x}{m'uȑK~ɧzysq@&L0H0$Vb1ȫۭOgcnχ.5k勊jubB‚yN>mK3Ѻ7j?~8aCH*MOO{~ݳuW *l#/׶1.#s;!RiuuoeO:{K.a=jm''%"ӕ+WIzFz:BhW '{r@ FooNTTbPP8S0 L.J%WF~3>7oObhg j{a&VLs%%%|+1ණ͞93;{3X,;7]]* !DB7s8^Oyg9gEGG'%&Θ>㶼VmooGݷϖh%E"ѷ992YdzZaqzh C[A F >/::I$ DuRickkBPB /u?`DDXYY.ްwju bPTkpf̘˅Ӳ#ëXgmmBU(V588x2wΜW g͜_̷Z.eNr1 9cB#f !=SRZZ:e/7[,clբS{K.ϛ;!Tx莗 @ <ˋ4?!R謩)kkkv橝gDZ]r q A~~®.d0uuuij\ɬl5h4Yb ?aض/^ҳ@ 5{vJ}ΎzgRݎ,wC/9vxe22W\aۮ9uBx?j[olA ={&%%D;w gfd3g=zV85~/;w>Zmd2.XhB^mX2npLNq\謨(T(:߿:Ao`cN?W><<*z`V^^^GשTq\Tfp8^A#ɺ{#ps̜ F}E|Wq۶MH \9Tzw*>^Z$B%%}C(nGsr[lkccOmm T*&`2РbnF^kD8LeЭFh4F` 2B66VWT~ͤvI"i^^^AABr&&&Z&|!IRtg t3d_66u"8178ZR0z7CIۋvIcFddTڦjCCC  2  `Xa:1<_PtM4-lx^͝7}'> b]d}-[6Y,7:fܜ CZ.BUvСk^uvΜ>}٠ w+A8 ~y0qʸqxt<ͶII?uꗾN(:L= tEWBW,]V~zey575Ϯm!xӲ3q mT zfC\.KPafV$ɞӕt7軺T 9)U*oQm$F*<_*\vѹl Xl.LJT* qD[~( z\1P$)A0A=Ks1׻i4'R*!BbA[oc/jŊ0A/\x߷Gc'N||M?:6jŊE ֛j}+QQkSgΘd>@cn\bnvLE׮8pX쀀8חaT C;37Gf;VE$)4z__NY/: Q;#--..VT:slRuIM/8~ҲrPxP(ؼiSX}vYbŒŋ~\FF:ͮ{90<6K wHjO*0h FDggkkkTd4:`brr`LIIuS1 kJWIJrP(rʑG-\0s [XpkiHfFB/` ɤ,mlrfVa`O?lhRg2O\N6Hmu! 5kB[Z"#CBC%5c! p2eӧu=jX̟'}ɧ7䘭iЯ&B}~ð^XYUՀswRqRVvYUL,1cqTTѨ/.?u皚R'nkkkͿXPse ]Hd2'MO*$$!4k PuM-BhBVc䗳gƾeխZ*~uϿo"bc{ZBY +9\.q|Y ðL//VCCeggk.P bqI%55oL0|C!^ -,PsƼ)'3k! _tivǧg0|>?=-_h1~w ϭi׶ljokMh))>շ?!+kܹVuێb17p>_&먫}RX.>b)u: Z իyc IDAT_U*UZǣw#1FQT`ܳ'q11iWnƊ=s3 8!ױ[_.kMl|m뚛awTJQzں]_}5Ndž cX>!^5i7zFҥgqԔWW n'Cg)qWA[2iTܑaacҒˮ=w.\`Zvvss3k:sR!~0 .jS @BK#׀;221::l6dmCikpcsSFG 9yΜӲɧN6h :f4;:q"17p8PѨ0,!!388`^Ɠ8;UNib΃0g?d0 4IuC%& S/f2ؖԲq$bc^- epM!I=O U*eWf5@ \&,,d4ףI R\r΅wDhpkٜ0AW_hVuʹ^x0 NFUUmp8p9'WZ#|eB_=0v@ \?ˋ%wO3RS'b*.7$gz|ف n_6a锦q=kpc+PQ(P 4[, Ǘ ,>ϝ:AqUOwPPss} c"a+]𰧞ZxԙZVqd2Y΀~s>qTHHX,޷Ç>Tƍxw Cݛ'IR.;lNttr``XZڤЫWLw!-))-uGw$Ow 4Bq놆XB3ښ`_m۶6!!>((pR)Bꫜ |{jL&G~Pu[nٲ%F_c[B ӧ3f,z5yϏHPP8I--u= 500b>i d[$p{yy\B努h"BBPgg'J&&SߢөssGE%&geM//ZWW1#船Jr,Kժ;#TDRrphv|nX,8~vn币vcr偞$ǧ! 쾛&vߓ ,)7~VkѣR=aN"QhJ%Ѣx$o%u:}KKkV>^^m[{{{+>,"J,/ R1 uR.C,{nN+--%<11w:::'6&F,檪Vi.atTTpppyEE[[K* FGA( C)@#idI1yuG},^@,ߵkLv{[ڲeb^~c[}+9Ig4Oge͊IhۛFؒ3V?q``kg͘?ޱ|0MMoٵkN<骘{̙K.yvMPBHtg{{s|}V0töQ^^K6W#m޽?U?Iz $$Ç:Юwҥ_'Ouqgp17J =ٶں:PHP!=D"aXϿb !amvOn+ Z{$m۶8cfZ޿Z[;}l T*{V8Jš8NiiZ-!!QUg(!IR.=Mh%A+7E>}jXlX,&ɨR)5.^;ԸZ,KOMXP+s17B$jElP\󭘘hAIi^ڰɓOZtӧL

>\($ x„̶6T*Em갰zyq17a?`TToJ2s 4_Qp:ݮ5T(;%I'>?tFل*.=cC77BC$[l *Xa!/T.T|(/#364HbW_PQQl=$R)U*eu5'DJYuu׃"%:6L:F"#lPmYұ9lu?7z7|k$7 SCpeA׳yVӡ PZjT*m4}U8hMCd@|Tvjmb& ԅœ$Sq !<֞ko?,[×.% :̞ͦ* *Sˆs#0OB3 F8oZT2Ns|'E˖-0aBH.G!IS\.%&*1!%T8Z8EC Ǝ~0yK.Ԥ-\t0w8a1Çk{rG$I55 ⴴIBʕMc5Fs5ky˖g޶cǶ;Hܵ{@`2T2+V=a^%+ql G8NgJAaZZa#摰zzJ]OauvJϞ=<>004; mmMNTp|//o^;Ķ0ƖxA.]^hVj5]]C$]BMڒ'slI?xfիy)}hm0R,v0ܓv1緷Kd: !n y1a#ƙpP_ϰ R #0 kiT%l 4y147W*ť t 3-Dh[ ?&;HJ!p"“صDVSHC^^,(hKxB6[gQ`@.Ԥ-R4#93[.)"4.J&k+,6!Ptp8\@&ksI+`$PVVUQE J$Mw\lxx}6@ZWWf/YFU.# E¶詣:44:118!$Fx~s Fb]x|A/&3ŶvL&&deM>o|劧:h8 K;TjA0Dz !_/bqT*iooQ$Ip=/0FbmZj`o NĎŗ_~7CDkk RI-, I$wtiX#1Fs9wBDx80dCw$ wB$I6L&~0@`4j5Bq ìV+ñFA Je2v#@/T AL@`0::Z<7`lhTR$00$ AUyy0LlFhm`۞3ky흳+LVW_?~8ɧ;yBoL&!ͷ}?44#O>>mZZZ`x:EҢIUU8.Xss-,DMMPddT*hBacވ^N3n h4'UU[by?xs<2ٖ7zoK$F*|y۶P(uvv~wL&w7DE%0Jհ|||}}6N׵3,PөIb=)v#7yϼ,3oL*?V[[wǪT*շ}4qbvԸجBw]PPЭ+hwR=Pka|?¢1 I$0I$၁%at:=n粘۵cT￯ɓ'9u VՅMۆq[V 8BG `2Y"*+'Y,MU{{أѨ.Ϗ$ H:sA펑%//_ * 9΃<<~8\YY4i#bbR. F 2JUT:8N $IR"`1&&Y Zܱ%ׯtAC&D?m'N]6 r1掋Kg9u˼#B fsst'JH=v#7FYl6 hӿ&oBpc^m?假mT{PDwuɪJhHr٤tpJ]}0f۵l#$;::=r)f$o[T(,,B66Vv<)>8NP( p1s 6npQ|`0iiBM>.jښ8. wGP$qBxmZzWUhllshl:Y^^R)Q(dȪkV]]rH*F$17fÆpSiޜnGb p7բpq^2ƍ!dNiggVrU5ĹlGQs#Μ孷^/))hZ:1+kܥKW)i_G>j„Nv/oJHH7x55[9Ι.9{<0>>rzV* L/>_$P 1 3tmmmmM E]K $.w XjvK=ojwiki~7UUն[01ٳg_'IJZ, j{޸qDZSbcc>n,Ip/))+))yյ:[P޸ 0ਨ$__>BTPVvEox3-- -- !h$I+ SN*5-}xD>l:.+ 1 BP& !R]]Pt8stNT8/D8$ ryT*ikkC:)zmhIIi04$'% VU)RZ씪aC BbX^2|Ҥ I۶D%O><77ϙ |P(w,hbù^ׯ_G >Hlr@O3HLU;u0AYz;F"5 eEEgjZ:}INJ*.mlIe{I:N!.]\%;v||Hdg M&lhhD-Yࡇg?:kRNRqi4$ͅeI++KX,X&L^t7G= Fs69ܚsrN__`nifee:d0XYYf` ^UѺ0N--rAAa"QphhdHHVniknnXzicH I7N% wGs%O\ǒG~~yCEE@GEDD$K$H{@q]p 8ȏ` 땕2nĈb\UU*m~rCEGEWTB{d0쩧Vvtt8LcA4=00488R,CjDRL0 j)H/x̟?~8Xl[ZRi?{g&GYS6d,dW%AQY %AA v/!`w!%@3dgߺ{z~TҙL23ɬ=3Oou[{N2zwwb{ǾsU߹|t}w4.Zf=4KvbnC&c~O c;Q.":4R,-;fAI_w52駟XSiUQl("b)+))٪ ptgT @ ð{nSނ}>֭:p?O2d2556|_袋j ^r7޼cms~f߾l\.kk|>IWVUUC}>nᒯ}{{_y9}K9?~أuWO>G=u)f2l*j2قA@ 3 VT%&/_`7g'' ׻b޼yW^qO?=\^Ɵ}~k%tXtG.[O7+.wT* ,664 Dknqn6O;f Ks9 g\aqtΨcpg8<ͥ' CcVT%_ZuK].MVڲ,َ,-[MN;}^oii BK,5XvP*W]yV睷cGˡÇ.YR]]evO$< wnRD^9lyvL?(`Y6;"BijZpJf(V"8^,j,[4oٲe8_2ǎ7xe%KKJƶGND#Q?qQ8t:孷.<8uXCxPe.YM4:p`Ǟ=B>D9o޲\aK@ f"ZݷG zvݳg>hǎd2JḶ^hQkk[k[̛;<nbK zmijft0H&R(j~B] f@ قaaAېch*LvСhlSPr566j5}ζw㥗Yx1'~.W8h4uuɀx}vZ]x;oYcgK}]ݖ7ߘn+Z_Q1G",6sm@ gVk(+C;ߟؚv}mm{{hy?n۶mO?l&J_.]6fǵZm>llh8x`MI7a1!8C"=ATZZm2z?0CQt@ Ĩ$3d3l >MrW*l6;A54 42b+faxك¨'LVj-/)9a @ aaDSG'J٬X"yĨB\.d2Tz8'iʦ7?NȚ];:Z( aYq%%vl.u8~"1~\,ˊDdrR꓍d2:kQ=n>MTFMܤB y3{ʦ-; Ɇiuqzh<n 82"NFV>/ 烯D~wgß^|f /8n;/NM0Œf+8ج{;" \8>q3": % M|`B $hfY Ɋ"m*vvm_D!xڃ\W(NئT(y1ŦB~^)M,{d*961{'a$Ij4_|y F&vuz]uZQҺ\=^ HbKHdm @:ȸOZWk*jv?aRYlm/|*fX*5rNT(:=70̰{?'~{L]d2vFf,-Kz{鏙C iT4=IrL&JqoM*WȩTBXJ6t+y+deS[-6 cKr<@d6E%{ςAX,_XYYK@4 3 aTG_ap߉$|- d2Js>qhOGqU6e2@pR'a:N.soqxT(V̊4qec[- YC_s͕jGFj{!|WQolP^@ 084i4pxIG"1(Z}Y\"V&ITP~RNHtؤRt+/B޾ )z?{pՕW^D"ظտOR|B 9 K d[M1 ôuAe$`Dy0nNZ Cvvv=ȣE?RZ B?GYV_n ^H$ַ9{9>wF$9^z u*Xe*DÅ<%i}9Qtq.0O$b2HRl}y#l^.pW.@0`7X(&4_W?d=>ΜE+ݵkWcG+7$I ޺E$2q9n |>Mdd9&I滻*Z1*!"K$2WҚL6sbc_С&jӈ`Yq=7+H @ &\.H@.WξYFP[E>>o{ݿoެ~{Ǻ߬[g<EɧDϟw~XbywwW駟X,J%Psi[,X,LW(ȹE"P(b8-Zkמ`#<1\$I7de%fsZV;tۅ@ YN.`E"ݧ6s I's\>qMtl6H$7\X|[_lO#?Xr}Fw:\;wٶ{^X_d4(%Kڵ!w& %t=c\%K_yeuytQxѐZRixNׅ "bHƓH=ll.df[eGNXe@ xγ"#sի&IW?˿L&LJb{juw8S6) Cooߨ=vGPHCVRkU6JߙN'.@NR$drazz66WYYkf%5s47ð~r\pu ø\:p.X0߾Ӕ^?]g bZBdb)S55MqLlZ@ 8r MS<GyydHp@MfԞM{F`ÇrIdFeѢw=Fa7glѱpN'f6?4M9]fjM N$bmVtM@Ė7ߘnM&ɔ\C_0oޒ)ٍ("=jĬ}M], "W\β,AE-^ܼi°8d(y55O>̐uO9(_r0FC6[ZUhhB ,! Xj! ѣ{U*^ 8/PXo ^U*Ν7h[َKi H$D .]0_wH-g_[I뼑|+_o?#mm\˅usmA hq,9$nEVƆ[@ .+xlޏJdJe$:4#pe2L1qP_jD=(?4&KtZZv /fFsnˎ1-, D!ZJz^!'G$9xsA0 SUUM D"LU\d2P(y<{|޼ ~aOAlhl:![<֜5~=Ql6A# au]lPlI1e;;t&jT3QApBH(a>/B!'I&IV#t B~BכcUy-kn¡Cƿ/.euEFK+z'O06[JGsfN Apښa&nE xA4CS,eMIS"DbQ>Ow1E0 >N8HzD1+d2'[kk痗.^" wvc{fܹgmkaXqC7_ܧ{SˊVv{ˎY.۷Ǫ~-GN,1d@T__{8+-1Dm옻6Tכ4 X6Mbc%R1A12q"M4M"I`YZy RaT@֩YN IDATU]TZZtv !aѽnwM\yy2kz\7Q靝݅!]T=gyv 1J5u5c}qI&ErMɈ3%9s ª9sD6 q^>~V+|qO_kk/˲; /&A/M  MS}}mA9mh4s?reS/&Bu&:dNxvޗJf]czp&"ssl?\zlvc9gQl0 rBԴvy<(dp 峔X7o!<}DX X&XrF@fA /`ᘟ/愹 vZx<^c&PHELZmScm~TVVڬֶ6?4pα۫;s`]>Hd%%vɪVU*]mX__˲l[[R,K1jn8.?@sp8-[MX,ێxOCej>&rySP( )J!v-K,Bۼ9͖ŋ><eY.Waȑ]p 3 w80 ˲<OT<^8c.+1 iZ&ƛo~'0. m8kp BH$K$rL.(b@ $cxIIiIɱ44Ʋa8Ͳ,qO!CR^t>!=gz)&Ts5kbfY͞61u4ptZJ3oRQ,l&J&9mS$PEQ˲\n@i|q>/Daʊ%KIr)ƍ`0g{{{o6x}ĵu8xƟ~隯_fk>>yܼy^G~lO?,r~y8J|-MM޾{Ϟp?J@L  "X&K%Bb D8ӄ.8XŰSehi$_$I\.t:MQ/._ybW_}%2[ni5 mq%Ixn7gfpAjn~fM( jkޘn+c'I9G3Xz=E&0h 8)xY0d$xee%p뗮i|\(mڳwGd2O>t_?_ nܞciz6R8S˵|g}[> =SHp#bT&SdJL)+%@ N' ]r,FIT"O&t"N*E|nSH? 6nܼq!l?%8lяn`V馟l-[^?h<[Qqݶv}c(j͍@&Ao$+F[mX,בɤۮѶ}o910 khhx<2T*%].Wgyyy<x|>Naƒ=Xַ$ kB#;:.xÏ@&UWUפ2FR<ѣPɧΟ7W,;/0@܁*B-)R\ Å.Ɖ brt"K$bd4Jө|>{ڛX,kj,Ysd26!Ə5J䤵"*"+V,ᲅ_hѮ]{o| Ba4EAk0Aa@Too7PYYVju:**T&PaNg0e)2 (e2Y<¯j:J N wϝ0nP(5fHU]{͗{K꧝1aF:=@}tF FpLP \V("fY aYa8 MQd*x$&|ReYvҥ+w(^vg,{J۷r}>t:Mw_Sm7p˲?AT<}>Hoo_sϫ}@I^޵kO]] 7 H8qZ[ۖ,i~M17Pl.H$NAZshm(לѱlB!ೌt:y.F_VVc4 r:Inf+ E. BCabF0x<-rADt:=$W`woݻ57ں5 z "MVU,?Rad WZyQZ@ c +,}8o7zyŸGw10\PT:JVR9Vm ->6O1IE"h4EMYlٗ:;wwg؄d">p_ɤ\0IUU/]|7xOpuk6j4}b1|m^b`85$ͮ[w'O=ns8fd-+;|ӉS"8@$4v{UII`sPZEVwuuI$\jd2(*) Lx$ AJxkYr=r~S͛{U7'~o{uu߻?i}yOꖵwf9aRBҪT:J#p/$aYө)qd`4FCXxBD%4 ?K޽zMbO[. .Xnݝjn$y~C[Up饫d2,X0Cسg1iĸZgb.tC|ò7xJJVkeii\ru{s_KZ磱Xͯ_4Mg2?=k|o|ۅu}!~ym߾6-+2ǕJFc J,2 0\O(M" }/LY@oϟT7_tjp2P}Ç&bY3Vx4Mcw}s`0$s67U0 ;X,,=7Z;j4͹e`BL y.j-X:t5 sWD"e].W6FE.|>>J*JTiaR6a MS-O%g/IFY"VZVkP(8Ixx|Y1 cY, PH7ؓM>ݹb)X|>WOOk$<خ,v{_~ySggBdYt?uwƚkѩjјLd ǫ~g <3ΖEg#OO1⁦)/-*)ε+zzaTJpJIR[Pz>F].W.F<OKJJd2</ @L6TZD7)B>l6MQP( |>Oy c8dҁ7'"-))n4l&$~ _@(_;>, umm4M2!3+j;pɲ`Z|dPswuuzKKEDՍ2hD$Iy>Ot.fD$I ($Ine2fLx.d2^_ח:,ƲL2s|P.WR(:N B |>߀?0)'e>O7[,eFcRaV,J%x"f)tɫSW]ŋ5PGG`\;gNM02  \~ iyg#vo\.wvڽ{FC$hmm㎻O/n.D w[h|hEW4bn+&4w4;Q TUU<JC6ioruWTj4ƹsR`ЃM\.'JYT Ifr$ed&,0Z_Rb5b;a`)*L,N'X<A\.;0aNd@ IRT*\x>K$I|r\*sxNT0 /;wٺuڵbk(kll;(Z⋗]v?2²p ^x}+}y'ŋ~z1RCv*l6ru)K40 4MBd2))D"\6@.60HqXLQT<(PrH@1x_כM&Ng$b\f `(|w`\%2 T*:=G,;bD"J2J&SbaX! Ex<^20,p'$i!y|>g\.24ia(iK[غug RUO<̬SIisp) H3lY1E 2T{6l.++\ .[Ty^J$y<< ''I EGd>/ )Qi5e D H$6&UcaL&T*RiR>_  3b\M$&0 HdR\&Sdr\%KBQ!;  E0 I\&MӉT*$SD6!h_V/?_|+׿OvHsCUs>`enlOؐ'1':w~s|>}b)XKJ&=:~ ='9F,_$>Eb GJ@ ƃT*7m&UPqWxXN3l2D"ɤO-:?h4lܸ;ScDqRۊ=ٷ_?0̏~t#\jM7dÆ?o6Wtt7޹eۅQWhwqm]{éHp5W#/VVD"9BO9EQ]GF٪ZCCwz2ӔB[R\ͥVk\bY`a }Zn3 À(7+j@(wz^r\V( ZTEpҀaǼ$IӉx<h2smej8Uscر?xDvˊNpÄh#]C#+V,~nbX*Ba*œy& +r'H$ -Zkמ`#<>\ep82reP E"Za66[u,z>kJ#aVk* Y t:w_Smbh4pu+~{`ɒEvFNw& %t=c\%K_yeuy9󾾈b&Mwu9j0X-rZVkkk^?P@ TnV " d2>0v,k-YrT0dRNgk0-)/ , wἇ\Ru*VI$QZs 'l2łh8 %"L58S7  }X$03 ("=2Zk2 ˿L&LJ8>i{juw8S6) é$<q__Ča:D"d7K h&Iuݎx<<ۦWbARTj$Ɂ.7(&pe~CQښF HmLgQ>_VZFW(\b" 46݂ˌah4 C!o43/eSz΀+e ɻV0짟\x\lݺ;OMM6[xT*>^:{Ϟ}05i;p&=vGV:U3'*dl6[e. ~+H0L[zY .Wo fYh/PtJ%._PWW׫zRXooYU-%j^5iz.K7,p9O XQ_0 XdF??wڬ92c47l{dnd-Z{3Y(0,wxq{&=ϖ ve5{ư!9N"mk޾_5L6b)XJi~+a!8GDv{R&Jt:rz<\)- EX0D%%ŋWd 6 twB3ۖP5t%:I,p,ˤRID"1.Y(qwǂA=Dl<*Xsk-X\pCQiQn7uvv,^p, EGq1IHvBQx;o~k{َKi H$D .]0_wH-g_[I>7x\H$RC=ε_Xw`?'{jJ4X,$H ED"Zvl,aZSƲ=Uv/o{3s957tB3jD h#qZN6@"nuv8zzFJFĦPh9wX2F,* JXʝ nwSMcK_Ys8@:NҲeyᅗ&7Bo2Or1bsqH$j zI16 1 LFcH4"E/KN^^߶euz3E8B^ea3s8ZC54*zza6[EeeP((TaF7E(c0 >֪F`C!_&Hj^.WvzόK7Mv-;]dN(?㭪8z8Ŷ!T"J\=BV*Vq/ ;6$T"'D"L38J .l}Gbv ߯(gpO/L[^w ewnt`O?! t[5!f :V`R.D.?J[S3W7u8J`3gD"iwx:]h0 8a6-0 hP,fb9@22O}JB gRg-;l,}"|С#"'ܶmn: Dh4Ľ%BPd \%+R%Wxwa\.et6ft*Mg\.;2|v8'7 ( $̐7Z,ufY;o7iX>:2wyQewn1ꫯڸv?W_y睿JŏNgT᰿#>Q"C.WVU5t&]]TڹJeYH.-UHm4ZpDzg\>ZMMK`Y#^0rt՛Li'(W{\E!F/pz YvȜKR,Wc\H r\ 4t(QlP@yR\&SJ\%D"RSXγ˲\6ϑd$(2ϓd>?B$E ð,3iT`Ozg?5mY,fѰew9)y\DDKˮ ٳT7-o<4^^Vxw_VfӞ=XݿO~V W66e2bl?  %<eYpt~4?T s>O@sySVv㲻x=p;9PcNZe0].؊E!S HD=8.E"X̽"D$DbTNY8aPM XcpaYRc8z_j5w׿=8(h4궶[87q.jieַZSc2Vbq>HTVQth4z\a{zZ;E"qee}IðD"q|f0< fGL6{FQrubaPYY[bn$UU, l)G E$͎rf鑷Zl,-:]D>82gY.q|دn~b F##tF a2T&DN)a|䗐>_H<a88cP(L@ ǃb(E*B= o1ARP 7L_v## ø C_`y<|pp8ѫѨ#=G9JAT~<rLooՃV-';#"p䥗ϪTXl㲻""3W8qoqcYN|h8t?o<.BH$ɔ2B*Jb4Y`Ѡ\8D#)j-B89rem|RCtWeݮj$"OKyii];  y.x.IT*Zj \ɆRzp"D VV֙LvNm'M&Dͥ|ܱd2aR"IѽHl8Utw8:Z  C}}d\3-]JT`mpA ]wRgҳ~jiD"RT"!cɳTP>82gM( jxc@ )D"9uϊ=3=%<OT.`,.M&D"*-#ac;lM{NDd%uu$wzz{PlnVUZZt<aXIA ɶȱ<n0x>߀RQWwA6q8\}\uXR^^k6x8I89I<^lɲeYŒxlfڡ@vf:Ph鰔a(LH:vX~i BCJ[ IH8^[-ٖ-Z7,ˎcDzs>?9#_]}{)Pۓe8`0TT1 8/|7͛B>n4բ~h4711 ]wa0'Nz]wc;ohkkݻwRι<(k @ sQ 4 pWl~ll\$zZm/_ p_fÇ|sW(IQ={ჿhl*QkjjjJVs, +HTRi4z:ۇ^gMjx<~6ZGG9@PӵD">>kjP(rY|>/ͭNމČefBaZV|> R'r}?pȧO<BOMvヌ0Z~_/7T l6{y/m.b"n]oWl˕tP %AzRuY>6RnZRRYYqt ]]۳eX?ٛx?bacc'kj:V$F#it\d\Z1 wm.0H )*p&gD֚:V*8|Ӛ dU:X,<zFsQmUY3,6Jbihv'^6}qQ}h68<^e}N,65uj6ۀi,4A/&'D"_!LBP ~`LD"xL&rYn{uuJ@4Z''l6Wi!rRNNz^>Af'ɧ & Ļ \ w?EAخ />bqOھ}]kebth]/5-Y!A c3PQ(lvKPvP(CjM u(H$\JFCV@&56q8l6k8~FEIjN&Sffb##vǕ[PJeT@"XfFqjuX,G$ͧg,}5㯾Wox:ɕWnǦa ߼yc2r9ׯo}#D[{䪫>. 2ĿEϹFkCqu=Xlw}gEE%[2>>Ħ d2yݺO8"h .LΘͽFI.״_  BA.꺆=BMƉ (*ryH 8d2Y&j2LΘCqBd*Ec /w_x=[o;n{ߧ{Bc&U}K۶m۷D"?CRc2\u 4|rkXprVX,SO=N<' ?7s5Y{g{~o||B gpO~s?~%|7–t:54t뫪ė]a7_A hZJ ÜNȈ0Fv&Hčƞ|gAT&X,p m%IJRGPrzddXJ&2LlhB}γb1b`q@$vݻo}?8xWT f?ܾ{ wOO],:Ei-VDbW)DbY!Ȫo D"-@0==3o}ߖs7t}WWGeeŞ=-OENH(1ڥReuu]q" dqqeA e T;\5^665uh4@29cLNzszADQ_#ܻDs>_׷L&c@.578ϧ?{n޲e3yog2[oC}ԔD"g}D"ʋ~JxÇ?DD't ]]/ó-x 2RKsoכ=&]^ ܺ7?rfm9p0]px{}C`^Pm۶k0 ð,eL*H&gdr&b%USS'ږFGCC`TE fL&mG׳Xd2a47oLa=>I[,Y!! 2,:B,:նTW,~^q)t{dZ__cǎwwTTx4JL_@PGff 2 ?xFG(t8>yM )#ͽ]ozlG̫Z5BY׼ĐV{NA56 $Ă28`f&C@ 09==U 㼆tZ&'Z[7IʪӧB[BP(z]uu87-djBs*t:^_S#%=a/dr+t6.8P(J5$QrȿazpBH>_aL&311Op8߹C墹/oO\ ,SPw( EQ2Bi4Jg0l62lZ ih@sOM/EF\_߸i[, ^6E,*d25 [}h`|,Wkeydl>K>w6vx+ȒSFQiSȧ\4]qck|E\8 A>_(D"HT'55mn}ttx.ځ75uD͛?wX0%d2U]APfLPXRI?PU%V t:Fx!@uum[oԩs[ek6|8YQܯ# nww=|7~rb,!G};o3)W>oʊGo^ѓOq8K29Wzju ZⰥiǦ2%7l`O6䈱Xdx4@} lnjӹ3J#Xd9 PhF 3O"@h?<'~ҫiǦܠ4w) IDATI0lmm!b> _ bZ" h\C 4mzf'Ntmy~N#\Jv_Rsq'~DPh%ՒHdd:ymffbmm55u2lu`i`Zm J$K8\< W׷Q@`dI(JJd2Dǣ`,/΄Ur+^6XFG?a3,ǫH>"Mr>թT*wðh4ɤ2{y nPVÏr[OjBA G?p)qTWI$? ذĉDDZ1} 6tgo川yNs-di9+Vz +0lddxddjٹ}jj|hh~`pر_R`_j. J RA1i.j&@*)ZN<GuFcMMMo Rb)`lmIuuJD"ML^ɲewdH nPV4;v\f 7\Fgdyuuu9ve[lÏMo9S(o~_aPv.Nd6@ E(i6ܿcؤ^JwH*Xn\9ɓ۷TWK.k7 uu 2Y= y/6 ^f"u:- F$RnKJiBaM6ZIUU:ݙa^gqC;7Hs>𣧟~r``(_'OZH\- Qtuu[He6)@|6R ;zɱߕU:]&S|̹&͜:I{e55u-,'JZ Tj%zCΪZ@PҟJ%;Lv8ps:-SY'6orY溨fSob]~d*A''æ4Ckp*ؓɤ7B] [ׅdi 8NPږ*1emQg :Ή )g3&J4|B8_ׂ7yA{bݞpu_$^ڂ'`ЙL sk.½EJPn71),,t:58xr||uN*+]]]]```MnV7s8t:iKD%5u$yrrferAI"CBL=@UUVDPPO~tERiai.@r\ϖL&S*9Gd]Kb9~MT~0L&6njj2o4=zS\-s{[wJ$׿~D_}wK>dc..d J?.olTZssWUUm&;͹M"/+=ЂAG"_7*0 6bvJRvqr҃hccH$?G(F\UUaY4:ȿQaCř  6R~J`ٸp]cc_zn~pv_`ee^x<;vرgl!VgAn}oȈG,`OqrU-H.s*>$ֶ-vTќx}s{}>):lFL2ҟHKS@ N  5XD&E3|>K"vDZsd2Eo kRЩ&')ѺZv/憺qt}wּҏ )+Fena"yB}VuUD#GU]-ݸﻻϗJ%O>ٹMkK$s(cZTڀ $*EQf89&猒z}Lv.J!du@`rpdѻ*"Cï8>+{ ,jWz Yk%AK=Nnii/ Y1)zN9WR6O}~58Eg44ivuYN ,j^K x`XZmwN}2==5Z,9}Xk斖'N#JM?N EADlelv||FJ"BڟHi*KU&|64qۍ55A].aV5@n$ |V5Jwl2_^S}Y4"n>jfcҥM1W,zL*<>6|囕JwA )[}Wɲ>'^Gsɤ/ z MbwgWPV ݨϪ-pF^nAB['Ujj߽EXx`h68xuͮ3==e2tmmNtJ2^O&%V.")XanCuuLֶDNE(͵l6=8xXYB.~"ߔU廱,#;7!]{.D zeeE088v8)$H3 $bBN*EA57I&~u ]Cl&Kp] ЙT:*_CDG>-ݨ*a@R cLk=gq2Epd'ߑ5R13mmI1:#4^n݆SvY&(ITU1 s8D`:];JBt:`B?HEI-AL|`83H$Ąf/M1;8~,? ]pI(=:3SO-|ngny% /ߜܰM7t~u*rו\%k?ݷsSTF&xY;~& gq,,ZR5[, `i4Mt:kf&fGȞHT`@Q$X<"%Riz6\CX־;J+*v :66ja\iкuMT*UW|YXecr她% dg_>p$N @M'YmU{^bu8_yHR]/`Y[O߀@xp qe޷d*ZN-m(%U£hϗ_ޑ DC)p#;~Z8XuumnJ$p8PaL Eщ m-a'20 f1&L[,}9mnnR>gddxݺ L&; *. LR*[sYq~']]ok+;5O9wl)H3V)I6 L&p!HsⱤwļ:MG>$%_{> e1W%/c dӤʪ}asߨvݚ5mQRRfWlL&4XV %7*8Y,NP(CGM,͢( a;/|Akf*rYC![&=>>r'L47w)d2 kdDB48Y!}}sYмP8HgqP!E rN-i`Ļ8IhD%#)HXZ㙰HԹ.PqE@ pEj4ș D-ĉuvnW*A1kL|hyCssɓKMh0,`Q?,`tt:1fG ōpXDEb(,. jȄE^Q\v/cjuR4׽o\AD&X۰] "`&`qs謚seE28q㎎ q}s,rZk_d⥢J,P\oxJDQ].ؘ`׬X,khaXn7d t:+ =3TWiulN\[Ÿ\O<T*W^;-daRQl6 B,dNNN4GET$~M嫹u+=@VJ)/ or>P r/C釿7<Ls=o$g-FvKؓ j>{D|מ{d #,! jk¢v=p`"0}p"zSÓ?~mok.={(T2NGơCV$3'OܦT6f2Y0ir+*adľ"DQBj0,kdyS*xZ@>Ph­`%T23 >5΁LX7# A*t |f[rTH6["/m.oii޾}uD >o>xZ}5 P(NDV*pDn\M΋s֠{?ŹGn{^X' Zc; lzI$fzz>خӵNNzZZ6tF.W#(I] 3  R髫%DòAM,1O$PC'N@Kyf7ZQN$(2ьaY7xï~۱ =}\ISD q[ JHj{l\WtkmͣG-Ϸt@fS.f nZchEݐb[Z68q FF҆Ųа6r0c0,4B@Кi4&cPjEQR43'(t:crrj``55m`0蓓cfs/}ILyGlv2|ꩽoL B.w lWW' k~z[wf~m:っuk&@ RY䥫ZcX?*L08e2[[|YGBU*=N$61*r.l^EQ].kр$Yo'Lp<:]ǫ4:dmw:-9KBi$8o~C\y'xlzzZ v7oL&S}\9.׷΁>)UW}~9}1)SͽMg\iq!l]s,]QSFYR&\%{N4Cllix|7Ǎƞ5`"_B܊zD &\RnbLAN? 0K_ضmkmx߾= }{gTj,#Zɜ٣8cJ5z7t}WWGeeŞ=-\"8f)Oߚ Trkkbq6996_uDiOO,J75u0t:C1bSv(! uB]A.>y\n,#nb AH$N}{K/BRl6L08k5~z*e1.Nsm 9Oǻ{z @) NgTUUd n9ܕU"DI$RU)}(+4@P;(:`.4:TZ6Rg 9&8^XD(\.B!gv[lr9?L&{wݻosH$/HW^yWU <|'Hض]]/ó-x VTyim:Ǥkχ;jՁnH `Lȅpx ~\},Рhn7ΛǫhZPŰx@g8CLAuͮFP aKz;ݵH$~=;vǣ3wtL_@PGff ^23`4y߉B/beEim:־jbjnY>-MM'N|;NmMs_ߧ%:Y rycccc.H]V H$' d ΘLVSSFVkq%En!믝=̋8 \`O>_aL&311Op8߹C!)iuL Ӧ&~/ ALP1 6z҂Lt%l.a½G nҲJ\64pv-D"m۶xAYSSNɵZ&0 [nW.ܗ EY8Zo IDATǫ$*jn@7_nP(zN$vB4LCy9<~=Dqi>_׷(j % L_cc*UА'?ys*#}̅LAKӀ@ de<NLxrT0T08xމlR%ӓ.m3HmL"Q >22 Q2::<2b/*x8C<$J?^zҁ,OPX,JBDv$#AElDܰs5qP:ty_6t'{7 0,;0pr9 o5<@$|P]]G8xkLsy# oT5HjCp4!N;~i@ʍ OEH$Jn%WL&nR٨Tj,ҝ Fb!2oHDDQNx<:We>RmM' bPh%E:?pC[o/~oy[E_Kܠ4\Zacf ~L׾RP8>> C_X6t8q2믿Vnr8s8Gy_ 5 irr' DR(+*pM$Vk_HnѡQՒ\ VGG@*r?\nCG~z!|>B cnP(XlTX aAқ}h449魪HΉ(B&S Iy޼BBh&"P`xxDlDYWWP:$Ikr+&SOn)ߟ{`Uhnx?/u].w"xh"T nwaP'O<ȑ ur?&4 @ TTE:ߗ?VT(2 MXRHϦi*L8^(JV${7(+=eXL `2,+  J$wuǑ#}wsvuu֯s%=֢)H!qdikۢR9t:5::Phr6 kb9qD}9(j}}#K&( (ĄwdVICCP(8P4d|c6}xfl^Q\Ub>ȃ, $ڃ I$bM𶶖W_!B W?t:],9yGYkYk"æR@^:!dE\VAo6'&FA'l(j8<`0dؘDAu<f3C&SNJ$@ e…Аdr9+劭ki5[6OKT`L&#&|M645^}%Wop6}a?зTj"h/38z_ @ --lPw 0+gCG6IRD4Rj%z~xEEDueHn {TzSS'FxnyB.YnvGl|4x=4j4} v~uC>/]h4z6\Rrcǎ/y%⦈T*r;v\ܰws`!ql#::S\b,N]rGvl*k cE_l@Q?\J@.E<G,j+*DL&i (I&SՐǫllle0~D0J1 Knk0'æ|tFSSJA Y9uK e%.ǁz sSFvnAݻoX qeccD"Ns&I$UUb@41)@ HMFYFRꔙLf T*v(̇Ng  x,ҁbO=8QB& wߟJlJJ].cwIWz NXv?S5!rәtL$)}08tuvB38x2I& -OæJQuum*ZəQU%5( p6xAi0')n nȅ@+Dbdǎ y"1φB2-بf{>rl+V@T&ST*N\>  t:S$"&ծcHl$"Qm"0{KZL`(v` d2傂rvٺ>:TڷAVcd,vEă&MCek7z8ZWlFc/G]ܡA TRc2Y33aj[?KvyGxxne)A\-qCqfM&`2:]Lq:-@ `VP[ewɮX^r-ɱe7_[喻R@ W*d29tm%Ph\L&:vLfn944Y,n4ۍV<< U(Ι"dtd20e_Eعk8w.QoO`@in.H@ H"׉ iݺrfzڟ͞QZƚCTML&; \f +EI*é,G=gњg-d͙Fgu108CX4 s靝?P\Qs/xZC HB"r _ɤX,n"1l\qAp 8Vh4F08vHd`XD"ONzGGEk2,¥0͵Y:dӦ.'P\8eMVzK&M ra0X zNN^S(H''\nEuuaZm L%8R(TNgf2I2 \it^O@ Ybm۶6NAsPl6 sX,&999YAEsF\Y&}]Ws+=@Rp1 RPx~1 sͺv ˤ)G3 ͧR^k||NkV7hT*A2By D";V(KPMc8L%Vz bO=o͛7 G}h4EO?h8ٳobbA`ЅO>s<Ѓ믻\ɝwSYYֺw fd`D.JJ-a3\lf&dh4j:X(őJqɷ`>3RXhxxӵQ(ԑ4\+Q|Q,YQ>J, ]qȧ=]Ǜ+ }σ>rٸqJp~;w^mX,-5 ( D(PLy,];Jkн,1 1H탉DtL&C"41.Ph@FFlICm<f3 Y,Je 4˟YEwXR4Jd!h`[L:%s%AYgv~# "v=t:8Bf41, ```oկ~y;v|a߾goߚVQ#t(A5}k R)I}Ϛ͖ BY>Y[־%[6ʝGZ֟o+@ K ïoPi.a R[ q⚧799}]ٿbh|5ơG6Y@ + 552D`t1o TjLv2p8LL8<]UU HD8BX$OMzBR >55.SWt&Lill^cvRqZnEH#3s'Q](m_} >կtۿ?t+MOO yd2r_; tG&''W]ŤL55g^]@ KBihгLfFå\BKP\.!8p`X&R0ǡPh%a52YC6|^Xf,LnllәޑROpōpMMiz:Jm{vm7oٲ<3쭷ޡkwujr"ϾN"^yE_U%N>v|tp3a¾&]^^#1,v;\VVUT*4$@Vkj)d/6 bA^ }^s{fr p`'$b 6tZs3Eso_b^e0O?b[x饿Kvܵw~\L&qܮT*bTj O,6@sK$>7oټy yЅ{("ͽNTbf47É#klN4xƓdʲJEz{sv(ZUB8z^vJՖ0,!b6Wp", E}X,+NIf;:|f`*HHD\FE{ڗZ%rBcY 8c)p1q,Y|7ovH$wܹ' xÏ>`۶mg݋-p|muݶ`|a2|>cߞkZL&jk`pk| ,sxI:9c'waFY0$.IJO@hS1zяϲw#*0,v7 ObJHd^G*udpl<?io U`@+j.rhgnfHr:pGXϐÙ+8| Nn  BK4qh{?t:3߽W8k˖o͚UƍPsYh|s^}… >ݻr[n^hj-h;VV>oBN B_E=sw^ݰo'0Hs"*s,jɔ6[5ʼnFCnw$Bfa9Hk%v{:|ífT`feaHә~ϠUԦRù0S&|_8\ GΒcxpZvc0>Xy+HBbn:TJve_p8~g}E2w?^y5Ne5?9sr tz0ux\g`b^uwݿo߁ٳ믺2)e'"ܣ HB!]256 a!mxdX1}[hH$ofwqd7a& T ~$htuDtcFCryZ Bd` lTPSYY/Sc!ZQg2Cğj]_ڸjЈr)éBdYRCB S (a{0K]M/B6{L> =^(О$R$)(ITНz&SN}nwٲ!4 hq꿜6[$>.9sh4bضmze=ofOя!M޴cPl\|ɥS݄;Ed IDATM`B^ R 7_>l66t6[ "~?0Vk R fs%Ee f fAWuô X/U9dPL&Ec+%_:)*=;d_=*֮]鴷zdZ)gؾ}gضm'{FLJ&1 |62 bT ӛ-8jKMrAz{;}>ר1\.&qǑJVk%DmA((tvg2Ew DX,HXX.WLlhi9;QZ|=N3}a$AFwDZs g.p_~u޹.]dΜ{N}e9,Xfͯn ޠEwU^pA*z+p8>lS1!X쭷}_wwwtw  0?(N JsEW<!\x֭r鿁@g4@X,Oܰ)J %/e۞~zN͕k[|ZZjj;~LWD&Sr5 \6+ {~W~TJ1)r"mA,!~;7l6(+A髬c0X fsAd]ԻM#PWV 6rJ ۋ?_6UߑsWW`yLxɩrY( UֱQfP7vPnKF>_X^^KHJ%UEe{,í%Bf"lVbPoL&T*cnwA`%%:{( Ô/9PUU(9KGgwY4wx&'oT8\ p`'$bـut~׾n30:bD4Kp$!eфgXdJ7 8Aϼp8==]U^^rkV\L(v\7|Gl"0,te:]igo,灁a++/z`0R{Ŗ7\YixoOLQ:!ݓAD!3à M7]ᰟ~c~ͩpN*RuBi)N8 )aw#RTpǺAQ d2ّj U媔+0eEi{R!uu mj\ƽcRbΜ2* :MA]Rb#n@TY9tuтAP³۵RJ$==Y3KRJ(8i\.ԃb` H]}7mz㡇_}H7o\fmw6]s||mow͡ō(L.#hH$ӟ(ӎV)4FS8pq (grwFZ~WD"cO{/^h۶nGݶ`|a2|>cD?J&;?ګ}}m>߂ >޼yNéhhiBLr(=\BJכY9tD"Vh{X0%PjFcd2nwS`gn3,--vtxl|hԣc`pX\kOQԁ~Jhhiqi+쭷ޥך^䃝-."k/^2e7lz݊3<~?ܦ1L=gDj)1 ) V n,A⣩M`}3/_-[G5kV7Bs9gEN+.ϭzM .vsͫoyu[[HAA_|r*N5$^'qzz{;Dz'jn>H0͕*NH BL猤DDh4 Tte{i*6]\ZoKM缹m~po] ՘8v3pв)P`_GBY, _'JR1?{wGQT]m-]a9j:d˖k~9s4wAڵax?q SmVzzڽ^Xlzo jId2|pYJd*xOrLGښ ζQ$@|wO&SX,{^Z N&~+6;93h4Pȧm3)>" r|0A#ӑ6Z(4\ {p*YaԐ0EA kRaL˖q546iS}]]fs7}"I-K+E"0aD4ZfxKm*lwsfUUI4rFhf՘,7ryI2xH$)+S6ɡLD_RbɞT31)N2 2BYB(I#(Ad~xd$IRV]t*FL EMC7`PR#8Lƃ3lB)2 H$j k~,hˬUkhl\t ؒq^ݻw95͕W\`&ӌb89ЉܥR%E1ZE|s9\.uج7L58oӕ2P] ͕Z[ d'T%! GM;;}JV72вt?ۧ @H$?ޮ]{͛ ~˽}9¨H57K6Nu+&%{ ,v:K%p # $0'p :Кd%@]q8Kv=w%s޻o_0;d˖sf/X`͚_mݺ-yy|V]xT_K+p|y2NÌBf2CD"}.Wpă`XKZ#Iwuu E"Ie,Qx#MiiyI--{I>dK5 mmx|\lh6Weמj)Ǒqz~oܼ^Ozժs _@~áPDTͮ]{@$ARfpS( VB][SINd23+bC7 a!N\~Mͼ9s ]FQ^WWw]}3$I67Ap#R^^'$N灜J&Sy6Kݍ7ͶjX,V P頗 T ڐr(wbJ ͂,B9箬k3=,g$`6͕d`&ɯF}7k+WZ{;~qpÕW^\xQy;BcN 4Ttr.W3\6ʑioVWf4b{rTZTLKjHQ $wKh{eϻ޻>͛`X q͚QtxT*q<3U㬕uPvO1wH$d2=WWwd\T*իox /p]vڦN}:k^n'e0μiL0nd2-%Z2)_HΧCQϒ,R 0#]$3) 3\U^^'YS Rxd79xXNE2꫿_mʳ|HDT_Kg2$q꧝6wM^XhɤH5gd-J8N(fO많#X0:U"$8`S1IePFt3n@mԧ5(:]dggk[k1r6:;}힂s5ZE~O~G5ãOBh6X,V8hz9ͥ {ZLU3~2e <\aiuXwq87T*~͛?এ/׭o(*=y흝]]CR IDAT|m2$KJΥ3\:?c9N"Z擛IQ P{ n6?B ƍ8p Gtfǔo/ 8Hn Cfs,J !D.WèVz(%/N67(OIjxU*\ !r5>ٜz6]pRTL$b>_lc 6VZjkmuʽ^K,ht;2:!p0lS]CW#$H݅= (z}<w>6aD"SO=vp8r}zS^l4 /m(>(o.Al6W('N\ lZRCQdGwMrޜGN`כ I͇u<**\~ .D[(T*Fyv:JוI~hKђ?/[ ;VX>ꜿvH2{tBQҸYw󆊩oG4 m-xuT"w=ᆛkj*W?(O> `PV}֭[@ I`pg]z FŚ^V"L"#<_f2GqOL7ôBՖ͕< puBחU(]#uGJM&t8R!I77w#An%`jZ.Ny< (kk6W46͛LQF9 `2.ܹ/]:PEEl߾s6sb=?ok嵇>/x… #ki94r噗\ra0r9==4K饿ܹkr,LGeA'+Xl <5͹% z͛l޼V߽7G?^VNTbYIG߳Z-r'hn"VK%' I62HZQ1K(r5 X,| =ABJ%1"v{P({}jN+0:q@< {J͠ɔ.Wc]i혩?5k΍fwau랾k.p8T*>҅) 3yv-kܝ3W^_P(| Wm7xoAbcyӒbܧ>">k0000BJ>_HQTWkIà EYK^otQK9,ia **fxW/N \.O.z[`۶w_֚&lEs:< CƍdL?bBXRbZ+|EQ]]~y\jRlZ.J%ZZGe0*ަ{9^U>_ rl5R" %TfIqd*7ʽަ\ykS.WڃL_H$贅S.2V+Z tB!r(ɤ?EcH}-_gpl6;H+Rt<?E ôBH"c :ȶ6ڴ{oAkjm&D$TVb8==mm-MBJ&S'іw-I*)1C֫պdJ y}3Ό][R̼KnLI}>Ar =ta( E$ͫ?ʹEۿlNJ'kMlH$|饿}?]ry\5hbm۶;8~$*n޼͚'xYue\|Hx&<3MMeN//}ɧ=Џ~tdpepe$IF10&Om) :ަZbp8iiiktLYU5Et=#zdfdKHdprBҥRqPAE'H0ثRi4CY$Po*u|# Ld2Ts<^nT`0tKٗJ:Yb8^vOlD[[B2m=ɔ8 8}F 3ʩ&7~[hH$ofwqo2|ͷ5PBׯf:_+gM^hEG>;+W.^pm@ 3z?t@G,wnJg%/e۞~zN͕k[|ZZjj;~f] 39ƈ^tx\/cnkmu% lZZKQqd21Kg Úb++gŲD"t'FE7R) Ŷgq8.p(' [eevǑ+,)1LmmUZֻکnIʩn°F7mMT_ر[(Г)ݐ;-)"=ee&Pt6K?܃B`,_~{;:7p[u8 V644>K*jG'ZsO˗drvkGiS݊aGyN RlWB K{<8X,\כFa!%{><4P405TWrP04J[/͙LiBl6WٜL&v7v ue,:v H䕕QC>:hbX(k|a0=NE6η٪JYyKUe|q2nƋx{7]7EeN'IsW8gUS*JoX&S]wNKҚFp㵡onm' mιaN0WA"s`04Hpr`^Sm0X<@__kw4BQb lzc!bV&$=Gw%%zesG50,Դ @PMetS,T:4c)+l =fǰ&xGiqKNqQjӺv=wƛt}֛otuo\rY m6kGGW:TN/\,GEMSO=~~;A("i&uÆzݍ7^+"R˯z@;˗ӧV_/um6<7Yn @TVVn0fvo[kS$i$Z-( twyM#  tؗH>MrbNq%%2;ANX,Rb` 6OkV(&=|]JZчB}}7hP..Pyd]K{j[5Ig.~Hs7rY[n˽v ;w /[{,l탹_mÆ'_xowQ O۵kK-\>Qr[D0-w'zW^cH"I @;%h4=2{]~X ӫ8fwcu7_wݏ{ea]] $IfnWpAQNWכe2% I9::Z , jUp8rZPv7ȇ,N(IMM Z镔-J}e1 EI<>v71f-/ml<IQñUUxd'ݠvG[֬;wf*&GsOh#<6:԰y`?6rݺ's ;;;sW]\ w96jչUk>tL/EQT~E#Hqڐ>.Z+]WSk7mz#J=̺[n[2ExBLe4Z4p9n)l* zMȘR hyyFSJdKˡQ}|  9 >*h4 )RJK.WlSBOOJɔ!?Z&N\߻wkl>Ӆryr%^.;v^Xdj190%E/~i^)3gVWW7yZ0%w}qnQ?E\aim+T*<_N00.|{^xڵOK1Lw|`1<L&:;}]]ٞX,Zk`4xCЌ@TS3O 񦦽ꊊY(vw} lӂ{Pts^S8wKe(ԗ) sE,sv7E74잩1,u."}$buÄ^^y執ݶ-a#?b_ӵ߅2W׌EQh*@6Ktvutx'sDRZѐ4 :]V HwqFTN56*ps8 2,I77Z2t[[VU^^-m8bVkϼ 'jKZv>EZ?ܕno11Lw>;l_YeCprxK@S{{NJˇ?8AQ ǃj9pB!E]E!ȑX/4B&SVHp_GGkOO vDZc Sm(nW,t% ퟭP1,pnz^o2t p[+5in.] tw:RTj\9I{?f a\.f8.B" G("B(? [NNXc IG,],ժOG! 'Wq0 ws嗮Zu͟P]h;\>߽ Xk7û "Vs>qLD"!m0HZQ) t:ttj[OQ`` 88VSs'#ǾtzJ>_XS3D2-qs8U hF 2NU9P--;. r&nl;gΒw9 \._ B@,8r,(nGEQ[If)f)RfI2 8XOQ~r:Eѻl7p6s.uKE>Y: tq,\xL&}5F}ٷmaC[f*Yswn}>H&r*°̺uOp5\p^8Q*U]/ZTٸ֛?hsko,{ Bjg2u Ee}p8vwRYb~ i?odկ~4661O?97;5Hggg?cq{~xH$r9p$wi|wH& iM/ofc믿A~'~In} T*Fc,)ѱXA`@= LAzT.) D"!8m ðc&d*'ɬuxn`)--ǰñg^sZkTt8ɣ'6D(LTV몪fB %D"HdbL ~(H.ebH*Hd"R ZXO@iӿ7mQrٳ0o{>RQa^Qs%uttQp.͛=u EQS*!!(K|E'Hsnx ݃ s`0Od<'| 3W;l_Ywz 3e)jZTD"1]E? JbTdrwwuNBh4Zj.XLu:R mon03TC +,e2^GypO$ ZlhmmB\TjPaBt$E@4(NN2J8 z@+3xuV}A 4Jo??ڵ% IDAT޽ow`>䧟~>j3 a(F 7`E02OujޝVL%BTRijL IPO tL?Ezdpk {&D3͇ bzRKDSӡ{ġZՖө9H$z--i,^\^RZjS;s޲tY1XV}p{ȜkQ*}}m۞?(rHt;|((*I55ϛ7!ͽX,_QQ(U*s[sJ<yHTPƍ-Y?L˭?|D"^͛_1Bgvx<) qCTДTH$ a:M|%0{EQkx.Rljb{b3)JT0HQp:mHsRTq؉ahEE+eȳxs8Ouxgo^znw8NQԟo߶m.[.߿r۶=]w\v٥dR,oj?ۍF#afef+Ogw$rq<6U_w˖WyO뮼-f_|k+[yͯի/δ3tLs )p fp%sk8px"T,DR@ C)(nqx)-?.KJ*U*mgM7^D"im|.ϘK.[ Gkt's8<{XyE"im< M,T. %LX,jm`:տ+j~386AEEݒ%+`00|>o{ b$InٜiD"O?$IHb3'm4E H_̆өj>^]}w9|I~)7_Iy01n0e8ON:'L4 !(//mo廊4koD"ڵܲUVfv[S7db؛mp%\lTgg${)h}a\ ,daMsɒyV=p/D|>S|D0\+4}>o XMiII+iH{VTY]ݤTl6Soo[2yv6PӗW40:' Il:VgXMvtcżJSD")i98hu:p6T*yŋ/ll\t/+*,YuyB'p I IDQ AQbABE/x<^<AgSS#jyyT*eopku4{UU=tZ򪫮غ kZoEߜer'뚦9#)|W/]X"oڴg:G/r\.Xd I DJ4Dsy.{r*q\&Sk4e2 HlW*Qdb%Q sA-DYl6y K0W"WW7FQLh4eR=>K}8T*eN+O/Z8t]tRš9['{xnK̹ƔuF8;6n, '8>V*JN,1z(}s\qd2{j5xɔpp0x¦EwZI$&ۏNjfA J1@H*gn7 n~[ۑ;0a5G<}}$Yl61r<6K ØLzE%x< %x"O$x<'T*IQEQ4M S) Y7AE.;w-򦍩[oZmV/-$|(Bo_z˖ML-[6=AW29ghf)Y>Q"0!'|>}*2si`n-d}vwf]BHlfslpl6 6lѰ P  ) .WTT%$^p4I3Ajjjm1 nV(44MgD$64,DnW*UUW7R]htUZm9p880`M/sR *p8d4ӚNSՍIgQBxBLzدNRX$H$X2H$d|C7lXtvtޢL2uȖL"@Sq`AӀq(3X 7}4 o p{-7?edv>0(8=7j?G=4(,}aM3" AIqn"b !C B((C`Aa$AF8F0+޼& '[s`EsQv(lp*$q-7ိh2=rOX̟L&Ux<H<ǣxlz'͑2Z.W(H&Vn7\2 IB,q8$E]yAB#9:֔Vө'f +ڪT*v${B(*u:T*Ib"'f)\a8 P(rكAo }̲ [hRY 3>wEttt)2ER"fDBT9.)ןyp&ر>S03ruלbw?Jwy_?(\SRJ*U "T*tڜN90F\'**jKJ*FCmN5X,Op8v$GDc">_ z[[gTVRCGTV8IQdɣ68U^#q=z<.s嵕 ˎyf28x%%˗_yd454>MvzPxv3G5˗n9s7 p "(`M&s..nE0?e޼f!I{yfE bQ__CCP(8j5WϬbz7_\zaX,X,Jb0?t~p:|>P+-.+cNln3MMFcW.mml\b΁c`EEZ]HZZ^f IvY^)G4N]fso JF&S8θT|.8}3.5:9FSpG>(ion^\_H.W)$U@ 22iꌢhf<EQîI8 vv{eC-uםX[~X?Ɉ(8Zkhs bKRÍ oLIq8 AH$b2Ϡz]y>:]EEE=d73G,/$Iv$hm=W$/0d5;! u$nm=HLw8 /+Q*D"n6Y,Ƽx11.rF0&mx# 6nO?߱ n57/ bL(/:L:.uw!j啕 $N==m&S$I)jFcЙA: }"KnAp8rx''<^*U4FC&Sn_j4e2 M>sptǕk閖BJ]vу?/+ޮӖǞ{zޫX~}Dװ٬}|񧣺ͮ Npn+W^tȱ˗wر7?PUvKii֭O3/d=.d;ᄏ[[2ot{10oHH$#<]f"4M{<}#9P쾪 .Xt]wǙJh4^G~9gA"@,|/D)TIQ@}>" !T*K&6Kis\ Aʊ:E~_Wױ$Ɇ:]e*jm=_Ȕ4i: nALir}Uuby]|6L&O r֞'+HKht%8N46.r`ggW}Kl"G|闟~; VpY(++rB߸ܣx@  ,YIg.WєTJl6fth>yr?˔J+ٝL(IӔijjtUKr:S]`hbL`+Wéc.l,Xܗ\ϿiС#޺A.93uW^_sOwƺ-]C3. 0 0EX7\~؉ nz31mLǏpuX,4>nN8N\68.e$c3uyѰDP}EKJ*kHM``>^u NEQtvou7o$r8lYSԴ Hqb_sRJlٚÇwfϨH[Z] rʕW8vgv7f {K./P=WS\²P- S@Q.0x IDAT(K_zo5T*J%&Tw]w0BLÄ73QhH|&y_eLݙEqJJ*52 ls:fܭj5Dλ|w%x=A6[QQUUW7^n7;p88!e.7CQXW9@"9wVPl; pDG8 7vݐyu%GV5ꫯ{,`6}4u0 #[>߷.RՙXD3l6% GE4Ť`aCQS@t:JStd*NQTiLҩT2'd2L& %%ee5$Ɂx].Dj**qL&s1@ jl\D,v$T_VO>{o#U*>1kX,+/Jxx}5 %:]Fg0tM,P.g86:ʼnjUU.'ˉ HuuBc--N"Vt(Á,B(k|=N0L=;,XTjDo?/t:e4v$RJLUUU_UUH$A}>wR@*b6n>WZ8{rEktAsKpOp :L .XUU vEHBa:5\qB-/)rh4b4X.PhF.NfsO(VWWTp> Pzxb b\o IN2k@$Mii\k}I&~Q^^WSӼtr}cFc؃ LTJJRS*u̢T"DP0bx(X~]54,,)otv0'whVjq*ٌ&S$ |QuuT\иӒdVV֗)jo?z4JeIMM3z}#O==u\pJBQ, VqV@B::y9ܼqaY˕ EA659uqk?1ǻ;o\bbjR455lv  d%u뮟?ڵ|?X'DB`Xv1q:cXkkGcc޽bB!X Yd{3Wp[w[.=08VeRIr X,A$#R\^ߨR4󹺺NNR8ԴD$b'iLJME ʪ`;Sðd2n 3Drbf9\}9vxys!7_ ùϳl6;HsӫW/=,'IO?YRǤR*dN]z}+. ݼvcwq+ of\d1, =01?2ыé'h[=a\T<~U*AQ(ƱM"P(?J.|LP)%MP(e\ f3䥖T@DMEf,%phjZ狙ʼ; +*RMFcf=;$LOlJ ]KĪ"߾}(%**jJJ[xr8d6h4͍ߖHę 7\v{_kn:M}vkݻ_it8,X,RBTj++x<x&kEl67:k:p.Դ ::UC,UU5`[eAJz}#Ifs3B8ZIo0= $I: Ah@0r?ϯPOz/ٻw?@w@߰aƍx>DyG3p 8zo5Cò{nFQEY-v6kkxwG1}Xl\#kR%A4 )*r KT3e)u:=åiBBh2U@+%C%au2)g`{..W7 Vh잺 EQ}}FcwIIEyyFSє|vݜ˪NrH$kFm{.=PuUkϟbRi?zD"TWW]i'\RZ,I@Ȓ:G"f6Pp83enrəE)9gAQT,+B L<8huyLʪ52ߙi 'ǣg5t:q(/)2F"IpDJDEEJUx{{ۦ¹|v)<)**JEQbn$W'&V1d2)r vM]{yUU%.q<sih{g_aCZ(3ׂb8pL%uL]]~pyP/K\鉽Ri:z#gh\.8KB+?R)\ 1-j8yeMQ4 \.Oee9M k>pMHDP0-r`0A /^gϾ=]]R3U2x<^4:+ӱ,c9~DH$Fp t?XbL&/jo({$IM[nilGy,9,q}K,&r>*,8oSs3ɔhC"fureb\&SJ$ @̘oh}nx HLs8<2y4$qX,K$ǜγ_ŲEF8֮=jPRYYGH$;L#IN*o0IZ^DBrZTT:ZGӴv^=`Gx9|:<ԳzK/=g;p(Oz z]楛6 Bv{G8pK/y晭_|Ͽ|_\.nw ?~ /'Iw ^"tzSO<@l#~w~.[v^_u?Mׯ+=\|Epxn!5W8Θe2W¤ {)~ ;[25@ eb\(r8\h MS>t^TRJ$*\BӔf4;=JWW7Apv8R}EE-MV!AQT/khXm6C1f7{f{遉x[[s|D.e"^%`0a(F#D,SYFmx/AX$_4-9&_!d:J\r}>e%IvIINWbqhwEuu  -EY,gR<@ UVѼ NWURR!\Eq b\, RT)*h0i`2T:Mt)c&_|h4֮kySF<w8iΞ$C*rMYF(1~$~AgSPz2T<ް^yҥ_V{lZjUW]ukQsO TQk"9276eKK$MvuL& BP|c>!)=>uy|) V-T@JY}&Sos1(ںAޖTOܼxCy ZZZPh( X&͐cm& Ixoo=Zdf(y<+`8A$$IPC #`d6K,~s,:Sǜ_~UHtu߿o;;w^f?R)c _bY<8~@E }Q4Nype_aO'/eq\8+SYm,2.03r?ܱq=Eg69>'`'L&>'> s2a RR-W(LИ1{m6S:=%iY,v}LNS==Fcg.qA5;(|aee=H#*J6dc5 t:x\7AE.;w-icۭVj_v-7;d.//(JW.xF޲e-[6=Aa&r$!GiH!j9,?.11 cY~7]dn}9ݛ3wY Y,a9\p<6a84Eѡ?^ zc)7"B*q.ՐҪ^W[ۑ\TWhdk<ڒ!ZmJ0U9s0E%u:=-OĀnذtLbcFd2p8Lhb}}ܰ?/xO?e'^UW]<3|z1. Nsm ƶgk/+//ąìn`_L"xMR !q H$$$pM(* zP(@8F?7D2FPdl1 ~:E L156.pĉy)bY,^<ռ𫫛\~:m-#_AFX&_g__v4(uA;ct S%/`@RnvÆ\.@CO= E^xv/ܵkn`p( :c<.]EQOl? Ks_P}rF{ ׋ m <H_APEQ0Řq@Q pH0  q0B8|~mH$bH4"h8 p8Ggw TRuJ @*ٌVO0 j g’&0rBLBє3Gt T '׭=܋4M5Ƭ]np(gD'?:y7x+ߏlٷGbQ$ >RxT* @ $l6{8i#}/o`BҔ/uo IDAT>y.菳5kkq;y^rE5װz}0H4Ӟ1$x< x"O$x4bfzhS.$2cE׬X I&T8$sra*4XhsDpªU}>GX'b#[MSĤ(i)fT*NEd:JRL{*L$bnP$\#IE4v瞶P(_ tOO؝Z*dno?K8NB\ !TtJn0to&LǺu>(@ F3Fo|m~sG^TPgO]PY]X%K/+2^X,X,|/]~exO>˾~ol63s)\w5矿}wޗy/F'{XB#R%-u ZAt$Y55ju)ntvs 0=W,3jQ|Yy<+O>{Wk'IV ؽ{ό+… x`O>{^uڵxd2Ɉ'qEU?z@[}tYK%M5Mss%qOwwӟbǷKt:Dn}:Hp=͖'x]w R޽7o>D{}iO?Ɍj8NDRH&˄B1AD"pX'|R¼E1@,D"H$pN-FvnG((HHZ[;_$4m{zZr!,/+/===my JK1 BFcW.$ɮt)r/RddOD"a2n07((;wv-fͪW_pٲvg۶=KϫJn'۷?-IS#`V]]3jU7c':]J?;9"o6$ɵ^T ۶=7 7\P("vQEQU&:kjϟ7o^3BW1{&,yu߯(GQ*|ieB"@,|!iH&.uy.fzMrt;;˭66.DxP!*NP4p8̃&'Pt^{H d "6'+AAi,r܎NPo\hQx<ۭӕ펕+/8xp$ٳgU?sSSc[[n--/L&{g\d1L Baݾik^^UU Lfg08gJE#!Lbt́2IR37tj}ǒc=ay ;>jϙ{z%HQ)\;`AE zUD/*^łr"-4A$l6e{9,K!l2O>a̙3gRX*h-I9 ln[NkOT^X8B^Vv灒@d~hl(+#| ;H( JH$WmޑĩcfLh`/p-0ZbzM: [l{_mWqsMVxS%,BWv?<2oܵkߢo?Zc ǟi'0OYNhn\. BN-P8==-//7֟z{]`t/DbT"I$2H"I\0!QTqxNr9<',Jmj\#VZPtÇ-[Z|eel*UJzzA Xۓ%ڴ!A8y{S[ypȎS .dM3s"7 MO(⋧ǝ:uʺu_VjU}!//7;;rhǖBFGt3Lx9ǒhV^s睷kFRǟuW^ZmZ/޶p\W}^zq8V*+W_6-Xp^p8CC[9>^]UóT*xv9Bx@(H$DH(q8nKZZ|Ns[Z|-B&Sy`^YyjLM.I<\MQPӓ%I[TQd/i݅\pٝc~8λ ]=Ǝd|'Czu r~wܹh4ϛw۷~_qiӦ9r4,!C`r&>m˓e/*W(.Q K_&9N:|6vʕ/?*I\nk!Vsǎ.17{;qi7Rɒ%x<^ pr8IrHM. |>'ry<p8v ^S~ <> "yJ?TI.4#\^o"J$B⫫QD"<O]]çXzɬ&>() *-̕Ȭi 4wWviӦުH$rgz睵\.p!?ҥOo߾WW/`ܸ1%%{?qfζO<WP8z jԉr @y@ : |}f̸]rul3T! B"D$B*cn+OoY( ^+ B@ki.T> Df d#VUuj/Dee &Y'QjjVjj`46L 'l^&--chjA.  Ǎ$IP>h5^(+ .8ff ̕,4w,_v}G~qs:/f[c k43\Fo766ƒs+LzY766edæ_~ْS0d]]eNo759gt|MDBQc^vǘ˜"p4D" #h. !ZgBX$ffBZ֖\'(/(,͆É5'bHjk}K%P,v%࣭K(5UT`8blnљYJ]_4B܋V {yY4Tyş /."8Mѿm8h12nSkmLݩ E݉wf;sà}ǢE“kyfИsOQ''| IbKo_s_IH$)'I.EEjk{;Aم8vd:%33$IR__ݓ1MN't`&VӮ]yxYg漫lY?xC0Lh%cs/=`#'9JV tEʾߙI 3'af߀(n.3 E"Qq$ BYX s,Ϳt_!.='P!@uuPջ$ZmСg p8xƺ8$)P(4h'H.P*C*lII6s+Fl-ORqy}_֏9't@Ka{ڵ[={xvɕK*s ?+,`f7+sFniӄu5o.\xOs1==WbIϖC/_qw@w$t !txܵk&K >_U= M4 Uţ T}}UUՑ/.rٍP+I57̹'5OOx<~FFnFFL@h`r8Nbvp"$|>Oya)}Ѥfe !IU@ffr ޿Q "cMj+U@cs[c(/ZX`c7fyX ]HO?xG6κ|L(f;R$Iff RZÜ^0x3B@h}a;V9q#yyhkYu j=K\ڃQYi:bbNzVH+Wb٨qw6d747?oen' Zv3?SO`5wOp:]FZZFJݎP"\^^? > hR \)IE"ivvoix,Xޭ5O|_ry?KxrnCv/#yv-_IjC{#.}7]ywh`L0Ns1ٝ ʣ#kh4j;NX%Yrt̉e݋0h@wx̴lZz͆&}#+?NmsbRMQQdj:ᒽ!.#%%!0/Hɒd98O>`T`t,,++i鋡dwrq޾,=dѡ݅ahQE"tLRCY\uQ^^qVVAp@eSqM*%7z<`儇x"P+%OOeh DHR$I7>VQ/}g`U#gN<<нH<թ:]N&75FMYd2E^,P0RSPwj+Z뫍Ɔ@fe$tkpӖrs1\pC\\M7>ܱF ,1bM7ͶZm*`h+[VGQ/[bH$X,Gq|s% X4w]vT죖CrsҎ)ÓIFI &5%%CЉpssh4'6 &5?8}USSn4{PNQyyC9뮮>t !*& ͔|7⪚N,ZϾ/=p\xtvm8qF~JK %Ebų6c/_e2Bw}Ljn< ؈dssUc%w9o*Z򅾹vnEf&a3'6sG ) \V4TBr;[,M&SiKy 켼b !L55eV뉳 77XQe0Td<ՕOK$[Ϊs 6>RhMV}{iy]} Yh4:oޜ3/⋯&O>79ԩc)]Ѹ\p8?Lܓ нa +3 rZ$Q(MJS(4$I~hlZ-P(ؓ삌<.1nnԔy<Ğ#JfȐsWUmi9кdFZZ6Bhlln֟wKԖl&} }KzPee%%Dig6z;`r"G=uB>ceV2XEEp8D Æ ?V./8xDs'J0L,H0s&OeqN9 Hɔ FTd*X{tyndl6s_r"RR2rrT*-B8 Ԕ=q8Ehm:cm:}X,DB姞%i(  }K᲻2#zqD -[ f3F{sssj5=O?O;ĸqcKJk3--uŊUuʔ fͺX7L,8vNI& wqƪT_^,\.O"+*\-R` !\vjvs1BQVVAVV>/dj/@q`0taL17l]Jo\z%}{bA.j^'+MZRӦK'Ǝ1&zlLI,[awg1iXHXy%B DbP"KbH$\.1VtNuCoBjuJff~JJIn54T75Ѻ6"553'z?{P,--ޚgaI&b:K(5UT`ݿwkbm0ѕG()1@>>lg)LYXS$gߛm{pp\%-P|j 8m^q-$wx~IO ujQg B: ox>v6iDLE"ѹs>xVM&z<ի_$Iͦjmw`u.fqƮY>ׇ4Ăgk(b!!Ip8\p6\.p8ޖ_ N\%I  U 5{B´,djjJ{.K p8P]],;a%[ST\G_etL _mР=[nax.ih1AcȔkn"8T&k~S` tx@Qbgsvا4>uZn324b@_e~M ,<o4&33{ӣgIɾomc {}_{wJz[?"]wݧVnOKK/C'dBhl㏛q3=ؓtammŏ&iOjnӁjWmƌ"_N|ƸV!D@ {B@ [@ !PҲҲ!F#&SCcc8 =TS uu#ŏM`25,I14W\q$Tpѕ@љm7(X.ѕ=Dרnk9(H#!L,mz9rwMdĶhŵ?%i8 .*ȭZB^'HM tu!62Lv;F {_o()plnd$1v|ᓻ S4i"YXѻ<̧'ׅjWuG1F))LQEa)p4 áh4"pO$Vgt$Gҥfd͆:ݵC(2L`L54 =ʹy[$BRs$[7:GEg8; Ɩn1?D":rؼ+tH*S6VdKPQڬMStH1fذh4zfxTv)a>}HVBz}}ffǫmWaҤwyG]74sJ$7.X8k˖N&1;b,%%]P4A8nhknZhwp99iiv;z 6o KS}}@0 FCo{j|5@a!T&E2jk8qD,υDW`nVvi_7漢 `覢hDSbtaJ>Cȑ#>;{ܽ\e {Az}rYMMI|n+pu͚ }g}ٓVtZmP( }>d25햁_JK)pf}N$ 2B$BRѧ]eI>cM.#N Ժ6 3_NW&Z=|]yJym8kȾ .;=CNh~`ϯ?ܧ$}-AGSOZ\`/..\Vs'a&]Z1$愴pZj itw?dRcʚgsmPT5yFjjH$"I}Y`EQt5$r5BGk4]p82]7HTU]9Ꝇ\.OҪթjV&S!p41-&֌ J`P(Fuueu=#s22BK^_dOo 7q&g%>ߖų`{N?,9nmb{FhoؚVLxd_"zK9>_K?g?{ڧy۞O*4$ٹkAanNgnw!T_ I|^(D? W9н8}MpSiogꚞ4^\\hB٪i_ziMiiY"ށnO>N~˟XzfoٳFZ.=ģ@ݞj\P_< Ȣ]l㧟~0w@`]wMsQӾkUÆ ?V./k&ZVR \seqqBO=lojNNQS$Y[1v:6djt8I/ +:h4֖ӹzH$)(!Ihm֧]eIbb :yyGXWtɋCologx84֙MRpm&7EQ}umR -jL |ERQ<9=5w^b>tI,_IjV nl|E=Z.i+g 3Mp3]53&0Np4wwiqYN\]]CO畤Bee1t03oޜ>x׮=cǎ7o΢EKҎqhSgB\v%w}j^{C?s.=_]]e4X'R)op4?~mݲb*鴋?FwSݒ*\TjrUovf3l&40)LMA\.[U_>_}t6ogfAYMuuZ,DNωlMk7x~?_P 7\y?_WZZPkVReffݻ!8p…t3㲚uiӦdR@tvx_ }=ZwȐZ%%x`D"z}.5j$| ["Fp½=Jpe2BV( Z$Pb1Z&r٘#\./; ==$U_=wP\XxH$DBG?k8K1%Qnf8H5{;xT*Ag@aFi9t3K$Slݺ`HW5wsE~ u4jt!ecáVXsۗe@H3疧^n4:kUWiˍF;.YӬ񳄴1֠~ %%m~7NZʮ1=I<zЧxT.*RD"Je< a Hf3:vtzcp8C TWWpQIyf3֖E"}r:Pn t n/~%3&40Vp w}y&MKPGC_I"ǒ4d&M@״Z9̒}CYYVWrѣڹs71}t֠1TTTsϝJ-1M/vHC|`0$/ Ó"|P("T,J2Hm}q8V˰ddegpphSSO%id2eAp@6qW׶anك:̉047ۖ+=r{ u4VMT$FBJp;|믣q` & o.^f`_-]ذal6&.)w [nBG\hR/*Tܱ8PPf͋M wrwp[*x!Adffgrp8T[[P{R!\^nnN1L z=͒hXˁwbĆ$$PpѳAd++hcٳk5uNN6]V\W:8n9;w;vl1a?}tJr:1x,XVNgL 9EQ*N3vw}n_X7x [n+Ǟ-^(nWV<oKK |'W:Rɒ%x<^ p8A$rNx<.W!-\n C^x~mi|A H]]P} (5537$~/(Q[9+)]@w;YUTCNc>?K EӦM CMMt/:oܫ>Pwwy1cF^Xb57Kl3aN^ ^$pV'']@QP7`ƌKoڕ+WN:hZHl]0>Lf#LoP(@0[@0~/|AvvAFFAp(*j0T=OH#I ΐJhYώT,}DN0][͕ D@ףܹw+y鍲;O. ?8|}>v4SQQy 4fYT$eaɪl.NOo759gt|MHBQc c1EQLD"HP4 CH8 á`% 23H99E))p8X[{d(H]LեP ,]'ZA%ew*gC*Cv`37$DshÝZPFZN/tecaI&N8,$1}%۷q}ܯ$AP)+OM!]AUQdso1`L$I0;V$!xw]D=Dïf]\;33 d?.[2ڽ8M.BϱXmkԳ \ nj5bTU#D"i4+(j "b K(5UT`ݿwj4',,=M+eH*?{LژC'CfOWZq:ь1m/?vW緺to|>NȐs&cqe%%7mڼdɃ?s‡齋/w%sr |!EEjN.,̇xSg5y{~zeמE~zB%>dDe`nrr$_ *UhTVVJ9ժ^{;V>YgfգfLHrݕesoSʆϘp]L !IAFV\fCCBZmz^^P((Vb]Y"68 ́_}xOBmi奔~lΦ0Nnq@C sH"Cb+kWxy;٨qw6d747t-'' Dպ63+>TZhR67ʃA66 # In 4[?m\=I (Zwm['PrmC{n@Q~Ca] B';tG in8&Ayt",ݰl̉G `BsA)l6!`KCCms>DۡRiI XSSmoFm^/VNۧQۮ?vTB@_쪫o3iM_hFmvn!ܶ7V?ڃanNuH|C1eebI,L&fme CQAE.]Ix( 5546N)fETbLKsMMiқ)D\ﭓ5O|E?v݁߾;@4֙MRpm&7EQdz'}sgڵ٧T[*3.E)o۶]MV: z̉Vd &]KU!!5675SOODjjVvvP(A$,%Qf?M=`n}c%F,X BG}' ?OMThpďlbX$Y,헹EFKbI s575]`99mciyܽ IDATCIpMNѤxnlnXngB''##7+cM&^_y,,}M(7pJ@;bqe}g}ٮ<}mmc ǟ*--݊lv>1^|dB}#F s=+cnK,>1W]5;Vr?R)>+_He3FknӐ 0ʙvU9٣S*5*NjڤM&h3dgdd 5z}U0ؒYXrs2\pCDs 6>Rh |>z޼ۮ_ks ,XP47o̙Wt 'ߖ嘷ȑgN+MrýȤiVs0 aW&^ӂ$*V)X nbi6].{bR<+ %% p8XWw6aS ]\t/NwzKpcfST!8r׮[(3.[j)Ě-**7!!6lsvH_juyy)\jnpУI%B#` LTjjRr(*lnv:m $IfedI |z}eSS}wQbSO=.He+lqzonnZϟi77nؒLKK]bb2Y.Vs4;$_͸qcU*/TTTgNP(RR&SH6c6@ 7vnxXE\lY *t$$%4 `o6!`y}BqMOݾ}ǴiS~zTմ``С241cFoC6 ޸K s572U Fo,I&T%%7mڼdɃ6 T!)e2D"JAaviv&BP(`0h074ԲɶY;Id/7U0\v]MccSccq_m8^t:Wɓ/HOO[j9Ij|>:2H$Bo`~KgN[P+`㘅O`э;nձ:ery"X(DH,?.CQQ:\.x@)J$lvPm:`aD$P+d [@&|>:rĈ&!D:?M~^}  䥗V\5={M~i>i6U _gf/Tm/+yCU^LyX+2ˀqУwgt/Oǩ$ry<BP,KBP( $IƌBFnvnq||%$iiii"B^_n0Դ,,@Ýt2'qyܵH4C4jv#[X$l6ǎ&M(I}H$:wÇϟ?jdRǻz+$7XcٴZͶmFl67n5kNq};n}*&;cyRUGU#ǩwL=ӽ2wCQu}w$>E@l Dq8\. |Z[y<>] c!z D"--mi|ޖ [ fHrqlnhjZ1ƔkMuZ\-{]F.ki8O_<;6i1!4w?V[J4>|Kv.ٿR^o u}j't=trnL& F]㏛q3=ؓtammŏ&0`0m,Q:Z R# ôYZ"Z0lZW{L)Fq4W~_o.۠J~p1%a0Uj_~#B]1ۋcPF]F$C3 áP( C ~CxlB S6Io67E KB?ST̟Ц)b~Tiv'nM˃RN7fU6Myác_)vyb*Ԓp(ҧ9J;H1&??3F,ZX$:+bſzl86/6DL&s|$/bP$m,R:г?ߗ׾riÔiVsSj>_C_;dxb1xj=X?⟿=?WOo&`:=.Pj (Ea0h0FQGFQ`  P(óyH$2&MKW(4!amn 4+ KC?R!EQphjr{oYxԙg7ԘuGkxΝ:l×9wVnk1>wsӣpN>Tie-Qo?O8CnZWS^ 컋R ̓ݱqctM q4 }:2|N c3n|nxygO,Xnxᒫ\yyGa@a|%#tʻfBEE+St0kY"tT{>ҟRt:;NsÛv:=D;ts+Hxh4`خm6K:.CMHvۚ OrzA?m+j<_9&Ohĝ3^ BR螥^nhRdd[98=G]]1;rny'9htL:>[]b7 xG^o0ݩf 7mڼlRŦT*^yD  o{9W`!3n_1;7EOmkMXB r"D"ѝw5jh P護ޭԩSnf'MuKv=ݬg_~ٗ=9:]VTjWHd2LM]e01~nYڑϿ̫̗ϚP-!ƀGe5s/ jWM4ͺiX?te_ݳ MN. * ժK.7ߛLv%>t@w*y`oIjq$IZE!J<%N/P(V**NMDt'rX KӶXkߺom|`̤8 I.w/G鏻~9j3Jq PemBta(!p_WgQFnb| 9gtMM;t\td _79н8hnH-6snF@ @ulmy 濫ԤG{ ~vzN6btΚ뻞 gaCxZSo(<3͍6XZ_zvFq*=c Yib6k?0v٫V-))w79 X>Dsr@{n^hk h;^L)`.{ ˷hZmi{=Q$$T* 7NIԽk=oYf5R ժZáP `֬t9MMMihh<Ώ/{0X,[^!]cm[vaeaa rȅ"aC5?{WFB $ػt߶2N E\A@uKny_WL+X٢N{_'sI=( @AH-N| f]CQ Pt(t n`jcyVлN?@{N]=tZDFϘ1}Ȑ|(*6r..hC_zi8{,!r?Zm 1'{Ȅĸ"BH"Qd \)(b)@VƐl,,g ᨵavCט&gOj)c7/5݌ P ŕb]/e7 Ы!+?<2oܵkߢmҴbV{~~.pFpn[*x<ϝ ;}snVgҤMV[dLو,jQEqCe* *xAYG(mwfte!:&m'>7{IZҧOD"@ JD)*WK˹y@}IUuYŮpCs8iP{X.pKqFDXXyE\'v>T$ry^---w\C@ӽF{nD"t˙3gϞ='f^C)`…B >˼F}B0 S,@  E7@ DB>_(x<8 ,k5`VLsblgrayFRYRzLl,V{!ڔi*m8x5_~MNN.L8n˗1bcք\_j[qj3ZyMH Vd2UVVLFh2ʫ+*+p>BmUbhqnԼ15zUUUo_je)eVbel)eXj2fh0LfsMxmX,;B0Bp@DcKFAVa7rq]cƏ{ {li~!ݻuvqIu1qlY@:Bىjf\ʿ8Хn]rvG.KۄHBmƶ?п_Ltʴt $&'&&Vڙ}mOly\Eӕ:p^F+vGS&sv/aH#}jES2Bu ,K/^VTTl+ݵk…{oyVVرrgwi\6*ە17B!Pga['G^^^/j7o_jNW+;qgo0,?Z%%%3<===<}z/_^*]!B- &XVFk4 l=pF7{ 9o+.]>}*0#{7Ț4iaTVV7Kӳ]IIjH!axO.3k<7Btv#pjKmBJVlPJ ]RRRYJ\|fl H&NoŊ5Çck6:{nnlJ;cY:]P(%xŊ5i-x·17B.͌wsv/#UepvBk!e4?`9T=jV5ח;={O?d2_޿ӧi3((pٲjf{&Or%!Gk3nm]BɀCPJG}x{o#G_R___.>hє,{_kuS5qc[m cn\_'bfj3 CRcXRJ C:Tȼ2j!:i M[.nٲgھ7;v gY_>ed6+x<Xb TK{.@)ev?cn͌ƛ/dl1}0}=;?ʇk2U*WNJ Kuryϟf*|܃7,WB54oQZX\YY-WT[훟&={־}Q ~P(//>Z|ɓ':uko }!i|MFT6YU{~H*RRJGNv>TJKYۿ9׳~<Ss mǞb;zP.G!^BPaEmwww//OF{ct~YW{ ۿuЇcn68q~ԔӇSCe!?']EX @䉏 v͟sS=FStkdyNc&<¨M@Rs~=1s77<9\Xo.Ѯ}{{+!,x{{-\P(4 "O#M4^ՉD•+7~qw%'O>wTSUUUQ-eΜ|}ez}yuuuFrnqnX^\sko.W`{cn"4pXڔ{xwpl PQ^g IDATPwɒZ/҈7m_<{9jb/}`5\e)ݰr7'Vx!e)L/&''&N7sxyyN>孷t%3g?~٬lVn6iXJխ/u`,%{^~Os_ώ0vZ_8|~PWB!RJsbww7J]weffi:J'U]JXn}Gs;]9/0@8cS+v` !ܞ]I'3"cc? @!$+8.7k!aj{0FY05%"aH^jʡg5BS2 ?~ѣ'(2M)t>>hKT9/2 \wA+/?ؽ~n`YR[d\<\#Bo}U\ʋ"3-UWe|>{x `TWbPۅٚL=sӕ^VBVdS ut%wpd2Yii]vOoF/g\B&NlI |MF_aw"7VopO#ԩSR?oTUa_ dhWu'#r‘+=bg}i] s%oV{?=qɿuZnÓ.0Dbsss+s#-Ɉ97UP Zu9Kx@fBu C 88hĈ{***?xo^UU-ZP+yV}̴Ñ  _Bﰰ!s:tĉ3dJqls#B~ g!PEnLh4l'oyzH1FȵX"ޭەݻ ns734w˜!B}4(=q,cn\ OIǖduBm293'ٽ0Fȅ4we. Bcn\O%wc]~B! cn\O'bo"erCyi:BØ!i2"d:E>ɏ*H|=*>zw!rsќ)8!+ЀhgwQ0FxpN;0TaO߻J_R ['{+!K5{ZYyOlؚ xbNo'}%_/sϿ{VrG SUT* Gc1S}aTA&tmyOzM౹V𞤱񘘞!r-)ia79 OE"`i J~=Lf;ΗU3ptܳ?2TC!>Ͻ3~⏷=H*489T%O}r CG=;icdxs&(G_ ku@s4{o\&BBW %Rψ;.Ho,'0DV^VUYަKQE2\>Ƙ!WD)]O=w:CG&M@YJ f]%t@B*,lr ~P<} t ]t+Nƚ|!FC7U"T\! xf K=ߐh6Y}ĿnL%]bZ~|]UyVYyg0C/:q*C"e0F6{wn?!M=F)&?^=3=qTýW?\QV..Zoyؕ 4r|Pas#dVyuzLd_-qgVL[%؄_r~/P:ugxDeAM?TsGӢ rLTul%m+Tl\wE:ydՂ !G$M9`湄VYƵyPʸ>?/pS!Z~+k@[\^!/s2Y@"@!~*0-keA>:$IyNّWjr$7` !WawW @!?umǤ1=H=pT,0?N:> q\|men<7B.*Jwv/BuX7,ZE%?5\\rA{mJԓڷ}_=eruK8ϝ3l \B&N^o#"~߽ٽ@,.~P㉥*hmMyOeyuUwi MK䤋r ZMsss[ֵF!,{(jNP\9!Swұ%Y#P[xgRUpSG17B.Nw}(UepvB j`̍ӣn,gBȡ¸^4:5K#D,u"a@/sO#wկvحϐ@H%}#r禮Ȏ9+BSXX?!a!#d"KM=0(O']_`kra#[KxpZ;6či\g;_||زuA]M>i- 4c! K"jsިa̍c4{R N 'z_YM3 (P 5Ya'{*  @kǦkE8!D]Zk|ǰV?֎dQS㿮 GN?JGo(\nB/a!\7xkFS?NN r&F#?K_APmJ`) t*}h7_o!//>gZ{TUxʼ#|K}^)q ]_XtYI!>l?]qֆV2oRX;uk6J) /~aMa.)ﰘ4L͎?,K)j2Z ;lΛ^}l={-n F!8.gØ!u7wa{# y^bPMLMP\); f= | [psi '^;-_֯pF!j!a̍ӰPaS9dzʾoOT3[ֹB!!>oV1rRW[BÔ*N O-.H=Ms;)q0cz<3aB5 v1Jawnqn!P 񆔴Yр6~\+!bJM :\Mvsp%GNJ%`Ȯ]̵,~w >+'jU:BR;?Ce6qտ;CR_uH[kz>Diw#m!P]iqbva q[#r\doj96s#t{:=B&SmϽ;廃AM^]?Yi/7]Ő/Xڷ~aj2 !z]gxDeAM?>E]߁o_lWBRsW^T3?7][\ena[jfu5RB6\ٽhpC 7C]7q䌬#!H=urRMXh]!2d)+;;Ӂ<܄"~eu !r"s#Xy uzܭNڬ.R¦jطP7ؚ*Jc[B!ׄ17BwWc!j0FAeRUB!17Brv#k+w9!PB!j]Fȵ0ulIVg}!:r!JiP B!Z0FU0*E܍ !B:r J'bev18ǰ,%_"jewOV7ͭkB5 9RDD,{C Y+8jke`̴yL߰|O\߮wL]VRi0k 7w7Ȣ<k6LBjO7ȵC6$b)=/y:{ҭ+K!?q*hU*B!ny;sHI>n 0ۍQ*E w_unJ}5b cj C4'U"xU5C!$05-yWl1[ Kj,7%:uy!Z!Z6m%ږܦ 8 ձQ9*ELT!!dP~mϽ;廃AM;_]  }Re[hӊmw?>k6Y^eu5_=BօsHF+ouBڞz76Sr:1wQǖtH'MnI ܞ8-P"ԩͦf@BdrR]nm/7_h["CcvnBiܼv:rM[򕺫.P)n-lTmVWFc5T FB syM*#t-A*EKnBsZ'д#趨TJ^ pn^8jnkQst]Bud87.:)W|~\\lP`)))׺,Lr#Bpn^9vn^bb+H$Ǝ6 +** 00(>>'%%u Wؾ`tֱ%Y#P¹yNBy}N<)==}ǩ]G pwp6`#NN<2UepvBÈ%ZE}}Cνc 瞟lr^-œ'Oi˖¢"B`dJJY{TE`h_f]eӦ)]}:Lr ʴNB&ZZY3-a7,߳㯭|(5)o{ӯ/U J*}a]h׊ b\$3?}z ah[q1aE1wH7oX% j$B-ns7z+|{Br5ٿ7 e-l%^bPceZT6YT9%^q9{ZxT.Zqo8pDi2L=nxj2c(K|VxNUΕB{FB_*Bw87q{jPJkW#3zh{n^_j~x<Z&7/c̍(B} w5%P@IWQP.Z{9l€Pߢ\-`kOqSt{j2YpOeʹOu}ÕBHoV}܃ws?p8gԄG_U "]`[jrb"fF' _Ӆ9ڵooow!k! [p>=b49ܲ`Jɡ3uXl0*޹w<##R6{Դ[H$nnnF+q~駼{ǎ׷짟zw_MلxQ#ʴ.An 玥My|~;}W幹(ZP" r4@kڋL\Pv(>HEJKv5[ wK,ۣ~;|ˋ>6otTlן`^8~Τ~K=a k1w_VW[7!Ppnpr;0 nfڧrASe>Y:U(dYX`æ\'O#܍*+*.[Z\\<Z"t,%{^/=y]!z-?x~NXܣoęi{w.\sܗٯMW-z:B{_)(p7xܶ!5M=[,Bx 0>l{aAIDATϩ.<|+ByEW]ڲu48c{1|imnjBj/'D~kk@? 깜M1źE;rN+nQظr-sru ɪ[BrʬkEzRo(pfk3MW.{is!9Pݛ!RZr@r̶j*B>RT*}^TENf^իgQqbyᇭVm?.o&-Ѐ,eZ aÖc7ᓷJV-wϧTָK_٪R, J=˲ ;7jVUWh6T`>|r]_ <^߄gϝ-"3p{?LvQ*Zu&B!pn^ Ə;)&%')AeN<2UepvBc¹y-7Ѕbny)OO/JiEEEAaAfV6@QEX6G!887EVaY6MHS(QEؖ}2GBӊCW T2ByM_Z\b%BQEDl##by<&Zql|WSqpȸ܅v*~^:UǰVVS0,nMqocsGY/zDCQ * X H{@?zK~:̢G/2 r4]+lKM΋KkUzMz!y~=UE2xɼ r43猸wTm2>>:G!ܼto΢#SH7s70сӟg{;է@)PҙsG;?"翽v955s4{o\,KT={9jb/}`5pwlR?!g' 줵V+;xl ǿ;gEO!Buܼs:ꝊJ:݈u}}^nuͪ%t]v0-'NiL=Bүjz8qkfzK< GT@B9с?( z>czr-=7BG87Y8zQJ1F )(N ?M>IoXMгBXx!BB0\!>P 0BHYC V!X֚BJ0L^\C.rw4 ~j#dZ2li֑RiU*p +51<}t*}q!0l|O`he]B!/~p!z!{Ƚ="߰ ,׎R^Tly!0htlqv!@'czd^-H9r>0[c߸c!P[٨QcrS#d"y2nFwl8 RMƕ{Wo[IV-Z{ImsGӢ rLTul% !ynBJ 7%^ڳWoEffKnfd8wEY.62qUwCMKVz!C$%rj_Y*.VЦlb|d:um?Dx<7PR^ZU]ي;eh_! Rri"s䤋<)كnnQ%|MF[kRRUgw+1ũQkphl-.[P MCl1WQj K!C.x<*n9a^0 GEr伻;{=E̜; yc̐n*J/~?_5~E9 !mt9uQr7:bawϡd]$҂2sg0WWZE"pXڔ{xwP \F`)9wĹci߬C(ۋiY.][^ͅpwlR?!gS]/Lh0g/?gZR?pT̞) tظb9R46~$"Bcϩeh\+>{I+%t=%0-'Nij9 Jy+<{,h0@t+N"x4N}k{ʭG!rA,[oណkIJ0r[MDQq, ]ʁ0_ _x;~mLn[Fm2O55Ps_<۳Q*E0GWZXYYh[ w_unJ}5!ĶSc]p.z@5O)ex נ`5H' CBHݑR zB_|*#{@m7 !B5\sw9u'v 鬳m%R)"nQ埼 W}I|*{j+/0 t΅ cC>_촢WZ0W==I>2ORʕYm4*ʛ?ۿ0c,54>B!볟S҃GRB\B5omG̩@fsX3s=osmeI\L7ga2MnInZuy˴pcz' sbnS!j_G/tN] y&?ƹU}wnh3 ZLkp[H`U(& F!P\;: 9% [;aPLk:p&MN B5}~ϩ&f.p-FhEF^_m:#gޙ9bcu ONh{ BיYs]ݜ:f.zn\-ghew].3}Si&ΡM$ޱ0 B!\͘):hub0ܵ !rv:IsRU  1H ~~a7B!(Uepv)s\0ݺ,Y&UnƝBV;N!9O[ҤQo+7 B!PV(<]'l՞}#!B2ts1wnn.@ݯ=׉\K# B6R?ƹy-Ԓ\}MJ&['|9p#Bȉpn^oی-nߵ€!BsxOn?EBv6+F!BȹXM&sY׉\K#-*17B!PąRܼi<\!B# [#B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B?m\8fIENDB`RaySession-0.12.2/manual/fr/images/exemple_session_lancee.png000066400000000000000000000517541417052567600242740ustar00rootroot00000000000000PNG  IHDR4L mX pHYs+ IDATxw|SUǿI:ӽ[D-Cdoيl2d(T@62Dd) Pʦ{+I?҆Mۤ4~>{{='w'͸A;bikkCJJ*j(beiTcHJrL!IKK#--M++d2)IIkccR̵m(B`l1c]&#$4-gʤL6ۛL&CnkK|B뚜Lzzz!H38fghd"%5-`s{##4dx{ߋ 4,OF}n;NΝ>+QYYZDBjjA;]=sߝd  4̜577|۞(j̣*L[ۋnwuzb׎ٷg'fܘQH胞,?Ooѳ{79ue˔sa*U _=,]QO'ɘ6edۖ8zoɞ]ٶ' ˖.ݍ5Vo.?WWWvFzolO9Gb]l^lڔI 2~m[9y׋03R)ʆ?D @+hѼ.tХs'=kW}Gf[h;W6nX _iS&ѱC{.ÇЪouL{=wc/ٵg:3`k,Yײg cG҅r{x{sI1lH$ ~)@'>>>|[ǑÇXh!.κ&ƍEf|6ao湎ŪUطgǏN{%;yEzTE=RzB;$,,\Ņoc̯8;;|AO~޶ K S@&m:mѼ!!ܻwG`oOHW?oFgyyؐFW4_3)))1l̾H$x{{ЭkW#6blsD1( O2й+IIt҉%,k$''caaA3`Pxzu6_o&"2 hE5<=y?^V~|cJ%}zĄcA/X7+N9˦~ё6m;w\^nH$XYZnreOOO.]+m|%sQc#J1m*ӧMӉ|ɷ˨YvZ>Of'1xi@u\xg2yg9}1O(ع6[eேhۦԶu+zV-}9{OJ.Mrvtg~aa899G`ggGB2))_?sԪYFCHH<~z@&ic֟u_@JAzmN9K``XJ,a557lN.?)Q6[ (6pbH忞þٹ?/PdI]c/RT)VKX߼{mVc^^aooBcLJ5jah4T*6nwcook},ro (tXrvnJ~UK<==6,,7W܍eqa_5ujipjdr|ڷ׷n;wC_`PCG|8kHOOƂo=;g,YIII1cGb :͊aixx.WL&͑MÝX:T+Q1o$XΝ6[qӏi݊e+VmA&O$*Kߨc/ZfHy7hnc/3:̱BӃ*@XXRgg|TAIֱh}210 25˒%2a8vڭ+C?[C"THuIDJu< ?u73B8Im5ew1i4|||X8.}{qӏyPTly;۶]Yl)-۴#55grYU I` \LOݻ+擸2Pr7{O iiiܼy Z ՁX8x7Ǝ /agggȏTd34VbbbJL|3ƞ3KzP(by!Zr' CtL LOOO4?5>}ۼXCrGqm>s/WN:G9z8OZ2fTgC4m?|[tGg@~}-,, Cn;$$[9_ʕ@VsitRL7 )u@Gmʤ\q=s{YYv={}D~XXX JSǦ~ePv,YZZҵKg=;.\ΞèTBmg~c^ncܿ#&u˭<;8Xl)O*T6l䃞=ڥn77W< Ν&+I$3gxJ;,}2+YxT녋عm﨨h&MiSШ5ܽs9ncb Hyxzzr%]5k2s~ Xl޺M?gݯt,fqqXdDE0y|m6zo%"2ggx:oǐ ىKrouL9:@Bb"IL<`©g;o>ÇPT$&*ټgVf֗3ԩR=vj5>}zτa_ws+Ng9~wfYDFF:Ol<< ؛6u2g!_~1.4O‚aC3igckk˂osCL69fҹSGR `y`=j&ZO[ON>PP26gȓ*,/D3j' Z[[`Oll\Fw?TsF_bb6䶶DG蝯%NNNDfkk̂b|W%Skooh BQ,a81c/`oeTnc/rC;}(z~Ddd$vpI26/2MA&✯w4^CcEP,B<^}^P YYl)gCVZ`jϘ9'q.*3u$[ Tp)4J zW B@`Y#J f*@ 5B@`Y#J f*@ 5B@`Y#J f% VVHeRe@ (:5jT߻C$ r-$/@ xJH-,d(I9*dme%DJ / h^vrT&B}@ ( iPNsR@ (& iP%@ 5B@`Y#J f*@ 5B@`\BI &RiiD@Z͍dN&D^`ed RiٖT^Ko {;70(_eJm6hތ DrJ5mZ]6ԭS\NHh(* :thG֭)_AdبT"]vYӦ/_8bpsuK玴PՄGFZZ:o@VkmoG۶yzuu󵱶G[*BCC_|`mU*WҒPNc܅4"r *5,%XXs=ݰtq3oJgƧ$߹GzX)']D"!r-^sTVs)R)Y@I ^&};;; DĐ* ;;;6n-[F.wR)xxxJCr-fuIXX8o`"""X|)+T ** WWW6ʕ+ˢINN&!1wwNڷk˧p Hغk?lRɴ_r$%%ѯo sNΦ5uɟ/0㋙H$*WDPPݻOzB;NwY_ҵK',--J0L&j*5޳Pzҩc*T(;wwwVcFsO_[mwɖ~Es!T\t}JKa2&O S&i;3=+I7n2{1>3>0(R@R,sT*gႯQ5ʛ7{O>ISH 3ܻK/Bq!MR&ѧw/(S4NvRRRv}1߯\Ξp*s-Ӽy3 */}]a_!-=hF JZ5ٽg/7sGoh8!"##9to//vG ,,Bs^AH~b1-,`uܽ{ ƲiZ>8A@(d}4 ut܉+ŷE3,-,P&)s9yt֭߈ӦNfoڢh W]ɓ'\vcs?t܉~HK?_bbb1r4JXt1ƏqLGG6ZZZf){h4yV%5d{>R "4y';Df ~/ӳFrK7UaQ999_sm䶌5w7>Aҡ}; HZZ}zD5 nƶ;رs}L޽hڴ !!ԭ&~OH$ܹ/fRdI-Z9v,[6Ōthߎmvi0oխKR F*UZ&D$L ȍdXXe]bjڴ gΜF7(U)ALTtKKKznp;{{{]cO FGEi׶ _QT^Bҥpvv֭d2qFtО.#*80۵S9pW*/O9`A9L{ON*s.VatZ[15!<_ۭFU2笜;Օ5NNG5~ƏC\\) a |9c>AZZ[F~}slFzz:C sV۶_0w|‚.;Ѯm@;geX,(W, 6 *:/DL;OFgjN>êk^}9p s"m=bVq(%>WajhZ"^Uf_vnc2D"LBBb/Z[[cg'G͑'HprҦ(OMM!DȤ2, &Hpvv&))d#And.sjeL.1Ε4 I,%nuiK(  ~64s(%Ӓ Sh'YʎC)hl{Qc*WN*@ x)#u,lt2Ehҹ¡|}ڎRILB%lWOB@`Y#J f*@ 5B@`Y#J f*@ 5B@`Y#J fM}ï9#ɨQb^s$!>_CD"LOAA1Y" TS*T; 3J]ԬYP#)xzzPN]]BR#xJI3ʐH,_-!~/%vvGw3NѨ5 edD*RdIl嶅kLHJJ"00 _^*S@2 Je XD\o~uՖ}5 ahr]`^Qߔ,YGR4(f}JR|y;}Hcӏͅb)PIxKE)I$S9q;YP3ʟ9 {Щ\ʊ@hSQ#ZQvuY~.ZRY Hr  m@ pX9 }\=*Dݵk\aRR`B-gb2xV$TisN 񪗠hX | e"U$zOЋZU566nlQG~Ev_`,Rd2 @PPNTT_Cb J*ź PTE 1hX 4` d@RB&HxkjnBLѠE\p?#%%>ǯE3:wlÇzWL+kAX߻м좔xCBFk8rO$ڟwF vF h@ 8zLn*@rTF#b43DJÃ(TÇ&::RtiU‘ ]:wDEE]&:TC @V1Yh4&7o;ysf1dV]*+WPc΄aC2zDEGOau,>_;;;ƍܯTW\L>k׮ۡCݔBE-4[t0 EXhvIMMۋ7~.rqqڵ9yAzߝ"*SAAAhԠHeER!(_ gΜ5-TɒG<{~7Jۧ_Κ[("e/"X(H}~75k`ڔxyyꊋ&о}wA2'Oײ%'Oc$%%k `dp,TĐ:C4L"H{ҖG<4,ۂ1R%Ji,oF啎[2U*ޘzxHZ14؊[9}Zme(r[6WCq n'Q*ɯ_ssّBzz^iz"wZqڌjJwrv…z"5龎X}AQT? ''freعkJIIaڌmg ♭}ϲlmllHNN\\O2OJFNNN-[LF@@d2+VՕ pysS‡0dɒ/_$>}jt&C*ByB%#]A"P! dY^ dxQY2ʘ4Z̓2>+kNllT+GTbRڴ㯿r>P}:~,ӸnndRV~c'NU~-hӪ%~>zBF3,^?5aHr'=Ozz J~{t]|||>eߨnR]Q,Rd_pA*Up&éX 4d!}ՆG{t͛7_H_L*dvTg3!"LK2+N^De񢞉K=xhiY8?{VV,4*uD@6nsOǏBrM+aH$\]ݐʉ]w $~f8r8mh֌ ;_qqZ$227ҟ/R1оֲohE(d2eKeb\uW2o,dR)[~ޮ &,,ʕ-GJJYnQByNHZv(۵6TgigcmXiP~+͛W#wÇ|M\\,AAA^=Ԯ]t  ު=oWr%Pv```amA)G)5$rHKN̘WB_l&`YB|`nJgٱLED5 ++JB0Er؜{q^zW]QR~BCC._H_L̟*-XآVHPe T=mZ#A_~A<*/tSzՕIS1uzUntddr]e8-qn$4,L?ЮMkv~[}+]oKEJya}@wrrD.%55䌛o9- xjSkkOٲexq#Nmt BA 3f ɰ˼N0Sgx1#콦:X[[ۧEJڵuOݺvkGȯ@TZjU9ĩSmӚeJʔ.c7*̸ nt]QѱS'~i3jbҤQdD$zT+W,3̝;?ocرqi]sXd)ժU{!mG e9*:[X.#F헖1IuճĊg)$ xWjMh RTSUU]fh{{dڴC99J{ \/̛N,^\/Q"zCELl 9n5'NI`;2)7nre~Osy.Ųٽp)ú+IHHƆ߭]p`QRt)= }uw1}gDڵҹfA=u6Oҥ=O+ظv5.931  9%Ǔ˯2mtZş.pRvyٵ} ?~;nXf}}},7+++X|%AO8s^l2\2܎[eFan޼7&gfe^u͸qcOttкUKm;f:98 CIJJ*t0==(yV0rZzwk{Ę_d*-Uzxh=-L~m&L*5\*!n(LJX +d'~JxD~܌3 BOtD3Je{5:wB\\|w2^<4z!ΞҨ\BIQS|9_ı'%N|9c fͷ0IWa"HprrB eZC||^#J2k/;DbXd8;9TU~*LV©ӌ7ÇB fs' G뻨r +P2:,^TV|W/"Oa{be*yH,dz111 FCtt>Y̠*T*`={'g'-6߸_ QQhu^$657/ޔR^ROEEhh(o֩KR' U!1$VU*-)Z9/=53 ;Rio<[i&޾+++]v_V*jz=0RqcPg(u!XF4zkese A{Y6^:j<׫˯^%'߸G}@`&([E <D mi6/JC SP ̅1p;T&!D0ϒ@? &SdYy"3A"o/*@ ,T5.$d쩍&0s֋FȢS(IJRSАi>%KL+C $eydJIFfJ7ۋ@4=s _O)SިQM)$ ֙CdJy.AB~4xlLMm~@;g @φ#0ILH݃,KW$ηL_͋YC_ "J f*@ 5yQ=zAOr J f*@ 5B@`Y#J fXB T*O2KLL$""8j6P PTx{ =[ ///BCC 4EO ύT*TLd2>>%(U4Ri#<*@!J[!ݔ"!>>J*#>HR삽wUPt}$6Vam!T+ nbkk5))$%%MdT$)E>>>lْ͛ST)<=='(('OrQBBBL[^Cf~/ >%Vu1G]@@@cŊXPlxxx<)'gBCB <, o@YyxzPY˴d)*Mkkkʕ+QQT&B.ݝ2eţGM; ///ƎK-8q[n޽{IJhѢ#Gĉ,[0;8:"joȵJ*9 geQF&VvYO//>Dɒ: N.7s U:cqN :ŒNĤ gM (ܨR!!\t`())$"d.S'"̝;;wGBBBm=zģG8v 23}t;\Ott4+t**KMjZxGg35h wR»^$%KdRA||QT*=|HTd$ߨ5O3Mo߾ 4Aq-IHH`ҥZ 6o\ *11'''@ۧaa(YІR)mJl?POJᷧ$e’R:ZU2VBB$Q\ xqswdR\ZBx\uެKrrɞ gϞFrmzΝ;  0*""///d2}|t>TJ"T*!`cy.rR.Ӊ@JO9o@OdORsf!III4ښ*Urs3[ԬUW⍶Ŝ9s8p`D*0Fƍ.[(,#44$#^jBCB3s "ՂJ-U$i=-UĆ>gX{ f6l8^^|2r4M x(W>Аʖ+G;F3vXv۷ofǎ3iӦ==Adŋ ,Tj@/ !00)K&S"~D.8զ}hn޼ǏE48w4dh4-)"dbmc/Le.(O<ۍyo꺏-ZϯЎn:;ʕ+MN]/jMεkСnJ6RRRxxxzJ"É/%=̞d+.G:2qD׫oP9::2`@5k;1\77l 0C͍O^/xܵsgϲx"]yJٷV}>R=?cN.]Rɝ;ebc,X [lfTP #^yerhZypJ#'U*QQXˉ' fAJNHHɓUb h߾ݻ Iɓ'kْɓбCb(wZMl¤seuAKjZllmՕm۷SLYx"%Jf͚oPqMbL>Rjժ=zPLzúkIOO@"| | իr6mÇIMMZjL<酝뎛ynꊋKBy衮"2* {ǎ;Lj1?~^zP999QlYd2$&&ڈGŊquu%(( eܹ!4,/O/J,IHNNӧ>)ի@TРACʔ)Í7糉)S,˗/vڴj7np݇o~ܻ{WWWկGLL Fgoݦ VVV>usѱcGʖ-޽{t7>ww6Mrҳ]vۛ'wbbbŅЪuTtΜ>ŋp ;uz$%'q>}*%;uO͚7ѣt_??N:qIN>-:88HZШ5ٱv:\]]ׯ7χ-JebI$J,="8)M\eb"-[,3p=J*Uv3"7J_~>ʕ+L?ÇS6A :D{ѽ7o,vn[4k֌/g֭[kӦ-O $$???|[bB@.3`@ƍ}d5jDpp0 0vmѣ<_~5k&Mݺ넪S}5+H9&e2+Vr*1ׯwJ1XXXPR%|JDGG.55k+|yzzV(L"""tK.Ν3SN2yT=/`ccÆ Yn7{|[PreV^CfutDRR25*PhB ҨQ#J.]`;.]bύ Mx{{ckk˭ NYZZ2yгGbcc3f,#Fs.ݻq#:tEcL:;wݻiiil3#FdXbƏg1?~_ >E.ӽ[7n߾EƍٴƎ0#/bu(Q#GѡCGN>MF8~8>T*z@=P*۷:uޤCǎO削$$$ҠqttdӦ9s&c F\\,AAA^=ԮP(P(V=Y~nJ+L=(0B*ooovUW3IDATރ v$2%X}6n3ȔT!2eݻt֭[1r$ 6 U`ڰNnUVٙ8,Y hEƆʱnZ״)#FDR1rpo֭ˍ7}[6 > n&** Ox"ع?+Q5 d2]Ϛ5YX-qqt֝-7;_"(\R2<c'y!y~֬4<<ze 8;;e i4$h8lO}f"sxnHR*U̔)Swڵk F]lܸWz/YB޽_'xINJB.W4 <62BnMǏSRBJ*T6s~2xPJ.|q9zABbOPJUmv/ *+kkm҄ K(J\BÆ yw9O'OhZZ?fѫwo4h3]6 aٷzΜ>?lb=:KTty.yŃM MUVN>M- }#___N|իUիXZYRZu͙֮dbUCq.]de<QQQ-[L'{$2 W77?ΨQ7f@Y|qrߟh]8uz3vppp$&&Z7/{l}obv.)cNK@.J٦%LAH E4.e FtjXi IdR*3) d cH8{8 !+c+:o?=՟Yfծ]NզM.#L/Ξv5YO'~z智/7\_qޏ?{_߬kskO^ U^jomjkq/G;}}Y/{o:<\ׯ ׿ΚU WbuӁQsԜ9scJGu=88PhT1}G,YR/yݻﭷު^{y#Zwզ_-/}O'?C-+xwS-wQvN4^ k뒃&3jmiuѪzt{B>:uj-'utHP|H NTkfά_z̓ӧ׋mm5kdhmoZَZCCnkkQ'P| OTϷ|mmA>kR1* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PM&TD* ф hB@4 PMv@FFGNlP_ɭcE#Cuj`pFk cFk`p0]V[&I.cpHsdl4z@PUŪ`฿88% ф hB@ NIYIENDB`RaySession-0.12.2/manual/fr/images/exemple_session_prete.png000066400000000000000000001062601417052567600241550ustar00rootroot00000000000000PNG  IHDR:{|o pHYs+ IDATxw|Eǿ{% AxU*MTDR-t;(RE:R,HU$Jz.v#\I`O8ngvvvgn<̬ԵkWCPPf0dggfYɑ%UU%UU%M$,i&AFe|ٺ,˺((zffn2ll6k-;;[mРzIKڵ& :/L&%''EQ(l6d2Issss&@ 8#_?0 ,˺,zNN.˲n04MTWTΝ;[VAUUF ˲l4%UUe R+O $9rss ʲKl6]$]UUMQXn398-c &EQ̚L&!77נ( (+?$ɮCe ,@ p*XNLu]&˲뺦(*˲ 4Mu@f(UCPUU(fEQ,u]7)b$IQUUeY4M&Ot]`0WB$J .mS\El6#k^]UUMe-ϺR5MS%IʵlFQVT YVXb]8 B[Cq2(l6&]5ZK@ \l6i6ITEQTժi&rrrdYEQ j@ QŤ(Jfʲf =<@ 1t]7ʲy$l6YUUf)$)5]Q@ \Hl6%O XL&ddYeUU` 1("K$[XE2OVUUeYZ Fu4*iy@ 14Mu] c9@UU,%K 5,˲$IʒU)@P[(nl,@ 5EzE5fsXYb>bK*Z2dr,[~k#@hHfNM9x0/4ؚ%K_etQƬ|`$u1%z2gf<̚%MIƓԵk檪Z/]bϧJ{*voKї5{!TUMu=`0dY9999u&*Ujղ07oV5@xyK/]65X6k5NFݫ'˕W]͍Fx^mc盜Bs|O[pktp=2^~[*6o\S m/z?M^яE4iܸݻr߈{jRyXF\{j5hgf%חtaWYx{{Wq/M7 /o/Tr$IbG}0:w1uSURvm8}/JXXO?$&?͍pKHFaժP[j9}Ӧ/ + ww7s4ͥ]d4"+ YYYղ,X,Ub!77Zj>&"yaO>nnnXjk [җy/m۶fD`qw0mSL1GQ,;`YYY_tW.$Iiݝ\u,ݞpF.Y}ظ .aCm Fysl7LF#H999N) :?-O1/PfK KQJE :"?sBCC%i:Z9W}Ŗ8qWa}eNs_ð!wͶhܨ#ӓ-Ӽy3xgqw]^siEaƴ)_/>ѹ eq5װ/ⳏ釵5,^W}_оuMyױ曯ⳏ fL£غiCAUFʲ̐ocb`d ޭmq:ZlӪe ֯K3xBe] PV|)7?6=˗3Ma@[?5֯^={ki/oؐ;X|_π}R~=/}U_2a^I}aܱ{,u~u I1n}a!ƻ dlX7^#_id t֕''Odwң{b˖-e^7Q|$-R UUWy/JW0_w;_EܞFEQHMMeoӷOov֕N ӓĦ2%;9-Ώzإ:\=&'7?__,c̣Y;$I"44;nx8`ts6Q:COF ?623m@xm. FVVCn灇!22KOHH3Du 8p`OM˖-OHd2#Kpgqa4_)fNa6NRSS`00ƛLz¹;׫Ww ʈ{f s8z+y>ooo>`=O6Jڎ$a27^YW $88={+1K/<_eY33s4xj Pz[n}5_}h_,>YŦÊkO=Y,uLd$+)X5}zr߯o^T޽uكwBÆ iڤ E'\/6&oN<<pU^OJJ o&'OdW_;'%%T8%88:T H^lTUD^=9{?qSKNNfurյ<?~)fWfs_=,RPU>/\ɐoc[٧999l3wLe/s&2(RR2AA8c[PPPawk.u=yn]o)t]n\: +kqk<<<7ʢ9+IIIȲSOO+tͧl{Q\{eW%S8y?zcauz!a5)>Y4oi}bS*3I留8rw9̱m;iڤå!qfΞ;GW5״W*wutr3=7ltk0\rOc@<::GǷ24iilݶلlaȣOa#wucH}ynu/wӫgYi׶ OL~숦;w.h kn<=pVEyyS2}&3gLCt<<,'V~ #ݷ_D\l4"..`vؾpbMy|KrJ2^||G6ϼ^%%5p>1gYƘGGkOHחy4ڏQ?Hll>XiSuߑAVfSNw|mfyяY3PU +|yAw.gg1p`dIfշi[`Bi~=awW}dY/ W7Xb_:}&=;~$==̬'!|}oNfLʿ/fxyl\yV >0Sz4yy~SgcȲ?G9eʯV ѫg>SU\˺O>ptr(]׽4MOZSkϙeUQa$KJJ9Cw{EL\ٌ'))Tv?Y͋p ; Id4CJjjOhni58%8S{\#8+}h,*m߲;MBBvu/Ofv.dgg;"˃()(e'Y‚ɲ(IRVY3srrrjoܘJCu3*㋭h're?M)Úrrs]=-(k2i*J+$&%;61b]|~J-x]K.- UU]~ʺO6sǎSU\ LLM#T10|ksׁI fcN=a y͏d8R({۫ԗa(lg(7$\rPI3՗yo"_P5  55s^!))bVIPGѦMk<<<6tڵ%6.!wpKS4jؐ}н[WÛEVvlO^ۇk۵bѿ?MӦM";͚qmڥ M6&5%T0,x{>9H (0-[λ Yt1^^^$$'00Ĥ$sO=9޽zrl6$鉮<޳d^bky,Hz_m4ii5Q39-IJ ~c@[S/juUm%]VE 7e9 .7ӨQC!Vwͷ__[̧}jeƬg9ro233yFw/M9zL̵^/b3!IW\ќ(q;͛5Wqfn6x FY4)8A?вe xob^ nnniZs8?MȢaqq|,]_$$$O?ݻ H89|kRR]/H#D8YO8+̲Q#cXMhNddc{cc2e+l߾ {.s sʹf2ᄆШaC|dggo_μ۬[#Gnt9η߮aYV}-Ekq>11M|%KSy7X,:Ɉ}9s?c܄I 3III;~OyL41lܓ:2 xC4ٹmRPF҃"x K0ro{U|%֗VUaos<,Hnn.#6[;͛_`ʯ佌g8]Ĺh|sQgG$=gA&vW_E X k g@[1 :i>OOO|u6mB||åx>~\O}3E{4M+[аa|}}9|`68w.Ν;1޳ QU“a=3w޴)u?(& *̖ f{Ĩm`zz\e6]X"?t0iخ:[KpDÚ4a<&'55Ue<;k?6\> y_|l6`˕wfyGyc .> A׷`S{ͷ0(4iLǎ8˯j,tܣǎylh&Oil۾ޯk"9ؙh/'PE+VSYV,{cnMv++?2(M9Djs9] $ ??_3ʜk6𰐜R,O$||iiiŶd$//OY!$IחL6|."kRB(+L'W2eiCl^ΨL5>qX dffeJffz ?,EnnꜜK*fA>-f,% $'-'Y)./P_$T1"I΃4]gcN ɨ%yvJ8\VkAcue1'n&[surWЕeT۲z)^D G)@տ :a@  IDAT` N K u!X@ A@@ B@P'%:,@  ` N K u!X@ o( WnGMWEtڿ ID{R@PY-X Wx$!IS@3S7-7#L-,I88 JaJ_k96:<ѪKV]jŖ\I{Q bzXBCѱjFťVưŢUK 77Tqkqˆޫ_JGEaC/W4oFog]$'ӠA,UUޗbSC8ݾt*B.R&IѨq`4M.GE/ӽ[v˸IO Oѽ+N6!Z˂|ZWUfeD1ѥ}}"eBxxx0q8fJj3go>~XR$'TYY,ZWP8jvu4 ::Oۅח]9/<ǂ.,,{)ZL~+ZUzegg3cs9M7͎|-.UBTYYYeC$,KE0➻eLJƍ( ǎs(4k ̙=zaMHpקip29{U4b/@?@bTZ+[7lfM+ T<ŊRXȅ*<@Zh.j'Sh9̪CT4I^ Z0Z)V}zEmsX!zb_N(2WM[^ӫ'O<= [F=/y槍HšXCztʣ?(tz{%;w]|ɲi&G}tCX/˕Ur-+7c mԩ#]w _W|EnKbӖm\|So؁ȘIII%,4w~3tОǠeE/uQzaLyrZ`æ-̛/<; S=V%F&EIm?[@`@.\̖m۝w cc咞ae˯rߓ.aaa̜6+\iApp0 XV}kͷiѢ'Md4k:#6::tQQn4Pn H.XR%9neIvUuA ]_͸V,dIM52eZKN[W A>xwb'&M < 'O0xƎ@tL ^ӎWđܹ2 SeF#7dY:cM 99`>`~[޴)>>޼ƛF#":o=wc&͛3\N>c۟O"YZlogMp)|BC;`ӧ^{WDY]pAW_|Vjhތ=9ٻ{gxaLyj2߮Y˱cx9*,#77B??ҝG\Wt >R(-''W/ >nց.c-p2߬fǘ19<t@?~<>QG޸x32##ͯ!e]J$O`@!mj!ٴi3aƴ)\UWZBsfJ{hƙӧYB;8mgL\D2#i:Zvf^Dt1 TrY8W^8?zr04u YYѐ$c%\[ēSw!^;u}0 e;#557뮽s};|NI协X($|t8F = ֮{XBcbS`w]{}!طSuIX<,bnLM p+m[軿ө)=zK}8ih&Lz  Oiiw &&G=jgΝ :t"ϜE%R~!Ƕ RNݻ'9p1@>:pBv4 ow9{~+7ㆎv7;999d<#ztSNXXhn޲iܸ7v6ƝQ 99Ν;ڦzΩXUEQ0LS'mϼ]4cG?pM6-]ec68} Νi~~ڵmxQ-j;(WZlA-?mۧ75tlk԰a|)mTU壏?a's90p } mڴaʔIPY6?ٳ_0~<<<ر};_biժEsAoPFǰT./,fγdu!B(#֖+7_˃,K(Lq%9 ;i_-6_| y=1{~W缈hۛy.PQV3cxyLyr2`wE.xw[mLd+>kf&b6oƠس7Z^rw6bɢwHO͍.na:$I(t.ֳz?ph׶-Z`Ty(K}@jZ 699D^go{ϾƏccfIdg' 1iMSen>W9/՗og- /-V}W缈dۋoCٳq/hܨ55ŃGfY.s:Ïf⑘U5'N$&&: {,'-- ۯ7IIח iW`UŪΐtr,{fYSAt /2jn6-d`$EIDЧk*׉)\bȺ,ˎ:u*vr%ԧ .>>___ oYe!I~~Xx{{cJ[#55ܭ| 醎gFK핿4k4kڄ_wa(~ܮm[5_|7'8D$|||Pm6ˮ >>hNZZZXuѶ($Ir(Vk SUҲe m 744۶3i֯__5:ѣNJmwޫޅUUUNue1 $)I4M2,јS -bo+AM90\(漼|*/ͯ*M bRRRKCuZ~)H~UM*Sg⑇w[_OK-;;/,Ruدui$%5/o[<}EUՋTu5: V1Aq&ZU< 6Wq+VF jPPbo _XM7a2рEjʅ'(?,[^ȞS d@@״Sբ`oӸXկ],ekVd 41a<=ڄ9vYK.uߠW!^ZZGk%++ܖVDD=Æ sٵW#G0l0V\Itt.U)Zq( )I9܀,./,oJMq@*քwco4҈q&;zԥ}&L+8rHVX1cFMh޽‚iQ& &22«]TJKw* "B'NJ&t*6|?Cqi^{unfvseWQ]+T@`vs? {@W3gNNNF݉/YM6;;佺1s&uj*UJbbb濓'IO (8 aGZZ .͔Ilc`*#bLMƦI*kyꩧ,oooxAvFPP I,_<կmY))gE9hdW_矙7uͯcoY{ead4lѣ'̫s_O?a_+%!!c\ ]/mi6m9 .vJѣGl4ʞ7,;==[Q0&M̭gȐdZ3ٺu ={2u4Ƈ2jVe4 ͳ*JǞ!铦WD|4jԘcǎ{nիŋ+_jСCV̗[dYUVwdCQFs>6 Ix 66?B.]X~=999j ???XtiS\ ܹsϯq6. +SnVXQ:͛>|x 7FQ;FFF`4k ̙=zaBi4LΞ=[eCIs.%lTU@iԨpy'zFo|||HII_ސ IDATm۶`?F$%%fjN>Rz~d2}6vɀhܸ |qCλ 䓏?Gʼn n#4437HJJGD~~~w$zAUmؾݻn 777 ȕ$3+gmepF#O]ucƍ 4l۶I'ez"##6mk:9r$'nXe$zS8w,^ך{6nܘ'Nήp 4hP$88;.xrV+= k׮oW;D?`򤉌=f:tGF9]7 rz_ԚٽF]ssa6ӗ3gNxѢBibտ6 nv>p?2rxxx8w\W^%33ƈ27_+tؑGG{yZTF$V\Axx8_X' 侑#;>GDD=ˋd, < '_YN:q9|}}y׷N*E ?ǓO=͐;8k`  +‚pE3vl29Vp@ WKbyrrr0LeX*w,T]/:ضm+SM__wƲeKYd ^^^L8O//"ztWhbv(kdffS.%L4 :uDÆ +\Ξ={:i\sayFӦyaC3v, oV1w_'|\jƴ38v(3\>sƌ'|; 0q$ƍϰ;Ӽb< , C#Gөsg>C&L<7%KW6nl߾N:yfl,,sW)VCjzjڵ8n@M6Kw7=x{{ٱcGj)DEEh{уmFrr2\w]{<==YtcW4ǚatyPP1DBCCUW+I/.i9rÇ(J~dvsWF믿rX\})cƎcǎ<_A;2((QNI-ZחTxc>`o7777i’%ss.;UU;fӁk}WYsdp0"(VBD˰ "XjVhrֺpuJ8=쳯sHr$s2k%<3`۶m6;}Faa!Ϝiw֬Ax<>sXu`ʔq`!sECCQG<(^owV&fϚ͊{O w?P\tclԐ R$ 4 -cѷ>Qm,F1^07x#ڶm[;n*VN.=jjjPUGt~bb۔Q@tXwGsN?Ç$(/+ ٶm+&}:11ݻwwzĄNi:ڮk-hzܓ{~},}*++3f GzٴiO? {a~zQ,BXQQQAqE1=~\ݙ8qUUU4o>.+ԭ}O>9sBiI #Gb ]DsS۷o2͜uO}#H.72yd>~II 1jԨk'| EE}>ǃr۶mWQO4k[0nܩwΟqv%%% X, ƾús> ?m `̘qAy$^Ϗfbn7p#W]}5&M⣏sꩧrӼy<ݞҋ\ ,cn/ 55S)9FeJ}7[[~=ӦMXn];^vsΥヒ[XqNg?( >Z͛7KPUE/< {[m}4 %%%?GFL[^LoeŊWxgYv{M6a49Sx٣xoc ̟3_|EF(mvSQSRºg…u٢/EԩSy#޷7c1;otI/q~mYh& -zghDn7ROg"*//r1yd>Z>'4sr|+nxtB+{b谅}m[r_Yg^>̽%Kr 7멪ߺ.~3klmn`hllGsظNX|9\s͵̘q.'wwz<#_ Ͳ#*ʬs^vm<͛1cK=?ɏ{6-s;J<Vk5mwszmr9?(zt8С=a.XYYIAA#?;'??raXp8znMB[oFWَV8s9$^iMӴfouǛeEa䮻?/x?rthkYM;RocgC_c[9=mDZp8"*bf؈/2 q:aWJ~}~+qqwӶǓࡇO?q($''B+a6?abDˊtfO~UD߮^n ;e˖1sn'=/oO`6'i}]-x_/bL3u:]Nkh4*>('4G{QWޝʁ);}=ΆXFŻȈ*^o;(ˣ^WFy${qy̻F.BΜ= "%'ݻw=uyEYqbr8X,N? vqKfq1 {pdddj*n[Zcƌ˖- o~ {.$v**.s^wZss3Q!_yy9nN1PۻO74˗/e˖3 8͛ǕW^/ 7t#lfߥ`I. ʁ^@4ƅA\HeL kotjj=M̨&)W݁Bp:l9C2)8uZ[Cc&XRSRINIᨋhX 9s&-bڵ[|8V4h1uT9f%“\DGd@ٌi\HBX]K/qGms[[9biNLD뗢kYkfRRRX-Lmw>ۃtU v<=\CsPRR{U 8aKKM_ٱ"/s%Kpnʗ=c\S}MUɿ~?;w zBiׄStqBBDBQN?oRDSc[6mrT1+HVUQz߬J@9X~%)-xܪxRUM_ {fx<$[t:/Twj9n帅U$[§zB#|> ! a6.& eC] væ:QH` !ķH@c*bnޫ5=NcVqbBnH` ! XB!B %"*H` ! XB!B %"*H` ! XB!B %"*iy&44uJ!Ǚ^ϠAiJmm MM/JyXs$PxR!qd62(z=!!t*)+-۾dK`5 L&nS !8z=YC`gt `g5d^d|\ZXs$Ni\1J+K{z3&LM_ʀhnnb/Qۗx)+-!!18ZZZhl'kH6۩!s x`NHdTr*Cq~a2Ч;lJrr2VSJ>ۍQv?|NJVViiiPVVƺugLLYY1-39m$6}Q۷_OO˱ J $-=j@[KkPZډX:`Б h .M䱢hyr!f3C#9%AEE.W+^}XRSSpPTtc GJOOgL6^y8@MM iii2m4nV xǨomXTUs1ݾ?rȣ^۷o_ww)S/[huXőNEy9@lLL15%%8-qhTjbelyz!RRR9d*+]v+nn7G0$;&o^>?//Kj*ONKѽ)EEEvZ7oWgڵ}:khXt\:d8)F31 PGO L q"3+۷ :SFb1S~gkoo;wOKK <>O=v˗"|Z$$$m5ddfm]zֶիs XLLfṟhaE s,Ɋ o瀩߄T2غesaufnLfRRR#x̝;7:ܮ];w.7tӧOxК1c~{U[[j763n'>>x46m7H]ÑQ L]Xr%-Dx:B/ )+-qSUU׳]{`̜9N) ujb҂ 3h0c=AZYs^gM_1[,$PZRo,))&%%viӦs{9򰷗BH~.o21^/dTTT@cCؾCߋ..g~-{K5ί2B1s[(P}>Y-wO?x||IKq?+.'++ 5?)vN^~Lǎ;p9ح*NԔ 0(((z~nR얖֭[Oy'_| grn]?_.bzF/ zΪ'X91KL!^  m#ªkPh ؈>>ӟl~*>W^cvɻyx4y MAJrJ7<$%MC[n1=\V\5#??j+!!Ea߾}m1d(++caRvHOK'33aÆ)//"3X&X3!Nf0.d>pQlsW0x`JKx7ot[bomBΝ{%}?6n9ϻ\yw宻~UӮjjq;NGFf&iQQQv%Wk+Vksp9 ++ߏ{4qs ov(6nȝ?[nL4 ƛo0g,v1]o5ΖXìmںaGwW[)VZT͚Jw͍Yis|!fμ^xh+4i2mϘ/a4p:䪫:oἶrqqq8RRRkWRYYͷ-[:m yٸqc/K/r~@kk+۷mFķd `\,,ttl2x 64@阄u%|:~}Ͻ>bXsl6qq6{I<3wб.yno ߴ~)g7SڞRx}><~oXV{Y5@0Jb$Ipf7K. 6z۔3kNdff駟0qx.Bn_t;F]q9lo;m睿 &&ٳfqYgqבŋþ#ϙ|8gqF1^/2fXo\fumO? mƮ]m@~g2]LJJBQzM.B~_Q q$o-@՗ݶLajjj%4hРi}V5]o4CAJye ^Y%>}FPk+֝ f}4I3t n->/nA $i/qW!V5(Q|DR?5G^^^YyKsUMnӘRbb"ww^Ą.AQV~Nǃ/3`r˂36/S.ynbbb{P4 ,RTT%%77~=fw&NDUU7͛b֭@[hwO3g--0r(oN\xE475[>V^ lpK Z @Yk`O0A?~IQaM4MdMa.&NĚիyB?\xa.dt:4M;jѱrssA, Æ cx<,֯Q6lX׺o>=< Faa!Z 55:]J1Z`֯_ϴi}ڼ<֭;j \ze̙;.Joa<8K(;khz6õ.AUUݾVo٣Oe38+qF 栆qx\ hjU WhhU?~Uf П ɚ!(L`N%ٳgxW;pEu߻ n?!ϼ*s/<(13f\->^}3aϿż{77]=<XɓIII駞+k(`@ IDATm#:($PT\,\./EԩSy#޷7c1;ot*'/q~mYh& -zghƆ~cqXU᙭Hi Xu:ڦ`*jifgWUN BxTkeW\Cزes}?xV,_3<~p> &=GwrϽa7S\\yӧ *DWN~;fvN0vaܴkGcoY-1;|>jhh;sN4MKjvBeEf4xH.#q}>6H)*UV U`^A BN!H[+05?; c`Ad"666|Ց 8.=t:444ȳX_fOѲ"ݱlw*6~/tV^M7gƎ˲e˘9sf鞗7ۧt0^o7PZX7v_YCCŘftzN [hua`1X8@׃?  a@-j SVcub19VV_|n *jjjnhh(mT:BDoF,G2͌={DZ',<{}=^ +ѵ^K,bb6Yiyhyiy)qRqSphi ՂbʌSt$,!{ee~"a83(++H,[UV1vl䕯cƌaժU,[~7atA:jܭ4kxhy *j@A fTDQ 4uA =uz0S6 ]R^^aSǖ(dg0ng޽Ǭ6)//gٲe<3N!..yqWr{wt#lfa-n[0$U /hjcMcrEc#—11l^80}4w|ݔ|44hAP&QXԠt;z ֓OHDfSС#t MӔMB|86mC|u:\YL&1Qјձ0sL-ZڵkYn8pZ\:u*IQU.mj ue@ٌi\HB{gK/qGmk+HHH wbbD.t,C: ݭ4s祱qatd'CӑxAm/yK\B|-RSHIIb`2m|^N݂VDY0Ph@MwI ˣ[u{fx<$[t:/Twjоbb8簰m i !p>a4L qq7H )3:uX54 6-ՉBK!E:{,^Dq7 18{B!D7$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTBz5-dBӺ_LbPVV(t]/je6 dddt:]hYo!'6^->A҈"^pVnn.#:^  2^N 5MCUU6sulā"T!Ǒl&k(Jөo"(F#%%%|> tx^|>~@ ljbZ1X,z=~ǃz4c`4"B ,^O֐!XXQ <ثV-,j)Ѣ2L8$>S:,1~TUEQ˩VXLJd 1a2oRDss[6~ھ}43x^OYi IBcC=YC#F4  )$''cZ1Dzq8Nux=9ngԩdee@MM eee[>ʈ{ƄɔS~b=Obӗ޾}O<OB/СHNIpPQQՊl2Kjj*998zlH,^iӦQPP+ --\MƭJAA=a +rN=Gyk7e^~e~  8ө(/ #339",^ǰ1 CX^T.<^/j`d2>f#5i}:|>=>M0 Š`08{ 񝔒Q'SUYɆ/>[vvq8P!ٌ0}{pyyy,]UV1}tZZZڦ"֮]K\\c]O=s:\{Z-2Lf :M۩cp& 'Hc}f\.:=Y1MoXcԖ @"HHbR>5JH!323bm477:SFb1S~gkoo;wOKK <>O=v˗"|Z$$$m5ddfm]z>Trzp8j4Ty U6iumkwwUmj^GUq}64n(uvnkZq5zrV^ ^ɮr~@KR T2غesaufnLfRRR#x̝;7:ܮ];w.7tӧOxК1c~{U[[j763n'>>x46uJm{pzXzE% l1a4v3n0 FK°pMKÔG1HTM@j31lb-jзTe!lfQ޵OP^ݻv2r(HOOgɒ%,X qTWW`,YBzXZMMTUU f U{l6d wvi*Q*hitsIJu}D"_OktIiq}A^)XL*1q&S,hA:NW=BV+FbԨQX~?СèUHTUV3th,^+Wk׮>׮]\EX"<՗ RYY帩TVTPZZ." jc1 Ci_tohj:=Ԃx:=zw L~ZTM4^gU?) NG]]z_l޴O1[,$ዣK{gNl)n3mڴ~{Xv-#.yh?7o}~t:| ˡcPZZ墶85S0l6GQ еRFP#v4 b!h2Q@ pk3'?^Hff&RR\>j_o~[.RΟGcc#111(ҧ;իOg*wrŗ0{.70K.v_hE0WY$*QU5bXtp\GnwUUtfz=IIIv{MVqQZZ͛X̌w*MMaVaa!;wo~p-]ڱc`wʜ9s?sqswSOu7u* ,OS;nK,~=s$PQQqmIJDeEEEzsagX{.+WÑUW]5@NNo>Z[[#FLYYeee߷?,]=NUuidff2lp<7<[${$2 x:MzZBn;f`EQX,  6  #it:r C?dw7_#? REQB]rɥdd' wͷPYY5kbƍyM{%%,\x;gL6 NUUoN[|<^s-1y$N9e4kYîݻ=3g\x6l_| {aD/'N87r 74;~'p]wsۭp8y<ؾ?>c׿yf3O?y-V+.Wkt:223IKOc Z[oɩ8@VVVpiii.~y|Plܸ;~r #rs4i27ϟ7`Yرc@* MLPUш^o3Bvh4:N0 bt:; 09rJJJ:uktLt%p~9n7fO_CaX:t(W|駟[o( 5 lg+⋈ٸmB>FW_rQ__ϪU+9䓹ۨ//ÇGW\?8y,X^}uմiylڴ]v?f?,O?eM祗^ 믻+Vu><("328XXr;χdxiii,Smmmh*1I%Ku{}b痱l,l6M#xg8Ic]>2nUU'֘۷IDѝ1h1r>|8d2c+UUX,Jjj*F@ss3Geee(:uӱl_ah۩S1${HhJ_samo]-[6rmB.QF+srrg?/7( yhᅬ5?3f (k'&>h;ܓrٷo/cƌ =0ȣefr{aoc>3ΟVMMS //SO=@ @CC ?8[|hܓrq =F(zWs vESO"ߏ^GUU &LjRUUlFQ|>C%--O?M0d޽zN9F޽{tݶ:FP3ٳ }#Jkk+ _=|8Zn_~yn2 x}ժ~. vƍǁF';`޽ٳqIIu|ǝ4-jAMLLliFyy9c_Ɔ䶏\]8q'Ofq\lۺh | C ݻw*۷o / .rEnau,mZ2`莲6@ ^6n 񐒒cb_0{O><tܲ &=t0Lرo_}t]صk={Νg}6>+V,u)Nǜtp0.ԔT:6mZOZǺʁve1g\hhh+>'gt.P__;ټy3>UUYt6[o٣W lުCvcW111\PQEG||<---xP4 GlllX?`x_(--e@ll,:}ׇYkrANPEGbSQSR(*.q|.\H\\\b既fcԩ<wܱ۷t:C- fif/Zdf'?&11C᙭HK`0DzX,fl63l0Əf###I&q'c28Ә8q" 6DF#&F#f@ J{ꫮbƍ\zeꮻ/~Izz:| @2W\#|p f[t{G~$|p y_BCCw/楗_ 5rHl޼*,yuaGDMxWޔ3ޔ3-N~;fvN0vϟO~~qjp8šp5cCCC7Vs9$^iMӴfouǛeE66~z=V54>e2xLss3@.CaƏOEE#Gl/}O?lQXXtt# BӴP߹륡 2 $''xhii9?jj5 ($%%w1u륤,1 l63~ĈfcSٴzjn>?4vX-[̙3H|>lpSu5vPoNسn1t:9 U`,U\\ꖨСCm6TUeڵg>S>S|477c۱ZnL&z>@ pʢ¡j(nυ8Qx^cزesof3Ga='|szt|I>  ,UUz.bbbHLLZ1š0RÁh$11G  &&&``Gٻ akk<"DO?]vFҲl2z ee8=[)?? VZmqKk̘1`ٲeD|~*@ @ll,>k b466r0~?111Lu:z=~EQx/Á7v;yyy{dggjjj())a0y 奥TU{&hen¦SrO䢋MQz}h"[@VVA<MMM(`0TU)))PPutZVBa)pIӗ2 زi W8Jc5:f[/..*>/4n1s{4LZ|xa=!nPUM_ ":DpTG ` "ܮ;^7 ߩ; !G8:VNW]DžH)oBﶈ@(:*sZ}Nwq%Bj.A!xB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BD ,!QAK!DTB$BjSU=#7`B߁tO89=h!w. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X XP#"J)n=    Gg+  Vk]KHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAH`R֭Ć@ 5"8c,ٰHa֊z^RcVlm۲aBRʷ[vWJYZ[6,ROOOr˺@n/]eX {pQuZrYۏtԣo{k7"1Xﶬj/?0Q[[N2njZsj1FD|ݰZk6~Z1眭6՗/_ֶZkhV|sV }1nj˾Z+Zkc9s9f=mUGDrԯ[Vu>>>>x8OS׭~N8y>m9qփZ89x͸\.8ED/Zcl;oֺl۶1o߾ֹ1Fk8RFěiu̪cV_<9kk?~q{ZS#w軧']^{Z묵εXkx^RO8t|m5.{N}c۶"VmQ[kuUZ?D|{ssYwH?>zb9Zr|s#_.ݻ}y><DZ־ǏÇӧxxx/ZkrGs\AqP]3`yyYu===Ŷm3^l[[TAIENDB`RaySession-0.12.2/manual/fr/images/flags000077700000000000000000000000001417052567600233672../../en/images/flagsustar00rootroot00000000000000RaySession-0.12.2/manual/fr/images/options_du_demon.png000066400000000000000000001330501417052567600231160ustar00rootroot00000000000000PNG  IHDR.-)sBIT|d IDATxwxU)$4 XHQbWQ v@_Tvӳc!KvMHLs_ɔ3g&gw=3R]  Ʈ   >"8AA&B  D BGUm d<.c_0-k#p= ¯zm۞"0jm{6Ʈ I ִ5vtmi* Dp.M7qAAA   4"8AA&B  D™C%>?C.\JSLĀƮ LT۩SGi 贈kĉ;lq"e j)squ!L5=Ne*.yiAdN.>}Zl鷼qM76N bbbcctFQ.|VkcWh4~IÆr٥0sK5ql6qE}j]Z{}my<-J6j>cDsdhabI.Rv^bBG5D1-OU> B;PpQ:'[cϛ́SQZYvCOeF#*h4t:q:VJ%SRrbXzl6S\\\4 -2~ݺ 7'-=+33uR0 ໮\:C$L&S6@m`tcwn*j:BV'ֽ*'#IF /5 0?$x_Pu \P2"5z8=n7=A5s3|>o>q\}ըՓoyIȲ4{-3/p혫 WѲE eli׮-zg~dw6zYCOR$/[s?cu2\p~eޝ/}Kx㵙D3뽷Y7ʿ( z꩔=ucN^ƢżܹR'N;9y*|S]sYsh>=G KJxͷeXN^Fm:u@pF+1WWrх}Yb)?OL̕ï൙/l1R_Q޵cf͗I^Xi3z۫$&6cG7_ro 䂵`uO뱦Wn$`t 5_r_c2Bs/d7-{"IG}uw.3w=lo:BƪKsscd>X+}wZd^;WLJ}t̿Dψ* yAZf:nkF 4Z7@<͋gϲ[_ɧ~'""w~^/DVQFFR?61t`K.#--} b./<Ǥ;i=sn 1 IdDeee51;||.Z$IpdffqI/V<@[hѢ9GѣF3=ZJKKQ\3*n.;NΝ,/OnjKV+lQu<})++cdegO%YVR2VaCp/XNJL䬳0y n쵌3|j4W^}y4`];~Ey Q\\M7^=5coBo{յ}׬9g|̞{Yjuжl9VQ^MwI$ ~?gimVwp_g mrkd4NŤ e}5L)}N:K,=t7  #ܽAKV≮Z^`S0=:`ѪwF;[,_vaH[ˁ/dB j29]^~Y˔GSe}p1~wl6;_}-C %K1t %x:x.`77oNVغO./23b2ȳ(.)G0rp}6^4=J^rT*))7hsWR_Ź{)f-ǎ`_aILl5mj FI^.]:ӬYCבgT@oV,~oHJLTօIIt؁6жM11عS-?Y(m;Acbe<‹/}C.΍}SܔśrVN |2)6$;,9Ҹo f-9Z$'C& dfk/1x<PV23$:*2xa҉׭GqNѵL)?f߿޽XP;v8wM;n obѢ%,\.WeL{ ?_rssy7پc+WQRR-}𣏕/Zdd߁Rsrֻ\.T*U``ɲLTT9ۜLt3n믿1d f)C⍷> )) }%Զx4?Ob`m/;MEPwVM܎KV."I(vu$>1:2gzweǝ >Hp^Ϋ?|,j66֪x>cbn7+W2x@RRSYoJgh'n}ZOssэjp̛%_|5c[o!p8f-YK=ҋ=v?m?/F7jOjՅf*o^rE8NvVP,Yu7`2j6jRjFצj+yyyỴ̄MUTV] d:b];-rIŤЫPhtN^u={Ed/ Bi{򰙕`\?ZeٚҺU+嶸l1WHIMcX,w?d2.b˖+W[oVC~QQQ`4vhժ~NNyRozmwIxxxj5_7mÆAVl۾s;]#nz ZFe֕GzO|jF^h=j_9֭l2s-Y]KMǯIm/X[9|d℻AfY[~zgkR=b/\f*zDj%R(pupMK5=Agm9Y\6f{hn9'WHT6A{9\eQMH  ITxq+|\\&?>iOLb2Y_]bߒGfF& &33X֭ߠ,o,N~fa1||2j~͓KQT1i51;ճYDFDRPPW ;n###p6l~_W~!S'?Ɗe),*S8ޙ_ ӹ;'vSTT3/y}O2bpdIҭ[WeaEr2nklj:~MBm{_taж2i<q t< =>%rwܦpoQ-Ug$v{9ߠ@kXUu>dY&|0 MFrsW=?`УV)hĹ+Ԧ-fZf^eñlbQV,f3jk*X xvA sAH o#eF瞽̳s1Z&OZ .b@ gScZKu=z/_SݫWu7pK}ŋHJJ"))Y+Ir:wTmq,[Yn/. ))!MVtT]ƕïCj|q7Ҷ;wo>7, }U˖:~ci| +-߲i#[6md9b=`K/2ez|5f$4I=n&%%ȡC6|sFV-_V`;u-U_5kZ-n@ $IމXp7^=}ᑇS_>hˉ ,,,cN87_ 1W1zڝH#* g^90߼e l ܨH݋`A|e]-IMKѣʲ֭[,N'NW_{J$a)((eFCYYYfWQnB~AA'SHv;׋JBRp8nc0()) .Xz=܍F#5ֽpe ~%ÆWf*R 4ŗ/1Wsu70x,~!ӧ>'L`00pPVh4*'s7AC`'7)`YZ~.c?`iiz^yUʔǟR^|_֬eࡌ5/ǐR 2U 4W K wU*录ʵhPUbcYaC+Wͷߑr5h4FYS}%5-{&[cLܳ0IlٲWfT>QQQfv3q31x^ڵkj]\voUyyDGE_h l6>#~Y:,eT'}٨-©l8xU\.V$+xN?ɰ ;_`!}l'iʿE0j:/k~0%]h4b0joڵk/:::F`iӚ;}*EʲkUf`0"2^3Xj#G\I֭eL?sk99+Wo%,rcÇ&;Q9l9NMMcJztЫ ԗY>rU L 7~W%K2zHذ!>Ms~jǏ>RaC|ʐF![M$I!՗h<_:?h0AQQ1JʁybA@6֔2j,%Kr]w*1kco׎Oaa[n=贉23x)<>u2==[k IDATd||dffa<zXFˁyx7Yp⳹s# O?B֭3c0Ll߱ʶo./ ftBAh s^c~z8&"Y<JK|<JguQjZپc':xpݾ8xЯ2t:5I)dYKN5 qڽDV9.jo.hm߁^sNT2NX+Q{aa Z8\NYYHDΝ1 T*ٷ?6ȈH"##PT\.dY&>>T Ohݪ@{^L&ڶthOgǎ8,!A.!>CEdD$j5,SVVFjJ*gV"jr#I^GFD]VZktP|CJ|<{6^\s-yR\Ah4 sÆeJ`7GD\Bez=:Vŝ_Pf߾xHl֌fF‘$쥸Fp0^\l,:G`쳺(cVF#"''ڷkG\lSN̻j2h4=z dYFzIJJD%vEii)-Z4'>.0KzƆ\GDrVδl͗R8v8iiZut8#Vk 6}*ΡPXXHttm۴!22L23˳QTTJ"##|yyϊU"00tz6Qi֬:VTVGΝ&=##` +-))X)R>XLtQQJƋ?\qq1N-cIȠfz+j4` ZPo6<VirlRpthUʲ}皑ɕӀJʔڢ" my9np勄7%%E)Iq{qq=LI[2С}{ )At =Æfoז."++II"0*))%==EaawK˖-p8ᮔЬYqqZ9xpA&* ;\~*7O$%@ϧ?wtk_4K'&&H28|,v'n78jJjrr++{ ;CVۺ}.e"E8縵(GFDkfrQUx^\.YY4oDCR#GXP럕5&vmrʪuOfvZ޽Ww(Va."'jm6n2|)D͓j58N z_JˑGku΂ phy/ۗ L)9v8ڶex^RSHL -++#.6(b>R;Fbb"[pGxxTEE8p͓h—3pTw8 _pݤRU(,..vd EEE8x-ӪUys9zxmkr}jՊDqC0??lߗpͭQOIYB[p*Cv>Zj vݤAt`IA9uJ=n7k~ܲicMJJ">.M7WYw 7pk${& ӞMV,Y]v_ Z~\l,?+Gn; ] ( Dff[Sy8^(z|ܹvW xP=}.8ACQXX,OJJI{ v:tIݏ^;nGV*,}!I'׍eϞdegѶMv QQ݋UVW[NDDDٰq#}>>N#sA&(**s{b?2x~@YתeKRںu+ߟtkW)S$,3UʲF,jf3EEEJDB~AAH~ZiU֙FPY1Ld$`/}]jQTxHNt=VuS rU{سDF_ҥK{L0|y+Dp.]9|8֭gJp>p>bI^?UVnݚcUWߧm۷3yr * ixNnq7 _F%x NBZ6p߾}x|j5*k|[y9~IuӃ^gsхzرs'O>ٳ4j5w0ooyM rsyxI$%&b4y7|̘<-Z4GUp-ˀy/_-o.3OӻW/,Z}0e9z^_NG$1nM|~91t`>T*}acݫWC?F Mȑ#95ش'=Aطo?Wd \su ^k|O\UTR<;CNN T*V+^$IKzx^xq:Ly|lJ.чmih5zr<:xN !Cq\to=N}΂"I Aj4w#G_7^g{pwkn."^~i: _1s5q$&& ;7rsHHH`o2ុ1M8#=Hd_NGVk qD+i߾=ڶQ ==޽{+~>w^H9AXf--7Ml޺}.Ì5nݺzpbM7k.v jDGGs{3pT*)))ʱ322XVL&68.w>Á96 l6gս~ۭ||L&oDϹ B3jHXN7ߪլcعsW. nZ?>dLpÆࡃa2%X1ddf(US/<jWx\qe;1 RĀ3Iddf.]vi3bۈ >4*S5<>~:s1o\3f  e6O1~zWfpQZ \3Fv饗8V^QQFUyjQ} nl6dAR!8"p f}s&C}غORSӔ/auϿaHl ֬]Km8p,>>NWz\o0 j$7 (履tu;ΩyJ۶IdDo&2JK}3 :0Xkر _3F?Ah*fUWF`0.OA+((Pޣb4 FQW9G= "8;를QF`U/Yﺓfj]+h߮_}9" =v{i+dffcSx|d{?2[k7w}'ʊeKlX,>s> N@޽"22xS>u9ï䞻$=#6_Ce9ʲ).*b֭7X/>e2 ^/!y*f K/_ckU[op'p >ЯS)z_jI0™tJVUpNؘh6il y*<KK2ٕ4u0JKE.߿N#22\Ԫh'M_lLtuiit֍T׽{wrCsM/Vyg^2>y/..ގs*t8dee,^ijeve7@FF_`^™bz7[lBVuwjZ\beee&/TvrzdnfF]vjJ*:YL NdYWvz=Q̝70ngMii)l޲Uy, UrWN%o]U>Fڑe#2"td2|*\..ɫ0Lt? _ t"233^yyHϬ1 @RRGq5`У?ڶmMYǏc4Xdn27fRK= PW<33,6.G=c˶Xh4e%T756mZuoUe  {رc :P`z WW.T*YFVP՜wyDFDpy瑙T Oz%%5L$dCj9Kg,lٲӉ^%5-LLf{)A-u˟b1޽EE"e˟`X23/--f3sR~NWڶi͆8 z32;+Ǝ*c*摓Knnڷcԩ))jҹ;wfcrV.v,¦)ڦ$IUƢȲ AAvS[0֕*Q4kdr IDAT@~=AA8ST ν^/^WAMxmն7ȑ#|x8BY/i`h}>iQUzdfemsr&f(RJRCZHtt%Jeܲ2$(VzcuZT !66VIΡķ˅ޠ?r*GFd48N8H^=8YH܉ ˅dRVVFDD8v ğnS^JwjvSIIi\VP5]Ap"嫯5峇pR\TG]ޓr(,(坊y-j kL ۶ 9+1Jwr\i} N+``Afl-:&:sr:hu:e:o8y-.[׳i۶_p~q6¢*׃4 -Z %5mZgp:)--eU1jT\e 1J  $v=iHV:N SAN7U>IzE^]xVdd$a=zys2/IMM!"2ȨJCNXV m(IHSNDDc2 y}:`Hh4jT*ǃZ.fMõtͧTWhZy'Sf qÆ-3;厺ugϝ#?/΅OP\r 'N;S~=p ǟ>Bȉ'iԨ!AAL ..-h4̦y~SVg,+tqt[!WQ=a<[PPP*wEkd⯿)Fcu5xzyqE2,[Ѱars8w<暍 o ::RPP`6Ib2Gvtt$//$JV +ۛIIY܍'jOƄ /OOsfK[ljKǐDDE++9jM&V &y%iZg#JD?os觍6ι37IZ0Uc!7V-89䶢 KQVUV]]6/k>r2g#d%f4ٹ;M䯿.LY&&&'O<pSs({%kwy-SH-YGu3iC8wp Y!ĿKsɤeWԖaRs2yٚJ]՜=Mq#ȏ?V^ש]~+ WeIDw7-0n d»8Lط?P4k^B9ܞ@6{*ouu2~qY{gbb67U挲?/ @c9m7 >>>gd+LfEۗ:ujьYםV?K,k(K`` MGzfǟ\wy%;w>Gyo cȰ7>lMp6}ߢqF3gxz$''b*ԩ=w7f붊=Ṻqrri&zǎZqŵmӆ2j6  :m3 ۩rf*wp^_ks%8lMg$05LjG /({}64sqxyyr߽+qTaqwwӫRr8X@ŋlptk<^%1O9pQ {z@VDMZSDf*%8iDGn6O>ɄH 7ӳWo쪛N炯]oߎ3gY_O34M OҥKV̴) Dudsx8Ιk{_2kG4.ƌ[ooΈh۶-&LCN,\ ٙwnj&}; H|^2>rիyn̮Z(OIyx4 ? ^{\fY&DZiI?&O⥋vS;Nȃ>@nn.a7=lٙ#`2_0}RdܔRRRm}V۫Sǎ2}CRvmFy̾RMr1{$ HLLd/g,ݻn3ux{peѾ}0xK+XxIL`"~ ((˖O?Sxs7nŋ8z qjyox95MJw߱dWxԨʕ9uQ1yyy k߬^%KٹkJkӱsx꩞cvIvv6ÆvZtLjj*~~~F4Z-r8::V>oohh(_/_AMT*oY/*,xcxܒE_ڕϐP\\\hґ\:bk*Б|f~4_)S,?$++*{="˾bDRѹSGfΚmXj1FҭSJ^/KpDV3u$eprrb9fX룻v0ӗ  wwwm=st=ʫC0Lxx(uv}a /rݸ1_/[mۉ;ӓ'MࡇѼCtԅ\̾U%ݘV[gn;ZlIO^9U5zE'99d\=ߢc0܈Kmecyy~"*Ip퉹&;#  ''gQ5ksEn g>mvv6f ~jՒ3g# cr%^~zrR"͚5SYr]yZhذNݷ߮RM*d:Ipp0e˾ ?/߮ߠ/HNNɥvmN/| +Ξ.\'OJpp.]JÃg+̛S !{gK/5|v ?GZ}=[:,FT7Ti()VEyRPٸOs9__#pu-ڶa!$]N")1onOH0CbbY^IIIԸ6"燏=B%9q=,ÆmwJ51 ooKŚϦMg)\5c?~]eO0oo>>>\*V+zك|}}ֵ ڶQw5._K*^÷ҩcG·="|J6Wd:ii饞Z\>j4yi`^kV⣙J} !== gO].E ??"7+/lܴ VɅ!;%%s9tƌWxKxu ­qP;p55zSXRpP[eWDIw[.BKMM?N!$}\̺h8991y҇מ:7kGe71j^'b zu jF3Bx?NgO d^/q< ®:r>zUZ>{p>>@(kӦM< onݺu§ҍb?p*fh zQ *5 5k,)Jzؽ?Ϟ*W6So+Km∋g@~qO/j4j׮@Ff&ӳTgϝ#.pKJ 2ڗ섄8qbY+WrwJj5AA@麕WiKv B!Jٷ?#Gf!|g))t.w\WՒE$%]&%%L3>>ig0oRSSb^6Px1}w4F[‹ gw ##l9Z;9|0}v&==lxk0o"o%'7?L B6k˗9s/8-%3BMŽa ?cwضz ,fSv[ys?eʶ'NrooHBB<Ͽ]doFƿ>ӦLoM&V\ܭc=v.@V3N\(L&F͔IһSFe⇓z?gQӛ-ؿo?Q|lAQcls+$$\d1j;Ijj*:m#pRu>cfҟ7 *ͧzr^Ԡ]:t⾚3b͟Y5graD+v< ҉M5sqqݍR7t:ִEV`'6W{jHII-C]\\h4V/IM0AFFy:N^/Wylzqssh4ZTZHjjjVUګ,+5jg"MHOOz>J"%MF\ϙ+윜rAZZz/V]hтצ Cs!ĿVYŤ[Orڼ3-qi++K!的˾$UUwYݗ8Col̽ J`.▐9BjIUK*(dcL !e$8BT[* sǁUB!S$B!D!B!UB!BT !BQEHp.B!D!!nD < ޚ.*b)/''.jou1,\qӸLMMBg|פ?5j|aB!?…8t\ymѢE9B!BT !BQEȴ!-Rcn ^_%BQ!0/Vn !nt:cOpСJ.Bd`r]R=LkB!\!B*Bs!B!s. 6ANˉCQ{' !>$8BTKH-YGPTvkB$\B Z7(w`y8 ~09~(sfU!M !X?/ @S_p[{I5l_">!\T~};&˗/Wƍ1v}~`%6oMa qqq^quុuJO*,]{b4oHٮ3<=_-d2Ds!uSZ Bڵl x˂V-_pDm\z*Д h֬ +6777{QVZMNNέ.A$8B*XbdddT8}gggmGGG233͎iM~~:0}+#|:RT*Ȱ9zRմ4e$ɉDGngͪn7_.`Sz"@6mضe3 :D9ٙ&ϾưՅ>1vmPm-7݌xM圊5@˖eF"q`_oc{۠vnذ!1vh4iըΧfGT۶l&WFf?]v-Yv 7 DZ3:o׮!fZjYf]:w-T/O>WTq, obMl ߄7Zdkf֯[Ktv:u제g}4y7nvb9r>)׋ IDATDElch|2%Ξ϶d\!%Z|A/_">> YN V5!۱uv{5RV-hJŬ 2u:Z-juaxc[ʨV:e{IJ`g8991c>6cүQ+s)va#է/.Q y{hΜ9d⹁/ dSz6nD|BÆN ؙT0 |9^~UΜ9/W\ۋٳf2nۏ'_~gjk???f'M!z\\\Ѯ6jJMUVkP\\\hґ\::N?AԾ6;w!++ɜO>k{=4o:u!77///rrrʬ?gODDF>e=VTq}z"1)_y(2pELJS户#4n܈q1Xm||a7R pɓ9r(CVޟ07GJ϶d\!ׇ }=wMnN||<NbϞX:؝nvv6f\0LF jֲZ jw,[5999|~VZ4l؀~zq/lْ| !99j9V\ޮ(۷kү n׮-[nSINNd2#ׅ ݷ|lӖmcr_DEGc2,5=6'`Uʴ+WҞW*56_P@qR"<\]]1 dff]Dl)O_fk3cr%^~zrR"͚5+}Ν?Oݹ{1L$$\,gPP {/d2QPP裏W϶d\!/\u*322ԩSf%&&`ƷW,%.4+#[1LJt3)韛|11lyGh4Ҡ<%֬Zɏ?G3gYI2>.Ա#gϝE7ZU8Mbl)/zv̶]JLjmMrO6+嵿?IeOJLۛؽ  2۷qf/XH~~]u)OQ}ΖTq#"_`ěEly{ .]DzzzL:+z=f}̱ --lybb"j/// - ΅ %--lޠl[tqPvWY˲z\qttTFakgZ^o@V3❑oN3 ̜5 ?cQL`" j3OtѓW 'YիKMMFz??m)ZX`<-#o)әo0T)Q d<,.-笱էJn1YӦ̞5.\@דp1j>XUЧwo.G6J 劆?&D%}dZBT"كzťRӎSHw'g]$$Ӡa%0yhp]Z[#..sԟCyΜaC(7FvKOOOu!;&N;Q= |9ee{Ν  WpqqaϞX֭K)e۷Q; oH[ HV@\ lKh4w߽J}۶mklп__=ӧ(yf2KNj= 9qvץ>aseէUk =vĤ$<=ݻѮ?mmTfԭ[(;&'''N>^yku #BQI&c>J}T[iݻk+IKKŅf+S]b'ض%^ϥ$+-{Fƿ>ӦLoM&V\ܭ3r&}0=1HOOɉq'pq>_ZMFz|8y]?=dfd#|qO჉{g4dggӭSlդg / ܹ5'h2ʶmYvP?`pvrbلo٪jj[휚_|g t2DFFq-mL6Qdee="C ?%:2ty{hhp]|lAQc Xes`o[T4}[}{^̥D<==9t{'??0ьPx/^$++j i\|///>3W=S&ӳGwTj5NblTrCqSx(1ԠV󬟟3ֺmX'~C\ u9jr6="JĬ!O=3>WXhQ`q*zMc///ӕ5KrwwGՐj*rA~~5]u:1j 55լ* //Re,R.iq=zeVEBիv h>...h4RSj5^djZWE\Yl"J*9r]ԏ)2ӷ>:N^YV5ɑY109.)/ߢE |%8B4738}<Y4]wƵE7.}u}JBۂs"!`|-y~#qP ̅B !%UA.sc((l&pp\!-#RTO`w_%?EB!BT !BQEHp.B!D!B!UB!BT !BQEHp.B!D!B!U~~|B:uK޳{bҥtԁ?[_MkδhGGG.Y@:uҹʹS@v툢E.￑3^z\%b捴k׶ڶiÌݤRo f͚B\ ΅ھ`MR1e$~W޽Nrr2{W/2yv*CBټ)g U=Mƾ; Yf6,~NY;fs-?UziԨ I"أ*_|n&;#GK/e8__ߛX 4 ݤ !u٣;j5,3SWF# >/XH ۸fS=y8uꔲ]Ֆ:v?pv777/ŅRU*fLBEe,+ח}ShxNG^~>7:88Dff+rr2/4Թ:leEӑk?x}p˝ӑG^^^(ZN#==jyh[[e*ٷXZ :::V. q+ȹB\ݺeqFWѽ[7T*{Y-^bΝ:g -[>̖Ɓ}tY״io"|S۷pʾ`-]̒E_3:nu!쌎b÷kE'TAÆL7lؐёڴyQCmk5%l÷lټ=f[oVMŦnN^}e0OOĶ-Dl_i| }J~kVi#۶ӵKgmlWql޸v\t [6o2kDz5i 7n`5sJ:~R,%_߾@vFG۵lv K9;lݲ[зOo-LƏ[̝ ;# iߞ5숊`ۖ̈́*9999L!ёDl9Q]m,ĭ$B\Y.NQ6%ߟٕڹ~̚|ƣ=ٖݻccz?M^Q#V}4m*{b.#{'[!<#""ԥ+tcټ=Me_(?Zo1c,:t̎b|ɧmBn=xEs__!v=B:2d2e~:vJϧS=mR*UaU**S&;&CѳݻuñtWX{Wйkwh݆ӧەFYu2ǡf͚sDc=J޽iB:v&l&O;e$buv݇!ڶ2i4jժ@Zhذ'¥Z-z4۟NbSP쉥nݺ4oo߾}ڱf-Uw\qq (ܳGwWXWn0N?=nnn<%nۮVGEGӽ[W%_(\ ӿ_፣%۶"뫴uDEE3hЋԨ)k ΅:L&Ə{/X=^^^j0~l6Jh]IsK̮#*x{&N|ё=jW#GqFEĶ-o kO:-n 4lؐMaoș?$--M?o{7[luxg:tĕ+W5j4OϖMlټڵldFƿ>{bp63fت_ecEWPbvd5^Oմ~F#۶G' |e{w{Xj5˖.apRn4L>}zbۖ̈́o 3T?!:W;"NG\\HHHĶl۲; if qBhde9gLmC8deU3be{s/h3QTѝݺ)Y6q|kZKI899jq)EKj5^^^dff{ kwwwZ ))VTTx{{LQ(C))xyýWTxyylR%yyy=iTm*+Zt::^oV}RԾ_ѾxѣGT>WqnnnFSpww/gHT/b0۶׏-7%-Zp#v/s΅Rnv p탋qmޙܿbsWa2۸C_)=zj4FT3\rb2Lh4*7ZRPPP*06LeSg) eU?v233-Z֯_sa02eÎ䘭.DU'ZJ?!7\^CQ۹‡>=w{ jgٷXBT9 !%UA.sc((l&pp\(N<ɳ ŨfOãSW/\QmTVhw"/J5[Q\ OB !BQEHp.B!D!B!UB!BT !BQEHp.B!D!B!UB!BT"!Du^ŋ|lƂT2!: ΅㿢R>Łϳxr'BT ΅m;08~8ݻus江,&'BX"s΅u|cZMR~*CF iժ%ju_jՒ:^j_m__J)%)5kVZzK,ﯴF\!,0oݔaC0OxURO?gf=<<>>L:&NC kMOPP Z-[={Ѧm{.^-`֬iґ1cpp(Ls˃}{m:vB6f:|2 *k4K|ӻ>ތ5SanBGs!T*·n[©-:H?(/^jU׫GnN. IDAT.%ҬY3Mh4Ü8qBr8::@,_,6_P@斿X| Q9x<=<_'Nڵ  *uxV ʕ}jբa| ϏeyΟGw߽L&.ZmM7 kUuꔾ֚+Wq:vZQ.UˇNٙk&)2v哛ӧOe֭t&!D&K) !uK)ew_w}7?#W燏=Bv%ӕ+z HIM5{ ) '1),$|-1>>Ty| TÏ,mR?y]b4yc0s;L:+z=f}̱-`HQ?774|}}9{\cUЌ7{C]h׶Եch4\7(=^ɯĊBgΜ~'$8Bx0^9DDFѵkn-YZ^O^2j:n`0esI̝gW^>>0/WN^PՌxg$-((`UZ>{pK>[0˗'22o wGO'~Y39~r!SS!Ȋ˗ͶjCmZ СCM?I'W( ĉx΍s^* //O-F!-bi988EFF hq >UՐjEӡjqss`0ڧV`H) '''IMM%//OٮhZ.VŅk#Bk`r]R?}i^֢E |e\Q-%\}q+7 Z%[SV}qKL&z})'yk_233%Y ̡pjLE.''Չ2랗Gj`^!\Q-}l/<<ݻu+y ,zjUU;BMs!Dd,(`ҥ`RUF88H`.░\QmTVc8 W !OB!UB!BT !BQEHp.B!D!B!UB!BT !BQEHp.B!D!!BTOCܠ\N҂ roPB$8BTKH-YGPTvkB$\B ZՒ6AsQ8jK!( !X?/ @c߯&-[sI ɉ.55̙3rQN1[mr+|SCA\\MewL /_EB32r.uwjC OJ{q~ݻweK[N  YfvӨQrcIPP; Z>߭.BRus !Ŀĕ~i=ގC1V8@zNnIHF!??8gggKFvv6`j\4޿__bNmw{E>pMd Q,THKUb*H^ "QH T'\MHlz$?blɦ<i3ҥK7;O0z(_;z=̘FAq=T]\t;s&?mw;880}TLF~GfxԴ4zlll:e2nGnn.L6ǏK@@[[;vFD0L4mvzyy`\Pmf׸׳}͛wߟcߢSNLFnݾYo_~W_RY?mϳBEs!uĉNHH`}|j>ؽ0NhΝ;#0LoE=-00UkXz?ۇ>ЧoG<̗&22 5?ض}* ?:P78ﻏ+VOAAz}ݷ'NSn۶PJ>_@խkq_]gz#M0LJMIOkGƍMDxFА9JpP_gҦIHHՕ^|'''"((F'hؠ\[.ׯ_et ,Khׇ+i/۶m'-[(lݺMIw97Z`!&9Bj ?{;5Rhdv쌠SO1olnNFFZ>YCzz:^rju/x_xrGg%pz$$ޝ^OAA˓=ӹSGe٥˗Ko1h>x0#ؾc'W Q?w|파&;;01|jvFDگI3$%&᡼}/!$8Bj:{=#;|{ U2ZWWWܶ|SQPPlb}ai߱Y @rr2krJ é%??3~$Xh!2^ajƎ@5kC9x0͛5 ~Ν+~o~Bq/HZB"~~~ԫWOyCsE+ǐ⣻ѫgOeV7n̡A`@n08x{{{Kyq𿔾}2h@\\t@a~|O\] sorEܸvW¨#}8;;Un; p=1) w7Rᥗ^P{jΝ;_^W !=!#BQú{=ZݶN_,^#YYYj֭`¤I̝.}{G NjٹcL78y4%͛7w!!|nOkG͸u{2Kչ|Jϟޘ(s2+W1m&%%N7fgf&N'3{LOFFL>۷o3rpѽÆ!!1777N8cq+W}iS"33Md6BYT]Oa4/2&?ӾS('OX/~VB#_#:* Źa2KMGX=v2kΞ=3ɥ붱ݝ۷o/Z^h,~gggF{{{t:eΙVqws#'7bnNVCJJY{jJ)FCzz!Wo'=n7*cUjՊgVx}9B-YNGWj;0L&AwJJJV"//b`E9@VVVvI~'77lsKF2ݡ%ee`0p aYd\QHp.[J\>?RnD⊑U{2!l !T PPIm=VM`c _4* !sHp.RT*;7*1)nB+ !BCs!B!j ΅B!%$8B!\!BZBs!B!j ΅B!%$8B!!B=9;Clf_&iHT{0!l !|H>JvfXN!N! "[ xҁ9@aGB!##B

*>'ZGR6{;;:v@gzŦ/9vvvL0Аtn&ߟvA^^}{V˻ٿo_,\T#mB\!͍ݻѪe 燷wah'r)v$%%L/E|M42[Db0J-/- 5ZFՒa\`ggGVV xmPuU*.:ie;;;QnyfffFSSSTDR%ʹ(Ҿ4nbmooO^^FBVqpp ++ *;;;j٨w5k^\S'OFyY]yyyՒ 9B*SǗKVذ!wߝÉS'Q{2fwvxzx7\ALeKpw/qnԨ/- G^ݺJ3G0p싍f_ܾ-[Kn㏼º /^"߿Աݻuo ;hִR>|Pt:!]9>9K/[]ךAQBQuadeeHRR 4$(( ߣGNJ"?,mAvVuʭ{ʴt 2ё90m=q ͅ ?кuRu\~-ӹs'lll G͛4y՟d2QPP'ж?qvvz;wkXD3"АN<+ 4ŋ &_~CFL&Fo=AP`}!|#W\X֦Mk\EɁl͛ ѰA i޼c̬T_ILL$%%oooHII7%EڵkǞ(1]pQG>{6>tܺulm[h S6!Js!¯׮SիWy?9tM>^sNfGИ [hdv쌠SO1olnhdQf;TQdgg3pƾ9>^Έ|||IO0NLLDV+-%O9v8xGG0qd¿XzɩSߡR1 JY~~>6;%^vIbbٲ$\t:-7V)OHH(3$oo uÇ5,^EO bc`^\x <٣;;uTxu1[6jh66|l A1XTR!Di !D??Hdي`'Z”"E|E>rS}ǃ6":&ẐO9+-[ԩì7o&ԓO> sެT B$E!j@~~>} oܠ[Xw |j3GzA<Ը1/^ڵk\ FPtvvV,.(([[[p71) w7W߸K+@kp 7h4ʜ؞tɬ]xSt܉Xz KM:y6jD&N#GҰA:w:u`oo_uzzYV!7WEy`%;-]ú(^_5k?+\K iO> ܹÇW;3JzF.:qqq y&'LbҤ vwa\Q8ME JOa4hj5R}IDAT;rIe g%.<mPWBkB6dt:lm5ͧ]ZŅ\-ZGGR*~̼]j''[LQTTVy}Ijj툫+dffZ%訤 dooN#55lrk"\]]h4YVbj B N{gz/ov9}jՊgVx}9B-YNWϝZvO`Sd[4 C8+oyyyVGh0/Hb4˝d2ySQ;w^T~I6)k" hBs!TXGp'W4˹B!, !T )Ljh ̅Be$8BmT*TB"!B!j ΅B!%$ER*j]^eL#(Bh& \r3:)joTB!b"B!D-!B!!B)ui`㿺Ip.cAA'/dZVZUj} ΅>>>5V_N= ΅6oY{\ O9S[~C2J=999fǼ5䐟jeE#-=@Tt4)kkζXVqtp 3+Ja4-^ Fǎ8~<ё{ܩ#ݺve :eqiӚ;ٲ+b#֥Tu e7Btƍ}?>Z=~wfۨQ#F0~Rm,=666̘>}|&K6cxɶX?uI~~~f6\\t{썉bϮ 6\|ifc彧spp`)طݻvM4nRKo Q{vƨl"h!/Y*WDT !D5| WϞ,|o&|*%)9^|b%/_d21md0h45f4 -f\߷N#K,zoo19sڗ-oϘθ rJ՟b0 a7Rװ.~999 }}͡OX-ycoA\|cg\+vvvl|!DDF-_#M_@ =<ٮ=xzz`\;3gҸt5Ο'>>͍wgQϛ31|(j53ߙ;3pDRVctRkO@@-[K 7bpuq!<|=.]bL7ƍ߰GәmǘtZoQ% '3ad\\t| :uHLllhO 3IMK~ays,'Oߏ[=ů ÇH0 cFVU5忧2xu ֝l}7K?XB^ahNtJ^^zpVckMqM ˇZQ92r.53gAD+Q#9q=Kpppnp0II-oO *:Fy‘#G  sYڴ~7oTlիFHH/mw(_~AfeWHJJ*899o<\^Wy&u黒rrrX%'rfii4lCD7on.?4y՟d2QPP'ж?qvvp+= ҋ/Drr2Ye9 Q 6h7.@֭8 ܾ}Bv +fZZ:.@PPc,- ,$5-M\ 'Oޘ:%=ݮ7*;?k"]BCX>\I}ٶm;lfÆp%uߒ*Y *GF΅lxS7OyyIÆ y{T4 7n&e3˓=+i._.{*^ӹ_/dwNNxzyիVG Fװ0z>'''eTұwԑ#Ft+$֫O*`\|Y.7w7?!!By>>g~j-֡BUjYq~cАy}`"wG}NXY*ܼ>/F#G2[~yF# Aic8}=-Z\]%|%}{&ӓbk$%%Ƿiكwz ,TJ11 Oog ΅fMߟ> Gͫ`0=0uD9v\%rΩ%))|S?^6+y0b0\]\\L& 6sNfxyz*kZ\]]s-[зoz=ӛ>j2mooϜ2|(Μ9 Uߌg؈6YGs6{ɤ}FQIQ΢b=ό8 ?/ZȀWtrKFV3v,Z>+WbҤ̞5B}a,yEH?铓0[R,ߺ2LNNÓ)I5˱/W^*^?|/oF 99Ǡ-_ͮV< ,哴!|+Zi|=Ln*}LL, ťpO()Ww{HAA2V43dBVӯoRSčquNZ-\rr 󁻆u)a4{{;lmm@|oIzzőGiؠYpTNS٥S .]̀W_ G$_8G( qqlQakks.C\x77rڵk\ FP4gggh4űcǭW:נ>yh?k}R""Q1 {jΝ;Gw9i֬R ϛWDOF΅|QT@kiy96jj֬XiSg7)))t:>_5k?lcj K}ŋܱ?q[[e2rf͝ChH[gq[L8S&1qBꀁ"_>o`"&N̼sL/Tj5.]b6._ٳxWOTj5[lG)Dٞ >}RSѠae &3{LOFFL>s/j232qpp9sջy>9slh?1B>\ٽ'R2+?.{c!2*W=Ud媏>m Qdffø ojVZѣfV~i.]Jtnr WWDO[ji)'OmX0[nO)h4˜[ښ5RSS4qEWTxxx^j=v2kΞ=3ɕ*puu%?? [booolllpwwJݍ|ed,0kqVZks[jcYQո[*鰵Րjv͹RHIIT}Pk>yL?ONx~*sm8;;c4>[{GGG4MALs#uΝedff|Bu?KWjՊgJ,EF΅&O/??3c%`7Lfїǀ Vʲ)((P?L&z>`/fh4[6(+lWk>yL?Y[2FE{~( Te/"vY",\!HfҤ dgVaf?HZVmHkUCrJJ_[+BTZՕ ܋!^bRRʅc4+TB!B !BQKHZZV&!5FB!_\IZB!%$8B!\!BZBs!B!j ΅B!%$8B!\!BZBs!B!j ΅B!% IENDB`RaySession-0.12.2/manual/fr/images/patchbay_CV.png000066400000000000000000000321741417052567600217410ustar00rootroot00000000000000PNG  IHDR5M pHYs+ IDATxwxUϝQ/.-n;qSHwzH!!K $.KYXva_P^elH;ݎ;ݱǶeIV}2eYl'=z;wttv.yXjD]?~T>xxkhyEuWƍ׵<<P.̌\k,KB|P($ LMIu U+BGKN"h EfeeyڣEny-I0 4{I= "I3 4G f!0hF0@ E$`VJh fHbHcB @hgl9UqL&c `8b9{G%JP(,E$)BCizSrJVָZ6ðƆƄq(qxclA~g+.\ih[ZZr?Bℇ⾏0PH$EQ BT:v'"*FKxE_3Ð@B 4 @ j ЖBԹ<q'#=ðK+U$9sTpl>QRH$Z+Vu1 {Cr|ݭRS9Wxhܤį=pVm}%u5[]s+rhaKKMckAZjxb߫4MLsfk&Lh:qDNǞΞ5juRR"9~q{2 0@QVG1Md㾁Yt]&J]G1HRG@ss&rHQtdDDNNΜٳv^4Sz-SNM<9D4Lb4Z }_P0m4Xr6_342"1d ==}jֶ >yyijege9Τq74ibqA/eBDH(Zϒt}9۷N40lLpcĮH `dR m?erX,sn6ݛAVț??11 {ԷhhhvyD{|TI.L&! Bnl6%Gu9.n?r(k h:!>!0wk Gqթ: H&J}AaR  k  8`l=f>cgON"D" p P]]:*뿜p:-)eee)+WIxbEVE"QEEoA[,V_bثu| p!B3q0Ѻt'7vZ `~ 2;NX0zߩ))! i=8bP3fr.=~QuII111)/kJLttvv6wzjH$dBzM  bOI>_A@҇pD! BrxQiZ0HDQEQ8N$Acah JDsZoBa]+!$DRwRqRUUPp806Ֆ3a|XXXqہROIQJ`堩^=7%}U%C'y\u- %ܵpaqSee00P(T*&J[lE`K0֞sҴ$%%wj'Xm2s! @^1gz{=B+ 7$Msջ+$& IՇaT*lnCI ymWWQqnh2EECBBbEM3rĕo֎+ #O"$9_`{h@1kC&K;65*J XVPaAJc0IDR'I$ H$лWa?KSS`HINNMIDQ&ѣ/2ǰȩ>yTf"#"dU8A"h=eB3fLk'DqqqJt8^mBDri U!!vA"VU(mmm>NQj/:^F@kXZ cǎ͟?}ڴĄ&ji4Ebk[1crLi ?96G&)SΝ?oQQFe:}Z66&fiNfZ.^tӘ˗-qq'JJ@gn>cɢE/]+.K/mi,Mhƍg7ZJJZǏQ]],>ĘYL SPT(n! CF~Xsf9???+++%%9>5KtKkKyyBT`8zp%\|^ߏ8ygΞ4q⬙3j;V(T,vk!A W\=_EsO*r<::d2Y,DP(FVE4B5< SNk)BI`Zv#& 4:$7p< E]QQQFQPxtt@ 52q $@<^< zFtXK46&'NprQ8ru?wyظZZZ?BWu9VtO?L.s&=ڌ٫4Ms޻qk-s:^X>b"#I"T,Zoí|eai>C9']* RY~\d/Yx.fFFFJ$J%O>c4̼ys? saΟ?}ڽ'Xcf2ݽj&%%TIfٜblege](:ZX[%wGJuuÇ/΍F@+  Z'vu! Cnemxs9{5 Vh44p!F8^iZժ[/c6o|L mm11 EWV^Q_PW^NJJ[/Ngʧp[Uk[,_uqn•n[?蚜NeeСìFFF&noٳfVkiI?rWX$FȄ Bm+[ZRk42FH4F#hD@5L4F5Z4Bqh46ƪX4KKl82H!6[HJKK3f BhP_˃|*`X>3)' E;lURS_L?TI.WYT744!Ι3=8vط~!0;E$ `v~Wt:-@'@`j^ikurMHӓ3oY|ĉPQQW8o%7{a;( Gӥ\~qly p+xll,wۚZ:r9c H%$&}`VY!I Ă0H#L!H#(,Z&K0&0)(\$c(H% p2@lڸɱ_mt@ˑ0c;Fhaa 2t: G."&&-p:r(|ISss`lW;}o'Q?9$ !yA;h PT)(BaH&&mc{Wcd PD;iHB搄]K {Ϟŋ8}{R?!&&=hhlp.MM螁oA1ϝ;?y$7wαٳgs;ui:"BB`vPa 0 ᄃp(EAQRM$jq %]Q7ppH)aC ld; PmljP^ή(j}>鋨etw0 AnsLofvbN\va=2,Ak0DЈp?Y8|!puSr\t޳ڒғ7!7cO;:.N|c]Q))8t.BKkWN䬙7@)3O?~Ą.[E|)Ţq/v1<6A/c8&m0ғ'}} 偩;sHOd[n muTԲK;;;Ngم En[ ߼P*7=Fnnnn6 I&ʤRгO?ugZmȈɓ&NcQTtlJ0`+pX}22 g=PFefFoo}N+**NH$qM@N顇۾cmk`ɢEK-{kmk{og a áÇYeq8sAanƖg:tM]wOMI勯jkoc:: tG|: O>mk̞5qQӪfnG%%f1reHd濎hU(!JV顯?ƌ C3ܴ.-;\ʟ=<}W-!-B\52ۗe˖pEH*/rmǎ7}͛XjŃ>1AcN~pv҆XP{[T8Ώ>t׮=^T-[f] 0R"CKð09\Ԡw^O/CCmT2~|#l~ ,JrY@g#3 shEvmbZf:5N%cNm|! )CeY{#Cңaj/ +%!& Fg'$K-: {U$JDp9P$e1SJ`m밚}m$RH"4u[IlijikpQU~`, X,K-[7oN_#Jq0=j!5!!>::p47xɜ2k$=mIjbpۺ٦ֿdϿy/@|ۦ^(Ϗr!ҿ~soIPgg>튇~+eņ!ʡ)o/|+׽ə맿̞[>[ƺu7$ Mq}Tu=ص*6}XgOW_?:;vcmINvu1 ''6&&w7۠Cd`6mLnl3ϪʛUQ^×vȞ%GjTQ oDԁ He?*R8UXS? S&{ۿ|uȖ߮8]\Xӱ?'&W~.XvҭŻ.1u["9M6f+"G x4o 'ğ'*jŝ;֗e觉_?]XXuם)//߳gxJBO~7zC30^"IDAToެ6|}|aKS[2DC&ݜql9!%'8kb7sT&zmG@]e;/3~Ejڻ:W:E_YE.^iMuf< /}u d_7-q–n׸׵iw@MMP(jě6m /˗]~0ZZ9ĉ{׿̜9sϞX1M28gzzʎf=O䭚(lV祳΅'} U1dq(} 剃n^8nlNRal&ĩhul{*mFm8qF?x,<b1ښt기o~ HrWPTT;GڞS\UQq*>|j6[ꨑϰF761ñ)Gm??DbB(TPƧLy4>VʉKߕ]. L414ÝڭN|yO;Gʶsk󷟺RoθWw OO쿮nwVCjq(Kw̙SqDGBI*hTl"_kkك '뽶oLz 3?xњIgGe'$eQU!NGozy\:أ@b=u&L;f5ͼޛ_{ꫢrж8>jnM'!V;G/1lo~ð~̀bյ=M!~G}lL]񚙋ɕEk'OsBZRF@8$8|R SqT=$͖_9dEɾRw ??>w0:^u z)"&4s\|IrAce\a:MѦn[Rr`Кjq4;utg[8ry+G}:\_aghs._ȦMh$I7F-H/C :LD,&EblaaXLbxXfqit6aV;*;g c74QQQ6?:>+>/Qo5>" NV_ǎLkA72}Pղu52RoǮq3l6#%''KLLCegggggSwIpa^RRX,JKKq\q9_hAjjúugL\4x l>qt왕UMW5{7}=^1;;wU0>b+om%g߾ {ûWe˖l;v쬪ri:? w VXr0kT}*1 ե0RLL(cp!T*FcKK<į.ۼmm}Sp2t'Fh_ltiU r1w3gζwxFs&Mʙ:5W(|6Y'NOk*Aj۵k72ТZ4>9x G: #CFj*S.]̼0Y)ڠ OE "xux Oڟ8NR0 tʪ^] 63f>MӴVEQTnj[v|o_r6lXz ^k¨Q2MX>~|m4i3 kA B駟/sʸpΜ9w̹48'&&T*FWχ0Lmmde Ag8aĄΝ;^nw)M>Ыí[?*'2e2WÏi?+h'OJH$_ ʵZmXXʕ,]D3+oz>dJ%wӧ8t5kVG wkon(8RoN9}ֳ.\ӿ?-[jÖ_V{7 !|5&F}+mhS ³Fe-Qp_z?NYnB(==-:Z-|onXΘ1}̘Qo< K1-P(/p/_V9]'ޜ~oMrH/-=Sj֓ahh/3bR>q[1lχ:7K/_ʍ SGJJN>Ц~wCeggK>JN&\z>lmmKII.**ǭȨ-?{&_>q Ex=z>,,<&֭[!pp_ ^&$/]x̘llld&<<<'gBFFi!wݵ[iNOOݸ~.]M6>| Ww=gά+:Z]TT###222,_ЃwtuW7TA9||+V,g`1Gn۶B7}Ž{9#֯_s[6vۚe˖DEEmr٦M̟?W pqo5+n^ZZhJB D"abbP(hlX,NJJ C$<7=='Oi8ΚᑵkOk-O[A?`邟4TtCi#WSFx]HgadHMJȷx^kyjKAG :?X$IENDB`RaySession-0.12.2/manual/fr/images/patchbay_a2j.png000066400000000000000000000260551417052567600221060ustar00rootroot00000000000000PNG  IHDR!C pHYs+ IDATxwXߙe K[:RD `A-XK\crorIL3cƒ^ wve{ð "p><<3gs杳sp^@ xyL?^݂AjAtg hF`(;+A(9^u΁L˕>ZH-/KΡ+1$WuZZ@WҤɞY kFj1YLt.mLkCۖ&Qfqq1]Y}DOoH0x9&QNb3#UہGE LanaLƏ@X0)**2usdbh ThaAjAt1qI!IKOokпV1#^tceȦ]2 b|Ǫ͂ArAtgP iӸ 00zxE} haA\9ZT$RiCCCAAA D=E<+H0τ.///++UU tsw477OIIMHLy^#L;0l`PPhHȄ SRRƜMKORqww{歲}X,)SΙ}FV8cMXh7fZݝdzTgryDx|'ݖNLa! ͛L0iCΏ˿XSubAV!QO䓕,7*qF7ƌ8`0XŠ'L8#JrUD 0Sf^ݧ8N~N3#Eb %ۨV=w%k7n߁8ۻ~NNN((M7{>. ERrrG c~ wҟh1c͛xSk}Ż fhQ@ HJN^rqw:O>8x`9g_z헝; O(t\.OrrJQQ1== ,fPTㄭYy(-5b-Kxxx@ ̌ r<'7/qcFĐfׯYlCwmP to~3A{̛Pl:tɦFoez6 'l}ts%^^T&3%[ɑ2pF}}}Qq\.TUWe7J%~V6CqXlqOL7o^UVޥ`/SH|y|T Qˇꚛgss_ac ի{#?A7(++{6jXX67qazt̹\@PU]M;py2=_8۩6,T_`9.H---s `jH$ڊbEMdvܩ/#"?"u_NZ]'d^9yڒ>!se2/xj Aʞ\ K^]ed2[vĈа˯2h7[0H-toII)@R 8;;UTT<5T&#yzz`f\ٻ!!!޽sƐs*;==q||3`c"#lv}}=9觛9:4*U>:2E&55טǾ (0%Cc ׹\nIIg~2zqt⒒S9\G?eb0///OaL*U~y_pqi77[`lSCOp |Zs j^tr+NP```@q Rb'O*.)1>P(^\{1<4LT3|B2#ʼnL02|TXQq۷;Lcy.$7ϞgȦ Xn]tiԩZa&vmӚ=OFR*=v=]t[JesNNN3gLKi鏟4 &2a֬ǎtJG9i$Űa4i%gD[YY-7.`L?~ҥqqqgcM#^m7A#??Rg}}0``ZUTTDǰ~}  H$Z%L:u7o:qt7888@eefC,&@ ꒵{uӦLy7]]]gfew) &GM5s+$$$?qa#2#6thhHȈÏ;~&&c!:605)S[[D*5rW(zժ=z`aFINNqtt2W,O>sz0bۿ";𐐰3fddd:99BBB ꚑ_qS@&_BPx{XZZr8Z-J]\ܹ[T\3% Y!0KKK .ΎdzQ*7Ũe@0D"Ex^0D@A  `6  m.iD7R <-A- >1AVP cX-] H( P @1@.ݜ*D m wh]aۚ.:pGa=%T*.5KdZ8/DW"=C0&ј_nK@G 0pdہ^1 1Y/0v":YTuu{ݡ#c@́l>aؒ's@R\w6jrY& 2`wrmMſL/猞D?Ğ[9g-Lh2rfmXJ [,eE|;Y3-Kc3NK03ct#y?os^>thgR03E=֐0=~p(?盛nnߨfcK j>{ku;m FN_7ںyTjhMSFO| +?cVn6,D\n6Mi=^<`ԄɰֶN<;oڴq/YGn.x8/O˒ܴ䬛 ١*Ȯtr*/gzR!e#)7,Cl|gy=źU{tMi51 6:E:s4whzRw#w}{:r@ꤌI|LՆIA.,)JEg &?kpIAMzrAS @){0o&±D Mhe1P}V'VQOJՆns-:YTQ6!LUj5}(C]4&3˧^>.VMB0$eB%NMk&\94b\^C|@/A˘\zEZ?uBHObmtGt gWγk T{fvե}`TȕR2-3w k0 r26۴}1ǯNJ Zl8m?6ZY o#V3Bʆ i}DJT494,VMB0@L@B\F-@Ve=,#9>~iѺy \=e.hU{1hrρ[ I g,ʀiưs6 kׅ^W /T4 8Ȟ,O['Lm̎O|^ 72y 2 @ uiҕi1-!O.SNb1KFfe  N`T%扄) Cxvd9sa-\2îzE>(+^v?$R2K_oJ'Z֘uCTGdou>=iN Ú{G~d[~b,|R^ -o]H}usQ^S4ȩ)ߜ{o˜v:YTM Z>?CDKLK0@LA[`=}{^W-S9adU|=+ d1 烖:- yGg%qr}zPkH˪_Ƭp@M>f>'rգ箊HnKq6#ks A\-ЧNl~`@jrɕ^zVl,ܼEBIqn;Ja<0Yf5Zݐp82e ã>vN{mɫ@zML!Q9ɫ8;= q P,9>L'׶Q Oe~h֘PV"R3b- v͋@t /G|ϋv鰙/MDһWvzJ c a:=6"1/M 9/D!:c]2S! :9{?4ޏ@:l~0T1TKa9>Lg>#ësfG :maHaс`8c0&TK/{>ofJa|n *qPa: 5Z^z/v58Ӂ\'B\/*?N*4/YVÌ61 `X/ kNme}FraBlByad=E͝1Teњq֜ڂ;k凓w|~:?pޖc Ҩ5BRcj*l%1Ge:%I2dNxV+?||jfM ֹuUMAWP%ڙ6ebvNoOH4M?=wee/? geu_;}h|QW-*yU`:l9/ &3mPJ|Gk*aoZyAƬxܐȾ+7Dmq1_3K;4AaUZX䱞7 3Šcd_`nh:F?wϵbm5'76Vk0 ]].+*bcRrKzLLSkaH?{Zf'W)wn>]tZZQ"7d >z@@!Z\t䪏&gUlZ[X'2Z{͙e$V6\F,YG/GT,('-9Წl-@RSE[ݽm,"YnF=5`@"TjjfjV T/ֱ:u܌2,qgJj@ ^"v~q\j4[cl QV2ynގV@RW&LH0ZzXłFSikF}4dRj ܡ0Se*Iz3h%{\{~33ƊO(&Es8+v{u_1xQM7\8-]7VozN/];gȾ% ?piw&ZL}gYoMi 61O-͒>:^aļOW恵3Ȥ f4Z9Z2;8܏T5sðMWFٶ8vc*!fâߞ iVe䮌#?L-}kw>)LZvIEX!jaIqٟK.EsGO<"F}s{ v"@|h3{2aP b%hptXevjB.Vl};[k84A${~vjȤ +Z˄|òu\X;Y|zy \d!CFٸmaqnUn̯\%|hY]Bxo^?-؞%-|+ҧLxwd׍2uհʜj;ܿ|Ry0ke#Os=P³#J}xf!BO%]PhMq#$o?~^SVWm;WRoPcf7~*^EASecL&MSF݋HU^\52;$aB.3;dVT8#Tmu}iA5TZ0x^[]{5Xr|=^l @C;tg/'B"ܣǜ1)pܴA# $}=rņWZPC퍻.mKq.^\KXl3[; ^Luw#i?nt_y66L6G/n_J'_0c2j* lxO$ZS*Ti52nGvDĭ N-|3ri R<w70͏~-{:}&t'ͳݿzߩ($onޒ,K׍ $~L^TJ?$qҼ!}+Kc>vkaK֎㘳TJT"'T[N ۺ0'WiT8!=5-%ge:g]hs^>/YlJn}\ f8,1 ;םa~ ߌ\N/KpUeG=ybB+rҖecֵ@!WLpXBrCԨ %4?iq!N_2""*>4t>ak7sU.mtNEqWߺ(lbh9+xE O9qjȾC}"&1߾@?pUF%uKtYcckAgCuiTT X mX .QT !ZʀPkʊj2?պjџ_hmR?kX0FX:o_JW0L@A>Aeџ,k=V*zػzړq(zz;@M"򝦽55?- C[ 4]%b̭Ww*qyq-U&_*19ñi88خVt_c9;[{}]^\ sd`ިΨL@g=<-BOr0]M(ʂJo?K+y\BCe \k^^\r#B ј m~qqU0mÐ| 2 Zb< '[ O,=yTLcZːQ}@+iIx XSKw|~ʱ]xdbG1 \zJâ!.ʭzT @ {Tv8R xvtJ fLJ0s^ g$k\)Ez;Qm-Bn A/DrC=9J>aZ2{GfLܕjUJ*Jx-*}P CB8bO G' zUI^Nmim1J햿?湇EE~f4/Ih`E#{65`X/Hvxgl^I#T:rH"-\$‘}TY={9FL iTi[ 8&_ wQYa\1nfpyq]iA-XaVL(TֈRa޵)wr-n}?\|IeNR4hd}5/AZI  ]ڲg~Y e5A}0^zM]Wo1ܝ0g Qs7/e_ `0_ a83ɥ5IfwFdbӧۘWN>ڶHPӐ`&xz2IWcr& L/7.OEL6LWv|v=4~VHKjۆL^J՚[^TKa+phco~:}>^Gu`ӕ%Y+7|ὼꖝ1)+6D8v=:^].S))wr~rh0 27:b夗&>3ksWE|j5lxtQ6TɧrtV zSN<(۾xmF,5r?+weDT \ϣ\*K߁ވ rǯZarԁg !$"YLyèTT_<{g2Ea,muUz'7[q(4`s=}XlVTY*P_8Ӗgo%+JZ?wɭiO  4i;LݿQB7,ܙE]ȮACBͺnͨI3sJЬo&I 4U1,8_!S^8|WZL6|HdUɺ4KF~vj1L&B @) ?]0Z :##$ޞE|\Ú1QF :GK0hV?! !5.~!]=+͋ӌ 2a Y,/KüL-KZuxѕΥxY0&'G G5YM,tRFG ۶_Y0YjI Pz2^3&{CY:!KBE2-L;4t%M>c>>6- 1OfݓK @ @4?D³7IENDB`RaySession-0.12.2/manual/fr/images/patchbay_base.png000066400000000000000000001326771417052567600223540ustar00rootroot00000000000000PNG  IHDRj pHYs+ IDATxw|Te8 !BI =+몋u U,]uW^ *wWH(^^C'|>Μ9}d[B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!⌊w]Ŭٷ;DnxBh;S!q /,w!6: B[@Q8!/!Bu4p8NGZ:U*UYii~^^*(SwIҲґ#FtvB%V &7~x@1͛6o^rU[,?omΟlE͟?uªޕ/?ȑON!PaDrrmnֻb*o7-;B換rJ"8BHB@ vF,!Ӧ->SL*|ͫ;yԓO=t:cgD"lkG!z h @mnu:= l=k׭;4sm=ޭqXWn_Ϲ^*uӍ79B~7[,S&O~hrgᄋyI|-[JNɲehTնZ {_7.ڵ(jgzj_2dX|>߲?߸isg5B!)>Djsrz}vNV1̝*gĈHt\I 465'lnlO<46 gd/ƦůZ8to>h>p)LV[mKJO4itq۪nݸg}wyG?oƕlظC<#?\SS{̙NkBSp  ,55-J7 zԔmٲiO >{v\E#G3caÆ@^?lPP^^Ï?ie/Y}ᕗb}#GlFQTqѨSB˰^^4. ȥ J[7޸~aJN4z<+W BpQ{rc%I[\ь8&B#BUVVSFo~zqQqpՇVV{V*UFRC>/;{L&(o0?/oI۶moSNM0;G"wy}رɓ&=p}c=A!#BmD"{G[zMqq簏+*nfye +WjK?xtq󋞛^6mӦֲͭe붢QE%%c~V|T(θ喙3f>\z>"e݅Yo;}l/맕y} ,?nu[Njr$S[%Rs~TB.ip?ZR+VkGVPn횫^BΠLTN>]iӧx#֑ܱZ\.W#Ał>"yCf>K ^l`0!POG4yކ@0XQQi0\\2 fff464; B!ڂhZ[f;{nu@HvN6RQYnnqnw!P m/ic ٺ}~$ne}+""B=G4?낂:(7Wtv)F-0 sL&lv{0h]>%\9i竔Jtp B G4|yEy1c/X6nOg4:Xȿ=RRR?ob1|9 avq_m޺}_T,~Ŵԏ?tͺuͫ;gx޿G!;>D`0WYn1?zn0H3z49v@^n =Go=uZ]T.ZS?x _5rYVVV[A xثG;H$žicDr'x\^bJRxzZ>ܴys 446ݻ7 n޼.u}ͺu&ef|4w4}-~a?ou6mv?ۇ'M/ɓ'Mrw߾w׭D!:GTJUvNvff`Ol1|Z:|MfθMdbW68>M7_Y'ɓ'MXS[wo֬ B7pvVưnlX%GmΝ_Fz?W_:l9s6vJD!G4\m􅊊UV8ys) (jڴiî] 5Cddf]*X iz ۿwEkl^7t#5xF׻o;~3hŪU\ u}3o^lm[g`Wq1=G!c0}D |yy# _7~#<..ʒcƕ;~Xw;we/znW|>_by<^ɲhԨ{6?/er<`?irr ۙD^d2߄BBv`OL0A TTV?~8ٳKL+V]\t7 3g(ʢQ]<{c$o<1GhKKxXS&M9cƾ-# ;zݸ;o= Ϛ9=Ey`(##h>R:u6lܤVkk?FeRC|>_!27`!9>"<@ VV _Xo1yF̋^#!QUX8TTٳ/ĻD!Q>#KRRf*L(0jNew~( yj{/>}á=>̓h4[!PBuMO4(79YIQFj-F{vC,a -[~B904aFQ;P(DQBp:ԐiarY(|l EE#y<թ !qfuk;t uP(2dXff6ˋDuuMM5Vazxӗ̹oA?`MM;~xizBhXRRRj;/?ߺu{FF^_ 6{qEaW_ =B1'OW]10!k +\^N|tjj.44TG^=m ?࣊ʡC R{`0g-߿Rx׏=fS￿TV_6lش|nmK/&B!LQeN̙#Vk{KgsGHzA.TXС#`X\.B] g^#I_0!>N#G^gcu}Sc:{˄Cm cO塨O#HB"dԩ3_g#tx{766% ENN /hqqRRR[eZ Bip8tT.TDQ[QJe#Gf*l}DRƎ @>k5 v}W<%N^|w}?z-znٲ/VO/xK~zH P?!l6oڼyUm]`۶;=6ԩS`c :xW^`#G?q;#ԫ0}DWVJJЁ;S| C!ٰau~}p??aA{痱 AʕW\ݽI))&EQ]XPvU7to6[v! G4U*Hp4TPk2#P5}ڴvjI^yu'Oz򩧝Ng@ H$6kk"S0}DW,=zJ8ڳgc8 B(I(^Bvk.@s84Mu sx㍷kk^~Ç/NB;91N@:[;v+ Q(NTFv:As8wv[AA?xݪ _v@Q7xo# q|2e>( !{{wމI&[N-:eˢѨVmcn\(޵k[!PxcK]|Ar\*Ud$H$}ٝ/jvŸU z/-+#~}߯͟_Q^NQF.Vmǎ/0bH$:ؓY{]w'zZ 32SccW^-:7sm|O+۶%%'O4mr 7nٳ~7JJ6lxG~葇=}L/B= GԞ1|ԩGYڕ(HdJF E& s |7 áp8P4!a&=tOl\>bDDґռ b;vv:op۷eBqeTPT4ꉅUUW>rrM<saC ~qIӧ<lٺ+.uG'>6iz}T__ّiҲ4>_tfr^ >4Q {krPtȴsRڷ_4ʤ|Cd2EQe~F0?/oI۶moSNM0;G"wy}رɓ&=p}cW}LQRSDI55`;4U nih1~o(FӞ=nO?]]֞5nwԍPI| >[ou*jN{ΝyAUil.˯/6o5Es>.vͷ%V\YX8LVWW/#/znzٴM6Z˖ۊF}'qWWRP8[fΘ?p)\8ԺIn%> ^*EQiiG IHH~<3}ۯ3@K>fCۓoքގ2hкkB5g϶8׿S/Z{|ނMYGK '+rGoگE*p8ν 99j4Q_G D*ȌƆVsG\5rdY(8ujmm%;?P{*p=]JHǍKJJr\BP @G*߁~e~.Žl_0l*B#jEj BHCCm(S2:䕎-֚>5sG_K1A{]>V(:BVI>_8vl\ǎVu-}˱'bP 2`0z@ 9z%+HkAjUVU_MEEgov#"ng'PEtJ)! |>_T~^R6 ϟo+!CϞ=k4-0}D-B MsJJJѣ{;fefƫjPpE0SN=gN'4kBn;lliD\V;vlMPVVʞ ]cptqNe6o'N)'ٲZСK?"++ku+/T(^^ 推D4(LT\}#`4ENռiӦv546VWd Tl+M8qX,|ټ'֬][S[;xР_=MY~سw_{o^KN>ݹ7P_D !CTTw8!+BydedR(q%%/<Ν{~sbE<`dg xW^Vp]ep{;f4=}nPñ% Prf32!ԗ&N **+?}٥S|V..B3gJeѨQ.z17||ѣ_\%K^o)&͜1c߁eԩJJnh$ҥ=1>B0M!P__XB'x<. @mhzŊ}/q,((5r䑣G/yeί^V6a]4/'7Xd_=2&?gVVV-N0dz<=㖛#ǟ~wPÆqҠAyyEc7HW@5sm}yy3f2e䆆?_Б[E"BK d2ۼag/a#j`0#Bh믟>edw`Ent!`(d2p#B%@xB=+zj&LQK\.?[B6" A- "W BGԒP\.9!B%BT*w,!wDE! kA]C>+S N;tqoGY\YS`BZpzޮe=t yz#ڂ#j$')&wD!gS Nۓ7mp#ja"(:9YpB(Φ^'H(dB蚃#j)Rz )Bӥܱ´s_22ZFW<@8"(꺺xGf3SOq ^k"!0km>~#n{ráx&qJ{3>@g4vX8kԒ%b@QTB)ik%"Ql$j}#B>u)wD;QKH8 DIud .DB]v:EQW^3c/&D&"~uNyLQ+|>D"(bi4(WԚL !t 7SgMn%}x|KBEaZFc҄;0}DzRL"Z\Z#B(*,T*{|n/}(x&>}^/|Ar8P,''%%'%IbT*OOB-5uu(摨0}D,Zm\=RE"=)Bv{/>}á=>̓h4޴yH$<WbDMhRT*BQYy,~£NQ꺺J1##W u !L,EQÆ,[…rah0Fv:]P(Bt:c!M P(Fx< W}>Ou4Me 24/oDVV'^(pꏢѨN&'WL>_h2;.P"Ϸ Se*oS\y̙syyyyg4i 544dŋ1Y ௪(/ 7gwG{ya¡SF樷Rj:܏rkk/8VR689Yf256#tIIjXyB'|VPUTTZ:o>lJśo~1'Ozj7aæsm^z镶Myݳ!&Sj>|\Z`DqmG:êӥ*e04d*.\B%~3Q$8pl6 9V~8tX,.C5>@hر=6qqcLٽ{+`$juN *U*]MLA`0{|UE4D!޲Ά1!PgoR]]P(.6lɓ_ J` j]0RB&'BB:tĮM%%c B}BE Z\vSﺼbHOhRzL0}Dm2hV(4`256-A!Y0Z};>/~yٲ/Vk[]~ɒE"ᕅ#6r!YY=U&JHl KbqrqDxQ(,#HjPϛ5xG0)Ć}p tj~<3՗~u! lذeb/MzU]GOhvmnf$B18s>\M65t55B(A 3-Bl6[7 a[ 7x.==嗟;|nԩ2L$;_G" >~o)kjΫպsuD#jfLKPVnCj_Bh@B~\.X4M}܄E$z.hlzpX !J8>X,*j5B,Zo46;4JL99r|ĈBS]]`i.p\.W('%I%X,MJh4)ZmjaXc2565X,+kF#7))WJ>x<`0T}Zm!G(Ñ\4?om~StMZ4(鴝?hl'Vt<5Gt&SSj`RknR*Rr;4P'#wu{3R{;{^^N׽3gϞ;9zD"9cNqg6_`Z 0( tC=!VOUG:?mml ^4M{[R3gl߾#Bpܸ͊)'B GtK2@^sd )B$?Q&4MzP6lr]HΝl6KNcK\RϮ( BHl:>=Q!PoKIQtǼyO5ף.۝nVUuVM(Bі+baj51LTIa&9`0Tb_RB(Q] لg6;I9sHCCZ*A?0/%$L1Lb1L)65ޡ!P]1jք}uۑ[(~OOμFb25 960 z}Zj0SP]1j>ڂeBޡJh'p|>LQ0}D~Bpa&ScJJZ7B(A`CZSYڔ Gr>[,|)%$F.6j=B@R$ށ [QG͆!:]zcc !$ l&J'KC%x(>@bLQ0}D0QIKW(46 Jקcuk{uGRR2ÉDII_y:`h [~&%Y|C!#j!"ۘP0}D ].D"ujP:.!B@G"0G9C=@,_z^K*M !P7%%%"Bר>q:mOPǶ1p q=Q;0}Df46RӥON[(T<?!24p8pXh&&P?#4) i44aϘLMF !4P)Zo670 #@4#j19Fglh4Tj8N|cC!5z}!PG4/z_>0t!X 4MxBbD"u8 0}D]V˗HQ!B 8z} ,#xx/LQ^qh4b9Bo`!:T@tZ@Bl6sBa rHQBh@h#w\uP׼2 :6P,*BjS aL&iwP_uzR(=c46aBTV9 J%$=ר}>n1 a{=D"mB?3}VXF9LQ\@/+|{` mBVRRrr#BQRRie["j 3n#@B/%%T>UߨP#.FT*-e45B;sNڴh誸 x0KNVة3%R*5B^NT>|lnj񹝙JmmmCa>`54:dj"!L CڔDA rU c  `ɇvfff~Bu";Rn h4b8nl0Q&B;M!$6d*^:33͍ĺQ Һ_QZ qO;K#]@0QB.T~qypvP?#%X#pؖ3&S!Կ:lnbڔH$ddǁ}i]ȭ}D=hlT(z}eH$lYT*Lt:m!Msj=Dck+ u ôu׹s־ 0q Bo@veII^ti>"P?Vik2ǒE. L 8rTQG8;z'2.,|#Q0wt!t(ZM f=,';`0pO:&ᅅ-$X6}D=q>6_dϰcb##JVs4a C ,wl}D=h<8_K-K{h4)U wt!t(mz4.&BX.WvzGJS厀9H$Tj\WATBn!^NPga#a1=}FT &ScZZ^~q!zOjj&EQyfff;Wu_Uh4)zRB1IIR$nB2h2{>-զT0LJJJDbںR*DB(iaS.P(" PU\Tq&'K$6E 4M+JB "nfffzyOpt^ M\&aݦpH))tlp\)vS(Jqypb1$zDg~Ƶ׿w_3O_Z5wP~OsSL??4ʪ? V04ovA߬YSYU][[ܹ׍g9zyZ`4(?/o:TӽwugΜ!rGH^o[AIK^4Z<@Pa%QtTBRб~dXr_ `0t:8tz>\.g(jo?T8l؅(67P4jD"v `P?Yn*Pn2S;wt8cF{ aC6#Gnݺ#Ν'@RkVB>-tm ^KOIɴ -*N,|>!YM EAluJOBv](fg{UW(rO)jms-z~ܸAy'M|w;vT&B^oӧM6lԩShwZ Blbb2d2+ x=F;薐M`csTz |N]&SDbgjZ-BZd2a7%2x1 p:-mNy'Bsr9}H<0.NMM =P(("lظ?́MFZ$>N ,Wbx;{3bn>jԨSNzĉ?~/_KPz)xmcBJN:ᅅ_K4hRkk+шe(e!tP*5E[&x*&\[},ˍR;o0gvO,䦆65;~P(\.nw!ERٻ=? IDATx+"H*}>b5?y7T(n{yWWYzp.Ώ"$ԟ1 c\\JQL֓}!T`Atgz~CbiddIAJ!e+䲒ojY fLX8ee|W_74Fc,wlK86Ll:.[62D"<Ɩ?n3ut.n8VU&S[Bנd>~Rզ.-ç3Lj%sS4r/8NUQ^QG765;GWc̸h4Z__i&C_%yrzhmD! 5e@.W "J]h9~`WOeONȖėnjqw CSk.K.k>6$+g.(2d4My1h6v;$>_B(I$Rn'tR᝞4#}g._|\z r3֡ں5= 6 ;[lj)w~И؂eSzEvMj E.dJ)q!PB\t~0Ͽ;^naǣQz6WŖ퇚9iE1{ώZ Q%Z؝ܑԪ%TUUV9N[Q \}( \v\-MB!zX, TRؖç\0ip]pEi|.u\%6= >򿧓_b(QpEQ!(fJ6 rZ54T/kGki&- l-EXeO#!Q>8n: E"qB 9 C 552'PWxۣ@ F)iᴸ°"0dqӑHJ@J ˍD;!P h!DN?F(%"VAQ/!} [ 1nLDoB$'_XQQNԯj5(JF{BaǓ]BQMQ4ER >_t+yv^C HhS8}isF*fqU^Q$)++Ksyy/<(777 o.V#T@KQHHB(!E"aPpTx@0}}98V;x r$\7\ۗT*Eq87͟r\FP(اEeee)|Rye GѰBB10 C.#9Y hXB(D`0 7.p#jUw^wjLT3TK$I}6?/!7l\~{| O=gaK^QUsaSL Sy^xiqeUݸN?}o&LxOh4)z 6l~P(<|˯vLxB=$%%G"a*>rr=J>1;fl~^jzX,2*;63wqr$ز"ے\$`d!B7%C' /@0lޛmIeuSʝt;μgΜ^TdׂȲ߱ 6oؐ qСcFzSwӊKJ|'{]8kVر+'O4fcǎǫvZe'Bt^񔗕7649i&5ed#JaJe~Xl%k֬ݷo?`M7n<|0 ՚ҝ-˲^oQos!|AJ[{S! G{1(ˈeYY+**of{lB0loKNŏ8ǟ(**:tW,yywsjjjf͚e4B~\xſ^4{#_@Q P;jljehll$+,>h@>&, VfeM H4-Mڠq뾓άLMfdBBCcZ2x͛ϙ5v 4Pb#h3Pmؼe-ssU*U]]](갵#Fdfflظ!bB߭^;ynhh\<碊ʪ}Ͼp5W_mZ>0 zmW|,KPHTr\ fә_o_HMM5|k A"O0,#G"~bJ655E*!YiB("BdI1m?t_ST4b1/_Biiy4N8 R;"?lݶ}ذBrwMMMQUU]YUՋO|jNF,(A"lkl8]UI4EQE!AEQee RQS'=0ft\vpEaϞ#G5j\qe'O.Ew-rڵkk-{PQxgѬ O/$|(JdlAL}]]}]]ǂy‹ I aXeDY jkk!PBh˽^,˸0˲< ,V#4"\c';iԨq啕'z~v 9e>F!O?W 2qQ'cOQ, ؼSx$>%#,Dk= !ai 3dȐ4Z f,#--ɓo@ Ge4*nSS]Sӷ ?bDyfol9١HowdZA&+.{3|xμ9k4h4hYL׮ èTjIjMm!jefdID][EIԨ5VRB!TU EFebXa(4=B?#PǙPPc9thС! >{~/%I$)zAn0λ+>}z@0X]U-uk+RS j]m!Ĝ L,*L$ niѪ^$It;}!Y7h4z5xw@0PqdXR)f˲,`aXfiiur\@( Jht/(2/;\Zv'9c/^DQܹkjU;M wEcTlO6DO!,d#*!C!M fdBH+>[{Ai7ܰG񪫮˯z'xm۶"_n@ ֤zr:iL_:!==v8M:шo8%5X|fmC B!QT*(Z,<ǵ1KNVd?3˕UT8i!9߹n ´Iէe!DӴhhpI $t:aV~͖-[)q 7GHZXVzNg :afZ\`@ s\ B=pڦ.at"&(S4M~##vN0 Bpx M$7Kz.|XfQE )IREQOQ˲zے0biӊB|b --|bC|٧^[oݣ]}7`./vgY>/{aÆ.䒭۶9.!7믿FTW~WBn55ii)O='Ӆ0wxͷAA&́s\_/ǚ# seeeWe0 h! Ͳ$ޏa h#Nah<_M/`LVɪ)_!nwz]~'N=d5O{}s؉k4/]vGzlޢE ~+XyCÉ(J=$EQO=Λuu'OTTT<|Jɓg $́sԎ#G{CJ 8Ns'zQkVSet:$I~_VԄKx<C,++eGi@rkZ4}nwm^SSӉҋ/SSSq&N5r.t58+,_㍣Geւ/xB ӻo F3Fh4@8].jK{7?bI;|xwQ^lر x?1jH!QQ4fsŒb2Yh26[x/Ɯ$Iܿi=zba,s3g*MuܷheRRRg]]=g+[(O=iӊv !,*k;{[oq8 {>㫯ǖ-_΀%e]\>F1Tij*t0L; #Fv3!EuB`65^Z>`tuuua(I jŽn9]t-xߺm{CC(|ϯ{:4fICƎ{长rرcnʪ wݗQFN:?ؼys.c]$ h5-fsٜҲV=}f۶ ôo߾cskjjVSOO駟B'3<=$K$mdggi'&G1G68*MEnœht'0S\.Ǟ=C^(3gݱfGnZ^TJjZlzcƌIMMݳgϜ9sDQl!NwAۍ]A~OӴjB! `F#*]ycƬfe8j %E',n;(SOh2dDfP9B一 |~> s}Ǖ`˱^lC 8Ro>]̱94?^&J%IR?bq\m|4xk}ȝ,˪*u]eM&liU[bɈJZ4jl/F$cT(stA2ai=rd>EG1j!m#W:n"T*PMM q#Fp\eǎzeYjjjd2@@e;1L}EÑrB!))LTJx<.v|>Oxۃ\3 ˲lxaXTVjjfРL%%^n[֝B!7̟߭ 7\a~nK6rr-\xhke"avV7\,ޫO$I(.st!Ql0mEgg9rR1\ IDATz]t:=gf=pV~?0E Te].WMM .iRRjuFFB`Y6 4@RFbI3Sp(Imvr!T(TjFT+JBV ˪J˪Xi6RÒw!#?= Da`\"VVV2~E}$iNkݺ eee$wBlҎ:_MQTż| љF;xQpd[mmUB{|> $IRT B!e%Iy8+EQ È(^X8 ġSh6-Khi$BSS񸺸y*V֨պJT)05B($ BHIjN{-!I 编%Ie9%&+ iW}4ue6ooIɁ}Na@$|nG\;Hٲkի,[,fvQ郱 qUTzMyEWV*BVU(X&"By8, CȲv@0d5S  ⛚&?>JZ7FkDZfE/G yz Nf P( q ~{y璦&ۚ5?4;$|lO;>!r,+;.eKjJʠLEdJjȐ၀*VC P$vϧEQt:84(˲(JVxDQ i@ dJ1Zg! .s&ޠFY@dz<.:q\  |]" Ao?r|mrJ2^> FvGvݼ"xBj^oMzdtFp($V9STqh:q`"J(Jx4!OXVLx,Bǫux0Q8ZR&\hިzVkjJwA^7^,:,,Iӽڛ8h׵~'ۊǶ w(ƒ;40e,˲BPTFRiU*J;\|h|>wTSR2N76] E(>8g 0|DćPHTlZHrB/htFh(*|=G?3Jc4ZL&h a;>sCQ1{v啿<tM gvrbR$X n)6M@%I$^Py^C$̡(!$b#(6fbH6kM&k~P;ztO/;L` V `UWT5K_ BVo2YF ^z,˲t+ )6LFhL1M,B^vz.i aɒ{O2cHJ_>YjwT)r FP-?y !DQ!kEPa*Bhhp O% t8  yP8!q0W?EQzlN1-EC$IrNuYaX9dJ1Z>ojunu[18$5D;vAd#tȍ7.6mN[>I'((ijGTF4Ͳ"efhN kĴ̴,,֠I!$< Ch1-K^or8[O]k`0ͩKNghF^r^㺛h`;8DԂ䔏[F⌣dee]r~tb`ŊV;%,˽~{Ȟ8qBۼ^*XVP( BR(,R(,Pj>N h 8bE'%efsɔ#?@x>tڝΦo)jbI5RF3M3 ^@_ 3rւ:MixVS>d'jp:]A0S\SBVt3^K ^j &7F$>Ѩ 'И>w60 ?ua`p^ut a RR*UJFR+JRPFfJ[D͚21+$"˨Tj%lNjW>l c~i)bI5 r\岻\6+ĂbAElr<+I(>[u3mZm\[[g4?]v?cxh4,_&رc#RVVK/7!Czw}|xcgmݺmݺ VE@ /u4cFƐ)*@PT 8RQ4e(/@ '0@-KaR4J>lCX,4ъEQd䜘="VúHǘc=Q[[`/`a[ho _V[[;~{~[xiJG{7x}]] / p]z鼕+W/ݬAcN2-*)qLET +UB)UfYVk4F eQ̓<Lbf! P*&Sd1, nnot:c丢T,4%U7" nor~9xk09J`;B$|n5kGl\P0ᢋf zJrӧkjkk6:عs7ޘ8qB]]HKK5>jw:eh6t(,ɓGˏ=!sO+RRiT*ZRP pP(q`0qktfi$0@ah)&Uį0lZhZ5S,4^Nј+`C{x@I!$I%%KnLE˴W,'՟ q63+mDl8://;-KgpXL&ٜ7b$;63Zٜj6(Jv@gҲaò333Ϝ0 p8?E 28##nܸ|F-|HŔ&۔)#ψ<3⨊ZCx9jzuPJJƠA4 <GUUٙ3 gAJUjg(jFg6hL4bѥ$ƅy{7VA;Ͷѵ,8&^Jm0 hh-u;6u.^o4SF *@suisωu0}Y" P\>v?~{tO?|us=hhojj}( ˯Μ9SSsWZ]] ϟ{gDxO?ym6{jϾܴiKvyE:Bp8j4:h0fɔ2\.{mmU]]u]Ax\= bJFVkJd!$In؁<%YDm;1yV޾^(YyWmߕfh fѢP(𗁐ypJEQ N[25T%$Qgǎ];wZ~X,.+r-<&?p߆  r{x5.q /R) u|u˖=P(8S*g !dedYJh*V֨VOQtI箫dZ,04MTZFVb0XxIx7 ^ q< gRXT4uϞ}v Ǝ'ۿW5تCbgR70bv8ةzCӌV z`0tưN(ny:fjl1v7\vsN={Auu5gP/H!! IB6 l6[GaI~L -NErB›o6Ͽ}ΞHQEA(-AKNB x<'dm] I==B[ayRz`A_qB!B\3ePP"w+Y wy9,WW׼;~*o96qT A/{#sϝv=%%7.--OEZ^5RjNnޜ vv;8.&#aYh1,!8q@ VII!;2ɴ#H~+𫪪~罶*][[_X89F$!!$I,#I!$!Ahhq@2P˺=PTZ,qsRiڄ8B("`/ĉmáq?ܡ5ط;kȤshv=$tfSSQqR(,-/9RT*-2_-@@~ ! f3%D $y.v$s$|Gba[˧vGLxuMI !~B$!H ݉l^0,ð4MS(a?2 MQ M0 !1!( \B bPxggg߿ nw0 P(ZЄ?P;vAKzGؙċ?Zj/H4EQE4P({M f8mBPgDe`[bB@H f%lNiB(iê H>a e Kܤ^{('.ӳqe KK,K-2j=tup8M&В$CM&nz:|G] ~O(9Bp?mI2M3&bd2YEn=WkBH*-m''Οq $Eǔٳ}>+x4@Ch طkXЌ_]uv|e$][[?u]NBU&{`ή]|-~{K/X,oȒ6Zs^ f /q8lG"EA-YI!@'qݿo{}{y =ɘZx?R jWS*} --W^+++vǪU/Z-[͝{Eѹ#o߹z}7>~aXt&Q=es8l>;VIrSQi')3KhC"}b1vK>p8Ww?ouZWaε)ia4Ng4-FIֵfs\vd$I. DAԋ KX1bS*`׮=KޯZ+*LNhh:^3tz֠TZ"Yng85 M tS>esLx $"X!mbtdYT,+I1ttJO$H0M3jV3FΠT*5 Psm^sNC d" c&u@$M$D3RZZ~w^~& #fذR]ܻ;;UaUt:j͛gs/B`;@]̝;_ظqu :(Y* Äs^+*FhJZU(4ס',K`syT8u0) {D$|LXw!Hd%$IxLfIeڮ]{W^lك+.O5",3MEQ&Zy-IB( g8y>5"$IN B2<򱺺s $ZTu7m6l${Q& iSL2GZ2q,\ɒ$J,I(DQBC8 ,uH zOGЉL*]@#ПtGڦw}s$|- 2V $v$%$|D;ېVt3 9ې@ P>eK˧^=dwt!^'$D}dGl)7F)HTxiӦtK$O.3&kݾc[$cz8*ؑxddU&E -8_tG8 k&)ekפ3QC @ $9[J͟Q?@#Ў5Ie2yM ZeK 3reljZBlZ&@ l)ozȜV   m@dEC#@]k9:u(Z?T @ B5D>VNSۄN9X;I5'r:D#o0yzzΜ=v(I6-y @ BNА0*UUT.Q-lT*E ht޼ ǝ9s'O|5W(9ڵx'H Z!woc49y6rѬQã U썞nZBQ,mvHQl,뾂F()Ы~E!K © .,//O 6{y/$~f& D>+H IDATVl7yѢ-;JHe Mm-E&_,a'ߺuD^V\4 XSTcYEazѯn2xxm?^~x-K/7G)e:UQqbRAיL6dGЊ@ES$S!^{9uX.6(|2Bmb^zsBR (Tjmc IysF UgSTcP} QBhIӻ~Q@֠S )$3+G]t!!W^*.~Յ-z:Aw>YԬv8r/.gɁ3yC#@hEx|Ş!9YS/kN̯?<%3ͩvD^lwG#[?n?;wn8۷Y9)Z>jeJv2ACLӝ+HlIakԸ֕5,e|ϴY/ Ps=n۷=xig߻Ww|/= PB; ! E |uuuh'F '>_k7 R[k*+>k, `7_,Nϻjʕ<9/?-|WdI~kB2CQ!^heL,kЌG㲌2NAƲ,#Ek~aGiVfRu@2Boݿ_ۛ$R\zɼ#G.*X-噟3 "\Qhoz,kQ޽L9~ ]{ճ/}5kׅys/lܸ)6};&k@/#R:[g`r>ċQ7='mg׎a`Cizf TğS< ^?@VCvvV";JK&=~<\`nAҷ)E~DIW_4oUcsOPY'T>au^owߵ)!\8~aTѨjf|޿Pu]wͽxΏ6eYj}~~ƌ9x$=QBPCT]]GЊ޹\^eM\# =P:* /gMIͺBf*j^Zm~N^7--  KʚYfc yH~ juuu Ϝ[9b_~e >)S!BFӾD~D}1;;;vBBD"ߝhvĠAe z BrBkb>[cp>03#sƍ틙fnhlX4baxG8qb]}(?zQ>Ө&V1;;{̘ >VỌ iX6Q6hmB {3s񫯼2'gةS=8:wBr6n4w͘Q0q}xA\}5@|L)F>buS"‹AFK$!z==&';7= kL ĖsƐd̜yG8l9ro,@{~붭@h'Ѿ01==֎TuMR֮IOg@ (k֭5r䤂W^Tvݏ@> /AYgOqLŚs˄%N/ }ScFep<^SUUoUUUUVU|/cؠ'3Odd6"Sssf+ۇw2 =uT{2NDΛ1g^=v}illlllĔ(>N؃cB9xoG@ $6mr\W,Z4q„[>yk@Ɂ֮; @ tT#`_>N]payy;W}t-0gذٳ/\_|%%3@ ,u ^>^zɼY82M!,ЩS /d2߰!~(TWWrs-x%#E_uua Ge^{Nd55w._r8? @H"$IDb0-\Q\TGߣ-54(|at/Hmٯ/ꪲҲ@0o @?XA!'+++;r(B]:Øa •fy_XZ/JDzUݻosze* {h9|.ܵ+]#+Hxu䔏 {cKCx|# ,nظŋY*^R>@}}=@H*vQۆ'doEr ǝ>]?ߣwy&Bb_os! P{2BFI>dP-IOOEGf'?_g(Ziަ7ۯp[[QjoM?rzޅW<:Ò'NеW_=Zv]{7bƍbӧXG@ $r#(4M2B+^We7z"+5BXYZ?xxRŜDQ=wu?nwmjb}?@ t7.%yɜȒ {Քt[/Z4yMcf>s=?x99$;c~ЯՏq4_ĉƝ8pܳϜ;wٳ#r#SJ~6ݚ/3|i C|o2]HDw=7lȹ6%4"\QÉ8 Lj]*:]c'Ny^zOD=u"+˪v'1ƈL&F *H& UR@4&4!je 2AtxJ'2+-mN),*ӧcs^\*.ot i߾ݴZ-&A@MOJJ*.)q:Oyt߰EMkA}tr}x]LB)0p"ӛݾџ.bbSrKBqm̹T_^:ZqJ<&^מ?;!76njgV߆#:j熋 6s|ADǍ|q+0sјx]ue` &qWڥ71ʘ`e~y#4mSj/c/;RS/~衸YYٗcMovmIJ:yu&GDDQu=A{5cמ݉]2ȿ###w:p~M ,ڵGhƤ1trԻs.X̵1H`"1FLp"0FL`1t9dnur ԵT 鈢+2Q_毘`RDDjKQLR`hCt Ֆ~5u7~^gyK.{e?{Z {1"Qq;^Gj#H`tT=F*nR#ո<#7'v層.H`t%5UzSLB\.n܍ 2OJ\㷇W'Rm)U +vx>/О9m9q(nw/OLxmwwT8]?Nsͪ%%8x0#3GӢ(~盷lֵ"#}gUnݒϜy6J ="TVXYV[y52,8D]^ZyUMhkAZZ#i9$Bb|| .2 bK6x:qС=ޣ\.'#G.$rfk0Dg2VKwU^Me09˞-- =j΄O@cKWX;unٺu]=VsΫ q# @sU!:!fuvg{ VWXB;NΟ|NP]4X:uj㎒?Q>|ԲZQ>@s-/-%.+ui->ڟy -[_[phh e]Q9,:7%: E+֨pjGh>Kt ~R% TY*k[#Njp<|cQZڳK5_B*+{ǫ^ޠv!Jͩ2RUϦ3sQozx ^mԄkmV!pҖfvs&~uX姘)ciM>?fcO]uOOO {ΚuY]q.r&;Rx\.완z˷q! [ZJF4_(MDڇ'0sts,BOh݋Ӎ#|LقmXHx`Zd#~dHІTj-UV&tEi/B ,ح)fO2"߱K15!jQ[c>JGWVrfc_.}pg )rs˵~2y֗ņ\! Ҫ fwg^;ibxb:Hc+%i},S4 X[!EN@QԮ/6ZCɉ>c-52 +)mG~L;-_~v||򐂬U;'F7ϙyۺ<1ehxO}bmҪgIA.;98W>W7u SfM]vMq.xPF u> _)Cm( {imaq؃}=3߷ WU1ʘ`e! +VB kEy6tx>rN F9O;Wxp_K%+h֮M'L5DD&USm -+۷#kX8p֯YKjh/ξVE{Ôc/x|Wf{g-ۨn{YH {1sJID}*xlΔ҈[R q9ŻS^.-ؿ3M}t Vx5KxNޝuT0R>o촒~|O7>QDo`bF}r9qƈ7^X핹yaQGIWu(:j|lGEyvSJsM]}s=I>6Ѧ5 JC&Nq{OLںDRUG;J?ETlh^ؾCs?"g.GSzW{ex Q2, ?2&XMMѯ󒷾#"u=oۿ3EJDiE{2z{{"=7>"Rɻ۹vq<;!L m2 s޳|q"I+i; 0RnG2#Š%6"J>×fuH_G`MdNҌNZ%Vyl-iQQI >w9"`$gmxdҝ{ t<:%Fy=Yꯋ ,v؝$H&B#D$ a*0b$z'"MpYD0Nq|{8m[[/3hDoK`z@Ǻ\.Sc\Oߟ>"GU1JK)X1hʄ4Axwן]76]>N_XSWX} <#E 2w8y6*6'0ݚC ;Y募_}BafzlҐleT7~u/=}s㔌X{X޶_N*/E/|muц)QLX{pVw^Z{@Zb^)*Y6ƙKaBTD]n][y%.{@46661Q^;OZfVef#}uhK~yS/}]LȌgfm^}ͥl_wOCZ1j)TrS%l=z*cuNx-c~@Tcuo}Sc&uCX.nsxfIOmha1n?/c&5sJA&\4&:^W]Yc4CÃ?>_i?m,#?!LA4*J|1;Mw "4mqhB*y2~*?WFUlk=͡SiFwɄ4U5ogi1S3ue^i)oZh.Q49ψӉi!oC}wo>ٵW{H$r>f>]S/<5l( 6 &9 EгϞ#:j6z 8c >2ͷ ;OHl9toOu E>u_Ct\>XkbmXc֘}Sa0CuP=o+F$5ED=ufEm#?^ntrHx`t_Bמ犌z3s>"Zdb s%|/'⊶ͤ^WEHmx34,nŬ󌈈 l:hYs-c\%'7 u.Pykcp}\ R@ȉ{gD\Pw߃J(B! tcD[|6_,V9H"Mt*3~p|odnS9J-R(u;3n\K71=%?huAezCTՖM1 r [w#F3G2yy{O5pՉ%co[R,kgh|nYV\JgIq;tw[7WѯB)T!IMGn:9*ի߾yH\/0ϾPdTZm"h/ղ#\>Yf\Sg"mHd[gWekG|l\;^k4#Q:7Zk@x-f$DT&\.RAźJ<$G`G[kjv/hQ(͈ QyBJSseJ3sQozx ^mԄkmV!pҖfyf̙Yօbb⧌%s6?u!<==ûg+$};kBg},;wnǹșH=rlβgwT/G_g^ NZjQܳ]$}x ?0WXH0ϲ.+ֽx?m^_?@5g|ot1Xi#_4/%O 6ZL`7"&^r,DXYn[R.=ϟeEc1bbjBv^wF:(**i<wB)9w\-ӛn} `vxf~y?_і!=&X)rʯ+bD$ o$"'u(KjUJx}gkRe w:jS=|/[je WRP)tŻێױ:v[uybr9&^7'-;]{E?꽣' Z'hu+Uϓ\ ?w"?s6q|Lo0̛3\N䡌7fK?}$KH SP\ \zfoۙY!F!r^hrXQRc~eHDSG:גJ>k*S ɳFT;jH#N3?#k4ZUaA0;7_eYk{`Y6~imօb"dޭwnsiv#"Jrǫ;6ۿ3e#7}~4"CDΟxԢe~a==LkjlS]"ȄU;^wg9L[5>;+߾ L; qҨ\.q==' 2>'>i{skcuo^1iGZ"ڴPAViph#sVc?]<2i뺣IU*Qyc.K΍Gd.R͵=u)wDܴH';w3"Qxxb!0T[Hm) V 9.k=H/0&0clfo@1*/0$ڱK=/b?T^}xy5we%&뎎x>&X֬b0myƈyFUjgOlK J\`yt`DĨ}}J a\NQjegTSe˾X篼<"B~A.%ϝE x8\)}+NZRIISw[z?^Y6G.06^'55j#F Jw%uoñk&E"թ'sROdlvQzJ gܱo?/Oo\cF*k_rt K!1TY;0Ͼ^#B6`X'sFTUJ5L;Hf@dV`po%ѭwtB\@Wg^󈮹U\ʳ}[[/3hDoK`z@Ǻ\.Sc\Oߟ>"GQ{{xCdR VxM{ zϮ./P)dr+~,ܾFܑ"|Tn͡_Nr؝,ϯHvZB!0HGIF=6iwJ{_ϓֽxySJ5 [+۶I%.0%<*X kJ=KkOHKt+YZ]9}8s~F.%1#wR+JBjA4*Jv rڝ qAae[4!JLonrnJ+_Ѫm6~P)j UdBuʚZ24kt/b 蚩OKy?b%"alm Cꉿ}]lZd'\VĈEn,ۙ]D#Ӻ{W$ubMUV6A&]Q[t)A>lAJ&ε^Wm뺵LqUg.-׆eᏤӹXTpYZf1.6E,,PAe|zL>઀ .˕>&$h7u&ֆ'1_ZxM4CM[>rJ'ddE&+k{h=p.|߫ ^EjG\/z~?J \IENDB`RaySession-0.12.2/manual/fr/images/patchbay_start.png000066400000000000000000001077031417052567600225670ustar00rootroot00000000000000PNG  IHDRHD pHYs+ IDATxwxEwVjuݖرwBI$$|G -;!GK!WHN/{lue?Nb;X? fvFvB!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B ѮB[v-ѮBwѮBut+nN:*t}vB]B!:"!؇ !Pg-!B蚀/B(p8pZU*qr[Q!-(\Rtqkc!vu@EM\\Era^a+V6gV7or0҂-X0vX0s%&$,\0'R:B/B( $-Ӧffe@qQ/kHw|JBn{zÎ;90`?niB- 0 rH4|0a!'LBB)2t6.SO=j|Xl2B`joat?e{7>>t:|˚5fpfrKnnO>Oiiǟ?h r?0g@ Øѣ;G.3 wrQxlٳ~[ghy>04?~xރϛW^^q̙5BVmvFɒgIJJRWc=pO>oM6+zxNSO>hvf?v{Ą޽ztv e; =ۧ7yՑ#GV\p|Iyylڼ20o@8!P_PWk[V^oRiY|&Nӻc9p8+Wz^ݲel!Cbqs4/v]!:l-@ 2麉6euו>R0aoT2CNgffLF?n]@>}rGe&K9u#fΘg5cG{:|IPpX;~ !Z/B]wȟqӦ& 7wlqQqmf;끹sx5pWӧw\\\YY٧}&4p ?7q 66Yʦ[YSvӧ?Y@ |MS&Ov\, vE7Biͷ>{ɗTJu;.\0tKeeeƈD[h4b824I(JRi]4B.(l<㩔Jep,Bu":TeU7˖ y-B!EE@0|P?C\ }7E%C?v8juL6h^w:wr:_} yܳ9ٗ(: 2 T"$a p8uuzXg釀B(L"#F⒒OCrƌeW40o gΜQ*y< lF~Ͽk#1FMx/˯Z!t\.}>-))`-SngZ\yϜ)++OOOk~9K>|h~~0|N|ϝ}믾¾uA!^'B=MsWo9ٓ'4f, 'D" %^|>_&9ƍ0b3' a,r fsݡr(r5!-v5cF?Y^_ߊy:``4^y}p%pfj0Eu%?._OˍF#!B(R"=VBEvB!Bhh4ѮBWQQ*t "B(j4MNW[KEvK}Á/B=%ЫzEWlhW!hrs&"K_P;[88,#'jTI7C8/B5f_>Kst? Fa_P;k|m_Q¼4Sډu/a>lE!BlE5">_x<>r<s<"p!BPk`CPIJL!H~|pDjW 6F_p8D"Hdb\$b|@ $0:!8 2L `&0@ KTF?>zK64?1={JRL Vٳgwu`) | 1 Z&SJrX&0L(c<ltnvyny^3vD,^( Oy0]!}R*{|m~NMm֍7ޘl ٳg)JJJRSL߿M~@ .uF]](#)rR+| :Z_o-Nq:DHnuiOpŽ<ԛo#+"m"B}=[y<ޮݻwQT\R__O(J"gdO?~wu@ ⫯Z/BYL4..)66Qp(lu*`viB[i!NLzeAXjzBaZCA->\.z}NC^^. @unon6/ræMF)h,+/?yԹsޛMX,+^ڢ(*!>>U CzXk6,h]4{=i)/غuysv;EQ˖}z,`HLL[n~f歩) +Wn݆M?L0\Mݎ!Ԏ.o|3+뺉%O}>{0 +VJ$fͺ?QRZ:. _ TDMll2Ms*F/ ⋯sss>^rB?_/;pRx睷=6x+<#&N|jٳ\,m֬c_Y /JIi=>:p#z'N&&$?n?=4O 9R%=b |#aQo %ҷ"ط(ꌌ<Ԕj~& Ä d.{\gѢǦN)!!5'/}~ϻ\pr^`  \.d27a!9;D"ammÇ h4Ç5G~.py޹>ߖm[499?^]RZVQQܹÆo ]4.xlA9ٟ~qzǟ̺uAsssΜ9Qo0FU"mNmmH=9o[BTD@,}ii٬v0 k[߃A& 2LpݺM[/~}pٿLgvmwsVXն~z<phNFrm6m2}N7OS\\i&v!Cn4X~`N7`)(l6.7'S@4M>{}~((8yDڻWvrzLMIU#{Q$0Lg.!qq)=E"1Bx|>_y<<p\B("bB(X 63 {))ɯܑ#ϯ: Ø&8 if@wLϬwo//!ѩrW)hls=Сiii3gL=j~رcUUUƍe lݶz'L處ջwcP_K\0u`@]^P@?و`z"v64L>_0NWY^~鬿rViD"DbH,?B8&hqc)&`gaa*% f|0 TWUTy@a,i̋ݳ2ry~}2J .wљ!{/uuzCEA@s%W8.0(7J+%F,;g;d|2v"E"mټyyysffso+y3fرNX\.?*V*H%Р@iN}0mNE N>}R%SUURQQd<_.W)q Z&Sq81avn:vv;e\߾nO~}{"6^,jjj"{ThNl0M/%PK:;v]ާPi6-1<`PT{cBP*NaY|\.WPv{y쫫V^a䏗~OQp`PgӳSd-)9rumaT%Չ118vh-6s]ūV)/LHgΞ-lq~R:rOQlcA㵽`6\4~~nJ@!T7~Uk5jZt|cF~hރ☘Ͽq`Τ1>Jko[ޒ $PDQTRRZjjq8%%g,6 ɱI (!@`X &j5^յ|/>(!nӧOei#*N6GN  -^==St.ё~QEş}yV{*(HLL|Ӎ)))@jÆZ弨Q22r|/+;U D$'$hR$9nuz}bWPԅ.l(O׭۸dkn)%S<EhxR>~R2-w="tZNm]Pgo+:4}E.Sp(N޽||K邏v33(*һIIb ^_U :޵2B~͟tb{䑅_k IDAT!Zf.<BéٸʚȚ{Z |[-߭cݤE 7ǟ# MOcOweWHIɌM`:]^_ݵZCOFTaԋPg t<@Z{_KlY>(gQ ;;`Nƨ7bmziVU嵵s+--U.ژ@ ѣT*%%gjkb<_JJJ`[JuNvqߎ<^#lo,o[vi 'LG 'hr\ 6^0L_H 8Ż"0 bv <C! "&\)$ Eq~_UUIuuq cDVydUפ9"T8J*o7Z|?t$Ά_tu"32rE"q /)9o2F=&FL**Ԕw›:-Ѯ}NPو`V_@|~aCs8dp8 dB˜vG#mMLLڊ$H$l:NGyyamm5tk\z?KUoG ?ff[o>vYBih}b ;pGQSO<^\\0pazz)/?o+{jh!wd" C,jnbB,=7~P]Ej41髱ߝ?wNQT[QQ;[YL$+\P^^%-:̚_VG .`AF?aM  ~$vc0&7W* v !EA)M [,a!֯pBYx1.Ow{P_6#r\aIJ>.wu%ݵFe62MszTqLUUIMM.;B㶡C(%K*,,n5{S]/W -{)JB V:uuz=Àl*/(+/o΋?\aa5&ddDWVT :==KK 6jR08px͋/ !='V`Vv݆0~+**޶}{wi:ٯ*)I@L;ii E<œ!M3š-Wݗ:u}) |;  x<aP]ԩҌ^BZÚA"gdp<^Vvn.!ԍ5Ʌu`>Mc_ |,=zdp$H>ɤ111Ǝ0t:7n\ZZDFQ&3>>(E%%%2 heZm.G! ߎC#gΜqÇ7~t*+å:; /z]EEm64r?/Bu94ry<s<.G<C4åiái(á9!NBQixB(,krVtB(RR+Z~U*P(l.FP#ʢp%'ƦPZmy8Bsi@ DP  EBx<.r !\_s 0@  2  ЏD{!8nI7ǻ0mV߳>WXXV^:0-֥u4MKJHH VLM|@[YY\_̾!u4MDH,bH#j:N|>|^y^@~ @88fτ$waÆ  =dߝX,:rhY[QQeXZQܘ1wݵ.| |#vW9_g^s/!,r9KKϚLNo(b1VU!B(rD.ɅBqL/p>8ntx<.s:B(e?.[[!>>;Q{3WXպwGD$g ÁodZd񵬫 :3P(ee窫\`奥Hdb kf_4͕RB,K$Ҙ! nj5;v;>Z[i\borvݞF6J%4MցdqFOHCӴe4Pf[iE |%^DPnBdQm[ ψZ0[].l/]e-*d2LJB.0L鬷mVR_ouDݺq~fǎ**11qժod_e R2tɒŋ߹s]{`Ȑ7<_%naw&***} \cǎSkf-9ӃGK; T* :s.z*XEE'{y9:--KP꒺YkS].o%rR'cblB͵Vf3NXz[49sn˖mRwq/ooci&Oa[.lÆM3f70iӦ-lJ?/RKύ9|4hС _ &fXFH]ɾ}f={g,i RD X,V8zMLL|o6   77g߿={=\/?y֍7GVVvc |բ6,Aש^B&K$BzmYYj4Y E@Pj+s5tɉjoGMT*|>X,I__o'#2"e>KN$IsKt:]^ހ[o l޼z}3OHۜO}or. _tUt`p4|aUee/-TƧph,L"XNPe2EQ՘Lz~ίuQ%uvDt2MVM&VQF2nݺFQ_a0 6t߾ClܸɼǎW^vٮo߬Y3}v%o| Wz]GNT`V.56t{*DHd4 եnwdx<~zz\ O7]j+kT~}jsĮI pJ4LOhK(J.W*U@аa7k fgoJ"x<)wzQ޽sGb* I4NxZ](f;uBjp_)&&jϞ4M_ȑ#zeUU5*^3 ~__} {\VjӿIi}#S471Q.uVV{WJrM&E6LA3~\.6n\bes{fe-\0-=-X0vX0s%&$,\0'R:rx<~llJ/+9aH FcT\΀{'/~n>TYYN> %O> |gy^TZ,K~d]r_zUrBforl6$nNUVZt.v csOٛ94v&'$$TAWUUl4ֶ<FpE&11ABZO|JBn{zÎ;90ƏiZP~ҸPBrDÇcr8a§JIۇN:Ӌbd2u#5jub||Ld&:NhZ͝|*x|hphi.C4phK4Eq.i؎0!B`GWi7y?#>aƋ2gdrTLƎfk|״t/F^i^7wؾf/;ZxXPGOV(bٙVPc4:%B/EP(D<xx|s8d ;\ mc OUBZNWYY9F?񫯾F <`6[nĵ߈]SQ/\Ԥ;m!Jbɒ :V,\llZgݢVVz!$!!5--á=wiY1܅Q/XP\TDUGeGR  Z-7֙.ɧsy޽r>_jjh_y}I^;d6}S8a<l޲%&F4zԨAMHHݫN+**ڹkQ&N!rٞ}?:r0 %voڼ{7 ]D"KR\.zz}e]]q33BD&%H$ |}14P]4\.r9nzl{;`B͛6ovU S80mVcrNݗp ?_Js7/b\U11v}yvtVk6׵PӣG/2ΰoCg8 )))5Ǐ=zlnZzfB[JMfy8!++OƎP{ ;:Xr%6}l&X\) jaLB\^\\R||@ "z}:]e]nFOZ|P"I$2T.bb/vN᰹\NgeBq?ۛѵc+oQo019Da XjCH( T*$)+%fl6Lz^)hf..>U_ok=ZɨW&7v/k=:#=|ѕ{-`bX@JJʤ&dI]WVVvHomR` ʤv:=d2!dqvz6ӧONvѣld)N9b3|~f:=vlQ{ϡC4 ": ) E,a`XWw`"ǗɔRR.WJ >_@ pf9vynm9sӨwpst7mD垢Ѯŵ(BQoӗB]i.cG^x EBsKi4lv^H f&$h!^kvԓOB>Yԩ.OR&Lhwa0JimÏwy#ML3p`9E[m3yv/_Oqqqeee~x/<6ld)6o?dOڵO&Jd`M7M]{ڳG!SeXR( #G4YoJ.n^[ϗH$FBqqr]`V[5Bőɔ ZJ͞T}>ѨZVf3w٩-9s|n!mz#oӎ]mT5`0 v@0 ^<=WG$J*U8uuUxJJʆc__ajr\^.m2`΅qqI|>ak @ W$ccxL nl0 jz .Ǯw6 ގ/SÆ  >{K;vEFMOϑTn)-=׺U-PkŐ\ m 0(11d\Ma^:9KEq ZV' Bᰅn3uo;<^ R(Z<og_n[lُ˖Nrybabї3 Ѯj=ztCѸn/JP%Dbx\zhԵ:HNPr5EQ tFhu> ajݢ7bjb-FKK3!DR:нTTBӴ E1 Rf3{Hͮ}xAcL& mVHHtC?f*7\V'Q0AA[Zzff4TZm _ȌMZjU,P{*UZG\bj9Bd2ZTĈ NgTg0l7AiVTD2^Z< |[7[?{55ZL8 ϲ?e2% z>6$''{gϞ޻RS_zYϾw.~bl[JJ{n/yDR[4UW |e2eBBj||2/`꒚ns+pO[[oVWv \ m۶ؑP*9ڗX,M jk >-R">>%..y<CTk4Ek9h22$PZqKxk]Be2гϾPSo{ I'Oa[. |555}䑇{lW_};w/ 8}̇V[}M7^%!Rw~b1Fv}hu샯-c\WYh4JJZEQw-`\&B)c d7[.TJZmlbJշONWXX\2{HII9{lm.)PPB^XvM|jj j~E!kbO-F},\Ϟ=+ب)HO8A*aBʪ8qL&aAZqqr{l|JRr|:]V[a4vkƵeطgffvNv0صkY~7\.w΃, $&&~oP~Ν=;=- ={fΘ~woܼ~T*^y䤤Ͽr~=Ν={%?בem-Ǎ6uʻߨ*URyXLC \IqqIg(?ٚlf7 :$TH *ݩx";Ά"'z6TAQ@i'(EZBO%=lH}gfyv g<W^y"##r+7˲! \qPp<!3EEKgovkJUXZnP/{}wl6o߹R”~}*rnii ^za;v:}F훑zVNLHX6nJ{7l$Jv-rԩ_xb@H1ժj󕉧dԬ N 7ʪ{Q$t:]bL(ee&S%6]q(>ЀM|O0rfgt萜TZZBP՚L0d XJ]ee={0-6pFGGs5{<^߯j++ =#w8deLImɢkm~b\T*cjJ+KYPYYf05A(7)+8`e^zϜ!8!#m6KL[ l޲%K׮)N}m8˯lj4NҲ=7t={x~s۶y'Nػw_>111/4?8A/Ш _wN{>Ҽ_)G &t b86lj? -b,7J=Œ%kkP|j jX> ^(+^رL7R z}ciII?ڶmҒҏ?~wZ7_-///,,{zcGg4VtO{쫥u,1bdn9BT%Ur*&F)+b1&fxCTi6-Vxw3V~mv@)hӽzjc=y˖ 9r|S;?/ ޷OX-ߕu8q :tEEeBڭ[ץ_/}ԛoi=\ZZʿ5j~ԩ5th4:BFj&$Hڊbp8FcX^)B%j;:xXMg6o|Fc6C,:Η_^Rl6WN)};lڴe׮=bl,Y+in~ J Eu竽ˁړ\3w3bvK$?^\\|iF bHt!K(T%0[\.GeejXfjomF <҉5jҲ S;vl\\\|>rEy} ++yqcիC):>|˄;5 wjyB /)0NKz*++++uǷU*$%z})z* #|M[h.) FkO#Jh }YUU:Gu:לݕuyŋ溓o}i֢֑#' !}N)uVkp:6f3&_R7 Y3g|1PFXwy8`@fV3!$kRٷO翴kDoV| /bΝkmf0L:[FbOOsKh!!`T7ɨD%t"ۭCɤo…-ZٷV|#@:a FZXXlي YN󲲊- (Ji 磁@wz.z=x\юbA$/??+IF ׮oJ3gh4~9>ӯoϟk9`Æ pmd17pK ڟVY[Ua.>>IBb4WV7ZmP( VkPju1B?0O.YG^2}78jpGj{饅-4LP j4q2N9\dr6QT  \,jI|)"/!Lg]Ϟ!|FRiքBxW/5lY!0CQQ@#ei4qR3˜z!0@(2P( B@ E"BH$bX$bH$jRzl6v:Nn96]4%z}RBj;< :zjkN%7Z$d++JұRBb-@ y].gz^v;nIJbc(Rd4JMpEp?a7.S/j5Ե_J)4,K)e)ܰ~/> |@2.##!Rjh@-^_j4p7!G|B!=zth4~+s>p=%!HccccjnbUUU:5B#OIiYiX7o;޷zq͞|\B&drv,_ yd\ *EJ _[!ҽ{+eYa,tZz !jbC-КJz}N!#H$ f0LV4J hWU5(\v=^1[y8?aL_C3fL/,,ھ}l6a~׿a4ߵ۷իۺu{vm֭eӦ-蘘ELJ.W(e Jp:6l6Y,&d7ȹsUm j- !T:z1(t SO?"C6dյ)=( cLEEɸՌK)~jZvZmVM?h3TYǹ'_iCӋK{~O?ω'$įX/=׍o7w|U|pŔҖ!4J"J "8t_zvaZ6ft+.^Qqb\ Xx,3/7nlFFz؛ݼȄ!-,ٗrfOδ)}nlIΟ/\v=w- {_I./m EB?nlNNΩS_,[R IDAT聎5k)~ܢ\[~'s˗\ֿ 9Z\R2f̘K,ǫT`@ 1bM6;_^>(?ڶ0"vBGK-^gvfG;@kiSa˲y{n{bTjA|B>K48e59BjztrK;˞x#R,t_v^bw2OGq%y,i:ήfR)JfJ$Rɷ߭,))7vgxt \.sy}Db#>wvw*%9`}[P]g? eeeأN}k+vಁ,U4SVP&f)W$ɹ=|_} :kZ $*:ެxkaE!P8y[Bn@O攥%{x0֝2LjJINwBa6&# Km=SBU}! !Bp)J.m{af͜y˨Q;vZfMM|BWe=B7݄r[82VTk^k34Ւ<OP 2ʝ:N:?c bH%gy_~?ˊoNve=|>A <BJ222!J*aVvaBHRbҮݻMVjwN}~NzzzyE`~`MnK^sMNNU[lFϭlX2f_B`:s씻JI鐟_PtN{sA2ӏ=]ppϔ))r4rYOl|z!1Q!٬:qrСuÏefrAdX1_d2QJCBf?jBZʷ+o/r[0Fh[ uKHBjmi:ɨ<7m@)J֭ۮs`0 eD zw$tܓ"Bjמ=fwܑ޻}r}˲˖}]:w:tHRb?:}Lۋj{e`:yTXZgnB[ ĉ1GOz_ޣP('tލ̬߭x<|~78_ `w/BVr߰aæMRS<#QJmv{iiY~A~___B!,fd䄻!8j[/B!&bz|#P(ѣ{bB\ZZZv !B06 R9~=R })3۶+D!FԬ06O<977wˊCOIaԨsO?++/0-ɜrKfT^y 4[3{\}<3+|MF!"4""&0*;&OZ [8(e8{`xm7.f߱ ׬]{wd8]p7! ?.V "#&qcsrrN: p|b?Y[~ۻOU/9|:ȑ3f/\bXV{<̕C]5[C!ZL0NoKPED & {tt2eRڙ9ŇaӦNue\?ERٳ+**0"j m W!M' ԣ{w]\\½yXIŽ?e[9|:+c)M\vv5+JTj6=W"JneIIɸc ?cƣ_^r;5[D!ZZ8iʝ3iRHKg7%$$Q SwxǚJl<2Kar<;;YJ6Ij[p8W_vcZ~7+**"B-tҜʂ&Ͼ_  nC?SyÄZw^80qm۝$S 6-F&u~\u9{)#5rmۃa[`= B {#a aaYJ)9cy` =}Z6)Kˊo*+. GuvPjd9'/_F|Zf@⟿}\4Yot#7*#cH6-..x6C3Q\-I; ˯yС~ԩCϞ=&N T"y/;J) iϕEABņ|jT;snoR^\KlZtC@.meG ^zKT>!@@ `bj6dqr;pС@}6RW+Fg߈oҲ BR߭:vvyU]؁k+wS`Zs^^QvXzuq?!+8l]wt}>N# s ʧn]gU1~5$Bɑs0ePNM5jKƗN%tDخ<}p㣺e$ur7%#'Fۨ}nFtwO~ Lu˼K3oѴuvh)Zoxuf/JN%.6b;I-̙S+%C~~A9R֣v3f̭ HO?zt•@bB=S __&B>.R8/D˥wG;jKXiFٗ[g?>Yr^sZsR>Ǘʪo]=y<FS>}qs'<>C:ht߸gEUQ,#)Ot»5:RZk-qTj9dIbsYRTZa/Oo-x6CeN6th~z8|cHjl2[,/Fc2(!!5k!DQjە B|R{s֨3FLH}uն=uXZzvo9zCY5O l{=Uf[`M+kkzg1l;uߌuԏ«}mݾ-S>Xfmq(UUU׌w([n#B<=ds\" !0 L !ȥzBBrJUuRRP"3* BH@^Tb dv*1CHwtưk~;&wL]t}5kWh¢m߹U5E! "7o\ WH ד! x\Y~t5_,9Qֽ.A|k2-RB!p.@!y wԤhPȌw@+ãZ,sWf z!:YjꑇG BA~)e<|$.A76~[N9b0  B ÄN=,qKM>W{  %b70[kr\^;Fw7ì".QsBrg?[?auާge%w،7.) <7Z~Ν5٦gϝ c޻wQ\\w߾ܼee˾y.;:$)1k֞>SHk.Yz}(\MB!zGj%=Jy|*Ti MZ+N{-wHZј&g!cǬqq0XGL/oo'ssnj=u}{B&NЭ{7ʲ3V|] Ba׀nQu7G{hըRe˛ ݓ<5:wkSnd\|r߰aæMRS<#QJmv{iiY~AxE!xU]65}^?9;MqߦIJlvNNvO'D!x&4g)܍.!B2pLn~~[("~!Bѱ(ELşBu+8UpPtڈ !jI݄V!oD{/8/B5~eͪm8Tw5BTnbxS/U+k)x|# ApO0"~\Kk-ۅe.{1Fei<{|\~_@(ٛٿ.=weg%RыXax/6ߜ)BmN*};(5 :'Yt?e)a'~tP(XCb$wzaզh$M}#+:a!Pp=!V}ό{Z]*Âǖ-KE~|b𸞻6ɂ9YM\\#hf& z)1 尹 C ²QB@M٩gG CXn^}ȥ:s9Kh4J\mh3aȳMmXR V}Jo])) j` F\6.tY|R7G(p7!P:a/!,z,-4zgЖޘ JN%.642Fd nomnB!.4Tyw !c{Θ;Ǘh9Ki%q(Em)46GwT!PDR:z8l|)Ӈ͜u+~/ɯT̘3aظ;7d8Ю#'o\VT[g8ܨӷ9{~;ٳʞ-'` DUh]/ߴ[]=u_bKvlɉLZI?a(ЁòRs@BcUhO9]qSt\ձ[ұ?r R-kB~o*QNdm--0Ow PQl*56sܔ7f]V/w>[ۗUza,&0l'WT;3 !?mƬ:`_k'טY/M*ɯ?c`,XBBvǽ$pa$gBJP0!6VXRpB#s#/sqgas sZ[N%.69dI2GY;^v㬕pC_ E#1s;};ܸ1wkSrGߝUV\|.0g+jܞ~!TL6>Q7O}#+&5k!Pc.F3 {͒0^g}_N.KK *@&ȕQ*;C0 =0\~zC3źDd/=o22rN3 yl_$FUSQSa8oN~ͭPFqm5~:ۥhS% -WFqyN.~[ B[]!r:Jl֗VZzB YrzjܗoqÐZZ=meb(f_Z\sT;sno^\zSglZyZLxp>-qGDL@ `bj6do/\?tsPjd~_ass7RW֏BE`Wyڈ V-~U !reO *G_>r;䵥},!}772W^aZ>ㅇ|_NחVK"P}r{nOܷW/SJmWRr/!L㙷-ȮE,[:2ISg .tZeяO(N.۩}۷|7ؤKT*nO%rߋgϕGfjx%j]̩x+[U@C;7&o;999-M|S;=#;/U=\ >ѳ7!fW)y,~hӏ:ynG$ZL}m#ø3kCZ>6W=ux; VDخ<}pڬ[e$ur7%#'Fۨ}nFvwO~ v6yӗ0fޢim;f`Sۗ߀KSzW[B(JJBKhaj,VWC)^,mKDXֺ`4Z,k4jjs_zH"Zf[9@&(mf᩻yƦގge.KSFLo*RT=˾!rwνo eXJud_oK<;d u^~)Ҥ/?PV}}zxɣ)6틍S̘;IA?=3&.b/e)1L!}|򇔥ޭQZoE!FO⺲iu;+` V#ycn v1zFu1jsj㯪ኲXf֖To^Nͻn(,7g=cĄ+o:pw\z=;ԷuJlnMmsOVؿt|[\]k=]ӓ<}c۩G!"CG{ύmI=n ؎UgFEIDAT .Z5+`"r+s^K&x$saNq%! \xI)#` n_B 4t@Y0H$"lDP$pjY'B!>ɒm@sS/ ؎U{9MeEor.!@.r3LH,0˾-'.l R_veh sNuKPT7^Qbr\&]jPȰ]C @CO?p #B'99{Q Zylª1uuae70|+_MѯH,ԗTyB jn8S ѾM0ȤKT*}vXݥF{i٭yɝ/6fy!B,3"T:pF#צtk1گVʆV~K.]eU UtI ;wBEʬ}=^J652K\Co}4wu8Wy8!P+ xߞs+o |M{)s,~٦p7!jJ23}FP6mV|M.M wZN;uC!e 7[uRVB)**Hulں{g<6AenF!t}ξaMED>!̍Л"HA!AVƊ Wt`*st晍!B ) < MMJؐ<-0{ia /&N᰹mfgp+!@)YWVެvHy\!$.Iv,&{hy7B!nTh$N,=:l~/.so}ר.-0*ceN?,B=sX\"_kbo?}+k"fٿtR޷R#9ۡsœES|O _<ڽ,FrGV-B!DNm!Z^>v{RZkgƈGǽgv.QacϖE?>1x\]j.R#YC9'KAF;L@FRZc67aH!!CX;J(htru:;l{h!aͫTR#}.ecPFQjEeȳMmXR V}Jo]M((2, my`B!ZVa 9TbBBl^|a)Q,|\_f6ы;]>M/?A~;|6Qs[EIuRدx`ǙҦ?B-jS~g؞U_\tOxHʗ) f~1O6:~[{/vۣs?3~ʣ#[vj|ۛj2rEԩ#YR撿W-mRia+C?%g۽JiB2Z9\6xr fN?Woohwol?8B&ך/ciZ|YWXl. RǗS-|֟Y;j8(zqk./ڽ9FW(P XV@=1>5UڴV?yhϹ-k/ontwg_ϕg0;7S6%^})KK6?y͡=[Nwoޛ ]%L ~x|{@N>c$w;:V$~C;/yw_FohZ!i3'}C1wˏ/!BOZs7J)^ٮ2}Iڭ.XJUľ9sCCΎǃ pyGs[RQRrlQsnO߲pyٜu`ǙS5F?=.[@(QD%6ڡ6=u_d){l-3UW `tʿ nua N?{.]!B„׋AJ->v*Q2GY;! ]^2!!D#% qXU^|koHC(6o^)= 76: ! ǃޔqs?S|7iwu0Ck$5ƲgX\o !$d.>$*!@~+ Lhcis3PHėTY)5peƬO~[k\`!B|1ah\Zheb8spm#nu\a\"WFY 0DBrs{;+fh9'u*~3Gϗ<./C D1ÐNܼ wBUS{|[dV(m5gv)nICis/@8y`mb`ȭO=[F˛u /FV;(ۥwӥ);o ^BU uhhW"\NHR4ůz4Z޳Bʨ>,U6)]?}<׋G>>Q՛;z/0o-K>yy/K%R@(xO=7x'|d)6+)9ˊnv[dWD\w?⤩3G}.2ZeяO(N.۩оa;enߒ7̊b.Q󫸭V?b}/9V?Wٛ֫OWu1_lyB!ZJrrrN\sI٩ZɕrU405nQFEH+m>1' ә)^,mKDXֺ`4Z,k4jjs_zH"Zf[9@&(mfZSz!BeDNoy4F]Niu_Y0ks/wVW}UkEYj,3_wB!F @;賻̾-) snՕ6B!Ԓ|iN K;g7a pDxB!tc{ oWB]EJr-dEEEal B!Pov$cE!:JINwPCh!B|ݛY:("`E!7*,{?aa !B-K(!B7p|Y B!Z ݀ZX,j44*i5qR3B/\+Eh7!Bgn3̜]gϜ9ct""""07vDDDS`C """bHADDD )0!1 """DDDĐNa̩sq\_q:ݜdl`2)""+0zjRSNN9 **qXڶmä7^c5򿉎vCOsżs\qe}+/frjǎ1-7`> OfۣGw͙͗3?gq _rYg2/Yf͚Ѷm>d a񢅼ߜ <Zrָp8۵4uU.++c=ТEsRRRm~ǚbtg+/Ӻ(3/9HZ0&ޏg;wJvvCY0 Qc""r:csh,ݻ椷pT&?h;xaӦ͘f\NCv;S722 𗚚5^׷wKzF:inӚ_vq[osfpOdSf\:l(m۶kӦ jjڷkG~}=bcc狏rJ[;zOMn_O?MGy`嬳Mgl۾F6m>9skEDi8UY<ȝc2qxrs +V|JڶmGS>O?]wwg0xy`JKK5&j/NcꇓIO 77/`۶|7q->V+O=8͛ǓG`` |;Wk9sr~y,Zx6[DDSΧ޷_?6or@ppEE2b!<<"JJJk&0v>sXinÖzeN0L 8 x>=\NN;(\&wpZێwzԨy|<۴-}Wk9f츻ٿQoCPPP?@\\O<(۵cѢln+YYl;J3eh0 rNgc7GD䘨 .}ti^A| )*tc5a bd& @>ʟAQ\XJ^J69)YdS^RFHLQĄ_?ٹfRKaF68,{f v\.501jH:vSZNS+),,K.dgg{cn'%%{7ɾ}J`8'B\\\%Z;.BbL(;PAa'E,&l & &;VX1aqe2Q_LNASQn'ȇ@+!E㨠0"0.ffҌd:G4j`ؾc, (h8g|Z|}}1ֺ͔ufqweӦ͞{O׶mOr˙5m2V___=DQQQjϏ:{ ŨȉSm s.: P 8.8qPA1P@+y/.ꯤ($|_j{mp!sȖ]ʞ0󯧞⬳ΤEYYg?==/۶OAѣ;>yaFxa|0hOɨ7qmΔȩ;Cp߽0k8~vԏ>jЩөv 'qqq$Λϵ\j%55&^1,NZSᔩmѢ| v ygۧ{7f/qGvv6nɂI|8e~/"r"WhuUpI|6mrs+)S'C + Jh1MʱwA@@/q z1v?` }%RQ^]wb13p@"IIK0h0iXVV+sxvó>πA/bn[oӷѣ?-[N\ҷ)4zT>\N|Ȫի ˾mo}v޶F3pPzFp==_b~‹ygk췾""'w{Pc3ps6]V lK``=~aKx%ψjC*]$d✮^m>\E^ȳ=織0} F8ҳ=&!ZyHNfeO?Ӳe־;w@Lt4tk3<_>\rԎ 0 ˴nՊ:[on@ZZfhl64mƁd}?/R?D""' DV_уZSi _nQN '-㔖,\(\` 5-:+;yɰC׷g_X Cpڷo=je}DEE:Bv,֣sIaa!EEE5c ddg`0v4HN79L2oqb+uRuƱE.Vp"ltN*--%U+"^(/ MNNwl^nNn.OZXv<Y' O0+W^n6 w.W_}^v9\xaH니4].L& UJÆ bXBA$P<3Rल7\} Mu]}U^-Z-DHH0Nv-Z4CEE4oo-0F~~>[a {Ǯrtо2a[<"#"R^VFi{頁m?*GZ_Dir3Suñ,r?ӳT葉 47-]CKL6@,Zȼ9 魷!991l}t<Ŵ3xW˙nS{9x*skp#=636.X|^=/`,_u̟7|Źvc >i*LxB*~~tl֌.qqlRaLfmԡ C?ظqaOPPNk.&//w@@vV+aaadgg95aaaN*{FBCCqh#/"Ҵp9tJcpz/Zqe׮\pŔl^{KJ Đݻ?y愇޽{ˣ<o>|pטH.ZTw> YZ Fz>NHH໭[ɍab4QYY UnXy 1#77ƺVV}dr>{?Z,t`=t:ѣeW4nݚ_~LzEV(((l6K||<-euS١ U$Lƻ0dd2<Mؕwy&ӺvYgE@@eee$''M@@deeWG؋aui3I0=888K \d$'ra6X,dfRQyyteL&< ^IDzg`׻lЩ1xcDDDM).Iةgy&mHtl6guz/YftЁM6ϠAꫯ_p ~>Pm!k|ڡSGcS#{ ""*q0TʝN'32|9m(w8cKQeeel6bccI.22\.dggc2r6Û[ȁ˪SZ[wy^ּLcΓ ""A>e EEegcX Xz5dggG`` YYYsN0L8}7 - ˚cg* """Tޤh=0{:~g_qqgJRwG`2ј] """=oCn///79sTw-ͭn̙DDDhi &ᭌEEEG}";T. YwI46$Oޡq{SUlejhaitUhxkł+**wJXvZA3=4ʙk{T}BCC 3,WTT)޾{O~ux޷V ""j$P y 4GGU17*DDD:]EX| xrp aed6ADD̀[}Up SO)+/ge,ݿ_SS7|5#oW>C#N2)""tTv0x?R\:a{97o}ݻ7111gPsš$tHPu.>w!iil۶ ݎ3hޱ#vR x?B^ >DHK:Q94ӣH㪚EANtO?P<޺?瘟b!jr1 """\\;!e[2sg~tLO'0038ݻ3{lbbbh߾=[lߟ3o%""*mKzhp:dZaTGxa3QΝ;$'' {L>RCΝ嗝^l;shی<~39}as駑| ? Y9!eT26fsV:GENwh>j.F fӦ0 1|+VR\mMB``ZۯlfܝcٴisfrՊa;TPPEEE?cp˭ZOKٸʫ=V?0ta!lT)ϝ %@XI jM5YW5ۻĜy6d~V{޽HJJjDD1ww3<'rp_VKQR T(TYxLfVKj$zRRRnVrss| IDAT)3>d:^\nxSORZZʰˮ0W]zzxG~&N3|}eeeG彛fƌ k1Ts{s6K.L|!rjl篿5kjL$"r;8\.>| >QvKmle7r-<3V6mCU9,6nhX.!!A厄d"<<ܼZO`z2{`LONn>.~L󇇇W{;, a7""Md8]w4|w[ Pr{/))1ŴnNQqéw8:R}?죺OY7=OS# """Rc:= """DDDĐR`C """bHADDD )0!Mt2t[PPc7EDD¢BvlᙑXS`8Iuܙ{Mc 69]tax$q RX9 8"+0!1 """DDDP N9Ӻvmf!L`w!**""""h2+ŗ^bʕ9DΝ;ѣGwAQQ=zty||e0Lǹ'(e]N=[eX,Bi }qcҪUKR<$'sgPV^/ܓٓ3>옷muɧy^GFDpNsXx1?f2{9FvlNzz:;t`m<Ç?B|AODDN|+;mz^3UkxCff&oFofJKK=ڴiõ _|]t50QTTt>Z9r$Ç_n`ǎӊxY~)))8FED$2s L@҂ۇ86[nvpp02ln-| ZjKԩg:ub$ky_,NZsyW )֛O҂|dڵGbccYO *ib9c2xgh޼y니ȉI0mۖ={zАջ袋<ߊrY>jjZl)mӣ ߻WORRR˧}vFncGkG`,BNN111Cl\gڵk7o߮/""'&ðpaRcDEF~pdVv6&ﮈd!dzn篿6DFF26x!;+ ظ8rrrj-s=0lإdeg)FED$ߕCdD$pl^9N惯*'7'u񳳳INIf;VƒbcGwΈӿ__>5H니H$.IX,|}}=KՠƂBZrmq5=!aWym?p u_+/ھhbn&BB]V-ZT= Xz5۵_ugP׏Ax?|*jo@@QQQl6-m6~Fz5Wg-_΢ŋI8;+Wh𾏴4=Oo }7n4,Рr aX'332AAA8NٲiW ?pdBɭs??? ByE\amav /<<2+VRXXꋈH=0̚5Nfぉx='d___f35b6ZQZZuXn]>>>fx=͙ٳ;ghт'ϊe߲bٷ<أ<أ 67^o'ؿ? w ..aԍ#Y0..YĤ7^',, ? ::>&i|x89|̝=+1{1W^kc7_[n&i|̛g >>l68i74~"""F\`(//~മ]c@KW]IZz: oDq'Ymo}vЭV+s7 &q~_Ō&4oޜ@1[s8>Fb{ՏīF v'Lje˖/qGrJ27Ut:Z("""k 77[ Yj5Z䔶m|/;bpZjE;v9߰Im'~̴iӹw޽^^>s Un\.N'oe{!""r4ТE 222d!L<O=,XsϿgޜY\:lQRTTTH6lCN$a$&&tuiiDDDzn۱X}vJk?̳h֬׺QGˏi{czgʔ^~z+K]ʒoWeƶhZj]g-Ex-Zyࡇ:`,_n7K^n6 Z;6Ddd$)sŒ0 99DD{kCZZ׺x}YnS|g|׀dӷO_~|8p͛7y pѹ#$$$#u̘1O;6t(^!)j޼9V֧vYYlݺ[%"'&`2hCxI]իhbn&BB-Z>>?#i鄇{?s 5`G`*؁ iޢ7u+WѶm[;\}gWhɒ:~m1~lyGb}yq2H~ {1LX,[?k9~ukǺ(//'??SڞŸž}jzãj5l{.???|}}kk$>-"R&nۼo?ayN$o),?sg$@^Xb _c\.&> z^KYt wmtp\-d7'ܴ3xW˙<ȓ?9;~?yDlf̘۸G#OC 8VhK-w 2d(O!YrUlْ?ɢKXn=<`'f:_sޫW/]jZ~L&φX[y]{yj]z)O>wu77lGwzmϛN;;KΝy'Yr70y۳b*c, ,XĒoqf|! 8>>EscYrWYk eY0 7qmo9Gy]a#z*ywXz K-駟qzuڅac=z~ٳ'u^þ}ҥ+6żys9S T^y5~-|ؾyz'66_x;uh޼9M7d_~UƎ-7si1}'lݺ3J}+6t())ۗIb0x`f͞ŹnsEsuq鰡ddd0jh^}5H1cfl}m-ro+ܗޜ'N`edzMdUքGӫf^Mn6z-~'_}YYYǓh1_̜jʞ{o@zr&Lգazz{-"bI04TYYP P]nn',DqqqPޓ";;>I,'סCG뵄Tk0xfϞž}رc;˖-c!Ut҅5kVӡCbbbٳg={b׮]r,Y~L^n.:tTί~}1{,RRX~-w*SRZ=n`[0:t?D6m<}!'+W=Mo^Srp8]֭Z׺Ԕrrr!((O>hzN mH]AٳfW_{~mˎ;y"i'xm]tT4<+=-wGLL QQQ<ދd j7&m۶/#CLL% 7x@ll,i^RSRZq.z{6Rw \ϸꛢ>ˬL[D. HKKgȰK{Ϊqe'*YYfsYYYDFyndgesnjlYYDDzd ں^2"&i0wΈӿ__+{.gl9dw]yճ1 mH]NKNj 9鼹:lG]\r%$%%_Oj]w~='`k{utڕ38p_[پ|2:v==n :ʻ_8L:w\{`>W\y%ڵ;S@Yl)ڵ=׳obj(++;tP$s~xUVq<ر1,v)V=w͋~ 7QXP?'L #Q_|'O&77bfϚE6mHKK㞻ɧɣ=@II)^3| .&ibrrrHNN槟~-[ڝҎO?¢BlA|~ۭ l233yp:1glfLޠխY={lrؼyg?ޟ̊(++c͚[_}^yUV^CII sf޽Ǽ"ԡ =蜳bch$$$4; Xظ`=V+deeպ=**\πBp_1i6  ;;{DDDDvv63>3`zX,"""(,, FW5ב n96,,BϹ`Gxz4-">=6|w[zNvΰS[W)h(N\z [Am6dggsgҥKzthhH*776 .G"EANXL2_Kg޿i""'9aٳ/sDߜED952}RDDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHAg IDATDDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """DDDĐR`C """bHADDD )0!1 """NRNظ 9F7p?{E6p-HBD")R-tDwE+.UIDC*)JʖȚm9s2wnv䡕~h%̙_V:C.!(ӧO=$`2>:B6B!]0!. Ba B!K!B%B!쒀A!v{J%U^UBQRR  d2=$`R 7n\%&*" !44RLIGK aQ?Qd Ba B!K!B%B!쒀A!vI B$`B!]0Sv-j׮EJӵK:@WZq#J,}QT]!EXoooztS\խC :vxժ=Z [T*] !EXpnFdd]gZ?x_nEDr|]\\prrOT>7c6www EպպXخE=s4B#$Z-Gy bo04mڄ}`&,Z-[hݪkIs= Ǐ`Ĩ zAn]&551c_Rd׎m,_W|@y)S3fRgشq#Ǐy9 B;k׮aGж];yݧ[6o?˓B!_\0p@ʔ)MIJJ" HZ/ѧw/zMDD+Wf闟s@RҲEskhҸ1;w^t::w!..]0k ^}CqÌF#K-ѣ…p3Ʉ7ΟS̎u*֭Za^Q^OHHH|mBzƌ5mŠ&)) ۷oТyslFDD/^Chܜ6"2St)7k'  l2u(ߝvѮmʗ/gV\9+G?vSO=@y\|7oҿ6??$##6mp^!ģXG6m sp>^ɓ&o.RSSȠm8|k~wkV s7Ma)_<_XNZZnnnw ZgYxJ%1L& Ĝܹ3}2ed^ʾIKKԩ@B<OUj}ի=ω'WfMVKNh4oWxzzx_T*|||HKKΝ;]UBQRSR ʓ?d2VB!SB!K!B%B!쒀A!vI B$`HKK#?(B!HM-4caaa>4OTx(B!i{$`0L]xx/B!Dђ5 B!K!B%B!쒀A!vI B$`B!]0!®"yR$4477^!vd*$`JtL4q"{!B@OڋdJM!ݾ}B5 B!K!B%B!쒀A!vI B$`B!]0KF iJkj"NNN?tݻu\rҺݼrETz7Vy!#H^$x Ǜ?w O7WW.!-0P(޽K-,oԭ[mWx_J*xPnic+(Y$...,[oVrqcPNL&#_IJNZ8~jΟe3! BS"0'N8tJD98{,dӼaÆً7nth(|۶GÃf-Z;{ d ׏oVb ( Jy !Y(;-[ zK>Cc0HHH4?x7n ,<.RJмY3:Lҥy|ykkh߾>[Dddԃwo%K@+XGjj*iiiCrzJLWm M46̜5.ovf֌'$0oG;@uB<:$`?@q7ofa;*IZbGK Jr2 ( V˷kұC>]F:ԅ#SBG|R ...LwUn݊}|}*s] OOjy|rFߏ3ZsNJȐA={2yTz՝cGnM:m3L 9zupp^͠*sɧ[غy#y ׏kY*>^ )|BxJU^yN8 f͚'(8;;Tx{{c2IJN.Pyxxx+WWW0S׬Y3fY PJJ ))6_weffo{zz:"SB!K!B%B!쒀A!vI B$`B!]0!. Ba B!K!B%B!쒀A!vI B$`B!]0!. BaW UTvZyGU,W7:u" ࡖi͈d"',J:ݺP\9^in˗:ԧػ{'5_|)I]ߟ2eJc޶nz""#m{#3+?X %!!i9ծ.\LK{9V}c4.R BPyYdeeL5زu4%qvvyB`|h 'N, !Da(ǟ~fJN:rbNZZ&)>B)J\]]˥wss#--j\\\0 Idegm1YV%==tdddvC#)9R;ZhP*dffۧP(pvv&##bZB))\]]2_|HXc8zXkn...ܹs'vBe!xP0XRNƎ͛] 曯bА!nՊƍ_楗^b#vKڵ3jjJɂm֯ouCрBI9vT*cFQdffj;~ǎqc5D>}0aO-fnՊڵkŅO0bh ժ=Pxxxp <$߹_3f3( :EXX:Νcv˴Wry4~_xfu6zAn]&551c_Xmg[[PP_~)?nݺj9w&LDӡVY#*W^'%%#Gr5sL:ISD ڿցh})$$ӧFMx'L&:u}z+Wb(U'NCغm;SMsLVhZ^b̨h:mݫWƸqc:;c04y O[_GRd׎m,_W|e]~[Pr%Zji_sQ=Q#=f,'M~?.y3|Ïl۶???f͘a믿Z˖r9"#phhѢ;u&-=wڱT>>oj:ijz>{ѣWo"""\2KW*-3|(߯]Cƍٹk㛕X~ IATаaڵmC7$::F 0\.\`L{uVռ?d0scW.;N]k.̚5W_`CBBcn EMחZ 3d@&O^gђO?1L3^={2a$sL?ҥKv3W|'Wŋݷ q&xxxXcY={wd2JI@@@fڽrOB :wb#k:٬;CF˖sQm#V/_uyy|h*VQU6-կWhyB2Fc~yi >rҥJ][4oΖۈŋ[du95dmoڵkyU#uqiyf?qo//P0ʖ)CHpvvZ;Xj5 7x"Ze{%JIj KrJr8OV@@@NZ܊}"33|y-SO=%1 $$$,^\vva2HOO7=Y/.mxoo#Foaq Ý;wXv-F`l/LJ;g=..ހJ-͛yۗm[6~F/4ߜs@.^̻f"&&&N^o.gty3fL'>!y>V ??lͻV9""Ӏ  2o;y f;;ڎw%&{ӽ};oooT*˗g¸1jnܸtJ.",yF#̳sFzy}z՜:us[lGjj˳^Yhp}H! #rV݋~qIC DFE^V쯿# b9L}eW-#1nq#11駟1rNܒtIj..)?F^} !Da+) J'={5{._aӤR*$ÇyB6mbVdIA"# ;qwUoO{]vK.3p@srwwZM29Si=zb}\ʭ[9SwcTT:kV[8R_pu҅znyBq?ma ﷺELe=f3frQ:w?hެ_}5[ncQ=?r}ѳQJ.͂INJBRw֬֬&%%ΛoߚQFun߾/iv?6NGTT4.9Ty/_W,'-- 777;%6vv1lߺZ͕+WYh1˖`txu*%}M4v5|(N{IMMٙsy>t 4Z-SM˗d21|HOB_h4r!&Mj̈&L̤I:;3w|6mrs)J{4cB SU:vjslYCJO`B7z87R7vj5vYꊫ+ zy!Kٹkw7---߻#ĖMKhZJew6j NxxxѨB@hR*n} S_GIII Eq͚59o6y0c0-3Lu#7'$8t^2m>9p//OO\܈"++UJʄĹO-]ڹ P(^ZJI@&%%9#AEnFxZ` J=v>>>|b wμ yfqWM!S0<]Nm;(啶oBxfmxqd0ziBGBQl$`B!]0!. Ba B!K!BU,U*JBTݽ8B!{iŅX*UpUb|!~ !4408() www BC5 B!K!B%B!쒀A!vI B$`B!]0!.  88+𑣌=qӵkcLmۖV[StʕNEZF VZۼys>hA[4o''Z.3<Ï?lY0} *U0aD<Zf9zveV*T`_n]vC9ڷ9׬Ymw{^N<ȑPTM6cl߱63`@fϞ~kڶkyXgع'O2`@z-8ȁ: IDATrjvC}G˥XJ,o~w{سg/waT^5kc:}7|3oљg>lFhyl֬9K槟~r*T`GtrZ- 6d(*թSV:uԩcDFl{^zٻ[rڴic}l5w MBBB?`3Oa9z۶q15kn+qfv}[yߧSNmێQAQ 3gR͗t֫g U6;Ա5}՛RJy&5k֮];lll.]b4lP\tz= >ujӠ~=N9o@`` ,Z/z ޽hfϞE:iڤ1ԡ[os5ruftF~[TJ҆k^:Ӈ|4j؀:ujgmXti[kJ,]4 6oӧO_fϱ|󻗓M6Eԩ]HfΘNu5|sprrM6lтZ/d#>>#c~@zu_.j՚#‹5kmۮvBף֨mިRkԼFg{]խ7_͢K#zuмY34mjq=q(Y$GСC6ck0jH6Oe鄄l[u7W6Q*̞3ٳg/͛6Fܨ3fLgQ6˿VR*̛nڴhތ/0xouhؠ>tL!EMpjAظIϵkxQԨQ#GEbb"Hɠ O\lvQF 9x/<< VKr刉dP 6ʕ+lۺDzzaͻokJLLdժouȑ#ܸq;Jo{=7n0=s YYY|w 9}4Jʓfʕdeeb ^~egVknoמ(G~G2331 ֮aF$I㩧"33hj[k[u-6m]ʞݻ-u BBBHINd TRy'Yt֮]pBZXmR%4.]{RLYTB!! MAʕQyPvݧHIIӏccbWc0ܸqxZl7+,\ :www 0= ʅxuMn޼I݁;u,px<# ;vBRw9B=k}z嗜cիۿ4N:ou?ŗKE& ???m.:ڧ|}}III)wPaKoo721FA=}jC0cTV^͆>m j+]*"R)3GR傭9y5Vx?{9V}1c>S7;yPzIgLž"a(J?3+W_TFJJywܱ!FZZZ&N&-- R]* <^ ?3Ǎ%66 Zbl۾Jާn:LF~p'χ{ӫgOTj [dega0ޭ+]ɉ[ 9(j׮ŘQPըTJ|\qc9w__4NN3dffҺU+gIHH[ٶ}SMi&>AN.i[*7kكݺMjjcƎϿ9Z/1fH|}}h4L6[b l] O<' PD vlJLL =z߽^QѣGታ֙7O0T\ϖ,Qty=,#GΗu?zٙDƎŋb¸qTTFÙ32iT'NZw?{z^={й8i4Y&Nl1p+H QXۀrJj/'11'F,Z1_|}&,_#4 +-sDFFVy`̝!mo߾/.#++͚Iaq|0|$.]XCX=}ǎЭ{<];NLl,}y` ޣ' aO_Hj5:uG^ܸqCClٺ$0;vƍ8;;ᑯj՞_EWV)U֭ r>`\\\waP!ͼdɒ$+)^IFFm-L#٢V)S&g:'-=G8?__sQm*Ud>J+{ʹy5ժ=ώ9]ƥK8C:vxݜW۷CTrE&M X{ֶ[reL&۷nFq+̘1B/SU:<~_8q¡cK9͍Pj!n IϿLJDTݕIIIh4xyyYgB^&  8-'''r ^o}xyyP(tVQ*x{ {e{?üh4jt| L&z9D󖭉7==DŽDoگT*>>>{9|l=^deg4 ..V+q*㼹sr~>}:t}0rH>t_-[6c deea=W^i4#F 5%YQL|8R?) #UO0sLHJJBxl3>۶ ٺEEEz=m݊ Ǎq0;jNp 6Az= ߰ `ҤI۸aaÒ%K㡇Ν;Q\\/bC||<4 V?qϞ ш: y~$&&… hRaٲeº1c`0 xǑ ȑ#=+W`]tfa)(//Yv\Ӟ}@6m_~5k nڣ3`Xs`ժU6m_u3#&/̙R_ލT\|駟|}XiQcnMdb(ՓZFTTZ-ILUœ90Lx7kxuZ3wӧK\b MCzz:zꅐPYF%/sθz_[sk0X,~,߰az$ۇAIO> Ӊ;~ӿ3g`t]ģBV#//#G_~Akٳ'l6 ee2d:w޽{cǎRvYYf3t:a6-_GEzz'DZZ @gǍBgϞ8quN:Zj6 |n?>:v숚\r4},223!"`X_'=C.]#GpIftݨ "{N|79ڵ+z#[ZYYY0Lo ѱN}ՓTί(grwY :cǎR{- DtS>>TVVO?1%!&M>SNn{\WdL8u`ۡ+VHRVJt:TTTHp%t_ĉqFh4ׂXĉϹбcGo8ϲ9N8w.^yݳEEE ./_H#<, 2p2v;JXn. P܏tdq[WJZ <<SL9%%%_;݂,۹Scy_z=V+^7o,[l݊$7P_mm-}̙=z`!жmEzرcNǗxXt):t耨(̝7`4qE Э[7#@FÆELL &Ok׮F\FguKh4ɓODWd2aƍزe V^k6\^p. dnX螷P)AAAd¶[_P5.6FuÇ1x`飏?f|ܱKZ;(tddQFARԩShPQQQP(q uZjӧ{l///Gnn.V\s\#h߾=p9b̙\36 6M?ai78aBCC?4223ݻKuo|WʦRеkW|4oA|A؀Q]]ؤ} 3#fmڴ۽ד@zzbbb|;weee Aaa!rn:zE]]6QחMkf0XR4.ڵ ]5LMnBRPX, 8o7ZZ-v`@9j[:xQTJ5'|MBfi( k IiNݸh4\]TG1vX\rcl^j{@NxxrvjhZ\V~#ቑO*v0Q&+4:MEN'Fc+b gΜd:??3l=9Fg-4t{oS7k*lٳg`04CMM jjju|Փ?f }r]0`ш -JJJwu߿V^ ejo]DԢ WLR!$D P(j'@ {iv{8Ni*H"""ŀZ4vH~|0, DԢUZ,xϻBQӵ@RsJ"jќzARE @~L D‰p8(r<m @P\(@D-"38d1` """Y H"""ŀd1` """Y H"""UPIENDB`RaySession-0.12.2/manual/fr/images/proprietes_nsm.png000066400000000000000000001443751417052567600226360ustar00rootroot00000000000000PNG  IHDR 6 pHYs+ IDATxw|SUlt(eSV8"* ^(ʦ (CJBwӑf M6E>'{ޤ'g*-vp BQU]@!? B B!I!B$B!|A!>I B$`B!O0!'$v8m6PTi EQ8b^EB $XgڶiMZz:u] JDD8ZƐx.BgV  CFF&~~u] !O> B!I!B$B!|A!>I B$`B!Ou0Ljӧ7 6Ԩ_>CbAoJG&M#6-qB!׎LVzΨkߥMuQ Y,yq1f[es>MDDÇ 哏?OӇ'_W]gᣏTCXbC!Ŀix& :Sn{f:R* @~~׼4 :"M&^'R,~F(;oLNo$$$c^L6~֬]ަV?9zhޜII!11ݻ Bq^95 z3[#X 7N7''ѺU+OHذ ҠA8֭Yʏ?dsz gйs'V}M W͚5eúl޴_Z^?k\gKyp;Ul6gbc&flř/B9 iذ!۶1ݥb3:g'ΚFLo))8i"aaa3ƏVaC󈎎&77-_ʫy=~͚уMb !8O(-v^ OO@ *4IjBBB(((\ Q`V+yy z?Oֵ+{RBs^PQQQQfx:emU;ԿYAa`M!HB!O0!' BSaӏg<_I B$`B!O0!' B B!鬬%Rh4BCAA9cm!m,idfdBCDDq`3Yi0,!u(##> B!I!B$B!|A!>I B$`B!p8gl yB EQmE9g/E9.0! zXo@P vr0!stVbˈidCkQo JA FhRhRGk05kBk0Q_Ln,rR̔L@x7o!?33[ (I+gBCq. B繾p*S?X!8A2 mYP *5FOq4C!?ls^9yyZ ,b2h,a2hϳ`q,Z*VV}&Ps<"BS XmMv Y~l 6(P s>ϗI#4Nowt3l 􇪼2H ?կP(O3~~Ux9*Sʁ6_2~WX>u2m6mۦ h2Jt w+>l(=wG|EF~jTM&q4mض:{΄믫v.Sǎ>ެX}|ӦM6tH%p.8;5Ꮓ}V[vA0_pDU7.TxV7y;eh.=|.I SҥŌ=Guo׷/ZbX%EQ:e2^Kb!223hѼ9KdÏv~jUլYS^|yq =t:^^A }LiiÆ7[ 66}ԋDݠ]ve }ݕҥk6oB-TBu%9ջ)`GǺ uvJ)oC7 ]uΚ$;Csp)))n{o4(ZZ^CL& |^rWqmILLtojz=eee#DqqquˑGn@9ޯoѽ{WGRqǴ.wxLm ٶ}{5`4q bcc%`BQ৶c,c+߬ =v5 ~~~>OSUbz4n(TsEJPcFI;1u G]ǟ[.>a4ywX,Lxz:wM'''_]T*6|,_FEa„Yr"@YYକPTF>d%K^^ _׷ݻuхg|j:k61|0^X{ټeGO=m_&O?toSլx}[lv&NntCmMEC aa>e*q̙=FZac?7\ > f 4w݉Z&>.-_l^~ !.9+`PLWXXAplgJgZF3`q8) QU=aYm,|q|q~iiiCCCxyp<~ե7w{ZAv]3c&:ub˯[矯dr2{SO?]Dj{75ky%vh֬irjZ4"iNJ`ٸ=OHZzz4h4?7*:gCXXOSi 4cRPX g3zh6&le˖ȣ kun!Yè([C e{l˾KUS$TRkI5joo2U?w;999|G <ȝĉر{RVVƧ}f{}n.4[߲1LdgW_CFNN.FrrrW{;٘o_($&&b6gsI|#clV[ǝi7չ^GLF׮]i>3 ʛ{5lxf .8oL8G'pjԂ^Oz"h{)p W5* I8U>s|c v*$=-#mjZa߳f6ܜ\}fgY^jUN̐I:ٜh_Ƿoߞ7WbwǭY# 6;O5v?O|3@yAPM:1m}23?[HQKc&m?V 08kڵ޽)Zl>~RRG$%%ѣG&$$<?TN2 KEU7}\<`gc|l""#<֋h8V:rrr8Hx jPMÇ\4iy>ˉ&Moɥ^JƍX,T*ׯO شiZW:qIղT]p5I(cHr^,oidqm[~Kf޽ଂ3f4;z_7~|xe{-W_}{~0 P\ VTݽeZM2#,,Z]|aӫ^:TEm+CsűФ Ut469e RS1\~\z饬\zѲeK~G2d~)%Qayi\=eFIt #~RB$!iXyӄࡶ=z=59ojp8ܝMO, K>\g2"NݛVVVDB R ap!#G, B!Ds->U1`j=y\Mʜ#%|XXVz4n쥆ngzA!NIPP{ɚ)w7y$ 4.#22^Oٳ':RE& %!B\ʵ !ؿ?VUǎDjE|:w?%%%$''c6AgEz'8zFMTTT !R>o(An'3;x.FO,X|&X0n\sUrd]I\z=eee~5ծhPJC.&bV+Lf޽ 66k̳ϑR%?EQ0L۷+ Î(j?xV4 ~~~RV?G!r*Pp7ԂjYSQii)T3o7&;;PƩ 6RPԵ,ՙwEQ0z#X7_߾s]T*F#%//`IOO/#""Z<ˆ 4k֔-"44N1s{n̙}?hZ]~~B|8?96.-_l^ ::=JTTZkq83[oRxwXjJbsx+yϺ\|1,^'33ߝ\wLʕ#GRZZN'˯\~~~<0~f#=#kFakҹ3κ}g~wG\\5!p8W%aJyyyف"AC> us0DDS/2?Pm_gIDEE곕|*N&'hvh&0t֕%/._s S3w.IIGt֛ 85k3O=#.b-AAt:Eac&ZlIpp0<]'+ (R IDAT0w}Dkf;kF!1ձ,{}9oV{ֵKf48i"OӸZ0ud6mBR'%hh KzjZ-׀xtcQ벸tO$`B\PGua U]Z݋p}mzWbpUZZb!<}xN;T'44N# ,&0 f\yyyAlv*iGý=B |&e)Ub?I6oC&lsOlCQt2Ku2)k-cktXXFҒC"(s.zֵ -[ư}zZh4oތݻ۶m;[xеxE ܿ=z?<Ӧ*L&h44nBm5ʮ?-cjuFOcF"%%ǎa0X,@T*ƌ>r}[&Np*KN>I6 tuܹ[ZB\HCتÝ&2дvթoJVVUZ*eWQь ^8DlҨu2/D0e̙}?{I6qq֯[CaA=;n۾%/-FĢĉ;|ǝnB\(Nu"CL˯'5?V J/>gϩgj,iu0!烊fgB89~H; G \ =B!μS*7zgm`\pCm!D]?ɰJ!B\X$`B!O0!' c G||]t9玊╥Kزi#3gsN}.ԋdY*+n<OW}y+/Sǎ^BK?3q=mڴ1a {IIIeq~FMTTTd^Sr_ 4]wHz}E؁Ya)UL*z=zx`0T?0d27k֔~R\Bz=^Q>@L&S,*=dm:k] oZm=9+dM7WY`0oԾރ*_^ ƽ|e:Zu_MǕS۴B 7n^h+xͷƦ͛YsiՊŒϬȑDEEWϸc}}h{hfc1~X:'OdIII!**?^aiѼ9-ZHXXe2.}ɷ#-Lv'Kiӆ^|Tד9'44Vˣ vz=w߅Jh4'+YRل8?6 5ƙ-k.}v̝fCT{]\|1,^'33ͯҩ sCK.̛7ܼaBWh3f4<ȀAC)L:6&lⓕi3 ^c`F^y}f~7&3k֮e=3HJ:¢E3hP,$'0g\ ACg`y7LnˮʫGqqxE<` e=3xh\4r]W\q9#G g7` Vfaoĕ˹~V+/~1pPÍ&IO A7ZpSVCo8ixN8e}lBk ȕW]#UtTjPT*}挚ރ"""x'Y+ ӏ_gI :k]DŽszǴ4n܈rɥsSztԉ-_|I:l8]ԁ}x]vU׌OlL-Z1e0``HYiwyGtB  lgENN.^6jԈ6mZcNbZ ""_~8w;w1aS,))!)A4lMJJ ˗߿k׭?+offfp8^GLF׮]ߧ[Tf+GH㭜Ѥqc3˞;reyq8vvIF-::{{ʕ5ޯj\zi/=Ʀ͛q8VX#--\"""0PzNJ7t399tY_==\z54jԈMT)hܨ͛5={Y$8I(VM5mv}?:thO֭j,`$CdbСUҌ= pnxZ__'NpIƍpʑiNL{7gSVkr;`۶nݚKh0PZRBq̕#GT\)/Ƚɓ'yh,X~z=O?, 6sq֯[CaAﷹ{ab^0L~~>Ōj6zgm6v;̙uؗƒs`u[oof ![J˶F;?LףGZgOXXXVZ 99`0=Tj "772vEQ jzNh4͊Oشys5 fkj ukVӵ{OPT^N, ۷駞pWm@9^KBJEHHaZ)((z`Ϗ윜ZÊZ-&"^O@@@ρܫG\\aʪl62MP` JKKС=m۴oxjDQwÛvu=^C(TUQ[!8 ERIqᓀABBBxe4Z-EEL&yy믺.B$`牣ǎ1xpwo꾤3lHmg~ijB$`lbHNN9#yySZZZBo$*B B!I!B$B!|:+CAAg#k!BBDd'y;(ۮ[4? !‡;+3WH!B- B$`B!O0!' B B!I!B$B!|:+0T*bcc1g#{!BPPPp8g$0Ķ%5-̳̌B!| ]36Yi0,!u(##> B!I!B$B!|A!>I BΛ!6-:b!‹"`hy0g(B!EQڵ >^t:zYtg,?@V-QmUL_YXXzFUs3( Zh0Eu???f;{gCDDz k1Y4lؐ'xߣ~z3mZgg3Tš1{g]~oT*А.oҨQ#m={gB}ڨ7Us3smr-PZVV%/EQwU[q᫳kƶo>ןоu`4Yg< hnՊ(AOywQ>:vd j}?p뾊w6Ny]_ 9gTg&ЩSZ #00SiH^p˭~y*MUx̴j}KUqcǒs~BwV֒ڱ{֬]Wedbifڶm˦͛h24ի="**DZ}v;Fddh4/HJ:@\\O'ѺMk.Ё+ޠ}vqA 6xͯU4i҄-[ն_vZnM6DG7`y^EuMYu%aAgEFr8aƏ矯;zٺƒiǏϏ/ǎU˛3?"""HKKc˖/hԨQqFh,EuϏ,hذai~q ߟٻ;vТys Fz/LZZ:k֮Ν޽iii^3ZC;_k)**|Ӎ4juܫΝ;ѭkW2332o%Kaa!ڵsۇ⫯ E z[8vrt֕;wf{vS{9ޭдi͚x$pY CveAz|ԫWt<M46e !!DFFкMk}PTy`6V2&_藺b6tf^k(L&7n5W]EiI TQuBCCX|*#GҼysPu h.E ea\tE5 e#22'O `a<`>=ztl6syե\qer뭷pȑ>y 239r8ӦNAҮ];, VWo{Nzz:111̞}٭k\:dgg2l(Zd}jՒ }v[رNǢGߏ?b|MDEOV֭0n\3z %%%ܹ-PՌu :;cС};EdggѣGIKK?qd: bX#ЧĶmî~v_r)]Hp%|j5%%%lذky]!44@Aa!7Nw}ϡY3ywjLԓjw۵Sǎl߾۳fZ|muMb!^|i |tZV[חh4вe eeeϻ|*֦ukr$WCAA@yPu駟yGu@LpF֝_ǎѣGw֬]Wm9:7o{w>xgYB{IBxx8.RvD\_p_;/iӚdnArr q={SO=>6~}222hӦ5i$lC>l%W5k9bAA|3QTdffb1b8KZ۷_qޡ}{wvU$ߏc0 :Ѿl9j"/q}6׿ kxyZ^RTTDjj*4&;;Æ2vuTaq. IDAT*ڶmÁM@޽iۦ c@HH/JE6=A5ksϽpXviӸqci.kذ1pgj !.lu0oߞ?#XhҸ1YfCS۵վӂ < Ʋ{w[le1-Z`6gc6g*?Jw~T8&yJ EQiт#:Z-Z={w/0zwe63e&vb=M4AQ?i㾾HwYiݚ`0W#Ghܨ1e/'/BV-&l6MIKKcȫ٪UKWXX& ]RF˘Z-F}X>#բEsomZ~7yЪU+wpҭZwӢr~7رƲlk 6߆oAVN3_y4E !=_ۚf#4$YKOƴhAJJ؜\ڶiRN߷_]˟)(,,-_QTXDaaÿZLF8s![!Oati݊ ȉ'9p mDrJ ?t<:u 0 >\,^Ư`\#5%Ԯ]jцxzyss V99%Ο? *[Y|BwUN_L3֑߰;O?b}μ.t8s,EEET*?λoŷ}ǚWt![e˖rKJj*g/`klF}Ww\y+WUÞ={m3sfӼy$iii{xܹ;ۨNL6<{өc8{EM4A@2t`ԩͩS(t*Ν:ѿ__իǩS0ҳGN<կoiҸ1O=5 *ԭ˩Sf#׹гGzIfdfeÈɡEՓm%==6[Sir={tlÉٳ ?C"iD?qww~tggo<0jH2Ȩ0(j[UՃ;O޽),*ݝ:=G~ OHNIKO'2RO^^.t J XH69}:Z:d۷<շV!*9/^$=ʠG 4합7aÆ?/W򕔔`\t Vˠҥ3 8xyyѩcG3z>>$%%9ެ4 Ot6*ڏrj=ӻWO\\\h٢IIIGf DRr}sNJIIM}K4`rIZjŐjЀ䱠ZjѥKg?O^S:FE^^^tԑFYf9HQQvB^=٣k&>q\{t3"--QR\L֭8`=z[4 $>>2ˌFHT$>M:u1|Q͛xٱ=%5ѱc)31tn6rrrȨ0x[xx8ÆA0;G|9k唫; ...m*'ѤIVx 0t=6sgޠV>rm|{=dggpyU-kji\Dnn.-[Dѿ_t߸ak… }ϛgL ww7%_=wm6i±WVb{meR%GWkw̘~en 777/|lZDE[oAff&/,ZH.??_yMj5iҤ TK]u4e_Ļb8_}̙O(ХKf;ݫE|ŗu6_e\y^ǂHMMYzre !!"zAll,_l[f=n]ڽJyOY@+[hh'aaDi?^޿O:#+vi-og$O[iW>~3$&!ag݆'mz=*'MAACɉŋZmKz~Y?,FIqI1<@X>FVnCnn.sW;ftFl`KwBtUh4.vFS^ɿܡC?ϭ3,^7[*ǣ3g2s,{iFpo|'*6oPռR~zq'XBtءb7ص{vQncS)((RYXX()))JDVv6NNN 3Te+Ү}Z^E 4 2M>}:/,]JYYÆ vH{pvRy݂5>>ӧ7o򷻻;瓒,桱f#zvޣ T*.\`F$ иqc^z+7j̖{LTs#Wy̬Q;vEWLU;)(0ׯ/oy\]]]INN&###Ip;v*׮UcZ"Y3ez=_Ux7jĶ;ƍ)Bz={I7nO(4i܈49V-U~׼y$ e8um1m̕M)3pɤcAT*M2dpbn.~05JS]Wg̜>_\=NRpxFGygd 99JEݺuyh͘qy?yqr+r:^I&2pPeCCC̴_Gʫm٪??_jx{x0=+`E4 "#3ݲE D(j͍3gҽ{7nssY+~EUhup4A sBf˵wޱN.]ČƼa1^cÆoPR,/DF.]:3gˣjS7HڵyH+L~]6%##Lڴ6=gRŢVi6>j_گ+Ok;x2 5`ȐuGfP*l4˯'6K-gոVY::Ovņs?Za8|͚ѵk3Fzd:u wwwtL?8w77Lo;NxX۷oh4m.W'''.Gg-Zk.66n(Wޗ~Ev~t͟A`` Æ U_ч)eeeU!)M*^ʢf͚ԯWb*j[!88ԔTV{P )1뫌кU+n6 VZXA+++fajp9R +KH8M. TngddдI!R?dh4<=Lo܉>rgqjPRbτ:U 0 J;,jF#')9|bADGg^vJ9Lyp2ǎp[%rP\re: wÃSVVqlVˠY5d'lP1ioRPJx6]sh?T*P֬Y;ƍQ;mncz6뉭y^ϱcǕghh(}nۻQTԠ5W.uw~Fe+,vBCCۧ7} 0 0=C1nXLI6dfeg^t.kQ5jԠNJkݖ\ oDM9BVӷOoZße+k?o.%sɿtRC)#G?`sEZZIIfYNmjٙi3W}aɋ<=)&Nggg~w_ŋil޼.X;ɓ`Р<T*~/QXXHIImw_f'$GjJYiͰ#^-^~i9_mB HڵqwwW@Ϝalܰd<gϞcl'AAAΟ? jm~.-\@bb"i\x2U8XTC8w^^^lݶ]Ivq!yz6}Ͽ7mhG>KJ8yyv;}~Ǧ>ʦ7RXPcQZZJݫ[~}~m]UnӚW2bt5V[|TՄ{={[oËK_s9{T;ly9s z=|٢*KtJ'+_1ZөHq!n&}ZVTNΝ;Ə>fM x'`7b%9sMn4*w*ON'PN6}<~^+ױ."'R)4iBVV6uJF8~JwNŦYkf,?\R44_̤u|ǖkܸ.dqssSs,Zcǎ]~%-bggg|}}͵xAՒ[e?7EjZӃN/M9BRKqI٭3k"++ˢGʫ2[V%қjԨAII mgL>;FF < IDAT]ggg23,ncp5|||(((;kVKNNNhReXȰcp-LJ۾C.b4~ժj|||lH>mm+{۳񡢫ioڒ5+ndLֱfw-zb&{jddfVyJUe`ݷ+_kVZ9=g; RS/."BSCjU`U|@j *dk?Ȳ222l9Wf4-wpV=<ѕ7ꊯ䕳{Ѳ#p5lՙvb0̮X8+êتm`8Cʬݾl}=۳rmowt?,puh::^[KYYU3 (3q9Z-O~>dFv 0p"?UۨQC~ iTgyժ}3B/00Py`L[ZkU___232ؾ*h%!BFvI !B!K!B%B!O 5?XL:e-q\\\hWugE-`pssc4knyF>l Ɯٳٳ IV5glz^pH׮]՝ 3ݻucX\fޣA7-OBCxǹcXVf#dDD3ƌL\ѨQ F^g6o%/oepӦ0z8vwK,r"*&в7&҄p̘1կᡇ7޴\aa!_WtVl?\GW.ϟ\``zArJ =wc\,i:2SWxx8ÆAٳVпRSpu0&F F˖-HIMUh4t؁^={8w2ِHJNo>t܉RC))gC Yx8瓒ݫ'Nvww~tggo4k퉌$22Vٳg-#,4!ݦ \xJEN߯/ԩSF|gD-_haP}zSY400!Ѳe N'Чw%Ftb2CVnVˠҥ3 8hղƲ2zj*Tԩ[SQVpŲ՞]\\٣{Yp22ζe 8 Uz喯mzˠQQ 4\pm9sݶ`SN0z(SF]6ݺvQfmC߾} 3ܩ*J@'006mLi+[WWWuʝw'pvv&9%-ZлWObڶ%7/tӀ=QQ͹x".\Uu#:vUTmwtǯ>ez0q>m*'ѤIVx"'''/{QFV`0)((䞉wAhH+/SkӦ5zs՜9O=}zl{Y\\\PTZ|}M6oߎW׬`Ã7__˨#%oj̟7nk .Q\TĤ{全 w`\ (-- Z%ܹgL Lypzܸqc)++%55%/,&$$bګP\\LYYoڵj'}uq>|y7Q՜NLI&R8t4G%%5cFsPXXFߥvZ) Q epSWVtt-\@zz:Y kZ-##9wK͵Yqcp:1"5lhQ&mZ;oMff2`cSY0~~=w:uGr)?Bm+_&,,gcSp<?zʠ'iOOOT*K/b𡤥<2AR0cc)ލm8T~~~lтΑmjk ߏ \]]y}kʶzA|WFc!Qm#=Fu\̌LVz־ OJ"88cF3|(8p܎h4.fEϼpqTEyǎFŅy=+W/!!PƳf=_naӦOS"*]wR?9>2cbƎc 5j$F La0\_X1jJsvvf<6m2ZZd^411uz .r>DS\T_|IQQ[n3}݆mݫyy*g„;1r2{TTsbbڲ嫯ufӽFVYW7[V]Jؽg%.۷ox-vh4̟fWȶU4 ysLw6%55UnelP Ϝ!: O63b0=yt4f+?KݺuϿD@@2yizvP&''/ϟ_hZ[2nF2tc9FO8i7B8Z??_4WIJJs 8)' pRIKKR4h b:]_nrRnD|ՕѣFggg~^Ϯ{/* .p[\p$me5ֵ+3z O{l*e~϶-&2x5k٧G~;cF1bpj ٙ yŴmkЪn=jW6(RSSXc?ЫWOj 7lu1 !]hpyޞ=c0n.>;v4,IDAAz=/R~G,}alk`f۴WW^[Cˮ~e szʚWܵS}v\Lhv;Rgo`LA@׆Lk=F}}>޸;wv݋۶ՃGccjZ,*ʔvۂOE 4 BV3st^X2 +0899QPPH^O܉fsp:Vte ;wQٳ{%FRRҥhu4B8ZSnO-_}\fWT*6%t"X"m .y'O2Yo(W$:={TXOGcFשj5Q͛54i܄TZe^'}ks>$8۶UC '))}l<2Y:u6̘6bğWvvvF׳ʾnذQ]vJ9R`e  c`ͫ-ONNARQn]2i3f;vT"4,C~&Y3NNT7j5mFwХKg> yyy_\=N2nӦMOJJ -l@$9 ٸaIIxx8x<=>χ_|Ǜ6/-RXrw%/8nߙ; W{(HJJU;v2lP>rs8sb$&&΅>x5?gxJ_U@Lh ҷ;z Ѹjسg/k^} ~Ǧ>ʦ7RXPcQZZJyp;w///nnQ>sxn.Μ>#IKKÃgε׷۾|V[-Oke'4h Ma '&ٞU*~/QXXHII ͛oQ7m`ٲ~m䒒c ,~=/-{QɃÇm Oe Di+WM_| 3I݋o.}Ypmڴ )Vqq,?HMIUn^χLLGgn5+^ZƲV(gTTR\Rbѷ_Fۛ Wkssk|||YO{|憗YYYf}Pc/ggg|}}͵ʙ;nnndffݎ/9<+'b0=a_f4ZtgcV؇kVjʲWZO[^ڃrrrBՒnwY 'R\\lvh.MQq1݆TZEEU^W\Wh2~W(rj L_j U'Gʶ2 %%_ds9Gۨ|hZmV7*- GF)..6*p( ?4Gu֕~KՓN;p焻͖),,@YYYa0xyk $Xn%^=z08y$Sz_ıJ_3J`Q!n, T\\̓Vp725!U9ulA! ߙmG!7 B!K!B%B!쒀A!vI B$`B!]0!. Ba B!K!B%B!쒀A!vI B$`B!]0!. Ba B!K!B%B!쒀A!vI B$`B!]0!. Ba B!˹:6ڬY8fI<$٣;S}﹗E=64>\B!%`xx|g;00i}|b hݦ5;w~Zk^!7͟z"6*wssСvBDDD+%%%}^;vV //2@ ![ζ_j_Afv[{6owz۷үoe@~ 㙧ť7l;{v}KHH0}f꣏Чw/oG|՗|fb~͚5ٰC|9N^Ļ⻝MV܊xy,1!QmwׯO?GzrO͞üM??/,Zcgp""[oᅮ̋K_~`46 NNfh4UjmAHHZ WQn222[._|?B2ڥ3wNIIbkk8zEJǎ9b8ƌ#--;ƍ1t/nX !7Zahܸ1:tPxN_ZAXh(/Xo.:v 996TڴiCà BCBxek JKKȼ漥M@@deeQNm}+oαcǸ,ݫBCpӦ0(Y,knv}yB!njðm*a(((`ƍ<9 >Cy^ fΘ,B^^5#??ߡmT*Oyp2%txzzV]2̖OKOf͚Pzu*:3*-$BUm5Z{ȦO6أp! )9SXi&xzzfcYY) 'hOȪmȑ#JwIN;PBADD;w2x@7n|֨Q#tL.BQ#?#_[5dШaC4/ᓏ7Ǿ}y',x|&`zu'RTTfp|F FYYaFV\_ST\O? !ᴲ;v2jJϜ囯p)?G}ƏxeJ\5}XRΞ=g{~Oƍyӓ?G}b١CVg7|BI,­[vqhkRb0.Z-Ʋ2sr>!??Pedgg+`0>R%3+bʜ%?? \tfZB!=#6ah4|"岳m~UF32l.S(!B!K!B%B!쒀A!vI B$`B!]0!. Ba B!ZFzTD4kWul^!X1Fgx.04k֌gO\B!ԭODDKK!:$S/0!. Ba B!K!B%B!쒀A!vI BC:uص{NNNWn&Mf?UL5lOOO4򷓓וwҴiS/2v +]!q IDAT?ܒCPP֭CԫWkBS-Oٳr*~=+w}FV #HOO^zl߱O6mID~/n@ҵ~eNj'|[N> ѹSGUeeefyiԩÃ'[|W2{yhʃnݚ׭gǎtZ~cX5jEw3...i/^QQ_-[P~}B!l04jԈp^^@ii)$'IZ"33:u*x" Ci[[ۗ7^,.\WZZ#o׾=A=[ko6ҬYfgg@\\v3?6lw'yŲJ,px}!jr]8wSLQ>'EEESt_ZZuw=ާQW)323bxiٲ9"9) Zhlw>V%AkږBqa0L}1cPZVݻ?oOf=Ͽ޽׼u.]Ӂͣ޽zNjKҊ:dYWõիywIMM`(ᛯQU.~:-_N~y7矯kB!Q4t>xV-9xbbbl.];KYYgZP3ptC1bH7u===qss'337!n<<<'''x?3!7[o=ozen; effZ|v#Q3&99'a{瓟y%%% ``A!ĵΪկPSVwvB[ 1vrssl B"CӪ; B!-{R! Ba B!Z<ԭoA!BTnsWCǎ,"]ul^!#l{0FVǦBq !B%B!쒀A!vI B$`B!]7%`'fHZ!@^ލᦼVKNGMnFB!#//7NM F#G$Bqs3 B!K!B%B!쒀A!vI B$`B!]0!. Ba B!K!B%B!쒀A!vI B$`B!]0!. Ba B!K!B%B!쒀A!vI B$`B!]0!. BaHTVH^!vh!ݔ!Y))]L !Ž"t:b!ݔ. O/O BjtEn~yA!vI B$`B!]0!. Ba B!K!B%W ۻFugh4VO2WWWBCqv)]FCZ՝>kS-G@àشԩ#=OYٍV2Yt ryhʃ9 CugP־jug㦺}twwg鄇}ިQ#ьg?Ţ xhʃ4nfΘ^H;MkfΘNzvW V-CSNul_ϗ̮l0Ghw|EϕԻH(RBB}cC JQ bY{DR/ K.=z_/_ٙٻq.}nw1lxxx0AL|knnnaatƍ18lڴ<QQ{!~'݋JnI]c\MJBBjjժ9M7h~i4 6oL u;.|8e_nB:kӳGZw/:@qT@XX|yL&-[WϞK{ܹBCCi>N:݇˧oL4))DU˖$''hѢ9/^$33SN}cIJJ&w/ڴnMvv >܃:doӆ={Р=X,\p\9JSR}hӺ5$'DfMtDQÆ$?Ovv6M6aϠh^c<44~}c{ >> ŗB{A.bEL,%]UpV?SZ1$&%4iܘTL&P̴lق4m҄t2JPP} ܹ lNLJRHݺqY#44SN7&3g2h֭MLtڷkJbbb;5J*$%'`4ݫ'?NPP-Z4G3hԮ͙gw)h߮E$%%)SsyyѻiղEj4ڴ___9}oՎң{$;v RwٲWG*WDabewҙٔղtО ڵkK/m{?=GRfMjժBjE5ۛtؑ0N:EQQuѕI.ILJ",4_~իӰA֭_O^=19zmڵi&\\$wo3i>%\{\:]bP7L{td9wUTa/qww'<{ԪUz&履z [SPP@Hp0_Ϛ;oO!77Ιi.3mh: ϨY&F7dgSPPxѡ9s<~;JSfM̛h$==7'_@#taaazz__:,""oϏ BoMOFIF#իU~~je-핗G17ӓoϥjժ^bX3g6~t:NٳgWǼ*=zt٭c^ V/Vlrx4Mzwwwf0yWٳ}]kVI3<ݸ1Oq49gJ3gHFF&LL׮]\sß}$77lY]wgeܥ3%AȀx'rP舣2^MYτhӺ5.\j2WyHII!""s`FC~~9:mk///͝C&MHIIzjX,jayp`Ԯ]nѣw߽ԯ;vң{Yt(V^uĭuG2l3ТysZjb!;';vyߝ~f5iҸ1zj 4X9{1!ju.u,9?,fmtЁ:u#{|租7kʒ! FWS$?ϖ[),,[Pi:%KլeYQ\߰n-ժUcΝ"۶mS7GXd)}RgիٴiK/ٳe-ocL&?AI׹s'"""=v ~i/'Ob K.tރ|vpGlڼCQ^g},[޽zŒfyO?$֭/Oxsv6WdɢhӦ5v`Ϟ.أCټyj'_KMvq.ʾd2W.-#X6Pk&v {d$ݺ$''~@TToxCi p֑ݺqoؔGm\֭kP|Uy5ok||| $_ϝ|?hVYWFjt#CoL}!n 0xyyQ5,IߢZ|LJX|;wbɒEl۶%e:?}݇^',,͛(M <<ggHiP=IƼ<%xh{Sj])2PfJbf\Ti://Zl:WWiEEE5q2?W^Nw^6kӻ7*WbU.oW|f ba߾///Ab25k, !!6רQ#G'ᶊ8t7^^+SRR^rm{{S'59*D |gv8J{Rחྲrs lꭌ:_.ÇYx uֽ~Ֆkzk5sA F )>tss`(>{]a#$N<9mo| @nn.^^^xzz:=?ұc._B݈%]dn6мY3VJF 9t7eyN#wo~)ise]\9zǟ#!!FC쮯Y]-|GIKN6^nn.IgmڷkGP`w9WWY'O gU”i4խqq]v={w)u.U˖ɭE Ì߷ئm{&NIYfYYYxy{=Axx7$ٶ}GKW`% ٹk9:mߝFϞ=(*,TKg'OdYl .p><uN)))N;O>_6l؈'{Bh'y`@i~!kbՊefs3vK~B=s 1Ry<-֯[dӌze5) "++ Rj~~~,[F#Ga5@؆{IIIeW 摞VtĦͶprsshƿ1GDӒ“O=CZZ:۶og9rǔgG˯f`.^LȺl9֯':˖,"/?{a-5p8|p0/|V-[;m_~%KxB1 j9sҥwTToHMMh0'r%%%q_۟,YW!nMD.Y&6iժKAד<ҥKR.IKK%%Q27EVkK7N "##B<==1N,7Zc养Áwm>:\^'ܲkP+뾟ЫwrZ6eqrk4l6F!0 r|}w:@@VVtYYY6A|77`L&IWcN^2>WEXP+F!00t]Y]-#Z?222QŋϜ;cW+nnn]j4ͭ/'pUVR#f Ci.?,}fW\֨aC2339HZ5Ň3>Ic(ᵲW'WBU=X)#窜Alcx-uv۵ WTV᏾6Z){V+.seo8?~y,@|_WQr,8+j9}JY)**rw ˕Y[W+ ;ۋI*dp+g "3#;owDUR.8t1-v3VHezT[B!~7DyJB! B!P%B!TI t:5jTvE!nSR<%#G(tF3?Ǹxp7 %-=s LxkM ϏdϞ=,~.[7T̼ nwQ\K?{` + q3ܖ+ z$//Iaa!#G/>W'99^OjZٸi } gmܦMkyɧoZ}AݔmUD'O~+ϯ 7hBTjPTUViAxRCY|][.?ujצgiSųeei{t _16mٳ ܃Rȅ m?44~}c{ >u 6oL u;.NyMߘhΜ9ˠ[.^^^<;4 u[<\˖-I&MHOK'e85毿b8-;zKDs1"&S+:ukԍ ..NЦnbi٢>>ŗ{ۛtؑ0N:juX:vhɔEn%."))&>okĒviD*UH*ah4һWO8~MkeT)rJxyyq!fJBE֭)(( 9xѼYSt:}h԰! +/h4tԑݻNbb"ݻG2`@r ԩӄשdR^rTMF rAWwUj׮M^=:}Zy^ߘh݋6[c2W//JÃ1ԫ[gpw0p@իǙ3g|=;R)ӧ`Z '{jǖFq_uJvvҝ:# IDAT:ksWʱg5laPۧڱ4VK=h߮-Vc4HOpZړAvm=a;:+~^v-~ʀiִ)dJe퉋;3ߦ{\:]bb4b CQQ-[׮gb7'вe ~w %5Q^TJп=:3gΒ]w/p]0???3{td9wUTa/Z^z&M|.^NGnn.9%_P_fHIMb0gle>oMOFIFji㉈PΎytRRSINNqnxyy1o6iBJJ իWb8Si3 $##wLk≚ݙ=+ˆ^U&j׮-ڵU g'ƗU FbMaQ5kdFysx 1n,/\x\p3m;wL`` Oa@~<J=GW-gVJچ ջ9jY;67ի/^dL}{ }j}τhӺ5.\j:lGgeK5kKvv6Uk~0oz<@``z»ӯ\U&M7ڽ/V-[|JBCCI8-[ڼ/<%K/l>6^{m GcchѼ9Zd=zDz+/gȶm9yPJ7OPw܉~}Hg_z56mvN˯*3nݶwDLvN6;wt8"[W233; ϯN{v[ֵ ))D1.Onzuرsg6hl,~+0,]Wf+if%}||x}8 wúTVԩc"{y͛:%6qsP@h &Ml֟;or9<<͚r٫0nrrr8{]#`]_ZIhb&GR.?W/9>Uk˪Ѯ][E ''+Wb득Ä7R;kGGeu/?PJgؤΖ۞⦫0C@@X,t:~^OXX(Kwԕ%M/1Yt}kժŦ-3zyyQ5,IߢZ|LJ4Tޔ!CW.;jݣOyƍÀ~}[6lXn]{W.= UTZTVE׳vŒ%ضm;_ϙKr%yڻy5u:{m?Oz#4˖>ժ][mS>~O( 9%%,^tb<<< ?O(DQ.=d»@Ʉ 釗]pA";یɔEFFP<;:B:vhOTTo #>FI}\9qO]iG(>{Sj7}{vtTV5{D-~r鲳ɮ&`о*~-ca~5x~f)ѯQjUF iSfli{PTT|(82e$>̳ύosQ3/?7'DIyyy_W +V0l¤)o[j^+ct<%}ML%_㶏aeGx`@>sjԨ#GӓR^%g |gԫ[\'ba߾t^^^9># 0@F8xBQ:ujTf{?|0/ Myxǎ>>>hZL&fb!$$6h߮AʽޫSN/޽#HǎR}FD(Gvfg6vf=N/S%$8fMU.K1@>HÖ-[Kp5WN|9h4tn:W-g%%%zqss风Zpv)mH ]OY=={߿/@q_3&fm=lSZ믇OKW`%# ٹkCһw/.$_ 88f~R.y<-֯[dӌze4'Mf򤉬[؟e 1|H;>x=&%%]) "++ cƎs/~{~dͪ$_Qs7oKRRl۾x<W,]E IKK`4ЫwSbb"?,kQ^2G˯f`.^LȺX~=}Xdyݻke}ڵjj2f39vۯ,sv6I1^zy4Ge,^#Gۼ&O;oOk.37Ss5#Y;5oo׮ }.^DAA+W""Nt[˼ xit^Ç QSθҎf&Nf|SIRϵ=ey6QkV$55X ?V q3T*z=] <==1 <<7^'==ܣeyyy &|Fz5sޗsyW~?__,_nK.9=ٳmZm铙rjv؉8Xi:#++`mVksZ@L&yyyWK^~~2.{NNꕌYz%{F\9V[t/6}YP\|n%|<%K(S_1j;ڣ/}FFYF\[aύ^òX,N?:˽4lwۥKbɱ Pk,4{wej[޽Ν:Ѳe ^' ~Q:,㲫mk}ngejϏ*V?y+ǖUTT7??>6Vk۴_'ȤuW\mG{ԶW q-*l n-V믍u/+#oՁpB]wSO`4ILLѯ9 ): P|cQYu!I5[yw¹B!*> BJ!BA!$`B!* BJ!BA!$`B!* BJ!BA!$`B!* BJ!BA!$`B!* BJ!BA!$`B!* BJ!BA!$`B!* BJ!BA!$`B!* BJ!BA!$`B!* BJ!BA!$`B!* B ժUyfB!pm ^x~$x;qS4nԈB!n0Тy38HnFzVm][9S: h4DZna~6eB!*z#woǦ[xѡ,YLY6n~wtD-8i ֯aKzFW䡇Y&+J>;Eճ'[߇}7y`2xt<< ]EbJDFӡ/swsC/^i=E5Æ'KF+.ݺcX߯/m4!"{b%ow77wAك aK/0?6}:{b<3̛^QѴؙ)c]-_ҥo\C !7m 4i``}yfbmݷ6*w؁5kב;9{UmܹsݻÇSPPe(,,_jժDvƾ#NbccF )-] sv6zj}YbbiذVۺmz !7m%/7Ka!3>I~~> m ر?l>p!v4ۿ/]XXHfFߗXLXhhWbԋʿ-+;Sy3e2Ҙ>}~wB!*[0 t3'99Y>Clڴzii|IppVrq1f|4aɯ|˷}tU BߒɉСÜ?rjb8\o=ޝ4z*ϟOޝ-"4iLu劍6'Zj*լYAL,|ض};xzz[CtZ,B4 CLL-+?o5<Y 6nLFX|)$&&qh|=DeU|6]s9IZlf3ߏϻE2yݺ1g\:oOHII! g|ĥKrNe\v!FDoufM~tZr)ݵpww`0׳ߧ]2zt:0\ӺJټIKK:7B!w{ܪU+~4= WoDiy'yh ]7;;[|(!1C@@}1z77rsr0LowфBLp+ " !31e&SB!nlB!gA!$`B!* BJ!BA!ncZ`4ގ !xY,m ׯO\oB*U뮻UO|ܖ[FQ!:$%&`We B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TݖEЪcB!ĿBhժL[=-R)ǎQoB,Sǎ޲ݖjr,6vlZ!@0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!B B!P%B!TI BU0!BM f3!!7#k!B RYYTJll,w}7Ծ !BEVأ7,0XVb޸B !1 B!P%B!TI BU0!B B!P%B!TI BUW0 78 !!B0Ui"7F^pB!ljzӣjqLB"cBJ!BA!$`B!* BJ!BA!= Bqi_x"ĿRJ hAQS \HJE_r*4>Ģ[B `4J MT|| BR0!B Bt̅L!BA!J!Dg*%ԏ1 BUrAQ>tH5\FoLq\aB5n҄M(ܵ#F0u4ZhNUVDGGӡ}{oJ+)'ӳgW.]xwoH^jΙCƍoɶ\aB8p _y>{a:Y8qUJ޽)**%1x{ߐ !y\2d[YPP͛7gƍ7u;0!*4xzz:Mӹsg F#111 ^^^ܘb41X`00p𠠠rHnn.V'v_ j&++n~:oooL&uM(Ԃu(>qm.pwjhZrss.Lq} vu۩cGr;Zε*aB9|[7ouEEh5qzضu+˗-c֭tYYcׯ]~}n#G2y$|?,N@֭Yv-˖.e6j׮EXv-֯gРA_NY޵K֯[+صs'=7 ::gd֭tDȑڹ+V۞;>cJ=/[Fz eҥk׎۶`|6uVx͛7…޵'xn[fl޴}{,kެk׬alڸ{6l+/={xǔF?m۶qF rwɔɓٲy36l3SiU<Ӭ[m[ь{ャ^+Vef5jR;\~:VX-[hӺ5=z矧GlڸQ/Dpp0gfڵ]k!Ŀq j<||8pfu/ϧ{d$Fb֭@ٜTh֭cLymf3޽{3u4:u*#G_宻bΜ9>|)ڽ3gb0xLݕ9z<0iiijJ-[FBBnz=/SNexɏe׮]EHNN3ٰaڵcРA 8T~aMJtL ի"O233/ӷ_?ǧ\!!!7}:o&7m˦[lɠl63tFM߾}]j !Cf^ ۛN:_P^^zJ@9l0|||ҵ+#xkDҥ ~~~,_WG!CHOO_d3OwwwztNzط/ׯnDJ.$'TV/uUrAQݺw0f|!3oO²Ki֬ԩSdr.{⯿8}4KH4mwwwvMv8HKOrR-ZZjԭ[ٳg+[6y'%%AHHF *޽{Y~wXv-3ٳ3g*˻GFw> kgIDATѣqTZ777j8bܹs<䓄Gjj<Μ=ˆZdggc6K.U޵{75WwmvA\\dddPZ52j96]Qk_uYe?L?͛IOO`}vRdM=gYgϞE˖t NǹsB8+ B^}U&MT.mFf&Np4ѥ3tJ=Rm/7pv.۾};۷oy|4%!nKׯo38}zN>SNs.m*UA||UsYz=5jogyߦ P􆿝te]K۔k.<m,߰q#MWY;d2QT0Wzu8|0ɪmq&Wڷ1Mf>|8K#tiii5t/Z̧~Ư7’>#&MLLL_Z /)_j{+W?f/0j(ƌW^L#CHKKc̘LFѰsN4hV9{,׭#;;_~ݻw]nz6lĚիIKKԩlToNZ?ofomQ;Jn999|h4f3Ń{.ƍSyzz2u4VZU,-mS:?wy[Ν;W|}tVǑ#GlҸBYv >p- \/{QQӶwZEPƇ~re#//QvrE@|I$`B ,&&hL:v_A{xWAW^{v붒[B Uz0L.]^7VϏrh۶-?[B49X,t9^\"EK~Ǚ~?۽`Ot!BlC B!$@B!f$@B!f$@B!f$@B!f$@B!f$@B!f$@B!f$@B!fԦ&thT*)RV(n_V!goh„nWW Y!1yS7cee%Y&=2!BW2M!"M!"M!"M!"M!"M!"ɒ __5l@ʊfdf4eRY Y ,荙;h"~t">7*C!ИQuٝ;w?899'vnNqqqβg͜΍7IHHsssƅ zzӧY*?uغm{vwsM(B|Pk}IJJ2HT*&&&hYjss3⍞%66 {;;j5 gϞeމS~տ}/O XYYo>m  %!!F^#B!ovEK 3 UpֱC{`l\… t܉;c6X`xׇ[7aOzu6Tl޴];qww'|f;oa̟; sYrʥ߫gkٻ{5W`ѯ?ӢEs6[gnZsػ{'[6aZϧ?۶+GӰ(R0۶ȐBփₗǎH7]JiKZlǏiӺ'OQ(텓#CP0m:vhτqvvf_X,]+^HP#9b֭@,,,:|oܜV,NZlݚawAVSn]Ξ=?_-&)):k3_϶j5֭ӓR%K0l4/R038f`F ~::aCӱCF+~qؽgVVV81k ƌ_]~!B4;;[F@)vuj8:8]W\%o<ʙSUkthZN8I *WȣGDEF]IIPlgܾ}{{r# Ի@Ub𲳵3Hs5,--ɛ'a*Uݻص{7:8b\]]?wӦĉo!U-" nܾ}d2~k\]]quu!ÖOAT&Z< 0|pp011 2hW5٣;aa7_^F-X #w%::FN DѠP[%$$c7OשW.?+sf3fk#"տ7#EVs\\\Б2ٙ4OXF!zoZdd$7nܤn,X ᄇCK-O""z*KUƋf&CJ(n=z& ƏCs4]ȔSYt ;vp}ڷ{~ N7j۸я_~^-pqv#7@iZ1t ;ίԨ2id$v3oL4m!2*B!y_@ou昛)_k=4n`z|0#G.P PHsҿ9fffD=>(?˗{kz_nܸɶ #HUJ͛ȃзOovүNj$''fk>;v… /Q>4$M~xcnjB!0hGg4mҘGwN9̽{8pVaؾC2 c!~nۢ_O_͊l"6_˰!ٰq[޷m.\uaF)͛غُ[6nDغu׽xRztƆukYb[Ç5ѣGgNGJS1a$Kv߼q{B2EԍyYYYaggKlLT*NNNƾ_ ''G4 QQ’'OV=lҜ=w.ㄯAP#GSmUPN:vh׭2j5DDDU*899Ve+W,.^zk !{ ~'''0=:N(qqinxt:ÍﺲbJ3CѤh4#BeY&ޝsfq?q$B!а#jui>&K!ٛhA̻B!D%Z9t7 -x}9^Y_ggʔ.B!2-..ko7-SNz !B|\]\q&!N!Bw,qX4F4!BlF4!BlF4!BlF4!BlF4!BlF4!BlF4!Bl?STRX1lllvB!Jll,W\1 zZ q]B!DJŹr[-qHp&BBXX`P !Bd3 !Bd3 !Bd3 !Bd3 !Bd3o} !Bc*%fj%**\U|<fI<0mV3M6M|c҃&BwL BN{{jT";̚ɩSQʕ k/Y5kYrlٲl/RŊZĬnnnXXXzu<$***['NVUYXq7ok%,M%&&˗cʤбfiHJJJURښ [[[bcc?XǎxBΎhlllRՕR o‚gϞeJE|||s$%%hR]ǫC&kk=ٳg<~:jsssmF?7 ̛/o^=#֎qcdϽ 2)tΛOPR&J +{w3{ PT>w~ط__Zh;}*O.):}}}ؾu ֭eԯWWoJ*Mصsthߎ=Kߦ j5۶u6dɒ,[͛6p7JfoM8/z0Z [7mfm݌sʕ˗o#{w_>!ʴGҥⷑukgߞ]̛3OOON?ʧ>OOOmKNώcjr4z =+MP*jϝ;ⷑ ֒?Tkժˋ;ѽ[6AysQT⌍Dt:}Æ?t RQ#5b8}tR/_3p@jނ`aa*3s3{ NmHiKfF@t=}[rO>f%t:u*V[[[CptpMVh4!]t&gNOyq*WȣGDEF]IIPlY}Vg7ob&]-[IJJBr9\•W8u48;ӧ) O>=Uݣ|ԪUJÇHœ8ypuuҥI~ܹ{&M駟 zΌ>NCrIr{6z_jתeˉ ,,LڵkXZZ7OBCpwO}"#cOhh(<֭[ܸq];ٳ';vH,>>3fPvmˇre˖lݺ5=wt~/crMtt|J%NNN>S*T@2e̙3t֍ *0~x (`? ѣGT*iݺ5ڵ0`qqqڒ#Gl2Ut5oތk׮ vvXYY'û_7nA?3'ӦDv,^'O0ut,Xȏ?bܘtӠ: |r4oތMJi?pl2L'" J? 4:A?oVz4o֌RF-ü~..ίuQQQpMCh1-nAM*S!^fXBCCqrrbڵ4o?zb„ X[[mԨ3f`ԩL2 <<LRR9r`o@P#\#jUa 4C~dHHH}i]v?fPTǎoJ\l,/\cFVTnu%8$GGGNekt: *Df֭KiӦ&{zBgLM4!BSzᣣ177gʔ)5"::UVaeeE&Mcǎۼy3*ueXeKiذ!Æ Γw u74}ohB!xh1114oJYiٵkm۶OTX@7nȅ O-z(Qy@^n$8Be,h4TV `ƌ R]~=<'OhѢ]ti͂( ЄBNi4t:*U2ySTTz5Iu)RÇgEQ !2j 777{Ь)]4Ν38R J,iR..ܹsF-D!?ՑϞ=ёzuՠ\///vލzk׮MM*d$%%ѹK>/^YAzЄBNڃ?hܸ1666/_>+\\\Xh:u2VbŊL6w.w`޼yxxV޷I4!BShj'OdjjժQZ5ٳgS~}ON>իW)WJ:݋B@T͈#嗟_}oh⃠T*)V(6sz"##5H =hB!xVX_E^h޼9 z2'Og}FZ8wL:~vY}E`kk+ !`xԪUqƱ|rtL:'Oj*8u$,Y[[[:udryW\ȑ#dS!ԫÆ/^ݻwƍ̟? "ׯ~~~4lԈѪUk133‚Yf1f6޽KϞ=Q՘ά B!ީ7}}eooYl:t 00&'NХK߿lۺGAA)KKKlllشim۶ٳinL;g6mӧOJ38 !?)9fb„ iӆ ၳ3\x]vJݺu[.FJ3pRru[R nnnc +++ E|A4!BS,\0˖-c߾}>}7nc>JTbnn10{A)Z>\9sVlߺ%͇ʾK5k)<߯oi55gV:u5{}Μ9YtGcȐ'j IDATTZҥKQN%< !^ -R&m ҃WɓMxa^v~o=[d*ёҮWWW޽Dnaii73]2et$&&f3Bu6{>˖-ΝDGGΎ|7o^IJL4_\)JT* ⍯] Y۪ΗH~y(yZ%111&/_>Z~hfaagR@괺tckkKlllg`j3bii@BB+-IJJJ(HJJ"))me_#>>FZ">x( 2STX[[?ֶ7͛ )Zͧ~\'ʕcqXZZ!C8~rb )ZsssN>ŰC@R1zjԬIbBVV +Uv:|^"Iٹ3}BבQv1fϞRɂ-gga /[aatw߾0fM8~vfQ&Ϟ?a ?b )Rߟ8q0f̜#ek:vhOLL ֯ٙ'зΟ@bEYx^HP#zL6S "##quuEբVP ZEL4Ҩɗ]7;OOO6oڀflɒ%ӯ??3+/͛R7 fϞùС=:GGG.^D'gΜܵ?>{ݺy ?/\]/5juʏFaUt:njko˛ݳgi)Yܹiz5:dϟO*U#([[["""u !DFҚ|eNʏk3~}T*II& ||8ի'wyII|dgǡ]㣟v#DLs%Kٰn-V!44%ruuٙק ʑ#!/-:HOF==w~zܾs'ؠT7'O ?lԫ3jJLt{CF uplmmQf+PB7{w]~(ͼ?  S|9~L C?G(Jrp=iۆ={uoX3^{BXZXXǏg_0OJOÙǫ] ryOZv!Bٺu |-[}= [FEEE7 ''kS |r4oތM2Jir80,ٙ{^Q߶Obck||hݺ k$** kdFs!̟Lį]vJO}ՌӰdY|ٴ@3>lt:!!)޵kʕs[.\`߮.R{{;J*IBeDGG#X[HBBJ__șӓ}}m?իѣR]cFm~7m۴~[J`-{+$2GOfd#˗oWOoy9rvLNINNf TR{dY 4C~dHHH}$&&2klƌ!!!FM4|m[ 8$]wr*W~=˷ݸ{>۷ 8Jm?-Z4gA8swаt2_ڵ 6?X:>秩hٲ%Z-c1ܹs˙3g9t`yƍ@˖-QTZu #'lkaa dPƨ#ٸɏ]xѢ ۧ7ӦOY( \ʰCț7 LdST*5ӧOoVZŴө_ --7gꚅ⅄D_>3t&W]ʴ3g|ښ>Km1?YcҩS|<V_eU`OLU,SN0] LJ'/B#F?2kk,--yAW&;ۓ~Fc0=U3ܘ66CCmPN7 Z`1 ;n3{, e9'''Ív+JrAlll{eAO * GG'R]J"GohDaZvuD狘ȐJhkd; dF>͊k׌Ã5kcJwr4yaOAV^jYXZf0=P_0HCvG ,}f߿ؤDŽ4q!ߡ f[7Zway/4k&@4!޲ױo42C~o`2#!}V޽ j5 -{E4{^sJu-f;8agaohBe2<(]"4ө-M*oOd {Ny|1As Tƻ&CB!ٌhB!ٌhB!ٌhg B!23W.Rd,+WRX1+MB\OM|t:W\f!&!N!BlF4!BlF4!BlF4!BlF4!BlF4!BlF4!BlFAB!9Zg>guS>8Q?z{W4AP*+Z[۬nBpUt}|| S nnV̑Q*hPhQ߿CȣGY!EbŸN*P Gd Jp&v=֔=& eM!$>ZYq%@B!f$@B!f$@B!f$@B!f$@B!=Y&}ЄB5w:j,]-5!l+gN|}} ^E-puuM7۶%;uDP+VU+W3̌#Gs?+-ۛzudug6;OϜǼT*UL2Z8;;WPhz_ɑ#Gm)^8M~I:uȟ?x/^\3' 6aÆ|ZϊjզIbiioϋ<<< ڑ?~4hH&MS _Tmmm)_|n//TNj+-%Jۻ`ŋRJTTT}|_2lVҥK߷Ё{w~Tm۴SvPAo Nuݝ>o$,,,hծ]v֭[c/_￯/_&,,,* OO4?L[[[*UȪkHLL|77&իKbEy j5KtRܕ%)YI5&o|ӎ53WN^NPPקcN\v kkk *Ğݻ2d0ZV_F…Yp!3fF͚ɝnݾӧQnjvigܸTVSNbggO%iժ%ԫ_Νpu}K.q4i#8~ +^EN…Y|7n c>*P;oӿ?J*I.]9u$ӧM133c TQ$!>pmHկO:d~~mʗ/?MF*ӽ Ҥq#{}{ٰ~Zf֭ܿZӷ_|}}ѣ;48תe+ˊi}n$66Vn̘1DGG^Syxx`<Γ'IF<}T0iۦ%m۴Luziܱ=%K|Jnx.'Ot{lmlP HLL8CɊ,t/x~SS(YeJ333/ǏӡSTX[[F1&[[[.^9p2Zy_J ʊxt-nGZZRҒظ8u&#fffZ[Q0Lŋ ͍mR*קiּ9;iKΙCrr2 ,`*U .T*ӷMu^ȕ+͚7f<|H L^ A ̈́ =J:vС MKjչu+ooo (@``sҴ闩_~SR7jH._lRS~w˟ ޽kR]Bd7À~;`P L4AxDHuʊ JϞ=K;ƆDJZ$iʖѿoۋm9t|y7m۰svvj <==a\rrRmd]G6b05jȜ3ٻ{'ujN&oooر}>>OW|ƶ-~ 4l9sz g̞9'''uoۂٽ__zΗMP^=vӴIcΙ_z5MY+ƎH"طǠ[bIaZ*UȾ=Y|)z`]l\wQzu~П53عßZ5kL,-->ta-[;Ŋ5z_ա}; 0:e*7773g6sQf̘ Νﰜ9 6bDFFRR% Pւl\FӃsf۲l\nv'ׇuj1i6]Mgl@UBvT*Mlƽ/.WWW5kJP(R,_| S&M#ԪSMRz5I j5& `'VJR 8t5kסq/)]A+~¼ X*UdL?]zTV(Fnp_֭M-U|_mٶm;ucPT=qqqa¸50`RܽV03Sg^nՒMWI ߠSMg@L>Mn/سw_Ϥkɛz_4ZZvgχJz_u1~]XdƣG~:K.#w<ǫ+wAΞ=?VVmݻG[lٲf_5ӟ[lDj̘1=>zD@@˖q&FNFSd-]Çӭ[w VZ0>(ktwٙ Χ:w5(Vyo;}}QFeo+W2~4mwwwʗ/?[lq&"#r h@˯bƍ˭T6hh5j֤s.|Ӷ e˔nm[Qz5Wĉ>Ɯ8y2͹ZrG|yʢDoZPRE޽ǮݻtGΜ|,ZNGrr2.ZBŊ<@wM#GȤjc>V` 'NQ̌ɓ"2*J,mZ-9sz֩ʕCB6IN|r4^͛XmhZڶigM0;{{}ʱmv/!Cz||Xq֭TREX !!1c BCCٻǰҘgt܅ӪU+9Z7_>~_ݺQ\Y<İñ௿i(q.ZWYX9W*22 {JMXXS~Q_{Zf޼Ҿ}i+8HTT.]"22ժQ(mi/Sښjժ}6=eʔ*U^zlǍ7 .u&ʕ(<>sq*U@#((7иQ&""yy 3tFDDD&M~־ H@@Ơ`_ض}׮^ջiN>Ν;uxֻ5kbddD6/!Yf-NNNZdvI>?by9Gz88d\*7`ccCfjʖ-K_,!2O֩f-[l'V|uoj5%KךǏũg0773򎈌B' ҾK\Qdd3.I;俰:L-(\(uM*sssrǭ[A~iPKK,޻ǽ{@jgڽRǎS\9>}^ ;\vצQ(t6gN8q*h֯ yRɇVR[ 7:JɩV100SGO11.{} تV-[``` ?+K[.9>.Ŋ+VRR%fϙCYxS&Oy|\ooǦMpttMgY)TbŊQre.^٦00DP*hkի[Os\O>Ѽ iެ95Oٓ-[T*100jժ1Ν;̙=[Lm}>m%KFr<;xmVk|Μ>Mv[n݊gG *ei]Ǵo_Arؿo/m۵ӬՖYdaaILL4jCCCzC!ڵx~~hnnFllжM+cN>ݻ~}:?w{i6Res7!RխfV/&9ܹ{7oҫg=Bw]o4/=Æk͞;q~dž*p>Ɏm[(S^ǪT*FgRgnل=WƎ7n 5gL89˃!L49d,YK/iGEE`"ϝ-X0.٬ifʗ/ώm[رm+7nh߸ݻjqм  {wnW_1dWSf >z#8OOO/_ƓǏ7wM5c^,Yرc[j'kIHk7;>. f:.\l7+WZ:nݺ\y_Rĉps>bYt֝3gqIΜ=G*Vٙ1cRvrFp|gϝYYJ.\9\Kʉ:V3ƆFu˖ i7mg:dZz gmY]^:~a¾u~߱c;ogj@˗M!"1h?!.6g< }b!xC\ &&F%!D4x *V|Jo*BK٦ޞǏeݽ7] Z͕] !x%SFMJ,Q>q.M!xC-ݜo ЄBw%϶B!D>#B!D>#B!D>#B!D>#B!D>#B!D>#l*VۮBwHl\,WV5$@ *TΝ< yUBqv)LŊ |ÿF#]?R3!90>oE4!B|F4!B|F4!B|F4!B|F4!B|F4!B|F4!B|F}ęgvUD…9wk& Xq3|BBhYYYQJynҙ xaaasMBCCժ)׮]%<<\g>}TCxQqqq3$&&jWF%x :_W@G .%ׯ_R CC*WP=((jQZ5kܹs'H/<<(gϞq)\]]\gO`` e˖%%%'OPR cH4p5kӴY `A>1~o*zsss{ҹs'fϙC>#66WWWwRp!^aur?ضm+,k/|2:uWyYv4,[TbŋHHH3~: Xb<|b6r=hCZ\xqNR^=կ@ٲ刉4@' Χ?n:h3p VXδSRōKpU<;|3)S&Sl9*U|tٳg9>N-s+ ڵkO-(W ?v@P0`@w+RL/3qrrbsE-qlٲ)'RkZzuڷk˿G3W?0Ӥ_V^zs >H кvAs6 J7weܼE s]ŋx{^/_ p)hU?,.@> aڴi>I(XЖO}̩SiєMLgjj @BB<}666FTjP(XXXd$ZZZw2;ATX1Cfll!:ʮ. 凇"##122bؾ߿g'gJ#q|u 5PZb%{aʔɚ4;{7YHIIay͍c``3{v'3 4$8KTRܸqCoI,X-kZ P(:׿?ݻu4y|ڽ:u4ׯ[!Ksu~g>LXXz-]K`BΞ;Ey;ǏeV_NkٳghӦ-3O'%%ECD8yA׎۱bU>ť^}'c[ܵvmjk٢#~oׇ }ǡرm+Μ1i..]`4oӧMsN}fק7wng7ΜA wwvl-?_VMvΦEf}[lsN޹כZjм~fM͐gɢڱ۷s6 f/كa\-k8y'Ob2 ""0pttΎY$9ʌӹsr9wEl366u6̛?(jש)oҥ <mڠT*ٴgǎx{uѨqcƌ T*UGUa|IN:?icJKr?>ڵRJim޼9Gk۶PB9{ʕ㽇#c6lX+Ԡ0޼ QIII.]j>a ,[nݺkl r/x1w\ ȳɜʋ׊;#ڶmÎ8r()SZMNmףmtzmvڴnCVJ##  (R4hNTÆȗ=zҤi3x}ւ'0zXhɀA( rȈf͚ұ4hΪUqHjۇ7mǗf-Z2}tP6kA|۷a:=vEM?gq5>FU* inܸquRRR ,]"Eblle9 ~lW\ɶL}͉*ҦM#-SƏǧjѨQ\+3'ywɶ[8xE\rZJnBiy4ԩSDGg/ #,ZΎs2edjZ&QO@ꗊ3fPZԫ[3gлw瀳3&OaWK,ݻW=zdx8::쌿1U?޽{PD 5ےSR3z4CK.K(Z(G~|rkL2FvӧOuEw[,-,8~Њg @ٵK3pCFƍ3Q\~{iZN:Eߎ֩MHC)]yժUyw9z"{mR&Mchhao`XJ)W<̜Irr2)))Z>iT*k1URѭkW85l gbb]þfU;;vP^=Rx;g3f 44~9Y8ph.^HTT4ʊݓ 6|8O>{u7ߜ(U7ujޡCl٬7})jdVWUn=nݺšVUu֚4WbjjJy&]AAA7Ӳt}޽ <<֙M177'**JmJCC9¾};fl\n=.^K:}Fgx&Nc8zz44uՔs%z&ct)hgZ)V8:")) >1hvmbmm&&$ٚYK<C`+W }e9oJNI!2݇_JrE;;;MÇ>.nZ&((uP?d1mӚ$:xz竵@ K9%%s>F͚Ѷ͋;{{֬YgΜܜur8'Oz OiӮmL[5 cF¶;vjs!oKKK<<ѳZ+iԸ1{غu ~;{;vlߞ/U*}X9aaa889;kf)[s IDAT3C1o\uNSc^Nz333MtRRG&9933sܹMpp-[ٵ~,,,^zM4mٳg5"##8a#FjNS/q5Zlɬ?x>qޓR-GwHg>Ã8>B4;vҮmL;r(͛5ʕ?\ܧ\rX[mnnU(WμqJ*Et=8;;cbb111RH6++b[ ҥKӭkW7޴RRRHIIARqF0wӤIk=Nb?+X̡},Y{HJJWҾglXk6m77:Ol۶U+.piڵkOX֭[˯i崳fj3i,gcꛯ暇K$3Tbbbyd"{̞̀ߢ+-[q5Ξ9unقPBtڍ-[6gZ_߀](U5jNⱲkx=,-,,kۮT}֟M=_̰',,5k0ߨ\2 ###ڷ;2k֟{..]W_Q}ӛ9s|Ӌ]iVf`h^I00z1yvڰe w }۷n&22\b#Gi{9;wGf>V$;:'F<\~PBB_ZL>t8vwG(P'NrhƁj֠w^[!Zj5~~?'Eb}1"coI8` .ZZ饤0,\P*'NJn<;v|N6664jX,ͦMa-ZȤe9YQҥEmG֭G,]wA "ؙ;gfxx4#99(.\C>>?0zbbb033cܯefNLlL ,nܸ3Ǐ;v v{e&ͪUqvvfر$Jѣ>t~DFFbaaNttLf׼ysB3w~qSgϽ<8}_vOZn].\;z({x6(TWUݴfe]t066 ٰo@,mF묓BֶDGdK숊"99ccclll4100F縒9/-**ӁY6<""Buʋ|EJ{"##3|Q*300ֶ a9ڐDxx4cĄHO[7"oƾEߨiV`iA{OX[cnaAHHTʗKpr+0KV :XJْ<~Jmp:^'3bM6eT*Vё 9̳jW3chhȶ3l֭[w:9 dIVSrrrMJ"yf@Lt4} L,ݙ9aiym=ekkysP%OݻwvD>|XmIIxëHIIuVy^N^[z΁B.ym=umlFFj聯ZH!ĻC\hB!ĻAB!g$@B!g$@B!g$@ q8>BKļdOr +Rb]!ؘX\~J&j5WO(B)BH&BH&BH&BH&BzCng+B88:2TTJvB!JllNZhjo~A7!BAB!g$@B!g$@B!g$@B!g$@B!g$@B!g$@B!gr}4*VEng-BZ|s=@X"='B!D@Jr}\ⴰL! ?2z e B!D>#B!D>#B!D>#B!D>#B!D>l!)JjԬۮ-**/Mtttq4n؀ i^ZeYoBU011R4 dZ=XxBJ%..δnKKKԮ5kyY {{{*TH,tĶmսlȠtN XZZRB8S33:wTY Ԡjqu?3+ƃF33S&OO._M9L0?'**&_Ξ=BLҬݰ(VJ))Z(BCi/DFEPƆ?nt5=ʳ'τ{rCF }-*'OУ7166FVi<}JaRDPdy.Ʃ?F100 !!!| 077'666sssINNΰ/] 177'&&FҒX)m\\\ :>hC+Q*ۻ{V L07ih0yW/1g}4 5'&&:M:/>cf>+xUW/[ũJߜKp7,--9wg.ߏukWShQ~5b˦9t{|ɷD_];ٳ011ɶV1c:~>{ؽs;}V)ɬ?gbǻ eHzuGZ5[._0}TOJNSSvئ}5kkJ… ׊elߺ> 8@ݖ̪N...lڸ:ujϗ+ФIc lXzתU];i|hѼk/٣J.4ʒ`'&&G1˒| ..K!5ZѬxx4Ͷ틙M<ģ9ƘkXYYѴYs5 )1!Uݨ^hE̳㞌0TffTf_-طo?L4Cģ9m۵a4{ov3:)P+]Y89:2ױ [2h׫'N`ر4kђ3Q*=vEdhSgxraOD& 12RLA%.^LBB|2+/o~ҭKgllLkmmE՟R߸MYs3ѢAGU>o_sgr"I8vg0qolڸVՙaZZŸ| i<ĝ;wr( N3&6ָ&$$g'lX^=VYiIYz~M9|Ed=Z5kdGk/ ""OVRRRڳ-Zyc)Rq J*/^f͚z]dddSR[ǂop) 5&}: yHtT4K"Y">Z5 ((Xq&ךtƵiӪ~x񷥅Oi/V7< ǐym۱Gʕٰf닑f -eKXje˶Y)wq\-o>Uͭ }aޢE=qH&D1hzeE,]_}Yкm ybtXxx! IIF;B(bŋqڵlggWPkѦu+4nv ܽ{ozO^xmۙ3w9[;vdL4qZ J[.\x^אָ>uw~dǣbmevvv8dfÇ_yYvj5^{|C5ep? i#"#qpx1I޽|?G\\6y *Ʃ@{Vqi\|J/#HIHJLb܄ɘ3u.]$xvy6ys8wNƝ ICIII,^ݺRDq?x?""5=NĄƏo;wߧN؈ D0:4},Zc?A8l8 UdY/iJ?4 nߺMݺuh֬v <<8TRyev=_zGDPЮ6tcyoe>9g\Plڹ4tVVVĐO#k;83мyv^TY[,_gYs?1OPPH.D.N=/_/nuAT| i9J5;zvлcNiXd WDcyN/詵ǗokԖ"Rs45<!00 d[S|9MnnU(WV;vuTꆷ7n"8}5"-z:yʗه ҨaGPT)4isFҥֵKeɑEhw-\rrZƖM'u6Ǐxb/yo+lmSw8xZ1V '}.sW>W_p&x#M>J~ߑ j5 i7>&Lg >rDv1k˗.&41lڼEc̙ǤI'g;o>#G̞ݻʊbZ)R30)ۺ>rٽs<|V>> 4i*bc9t`0r/[grf͝RiȰLtL ffUWVóT*+/9.ex>qB!h0|P100 >>Fjޏ)B}#i!h_??lllHJJʳ+z !/-Fחx᝿ 7"2B!hB1ilyM S7BniB!'y,&&{%!UDEjޓMCwʗ=zr٭[CyW#%>kXZZRvmVY˳g^+WսlȠtN XZZRB8S33:wTYA9::0bPrxŋAHӦ;`nnFRx2t9o … }XS]^{yҩg_(QG3ytj5Ŋao'(h1S'-v >>>w/W$>"I|>L;;vl344?3cii ftQ*S^香Vn֧H"""ҙHrrryпw:uZsNwvejj @BBwG5ړ'Ou035%.| Y^s}dɉ=k>zo5ۻ{V 52aJByi-~!Dޒ1hoJv)))lтi7l؀>l۲>?n,...lߺ^k7^v~ r߿waC c&5mXyFFF.\V,ca( j){vQ@t ׇ>Kppp`x{Q9/WWW.^{9/ɏCӨQC#^iҸ...?ަ3kv6nXGŊ4nݲΝ:{vn?_ojժK|hRS _ pխ%3$&&Rݻ(٦PoA5mG>uyoޚ@,nUۧ["hoU6G&IchhL?_ƌqS ;aLݯP@"EG36nƒ|+M~{xӢUkZjôߧ3dl_2r/x4oɠ!C_f7o2e4LȡGhќӰay4c;? _ǎaƍ\H} @_ѬEKj>5md uiz̝7ߧիLM IDATwh}(K ޽h4oي~F9CgldDfMsx4gժ8dt1-^  L2Mbdԙ.QJ\t,ӽx*ʖ.EF 46:)S$ŋ{MM4׏ƍb`899PhΞ=#=Ν?EiiWu}z3"Ν?B&[M 4UaC8COk" ?ݻwۻ/CUנVQT?~"E4n/*B\)ժU>"EP|98ARpppKԬ4}Lʕ-3c4d9NWE)[ s'99#ʳGSkw˖$P'47ot}9z": fzFFc܄f-;zqjڴj^mia'a+ k5 co+Z(55K+}jre-ZU+8L?A('(H>V 5m߾$?T3;Wys[}V7*Ӈyq\@!AyNƠ%O3.US&}>4> ֶ'OhNNNPfaaѣ([,7n 99YӒ;;;=UT*~_k{x֮[OÇ1p툍%...G8::(s{]}1s199啻0Vjլ/#Iσ""#qp}#..LʊAO>[ܼuzujm^L6#C:KխCxx ŻܹO?AA hB9|ÌqsneeEڵ!'X|zԙ111թ:u븓'OQ|y*WN-`A[5l!ݭ[A~i{_FwL% @RRv-ܻ͛w޽^Lkŵpk/4]ʭZVtiu899Rȋh…)W,W]יInݺc)^fQ544XxyJy Ӡ^]>|:H/2*sqQ"'(HLFH fT2v/.\( 3} &3g֟DEE¥˗P_W֦M3{;mV&&&&߿ϤSgjOٵۋbEfH;tOu,#66FuPX1~1 u=vÇ;>gUuNKe˖l?&`zz!P@Zh!NВcr.뤻S~?ĭNw{wɒzҶ̮E<148nQX!"N<+_ ضc/㑇E^Lr>gy&&a;'H֮Y˾(!-54 ,+XK~{ùE|| ~ӻ''p?AVACcSC_w-Z?ox_/OYo``+햛q 7OY m8㒳u2a]k˫a޽!׫kO###!o,")) F7|HLLÏ<qArr2"˲HJLĈr/.. vCA@Tl6GD;㐔3-бy ˲HHH(E_={\0 bccqL&Sum-`l|<7I իq;ٛIș$ܶOuu5<r=z̄#JKt8 /ې(Hᑑ֝NCj5n[q9L q(J;Q~sBșh?)rra2͛7?Eن4!hܷ}5j5bcc%Bșhg$'h;B!3ɜ q*J#n{P_4$BYmygٿ8>9xz., cØUV_/7oą^0?%h(Dx{א X^Udi/|*Y^vi |PjUXaY/<|]?Xf3j5VZ9K+^ϕT`Y999((ȟl:#_ o$'Oih|!666aT6kM{^?/| ۷Ѿ yA< x7COW49|)Oe2o{Ï|'^vmYXbE偮a~'|{ 8^s5[?yFfz=[f3kV#u (//bD3N222g~硎]Z8T*X>sZeY|Ӎ ȲMy٧NV;y|1,0Hj>L/66VvYV#==;wnj ;)islܴ&|akWx[r FTBTDa4a4?x_8{Í/djHҊn, FB~޹kS֓fo~;ql dկ˲A#..U*3]?'OMze]oSEZ<Эݎ)ʀy(+v ">HaM'Ob]oG!z2[h2YW^SO?K.}pk?xp5b`p^s57t:1>>n?q3Owŕ_xG?nя(..#=\.[>ګxp -- _8xAddd@Pͷc?1RVVg~9T/7uT.Y;IX]?.<cM}STXG[[;wM =w t:bbbPq(ciiiؼ] k3>r?Vă=w7n 7ᖃ[o>:>iݛn9~_w˖-k.-7L0.tyӔ2b TV.Uظi3|JV'w݉.nCCW@\+뮃E75?wSʚyttʹggg݋Eݸ >0j5~tmذaDQsu된^??kVW#&&|i appׯ^qo~+](>9lݺRY⑇BJJ .'yY|} -7}455|1\p&GjZ߁bZ8zjr~~t~w8x~~?V\K.,DQ…x'‹ӟq^p5׀90~ӻqםwU;ooO@)eκcp`dĈ ګx7i{())Abb"x!O\{vsΩW/ 0 7G}_`ɧǤ$\pœO%j<ȣ`Y< mO?,T*zq n;x`֭_xshjj¦l˲̔'2PLfcRRR#…Çᦛo-+9QAyW\U\}͵:E +yw#p8\x%p\/3z$&$EVf/Q!vރOE'=v)xYNNJ{AȑXfʹ X|ΩA__?Fͣ(.*@| pܶuN8L&3LoGnN p!]#?e=>p#X9hnnA{{;?<eKT}N9P]/"‹>- DQ<=l6~I7Hq׿fd.;nDOO ۶}/(h,Y(<xf)wI8e-/7 JJrvcdɹ_{Ar}&ox;@+Jiֆ̬iiGcc֮ynERP\\?)v/jX$Թʞ={li%xNJӃ;v`u&_ڵg~$z;J`7. }}ҋFrxp% ##FĀeoz:dfzRٷ B&5 2|KII8&,iДctxOAp7SwpXG,>^臷K 99u\ϱyn:] > K˛=fOO_ Ɵ\9xwp%୷'q&U~1dRH<=zz{}*H,`JCLHK;`K_뇺f)w$ܲK8&&&,KMMo  LvbtJ ۧlD~eӰ2 A"<4 DYt%D=A?PZ`EEE>scN8xwq?cie%|Tol$ñcaoLX&BΓ$gjJ| _FG@z qd x',t/؍##RzId72b˲GwTXn_c@K^FFF׋xqfg F ӟs׮!7B͛7~p;ׇLF$O1ZSny7:: N'}~?bAjjRS6qxKW/͟)wL܅[&3bbbVa|a4"U3li`ϦHlzH@?q||q\NxuA0@?V{e8p˭z\p ojop8fLG\\ǧ>d3Y5afx}%\ccc>CNY٧{}|L~s=_09_6hii7("Xd1JyÆ aoߎ"\pmӡ8yquJ7_n1$%'SyGGGdI](]p׮_:(y*mꫮp7m~^rcVXXL9 hT*վe-53r'Wּ:wM7uA.˲ g{"֝S#QRR]v Nʿ)<}OO/VzP(|iZ8e&޳]t!N'Z v܅kw ]([}^vTOhZh4@jYhoovLd:h;wFGg}-r inl~}]?(^2rse6K_%m[>oAXw{.ʗo^wޅضClzmk()qRٌ?O^}e'? ?7Obb«3y};x7OV_߀Fx p&T9z_7|+/O= 1ZMx7j uL {qX|xF/l߾/_K/7^= ~N n>'^zy<RϤG8LNyEwy'Ωl!|_|gMx7qWwi=s.>3!8(3dz7A/_bcc!B!; Tf#݇jF'_yG||ܔyNjj YVB]3;/11 L4 xXI4?> ?䟜\)xqW RRPQQ_Q3 0Ma!$c3ͣ< nG_Y+g\9h.C%feplBLu Vuvgtz>8poN~DQc&7+/o68͛P y/ἔȟg2>MX,S&[^,KsB\3;),paᑑ?qxdO?~ۭw?Try.BD.'t:;UU΂Y IDATƝw4ydNhO݈B"+XF <}:!yߘ0>Վ=o|FișeNhہ'nwX[DqF!^~?2ۢٻЀo]uui@ ߜ}fa>M{zB#pB>-C!2PB!d!B-h!BV4B!yhB! 5!BjB!3@#BgF!2P$66iiRh:0 e˖ /7Gv‚|dggF+WVAVx?(.*BDgh9!ds J GaX:4Y9Yﳲ2'PD!VT`Xfy " 愐!LV!== jfEg=1ރ8A8 rNZ 23}h1-gN@ro `x74=z "NF|''% ˀ Mُ\"== eY4`Y Gc||E go-.]AHǩ\R!0z{dcj(/[R Ap9Yط@KAaa>ǣ]&{pGGǠӥ 11ͭ1F- !G 4BfnА,BgG >7B͎ƦfX,,eK UC 0HMա8y,N!r#jUE.AET,*ǒ%Pw(Ƒ(سw?DQDyy) ܊V1t)8TwV qqXZCp8́F}vEʱA@~~.8Þ! qoxTJ.(F}}#&3j-] P*(++E}C#QƢR1]zERq%=jhЀ4OZ844[YY FFFPQQ95xllZʕUf0((Gk[7 愐A/ r46@WW7Pj923ҥe byj6T6M\.AmZOmdxLf3F066كe2,ɹZTGFѨj`6({#Z'8\.4\Cww44i&%N3%%=RõgƓ Od6]J;HNNnBL(nw 1!aʾb@E*].384X?IT=Gp:jĠdFooϾv;N'J%8JM& 愐A=h&@JJ2JK`w80<<.y;pj48N(WkiiCVVpCzNg.e!W~UJ%Ruc p,xũR*a6;4 r3 ns~癟T=, N'8ɳli4'jr d2#66F ee ph=QҰ%"{Ӈt,X{jO7Én"tBTab"λ,8NjEMO N'l6;}>A6'; <ϣvoLzwcؕJϢA8b9Ŧh j8211W{P#,{~JsB!NBfZV{gqq˲`FjZ$&?ٯ(04i& ͖7 HÕ.JgR(deeH07b4!33]j xǛo|䰤BN"-ҠRT,Xz0̔Xm6i1MyzbZZL_ϛ[jާaHҜ2;YR va<كɞ=XZvN}!xJ~^.`;P(::PR\Uts<{ucǪUl8[!WR+r!ݨo8. uttlVW-`ppV!9xl6N n!iΞ@CqJCơSzmo_?W,ʕU`'ۻPZZT0yldo`p9YP5oFydff0+?OriGmLNsr3#} !G4Ӝ=@#3@zZSp:yO}"jBmP(x١UBفhrE1*!@ BgF!2PB!d!BmSRRvZ{HOOrd矇FbÆ Ύ~TWWeLNL?OXEEE֯_y֙ν&t8sFT/ 2eeeCYYjjjrʨ6xfFjokkle9刏kSHOGbbbرB1lEE:;;}v E9Pt:ӱw^deeIekT*pwZiNL?O222;w 3:ik"N7ϊklݍ`غu+l6VXӈ&21r}x U eY,<;BqFpp\a,X ;pV\ddV.`gZbbb+SּKP%ps`EʾyػwO/Tm+YrP__dff aѢEt&=zN+V@__J(J, ٌ)ןD||HZD9rVJի!"݋ddeev~-Z͆V$%% @Pd2iZVV4ǏG?t:.\(8~Y|9l"Q}}=***V}vl6Q^^Qp8`6}#665k`||FAee%j5XEOO?.dٓ:!!!<ϣ. 8rsޖ.] шNwwjkk166s}}ѢEHMMcǤy8z(IN$Ԡ8G_v:R&o2GŒ%KVvގ||ARՅi[fffT˜QnWRR0 ^ E. 4 p ,^;vZYSTZaٰwް+7y u* j`n{=vnn. ! :::d555 "8BݣY@A`4(..غu+DQDee%,X Z-X֭[P(PSSr0 ##eeeReYddd`Νp\GYYv!qlA` XAFFzzzձl8r,V^tȦѣGvP(<yDQDmm-.ٳG=Iy?m,M.isIgb V(=QRRV;\#'>ݎ&LԛJJBYY;*]p/*jr.&{Py??3)2Bڰaݻc{}y 3t㿿P~ nJZ2l٠RySMbdffb||cH}9Q3oW38,^h0ٕ)]gBEttt999\HpjJC΁(n$=4x*CZL ?=y:?.ҷtH9Bبp8PT>=`qŲ59%%>Cta t먙my'N,Zo(FZf"<#к5ӭ"͇A "99˖-b ylÁ&\:^G][Y=ĩV+V`hhHA__aݥ:''''   yjEJJJDYV0 #u#T*'BA ´*5ϐ( 9<ӈSRfZfY6oi #>>^JR/gbbX`Ol3/Պd)^(h>)ޤX,LLL???_&33 h4bbHo1  s'CaxC7\t먙m}}}vh+3. J'="yk[EfB= (][YكVZZRnLLLf,ZׯB@{{4#'Oq9attt5q TVVsυFooOLbu:hooǪU`p8>Z[[b l6)i`qС]RRdv(J8qN3dvuuaɒ%@[[z{{QWW J!vq ,YYYY`'ODRRRqZV444Jjf?:,^w\.Xő#Gd{\"1uvvbX~=A`鋙vӽ"l6sΑm`…8srv}z=Ja k0011rh4ooӭfZ "66W>oG\1źu`ZgϞi]WG{tHAף6 JA*m2rJ 4s?{C][SR8GU˰wސt0<*/ƱO^ET8Rw,7woGPڎ)s4eJrJT*iP(f#r:q e&S(p\h>)֭[zFlGa>)J\.$%%՟ lqqqdΣ@IӑGI.@3<>:&¡hɒ%ȘֶyyyXn֭[VlzsƼQ]]=`YX~=Knn.6l؀OqHIIxrXsz̹PZZ|@JJ O9)Q"-))ALL VnDJ<yviZ,Xv霅\p80LsiA0::pJq7##عsgTn:ػw/.\ła:,Xۍ᰷IJJBBB8Q<בV>9:^tjD[[۔er{bb >ǿ x+ݎ{MHKK #P9gN.`eP*ӌ3ك6 `…HMM 8G`@nn. ! ::: aPUUxӉ:v[0Y{( QrpaAѠ 'Nŋp8cǎ).X999p0S*` @VcAKK t:.\a0 ?.5bkjjP__ jl߾EEEHMMR˲8vT<=z4d|II rss!fݍL$&&p ??}}}GII !XECCLބ+**E}}=-Z͆Vٸb |GRyyyHLLÇRPYY V avg8h4TVVBVeYLt:pWr񔔔9ɕ+F#>AP^:ptt("!!& Gjj*N< af)X֭[P(PSSraؿup8, ))hS⌍^) l6( y8nł"h4nvi_8111P'O"##C|333J>## 0͈*]eJMME__l6`hhPaZt: A`ِ,17nppP3Om111!핎788sv3g||(BtJy8477CE(5$]'&&t0 #iZI * & :Nb`0F#A@ww7DQ 0R ``0Lۍq( hZl6)MCIQe*th4X,>ZRtd2Uz=&&&F 4<'X %E###RڦM9LHHtEt= Kyu^&zщ|Z=hRm߾}(**Baa!q }k׮0aEaX,T*A`2p8 ш$iORAR܌0 Rz<=,vY(*uVU".mWo]}`[[}E*"l %,dL&o\2If2Id=sϜ;s=ׇ3gٳ͕yNUgA`wזhѣ:x< t:Jîu [@6(8[JRl0LP(A2w0Rp ˥_rǩBrr4Uuu5VWF#233r$%%!>>>"BH .`z{!Ͽ3m+A+mknnfÈ#:,Tm6AT*U@:7S[,477K[ٗx8z[.+@i2l쪍sݩwڭ;[C[mm-㥡ϞӺ^ ֮s\C9ҡCJúHIIABBBpڗ7\&^lP5*khhhW\At:QZZ Q1uTM&IW+**0vXʀ/e-Ҭ^7 h4>}%zWV83gtYmv(**Baa!HwEWnoϿ&v{!Ν;ɓ'c̙gΜ ]ZZq!77>. 2e v;|>/VN#GnCTh4Jm\s n7DQ; u[YY)-z|ԩ7 \.>}ӦMɥ*gWm9n!555f7n[^^ .,O~~>RRRp8T*qq\.deeuڮ!C0k,ѣjwF999RZ|ެk_ΦtFJs;!p\X+,NbeTF!dp%cq8Xze-^C7ykoZ@NgQ3FZa$i+sH")zCGqq1*++;܁מJ V8ܡQP(u+M{S Q} s]ջRĬYsn-hBm V;tծRTd`cg &>>SNEIII~LE6- ua6ʳ_zl6$Cw$fbφBE h4Į]o8^o/p| r6 NS 8p9TC'^7#9w7}wx<2Tm;vUN'N@AAJKK.[2<꺫vVgaV;mc(//gpF~ *NDވi3O(6'OrUKMTbڴiPT8~x% wJ%LQx qر."ꩳgx2<38JA8y>zB>[bǮ%Ӊ}5@gXPRR" \>"r|ro sɢAom(<04CDD;0@#"""2 Ј 4"""((0@#"""2.7bb{ h"""D 'BE|2II'F:k"""vajޣ+qIV5uDDDDtEhDDDDQQaFDDDeEhDDDDQQ:h(j:YEł2|5kΚ(t:Ç#oć853""",Bs F 9(0@#"""2 Ј 4"""(8hR*~Uxw*x=KT2" 4"}bڻ  a7~x,{1znGDD'I223.HDtbU;~`tA-|}`ϏEEϧr"'v >߿8/RBzFz477 'LѣʇhDt}Wsrr ^_CZZ 4/F a( +`n%_Z0莅}+ugyF3 Zjo]{]w~. ?rH#%%nY=;;/ dffBP5k^xL&;o :{x% Aˡj˗^Đ!Elv^,YrL>,[_7ٖHW; 0 ЈOݱvhZK]ytwܽ^\pGƟT:#GB.cq=KPYycުwvzb̫qmE߅h]/oplQҋ@I6CRa,%l λHLH_>˱a&)?xwu7,}z`]}=~`.Uû8dgg㡇Cz}yXn=.\(//GI6̟7OJSE *+ʎAc ysbHJL#PVVC ;+GaUKϛ?=77G`9bt:<+2 Ugb)9dҹu=hD' m@zZ_z__k4lwݐdNNLi޽ ASSSa67bJ tZx^|&6lذΝ?/?3g ,{h)Ė7FV!/Ӊʑ B#70}1""%󡎋+^xq o߁lFll,^կ; { >yj[z / ,6x}>/1cHix)Pu R3nײk яYY3g܏IIIس{ K/ysUvT3 "B~Ḱ2IسgO銋JGDg/^x>s;y@r9Q_Уe2aXLrr2r:BFSkRdJ0Lk}D}a4"TUWc8/M8Wbˤr=8 c6fut!4"jY|sP[7$"" 4"x=;ٚm ^ 18#" hD@\2 NDqh%"""2 Ј 4"""((0@#"""2 Ј 4"""((0@#"""2 Ј 4"""(gqDQDVvJee@r:8_yw­gc{ `F2sra;dn H* 9C\Y!>PYϽn=ŶN8 Rb XJ >Bc=NL~lo:A# p{aaBR"rť-K?q\h2N61@#A%!)zX,.%GBb*L]"Q \KM!W ,f3Raf{#8(0@#"""2$>Zw {>o=hDDDDQ=hDD{4n[>/AuMMbFH?:~}55^;&&r{H/Η'zS&!%%nx Ə:U^>hllDuuu%jm?,VGھ̞}5JJvT*$&&vݴZ"wu8IKOOüs0uHH־t6lh#/##EEHJNq* 8t !CHJ%t:]Ts5j2331vX1{ld~)So뻪_52mzz:N .:kRD*k7؃F=s@7@z:#^_[2 >^rn;[)rBlh23a0"33 <Ӧ.AL&FǎCAZm*50vW&/{(xn/ qqqR{JV6 fGEll,v;@ Z F]U 6'NV|kDQv(_&ۺkҷ Nхڥ PT8J(d#zHOOCJJ2DADbbd2Qv7$7CJ__?Նd A!@Ei iSp .ȇJ޽_pD|SB|< **Naڴ)gzzt0$7zg++1nX:u twߗP((,DQDuM **N#=- yy!RSP[[iz(SSt:-p * 7=PUU3f >>ЀR1/Rwƌ]vcAڼr-sreGƎ)BCc#v;G=^dc}ߠ2AIDAT 򑚒χ&GIm;o0degd傩 5ƎA|^neeGaZj@Tݰ@n}Q#v=Z QqCM =- eGQrLrt:- Zh҃X,P*p:P*(*ÇdB|&N v ˎb_p,gdfFoԄ4PCCހ; χ"';{쓾 a4qr9&Ofzj ǎ* 7'O¡CeHak`Q b̘10d8}4N:BQFA.'O9`Νx>}FĐ!(/?@E03EǍ (wD;;.{FQbB!#6&1*nKn7LMMt tRSS`w8rVp8({gQN&җ!HzqdE(8qBA}Cj5*LMMHNIohhz/fCEEd2].V+ 1e=4ZZnx;.TU2$&%Ӑ?rĖ!`|>zLզߖtiGll,h2IKB7H=FcVk@fd2p"FuqȾ}i<'SUśAK{4HqtZ  ÁظX.8ZV>O%T*:LTBTb<5[_r]r 'P(lק9 R |>< }I?꺵m{}V+Ο?/m2;ۧ2 w}oQ4]khlDCc#j5Fa8Yqk6US&xZV -?*%22ҡi-mZTl p8.~fjʇ lzڶOR08aw Ш.M(p4~}-svƌ) LbrCp+ݎXY]fF*NX^cȀ|2|. 8\v$랦Vɰ˃AcwF#rrrx`Zh`2df%XyiU5jSjjsbj65\}stٳxӋBfQ#Q__3g+YitA&CE'm~S'7zlt36leln(@&( \nqHNJm3"#= 11*>)ﺺ:jR(7R7_Cx aۤUUHKӵ9 |jlA ˠT*vZwNg,L6 8x4mv F;χ\.Gmm-1vXL0AoS]A$&&ϩ)07v45rZ/_SS4$%%BoKjk1ti_Abcmi:(r>$$C1_L2|/oFzZ }Fp\8w-/Gaa!2ohtNC/V>IسgO銋JGcVT(AsD{S7)..Wa>y=h<Osx}= !;Ap_Ob\zZuvhw 2v^ 7^`tq w> op~pg{o I^MP`„r 'OVf4:suԂ :V v7N-7@e6 4dH{Jur:>AzPHlo߿8hPi2mzp\hjy ^ s`F4pqt:}GݣRptds[6p4Pu2srѨ(@s Lzp.uAQu|1Bó;Mzp6ubF>zF4p%"""2 Ј 4"""((D<@X,iuΖ(thnD<߈YVV1c7"/YEf G<߈h>e#_P"""EhDDDDQQaFDDDeEhDDDDQQ ;@X"""ҥ`XN/PPP0 길rdXQ~X~CyyQpQaFDDDeEhDDDDQQaFDDDeEA#"K-,F J JiL0.\FE!30aL!JA&ʺL!N""ZapFt 5j_XOdFDDDW EhDDz"n\g Ј 4"""(e6>s]b_cA#"""2A#".ח8ev<B 2feI8i^w]Gy_yӦN2/Lbr-HII$e&/"uݜ9xW#WWV.&N'Ǣ؃FDDw><ӟ_+ NVނ\.ǑLpz}X⾕Bbj#WWӡRX,55SLMx Ј(bݷ111!\{Pk4X`<@.wbcca"S64 , |=Yt) ;wKH5 ~?Ǧ#o|Cbbbҋ/͛qF\R=}f |A_oق_{ ӧO'kի͘0aBXXh6_իWcg3ַc[MO~V~֭úknZv^=hDD-z[O#ػwoo Ӊg[Vm;A3^zeX,o_yT,_>(ڿEEExwQZZ*Kض};VXZ+V@TJ9t0w睨Gff&|1>#\p ?я|r,k N:xMmAꫯ+qFYpBv0;e\|M7 >ChOx~ۨJB|||>snzU<#_B'R9s 11#<䓸kb444?1vJ%5>smy>yذaF#)9?T6^؃FDDg=Y,w}_~_z }!&O,mEVVf38umqb$(Jl߾fBUu5LMM9r$N'55:u*rrr0j(R>򮩩Acc#t:4 Ѧ\v† o`ݺu;v3aHJJȑ#qa :B^~ @ss8<xdeeph4v3gq&|>XVX,i??P{v|999Æ>N'|>y݀r͟7%۶aȐ!WcFKVW& ؼy3{vFVK'<πms9sSMܹs!pi/ :cERa!ӄۻ܌x뭷{ʕasϡ`(^7pִwݺuptЦ'VԠ:fY! ߇. 7܀SNjxB/Txm::YYYk{(̋ !%Kpo|{˗6 mj*55A6sݐd]Mm: yjq76w ׶MPx os`YY۟g{ׯf}ދGÛobAw4""`AX8kr? /cܹRzN 6G=L̙3KP__*?PCB@Tt@0`iXp!nf455fϞn>RB(b…^pAZgMPn n2m6<ӟܹslۆ#G{PT8w*++h";J2 j8N믿^;p#990~x&ظi,XÇK 6,tr9 ?ts$'%u,Ν=z4*K:I^Oꦭm۶?-vl߸i#!!mPٌ6snn. z:u4""=L3e,[ nIzc\/Ao?~OO>ŨO?EA`ܸqΝ8s 6_Պ ۷o<0~7$6~yÇރbZ_IJe0X=Il6111I=<}Yi|LL /k֬X6Iݴo7_-}ݎ8N)+`ƍhllD||x^|4K@AL[ ~Q4"""((0@#"""2 Ј 4"""(A_IENDB`RaySession-0.12.2/manual/fr/images/ray_hack_lancement.png000066400000000000000000000566451417052567600233760ustar00rootroot00000000000000PNG  IHDRGyܗ pHYs+ IDATxu|Uϭ]f OAaHw7 4 H#)%m t;F 锱 ֝u{~߯}=9s|U,C!B|B!'H!" B!2H!"J%^^^X[[!Bmbcc @k~QpUƋ >yVN!Wٲ\fԭfH! O+++HII1:篇NVV$%' ӧO֣rV133#...g0EzǏA!{^f`dۉ^j}Lnӧ0BztJ>(`Aw~X~طsfJbQ۳ pp^V࣏ڳgN֬ZC+FߴI~\H_fժضױgN4ny#W-7{N\]]ֵ {wc|oeV6o\OYt [6oჴoV^ݺnʖ9t`5K~۶}oۂcxxxlľ=VMك];}ٹc;kW`Aw`aa8v|ټRZfy۳>ظ~Ŋ5:~zz8 bN_~'B@QTVGy#-GrNaopww?dʤI\x/GT2~ƍ͠!CP=>4#)) 133c!m<T*%3 L2ACrʰt\tǘi43þ֭[;~lLvZlݖ/G\J՘1}}WinΖ£@|۷kKpH>HB>u ◥˰e_vz V}P(pww@Ho%{ (\0oBޭ+L36H4lܔH_".t:F}3ݺ1vxGJr2}~A:%OyU?_@RKNNF[뒟uIѿ\DDZkk twK~AӑO?Bjj ΎO:uښpHIIGݫ' ӧOʪQg$%&￯OU[,["We6HKKsp*N 'GGH(A_*GIҥ8g8;;sx{{g{=޻GV-ywt>6*3!tq? 6y]ԯeˉa:õkװ"E y5B䵥&>>>|ȭ[q:wѯ_?vܙmP||[FZ ?uS .Ltt`J%<|?^عc>[`"RRRѳ7z`ͪ9s3f܄qtt䫡Cۂ pfY?x05;?x@XX8J!_ 39:둚o+WjڷkǢ]aaپNNy:ߨ(qoF :|uUBYnbcc uѾ}{4]t/?~l۶epB;ɓ28E̞=3f0}tqssӏVc(Vd=F 0k׮ӭk }S8|III8(- ZM"]:qq?~{{{r=gԯ_OM?]OOO:饝;<)HBB&y FI3u%CBp޽{ܺu?xZ''lGbEHKKcaax9IN( GXXXcSZ-͚6UB񼜺?&$$d`dɒLv f@bb]D:.yUbbx^jj*qqqY\%%%`SV#99\5f:$!>lOKKu]"+3_Օ =zJ2FѰcZm;ʞ}d̑B!ejOZZ`4i:%KҮ];C hݺuz+\]݈4kP^0u1GB!Ȗh̘>}zYr%j wNHHA-[RX~}y.[͛3jh>|H"_YBA&s]?H!90о}{T*oOfetYwQZ5n߾m2MpN֩SrddB!^ SFJJ ku`0{l}`c_1)S&Ǽ+T۷_ B烣t:իW(>SRRrUFҥ9rK"B!ejvF%-GVVVTPslWT?˗UNNܽ{^Hf !"[KNNޞ<=zmoBسgNNN&mРe˖U˗#))zׁx䕴 !"[ϷexpΥ'^7B2ex.!Ŀ^^^dHTP(8v۷w .$,, ZjEժUZ6.??vڅC⍠j%0B,#hwJFg *˗IIIÇ,YQF2`|}7S?sWr$BlXhNi߾=%KsӦMJ*ԯ_s/Ɍ3֖5kBpp0O>})Ա׬UZ++l2{{{^J.VV8;;0@ >҅PΟ?2077;+*T 111o"Xl9w!::666-Zz I&OII(JT*_B f6nVD A&j,,,U~E INN60t7Eeѯz[m.^˗DRR ,0Y_ss 3_$>tfff( M|T*oS:(}||<ӦM̙3vpâE)W<<τnGEI"Q(T*e$%%V*TeKosu%FJWgV+#Fj/;|Y~=Uz͈jT*%sN]@M䈯iؠ>+UA Z5 iSkuB)8:~8sJdGѫJTJ#wF>7<5sG?Z fdzq0-ZŊ1^=ⓓp"6n$6!A$߬tR4iXIBB0{?;t{İ~6e2 xya钟x/aDFFLZZj sZAVq&OƈhѪ~WinΖ٢+_<ȯ˗rM':gvxz "ܹ8wݺuEaoo˗};BCC)X vacO|lŋؽ{FN0gl#׫O@ޟ1b׸0oFΝi/^ŋ`o@*޴jقXzɨѣi1s,Ν=GQ*L2I'/TUUIII(P=JrXj%۶m{k* N:ۛo6RSe^ޞG燃v[oKNX .\OVÇh4}2ȀYbŨQagk ̘߮>֭Z1vxt:5W ",^$yhPK-'22'OnDDXDDD(0GN?j֬iONu[,["u.RK9P?&<<Z-ḹ竜WhѢU6wa糩qqqsqq%K:e2ǎ3sug_ +WEHMMe…ԬY cooOnjBd5ʕ+̘14`^&ةT%%HIa7_{MKJmM_ooPە嘣%,eu\ GGG:D.((H?F@gZ~ч&s±F+~7H44+϶ʩ/31&0p -Z[jQdɒ|$5g;q~5l<2/9MNNȘ!(1Jfi 80ёZh2˩/[DxZ-x{ө'4_(ԩ2Ǝ#Yp!>AGDz{Y31`ΜiӺ Mg:44nnnt:Ӄk׮1/`ŋO!^LJ2ХjVʝQeRSS_tT*~Ạ;u숝NbʤIh4=gԯעZ8t]?gS |DҥSdI}8(VV$%&>#IF.  aժ@7رFS3'r ܾ}ҷo_6GG'ILL$!!͛cgg2Llllh٪~#G(EJ!`  6_υ 6}z޻wWһg@zgsqttҟˣGe쟕M…uBaԴ)$R9{ ,ӕg r7?W 9z8I=?r< IDATIMMeÆԪY/c6|ߌþ !!ݺs2a8CLL hՆ#GJ۷FPpїpW`>ܻۈ }.پ×>jψñonv4:ǐ'9Uݻk֮Z1p|7c&:t 5-3q޽ˁ̙>t(_exNLPT\5Ç5S/innɓlǸcٴهzs,s̜5vۣT*ʨoF[EX"##PԄ>}Xr%3g͢IOlݲ%_,1e닻Ma+^e3}bbe \9̲@1)V\Bȳ\6ވJX{ AqqGiIR,eVreN:īP(pp'%%E학GD4f e5X֖d}׍)))#>>>Es3i3=rڿ'4t]ۧ!cNFPPsH_KPMJ EagggARao@bbѹT* (B 6y}6a`ذa^&$2iV\frnnnЄ>?tcY^4S症ի<ci9zCt:² b54)XLAE" \gHo)0 SyEDD+/''gn\mV/,>+ty !^.PYwN#((266YM<5wdhgϬ>0A.eyܪ;w(nkK,ZJPښLs$s:tCo뮎Bv_ˤLrr2n ?!11B |uv ЙX>{@tۏe1L~w/?ѾRZ-33l$ xtI !i.^px;e:U^3y>n@f=4 u֡GA\e5ҸIwkװDɒݳ#GϣTR,Znz)\>}>ק[.'LAzYo'QvmNƖʗcܾ}Mгg/nܸOehժ5njĉ(PU,?k׮TR,[7n)o/;w2d0+O^9uʟY3gAh4&MLut" :;w0pDFFиI 7#GY_E݌ԪY#kxZ ))I}ۿ6跩j.ZȃԱA>jժ2ױCGĊnt}n$66Vn„ DGGg[rssYYHB-_;!reuu?`N&Yӳ{Wʗ{}C5YmLh7I^._m8x6BߞQ*h4ӧO֣Q>VVV$%%bNZ,[YYYMN,333Df kkkbbb +ZK/:CMyR2yXZZoq1}pkT* 6.dyYo^DѰrjmA8p7W7j>K wRf--V@ݻyOs8 e.PV'$XVV,--INNlmmMbbbRdlH+w)wv>Hѷ 55O;®;_W;'<<7N@ҥ9A=;uiSsuT^{bR˾=ٴan:|5tuaW_k/5zM,,,Hˎ[Yn ^^eruֵ {wJ-7o.Or1fϞŃM ;.WW͛`EDFFRzuY/ 7oZƍL erNKKC2XOixWTҡcG/Z>m* 40.<ϩS3&W|)֭;K6]ٽˏ]hӶ=PF *VH\\,x=sg^:́8{{n!;~ߝ;9v wg7nܘcQH>€]!koӠGn۰ WZS'M`ӺUԮ}xF]&]|J>zZjӎ7 ggg6nJz yBn]P(oTc)>r ӲUkԩMAZfJj4T*2[9J iٺ *g&3svvfwYp1jԢVz8p)&ǵkԩ׀Ÿ1 KF hQ7lo䫡7ۅ}/۷Q;~JYȘqנ!C}M?W* j F Sl՚6m緋&͚ӤY f̜!9k6͜I&MٻokһWOUMQn}֮[9_;;~~^\~_.p"Fye,ٳo}[n]v}˖-X]_~9ٳge[Ǐcld}\]]iѢQDKaA vׯϤSx=GWW7pѾk׮_-vD>Zuf)o_e)Y|A%|}}ٶu+-[ҷ|e$M5okӶ-6mB4ηzkجYs֭W={iOxb5loھm;uԦNL2#GԩS{j`ܹ,B>Mn[,[b':x[[[6m̤SէyR%ǟfH^W۵oϖg]Y۷mF͚ ,\sf¾-u|5t-g^:|;/HZ`|ѧWz3jhiݪ% lO?/Y󬬭Zɓ'Ln:cǍfZ͂jtd6mr!|2Ԫ] Bg[I?++j׮ÎMVXQ k֪iƍe7nɓ'[nQQB8:~Ԯߘו9iR?qAoHw}RSpuq%:&gggt:ػ K ֮S 4(͍ocutm3U׌m R'Ϝ[Eq,իPbE}}Ϝ;Ͼt-:uߌ?75Hщ+Wgxq ))):;;ƀ _tIG?,S1`ё`..DG`J%4Of:\w#9;;b-$$ln^n">}Ǝdܾ}<4pqq!8ZiV~7Yl)+Wfů+ի f q*'NDɒ;3gN-T+Wt{^PմlيK`Æ <˖>iiilڸM7RNfΚMpp0gq{SD ;SfΘĉ߲h"ڴimGXhwuu%""`JآM7ҬYs6k\3$&&2fh~'Kj 6mjmh׶Qy&LH%xw?yL}fϙ#''g.LkZ&MBҥyy&ZGV,kLHb/^,=Hy)խoPnQN|/0%gѱi|֫A+W8(o'O RRSsS3(Y GT2aGnZcff$mkWP#"#qvr4`@ :LT~P{%_iiFzfֵ˧Ѻm;t:fqqvͿf,8=h4t:G>K͛7y& 6d|3r$m۵c=YP>pcN(55>s+++N9kwxDֆ=(1vNKDDDT=nb$Us[Y&xL_s KKK=sV[|||h׮= rĉ,h41ЮݺQT)GVk1e|Y[kBӡRއB)<ĵki%111B 9},|IGo{ѣ@-R4ml8qP+ߢ_<|ݻwգlmmm+wyeΝ~c鋟vаGU w;۶lg\h׶M̩9=zq?~,{Ԩ^ _Jٵ=pvvbiy>WS3e4̛VM,G~~dd$?.gF~X]9q&J.Ͷ-ٶŇ[o]O?̦ ix&Ģ?ʞ]~nJ]:|EU矽P[h׮˖-',Z ǘ j.]'Y~+V,7^F .^,Gj5SL9~$G%8$й=w8{<+o+qsscTܷw/Gbps3w|V!sXb93L0^?ΎyQڍ7Ҧm[?^ѣGlٺ%Vk\wM_4/PF_۶mc֭lݶCpa ,5*={ٽg/7o$:;!^?HoTumKZU.XZZ{êڽd:)gвy3֮\aϿ,vmXb).7Xag܄ɔ*Y>XWVXJbE_|zՒ֋zM!eym`WK넆R 㗥ÛYe{NMMu{}iii/={WN{6?IDATO^F;|1^E966`]>+/QTlٺh{JLmKNN6v:|? 񲽌`'t:aa/}vHj5͛63DenzgG}C…#vb_U[ҼY !OX{54nH ֆ[n3]-չKW,,,j[Q!x,~[[bbbj  !0# }9{)SB!D !)_#!BLd̑x#AG9'Bѹv.Go !UxyQګ뮊BDp5?ɉ'Od]3ёٯ< Aq5 uWC!䉓To{Uωɓ(P BIk@1ܐH!,^/yB!2H!" B!2H!" B!2H!"/J2ej_wUBAbbcp.kLIp$eʔ?~" yVoV+B< zm{$8B!D#!BL$8B!D#!BL$8B!D#!BL$8B!D*T7WWΞ;"WWW<<<8<ժUw1^mM" D4 *UJQ%HEjIh)׾^ص-Y%؉-x6!QDB6YDdnjBouu%g9sgs>KNN?g\֯_Or})ܜ͛PPP@JJ V;w+۷IMMU+׶m;_FzzV9͚5dRRR4sssIL#NGRR+ŴmێWEdddpmWldffr=T^TJ}6wޞ8{ZM4!&& R]vGi+lUH^ziom۶#//^knݺ)fffǗ&Oԇl۶ubذԫ_ysj /ZU5.-\035#%5K/RPP 7oBzxZ+Zq_ڵ133#!!P }}u;@ll,M+߸qH&&&j kkrrrHHΝ;wJN%sBtO=Uk]rhԨ GYc *A|'}Wz{}1^ZuJqqqaԨ| VY׀`ooψѥkjծE|\<{ԯ \A.Sё/I'''֭__ݺc~&ڵ+fϡGn:9m4C``f``uksV‚EѢEK)M'((60l~7 1c4LYr}&rnݢVNݺ?|_|&RNp`aaAuZ]&ѯ_zzxDj8s  ɘˈGjj* 6$.7M-k׭ښ_^ifϞC@@[HQQ[?Onݺ%͝oo` $& 77W*3{l4g ϟceR96l8~~ܺu;w^:͛0bRמ|ovU"#"7111ej1xrssdɒ%|Ю]YO Q%jILzor366&//644@!055թwhtܹM4P ɓ'Z*/ 233!$'?ѣa` 0jH@l߾1c>eѢ2FXj u0...\|===&fjG;w!1& 4ё7oJy ,z)YdZKF SxѾ}{2228~gn E:'Oٯ-[6ef6l.iRQ^%XYYՕgҫWo٭Ede( )ˋaQZy]MHWt2335bbbBAAZJdk}6@i%.}С 20r9Wb`em%1b}lglҥ0|P=XNv#IIӮ]R۷o3g}aPV iӦ8ȩ'y!{aR!5֯[ay 4UX`$%%ufVgԪUC*/ƱvZ5ӬrϘ+ ٗޞ Hyz莹9;vftϾ}p#(8}zxc a o̗୷Аn=ggg&OF{wFD2v지r݂̘5 w^LȌZj`(ރݭ'?')FD˾DDFыe˿g)p[7~>4-ѧOqJ]rӲ -\+4ܼys0zH $$$e6rpаvUFΝ9ֽ{Hpp^/XmFzܹ _}5˗Ux춶naaaYwIKK-tQ~}63edǗfyV&M۷Q126b9kۖ]VZMP`Ǐ'''|?@Jssw#&&Ǐ5o%99Sl㳲b,ZkKn]iۮ#>P*+/vmء=/]d{Ύ-ocsr|H>9RQvvv9sZ}2qSn]RRR$q{=ٖ9|1>>FXAI 5{~uTR,ytSSS)@_SNqf͜?Õr\g\5`b…D>MS~ ;tڹrWF:ڨne6Wԭ (={[_CyzbaaAdD8FF*\Zθwڞ 䤦>,m֚BLP!YlllA>)}~r_呟m۶ʎvミs/~~yV.]$;{{{\]]iܸ1PncxzM~g|L&c/,-->\}CHOKήIMM姟vsYΝ;Wjʭ:}Jؿo{oaϞ=~iZ*'[Q(,]D-*--gһwNaի7"MK'vI% ([;;rXlo`ڴijJ.Μ9Pk/|=zHu^zXXM˃d}N*ܹDb zyҺ{ELMMiݺ {tҥKҳJff& gjVnu,ՋU+W<RxTEaam?w77{/r~  g_N;4mNN F*'O#UB022*WliN%'We5g >l+_ BAQQ7o&_HeJVePgΜe4qvf5ߟ͛GBٳgϞ3}}}={wٷo5j MPPWpOZ#vs*Y|wIle.ԨʕTRE_SE@###y֬^_IkݫWo_Υծs`@Z;FZ>l8uUצ=zGGGo 077ga?WLMMyXO{iLy=/XHHL6mI@~)a V~111ښ4vyhڴ)2 \N8p VnX~z?Ybr>ćaÆK}+CeD*JO!L~} H =g_&2͚5#8p?$'?^Dw<oq΃T"tEjC-ӦN㑣Šބq:4ܽ %jժqyNEk:am>c{J[q3aW,^(*#L6̺7nNǎSJQEP0\7n"55"Ν;V&? ax˗_yLUVknjV ظџ êk044T(3tPFN> >9ԭvMqss,70q$&N$]|p;] l/oo~yF}%kVK/,,$44wyTuxƏgaffFHp0v`u̝7Ν?L?3{7m"33<P(>m*8H522ܐƏg̙dggcbbœٳ Eߑͦ[qM.j*a֬ /L ?;;;fΚE῞'?+|}:mV E ҳgO&NDjXv_S.ڷoϥx\G#x:t U)/::1>$x5d8핸EZ 155}{QSJ"7^$Ud2(,,+YYYbhhHժUҩ\QjU~rHŕ?KKKt:yĉصkoL'i:uuKf322$Ceϐ+\JSffKKKҴ?===,-Vի;6Yc##233%Gcnz rrrK=Jm^}T15%996}7&%RJ(..&=tE4T xt'򢢢2ud/_{R:-s5jp #¦4FB__`[n1aW>|P#}ye:(>lz@fy}v@Z)E!Y8C:.kP8 EIg}t:ޞ$ƢjMuc,gy&N@"1`U>ZV'˲TgBFI!e0 :C,+,-B4i,vXDcqAu451<4es<../r^ f :;qdYz`q,vvp<pscjX]ۀfD "Jaaa`$DQq?ᑹ>}-u@eo / 톦899ͺ)'33> Au(JY˽ a0`P(F peYlln#9|!?/r5`b.^$NOB7p A؜N'Fa٠Ձ7o|q< vvd^\\kӄ-GV愐|$RT*p8{G8ru3VV7H$,V'!aW|(";1"rֿ8E TvSJl\!rRqd㓢M@oR) )Vadx N$1ZQ8?ՇCW26fC:Κ$goO7Z[H$PehIRWB $*#j@40>-.!){[GGA09q/_d[bRw&YVwhX,)&:a~8= rxY-M̿-+ $)OKHvuvy̿nlhpefZtrB_/1poUl}(4xqyu+<|0I᯷Jnoh"TKkFG,TUC(F2cx*L$asscP4TME4lJ208oki yo8xɉx` e>FF 󚀛4FWg޾`~^*յ  (ƐH$}ŅY:9!0op$C$My d 2pe .+8pDRT)e|m<]+ cHX"tT,\67+ 7s,JjY*6A*܍xhZe礞eNWVE"YQO!Zֲn)M6TcU*R?hO. @Y UcD"(7mmI?Yz9!o$B- ܹ@@y\]]cskkE)$B%[;م |o%Irt]/9G6OB!@I!BH$B!@I!BH$B!@I!BH$B!@I!BH$B!@I!BH$B!@I!BHU[eQzdۛ[B!VT$4E, a^```G!rn۝'Hp:WcB![PӜz4" χfp:u^?{2x V^p~~K166Vպ---O?!9=|sݍ_~uݮGWr(s²,&&&S~fDQqiI[[n7^xWf]|T6k}޽˗/C$fȁ ,y:\߷*r`ؾ-`D*TUZf`<<+u(t )<$quuUp{q\zUz$bKSfʪ܌׳*m2o/pӻŐN(JֺV[^k]khh@wweVr_N]ˌǪJ՗b9}1JYm_2n IXZZ۱0>>f"E, :;;<ϱqp]ױX,eY,//077}a0 ED"7 $*iUx}Ç!"?~ ]kx^ttt`~~>o$ [[[hnn bxeΝ;hiiprrχwe`0[\\\>~7---abbvϞ=$IYqAuȲxpD"wޙU|iDQ홟Ϙe9Uv>>>T*V,/qzzEדJ֛qdYƧOWE16p/..\.ܻwvbggߢljjȈysFU^:6ap8>Bui|p8:&''!2?^&"fff`SHׯ_u]E#W{U;T "t:0 TUūW ˲徻M vww-sss ]qU]D! 088CuLMMaxxؼ9N, `nnccc  ޾} ڂihkk訙$,6xtX8oM0< aggՅ[LWWWxo>uFv#b1$ɂd~Ʋ,DZPq혜qvvÁǏ_Of2==SlooC|@0˲ʊ9Lс6{>|@ss3>|`<@gg'*/TvOtiDYUN]]]x%$IfސxJ^Tq?bppË/zUUى<{ ޽{󘙙j'̛*7WTmUzf ys?JӃ)]v:1XUז166gϞeRUn[P82XC8]]]$ o޼pޗjϟ#H8YnV{t-BE1 7 th z8991Oq4\]]Au8(7YtZ[[kfY떊UUUQUWWWN$5S\=\__ӜPXi&ߏd2 EQri$Ihn gggfF\N'Dr "bX9D"y U"0t(4M!t]7 :ZN|V%{}{(2t}T 5Wε_HΎ!vwwuszp8؈m7Feݦ$IP(먒r_ QլQD". x f,bee%6ꚕܶqdהSyE 0f{oo]בH$000UUJd VZcz,(\Qnv0 w'f<&&&؈˂J2DQڐe9kb-V1 @CCC$ $tk5|yy|IRX]]E,+L3Q1::j~L&J_NV(bT*etnz2CMb˝/f fx*'RZ˗/}{}{qkUUrW/2cRUt(rn qJQy4.g quuYtTRn7R նQmF|1ۛD"m5+8rYki)<A~`ssGGGuo޼A?~aeeT#յeG$9N|>,,,yzڪ˘coo/A0M+z[嬷rZb8x-(nJVU ]ױ=tuus*-SYL&BML+J2'ڿ뽫%Br˓1׬*}+ޱW{=U^5qA(dY(Y=AFn$8,˚7RL[ZZݝ5\ZVPym3-כ[֙J+qn{MP! ! C"(oYM+v(~kKv;fgg׭ ̞a^3tuuU~$AOOYYsׯ%VcnrRQ|d Ø](f=iMӪjX]qzzjPL p8 ˕HvI&q,[o휝ve`ٲʠ\__ YJDkd2 kk*ըw^Oi!Hr:`hDD|au8Ǜ*UFڶAtttd f=Xՙt: ͖U\W(85նCc."p3\+IAwnE"3+v(TFŮ/ITU5vww^I8>} Y!vvv1J0 vwwf1cjj ?TUqV7o-*<|T ,jv60;; I:`R)|m "Jfa}},}ܻwmmm1p]7'TU:ݻ0 477g22fffac $I) ?t: e'˞J_=ܿO>iD"E_˯Ucztx<L?~h(nnnݻ駟Nj֓" a ,D"ӧONFo7=oնQmP. ?F:YoփU㸸'OL&իJԽv188I`D:Yl߱X <p$qg,QZC<19&YI|Z=GW(5my^JQ1F^UiwBJJ]h=be0 l6[l2(g_cHEQ{^J%\ NXs3jr{ Fͺ])eِN܌o`sުmjmیvĸy~ VuF?JJԽv,A(z۷ `&oVB1Z][,gh,%LIV"Hl}~I3jQSWK8NcXZϪLu]/E;ɴl}ƍ2TdK\Usm766Ws>GSq> )֎ԓUO5笒(T{4MؾI%6zrU$mmn`I&(W= !EGG:::aK7!ߦۀ&tZ-6sg:G!_n,52T1=R_unn.x0B_"yB!@I!BH$B!@I!BH$B!@I!BH$B!@I!BH$B!@I!BHU=eQzdۛ[B!VT$4E, ?Xx000͍#BMUΊ$bp8Ы1!B-iNRM=AZtQ޷޽{hkkjݞZZZhT=V+BBCCɤaֿl6x"w:Ɵ Y(vCebʭx<4 *n[[n7^xQC ׯq]$ (} 8;;+{f455ݻwy~{{{PU6 ^'''GʍfA4@ @to8IDATss3677o#DBj;ݶy`0h.ch|վ]nR0Ժ }[Fǁe W/}scNpppPQ\VX-,-\Vslhhh@,C:Ϊgyqqy$Iꪬc(Rt:ގeV߿/Q='rU*ׯ7w)VQ[*bufkk lUFMj=I`wEkk+4Mq"M vwwa033 ]ס( JM#O?a~~Coo/t]G:Ǐqyy Ácrr,y "5rŶ)`xxvO>677p]0 af&sssXZZv;={R)feY|lx)KW !=hoo,E0 M,qzz F811&10>>Ie,1ǏESSSp:`իWeSSS`YGGGX[[8455y N!Hݻwed`$ÇH&5,055ex<Ɯy0 ~?+TG C</X=SGGBt9aY8H?~4{?ʼV-inn bx]zqۼ)VWW:&^Ӊ93338??)fgg  q~~=8躎guw~~^vA$b1aooh%[&In#\.ZZZ@4l6 e1::ϟ#H8)FulllwE?сU7OF$~?JӃ)w:g >ŋ$ ~333 '''4 CCCxFv#b1$I,q,,,>˲˗/!I0==5,..BE |wAGGy$mmm8::¯j޸ i0::j&IӈFw/˲{s3{X I޼yp8fR3==SlooC|@04ݻwC?0x:;;]V ~ `zz}}}X^^*<q||W$I§Opuuece}occXYY),⴪pSVfqNA?   Z(`V/U>6Lo޼qxxu躎7oޠ?ΰT*Fa$ hޔcdYFkk+(&Q!b Ø6ʙl6kb0R/Xwtt,LC ƿse6nAUUsB%pEQ̛ybyhlleVdِN~+)σ TUE?FFF#f4SDGDuנL3K I$I,{t-qSG ɬS唻mgV,B&b^]-'eG*JauuXh*D"8< 锣ֲ7t{{nEQ"JA弟JRq`t*Rd`cK&3&''$8::ghh^T 6 PUܰtwwɓ'XYYE"tvvu6H3kmb]nG9Q|똾_Pk ,W+119O rh뵚uJC'AY `9qjiX#Um6[ޜz=z7rEQKe*瘭:',B7~GQ|5-'I3K&~8竒c(U6 O</*YcZV,ܶT$bw*v [Lcc#xB!5h4ϬIʽRѷ'B4x{{SW9}JE5qqqyڡȒ7r!LI3jԨI;:}i"#f:܅R)BG$!pvq3O; !JD#0I>a\GFfI$r-B' B!IB! H$Ba@$!̒y#uZs$AB!0$HVVVTZ{ulBx14lЀqcG[< x=ZlI>\flRSv-/"EZMVy ogŋv4 n@7^ӪUCRQʛT_]MhX-ÎzefX)sBn a HGJ(닟_}C]/!==`-ZT(svv-ԵgQ*ǎɉrB{`goO)]$.6߷7u<(^n1`1fpZ;r3r87[P>Bॠ ,[Άa/Ȩ?r U ,FtL "1) 7WWЇ7+Uu܎~bO<{$?¼۠A}dggojX}!<666h4233]jL3[YYYAu1M7O?iɬ_ԟ&|*^|]<}*Vc/0hbS( ~s("ǁ$rrrIؾu36ҭk.YDb4p|͒E Xr9{v},Y?,&lzlgƴښřɓ&us86#h1b0DiSObleKٹ}+5k0[֟2q8eM?V-[R[lXVwjTFxFT*,?ukVmf4+/vZlߺ 8!۶lfՊe,[???k֬X|["hڤmޮlXZMV0G:prvbiy܌m;Z9ɿ,N:_bcnʀiҌ={vݺ<==3j$qf|׽ hQ$ `}̞k>MOLL vG2qhZetk_Sܿfr=|Ut ni]\^zv%3eY9zYg?H T B;ud9z4 ҽ{M[5r+/JN[,\H5oyٽk7s gΐ#lzz:/_ŅnݺE__1]./IXhFC@J,GYzܾ+GGGHMM}ز YӦnoeRl8@Px{{sIjԨa45cƌ#]@{wK$I¬@JJ ?2Σ]/6u2a鼼ya5.>>ܝgAۄzTܰ]:w&N 11/QΙCa^^;7lv,ڵkt؉N_}EY3fUr?ط~QP?\pJ*VݬcǏ?$7nNDt(ooo<==ճn۷ FCXf7SFu˝83mBb";_~nϯnjDPVk/\ ;g>RI^uw +Y0\}y&tbr9ba^G/M=F=qvv&99,nܼSSSII1w+BFFDիlNj> Yի̛uN&H#G1|9$W¬lٲxz<֩SJKLg/Zumc˱ښwOZ*UUX4ᄄ(>ia-߼y :E{DR}G͛8}4nnnfcyeʖ-b yee߰wiFJի\x]:utILmlJٲ+wԯgAKP7H"F;gMguS˜=@\7D<ھc'ڷ]WW:~َ"h4ksmoGUo6l$3+O[(g ,Ky! U~]t&3+ 4ݧ wޝ9kGdp߿O=?atn2/XȼsDVZmѼӧdhmii 3fb@ߴD}B~;Oo9D&%ae">>}-r^?uM6o٢͛{vڭKjz{vRRReAƚܞ^7n`qL2DRظ)LT\LzGҧߧmysUFu:v,3Q;/۾>> :{{{RSP*,Yv:t|Ўq0 CVӧ@miQdff`ϙt׹tK'##;;;vEaYTV"E=vG2FTL11#mNnݺmr@/$>ov:tIg[mqr0 `6yKOO7oZﺚqz/qa,2<o:QՅJb 1ޖg.>sӤVಅB$Hz|y4J%ii0p?؞ !7R0G$7eV\]]|b(d{ !/Ɉ"oO-7R0x_! $A -7R0O؄\RE" f$'˛;~C*ooovB<$AŒQQT^RJ/}Y};w&%%౭w7 =#gDZXx 鏴2u-;jTʱqrr+ӪEsJ*t 7&0 Ο'==ŋs-O̧Z`OPҜ8y ;rX !L>HhQvv6͚6Y3uׯǶ-YzXם:2|PXf_uMmKSn]:mfVXƶ-iPE17ͷl.311DmςsYf۶lߡP([mM;]Ѣl۲_eo͢ _dmlvƮ4pzAՋM7l궷m[ٸa˗-\Wt]z%ZdӆuY["YmԮlKn J6C)S f:prvbiz@FFFb0%..k׮SԯnBd]4nPo!cOVhD(J+کSH$Hp"E/VVJmba 2Bٻ/jJ;^@ iLܼuAwޥ;1~Dzl|>> q("I3u_r0v(vG!8 !ףqH#Ǿ}QЯ/Ja:u_mҸi3cbے?n /Vyv]f̜Ʉ8{,&LqflݶB{wEP+^&ޡ^`X)?M݉qFh !MXpz09[4y>111ıi\kkr>'Oq~~ /&A=ѣ̚=Anxoک#fѣ/0GBXb%uAJH޽3[5kr%?kغm{.ZFAVu.]ZhQ?S5_͚5x[عS7^VF`` e˖a.7'NF ~/3Xmm֫xbKL1,OhC`"]skΦj*iVZkz۳w/FuE݂R5h4 9ЪEs/Y{4HllŋjGP;oaŊzjv^5% 3j0Ǝ u+PpER2 4nԈw Qo]}9ٳ ԉ+PbB;ub>r,$IR!T4Ǝ[L4Yooo/bc7,66V,T&GGG /̥KI1ӓ}bLZۮ]<ݖƒK׷Y'[/O/ORRRw^CtEᑫ܇Oneee ̈́of ߗ;qD=HsKHLK7}/0~H-;XO.1y J,ݺp ElJ`F EegϑIRni9rD $AzD/]b{nq { s6HR@{5mpuqÏh "8i wJ%=z6ډ͍_g|m7.55+WrU֮7bIyۺm_uj\Kˑ#>j,/\0?@,ib+ *V4LZ59uti8@W^|[O%''h;lܢ<+ekr=S];͚T*9vt Zx> |O2/s_FWf(Q\7ں@ZYYacc>0c/sW?%&%q1zu*_<_`Yr$A* kORRlٺY?gڛ7o1jOBRR"YYٜI'QZU6b|r/1BK s+[ 8<u9EmLYmΡߐL>}:d0>>/O>iERr|;f ?i38xEoז /0{ίQի?0UFu|!AJѣhOwaz_ij}6/׫6իUT*ڥ3F=)J!Je[|AB^3IQdEa_~IKK8N'''^?xȏGf:+D|Ҫ.ܾX=x[Glll $$$r*FsuhgKLY7;;;V**iMΛ>ptpZ(8,tBf2$<"q'mnJ2mYommmuQ/S6*HfMm< Ztރg 1I,YRP(pqq.9ڵkE۶_<œxQ #Wd4iwvʊ5jm6^+,Z;jڶkOtL ۵矑IJ=_3a&>i J۷ѫ7o ((Q#IVV֯׋o >5ʊ#燵 ֯gyNe˖e֌ik.E֟ӷWf JJOWNR2dK/+|ӹ 9hbcc]-ptt2oʊ=S뭷hԜUTaQl wXZ^^ :֯۶2qd\\6t(+V ##k֒Hbb͚6ͳ/]bsʕ+O/#-VvvvЯ/!&>nZ'ZUhЀFien{TT!Rpvvĉt;5m{ס-:f;z}蟧%ݽgq`^}>b$vvvѝ ѨqYݺQN<>???֮^ɚ5k K/Æ8D6mvZh1-?iMll,n͘1(oO4~?2rJ%FgHf̜-ӧMыښҳw_.^s.~;W-Zsج7RDeev7ӓ1F}9rr^as8v.t2]~iIk}bSRѲe ڶk?\r}\6n Ν;~54j܄,ƏCn]1r#G_޼GKw2n}ci= gy3{( 5m MwMh~=!Mo2tiii&׳䩳VVJBqS#++@۪k+HHf$%%ZFt=mɍ7([,sf̥˗9s}%4,d( ⵶~P3a=w5CǍرc|F @h$}C߿J>_WdqLMb/ZT7Eh4j?@`@ [T)?Ίpb]rHٲeAK͉'QFA~թ][ns7.AK&$ݻv?큛?ݮ{(H%9|(5kð$ђ}#zpE\BX66ٻ|9o׭ˢŋоkѢzSSSh4ZgI @A(!s')I{Ν;4 a0nܸsؽ;!!m+W믡hKꝱzbI]+^/g"++l{#,XkZ^z YzwG!::@/jŊmxe-##q&?Ξ=G͚ z R *?==+WZT106s8@ oRܸq={Rn@Jԁ _a&?66d~3ŭ[uzg3ws74m҄W.#Jy7^{:' Z\lln\VVV*7OOOSs'O7Ujov՛kQ~y{{I=to߾Un%qUnN*+m^^;7lLyM7LՃu7ҴIo;y?OOn?8Ǔm̂g7oh  >7_]Gh|}&1ci'5x&L'7wXR 뉥u˓ݻg1$&:FCl\\٤p[dgՍL_:{/OO߅F/(X"99T3_ܺfΥ˗I{SݷGзwof oFdzzzqic1oKgx:j*hќ?wtY9s SN3.f~[B|>RI^NƨX\09իWx]t=d u6*_ О6lhQl{T4)RGl޼.~*Jw[899wbtߘIwg/{k\|٢1_EEIעE$X-2 I6mtO\l#6ӴIcRJRn䔭Vٱs'5sLaꝩ+W~s(ʶRM xr%jժqA3z5]5Qx+YYYFrRR߉=666N},ݝ{NJJ^[9X[HLL2Ȧ5F[Bݍ<18;;g۸iv{[oՃ=_e Zmz]!GHHLۯ* <\,f늹cT]3FsLۣRHN.q8X~:hf y)9==L.\Z.P+$')33hfJз_x EOox*؎,3, !x|,Yʚ5kv/'O6jB5. ;ۢVS5`e%ɑBFvvSk|lllpww I!5 3\! 5dddHr$;!BI!€$HB!$AB!0 B!IB! IݻӈE!_MJJޟHBAW__ N!iHIӧ ϓ !BB!IB! @蹺IENDB`RaySession-0.12.2/manual/fr/images/ray_hack_zone_test.png000066400000000000000000000143031417052567600234230ustar00rootroot00000000000000PNG  IHDRGVV2 pHYs+uIDATxyxgY|4v|;MR&i)˱k)r=,< cڅfu)hi'>9Ķn?dOؖ<43^}gFk@DDDDq+@DDD09""""J䈈(#"""LR/E---0+Q"""e Mp䨥C!xܞerlhimEc)jf*nX.-#"""LR09""""J䈈(ŔՈ({)ݷByE#!_e&GD9dm~8A2nƍػ{~ڎ(qX(W;1TVVA(QcQYTO<SJK8eyhiig>io&GDۧ,;{ w|Q)rǂ}?=} ~Quؼi"{"Zќ^p]]]_Q8sw׼Z0C}?ѷ߻g7n{߭PU~8+S޿K(--C,~UUU}wH{$Ix?fã? v 5c=V+z}Xv DQB(ž=c=x߄;vcw݅o~[q#"oVeW]wܾގϣ ?)tuuCetӍؽg/҂{=n7u[ ǃ[^|}C{mm{F#w|+C?Bt0Q񤭏b% ``YQYQ?tEb[YY|>?roYH$Jۮȑ>lxɧ w|Ǐ Qn`rDD`я}|ʺeN3} y9Y,f(h4 (,,PQO|S$P>׆gk-[o}CDՈhN]wk_:$IB~~>a2O>4m=E5g<1g;vԬӗ[nJspy-7dYƻ.}3gpd/#'z, V}h4ꪌf ɞ(˅"GuՅQvcm_s~>i~?^7~_< ɄSfsmB lFѣSzM7ހgZ2O/ރgш9x.&ηn OZ_s >`Dqq18?~kߗȾ}x'DJ5ui7 پ};JW%+FT }g!cv^Lۙoً`@4]jdH$hmrlɴ)ُ=Ge҆l˰ ` .+DUU{sde7~Y*E tU. sA 0[  ,f 9@CՑaiJ#"""LRpX-'h}_ gd 9[v㗗sDDDD=GDDYhϮ[,?aphhjD;v^h?ҁ!;//,.m2~)IJKKv{Q ,ظr EkV@Css3088Uɨ&gϮ[?ɔo|jõ׾mm/d FsA y,/W{8#y;v^\p;/݆u.[>VRRҌ⒒h4Gu:fv^ `^{-$IZ:-\ xӛWnV͊fTTVy)_(hT^uNscѫa׽N 'i: @Цɐ$ !HL^ebO22Yg \.7**4xJ[ I~s()5ZPP`ힺ_IB"6w(2W`@~~>AEX,(`0P(χnL&add2l6## dyu.Éi X^(Q! =nSSEDqm'D<ϸ,wZ:L%Ihin "|>B"aGii DADQQ!$I:kvo/F0Bii  "= ضm+?zF:‘Ȓ|TXPSضmkZpQTXbj8.oSԈhTš_`@ssECC= ݎҒRn=S^޴qlV+'tVFoى\}(((ׯb⥗^ҷ7GLrg!,8g;P\Tc]vZ[0:6p88xE78pEzB4|>vm:TVU"H7cpp (( ibF0D^q7hinAQ%4 ]4ԘNKQ.XN0{!"^ͰmrB8vtvu,ʭfZ5kq@ BQ47ر.y((͛G8(hlDZn+IIbyE9.DQxp88w~@naŸ_+4MC^^L&pfx<Aep\0[0d?~B 58y,cN&p\hnnFkk+<$Iӧq) 444@eb`˖-/A<{sfu( AUU}\=LQb&pxiծ,4 -ͨWNj-Cy/7#Xeڂq_ri8} |v L@Ks#<#8} DQ7{I㝝JYsI$02Lyy#3pX\dm6 9z3tR#f3 HE~_bI!!ieNM'N#K#0PFxQRZ2fR~ttL[TUE(Boo/$IBqq1WUU Q\\ YuV455ދ``0 DQqڱ u!N u,D48.8DSEXeLƲfL&1eZt_g`0m>$!dB$E071<ׯ s%iitK=fYQ[HH|~giRƨ(Pukep؅<_6 $a$  ,MS¨(&w||m3)Mm=[ Ž`Νz+..ZHne2Uf3Z[P['{Oy,O\CCNMxE< Պ`(ɋbTP^f'bZQ|ȅ ٌƆzP(?wQoMj|*X,mR$za=] ٢( GblbFkkszYU5%,pRTUqu(/Gi\r|'3OTUAήY'.jURRp8Zq%w&{E񠺺x`^yyyW b1x^B)Z<@ !Xes˩'5)ee 3j43gbdd N,oΜTUUfb&jT$EQL_;- 儅]dt:3O?311qa  IE!1s %c{=(wؑglf0~Kq!CACk``v-sOe`5!L,KP : dV~m29WVVb۶m(**BGG>&59:q<6l؀۷,vcll 6lMI#v{ȤQPTT=7XCX̐e ‰! ܎"8]N}ek `2%cpxx  @Caa,+IĐYE33!C!TWUUO_xlŞW!ӹ=Eu=6E#WlF4ǍNf3ܺX $BC}HxÈ| =),zFUmy MxkF<(H4 ˍJؾ ##8qE{{D{]?V&E,CUU}0 9;H456 //O?\n7N9D"1<<<_;vlM.t~}->޶@ _7@ w6B@S !OB$"H >E@ |"@ ?_7*jV)_秣HHH$UE@)~q%$Ij$4 g~ըu q=%=ZnMFVٿ)ԪUZHN>Oثbo'SBTmt:m+BhyN˻t]nَm.7YcO0wϚ$llѺS n9z5& ]ҙ?S$Ip~Z[f,Ӻ.Cq)fZ@ (IJK }OE?'6 *K@Ff&c *FIṊe @zsݶMӽw^)%j1tiִ  x6|!Sn]VZhviNe._jG{Y|!T$أYK,ƝVٳPPA= /QTT@Wٽ+ ; &.HpG`|5^t#< 9^lL¦A$U,eEFFBQudE]GFd YNXӨa)M(MpN_ѪڵcU&?=zǎINN_| գelڼի1ڽWz^ tF,I|}&TRRS`ILFβWy,KKDFf'{B˜Q1.~Wsr<[X 7SlDq̞V|Ek}xrx B0jSU8YUdSNPP8z!_LcE[2Jd$v$$F+ԫ(I,JVc'QcF2IQOHЭk!!:h'0P[W% iִ _Yޱc{ }%~%%Vw[%`;<7Mס};&&c?^ڵ!zNfXl9]|#),Af;í­EM 42ox=7cPrYhdE)[:iN9ϴMykit:[1 djb37I j7u&z=r[V8x,~}p2sسwM!#G9u o˺K<*,}ݰPʾ$IDFFڵkԨQXe\]ٴe+/>s={ѽkWN: ޳KCl?8u2wم\*4s(!}5Z"2/\|Qi :&o< Y _IV Mn`v'I,"eG2eS]??+W( h2$Ff5&Nμ4U˲-:?ЉIj'DGGSYrG]'*{0h`>xSG)WL͚5l*|Q1ϏcؐFK*7n(@:{z`w#cFpr2EE̲YӰatA:UV.(˲t- v6###qiq` 'Lb!<=l*LڶmGff&#G`0pQ@޽'x|.^ym~GJJ /_%]qkusjT$WY"HMcD2{?r"!+VߌG]59r$S[k-HM ND;Ɨݻ/8JfVm_>:u`(mӚ&q!A5mBm5~NWbn.={t3Yޭےճ= NI0=!z=:^6á Z˟v9Ϗ Fҵ˃:jժEj\p˗/̰!"#3qq>:Ȧpg;=WZhN9tH}ܖC}Р~=˲[g1|5$L|l*ЪU+&O~)`-Zvd9|g'((;v̬Yo޼lٚ6_U}Q ?l"ǣxGe e)ۖ$#Y)WY*F#Q\ej8r$ВڴtX`uЩ~}}L?n̳O%&Z ?xߏPޛM"rGddd2wD@ .\mI;|cRٷeۓxd`>]`zWgŲE8s6\WԫW_M3UIH'5%uO^6\~Jnn%:SXXmxve QEQo,L(a,)XZx*)a=LC~62D\j4NS5rDX=[!WLyyW5mD];$I"""f\Ihh(N."##˻^n???-wڳ{.=yYiҨ!{gJmiS9k.6 &[>[7$0Й5aaȲmb0k{[$I+Z0 ㎬MZhN!a{&$?zeޣkޜ:urGr,"gxdUW\G{SP6֘3|hdJ4Fή] cҷ***c̜5~!Pcrc^Q[["hSUigIT Q9p$F~{fQ?fQ*/hATH.]^6w܃;OdYQeНA-*&p[!*59 J$?d Y6y>\s~&8*)Be~|i*fL8zO @ >£МeQ&"ňLAc)ZxCu*.|5T!BD- &$,@(V3'\{A)2 7كuG./J!{UJv^lSXh &obPRo&%r+DE9hl<^tl^+bxG\X{I]~ƴn_7R0 IKKsXVҫ+Bc(KbɄ3y/e1*VZ?@O}\Yx@?#śSFMXMA#:ԬYq5^U{;yEQ^|hUr<*UYiu=)r,?WNx&D9`(; I#h-w&vTݬ? ¸m蔶w~vsB=qpu>`DFF_1}L "q3fKAQxx]Akxh?s+ ,k,=vZ!j@GDDIB\tSLfn0czg]J5skȱqa FYkm݅l+$?_} W8t:7f̼h-D(}s!MxLS8֞"Qo w%6+=,_Ǝstf'Mxlq^XDʠ`OQ#.da|V\5kILL$% @MM O[@eeeG6I|O v{f[зoJNb2e\vv:.;1!t:(<^H]}lfx/Nj߾XV|X,3HO[[J 78Aii8SS]CuM 115a7 G4N*%.6UhX;+tztNEEE`Hz-f 棸m}+K$} ]TqTSɵFsTS) 2,1* W|m;nع]/WUMRt[R 4PRtV S/YC焚z@+Vt:fr/u=c٨"**JH|>6^=/ʦ7騨 >>bVs2'5JJJNabRZZʲgtR^^NLL ;a]^΢ ">.?`+y픕KEe%6L#1gt:gÏOޚ0L<\v0Dnqe,sU=sL0tIOt^S4z~>wtmv-v:,^Ϻҥhp?MDVfӧ_FQ%O׿fv5-o~w`N,lي5װr3` . ]  tYY;. M˰MQԨq易푈O(wrNFHtkpl&Oewkux^.qhëӽ<1o[&NSl.ѣF1hzjv_u>'3ixNE4>صV_D\|ofnm@hD%mV;TPӊ3ylL;\*{ q1)Btts j6٬TUUZɦ( O>xCC}Tc+*EQPWikܕA%N'ꇹmz滂o#!$ c`ʶZuEWH7V 4 o`K|AcBBqI70dWsm;嚏ϼu}*!?\ͪB!BFBH!DH ! !!!#!$"d$B˻˱IENDB`RaySession-0.12.2/manual/fr/images/session_reseau_client.png000066400000000000000000000130321417052567600241330ustar00rootroot00000000000000PNG  IHDR(:H pHYs+IDATxi\O2H , $-X# DZ+*VzZ+W-m]x[+ "(VQPDYHX&!!fy?L/? n4+-[rrr~駿{D"֒/jkj ,?+minjX,7 l&jjwwwh)9b_ӇG#H$/WÈ#vE )W\`naA$kjjx$&&>bMzZ+./tR$(jIwr|>C~MPܜ1V^=m9sZdii|I6l8c4L6ۻbVuuns=@TT=N fwwS3gϞ]r˗ #0p^?~F5v￿,C~jŊK^uև\ҥ˒Nxw̌oy޽tKz܉:5)iWg -,+-hJLdzMEC #vvҲ}֔\xѹ=|cdhتk`òyDv8P(H]e0z@tCMM vSZnu+mM;w{7L&:OR#LT_g'⼼3e2X1pE*'عٸisQaƏr'xv;gvii7r}|~q44hƍAqc?s1YSSӠǏ~: jٜ&>^}=l yMamm`O@d/&Nj5Bde ]bݻb =b‘#GbEFE;vla d8_60_tA(8~LRn&&& ֯l@ (//ޛk@leK>|4wn7~9s ,Vvv6MtyiO>[ttH,gtpp7nhhh vV (0rʪa9{JRyxig87oy'ST?a- E,i5H  7lxa6MPtM(ʰgϞi)///..~%3&xɒgϊ63gVvmfgsƉ}Ѭ'j R`РAؠZ./+pwRk@ ݀7@FFFEgV__if?o!֐H$T!fgeT(ZloL}.&?vl(n͚򫳳sNsssFX?pގ/HHVD"dgex<;++hAA ~񋿿џ76w4{lCG+*B1bh;(((hqqMMVEE>}tUTر2324>y[LfddYFSQQ۽ y`dlM648P(싆uKKKG8xp _RSN<Ʀxx- m &bLk׬ SCCWMr7nܸqc„ 'N/9|&Y^^hڜaF OO۷rl6̙QVfMxa+D6@11;B~~ w8qƝ?)mRMc TnY-HOOMc\.7--;3n``}}]w!kkfLnARRNOٵ+ZRE|Uv/_jqyQQlmm)~.2,33=qo ӦMoii`0\"">w|J*q=TǝZPP\֎@ Դ))S>Bp ~Żfώ;ZvN 99ĀD& ˫:J̞3g(gǟ| rl֬*+*L0e޽ fnccc?boPe\Xr"Ahtz7Bnbbҡ4O_/J>t>z8/O"`qdIm"#" TӺ: V4ssssL6@*ߧ7uOo\D/aÆ"D",Ju];`u;v={N` T(J5k@.%gddL$$AFOk߸t 11KDX"ѣk׬]vÆ ~AAA fϙO m۪1֯H$`oa֭[sr<%Yh.&%%_fUNZr :8KJ^bv4T$˗߿/_ ]P(:X0C5; KJݻ3t謙W^k;O;@PLLL$I 5LR m&2bbb\WW&i```aa^rcccGw@ h4RCH$ZXXr/ua600077oov;wȑ#;я7Ѓ<2OEEL.XT^VCqp`[X=mܹ˗/un457ou7r sss1%%%WE}88=Evt)AZE*V$FƖtK:"""RSSx<^qq1beep\7Ӻj+/+S)UOZ[[ I2:nò!SȆ$P(Z29e}9rΛ7'?hͲ^ ֶAK'z:[A]|+qˌ-R:<gyhp<wC.wy888ceşIENDB`RaySession-0.12.2/manual/fr/images/session_reseau_fenetre_fille.png000066400000000000000000000260641417052567600254710ustar00rootroot00000000000000PNG  IHDR;]R` pHYs+ IDATxw|el*$P ⩀ zb;!ł%;zywީwg= *](JQI6OL_/ٝ,K cIRvv5{l_QQe@ '_YYov8J/vy-"Ķm+WyͲ,/xgYgY8k۶8IAu+ǩ H J VTT8]vu֯_磻xÆ s՞ӳ+??mܸNHH%%lj,+Ѷ`0`vyqeَ>纮϶m϶my^$Yxl|Vt\ϕ븪ylێm; +˃ Br+**}jֻXEEEVqqJ+ Z@gvd?e>I%''I@Y>~%''ɲ,|v\\/UYYiتcT{ ]rȰ$q+)) >q|`ж,NUOL˲`0hWɗd9cA+##*++kT ed߾}#ӂ`$m>۶}>Q$uT5_rr d߾}UTTd[*2,%%< $˲=lP˭b"UY]亮Sg(c-E'@ `Uh-˲,IVbbb(&[(vU8jTx6}_r(ljlfҢ#U8pv/nD٣G ~8 r9Jq MrzyeYUƼS7jWLy˒3;C^?I;vh|=Y\\*++[{1&1:c%IzyVDZ|7&lң^[St$?x *,,lZFǎ>[{q㏓$ yls/RD2..NܕbCҌwk@~۳z['5s2]N6llE]]QNh{gVq9Sg _cF$j̧Zy h۶84͛?_=T;vڵλ#!B{")CGNz˵`ᢘճ=J)ے>6l$[Æ Q\|,XKH4rpS򫯴`"UVVjtm[}>SGK~ӧuz},gt!e.ڔYoJJJGբE%I,heh 4>H35klI=ޯ:(Gw]{$}~}^m۶х駝8:tq7 Ծ};t :?X^0FرCmxl٪uKu }vY>ڥu]}t.`+Zs~nSW^~O?7M}gZf_ԑGV( O&^u_tٶ-۶uUW5n#=ǜ~G<@͛[n͖eYo^ڸq|o߮?wzЦ͛վ}s~]}Օڼ9WW.cӨQ#%IeKTc8^'>^ݻm]X(reVV3.Wm_ÆIn"e4qÆ ܹ>3I7߄W۷$u޾lۧZ\d:uU99͕K-qtySN)'ܧ-[fESn^*++uM73Ni)7ݨ38]^?I_ڰaٺKtg'4`G=qq;G+)&<hq׌Uǎ%IڠwZB)Qi%Rm?_~8[Ѣ .]3+&߯7x5}-Қ5kuڥo.E5$I׬Ѵw|/[˺5s5dȑ>9s5{\ 4PwM:S?"ۼyX]D9vI ?%(%i¸k4a5*,,$h˾B=v K|᏾eUrvcxݒ+lEA :dl~nzvVRRUZZj|ߐz>G6YzVV[hӶo@nݪ^={s=f}jԵK%%'5weeeڰajdX&j!u_v@+(ء ݠG.<ٵҲ,Xnm* 50&7`g, #& yVY`Xscc?)ϩhO=:w$IWm%Z֯%Ҫs>]%&zbyCcFPKi۶.bmܸQii^=uII}5w9QP]g8Ͱܿ6A5G,/☷?s?{޻U66c["eӶ(.Պ]5m[wO*O=D/ שB4n 9|N9i{5Mr+įB8or*kFxQ[_꣯ɓ }ȿݪ,y^>+K$WRj#]Z݃ճXggV}݀l7i{wVL}|E/նmn>}|Ԥq)'O駟~jF4r@y%uMvyW++WU,;oe\'L^j.m6lRn^^C r;Zm[T 2^ X7mڴkj]w7jZkrZly^&UPkZIB9J/6ϓܪͱI<-8ĪSa"aB dzjɕy\C,K'ggbIN]'fvr]MȻI'ujoљQIII7--U@@ԩSG g}vЯ>37rCViP6vƍ5!1#qٶݻiO,\|v颭;/z;6(`̹iMX$+Sߺ94eرC 'Nԙg2},5J78Y'xZu]cKCpvU˭煣Ī\GyZ;Gu߆uj|:zXM;Q޽ xYߪA۵uk6mWNN;͙$u5j ڵi/4zwb/99YuΧ/ѢKjަMUTT( V=!!^@e2m:Yy[B:K.#KeڴiSWSʖߥ\\gMӚSNl-- dxjU$p$5:ڤIOHYUȨiUla8jbڶ (>DRu^.2vHJqnj%K5{\gW 22d>=Sp m:QɒB#cVu|G+/TRdzӈtťmt衚=wxiO끇l6>ԓuDD3uޝ5 ӻ$gݬ+WWw2_&G}c]XzzzQ핑!Iz|S5{N̯眭8]`KJ5z]:w'OoQӚC4'jAiioUo^}u?\'וW^zI+.,W^ m>3jժY~4Lu%; ,31ZϨۭҊ64BԨQ7RktkնmxOq4 1z|SZr];ako%I~SO>IWܼ<WrKCQd:Z#p%>jo\#qq^{Z%'W퉚=xc%A*99Y,뺚={F{}i\pZvPM" ǡDi-[˲,g(9)Y;v^{yE+,<Æ?͡][Æiu'}:o6l$IZz C#+Rַ֋|5V>PCw-ti*_Y;̧ie| /^Ai˖*,,V}R[5QϬ7zUV޿۷T[غ^XӍΓ-^Y{ezު^9zP-|RRRVUW^N;.{ whƍzr1b'I *((PAA9j۶~zK%] 6l0V@ie蛒y;h&&بͷ|*-SAAq Ӷm*(hLvk3mP MFwRSRߗ))q=$m/(~I#7=uk_UNj.Ш?h{A(3s/jmWj i ss[UNΗզ腗ozB==LJҿc,//_}]^)d˭ԟUWDukKJ޾JJJMӬ[w;jmveךOFFPN#-]EW5Ї~/5e$y4se⺮~{brxAvQ[lz$VU*EoVOEӪ6D4H4~9; U~~<ϒ'lWsr~p+Cun֭;|޻u١4jFcǎZHKaa22j<:uTQq$7k^P̪_a{U;J? 5+1瞣cG g*7oK4On^qکՖ溨oI+}z>גϗg2< IDAT;Vv'r[}uhuq<Ӗ-[O>iӦ_/kƍS6m4w-[LSީxP}ie6gעQ:n͢U%v1"˝<%$rFWk(7g)5yotib֛ogmo/)[oS^ /֌S+-5U?HuKnn>Mn&GRf6Jʴb*-X(>SN>Q/<.Z}|/XMO?KGRUۜ٧n,˒m1ϥ햛oiSNS%벨Ȟ~9i}j9>'pb[Pq&\3V\}$BWv4M| r]G_{{P}u=}^~ Zs}筹.f>qI+ӧ*>>^))zǴqӦZ_㧟׾ݺ鱇Tii(˯t[b[*G^~_SbӴ6~8ZR۶m|_8QSTTq\zRR}ȦspڵkV95Dj!ּ O,1evvc[EEEVVVKJJ|%''UVVKJ|m!%9˲[Un򸸸@iiilӦLw^JJp^vvv7p/5|$Gr` T;'{~X6HS$wiyڶ h#[8q-ҋ'*]~^wbheEEXۧޥn 7lHJ5o캨y8k.yyyп_ 92|(k,V,;N(w^.5?Wt$2 ~S;:#ߗѭѱlH:ZkS)ZN2Xuj@Q!r-sݪWZƜ_AC{*I3zMGH]WYb0"5rq9ϲ(t'_QW+a)Eaks\C"4~@(D*^=8ƍp E]y'|yYs>Jj#VܧflşJ4Z7eeԹrkKйK+bڱ+{ZΥlPVo&0(tyQw5ٰauR42mذ!=Mxr2"x#YFv^ًo/x:ЃabljMT#)+sLG]b LDW=\OM:C⡌_džri_b "6VZ8PYY[{QCqqVX7kTs=C))2ݫF,-_Bޞt^ʯdBme}ZZ'peoۢѪX_LZ'!J uesH:wlfD P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`@(0 J %B P`-*kL*IENDB`RaySession-0.12.2/manual/fr/images/session_reseau_invite.png000066400000000000000000001302221417052567600241540ustar00rootroot00000000000000PNG  IHDRE]L pHYs+ IDATxw|?{%MU@PE RT A~O%^B:JQ#rrk.WS Λגdv씝ˁzIv @_6H J@ l@@ $L<44L!]BCCK} 2iMo߾M@ viԨE"*-T`.QV$],_a- &/۔=!h4D( Pl~W 0VgI)-섆RE(4lذ%;wxPT8ŲPwlųT244_i 133Ғ$Bd<(J0Nh\ivTLZ+h(___*33*,ZNg1]"@@rrEH$<HR2W*|\\RBb @0KE( ZZ-騂gȼ<"@(2bL#ɼJ⼼8+bʅbKۛNKKU*騼GO@ Cʞ!Vf&$Z?j40 EQ"e%z^Z%&z)˲D 0ZɡU*Vioߦ x2?#EҰaC<}@d2haDp @ m۴F: /=y؊˲TITg%EGEBՖq`؍SNmA4᧗%RJX {ci!:;4T6 ֵ |iiXEi0t-JH¥˗:wꄺu 'U+eC@ K >>ɓ2+[peQ[._ƒ碣T*"Rt P~8>ѦM+i M4I|ʨWNhazV*:d|2,KwwN{&GſA˦땷jIjnq6:h,Vš6iV-޶NYn?@hM>(N:"lQ0?p!Se^dN2_n.&J׮Rx[.X#0c4DASwwR)Rk8;#(x_$9'1ʮ]ݶMk,] h,\KMV&tbjM4AV-kӺe?~8Lp|mYSǎ[a,[ԱcU޹s.f})&OQcѡ};o׮XhL&RU-,eV| }y)<Pa{;MSaEQ:S.g6mY;: btb~S'͚e7:IjR,[s11taC0 #a媵WEܶ;l]m` \L4-C{/Tcq5(`{;wHoKq D+a̘=<0׭k|,,tܾsW5`x\0o.D4Cc_DI@oARSӰrZ|2$7n}Ñ8uW{76|NåW,>:cg5HO@vN6?5[40xŧsfrZ|8#jfe[`9,bA` 9صf@ bqE^5 KjZNNN EQ"Dqa9*5ٺC2 Cձ}*vhx2cĂH抌 ^jZ2 ++ zޮ-TdRWWWzh4]&sAYb[5x/whN(Jòl6M9:NGtzBt:ˋU*7jԈ/G^̛P\`ނr%H2!99奋$$;$!)))V.y"KD@($~]e)LFqRׇqN"j7%(LF,[,*1",cL6[D]ѼYSx{$HJRz :}W^# P!Ey\r*C W ܎QP BI  PDT.,TJE(y  1@ 嗿#&M`1|%]PDz}4yq%`.U@( Pb],˪5 %@ Em1J$BI 2(|&N*LH+@ 6 BI  P`"@ ؀%@ 6 BI  !@(W*< BI rCYc J  P` % GmЦMkԯW2+M3z+M6^m*ZR׮3Fc;v4"1( [/]TZBаQCXr5ڷq,[ Mz )7f4"ODa&yZj_Exn!dQL1 ?@p?^HFB}G!b̨Q!+3!0 ;;CIEKpeea^ N ,`oD8VY~0b0L0<σ/|ǎC3b횷k A$l"ODȣ9{Azذ37f# o7oVYxThlժ%rss777] C puu/6a F@,2-X$0?( ժUHs6x3`IP)o ,U+ab4=رҽEGb1 H)pH$aC0a[H@\Cph4T6ٿ!dggb_DU5jTG:u^˲HMM 1QzuԪYׯǢm6\߰DϞƓ'OwEzz:V~w\r..wFRFD8c(?( ߶clݻu0x,fxazc?s1գC+LkޱC< NCbbZxeP~p-X!60텤$I$xY7FQfAЅQ( @u .zT!{Naz̬,k߯/u">o7o.HkH 5kjY Ϝ]*#EL n߾MjJPZ% Es'⼼< '<ϫxwdJ0woEQpuuEzz2|wYݠ@W,.8lT*JDzzaYYYŞ0 \e??x2Hb =#:n%D"T*0 1#^F# MpqqAZZI}:vJ WiUT(: &(J(Jq\\XΣi:OPp:xJ{yy5CCCnצEiyȂi%'FZZpV+|zP-ueHq %Agqk/M$eWW83߷D$ 2 efadZ<(~@ ҳUSzfC ˀ%@ 6 BI  P`"@ ؀%&# vơ{M#F y`s:a6עHf|}kYg"ݺv{ȒԪ@u9Ҡm6*aSk.ѽ[Yg J 7WR|J;/7_塼Rd򂋋 &M`+ʞ )S*[I4JKIpZ[5x#O"/|^'''4MCU\ ,s-wldNZlr\Xﵨ0 cVbLJEnNgi>l"!L-d2'TZ/^$cM(}`|*oQf%4M[]([K(6 OVqﯿzػewT(7葃<ބԯ^EFK_OE5}JOFNǀ_VXo^X0S&Oȣtaн1Ł}{Ohִ +Ǚ_0tȿvGo 6-ƪp`nsg~A}dZl׶ "vl# 8G ȣ¹uiSO8qvy6_OAz^H~Xl ] 0轁1l(bcoW,>p%Q$a!0i TTqa'ؼ'Nn:puu͋Doů碱۱ ޻Q'MlaX_ | #F`g.uB0w\z >>>np߅s*X"FϞ1r8dggcQ;g6y>w%VR>-MXd1ΝW| T*t9~A<=zr,_ '9Q꧇;/ çp=6o~7nBժUЪeK8<) ؾ׭v@ӡgdL>p}}rz^W*L5¶߁y,mwCvu()<iҕ&gr*\]PAQzjT,\VEϞƓ'OwEzz:Vб={tCtyT^jh[m?777l2[𑟡q~:n߹+t^z ''7F?@j_prFPըm|Gxqc<RlEt{e*Hbb BtTd1.djP~=\|}}[aҊ3ҡ};<~_`X78b^ׁvm8\z ]ؙ_ 9[QGQfiAVZ?0toXw=B_>>h4wǩ0-J^4Y<114M ݯ))KHh->׮ o ,tn߁qqp͋dӁ|^oۯ0߯/u"+n*>>MEY5Y@eYɦoڵH'O!ʫ׮HX, )))X&ܼub\ =STLF=Zܥq1#87noo/$%M&]xx#1)$Ziu-tnr>R6#_ gDiI< '<<1w,!ysdffӧ2cLpC`@ۼ BPn]<^9i=DMʔT(JdN'ooo<Ĥ$r0i٣keq<zg9oFJj*ܽ_~eq?F|`9d\.7/W4lݾ.^*q%Da?Ņ uLJ,~ڹ vcؐؼsټBWx:U6t0\our8r퐚 1A]O72t ǸRp!b|XJVJzRZ"n ܦg[U) kyOH3??0>>>Xj9;y3.7 <ϣN&9OOOz} 5Lv( s1txH7`x޵#GsNޭ+~>zfzQ'M&| @ƍ0h@-]nStv_;4pwsix >/< D"IثF!##T*ѯOo3cp׳J%J]S{ؿQQ`ؐ!8o_[L' (Cp*823 J04{ $8Jb<EnZHHMM-Sh{Rym47WWdfeY=4Mf6,afz^x)4?vSww7h24'4 ]o7WWgd H(R%GQT*EQb]vvvMy tǫT*ˋoԨjvCT[̼R eKrТb^^_󕝓cUJ㚖@w=ONNHV-xGjjCqpg2$VKjZ[^/GmX5w]<۬WY#QP$D( @J@ l@@ $J(4;+) ~l]Qi[TjI ;G>Q^=7nΝlڴ[/q՛-+\]#XB 􏦠[w:ͽBa8HXlu{Hq9Lf󺫔J)Jm^/L7Rirawc挏:P~+Xbxo@hu:H%^N17"ر!AQ@zժVŢ 4lpx$\ ''',@q}Ö"##+/E uD"( t쁶7"V@TưШQC̚1hB!o0u$F ,rd],f|*W7 D Bk{`>d2'pVo#`<8TJ8x06}#/c7|D"?O<@3ߓ `<ӹ3Z-X/]ƚU+pz,#v OFŴp?е˻hղVZcOج71F!OL, _mooD8v‡C*"55B|WG>>> Gu!Hױt aՓ`[`ڶSaf4j5᯿ƧsLM?@Qd2'deei!wT4MCQq.:G#ïg Mp?ܹ#<=0 }'_$nnnHĸs.Aբo^h[HIMŸ1y" W6IZ_nƥ+W}a-y΁;j*X ʕ!qQlK<@$'spssX,’e+е˻hӺ5 9NUp0޷O/k4E$/-.֮m,Hfq8sW,@:ZצEy"  ACdLa_A/}ď;1wlaxkӥ;|?^{<]`B8ƕpX5 zNWڵ}3|Mhܨ!ݺݦ?͚zlH$aC"0d ,8}߃'zi=ztJDD^/9+1f(ԫ[[D.]f:Ks}a~;B"9Oع+kV{O:|$}0H zQo Fݻwfpa]  ̥֭?k#<|[^FuԭS_}?z,+hϫ!Nw4hPod5o=ֽ?{cѧw/[CR"::̦=oql{`X__ԩ3B իvh<>>hܨm<σeYl۾ڷ3-\J crw;w°CбC{ܿ'tqqys(t݅ǫUj:=xCOk{ЮhZ<|QZU$<nr/bMVӵU/3(C4qv@^=u<;O ,|WMoұW6&3zdjes텤$ӴQ;Ek0ϖwKv_n /OOxzyǧv5ZͅF; ע'&&>{1yDHN 8|nܼ%\.,M/X- B͚65˯'<<1w,!ys@vv6\ *P XҞE'bg˫8M]"[ÞWs1\4_ݻu?S:yժU^:fQK2%՞5/,ǙLĐ_⒒;wb_9Yr ...HNI^RL$bHLzyj֬ ?qUxǥWг~zh4A IDATVcmh+ PzuoiwxVf&T&:<S2~wHR, ]ݵW./RƏ'OG 1Aއ"+\ʕ+lIIME|B>>#J V\*U,24nbخo[<|= ai5Mw)z9z3gLGrJ .=eq]oұUr.:j+J 6' ٖݼ #+FNf͚BX7ް~3fwH&,GPv؛_Dit^/*!ٻ(ʶÿIvB"MT|EQޛ;*DA TW"H MZHdfGȘMl(b9ɔNgٹ% B! (B$PV.L.tFu+<ZB_@y?]cy8=K8vJMv)^iݪ%B%2P;O*<]:w*p]Q]eٽ;Y,RSR4eZ ;wzadLJ{kާ{.|2.n"u5-ZMDyʦ/`YR"mϿ(NEEz=AA1*Npz4~?9~n'=:+6kڄÇ׏JXˑ#?3[n:׭PKd?4{߾hތ5kѢy3/Nv w&JLYsU1GrAVY dOi# 9͢]r1_'bىU,J(,3;ϵZ-~ǛoM~q3a;%D޵dQ>Vl6x2xJUpV+wIN //Oz{n]w%:e+*U*YR%T CYҲjuh[,[HH… GHHF|o(%jDn j֬6H0wn;M8*2wz^g{H!sR!Jv2 !(y$PA2 !Ŀ\zB!\@)B R!pABJ! B! (B$P !.HB!\@)B R!pABJ! B! f6=H2M)h٢;v" ey{e0nyV>R֥TP عs+_Rѽ[WL&{/AFÃА݌ח-_L0uK,"bE^N oӺq2Fo֭Yc=3x@Zh~#w)Q#JJEHH^ /lS|8AAƚz횲< t3e^^xzza6ݪ_R򃤥>$8ʒ… N ^^T I\rEYӶ~ބs|)/;h4RX,T11DGG'wb28pp|}+^g;wʗϷ{>׬~ڲpbϜEm_eAt҉vp;]BB@m4}s_yxiֲ5V.'44kW1~d233"r qcFYwppK^jER`xc.\1&]5d|y Xƛ ˋ=+U#&6W_Jb;o;߶c'^f`ݓ͌,Xw`[ ѭ+׬_r|:ZiG&ycljkբ[tћ+WRc,^8#&&:?L=w =NkWӾm>EYXz}ۖ-[:潵;-SaZh΃>HjJ VkkjT^~ !DQJdOK9kԯ˕5+ҥKpY|&yV4nk8@eZS= %uup8عk7U| ׮EJ^8*T\V{#+n'..9_qU7oRvmvߎWũSճ dG=F||Wvفo}<tI|=$55Ѩ\|3ThPIIIoc^bQO֭h4t:ڶifv2oXҴjB?Qe ]˭<õkQZU7j/?rߩN/d޹ {x뒪beYp>ׯGX]^*z Fϴ)п/,|}|Xt9~;^dݧϜewYbqq1s.Kvm[Cρܞ(hؽc9"gΜ}lߺY#G25T*Æ bƴ$%'/Gebτ5խ''OL&*99Y2Lj^IMMUv`eeeOZmt8># 9͢]r1_MhjָQC^>v;]*r$$$o7\zв"&6bկ)JXb{z=:w9i{ܼWqB_IEot cзWTfJlS NgIKKRYFnXl!!! .8|||!!!5j8"##nj(sSf '?-v 6/_)t}rJ )).˸Ez?n޼/f !w?eQʖ+KjwsJ HHMB7,̉'vj1BqkFB!@)B R!pABJ! B! (B$P !.HB!\@)B R!pABJ! B! (B$P !.@YZUO2a <@-iE>l(={tq̙5I}PTnqç+[Х +ר^=;@UZr9׮u!m)Qr+/3fHԪYYLu{Tux{{:///s!+F~)z CV[ձ{NƼ3 Fs[-44 !nK{Wb&>x}U*FyaݪC8xZAW |exzzVr3xyaj{_ulIIIppf}"p`p_ӡh5g_FMzz[sCbwيAVV[ˋLV^{oooRSS <~j@r6Fӝ3bԘ|~9U`r*Nϣ ;υ(iJ\,̆Oի: ͘C?й %???>[>ޘѣϔƠryZlNVVXFHp0֬nŁҷO/zvN5Ԕ&MVTe2ikT`ǎ̚3OOO^*M7ns3.3gu~-[" +]^ǖxԬQ7fyr|eՓ~}ze]{ptɕ+W'NEu4{Ve_V5zl6 ƾ¥Oѻ7oѣ[WfϜN93o 6Á/ߏiӾ#tЎoΣc.E~=c:a/k_/}gΰkZ@V,[;lgݳ Oҥtޣ4e<=i٪-, KY?evXm6ޘ=_axcGbcM 4 |̜>_=W_GV3y&McLNJV.?H[6:`"ߟLɓfҥzܼףS54oڄ2qTBCCY޻={;vVkhڴ ۷aXV5c#G诿CXb~;Ntt4:m ]aZYM.YKs**?g-l6tz[wyNT+Wn]бSW~~TS/oQT~AxՊfl6gѬ }rqӗ[٬<^1u+GժU8T $8'Nd'm:3Me\r5_M4f;7 ׳ KV4qi} b =+n˗c4iFõk]. f}6֬SOu8F ~~tш9!%11`F# -U׮]gƲmyie}FF ƍ%BLL-[b`<ũ(t^OPPPuNt:_IwΣW!J7ܹkw( ~6Ukyi Gȑ-L7oXN1&zLpH0aae?9HsJjjj2BCB5Bk"00evvx իlUerIԬQ 99-ZHLLM||} ڴnE egn]ݹk7ۛÆj{lj[KbbbP|??_+W!8?[[Ybeo䯼-[4KfF#ju'G·7M7ׯG;} &((,sé/9iFbb@u\6Ge!yR}+qW+W1f"NbȰװs]3 $wě͜b.KLJx켗SBCB8w,$$ؼόZfӿ2 r=Sorٜ@P` n`pzNHH`Da/}ysp~=[fTFݡ8nS.=;~cO$,,yo̢OjO֬]Wh^HN]INN3O}PҥK;}p+lzt4CV6l\aaNUyfG'8=BӔK^rj --d}Gru\h9YYYX,ʖ),۽kڶiC ex ߾/^u,gĸkw=hղjcsٯKrNeŨU*RS`7Xg,^&_mބbЏ?rq8|zZ0XQc{XZAjj*FOڈQ;a"#lw3faŻ?v ;m!%5 ƎP#7aS'iT\АNloYx;vJ|_z.˖d֌iضtvkהWd1|y x{Y:y>/8XO?p.^(p99-ڢV8},3fV[|ӦN]6Uj%o}=\Y9Ĥ$ qfM?./HMKؿ@?q/<#fo1L0cF1jD2##/D#W='s+<{/<ŖM7eQ{Sq:yd2U*ɤTn ]VVTFp8,sʹ~b }Ci\C#,???RSSݚ^4Rh4Zdnw()rh.oo:nG47N/Idݚooo6[rf-WGbRw" [חZϏ|-j5ft0~~~XVi݊vm+#==yT*Z%޻8dwϣL|IoʄWT~1۫T*JJ@Ne,hX, >>>G5ypu պ3l6gsʽ]\sʺE}yf*p2Uaspn7&ܓcy5G}6ߩ✓9=$@wR!+FB ~#xzz{HzAB9) {zꃏ1P3h4VwyAP~;~T% ACq%Zmz}3 I<ʩ#w*,*}B/R\>_T*|}}Zv3Zzw%UQFDTdHbUi߱ժVahڢ}]]'Np;{aYHmȴXX|-oبٻo?sF&1zXm69'UaՇOg& Ni90 |>SKN_l9۶`ܼGOhdl=蕗оZg?ņ_8{w^9۶ڈQ>sOOOƎIӦMYmL&t d?fH{Q<9pNSROӋݻe"5%ISqB ̚I@@zSQQ;Lw#a̸ ޘ͑#?ن/`JL6@V+[nsZ7_7VsZ*VNĥK+]E d2MLL=zfyS*4N]UhU*^y/p>ǞOѻ7oѣ[WfϜN7::IS#xz׬Y&lj]N-pV1}*?+W8ms7_7ʲ+9swƎ_^فT\tڅ*uL?&*I=<< mtه11<ޜ;'O8 QҕKe˔R>933 _lr{fq/(K 턅L{P{2aaTR͚㏇ | =hNV;}ػw2 M.\D[iš7k;$Ϝ函h޴R?ʕ"11eL3NoGƍx݇܁91KNNJfMpOQ)"NQ|F,L.^/e˕%ƍjs2eXu~?ͻF/drjNcJ,=,wƭK[,DIWbFAܛL&r_,yF&MGʕ9VUϓh۶5gEf=k<zf#--)kfSFE!>s֩XI(7$Z\v;N)$8`J+:r*gƍ2ĚL@>sFҟs3-MYܼۯۃ*1aXZ-W\!88(}?HHQO;mO9Bt%&PƛFz(w"]͎FO+lqwҩkwVtwӦ,[6[n#((PI۰I3%`l6j֨N``SپdQՇf ޜ@h edS:>ŕLpP~.:6ś͜b.`z:GsfY͎:ԙm8pk5|Ǜ pk{Yk\v]:ڷkVV͚@&*닓Ž jN/ttZ^ʫke4`۱lD?ZjԬYzsUϝ!]vӢEseYb<4|m*{һgeVgPP[5m۴B ʲ v:UTV^:Sr,оnnF[u.۷͛)_[YUWLJ:}$+1#Jiә9};=fgמ=Ԩۋ0LXVvC2^/6nE ظS4j5}>_63uD^r]μyYp> }Nʗw;C^>֭%9%/O/8Xws|cL<;"%% Եa/+TU+HMMh4r ^1id>cV\d"!!زif3197gL q|~rn}ּB5j>|o^T| ׮ ܈Ssrey8|'e%֏Hɓ'U&IPL&^פv`0貲Z6:fQۮ_B۟#ߟj֨gҢu:^^^.=/JE``IXr?ѼiM},KVl깓>Ds iwq <==IHH(V?5 LmsBBD:_nnZ?wTNQtF Z7|=_+ ;A!@LI'+ cзWTfJlS NgIKKRYFnXl!!! .8|||!!!5j8"##)1# *M*tqq}VYvrUO;eZ8H{.4I2lnQ"]p^7zWQah0}j֬AUrSq )IJdYp>5?ġն9Bܱy{: m\z&_DS; &O .򄸟|W.ߍ+BT%:PZpn^*1_B! B! (B$P !.HB!\@)B R!pABJ! B! (B$P !.HB!\@)B R!pABJ! B! (B$P !.HB!\@)B R!pABJ! B! (B$P !.HB!\@)B R!pABJ! B! (B$P !.HB!\@)B R!pAP}`{ծ_U+pZ>nmSTmW `0f!(j53xyj*ۻm:zT*UUZӾx.;^ӳz<== ]p8xs[ع2'$`NHp{{Fc Z(V=T*]j5zQTBGje.|tw!܋*qcFldff<#e˖aƴHJFױe6~gioxGNe֜l۾0&MKʕQf̜ 7ЫWtZ*L1~tk6zzz2vH6mjd21n$̟KPmDLL,^'ƍSOb9qS ))V-SV-fz]5gS+T8tyHLHZ*,YM[Vuڅڵk1~dJf,YiS'o6ӹke?XӧM!(0ʖۜٹa_TZE Ӣu|eM?ߎQxc~c.|sZ*VN͛7ټsʹ`u& gVT  ;'=#SV-K.d'7fZZ%sW /6ҫGw<7=g.C l ~g)_ldz}4i͸8ϜMTiYψׇU2rnہg5aАa;7hZȀ0ev4oՖ,~ZCӦMa$@tt4FҪm{ZiOpPp*3fq#&Z^N0T*ʕ+K]ةkARV3cTGVmys7y6z\#6G-ֳv[x4W[ /Κ1hݮ##Fa҄qs6.hֲ 7n`,|mZiSx}04 ߏiӾ#M[7yH1zZ Bʘ1ҽ{WF# /WUpAHpBp< IDAT0OzO+駟?`q8FXX5k5p8lf-zMIKK`+[֩&ILLtfǡYݷp*VѣR/W_322XmVkgffr%|}})[,7nP*in_t̛"-[ +Ï匚nס?keϜӃ1LJ7nL͕@߲y3nۖLg<Î̥?pƍ%BLL,u{Tw֯X,v~('OEq** ?A@fMOHO`ӗ[٬<^1ΝguX*1^\˃l7oeيcەQUcWFP`1r+BJJ iʲj5Yʧ/ AAAi݊ƍ*ܺ$ pzˀָQC2XX(_g򏞊CEm׮]wkߠc d2ܮ_*1aXZ-W\!88Ho<#DΘIY iڢ5AA<Tv'$8@FʹnٔN9959L.|BJ? cړojc;$&%*s7Spz3*jDUz첍II\ WYˁ6/GNa諯s_;gVʰh4"SwśFz=qqSA5ޜ@``S>>no6s=:!^+řd6'¹se!!!ĸ !Sb.SQs?8 Tfz{{fz!VSOqΜ9K^T*懽7;QTػ={(G))(3,v*DzI-/^N#99+8]sǍZ-jTڤQ"*ի׸v:]d Fҡ$ףXv;u:;/VF[}uNEkӼY~eW͆fnpAZ4oF?j֤JݪgTIFʲҥJ)_)]н[W:Z@Qsc.Jݽ oTbFʲ͹$&%h73n$MDI|{))xxx09r7o9qu͘ŔIւն팛8"i߮-jg2c~Wm\d)S'OdHII%#3;uԩ(Nϸv=/+?v _mDBb>|z־6$''Gj2L& lܴXHLLۋ0LXVvCovNΌitz#ׯFm._i׮ j/6}I[Bpǚ1qX^Fgoq?VΤgsjլ bNH |wnՓ3yQ=Ȥ/9 +]cرm )dg0vHqԫ^ПO?\&Qխ''OL&*99Y2Lj^IMMUv`eeeOZmt8># 9͢^r1_E?[V#11QVN@?iiiX|}}̼7/wj`ӓudeY၏7Idee //<<>>G5`J̈G'<n'.rA\1--iRKt'<-=E*v.7jݎlVk+ 9""*ҲE3zVY,,ɢwҏngn ) %*P q7r;\|~7I7$Rk4USʤ-!?JV%x!Qb"B(B$P !.HB!\@)B R!pd}=DIЋ Еz["g_5汝%*P=|xnB#kG _1~7oD]zՕ*AR!C[ЇW[+QR!IB!\@)B RG&! !R!pABBBƐ}j@yً9cma4Y&?L2rieYZ%&&iaaIIIa߾}X,eߏgu˶jWBFFFUTjժ5vܩly|kHH +Zm"Z^( xQkwDDV (?BBݝaׄ$ٙ|gǾcկ_?aXR?x'55U={+{.uw<߯M6Z|6mԬm3 CG}:Yle8N|~>G[n*.)֊U\Wq)!au7JMMUz1tP]xE5;NG}$ɲ,tz/藿_c_kq 233%Iz7uQGki 7ۏtMf̘&MG&M֑G8\IIIW^}MGOЬٳuqջ޽sK/ <9DoySzN?t͚5[ْz۷9;-u޽mSZz"$ 2 C] ekKHH$UTԞPH%%%r]~_eժRSSkU$s~m[0 Mbn٢kW_cݪe̙#I1c4nXmXA]{>IRϞ=ʫiciǎ5i߾s1 uѵsu)))IguV}w%C瞓$}[]pZtiv?A= ǵ^W^~Y&-IwjW/kСڶ.Bٶ>[72V-TرCzn[IIx~\BR濭N8QS@w}.B577>-!!AwO ߩs;b'๽ ɓ&IR|S\_?f@r@U:u̙OEiKؔ)JO2333[ߎ?22ItY-[\˖/Zm.15/Ѭo;uQޚ˯B,\/iնm[IUCx˖P߾}ٳڷעEƧ r亮gn&Ն%)11Q:u1dK/ꤓNTe TXX(0Xk۷nݪѣ>,˪14M v&N|/?]ğo^\k9I ~5k>s~uw9'ٳ5`I?^͕mےyssҥLԢUWlp$CR*++UZZdվ טnЂo믾v]/U~_&=ɓ&)SB,TEykU12;K]=j~ e]|qUҹszXVҥjӦMMP01gW']wOШQKSNz/hΠ2 C;wVFFN_@@M uX}Wzbt}9\z~մs4y+VTTL:tPaa/ 2Mq6*WZ:OޱcG%$$(!!QSMWBBP ,3O?-۶kʔǕ234WVqqաC:$''+55U>>m-ϧ;ī}Q"u: }zGémU޽ŋߏO;Ôݡ9]׿ :>V 4k#庮|pbˢԩ9B!ue۶&O9oP( kyi7o^䎮]硇/R4$4y'xK}d$[oSZjZ~iIR8֌'f$رCwo|9˲43uǧC W '=ާ=T^^^+$srr4t%7ycUCĉ;!C3gPqqoX=zczg;-mE~_>_5$IӦNm:t;TQQQ|SNQAчI;۴iW]U]]/}3ŧmٲYimt.l[C$ԎZ0ߙ2es!ży^SX-m۶u p~9眫Yf[~HKԐ֯_)=Z؟r&?nW_5LӐ8t:wx <I#&/y~~x`bS]qqlV(%%>-"۶UQQBRB5^;.ɚ:mfϞW_}Ƽ|P#F\ pO՗ܿޮysq\u3)%%Et_1bCu }ƌh,((P(RbbbDl[Hޞ?_oϟ~iҤڸq)9%E '؎#Ӭ"vil՘ZvC;uҶmꬰ9e̳ԕW^ЮaѢEXnm|K.~kiۭZdqڍٴiS䤘h4"0 ԯ_?GIUz!`,jve麮6nܨCw=zhÆr]W6l!/4mXJNNִOhG￯3"Iի8yYC{!CΨM1i#TkX5nu]W-<9PEqF[NW^yj磌FjT.?O\zlݪ6m믿ҦMt?7 '80^m{~qđoi_K>}F~3hP~^pwH QVZZڴiOM?w}LTEEnyfm5uٙ3gO>ZlLԒ%K4}Z:WZ_~IsSEE~!_E4Foշo_W_qE|׬5׌ք{UVfmSzzV\q58cHh*K.c磆\cڵF~~QRRbt7UZZj:OJJG"4] ۶,Z7mfw6> .Z)iF۷o˶mqm߾]T?_fWc5ԩ濽@V0eY*))z:m˲Ԯ];رCMzmzzoޤѴ4UTTԹoChZ655Um׹} JLLжmjLoζ'99Y)))***s?ԑG৩mwJ_\X|=cg0qJ%UpYYY4HrrLgn(r333ݜ777TES_aZ= c"HK8 V u+UCRlۮuNcņ)kskls]w8겐;7gSZZ/!@k4xuw`w (-[蔁r{mv7$"(@P~Pqgn#o=WQN+WKOU8v7iUP*ZǸU`ٯ^J<x (@PA :J`?`S))){+u;.Y:~ TH%`钝{SFP^=e~}l饏>^+˴]cik^>^n;^K,?e ,9%l[TU\(|I.<jpI ~lz\v~þFPOcbBPΕa "L[ %iF&h0tA<7zpWI 5g<͞3WOŸ7P~_{֚5k\M6: Zrlێ?St)覛oޝ]-234 g_|)zt?D_dy׽*(,ht{rmxNOEP@ O \kF}nݪ=z(!!A׏?\v퉮7Zc 04nunuVXZ\˗ԈK/[nПoQr͛uۂ-hv [] JoZ^ xF;vsz]st7ܡC5w\=8qPwJu˭u[t}jwG3|ZY54w[uA?ҹe Prrrm44)j˲,κ~JĉWoT4\Ӝ9sbŊ4uc)N0\}2}#dK?\KϿM3ɩ5oT5~x9*}o>~w= I>#~ǝ;}ŗYן5^vs/; 5oͩY~_uF\9R;=㨑TݣiJZ~wtuQ49?I I:uԹ眭W6mBPn~\=juڵƴ`0A?u7+ZD/III*޾y۷+9))ܶm5JzҘ?IpаCW+χ\5SǍՑ}ħ;M6Ae*.١O?\%%:_'?PiY\WZt:vФAuOU*JUןuէ}rݪc>2Y% ''6q]9ڸaÏ@coWlՆ(++yYYYZ=zP^j*x;7g`Y|vcuF3X iNUHX(@IDATZj^wphrrN -CPCx++[oMvnVшGE{W^ƍ5f̟jJ_|&N|PLԴݳ} .㺺{ԫxq*##CmuquꎻBNޜ;ּ7s=1S\= ==s>Ǫ[/@/&=4Q?^E]^ JoG ڵk|֭otǟD"I i&r]mIYX;oPkuW-zoowɂB YOp/].Uѡjj/v OV雍7s3 Ciiiھ}{eYڤLZqys=¼f5u|pPRl0Q8N .++INNvᰝ_ BnffZ۾$aUV66nU+Cu575 uUTTmVAanzOؗ^J<@y5b[A ~"/@+C؇ؗpyݏhe;JK{m".}{־.v+]=r.S%?eT@+dg:ѽ~dG>d][b}u;s9x+..ֲ+V߁Zix20 nf^˗[ȐF2hu,Dka?c+J<x (@PA %J<x (@PazHqaޞ^%FE %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (@PA %J<x (*Aikm/A %ӚxhRPdY[^^ə}inyykYV2%J<4*(׭[DG{m e(Pu5*(PgP999nff&$丹uf%J<xI>&k쭎g#%J<x (@PA %J<xhՠ4 ߯P(*ADd۶KE Z;(kii뺒F[#Z0 ׶mu]|WTxhvPZJUaGu nᚦJ?fVsPQI(]I$4MB@ vWUt+**ϭH$(ryHBBA7;PYY%`_#4]4x69-ײxZFQ׶mqM⸎lvhҲ,@ nJJeZ:8#W;h4vd8F]˲\۶[fennfffRqD-))qUeYeY8Ne8,_{+Wq,r,++sKJJ׭[P(fff999nnnnլ^c, n$qDZ-˲]UYYѨn(\ʲ,q۶m':@:kĐaÆ)))nQQQ<$@ Ę$uUQYٜRXUiS^^Z庮7+++~|jV6 nrrcW F~46JNZQ4h$qd' 9)))M, 㔻DJggEiG"in4p$8c'$$ؕN$SdjKJ(ԓdff:pNNNvmIQ0">/.uJ6 #")l''';p؎X$ƴg4v~nnpB2`0h8/ H|I\3MӴm2~pǴ,p]=o_{eY{ ЪZznTnoDQ阦鸮k/vcE4-s]%E%E+++6m8yyyN(rO>dcu7en݌|3Xp8p8|qb,۶M˲!)I^A}eYdl'cmcvD[R4H4 Jq*KH~Q^fe f^e0Kam>p]װmی.8?a#.I_~XP`D"a˲"j\H6Ewq׮]+Isuve!ɈD"8F 0bAkɿZ@s/4c9;sNZ,)dXvQ˳,oYea3mm`Ш=#VQ/';K#]QQagee-$cRͰ7tbĆa}>FJ3))ɰm;VA711`4ZeUG' :>-//w X> *2##(--5%)11ьF5{ L#+ pdgwBC- Jʲ())1322 I Æ$E"]IsAA D*ɘSen݌;v$UVVX52 覤֭SkU1R0z-Iڱc!I%]:%$$?ׂF;RJJJ I0$)D_ B$f%ӪA) ̘Xp`lf5UkWX`4G,cb78oJ2feL,0wk.Ueڭ/@RG oɷWd =>nsw5 4vIENDB`RaySession-0.12.2/manual/fr/images/session_reseau_modele.png000066400000000000000000002206341417052567600241320ustar00rootroot00000000000000PNG  IHDRh pHYs+ IDATxgtT׀gZfN EA@4z(T  Mzf$@ o,f933,9>k)!B!  B!DQ"B!Hl!B! B!B B!(@` !BQ$B!I-B!D浣Zj=!p>{se3< !3JH#ސ߾XjUCz !7www<8=y}ߦphcB<< isBDFFbo u 1ST6<l!B! PsB<=j+-^EoЃ( ӹs某y\Q?ABjjs-)!BA}}2Y12fbF1g=6b6cV̊bj< fLfF#BBQ0R҈MBQquGRa2CDR22gM YkL fvz4Z y=BgBQeKWco9* 3olKՈOb'$gvWT') T( bVt"9OEjիc_XaE JLJ왳s2BSc9b6a"1) khv ̴G2R!ZjaooO```a%Ϟz\/ᡡ=!3ȫD)jԨ3g͊*ka]a\l]"o~%ke?(m!x܆ `TlbŊIp-(4a!{ߠ).u\&s "9v_[~L;uN]fMJ*xݺ|׳}Nʖ-@ !^+UNGj {8y` !DQf3wG.NJZFg1V}[e|+B o_o˖YݛaÇ3p\pFy2-E`6M7iXN mUOwgqAGvߣ>`kY䘟ʕвU+GGG 37|t LyYf5-ZdE4Ee -5@vX`>)))XHƍ)S UUsHJJ]l9jԨ\2?7M6q;vl >>\ry~?yw9ȑ;w~Nfܹ1{@\ji7A$NYi%\ԦUߴ 68|_."U,n\zC ͭ8/Ѐ0N> @ O(L&:o\zIxXձ0܊GBBɖpcOf3ǎ{-~F3jz=UKg*EQQQm[_^hؐk1112o0WƞMb\n;FGV1bU_R\ǫrJDDD2q$zꅢ(,Y*VH]P?i ,^...VǮ^Ɔk`-,\0YpĉB( Ŋ(咹UL1{[&VE1{ hG.`N :5 8\|#GR|ɧߏ\}Z6mdNNPk4=z4^J߾XpZnݻ[ν|2cǍ/d2`6s-x<*U/ ~Hڵ ={*{-[|fZx,z7WWЀ;v0Bp'EO^n\ݲ-b`gHMZ+9+;9 v69Ά?|¡Coۙ3 ط6lXϵkyYϧ~ƾHLL$%9QFZr'oI~P`@cFfW :DbBz_l! Y13x Xك6*YG7"rj,]sꫯPFlJ Y'ptt >>_Bb6a4V7w+x;}+x+NZk!1x;b1{;LfjUsvǻurFeqmQ x?L&-^vT&L-ZxSNkpuu%11/@&M,׮]w^88:bkvl:_[Q~lEyj*<*"m}}oڇ1Gum{`UԫWukV}<==)UK/dwXWZϳg?u&0._ DDZ3$!*&UXވ"H0.î3{-~9z_n%$q ._ Ϛ.)nݻcccÞݻsl{ab^d TF!&&EQٳ'NdOttt!D^@pp0˖={XpN,[ϳuvk^/.YJKE !vJS1R22S66:lmPTT <)['G;ʔtN'G̭ hW^y&ѣUyvN.]ٙg2mG~_!ij@Q#G0|Pw y,]%.S ժU/RŊo ЫT((Lo_gϞ!::_|>3 V;C !DA+_|J$*Tx. by^#H!]ZjfbV2KKpmYxX}n\H(L&""" Za4B_$$ØXj5 ߹xB طEBo ɜ̣VYh,dzWzyY!==ǂ 5 !ӢP7IHHfs/1rpf|-fbŊa0D8::У{wV\E\\YqFXBg#"r/۶l2lܰk&|Hٻ۟7a*W_ҥ>l(eʖ}B!"W6=boظ 7Ym8446mF\\\ۮ_N˭[q9P:{;!BQh 5Es,kԠZ=!3(1!3gO?{y#.CG`3՝.Ϯ0ro!xXC`i( gϜ)a!# 0ʙdsq̹=yNdD7gߓթSPíj N#>|ǩS888X.]ooBOR1tP͛4hpa)Ϟl!xVE9]GGG +W`ƌ1L,YEn:N͛1ۙ+_`ٓ쿠QbQ,? [M4 2t0ϟWCIBMqwwN Z:W^Rp0ׯ[nڵjsQy *0矙0~<Ξͱ^^^㕗Eo-]Os`@ҧo_ƍKfMFƌyٴ3G5}/5!=={Zп__^hP>s%dt֕W^nNXXܘ=O/5V-iKtJEٲpquYӗhEBBB48޽FfMiRzs|zCз_lzf9p.{-Ia[!:};?kVbEf}C߻[[6qss11 HNNw\aڶkǂ-i+V,h4ҸqcK?^\`y)nݺE2eۖݻwS\9*T#iڬ)mڴaݺ?DFF(}_{/sˬll,K.}V-\(L&G˼bcڴiFܹs :#Gek;vQRD0z*WL]|lXZj9ر . &:%{I&A_X+&:WxOOO¬V}Xpŗqqq5(ٳkz:v6SKpE5$&&OOO==< <߬cccr\x-=yDGGiuˋPc~~4jԈ9s~ʕ+=z4cq\L8z( K,!22+v/OIBaa5+i6jyhܹ \NHHgժUxxxP^=z @٬ex~[_Rϙ=~YDz=YyxM62`@K~sNPk4ln޼!CYEZ^.?:vd)?hggg F׮]TXXۧ/[lӘʖ-gr1qvēRRJz[o7-[BŊ=[!7gꔩwwgۻ>n q'.Cw(Դ)L`_Vm)lٲnݻc2x7g-:|ysrfHJ0p`۷3y$~+0_`žߵA bԨVžm ذ~=7ldKɒ%QE2wl޲ժ7@TTcFfڴώ~>|ߖ-Ә^m* dMٻsYxR3́8{,ǎW8 Y'7G}>^8}=f ;t#4:dE{jfڕdU\MRgo'Md߾}y>2gHMM%>rptĠs֭lelmmt$}rb0ppp:gglmƛJ+nʵvnlllpvv&..[ &o?O aۻon9|)( 'v"qmX.]:縃B<+d[a^Y`~^Zzgog%yア4jؐŨj5f}74t֕YͤsNB,2-]HȰ,>:p ORaooObbbױ#==H[T]zMۃX߷es_Zji߾[oݾ};B! "KXv5+̙Et[__~GKkVѳG6o\+ٹcM3KZT),^۱|ץK{9fTje/5iK45:NG֯ӽG/^iҥxq_|ހ}ӆ:Ӣūyhb_0jH<=۽g/f_DÆ9s|ZXuОu6VkrrϧMeՊ4_ߺJņMЮӼy3m&*!xd$bFEJ ŗٹӏ/?%Sv׋Sh4dΆl63zHo77WWn޼Y7|dܟm{Yf' `%KRŊ֪&>>B!ÓEF: IDAT^V4 Dg&~{nl^mZi@LL,jq@r x8qqq|=[>x._c _@~}\y8F#[m}vz&,|L#BlLضm=wj*@fQ#G˩ӧx@]w1ϕ+W-+F !S>ILLD3i6_j՝gd(v y3}gt(Sո{!sM b##0gDB;Ucq zEw*z|(U5A΀BZZZ)vvvЁ:[➪IEDZzzȟf==xM:9zxRJ%*U(F_X*f]ܹ }Bu`0?`ݚ dddw !DaUPLlDQU57W*.ϟ4k4Zf89B2dP ۧ*SU%#\WNoAAJbڍ`21VyUNϏ~:u޷_ҥi֬)_MDݺ,퇇CMTT WWt:ժU+BQDThtՍ8F^ݰC7X~Z-T/Ɨ_MC"i='NIj^^^6ח?3nz̛?l9ִYӇJb萡̛71hRIBY*4Z-:ɌޠGYEAS79l$:᪾T*z)9;88@N=Bo0Nw׮] rlС鹎a-ȮO߾4lϬo/gnELJ?EQ ȑ,_G3B"Lՠf6zzC揍MqVAQT$4 ̓hZ_پc6mbŊMc{t95רݹ_"&&͚Y l ??[mFòe1lpK?fwPL/_;9p/O`2eTt?¾m!Dv퍿?}d ^TTH&ND^P%KAŊ /ޅIl!( z45f3V1#T+ PP@'>.3: ?yhptt$660\ 6ANgM_~cUo @.qrvfѢ9r˗/?0v8 L& "##}BOJ%00޽zb02]6AAA8pxO` !DC]l6dos)SѫW/ ˖-u@fŇN/@7i]ZzZ~ϛ=F#7nʕ+-_Oܼ͛y_/gЧOoƌtĄB<&f`9֫gRdBYި*WpԯGPPУ(wƆW34Ecyacslti7.Tw~y{{s5͏V &,< cfbV0+ff%'b6cVb6R)Y!7o~=ǣRس7ɓ&o> T јlj\]]IJJ"%%:م.xTaZݷ`'ƀoס8u=W߭vڼ9 /X6+I{{w>xCAy=bi$$&RU@^tzΠzEAš>]|E1aʸ/E]Bzz:35O좥 !D^H-^%\G_>le'|ŒXi*S !7c)U҅!1x])VRcC0fpX QaWذ~;vuF!xH-(5i26uj&lduDx^=ص{7jْ_o a0ۧ7 -碫Utc|;OyU^ E!>.׮>qqqܼi4֮]0""4kڂG'֢}Bq (͍7xfiN[u=mc^]zzIBԐfDc#>@F 4#իgyާw/&_#-ŋXb4k{9|8Ilߺ=zFN-PvvvơX8{ -|Zsi4|-uz[~$vkUy`G'pzl޸$P^B}z_Y㛯(QU+ӬYSw ѻ9rZM 3Zd[=9b8Æa[;d C۱-ZXJ.͂yg{vIwpp෥KTQQfL&&cƌt%hf.nq4Gk!Bf.]̴/СSqZJ9ˬR_5o;qqq!-- 7C8y2/ K]lذ1 :^oӿdԨL9ZNg5NgYĦRA2ӻ;u&U?h߮\Y"0XJ(5Xv6nb常X6+i֗Yzjժ꘣u[˼7]w믾 6EQp\;;;}bB!& xHaa8;9ѷOoV\e Ҹ|_q+Fhh(^^י7e˔ӯOf2ѨMܮjREGG|?4WҾ][6nLF ޽;u&>>s/)7 '|@jhժƌݱY,FܵPR%^{-s[qc0r\ܸ7`' 䩓:u!OY( ۶mGnTRȬ1jbcc9u:3IHH;;|]ղPΜ93z :VU}~M,,]tֵCZ^Sw8::`ogGzZymZ[5p;z11ќ;"?)_oWcQZM,m7BΝ2n\g1ϭ)lL珇'sZ֖g0q3gr96[͛!1<]L2̜ qqh4Zbb`'뒥,Z0HnݺŪk,t~I?bMܺu ~] o?Oa ;ٹӏn]2zH W^c $'%q￳`]7ۙ?WZ͜ٳذn j%˖YJ*&0mgt޽|kY/4`ʔOgzs"!x*WԯGPPУ(wɓ2uɓOP3ݮ򑜜c#;ΉZٙԴlvvvzŏ^8ٷ:ϫW;3C6I>899a4s`5koAT*\]]IHH,3\ L9^i~\^'_UՔ.]%S /Os6Vz#)C6BTaZݷ`'Pj׮ɓ'u^ݺu Mrz9-нA$ٜv s_ZZ_N{]$ݖ%<^˵mHp 3տuVQh44hЀFa0~hnN錯u=c9.YB $OE37ءCλr.ܥN<6s9|='ka#L툏O`ȑ~3:uZ"]F˜V ˥E.t9! xbM&,\`2 h4\)YkKXre\ϲ(q**=VQʐHSԲF8ͬlCͮ [Qxjժ==<[....x :7ӛ}esɓ&ѻw/oNf8~x!6w` !Dէ:$J߸PRsU)o+u4{c/܏ZB[_EˬRR(S nnn4}%4~F{P B'_pE~MB~ݛaÇ\pF7` !D\9l4('*UCX\zr%K iѢE !lΝc!9*[رx8|!,`'''^QE!Dwwn nsj\32a2,_ǖن>,v̍*153""4aۅOx/PLJLYrJ)oO}2ch4ݻ ]T2һWO [&|!k&((I !De4Bj-s1j.akkh׶39TNc4˻cZ0gsf,\p 6oD瞳l6{:|3cF !f`9֫gRdBYި*W6B4?.k^C4U]2i|wL6`ɻaز'(a}!V7LUw,U~xf z=kBUMju~2-EXI@Eo>/+Li/a)WJDcPZް\ǤR5d2kv\X(ۅQ[!+|7e,U]Qx:^ Zp5Ao!D~Il!x\M45S;+7 UVxv!x\d[!i&?34L{eưd "u Ƃb2 ydBH-p04BMlZM* !x4pKu!O<U*W&4,'{J!xڹSjΟ iEv\ !c|c(O%""B!D[!B$B!H !DTf5|}}-پ}c=zt~;v+VZښ7o)eΝ9F/O7 j޼9cǍ}Ұa#<=<̞=QOE!$$#G|Bqd[!D۱}͛7rA$''qUcǍcl޲>۶ӿslAǟlݶGһwo5l؈]vknohvu61vܸG!ġCx{{O>wQ}ǿI..$$!.-(N-S S>^^VXIbb"%J~` AǎHLl H)O◘H`=PՄLttt1׮``q|ꋫӧ~UAxI$(S (&T*$H@*eːfooo>/Z޽{[ZjO{tTX6mC\_+J~MwޡW޴jB7k_ /[3aDNc͚5<~Ew^W`_v_>ӦL5a?/C^  ;t{i(_<իWG*~ֽzL6NQ(/\Ν;5$'stss td2ze~Gff&z&44.S СC ><<*жm[Ν;G155c_?CDAD"A.UU1P(U;{;J(AjU)Q>B geO\\!ߟPNuJM7l >L&cS=/V˾8tZF1h4>u ŋi8pNoѽmڶ}#:@=RœZ5kpeF NƍawUՀO O4Q:((-cooObb"YG7kjpʕ+XrFr%-|رKKKbs?ZMrr /4ڦؿo_1{]fMF[7V߾ciaɮݻ&ACKYYYuN9AxB3 ENڔ/_[4n\AQ` ˎ;HMMpϯ$ у-|Z՗5kֳi*VF]iA^*у-pwstiwKQ/*ݷяسg3fLڵLpp0A="e۱4ÀMTbbbqpt\]"H8}+ ›S$:&{{KALLL6u k$<<qVY˽;w-XCPLiJ-Cqv.ɍ74x/K/GA0VvPPAAA] Aed3r(~a1>>>Fq_oPn]៿ZA(^b sHKOg#`4j0}ߩWygxC. GKvڵy9/WF2RfϚA 5ا+!(8C3RK[M띒Rn;Gт E"))3g۪$gd`bbwM&Ao.]:3v(222ҵ;aagw19sVAbB"QQE]RlY151)1={tgX[YEGG|Jl2i\̛3L4jFOyr8;dϮsf7:'552eKw5AWL )&&&?H򲱱auճH{ڵm˸c[pp@j&44\ ϭ\rru޽{|ү?G0lg-7c27nOk߮-RGTV BNEq-[{;{菷rJdfer R)>>=l"%5Uvv`kkKUHdKckg:+n^+V\ŏKoT"anfRjUINI~};TTS""#'33 {4ຠvݽ4VFH%R޻Çoǐ&!&dfd0f8avy_:лW`v%m[:Yɺ$V{eRKKWUk#4oތcFsYY~ P(@W_~eh׶-[u555JE `9)]1qjՒI ݙ;w̚=={п_?:o%?0t`r9jz60{Z5Yxr/h`?g?;L(6X֬e%b,]t/ D=\+4j PР~}9JÆ 055՟ӺXpQ{oFKh4kZ~ߵC!H^s$? 86AxYJV̂GOwU Wr/ eM7C fתUKJJJ k׭G"dY)x..TV7nrE {Lv ]6AA-[2ǁ]d2:jpY -͍۷osih^kkrU}Ǐ9u4VkPwooo̟B'SEԯπO#Jٶmtf'O2~88|7oٙ s%j׮En݈fH$`iaITc\\ {vhٲAAƆD{sq]픕U_rM oԮ-N1ȕ*` ˯lќݻw~n߾m}9~8ƌwd豸QZ5^fѭk5lHڵٲe+͚6ieeIjո_z`={&FDDL?~G}>O^ett =zu6*9z}y|}}h٢9Æa9p B'ORdv9r4;3w; ,,[CZZORR""l*UD-g9@ۭQ,aŪQߩ$DŽk­jcf$DŽpufZɮTEJV"[vQY@ɢDY߭!b HHKKcyHR&NTjp YPPr% kXv ]t1sԬYTJ&ط?{ ƍR|ylxyy}TBv eP VO%˖`˖ySV3˯|(.^RSǎl޸*U< `j%mۼ\3gׇŸ%yyvo[[<zcW ߧ# g=}*Ycb^p8/WnejQiQpPoX9O× $ u;\ܱڝGw M`'OҸQ#vV0 $Of(_pxV sBhh(4hP*DFFb*ڵmK ~` XHzUi YTj4|YG|D5r_Pm˯ˈ~x͐|(q_FOtڅ5kױxFuyvHL}>+E U Űl n"#-`jtQ/)LH$3s#QRi8Aqhѐ($RJSs2RC"DeEfj'|Q S t+LUh54Y>/Ax]Tm7R^ sF;]:N»1:ȇU]\b6k\>lVo ]NԪS࿎oO{?> Dq7?|]:g?o;&&gV{`\\\駟!2*:uj3p>.}_GM?`qʨ# iסk׭GUQu:EXpjySF /G?g;Tn &Τ;i2`6VPagdZc/A۱+k'frt \ukif̬)W=O9χ[kTm;(M" i5뜤29-/foCQF Uwpin|D_ٴ]ӐO^߯!MųiڌYNk5 WD?f ~7/[sw,Φ-wf7k bmD]"""e߮j|9{ÀakkOzvfs3a<-[V '7jPT*{\pw 'j?խ~:v/ ̘5Ȟ|r8;gOdd$ .үt{NE(@5GGcjnnDq8p0ykjwZ_;'IXyrvB'd%Szs}{&8yԠ»PỊv|>ZFmS8|)`oȽ{FXZ:w6oCh,;wk׶ fr%aqqq\y`'y͛7nq?T*6gKرm+M7&%5W?9]rTʴ)Q>#G|Ʊ#ػ{Zɞ];o,t|ݷ>x/bi̚1˗.Sz5k9}ڵkɍJu;T&'?CIQHOþtY$G(rROkOХCćߧw}2Uᅫasڜ<t:56Ϣl֘J0C h: 䬌46k:3~͘Tjԙ﷑:Oˏ8j>բo7#ڌYwHDݿ%yM{֍Cqi{) z;HGnbF׿sq.GIHOC*Ş})tTJFj" G~nTHC?i1QY﷉~-y ›DLUTlVygT)=5s]P:uii2oχ9 -fuL2 mCU[.zӎtSF7"5.0.e%TV[J IDATh5Y'ɒY9_aZآL/UJSLmHϽWmVV\@v>cG%55 &OJ{+]P HOO7eܜ4Z %Bݛڵ@@NCѺuk6n܄N#44K.ybqC o!NB%$h"vw" pѢkHIE]Қd;2,G(ER'TZ1"R={ҥ 55Y3gЪU+|q>#(JVX3=z9JO? Ny_-6Ϟ;O*^Uxq?{xk;qՋc u /Pn];F^=?'MHϞ=8t 6ի\ۼ[-%3 -y$LiIBFYR23 і dhd2+ur{ 2TBT{{{\(dd9{ oSk4|73FH$ܰAN=d2)cƎ˵  R򟇛Ιˉ~S.ڶ]( } {ח{ɐCDžz[-2[[RaiLIY&hbcڜ s) D-boRIBʼ̳㬟?~=f̜ɪտ1o|5)))tLƩS8v}]YLVXIf?*W旟 %%=w> 5O{vcAB =EMZ) tYRL,Z$%ghiX$,)[ZFfiJF \[ZZ"ˉ{)quux{ULFRRRHRlmmsnm;;;Y_ mۼ2/B1sX:3[׈آAIJJziRSS !:&&&bŊd2}ݽ{]{}$ t> 666uJqWK7A7VDD-7uƐci̙= (|Ao h4ijgWח-  E`SjUHJN;ӻvL{]j UFƍ]a^t% !$$䕔Q<*xpWR wAy)cFdϮ|q֭'}ĆukgE;vIOu_עE3,͋ϥyfzR=].oڷҲZV*Uxw5AЊ[Ph|RRڽ'1114RIffVeI>baaAzz:jZT*%==*JQT$''nR/;/JLFZdy!H %%Ũܜ c\ yY϶D"_umپs'1F235%%5_@_f͚Rn]6nڬ'– mr9\533CV;:?3Z4Y]%PT,/rRIjmZk>FJ?SYvV*bffFJJJAV= 9 @SǎݽkװuFj֨OqbZ4o8z >88802mR[[Yqilmmۚ6i5/'ӭkv=xxxfú5l߶GիgZb۷r>6mXzC*2l9}ڷuVc;7n~LժUczU+طg'Og>rkkG,gˁ{ٰ~-*UsgNvwÔ,YRѱ?.YL c;RfLʡ9tp?k׬ѱ59vOaoML8G@>mgӆܾ'O,(QPzڵزivn&>L?.Y;q 1:ujnoXZXp`^͙mhҸ1֯5w葌9B,Ynݺr!fϚaQ#;fkиQ#}+ʗ_cϓoV?m[6s~qNQ~ukyطgJ2VP0jǞ];ٰ~-GA^"Jك3f٫ о][z'ͰC>|(}}T*KK ~2AA(J6[˦͛=f;uj3+Kzy{c/wb XZlA`` ʕeY77oRN/ZΝPϜ1%? $ %7F Rn:ڒ#&~E݈zRp_o}˔)0q/]֖MѺU+_=zLLL>cIjU9}Oj5˕k9-[7*13gaۖMmׁ,LMMqbτ_#HXpS wŊXp>|O %5]:3sΜ9 @*h:BBB ,ideeat,0G :8<ʗg̜5T|}})[4>Gxzx/… ,^$kGM///-_sb=p|?ʿ>h֬[Gn]~^}5v:Vޭ+?.ɨ> YgXYYqiY3gpA>Hn]1͛`cmG$''ce8-SJ7٥dffp5<ʗ XZ[֭[ۼۼ dhZZ- $$$0lPN:EzZˣhP(eRѤqct gի @\\T(JZlJt:d۶oݭPSnm ?ɉҥݑ޻G؊+joFy{{Uݻ;v !15kסj9{w7B{l޼SNHMM%%5k++\]]u󟿹7t[L̘2u~H\\ J$99RJBjjǘW-G=96Դ4}U7spdT"7׹gΞe 9ILL QQyع&$&.}ot.^^X[bmQlYbbc?HAU+lg z,\B`o 33SkݚZw~ƍ# ngp^//*\xI^&Qӓs_'8ipLʕYn= ͛ :u4<#>gٲuL&7̌'N fp,N?`FÇG}Xh1y( 6h+ `o'?j;?ʥmllXʕ-ǣGʤXXs^v;w(_Tѣ7a0x{{s3GPԼiSNcooOT*W.?EHHA'AkAzy{quq+W;J̘QP(@:W,--9c=+W" ̌r |*kB*ɂrԩii<|HL5_*Epm>3o//unnn( ?xP8ڨpRMsn4nL|BÇ 5(cyKe}+R$ܶ=Iy&Iq:mARE`'`mm-5mGٷs7 0w|NGud͚uuj/oo/9Owt,=888T*9zL oFC*O\r囇NcÆl۶ _}ɤջgΜ̙|ݷ:uB#abbBTd>?'''*UN;gӧM?&Lw^}Z4oN㹶lտwqq&2zKR6i̒~,ގ(J"ywSѣ*ۋL} LWT|5awD=);{hO 9xxzV&:vMcjbШaCo`ogc=O˾}C6䏓' ygۋOJ9~6rww\x^...;z[d<1?@2Nj5$% ArWdCD\Jrr2_Oha B(W,˕ӧ)]Z+GSaa4kTP%FK$lml0S=#G 6Z Jsɗ7dYbNʕտz:+䛇VOdffC`} <"""III[vqqqRvm {տ!..{ֳm-H[9d?8͝wqvv~̙;(O~`bŊy? N;Rφqt xy=ίܧmʊRJҫxzbjj¥sl\z{W1eo|gAbReEs5[[[LLLn]<~&x{{믅>OF J npr9yIJJ6V8#+ˊ,23 +U.ݺUde!Y [dg(IK-HBBrt-޿;Yn rQfΚ << - 2gLf)tk7sf$,<ؘXOH# }APFFgd1 <TJdD$gt3OLJ̝9`e[V"LLhjRR7"oA)IO'}ff֎释{jbb% W"`gkK:5WAsD&akkKrrrs@[[[#H/tOgHLL4.J!===y!w -J666defZ*U?ot K$lmmOW+w>mxP*$Dži^'#?ro]\֭忮OiG7ji2;w'1Q=)DD&bi}{{R*[}k.an%TѨyW,|fɿVA^;wvX: ܿkDL,xėTzZZZS>Ng`I^ P h5'.DžiΥm"ދކ{ [T&3wלЇ2ʔuBD6$YHddfJigRAxU K _"_*]x8}6m8~xA^_fؔdJt ;&÷]d\n\n:KGRށ Bud~͗#VdIC&R)BJ {x`O } IDATgkBr]B{)=#"""!.k/I*b2C&UmI˖9z gNQr圹4Z4l=HIJ: yvuuկXko@u8?=_mggܹxwiѼ/DAYlj2U_W"jy8Ax}e!jܾ ""ĥwrw&+=WܽFch@g\CrJ9,!^&&&t:-[[`$P(>?7ld|2 ūWԮ]'GGr:֭[q&t:\t͛7ss'lARiRF5XZs玖8\r:]P ffTfnDG˱bfILL%P*4=q!VZ!C055%&&/ƍ?{QGӹs233P*M>|+++fΚEd-};\F 9xk׮Aз_?>cJ%=b矑±~tҙ왏,--9v܏>Ν; >L0%Ax^_`X|9+V,7H41sǟ0x/_VU,1[-ebbEɒ ӐHbiu2w(SƄ5\Y 7iC(_ޒ#Ӊ +D*Wvx(J:t@zu9x׏޳{͛5YӦL>/Rȑ03SѠA}6RDd{iFGƍ9ssHF ;DFF2`@8{ :vߪukBCCs'{E۹,%B G~g㪺nWD0DΜ:n.l51] {~_kv͘ݳt_r=?;TM?ǃ|0}?׿?]usS WF"Ax%QT)C)|ƈ5uVQʴlYKK2 F[ocgg-ptt}%7l@ffŋA9`0NVw6姟,[Hl$a08y8ʖ`ͼ{,۶}͛6>Ax]ƀ4hpsÇ>~z DVtYӦ|ʹWU ¿GGʖ-Rn1666aaa`oo^GQW (J ,AJJ NX[[3{\vرxsmHTd"M~tH^BcG133FPzuoVdhZBCoၛ[񰰰"-\ck|؂nZo^) ̬ Bղm/ Y|97%VVV$%%MFѠPj)SJŅhݺ ɾ}*ƢMxttt2[[[bݧ666j$IЪU+SلWVVVEZͅ ۶B6mG)pA=+V$&&Cة$b bcc"**C|`[YZ6P(033wELY30bl,0773 }gZXXu %*Ԣa-DZ)[,TZFQBZ-|Gz*T@mҒ֭[Ere17у"kNt:{ΝXYYE$ tuݱcֽgϞ`09MPS=͛7t2yOu %bEo8s ;u܂1cRjUΞ=ɓ'K:'*O^Q/ h4;<== l;;;~Ohى)'Q3s3"##? ش#[ޥ_OД*퍇lلT)R:l8nFTr>v{rbru͍e-|T*}LP( 2t BA|}CQvs'_-[ 35jNRRqqTZp""RMHN"##5{w:4F``5,ZP(Xt )ZY3g2s,?AFF۶ݻwMwA] ǎe%r+4(\]]9y=HAJQ2ү__;f:֩cZk߿,Ś`WZ2 )119 j3ҥر<ʔwIN2ut CV-T^O{wƭ۷qpp !!??j5Fx؂ Qʗ+˧r=իs0clz=!"i=z=q!;ghA^*RSIKE[Ĥ($%EckuRRVVJr9 [Err JE/$Ǐ3{,4 wܡy888jtYt>>>wG`0HOOg94iGGGT7nsء + -??1Iصsg D5ciDٳر3gC!ǿeeewqqqT) xJ%}gcrmL'-/Y$IH6YKrrNH@@W^5vcowIgd&0} #J*UEKOב\DFLA$5UOtt2VGtt2YY:u(rRRDE%MRR*U2IIim+~HB>|YQbKKFpiӱʕ}98ʾDDDbkk˘FQ|ݻ\!ڊ7CV*$q<q\ErUNH?gN<2No%=Xo̠Osqbx" %'113Iq*};mXr~ʹ}7nD#I2BA+; 7nRϏ??N2W1nodggQظ|\ `pttꃤ9 S@@Xҥ9x ϜU\A_ōRYB#]IDnSvLbbbA^QŘ`+˔)7n0_#ɨS6LN)IOpQ)[ݻ%JWi' [n5e==M)'|͛7CѐRŅz, %`H89UE&{-$HT9hCDg hڃyPn\~~,i9$q!ΞEtt noSOsA6m\OBB";tϏ(`Js<& *T`jgԬQ{w̌s[﹤$Xx1kܸ1 za1 jD- ۻw/۷o:t:HA(  kURutOXz H# ek١T>W^'11RAx`nn3gJ:"+[LzAspp`8::-T*G>S;c4J$$&v )'[41NAxM(JXj[eUFn ~aGNddθ80y$mV5j +++W?va=+cƌEPPti9zGe/% 6lȁؾc'ǎm۶s,[G3,GAx:ΞN:w]_]Vzl߶4&M:u cǍ`)\OLDgd2eӢy3Zy?o4o֔oE?r^+{zގ ޢ~ӷ_?1scǎۍ8?&O1%Ϙ+W_.k6Y)S1 P7ӻknywܙك",` .eKMβ3cL&NHZZ`ݝWW'֥RHNNQ #$&&r\˖.C$ 'OgY7iBDDIIx{{ETTuݝjժ`|ӵh) k׮1`@ #OdG1[dmmMJwRR%|MDDD_8o7mmm)SddBwϮDGE:cc1?g(9CHqttdȈRRRpuu%%%%טKړRg ³j^Odd$aaaŕpt +֖5kgMyZ D$|||hժSKc.DEE:EիgsʕC䚀$IDGG)/‹]"11BN$+VQQb kDRQzu7nWQT/}++kRRHBs.kSR(`2dA:urVڥ+v*R ;WbVsss¸z*}זdןCD%Xћ }|ܩ#{N:4mڌ ^^%^D kBK׮] \OT4k5,ZP(XtIeVZ3fԚE_SG\\C aʔF/^H1DGG3t+B&L ##N;ɰC~ >j\ƕ+W ?x Ebחǎu؁VAA.]̻rߡ=f7Ď /Q:up˸N9j^uV}]o0>}%:.&M'lAjѢj:sIIIU \%I&/,>AW xaN{iRSӘ7g6scW_֛57n,4037c˖̞3Lŋprrb FzEtL :v>}@; 9Ǝ!Es 1|QF{\?v,JBάsص{s=\ξ=XtK.{kϟ\.-g}fM2|r9VVVl3?_)W,cƍ7]ۿ__|||9jtu/_Aiчlseݙ6ennnTj~ٶs2C FPP^=όAx ĠA=wef T^e&za vڵ$"<[<<Хs'k>Z-v;B&LХs'V^C8sݺ :&gzҧw/zMxx8,ߏܺ}W1`<==l՚d0^(O°#x~~YxnHF#/ɓO}m6m%,oOIBB"nnnl3[lelڸ;;;h:~(nf4;Nttt2L#GXt6Jj _={֖'M~9{,ڵ{bdӛ>kkklll SA(\&͚5 W4y iڠR>[n[}.O$III]}Ȫke` ;v"<<ׯs1Zr5Z4oƤ)SMSN)G5j؀(Z*zy͛oɶm۟,iyv֕m`kkKlL j'\. +++pquK\tVXf UVZP*8u4Ge 6Xw^z޳ /HAJF&ؑQ\x$.]gK\٪6&:&h 9Ѹ<>®{9⟸^Dڽwm\V8V}6 XYY!ikԲ%{A1w,?ؔaY]>W{͘7201NNF= Ir{EVV3߯\.g~Tʧe| 4oAwٹcii\t4-[ҫgfΚqN:ν1c՗=|T08G}VN8o{6AA^%%UL&Ζ|.XXXVsT*)UJCBBbuZYZbnnNbRR: .zi(󲳳#99|Z666|vqv旭 jӶHZTJ\kd |gtApҟ$IOL322lxMZz:i.캧Y<\:8Vo~Yg'ːz4_CAx6%` g@~۶ Zm l,!(3fkR91 IDATYz (Ag%WOWabd{Vdz|P0{#Eo 3(UD◙)kAD&:c ܺF0~p ΎOQAȟHA^Cps#2* 3*%Hpb"oӫK3E %J*ԭ[x*"AxF|=IKMCT`4z  zEA*jt '}tOE$؂ DvɠG1[h7b$qqԫYJL/_6mҮMZX{;{T*%N[u#V$i&'^C21$F ހdHz OUJoeƟi~;5kƂ?3F=HR /L&c@,Zŋ?ԋ- f$I"%%$ĸXP((*Tj5Ȕ I232(WƑsnP7xݶDDD`ii I Cn9r0W\SBʊt"Ͼ[sy{׮AxΝ=G:u8x ]tM'йs'K |r G[0у-$ k9nrf*2eP(( J%z d  R^o,~Wtbsׯ_'++??MBjXz۶mr`ϲeiѼi۶`|jݚƲo^̙˅ٳ$akkK||<*UΎ BL?c_w^rN)S8Loۂ \7ӻ?-_AfV&WuS g믿J(‰lA׈m[TBh4V8R5XXZbfa6[ؐmhT%@ jrT&?**71 @rYsVAϷ^wwwU΂$ yh4vgРy >O%YщlAWB!\ #Ӏhφ½hخ ` #=R\`PJ2\uF IxຸX, }b3ښS7MK::9BjjjqBzzXTT$r;;{ }A(9ZМz"## #..+\%ؕ+bgga'iެ)C g>/ 68VZLYӦ4kcLJ^X|ZR+/!7pvuD2u22.4n&)(aqڎȈ;ܺ] 117oҼyЪe $CVHJLss ƂǣhrMtuuE$ptt,rL x+!t IXb1xyyU!>Q ̸1ѫgWժUt }~¨Kr`oO͋\֖RJ=IΝ^Z[88:UFNNݚyQul4df0FV;DTT<..NP\^zhS9wzMP(Jr95j d|? 6%2Oʚ-$P(ܥܭ[ܻw`1ukq/St<,,WdןC %bEosՋ:uдi3*xytx*!"Ċ /, AddFL ӤIcطosfffdggc4枬'-(\e^M>dmmMZZi6lad24))k id2 N^7+W:v`uܮ\.ܜG^>ں?kALm똫eTJJz]j29l\mQV55(fٴY"`ؿ `0üXTnU|?cAAYC.ѵKO|gc4Yx 'N,9U*>8 O_۶`ّ@A̝Culق:ݻ1j>8oM#,Y RXjׯ_gL6vеKׯ+Mh+W].\`0&:]qۻ"pb prV\.TP(P9ۣ+e1qgvt -}zbƟ6d0gϞ#++""#ik*T ss<ތZYZ&BvZo{6K ::8pBޝz*s+ƋIa=vcFKfs|gg' SXt1ݻuK% S$ZoTj剎 sK+j5 LBFRïACv* ja8o%-Fc{q*zyѼy3Sq'}LvGPf S[:.%%%א +KKtYYdf,ԪiC6%gȈ~~~y0Q{wR|9ӱr)]]HeUXz_mgؐ$$sZFw+3 EFh-}lz֦gg]v6nh4r)z<{ҵkgj53N\.sr%&%qׯ/ժV-#$m V4BK fj9*v~U7$DuV=؃}j0$k+[q'0u7l\'OrqF6Q@R|=z"++c0e|F=Ɨ_Obڵ̛3=vqn߾cjw}th۷m䉓̜=s6ҸxOlf:~73Rl6[ͻ#G)_dЇ4 *ڔ*.;D[XXT*IIs!:up'qr^RD  X8 ~#*Y^HĤ0 ֋lKD|BCFHِGy7d2UJ,"#"lٲ{V^+Uv% 6d2`ѢE zȑ#J:")?ѣ] $'#W)1!ˑz2EaeBnfE2Hz=I~EeoG`1=T 6Yt 6dǶHjMej52<כ!sN^:Hvvvq)Jd2Y VVh4 IRh4RSS=/ɰ~%zeҵ+j[9rI duHDxx8K82}+R~=\JZZýt|˚ӧw/d2Yq5ʩ\ٗw۶YӦ+[Q?FbJ"mwCRbUM动jDv\<(ãȺ}7ȼ}RueoidtlLJzΝ;B0βe?qqN>>gɉ+WAӗ#_si>3K0BN<#G1b$[l\rxyye/:|'Nh(]4;vq&:}7ЪU+N<Ŏ6J?oZÆ 9pwmtntڍkN8uBH;wb޽4hؐ"փ=(8OOM6oBxDիU#Kŵk9fiؠVɷ碸u܉5kיw5ٷo oYLB y4 UTg>ܹVCիWJ h|i Hr 31c3WW$d2d>ݿ.1CJ* #MJN\1k>111ܹsg \ԩӘć3jHnVٰgZy&d2eӢy3quueo8pOݝ6rY1s9j.^Hxx8jmжMݻƇpUz I޽i 22Y*вN;308=>毿*( W݇D~L_S/_T...Ij5jWզʕ+GrkҤ1uɷkk֣[KvvѣWoƇLda4m'DH&hDR֟WEennưa#H~m[XX[OA 9}7AWj*\s L0%ג$aĐBàqBeq>OWl߱'Oҡc~ݝjժ`|$I`00|~1;wnSn=ZjB޽{xzϏ'퍳3/_A4o֜K$IOff&BCӓp\\MU*_'lа!7oS@N>SMArRdeeE:uMe֯_Gڃ5G󙞥 n]ƀ4hpsÇ>_2}Fiw[.C b̙y*[6m~FF4 _}95ިAv ;0f8{3˼i"'ܜ !i[H?ёsfž];f 2BAz`?3fΦ~z;RB!g9ڽ؞\.gߞ],Y%KXhW=:ݝiS&Jmۘ=g.$ѡC{MV[VXɢKQ 8RF`А9.&P* .דHLL`Yn=>d|W:u:} Z$$$ڽIЫgwJvv6i_7nS@.WAϞOHx=/_iS`ooJꕫ5,|}}Y8M67եKgUʘ'*-~摑Lo "LvJ RShYih`Ffmlټ>nܸ+)))FEE"˱ggdЯ_>l ?0M6hdQڹx"NDGEa0L߷lْaGMTTWꕫz89:|Lt 6lpvvёCL##"r5f IDAT9;[ozނ Nzy뉌$,,pŚ`V"(ӧT ٵk7Kpr @<% :oSϊZF.W.aHh4h ^wLgAL2)Ӧ3ѼSyooolmmzd>u FKUfE\7""r}VFEp'b,طG^~3m*aeؔ*ŪU+~:f|ؾw F|J6oيL&ALFɓt2?\./& 1JE˖-hߡi|ܽFS܇B!'EsvE÷iذ?G.]>}*?> {޽g/0۷VY'[mvrYxBJ%^_):)7obDft4qq`4$L<А8n޼ɜ9sؽ{7ڽ֭[G`aaa$IDG$Ԯ]~OXX r>48WrPBB---M 9~={0w޼'ccJ>!>pzY`DXXƏcNHĊ+ˋG>PӨAӗ#qƬY4{ʧ[)E ;ʗ¥KԯW h԰QhTB#ٻ(㟙)H IPCW"Xг@S"zvOSSPOώQI 4E@AD@Ho[3?  ߷;33gw3y\tEG}^[:?~s?­V~M7Tk|6nDbB={p$+qw%6.at钌뵾imArrg-~ˋ^O5A{}*q[~=-[9y}3MLbBvuV/pqճjYn|1\. Z#''88guOa!wgfy!v;KJKV^Nq#\#t:x駘9kAAAFc4??K|+4S}4Mcq1v [~SK~~>O)FOh wN;J6uYrye%7h$fYY)1=:=;с>iii 3wOeyxM®]3lLr9aW]N婧b-TcZ9c_2w|2׭tW/ͷGIq1~prG~-{><*I^^wOz9dq: qtDZ.3ӷm2thԝMΊʋ  'gwj$nըIv%%h1]rf;gLlJl稪ʴ3kΝ…/rウxᇘ8N^/oM|k7x# S P\TXcۨc۞xS: Q\Tݻs4f-krQ̛4:DQQqcX,<#Ls ۶} ܧk^7qk ߟ\]B3uԾ>wؓ~ۭGarj$/Y²"$$a: #F` l2Q\\[ѷF`` vIMIٱ4' .jRt츬,:?{=>BC(**<_ff& ,, ;k=tZ! Nڦ:+? 9}Z"b0|+PTMWqqu᫯1f_2tM7h撋5L&7p}U>gUFZ+](//'4, _~2׭#1!/b9TFIRR)h7CЪU<:vd׮]uîEQU}=.׾`̙7>l6/}W^}]v{|dggqcl|ӍC6?'3gˬW;Nn}t*'d2;&&svEUYu֭8r6c5X,w *XVy";'ME'44gee'-7xǸa(ʞ={xGeP=C}yW$ }]S~}2q¸zː6o\7nKWqh>%%%󕖖^/p4?gukY*Kj$8TAUе?y]\>nG5p8̜1B mڽ[W6[`0 ri@4MnMx<T'!!9p|ғnD]㶻ᔖ.S<oV1RZZZUE!f`4PTT\k͆d񂃃Qy=pPN|?Lpp0Κ5f,o92Lպg)<%?Mw?_ASѰu&wŮuA߉nܚ\ =~qj wNj^oBML6s")-*,,\zGԕ&u8~߲mz3oZVטJhn6~ ?wRZwJ@Lhl!Ǔk]񔟙O\sV"Rk]L!B!Fgm8wPB!IJDB!hD` !Bш$B!I-B!D#:k/rBFL&:(x(.7B4S`̅A5`6)(Qj"/ݨx"b"ǁ]+GqQUŏ?\-Drr2lڴCi0IuEQ=:AGGvIpd0 &A!k<0-؁S#PPz(Bs؄ZT ,'͔(h_UE4BBت#$3v|s>QB0&**\J vSϘ_/<٠aaa,^ g82!DC) Yh/bܸMRIB4sz  ** Ivy 6ssD9V^4i06JUUU v6 X,v{q\xӎ3::7ZƫB.:kQ\|%DGEo>֬@u̲eo:YYY|V/_Nl!hirp *7?كhvTK/hN, S.-T]+zk C=Ap9X5s֭c̺>TE! 0ev0틿]t!00ŋS^VcX!Əb6~**\?}~{pp03lN௷dʔ;̞=qBӶeLW/WhNv;'MbEMbHB4S!!!ķNDFFռD;7Ò=;]CrUUt8]N\.qqqtҥޛwӣgO._UC7cNnF]chٲ%W_òޤo1v,w9ݺKݻG_uլX>{s! :F§+?pIKKëyY={Gaq!,իW`ҥK/s o'00"_iGnNDEEHqq11-NСC_o*/׋_rÇ^}\> xRL>^;wwk{B3~` LrIm3;ƎaϞ=MYI-͐h$))h"## '!!`iժQQQDGGӦMHLL$22(:uD@@o߾ka: eɤg0s,Mj}7%>M`` rb4s׃xnEE5;JDDI1efbЭ[7 YG4ط'iq)((hDjm۶RPP@HH!!!OPP`ZX,hFll,^KVرc$&&ϡC|guqqq< TϷۿeQ\q Nmnhq5W ?⪫ìYF.8$%&rh>gaҥK?JBBM) B4C\p[b&((d2Mii)f8XVv;Ѵm۶A pxxdee󻝄tp5^qqqyù}%#3p@2ߗ!vI :vH11GhKfjժDGG3)hɓi׮ruٳ!<c}ÆcuBk?um#̐CmFl!h(--tGPPQXXH^^vUU)++CUUv;eeet:)))!;;J0 x|~mݺ^X}sWc p8p\IzTTTiTVVp8jv{%{>SO6mkɆ B!~ xh߾={iDl!h~plg 0g˸"a dR9rtFCi裏qYl޼ -^Hjy։MiY.; ^^e+(R!^0qD-ZaܸL>jI3cQ-{4;M\I-PŬeڜ<(] :_\\7t ++:uu}nłTUU1fTՀ騵h4b6QSnp8o;o>WuyiߡCG&D7r(.طkd:fٲu,z+˗/ok'5Bьy~\hPV1"Vh]?e00z zMX, >U_PiU9ɯx/U62{}5ⶠ ^XuYɓÏhӦ ?v[mܴ?Տ9u7f /2Ʋϙ4i2kff-|qqqcӇϿvzc~_nॗ^f *:tH֭Y`AW &eB!5uVO߾l߾$BьqL]/W]a`^ _tbB*n)Drtꨆv5|99٤ڒvuy ˯ફJ޽ۧ7o޷dhbA9>lӛ>{QUU3ꏚ[jMhX(}Wdee1n|SQQQ< <3t֕K./>7fYXb^Ѕ?;1luͷx饗|1GFF2cLf͚+.įcnjf 喓G2idF~?cD0` !D3v1o 0a?n *]㏛0 lޔ;x1 hMffL… ;֬$55VZӱcG֯_GRRQQQl-}`An^}СWA֭i۶-[J}jyuˆhݪ5]֟OuNeee1lذOq IDAT>Y{Nrry9w7o> q8qSuR=L㎱c[!)%]UҾ`JK,X˥6x<*#\tt8Fx8Nu<Sj{{ˀ;o>yyyioVm۶3y'S׳𑑑\ CG}cl}Dd99'?*:1>|F޽_\?̗_|AH;hժ5QQQFZjMNNͅ纲2 .xDklx<(\H֭Y@AAA,} Ǝ}t!Dg9 1]Yt)GIHH WoFR""͐llh;`ƌJ&O?EIM7H":F|K#/<FKDF?IN5E mu$''8p{rϴifLn-ԑ#kȑ#\|%[oy㧟dInՠk]f&:v_~@E\ױ[1p bZW;k&]5}4:eZ_ILLbС$kG=Dۄ^` !D3(j۝q9pT @1i: k`v+jTUUyT{4R vX|k;v~W7KXf wOJΝٴy kXkW 3ȺYj,շ%űfm&_|I'++5k3YW71tU z>}O> شy ]ֿޘkSQQwOo_棏>^e˖- E1~8F~wf۶o1fO]hfJR]ҽ[W6o|BqLJJ l;1O/E:g`++Y ;lS'#)Xy-`\OqNv.,l.q6Yr}8zh," B4si{a0,Gc1nEVP\m6gMxAHl!8y*,`0pP!D2}BqST#@!FB!I-B!D#[!BF$ B!Hl!B!$Bq Bכpk!h$BsTΝ8p$B$Bs\qKl!hD` !9*$$P .BIH-(]9l\y$$$4uHBqdzacS ix88pB&LǦM:l!8Gу*^/F;vN0x`;<7ZFn<m۶euF=$$&d}MNI-h:tv:۷o:G}2/7ObbbXֲeKRRR0 6MCQ&NȢEXxƍoLJDСC1LDEEqEx}iӆ?={o%..oAhΣ( AAAIffio٨ (R^^bB~#G/!:* }fM3x`-{]믷|&v2-\Vx'4h7p={r߳{n\.'2k,jG^袋ڵ+KӪV//W_fm&zmܴ;w؉6}]gV6s11-v0^[zp | BCC۷/_Ng'n=\sMcu Y7lo߾YxlBJJ WfT|!5uVO߾l߾` !D3ӱX,fn7硇BQMF\\n vJUUeee8N֯_n|99٤ڒyr%UUU5ѓ]Kee%cƌes!X,TUUU{n6yǹk A5Z?>d&Mr DDD0o3L 0vYIjjjw/kкukKki{Ƹ;ƒ eMiI III\.rssII9o׈UV8qSuR=L㎱cسgODp2-͐jϏW^ył(X,wNRRpp8 ]xRhZuBk0HkKX6n0_{JJ +>/WyV>߱bcc/{dY _ń۷/_Ng'n=\s-Ut">[눉iqʱX~<#lܴ/WOܹsǒ* \'cNx/U62{Q>_r/2o`UW5 ğܖ[HIIaՌʃ<{|9`ժUۗ۷7qu[!1MRw(C-g$"''4^[:î\}yڵ^={pQVZc?@xx8Ͽ}zAջ7Vz9>>pM=0TϘ @DD?}ec <3͏=8wM…t!''c?Oa߾;f4'L`->"5I'3 †[!1]e7Cӫ- m {?pӧpƎ5k3IMMg|/B.\x^,X^f_K9x k׬7XZc`ҥTUU+2`.ߟlJKJHJJrKJJ߾*{m8j^ye1wYgϞwNg/&>>kKVر#ׯ#))(o>}ݰa=|t^z!~'0e]'s4;={4Ad '5B隗߮{$c2 ,}TKi{{ˀ;o>yyyR^^nAUUBCÈ!/7Ʊrsrr㈎>)\#‰)9Xױ:ˉiӧϨqm۶pc)++c߾r*CNN$B YoтQNth'.T t~:* eghXkJ=.ܺ|TUvlܸN:bl6|111N^^.DEG?:&ܜ"""ή.KQaYYY}iY"k| MnNˉXO|JOHHhUU5t!DDg9 1]Yt)GIHH 7o~6R""͐5 .p\zZ&vEQEv_tTIwIQic K@$‰25輱mu$'' i{Tz)6mBEy93f_{َM?~23}F !Cۄ5!Aײt֕͛7xBrR[1O/8iK3IXklלլcF:/8 Ct/a[E>111}|iHj-88Uk( aaaX;../WӹSG, F}ow ^T0LqƲ:=9sf_c(**u[PfbFb'={z'-AAl!h|f (~dIQA\'4+9*'Wd+5^:sv]L̏;UrC?ZTcQ]gr ԙ !$Bf(6R}'Gzc7K/:nnG-'Iu 9YT2h:o~52; !v,nWO""Oa4XnnnEgih2ʶ5qe[!B*wS#я+ B4C YC!ę!%"B!B4"IB!hD` !Bш$B!I-B!D#UD=#ǕI~2-B!D#l!8Ǩ# n~ !ĹMl!8GXm Q8Q=^TEQu4CrʽUMBH-瀐xuDlvh:&G%&{&ӎ^aGռhroSG.8%''M:[!95^ѢMg *+?EAU+P]nBZ$BqvPT-t&E[t]XkWz=x4/ajvԉvnd޽ύxc蜜ƯjPLJJJmvo'!10۷gϞ=MRH-͘`EΘVgNW%Y,+@xPU/F8磏>ey&l ^x!#ؿ#qm ¦ dСCGz+99;<jISTÉ@QQ6n^YzlN%6BqqqxM 8,F#F?ٌ(\ZGUU^oE& 鬵fQQQQ=kDYYYƤ*~~~TVV^Xߟ^_p~l[:t褶"n_ܹ3o(bth4b6'Y,TU8y?z (/+/sΒ`7##G/!:* }fM3x`-{]믷|&v` !B grr׸tM(7 Q^^tִ '_'qqq<̖-3{6EEձ&((ys%66%/e=z4V۶mY3)..o߾1 ~XVqsx'aȕWr,V7rߠ}%IZ2kLv@||3G`02Zk֚9gsa3{Ϯ]92KV &Ц\B2j^~U.IIƾ@Lп?%%|D~]:33eҥ˄2oEb۸sf<ƍ=.6Պ?qW|o߆i<3anOxD81c3lp223k/990 Zs*~}93{{givFs()-᝷߮a0#gΝ>vzLVV6u "44MMmfEbyl"B?$y퓙5%n៬jÆ *f(;w>Y^4M\./z]Dpp0^؋4Z2w\s7_|1;tDJKK 97xÓ\A_9|8NzYk_=%:ZҺu<;vWHLL [nf,Z;<.>SN< ,\O=W}mOӦM233k޼7x5_&u<{B=0`V~qՍ7iy=ɵ4]۷oq7idyFfED2F~M◟V*+ v(r<'Tfy̟7/~L(((Tb!<<8232*+#=ȨJrsr<ﳲ2 jCTTӦL߿[9IllqdffI\~\}9zZRRLAAQQ8Nn7~Go޼XUUsqo̝ˣ>ʎ'?nco^"y_tbU-\bƎǔ)Sy?muQ^VVx\*c+??ݻ*~ q:Ɓ|]`kZ%uj󣤸Vg`Z}Ar,6Mtcbb 'YJip6-;\8/_ڵk9̳XS  a&[ظ822+mbhْre߾}5qV%77J?CĒNNNN}9_  @nnPMtժK\{u׷Rn=jҥ,[ݻ/Yp:kϨ*%MWbBYYL64M̙Cvvڵ#_~4AA$ݛ+9- a sU,!$èH톅6~YA8n-h۶s||<:u'--m۶1fLEa;˗SZZh׮=z*Vf5, Ç_T!1+br0`m-5J/E2bH_qM6ڗ*G޽{ٳ~vŤɓ=7]}NuR?O`nn D~^'˯c[nXQ}ddf_xx;_ONsKHHd$&%1lՌ5dImvVi 6r/8tgsɮ$ڂ؎,XMȼv횷h/D`` X,^{_n~X,?z-̘(nf͚'Tɩ͊+޽z LnAs% zH7iJ:?{|_1q֚͞r?|O_R^^'y[x'X~ ; ;겝۵7W^Ï`СXV~{.kYq'Nxx8k|Û-b|t~:-t3vVZ6! 8-Z02:y+es~GD' Nq={$hѧXN%''Q܌}6n$88س|9x n6prrr ,,JގGM7šC]+\$) Ԫ E~Ќ{r3(+=dl~-- Pd2V}iP~4M̏nٛ뢸x`Q50 ˫M&jw_r:uI?*y3'Jȟ7kQ-"_iq@ԮׂQ$Gb#1Tػ0./&RYHC/'("Ҕ('MJ8g5M7Os<FTgddj\3| %""x{4>ƕ6~.}: 5eN5(9 ,I I8j""0`xxSQ]DDH &5]veO5zt}'" 0 nw#cƌuH^SG+0  j=kI8|2}GXp{l~A9a!j%00:gp8yY,&M̺uk<NӳJJm&t}ay4k֬NH~5tؘ֝vnV\i׏{4ٷo7~|㈫l #E /Ad.n7~aX,XaټvU%A M?OH@@/W? Yn=\pse5kFI-H ƏʯVbW|Ohٲ%Vw{>7_"..gXl97|33j뢋rJ%.w>+V~fc\3|893"Ro6@rr2˖-caw~@>aÆ\֭[}m4-"zI۶mNX O^Ϗ#˰X*@\.'Y?`wcW"1j Aii)*֭=z^RVVFDD%%%D:}ZhA׮]q8nOxD81c3WV׮]eDn}2!!!|ɧ׏/RS {r2֮//tgϞj'w G9ەE:l'L`ٹsl#f ),1h%LrqRRR͛II4AAAb RRR_+Yjf̛7Lbݿ?0F{Knn,ŋб#۷mcРkiٲ%o'5_o~5^k߾}|eVķrOYv-0|ГU9o΍7c֬K'M GcEaXZЫtҧO W^jՊ-[ҳgOwNN8h߾=]t!*2.ts!,,?$׽\w5tԉWp)l6JJOꪫ|`,XP,r'G=W\q%֍E X񭄄DHbRÆ^QHNNO l`4AGo"lѢoH\\L0D)//seÏ<gfԩ}ѹsg/_^u[3W;j#n'Ib&o*4aW}hSez"{nرcXjgЫ0`@Zhȼc$vor]:9"99M&nR~)))5CBBEEEdggHFF/FPP񔔔E۶m)((?dܹXV)--Õ]z ƌ_VСCu>VD>$)DbXip1,/%jaa!8N(++;ѶNR:u"'qɵ7Oܹs?(..Vr-">;!z=mg$%xRH ͪ!N}Ae%d>1J[DDDDDjUDDDDDDlz[DDDD)GJEDDDDlz[DDDD|5Y,gu8f͚:?ÅlqۑRv6nNpH I/`ot zЌg}u(Jq<[ Zm={EVցS]Mtt|5k$dffT5ϕ7#++0:WVV!7(S5SB1N%""""MX*Pw4lz[DDDDilS5'Ii[DDDIS^K`O(;y^a0 .Џ6IcI|$Ӌ54/[DDDv;;vᆱmXXڕ`qF\.g%))02ɴϏǮ]? )1޽/ٱC{Iۻ#?3_?m;=J e9~)KJjM>'c233IJJߟ&MbΝu*B7a0}О﹏[ź lذ#gwrǔɶl<}OOgmD.:* ??z?O?dڴi5֭voF1"55ggE4臟ǽ9+wݼo_eķnUe0 eZi֬~[DDDr~~<;s&%e%9e NC aɒ%|mi2q8\ԫq ω jc6t >|^7_vm^grw|/=?ӫզqi3??{Y :ej5@ZE IYYwgo)r}v%gjszvlٺfR]~&M|狊ٝXb%_,]FK`Y=v;}zbq}p>7Əz;Kgb8grw.4?]gphٲs\;b4#FoQ-""">Ұ5"OM6ϑw݅w7($00*r?~<:t`ɔpj&504 [GҹgHumЯk׭'0w$ݻcnZ4o^7m!886mؾc'֒8LV^"?q2}"""Wkz1n$mya=+Qbbb-[<С6mq*qFb"ks{mz$ɾg=(~GDռ"aw !,l#((z7v=NVyjkV'22HbmV H3jS])&i޼n_}&MbҤ{Sr qFûWi{Td$g}6/g[nn.Ff[oqu1gz bu r7|[R=1f|^rvƎl OɁնIMnwj:Νx7[5]3OED/XK^fdffPr ٴoߞoٳEy'ؼy36m=x yyyL:qѹsN{k ?[mrݐykōxR>[ZG_ym߱~\R/gdpns +п_LZzU[DDD|{3f8^\N ##=ѣo.]Xj_^>4&M|}p&ڹ3' 4$a4ؓt؞O=Ldd$?Gmۙؓ5,sy=}X~W;Y-e積QaJ^^WqYVBC),*䄮#;_8ޠlƓIii?.Aɢşhqu֍i:t.4io2wc[DDDD)b 5G􉈈zJEDDD0M`oR 1lLH.FsIDATTT Bbbc}ƟV\l,\DGEf6WtT4y7I"""#nY,0ס).m0 Zm;FpH)g÷bf JEDDgL\n7 N`X-qޏjEDDgjyq>T-""""R`#%"""""H H=R-""""R`ԣJdIENDB`RaySession-0.12.2/manual/fr/images/video000077700000000000000000000000001417052567600234132../../en/images/videoustar00rootroot00000000000000RaySession-0.12.2/manual/fr/manual.adoc000066400000000000000000001601071417052567600177060ustar00rootroot00000000000000= Manuel de *RaySession* :toc: left :toc-title: Table des matières :toclevels: 1 :imagesdir: images :stylesheet: rs_manual.css [.text-right] image:flags/en.jpeg[EN, 30, 20, link=../en/manual.html] image:flags/fr.jpeg[FR, 40, 30, link=../fr/manual.html] image:flags/de.jpeg[DE, 30, 20, link=../de/manual.html] image::raysession.svg["icon", 100, 100] _pour la version 0.12.0_ == Introduction RaySession est un gestionnaire de session audio pour GNU/Linux. Il permet de démarrer dans une même session plusieurs programmes audio, de sauvegarder leurs projets ensemble et ainsi d’éviter de multiples manipulations pour retourner à une configuration donnée. Pour être lancés dans RaySession, il est très largement préférable que ces programmes audio soient compatibles avec le protocole NSM, et beaucoup le sont déjà, entre autres Ardour, Qtractor, Carla, Guitarix, Mamba, Patroneo, ZynAddSubFx... RaySession part du principe que votre configuration audio est fonctionnelle pour de la production audio, si ce n’est pas le cas réglez d’abord ce problème et ne perdez pas votre temps à essayer d’utiliser RaySession. Maintenant voyons comment s’en servir. == Exemple d'utilisation simple Pour la production audio sous GNU/linux, Il est largement conseillé d’utiliser le serveur JACK. Avant de créer ou de lancer une session, assurez-vous que le serveur JACK tourne, RaySession n’a aucun rapport direct avec JACK, toutefois les programmes que vous allez lancer dans votre session en auront besoin. Prenons un exemple où pour composer un morceau, nous aurons besoin des logiciels Ardour et Guitarix, assurez vous que ces 2 programmes soient installés. Pour créer une nouvelle session, cliquez en haut à gauche sur *Nouvelle Session* (_ou Ctrl+N_). Apparaît alors une fenêtre de dialogue. image::exemple_nouvelle_session.png[Nouvelle session] En haut à droite vous apercevez le dossier racine des sessions, c’est là que les sessions seront sauvegardées (une session RaySession étant un dossier contenant un fichier `raysession.xml`). Rentrez le nom voulu pour cette nouvelle session dans le champ prévu à cet effet. Pour mettre votre nouvelle session dans un sous-dossier, tapez le nom de la manière suivante : `sous-dossier/ma session` . La boîte à choix multiples de modèles de session vous permet de choisir entre * Un modèle de session vide * Un modèle avec mémoire des connexions JACK * Un modèle scripté avec mémoire de la configuration de JACK * Un modèle avec les scripts de session de base (pour les utilisateurs avancées pourvus de connaissances en script shell) * Tous les modèles de session que vous aurez vous-même créés. Dans un premier temps, laissez le modèle sur *Avec mémoire du patch de JACK*, cliquez sur *Ok* pour lancer votre session. image::exemple_session_lancee.png[Session lancée] La partie session de la fenêtre devient active, en haut est écrit le nom de votre session, et votre session contient déjà un programme client qui s'appelle *Connexions JACK*. C'est lui qui sauvegardera et refera les connexions de la baie de brassage de JACK. Pour ajouter Ardour à votre session, cliquez sur le bouton *Application* (ou Ctrl+A), apparaît alors la fenêtre des applications (plus de détails à la rubrique <>). Dans la partie droite, cherchez Ardour (selon votre version d'ardour, il est possible qu'il s'appelle Ardour5 ou Ardour6) et double-cliquez dessus. image::exemple_ajouter_ardour.png[Ajouter Ardour à la session, 640, 480] Un client *Ardour* apparaît en dessous de *Connexions JACK* et Ardour démarre (normalement directement avec une session Ardour vide). Faites de même avec Guitarix. image::exemple_session_prete.png[Session prête avec Ardour et Guitarix] Dans Ardour, ajoutez une piste (Menu: Piste -> Ajouter une piste), dans la fenêtre Ardour qui est apparue, nommez la piste _Guitare_ et mettez la boîte à choix multiples *configuration* sur _Stereo_. [caption="Figure 1: ",link=images/exemple_ardour_piste.png] image::exemple_ardour_piste.png[Ajouter une piste Ardour pour Guitarix, 640, 480] Servez-vous maintenant de la <> de JACK qui occupe la partie droite de la fenêtre de RaySession. Connectez l'entrée de Guitarix à une entrée matérielle et les sorties de Guitarix vers les entrées de cette nouvelle piste Ardour. Assurez vous que les entrées de votre piste *Guitare* ne sont pas connectées aux entrées matérielles. [caption="Figure 1: ",link=images/example_patchbay.png] image::example_patchbay.png[Baie de brassage de ma session] Voilà, vous avez une configuration où vous pouvez enregistrer directement le son de votre guitare traité par Guitarix dans Ardour. Si vous n'avez pas de guitare, vous n'avez qu'à chanter faux dans un micro ou taper sur un coussin, ce n'est ici qu'un exemple. Sauvegardez la session en cours en cliquant sur le bouton en forme de disquette vers le haut à droite de la partie Session (_ou Ctrl+S_). Il est vivement recommandé car très pratique d'affecter un raccourci clavier global de votre système à la sauvegarde de la session en cours. Celà dependra de votre environnement de bureau, mais il suffit d'affecter le raccourci _Ctrl+Meta+S_ à la commande `ray_control save` (Meta est la touche Windows), ainsi vous n'aurez pas à retourner à la fenêtre de RaySession pour sauvegarder la session. Maintenant, fermez la session en cliquant sur la croix rouge en haut à droite de la partie Session(_ou Ctrl+W_). Une fois la session fermée, cliquez sur *Ouvrir une session* (_ou Ctrl+O_), double-cliquez sur la session que vous venez de créer pour la ré-ouvrir. Vous devez retrouver les programmes et leur projet ainsi que les connexions de JACK telles qu'elles étaient quand vous avez fermé la session, et tout fonctionne donc sans aucune autre manipulation. + Un des avantages de la modularité dans ce cas précis, c'est qu'une fois qu'on aura terminé les prises de guitare, on pourra arrêter Guitarix pour ne pas surcharger le processeur inutilement, et il sera tout de même facile de le redémarrer si besoin. == Vue d'ensemble des outils de la session === Ligne du haut image::session_ligne_du_haut.png[Ligne du haut de la trame de session] De gauche à droite: * le bouton menu vous donne accès à ** *_sauvegarder la session en cours comme modèle_* + Le modèle de session créé apparaîtra alors dans la boîte à choix multiples de modèles de session dans la fenêtre de dialogue *Nouvelle Session*. Attention toutefois, L'ensemble des fichiers de la session seront sauvegardés dans le modèle, il ne faut donc pas le faire si la session contient beaucoup de fichiers audios. D'une part la copie sera longue, d'autre part vous risquez de multi-copier inutilement des fichiers qui prendront beaucoup de place. ** *_Dupliquer la session en cours_* + C'est l'équivalent du bien connu "Sauvegarder sous...", sauf que RaySession est obligé d'arrêter et de redémarrer la plupart des programmes pour passer d'une session à l'autre. Évitez de dupliquer une session avec beaucoup de fichiers audios, celà pourrait être long, mais fort heureusement une telle opération peut être annulée. ** *_Renommer la session_* + Il faudra alors arrêter tous les clients. + Alternativement, vous pouvez renommer une session en la dupliquant puis en supprimant le dossier de la session initiale. + Vous pouvez aussi renommer une session en renommant son dossier, mais ATTENTION, cette session ne doit surtout pas être chargée ! * le bouton en forme de crayon vous donne accès aux notes de session. + Écrivez ici des informations dont vous avez besoin, des réglages physiques, les paroles d'une chanson, la recette du cassoulet de mamie...toutefois n'y écrivez pas un roman en 3 tomes, d'autres outils sont bien plus adaptés, et les notes sont limitées à 65000 caractères pour des raisons techniques. + Le crayon est vert quand des notes existent, il est orange quand la fenêtre de notes est ouverte, sinon il est transparent. * le nom de la session chargée (ici *ma session*) * le bouton *Abandonner la session* qui permet de fermer la session sans la sauvegarder * le bouton *Fermer la session*, qui sauvegarde et ferme la session en cours. + Notez que vous n'avez pas besoin de fermer la session en cours pour en ouvrir une autre. Certains clients sont capables de basculer d'une session à l'autre et ça peut être beaucoup moins long que de tout fermer pour tout relancer. === Ligne du bas image::session_ligne_du_bas.png[Ligne du bas de la trame de session] De gauche à droite: * le bouton en forme de dossier pour ouvrir le dossier de la session avec votre gestionnaire de fichiers * le bouton en forme d'étoile jaune qui déroule un menu contenant vos applications favorites s'il y en a * le bouton *Application* qui permet d'ajouter à la session un modèle d'application d'usine ou que vous aurez créé vous même. C'est la méthode conseillée pour ajouter un client. voir <>. * le bouton *Exécutable* qui permet d'ajouter à la session un programme depuis son exécutable. Vous en aurez besoin si vous souhaiter ajouter un programme pour lequel il n'existe pas de modèle. voir <>. * le bouton de marche arrière pour revenir à un état précédent de la session. Celà nécessite d'avoir le programme `git` installé, sinon ce bouton n'apparaîtra pas. + Voir <> pour plus de détails. * l'indicateur d'état du serveur. + Les états du serveur peuvent être en réalité très furtifs, mais ils sont affichés pendant un temps suffisament long pour que vous puissiez les voir. + L'état du serveur peut être: ** *éteint* : pas de session en cours ** *prêt* : la session est en cours ** *lancement* : lancement des programmes de la session ** *copie* : une copie est en cours, pour une duplication de session ou une sauvegarde de la session comme modèle ** *fermeture* : la session est en train de se fermer ** *cliché* : un cliché de la session est en train d'être pris, donc vous pourrez revenir à l'état actuel la session. + voir <>. ** *attente* : Le serveur attend que vous fermiez vous-même des programmes non sauvegardables ** *script* : un script est actionné + Une fenêtre d'information ou de progression s'affiche si vous cliquez sur cet indicateur d'état s'il est sur *copie*, *cliché* ou *attente*. * le bouton de sauvegarde de la session * la corbeille, vous trouverez ici les clients que vous avez supprimés. Vous pourrez alors les restaurer dans la session ou supprimer définitivement tous les fichiers qu'ils ont créé dans le dossier de la session. == Vue d'ensemble d'un client image::client_carla.png[trame d'un client] Un client contient de gauche à droite: * L'icône du client sur laquelle vous pouvez cliquer pour faire apparaître un menu avec les actions suivantes ** *Sauvegarder comme modèle d'application* + Le modèle créé apparaîtra alors dans la <>. Celà permet par la suite de lancer directement un client avec la configuration souhaitée (Ardour avec telles pistes, Hydrogen avec tel kit de batterie...). Attention, celà copie tous les fichiers du client donc évitez de le faire si le client contient beaucoup de fichiers audio. ** *Renommer* + Changer le nom du client situé à droite de son icône, il s'agit d'un nom purement visuel qui peut vous aider à retrouver vos moutons ** *retourner à un état précédent* + Permet de faire revenir uniquement le client à un état antérieur de la session, voir <>. + Vous ne pourrez toutefois pas revenir à un état antérieur à un renommage de la session, pour celà il faut faire revenir toute la session en arrière. ** *Propriétés* + Affiche la fenêtre des propriétés du client + Ce menu est aussi accessible par clique droit n'importe où sur le client * Le nom du client (ici *Carla*), qui peut-être changé facilement par clique droit -> renommer * selon le type et les capacités du client vous pouvez voir ici ** un oeil (éventuellement barré), celà signifie que le client est compatible NSM et qu'il est capable d'afficher ou cacher sa fenêtre en cliquant sur l'oeil. ** un bouton *Hack*, celà signifie que le client n'est pas compatible NSM, en tout cas qu'il n'est pas lancé avec ce protocole. Cliquer sur Hack permet de changer la façon dont il est lancé en ouvrant la fenêtre de propriétés du client sur l'onglet Ray-Hack * Le bouton *Démarrer* qui est grisé si le client est déjà démarré * le bouton *Arrêté* qui est grisé si le client n'est pas démarré. Si vous arrêtez le client et qu'il n'est toujours pas arrêté après un certain temps, le bouton devient rouge et vous pouvez cliquer dessus pour tuer le client. Mais restez détendus, et ne l'utilisez que si vraiment il vous semble complètement inerte, celà pourrait causer des problèmes, même si a priori personne ne vous enverra en prison. * l'état du client qui peut être ** *arrêté* : le client est arrêté ** *prêt* : il est lancé et fonctionnel ** *ouverture* : le programme est en train d'ouvrir son projet, patientez un peu ** *fermeture* : le programme est en train de se fermer ** *lancé* : s'il reste sur l'état lancé, celà signifie *** si c'est un client Ray-Hack, qu'il n'a pas de fichier de configuration *** s'il est lancé comme un client NSM, qu'il n'est pas compatible NSM, et qu'ainsi toute sauvegarde est vaine. Il peut être pratique de lancer de cette façon certains programmes tels qu'une baie de brassage (Catia) ou un utilitaire dont on n'a pas besoin de sauvegarder l'état (Qrest). ** *bascule* : le client change de projet pendant un changement de session * le bouton en forme de disquette qui permet de sauvegarder le client. + Si par dessus cette disquette vous voyez ** trois points rouges: le client contient des changements non sauvegardés ** un V vert: le client ne contient pas de changements non sauvegardés ** un point d'exclamation orange: Ce n'est pas un client NSM, et il est impossible de sauvegarder son projet, vous devrez le faire vous même * la croix rouge qui permet d'envoyer le client à la corbeille [#ajout_application] == Fenêtre d'ajout d'application Le fenêtre d'ajout d'application se lance en cliquant sur le bouton *Application* (_ou Ctrl+A_). image::ajout_application.png[Fenêtre d'ajout d'application] La liste des applications disponibles est à droite. Si le logiciel que vous souhaitez lancer n'est pas présent ici, regardez <>. ''' En haut à gauche, c'est le bloc de filtres image::ajout_application_filtre.png[Bloc de filtre de la fenêtre d'ajout d'application] * le champ de filtre permet de rentrer une chaîne de caractères, seuls les modèles contenant cette chaîne de caractères dans leur nom apparaîtront. * la case à cocher *Usine* affiche les modèles intégrés à RaySession ou fournis par votre distribution * *utilisateur* affiche les modèles créés par l'utilisateur en faisant *Sauvegarder comme modèle d'application* * *NSM* affiche les clients compatibles NSM, ou lancés comme tel (voir <>) * *Ray-Hack* affiche les clients lancés sans protocole NSM ''' En bas à gauche le bloc d'informations sur le modèle sélectionné à droite image::ajout_application_infos.png[Bloc d'informations sur le modèle sélectionné] * en haut à droite de ce bloc, une étoile, cliquez dessus pour l'ajouter aux favoris ou l'enlever des favoris * Si c'est un modèle utilisateur, un bouton *Utilisateur* vous permet de supprimer ce modèle * le bouton en bas à droite de ce bloc vous permet d'accéder à toutes les propriétés du modèle, comme dans la <>, sauf que rien n'est éditable. *Astuce :* Cette fenêtre est conçue pour un ajout d'application très rapide, et se comporter comme _Alt+F2_ sur votre bureau. + Par exemple, depuis la fenêtre principale de RaySession, pour ajouter Carla tapez _Ctrl+A_, puis `carla`, sélectionnez le bon modèle avec les flèches Haut/Bas, puis Entrée. [#ajout_executable] == Fenêtre d'ajout d'exécutable Le fenêtre d'ajout d'exécutable se lance en cliquant sur le bouton *Exécutable* (_ou Ctrl+E_). image::ajout_executable.png[Fenêtre d'ajout d'exécutable] Vous aurez besoin de passer par cette fenêtre si vous voulez ajouter un client qui n'apparaît pas dans la liste de la fenêtre d'ajout d'application. Cette fenêtre se présente très simplement, un champ pour rentrer l'exécutable, une case *Protocole NSM*, un bouton d'options avancées. Laissez le protocole NSM coché si: * le programme à lancer est compatible NSM (s'il n'est pas dans la liste d'applications, merci de le faire savoir !) * le programme à lancer est un utilitaire dont on n'a aucun besoin de sauvegarder un quelconque projet (QRest, Catia...). + L'état d'un tel programme restera sur *lancé* et ne sera jamais *prêt*, c'est sans importance vu qu'ils n'a pas de projet à sauvegarder. Si vous laissez le protocole NSM coché il ne sera pas possible d'ajouter un exécutable vers un chemin absolu, l'exécutable doit se situer dans un emplacement prévu à cet effet (vous ne pourrez pas lancer `/usr/bin/mon_programme`, mais `mon_programme`). Vous ne pouvez pas rentrer d'arguments ici, avec ou sans le protocole NSM. Décocher la case *Protocole NSM* revient à lancer le programme avec le pseudo-protocole Ray-Hack. Si vous cliquez sur le bouton d'options avancées, un bloc options avancées apparaît avec image::ajout_executable_plus.png[Fenêtre d'ajout d'exécutable avancé] * la case *Démarrer le client*, si vous la décochez le client sera ajouté mais non lancé * la boîte à choix multiple *Mode de préfixe*, celà définit le préfixe du nom des fichiers du client ** sur *Nom de la session*, les noms des fichiers commenceront par le nom de la session, c'est la valeur par défaut ** sur *Nom du Client*, les noms des fichiers commenceront par le nom fourni par le client lui-même, comme c'est le cas avec New Session Manager ** sur *Personnalisé*, les noms des fichiers commenceront par la valeur que vous inscrirez dans le champ *Préfixe* juste en dessous * le champ *Préfixe* qui n'est actif que si *Mode de Préfixe* est sur *Personnalisé* * le champ *ID du client* (identifiant du client). Ne rentrez ici que des caractères alphanumériques ou des '_'. + Celà est utile si vous voulez attraper et lancer des projets existants dans la session avec un exécutable. C'est pratique si vous voulez charger dans la session des projets créés en dehors d'une session. Aucune méthode ne permet de rendre la chose plus simple, celà dépend énormément du programme utilisé. RaySession vous insultera si vous rentrez un identifiant de client qui existe déjà dans la session. * la case à cocher *Longs noms de client JACK*. Si cette case est cochée, les clients seront supposés utiliser `NomDuProgramme.Identifiant` comme motif pour leurs clients JACK, sinon ce sera `NomDuProgramme` éventuellement suivi de `_N` (ou N est un nombre). C'est tout à fait pratique si vous utilisez de multiples instances d'un même programme, et que vous souhaitez pouvoir facilement les reconnaître dans la baie de brassage. [#patchbay] == Baie de brassage la baie de brassage de JACK est affichée par défaut. Vous pouvez la cacher en cliquant sur *Contrôle* puis en décochant *Afficher la baie de brassage de JACK* (__ou Ctrl+J__). La baie de brassage contient tous les ports AUDIO et MIDI de JACK que vous pouvez interconnecter. Évidemment, si JACK n'est pas démarré, cette baie de brassage sera vide. Il est conseillé d'avoir le pont A2J lancé si vous voulez travailler correctement avec le MIDI. Vous pouvez configurer celà via *Cadence*, *Studio Control*, ou via l'utilitaire en ligne de commande `a2j_control`. RaySession n'inclut pas d'outils pour configurer le serveur JACK, *QJackCtl*, *Studio Control*, *Cadence*, ou l'utilitaire en ligne de commande `jack_control` font très bien ce travail. Notez que cette baie de brassage fonctionne également avec PipeWire. === Vue d'ensemble image::patchbay_base.png[Vue d'ensemble de la baie de brassage] Voilà à quoi peut ressembler votre baie de brassage. Ici il y a 7 boîtes : * une boîte *system* comprenant vos ports correspondant aux entrées matérielles * une boîte *system* comprenant vos ports correspondant aux sorties matérielles (enceintes, casque) * une boîte *a2j* comprenant vos ports correspondant aux entrées MIDI * une boîte *a2j* comprenant vos ports correspondant aux sorties MIDI * une boîte *PulseAudio JACK Source* * une boîte *PulseAudio JACK Sink* * une boîte *Guitarix* Ici les ponts A2J et pulse2jack sont lancés. Vous observez que 4 de ces boîtes sont entourées d'une décoration (2 *system* et 2 *a2j*), ce sont les boîtes qui contiennent les ports matériels (votre interface audio, votre piano USB, n'importe quel contrôleur...). ''' Certains ports audios sont regroupés en sous-groupes, que l'on appellera portgroups. Ces portgroups sont pour la plupart des paires stéréo détectées automatiquement par le nom des ports. C'est le cas ici pour : * system:capture 1/2 * system:playback 1/2 * PulseAudio JACK Source:front L/R * PulseAudio JACK Sink:front L/R * Guitarix:out 0/1 Ces portgroups facilitent les connexions et permettent une meilleur lisibilité générale. ''' Les lignes incurvées bleues correspondent aux connexions audios. Vous pouvez observer que : * les ports audio d'entrées matérielles sont connectés à *PulseAudio JACK Source* * les ports de *PulseAudio JACK Sink* sont connectés aux sorties matérielles * seul le premier port de *system* est connecté à l'entrée (__in 0__) du logiciel *Guitarix* * les ports audios de *Guitarix* sont connectés aux sorties matérielles === Faire et défaire une connexion Vous pouvez établir une connexion entre 2 ports pourvu qu'ils remplissent les conditions suivantes : * les ports sont du même type (on ne peut pas connecter un port audio à un port MIDI) * l'un est un port d'entrée, l'autre est un port de sortie ==== Méthode Intuitive Pour connecter ou déconnecter deux ports, cliquez sur un port sans relâcher le bouton de la souris, glissez le curseur jusqu'au port désiré puis relachez le bouton de la souris. ==== Méthode Alternative Faites un clic droit sur un port, celà affichera un menu déroulant, choisissez *Connecter* puis le port désiré. Cliquez ailleurs pour faire disparaître ce menu. L'avantage de cette méthode est qu'elle permet de connecter rapidement un port à plusieurs autres, le menu restant affiché pendant les connexions. video::video/patchbay_simple_connect.mp4[width=640] === Les options Un clic droit n'importe où sur la baie de brassage permet d'en afficher le menu. Ce menu est également présent dans le menu de RaySession (menu *Baie de brassage*). Il vous permettra de : * basculer la baie de brassage en plein écran * chercher une boîte par son nom * Filtrer les ports: n'afficher que les ports AUDIO ou MIDI ou les deux * régler le niveau de zoom * rafraîchir le canevas: redemander à JACK la liste des ports existants et leurs connexions * Préférences du canevas: afficher une fenêtre d'options + Tous les changements dans cette fenêtre prennent effet immédiatement. Survolez les cases pour afficher les infobulles. === Raccourcis à connaître * Un double clic n'importe où permet de basculer la baie de brassage en plein écran. * __Ctrl+Molette de la souris__ permet de zoomer/dézoomer. * __Alt+Molette de la souris__ permet déplacer la vue horizontallement. * Le bouton de la molette permet de déplacer la vue * __Ctrl+bouton du milieu de la souris__ permet de couper toutes les connexions passant sous le curseur * __Ctrl+F__ permet de chercher une boîte par son nom ==== Connexions en rafale Il est possible de connecter un port ou un portgroup à différents ports assez rapidement. Il suffit de terminer ses connexions par un clic droit. Une video sera bien plus explicite. video::video/patchbay_rafal_connections.mp4[width=640] Ici nous voulons connecter les multiple sorties d'Hydrogen à des tranches de Jack-Mixer. Dans la video les ronds bleus apparaissent avec un clic droit. ==== Passer les connexions d'un port à un autre Il est parfois moins fastidieux de passer des connexions d'un port à un autre plutôt que de tout défaire pour tout refaire. Pour ce faire, partez du port qui contient les connexions et faites comme si vous vouliez faire une connexion, mais allez vers le port vers lequel vous souhaitez basculer les connexions. * Celà ne fonctionne que si le port de destination ne contient aucune connexion * Celà fonctionne de port à port ou de portgroup à portgroup mais pas de port à portgroup video::video/patchbay_fast_cut_paste.mp4[width=640] Dans cette video nous avons un cas assez complexe où la source est branchée dans *3 Band Splitter*. Les basses et les aigües (_Output 1_ et _Output 5_) sont envoyés directement dans *EQ6Q Mono* tandis que les medium (_Output 3_) passent d'abord par la distortion *GxTubeScreamer*. Nous voulons insérer la reverb *Dragonfly Room Reverb* avant l'égualisation *EQ6Q Mono*. ''' Notez qu'avec la connexion par clic droit et le passage de connexions d'un port à l'autre, il est très rapide d'intégrer un nouveau greffon dans une chaîne, comme ici où nous branchons *Plujain Ramp Live* entre *Dragonfly Room Reverb* et *EQ6Q Mono*. video::video/fast_new_plugin.mp4[width=640] === Les ports A2J image::patchbay_a2j.png[ports a2j] Les ports MIDI fournis par le pont A2J (Alsa To Jack) présentent un trou à leur extrêmité pour les reconnaître. Leur véritable nom est un nom à ralonges, mais c'est à peu près la seule chose qui diffère avec les autres ports MIDI. === Les ports de tension de contrôle (ports CV) image::patchbay_CV.png[ports CV] les ports de tension de contrôle, appellés communément ports CV (Control Voltage) ont le même fonctionnement que les ports audio classiques, cependant, ils sont faits pour piloter un ou plusieurs paramètres avec une précision bien plus importante que les ports MIDI. Comme leur flux n'est pas fait pour être écouté, il n'est pas possible de connecter simplement un port CV de sortie vers une entrée audio classique, celà pourrait endommager votre casque, vos enceintes, et peut-être même bien vos oreilles. + Si vous souhaitez quand même le faire, faites un clic droit sur l'un des ports, puis *Connecter*, puis le menu *DANGEREUX*. + Vous ne pourrez pas dire que vous n'étiez pas prévenu, et il est quasiment impossible de faire ça par erreur. En revanche, connecter un port de sortie audio classique vers un port CV d'entrée est tout à fait possible, ça ne pose aucun problème. [#proprietes_de_client] == Fenêtre de propriétés d'un client La fenêtre de propriétés d'un client s'ouvre depuis le menu du client, en cliquant sur *Propriétés*. La fenêtre des propriétés du client comprend 2 onglets, un onglet *Général* et un onglet spécifique au protocole utilisé par le client. Selon le protocole du client, le deuxième onglet s'appelle NSM, Ray-Hack ou Ray-Net. === Onglet *Général* image::proprietes_general.png[Propriétés d'un client] * Le premier bloc de l'onglet *Général* affiche l'identifiant, le protocole, l'étiquette, la description et l'icône du client. + Si vous ne les éditez pas, l'étiquette, la description et l'icône sont tirées du fichier .desktop associé à l'exécutable lancé, s'il a été trouvé. + Si vous tenez à connaître le fichier .desktop utilisé, tapez `ray_control client IDENTIFIANT get_properties` dans un terminal (en remplaçant IDENTIFIANT par l'identifiant du client). * Ensuite vient le bloc des clichés, voir <>. * la case à cocher *Empêcher l'arrêt sans sauvegarde récente ou possible* concerne la fenêtre qui peut apparaître lorsque vous demandez à un client de s'arrêter. Si cette case est décochée, alors le client sera stoppé sans qu'une fenêtre ne vous prévienne. + Si la case est cochée, la fenêtre vous previendra lorsque ** le client est non-sauvegardable depuis RaySession ** on sait que le client contient des changements non sauvegardés ** le client semble ne pas avoir été sauvegardé depuis plus d'une minute + cocher cette case ou non dépend seulement de l'importance de la sauvegarde de votre client, à vous de juger. Celà dit, si la fenêtre d'avertissement vous agace, vous n'aurez qu'à cocher la case *Ne plus empêcher l'arrêt du client* dans cette fenêtre et la case *Empêcher l'arrêt sans sauvegarde récente ou possible* sera décochée. === Onglet *NSM* image::proprietes_nsm.png[Propriétés NSM d'un client] Le nom du client ici est fourni par le client lui-même. + Les capacités sont celle qui sont transmises par le client à son démarrage. Si le client n'a pas encore été démarré, ce champ est donc vide. Éditer l'exécutable permet de changer la commande qui lance le client. Ne le changez que pour un autre exécutable capable de charger le projet du client existant. C'est utile par exemple si vous avez deux versions d'Ardour, l'une se lançant avec la commande `ardour`, l'autre avec `Ardour6`, et que vous voulez changer la version à utiliser. Éditer les arguments est fortement déconseillé, et n'est surtout pas adapté au chargement d'un fichier comme argument. === Onglet *Ray-Hack* Si le client est de type Ray-Hack, ici moult champs s'offrent à vous. Ce n'est pas forcément une bonne nouvelle, l'idée est de pouvoir charger dans la session un programme qui n'est pas (encore) compatible NSM. S'il est bien implémenté dans le client, le protocole NSM sera toujours bien plus confortable à utiliser et plus fiable que cette bidouille. Ceçi dit, si l'on peut attendre l'implémentation NSM dans tous les programmes audio, ce n'est pas le cas des autres programmes qui peuvent tout de même avoir une utilité dans la session. Le pseudo-protocole Ray-Hack reprend les attributs des proxy (nsm-proxy ou ray-proxy), sauf que le client est lancé directement dans la session. image::proprietes_ray_hack.png[Propriétés Ray-Hack d'un client] ==== Bloc de lancement image::ray_hack_lancement.png[] * le *Dossier* est le nom du dossier de ce client, dans le dossier de la session. Le programme est lancé depuis ce dossier. * L'**Exécutable** est la commande qui lance le programme * Le *Fichier de configuration* sera le fichier du projet qu'on souhaitera ouvrir avec ce programme. Il plus que très recommandé de faire référence à un fichier dans le dossier du client. + La variable `$RAY_SESSION_NAME` sera automatiquement remplacée par le nom de la session. + Si ce champ est vide, le client restera toujours sur le statut *lancé* et jamais *prêt*. Dans certains cas, il peut donc être utile de taper n'importe quoi ici plutôt que rien. * Le bouton *Naviguer* ouvre une boîte de dialogue pour aller chercher le fichier de projet et remplir le champ *Fichier de configuration* * Le champ *Arguments* comprend les arguments passés à la commande *Exécutable* + les arguments sont découpés comme ils le seraient dans un terminal, n'oubliez pas les *"* ou les *'* si nécéssaire. + par exemple pour reproduire `ma_commande mon_argument_1 "mon argument 2"` rentrez `ma_commande` dans le champ *Exécutable* et `ma_commande mon_argument_1 "mon argument 2"``dans le champ *Arguments*. ==== Bloc des signaux image::ray_hack_signaux.png[] * Le *Signal de sauvegarde* ne peut être que rarement utilisé. Il peut être SIGUSR1 pour les programmes compatibles avec le vieux protocole LASH. Sinon laissez le sur _Aucun_, s'il n'y a pas de méthode de sauvegarde, on ne peut pas l'inventer. * Le *Signal d'extinction* sera généralement _SIGTERM_. Ne le changez qu'au cas où ce signal ne ferme pas correctement le programme. * si la case *Attendre une fenêtre avant d'être considéré comme prêt* est cochée, alors le statut du client ne passera sur *prêt* que lorqu'une fenêtre apparaitra. + Si `wmctrl` n'est pas installé, ou que le gestionnaire de fenêtres ne semble pas compatible avec, alors le client passera sur *prêt* une demi-seconde après son lancement. Avec `ray_control` vous pouvez affecter d'autres signaux que ceux proposés dans les boîtes à choix multiple. Par exemple + `ray_control client CLIENT_ID set_properties save_sig:22` + définira le signal *SIGTTOU* pour la sauvegarde du client CLIENT_ID. Tapez `kill -l` pour connaître les signaux disponibles et leurs numéros. ==== Bloc de gestion des non-sauvegardables image::ray_hack_non_sauvegarde.png[] Ce bloc n'est actif que si le *Signal de sauvegarde* est reglé sur _Aucun_ * si la case *Demander à l'utilisateur de fermer lui-même le programme à la fermeture de la session* est cochée, le client sera alors considéré comme non sauvegardable et un point d'exclamation orange apparaitra devant son icône de sauvegarde. À la fermeture de la session, RaySession attendra que vous fermiez vous-même le programme car il est impossible de savoir s'il contient des changements non sauvegardés. * Si la case *Essayer de fermer gracieusement la fenêtre* est cochée, alors à la fermeture de la session, RaySession essaiera de fermer la fenêtre comme si vous fermiez la fenêtre du programme. C'est très pratique lorsque le programme réagit en se fermant s'il n'y a pas de changements non sauvegardés et en affichant une fenêtre de confirmation de fermeture dans le cas inverse (la plupart des programmes réagissent de la sorte). Si `wmctrl` n'est pas installé ou que le gestionnaire de fenêtres ne semble pas compatible, vous devrez fermer le programme vous même dans tous les cas. ==== Zone de test image::ray_hack_zone_test.png[] La zone de test vous permet de tester les réglages de lancement, d'arrêt et de sauvegarde réglés dans cette fenêtre sans avoir à *Sauvegarder les changements*. == Les sessions réseau Une session réseau permet de lancer une autre session sur une autre machine en même temps que votre session. Ça peut être particulièrement utile si vous utilisez net-jack pour décharger votre machine d'une partie du DSP, si vous avez des effets gourmands qui tournent sur une autre machine par exemple. Les sessions réseau fonctionnent selon un rapport de maître à esclave. Une session est maîtresse et peut avoir plusieurs sessions esclaves elles-mêmes maîtresses d'autres esclaves, mais un tel scénario semble complètement farfelu. Organisez vous simplement: un maître, un ou des esclave(s). Pour lancer une session réseau (esclave donc), lancez le modèle d'application *Network Session* depuis la fenêtre des applications et suivez les instructions. image::session_reseau_modele.png[Ajouter une session réseau] Vous devrez lancer un démon sur la machine distante avec la commande `ray-daemon -p 1234` (`1234` est un exemple, mettez le port que vous voulez). Ce démon vous affiche dans le terminal quelque chose sous cette forme: ``` [ray-daemon]URL : osc.udp://192.168.1.00:1234/ [ray-daemon] osc.udp://nom-de-machine:1234/ [ray-daemon]ROOT: /home/utilisateur/Ray Sessions reseau ``` image::session_reseau_invite.png[Configurer une session réseau] Vous devrez copier dans la fenêtre d'invitation de la session réseau l'une des deux URLs. La première (qui commence par `osc.udp://192.168.`) doit fonctionner à coup sûr, la seconde ne fonctionnera que si le nom de la machine esclave est correctement renseigné dans le fichier `/etc/hosts` de la machine maître. Toutefois, renseigner le nom de la machine esclave dans `/etc/hosts` et utiliser la deuxième URL est préférable, parce que l'adresse en 192.168. bougera si vous branchez votre machine esclave différemment (en filaire, en wifi), ou si vous réinstallez la distribution. Vous avez à présent 2 fenêtres RaySession sur votre machine maître, l'une contrôle la session maître, l'autre l'esclave. Vous reconnaîtrez l'esclave au fait qu'elle n'a ni barre d'outils (*Nouvelle Session*, *Ouvrir une session*, *Contrôle*), ni boutons *Abandonner la session* et *Fermer la session*. image::session_reseau_fenetre_fille.png[] La fenêtre esclave est cachable comme c'est le cas dans beaucoup de programmes NSM. image::session_reseau_client.png[] Si vous lancez `raysession -p 1234` sur votre machine esclave, vous aurez la fenêtre de la session esclave en double exemplaire, une sur chaque machine. *Conseil:* Mettez ce `ray-daemon -p 1234` au démarrage de votre machine esclave. [#ajouter_un_programme_non_fourni] == Ajouter un programme non fourni Si le programme que vous voulez ajouter ne gère pas de projet à enregistrer, cliquez sur *Exécutable*, rentrez le nom de l'exécutable et cliquez sur *Ok*. Sinon suivez cet exemple. Nous voulons ajouter ici Audacity à la session. Audacity est choisi à titre d'exemple parce qu'il est connu et généralement installé sur les distributions audio. Ce n'est pas forcément un programme très adapté à la modularité d'une session audio étant donné la façon dont il gère JACK. Cliquez sur *Exécutable* (_ou Ctrl+E_). + Dans la fenêtre d'ajout d'exécutable, Décochez la case *Protocole NSM*, tapez `audacity` dans le champ d'exécutable et cliquez sur *Ok*. image::audacity_executable.png[Fenêtre d'ajout exécutable dûment remplie] Un nouveau client est créé, sa fenêtre de propriétés s'ouvre sur l'onglet Ray-Hack et Audacity se lance. Dans Audacity, nous allons directement sauvegarder un projet vide dans le dossier du client. Le dossier du client se trouve dans le dossier de la session et porte le nom donné après *Dossier:* tout en haut de l'onglet Ray-Hack. Nous allons appeler le projet EXACTEMENT comme la session RaySession en cours. Pour celà, dans Audacity, faites _Menu -> Fichier -> Sauvegarder le projet -> Sauvegarder le projet_. image::audacity_sauver_projet.png[Sauvegarder le projet vide d'audacity] Cliquez sur *Valider* à l'éventuelle fenêtre d'avertissement. + Dans la boîte de sauvegarde de fichiers qui s'ouvre, vous trouverez le dossier de la session en bas à gauche (voir <>), cliquez dessus pour rentrer dedans. À l'intérieur de celui-ci vous devez voir le dossier du client tel qu'il figure en haut de l'onglet Ray-Hack, rentrez dans ce dossier. En haut à gauche de la boîte de sauvegarde, tapez le nom exact de votre session dans le champ *Nom:* puis validez. [caption="Figure 1: ",link=images/audacity_sauver_fichier.png] image::audacity_sauver_fichier.png[Où sauvegarder le projet Audacity, 640, 480] Fermez Audacity. + En haut à droite de l'onglet Ray-Hack de la fenêtre de propriétés du client, cliquez sur *Naviguer*. + [caption="Figure 1: ",link=images/audacity_charger_config_file.png] image::audacity_charger_config_file.png[Fenêtre de chargement du CONFIG_FILE, 640, 480] sélectionnez le projet Audacity que vous venez de créer, son nom commence par le nom de la session et termine par `.aup`. Si tout s'est bien passé, le champ *Fichier de configuration* est devenu `$RAY_SESSION_NAME.aup` et le champ *Arguments* est devenu `"$CONFIG_FILE"`. + Cochez les cases *Attendre une fenêtre avant d'être considéré comme prêt*, *Demander à l'utilisateur de fermer lui même le programme* et *Essayer de fermer gracieusement la fenêtre*. Cliquez en bas à droite sur *Sauvegarder les changements*. image::audacity_ray_hack_final.png[Onglet Ray-Hack du client audacity dûment rempli] Lancez le client Audacity et vérifiez que la fenêtre d'Audacity porte bien le nom de la session. + Cliquez sur l'icône du client Audacity, dans le menu déroulant choisissez *Sauvegarder comme modèle d'application*, et rentrez `Audacity` dans le champ de la boîte de dialogue qui est apparue. Maintenant lorsque vous voudrez lancer Audacity dans la session, vous n'aurez qu'à lancer le modèle Audacity depuis la fenêtre d'ajout d'applications. Notez que le bouton de sauvegarde du client est derrière un point d'exclamation orange, celà signifie que RaySession n'est pas en mesure de sauvegarder son projet et qu'il faudra le faire vous même. Selon le programme que vous souhaitez ajouter à la session, il est possible que ce ne soit pas toujours aussi facile. Certains programmes vont exiger un argument qui précède le fichier de configuration, dans ce cas tapez `mon_programme --help` ou `man mon_programme` pour savoir comment charger un projet au démarrage du programme, et adaptez celà dans le champ *Arguments*. == Importer une session NSM Pour importer une session créée avec *Non Session Manager* ou *New Session Manager*, déplacez ou copiez le dossier de la session dans le dossier racine des sessions RaySession (par défaut ~/Ray Sessions). Ensuite cliquez sur *Ouvrir une session*, votre session doit apparaître dans la liste des sessions, double-cliquez dessus. RaySession ne ré-écrira pas les clients ajoutés ou supprimés dans la fichier session.nsm, à partir du moment où vous ouvrez une session NSM avec RaySession, vous devez continuer avec RaySession. Si jamais vous souhaitez utiliser un autre gestionnaire de sessions, vous trouverez dans le menu *Fichier -> Utilitaires -> Convertir la session au format NSM* qui - comme son nom l'indique - convertit la session en cours au format de session NSM. Évidemment, celà entraîne quelque modifications, tels que le mode de préfixe ou la façon dont seront nommés les clients JACK, mais rien qui empêche la session de fonctionner. [#options_du_demon] == Les options du démon Les options du démon sont des services qui sont activables et désactivables via le bouton *Contrôle* en haut à droite de la fenêtre principale, ou via le menu *options* de la barre de menus. image::options_du_demon.png[Options du démon] Voici le détail des différentes options: [#raccourcis_dossier_de_session] === Fournir des raccourcis du dossier de la session En production audio, on a souvent recours au fait de créer un fichier audio ou midi avec un programme pour finalement le charger dans un autre. Cette option offre quelque chose de purement pratique: un raccourci vers le dossier de la session en cours dans votre gestionnaire de fichiers et dans les boîtes de dialogue prévues pour aller chercher ou sauvegarder les fichiers. Ça permet tout simplement d'éviter de perdre du temps à parcourir l'arborescence de son dossier personnel pour chercher un fichier que vous avez mis dans le dossier de votre session puisque c'est bien sa place. + Bien entendu, ce raccourci est supprimé lorsque la session est déchargée. + Techniquement, les raccourcis sont créés pour GTK2, GTK3, QT4, QT5, KDE et FLTK. === Cliché automatique à la sauvegarde Cette option est très loin d'être triviale, elle permet de prendre un cliché de la session après chaque sauvegarde. Celà signifie qu'en cas d'erreur technique ou artistique vous aurez la possibilité de retrouver la session dans l'état où elle se trouvait au moment du cliché. Cette option nécessite d'avoir le programme `git` installé. Voir <> pour plus de détails. === Mémoire des bureaux Si cette option est enclenchée, RaySession sauvegardera (ou tentera de sauvegarder) le numéro du bureau virtuel sur lequel se trouvaient les fenêtres des clients à la sauvegarde de la session. + Ainsi lorsque vous relancerez la session ou les clients, les fenêtres seront redispatchées sur les bureaux sur lequels elles figuraient. + Cette option nécessite d'avoir le programme `wmctrl` installé pour fonctionner, et ne fonctionnera probablement pas avec Wayland. [#option_scripts_de_session] === Scripts de session Désactiver cette option pour n'actionner aucun script de session, et ainsi ouvrir, sauvegarder ou fermer une session en ignorant totalement les scripts associés à ces actions. + Ces scripts sont utilisés par les sessions avec <>. + Voir <> pour plus de détails. === Se souvenir de l'état des IGUs Cette option ne concerne que les client NSM capables d'afficher/cacher leur interface graphique. Sans cette option, certains d'entre eux vont toujours démarrer cachés, d'autres vont se souvenir s'ils étaient visibles à leur dernière sauvegarde. Avec cette option enclenchée, les interfaces graphiques seront affichées au moment où la session est prête si elles étaient visibles lors de la dernière sauvegarde ou si le client n'a jamais été lancé. [#cliches] == Les clichés Les clichés nécessitent d'avoir le programme `git` installé, si vous n'avez pas `git`, le bouton de marche arrière n'apparaît pas et il est impossible de prendre un cliché ou d'y revenir. Un cliché mémorise les fichiers et leurs contenu à un moment précis. Les fichiers volumineux et les fichiers ayant certaines extensions tels que les fichiers audio et video sont ignorés, sinon le processus de cliché serait trop long et celà doublerait inutilement la taille des dossiers de session. Celà n'est en fait pas très gênant, au contraire, puisque vos fichiers audio récents restent présents quand vous retournez à un cliché précédent. + Si malgré tout le processus de cliché s'avère long, une fenêtre apparaît et vous pouvez annuler sans aucun risque le cliché en cours. Si vous l'annulez, Le cliché automatique n'aura plus lieu pour cette session. L'intérêt des clichés réside dans le fait de pouvoir revenir à moment antérieur de la session, avant d'avoir eu cette idée artistique géniale qui s'est avérée nulle et non avenue, avant d'avoir tenté un redécoupage des échantillons au microcoscope qui a finalement tué toute forme de musicalité, avant qu'un programme plante pour une raison inconnue des services de police... N'ayez crainte, revenir à un cliché ne vous empêchera pas de revenir là où vous en êtiez. Pour faire revenir la session à un cliché, cliquez sur le bouton de marche arrière situé à droite du bouton *Exécutable*. image::cliche.png[] Sélectionnez le cliché vers lequel vous voulez revenir et cliquez sur *Ok*. Un nouveau cliché est pris, la session se ferme, le cliché voulu est rappelé et la session se ré-ouvre. Il est également possible de faire revenir uniquement un client à un état précédent de la session en faisant un clique droit sur le client, puis *Retourner à un état précédent*. + Si vous le souhaitez vous pouvez éditer pour chaque client les fichiers ignorés par les clichés dans la fenêtre de propriétés du client. Avec l'option *Cliché automatique à la sauvegarde*, un cliché est pris juste après chaque sauvegarde de la session, sauf s'il n'y a aucun changement depuis le cliché précédent. Pour prendre un cliché à un autre moment, cliquez sur l'icône de marche arrière à droite du bouton *Exécutable* et sur *Prendre un cliché maintenant*, celà présente l'avantage de pouvoir nommer le cliché et d'avoir ainsi un repère temporel plus parlant que la date et l'heure du cliché. + [#les_scripts_de_session] == Les scripts de session Les scripts de session permettent de programmer des actions personnalisés à l'ouverture, à la sauvegarde et à la fermeture de la session. Ils sont notamment utilisés pour les sessions avec <>. + Des connaissances en script shell sont nécessaires pour éditer ces scripts, mais tout un chacun peut les utiliser. Les scripts de session se trouvent dans un dossier `ray-scripts` situé soit dans un dossier de la session, soit dans un dossier parent. + Par exemple, pour une session étant dans: + `~/Ray Sessions/avec_script_de_foo/ma session` le dossier des scripts de session peut-être + `~/Ray Sessions/avec_script_de_foo/ma session/ray-scripts` + `~/Ray Sessions/avec_script_de_foo/ray-scripts` + `~/Ray Sessions/ray-scripts` + `~/ray-scripts` L'intérêt d'un tel comportement est de pouvoir scripter un ensemble de sessions sans avoir à y recopier les scripts, mais surtout de livrer une session non scriptée lorsqu'on la transfère à quelqu'un d'autre pour un travail collectif. + Seul le dossier de scripts le plus près de la session dans l'arborescence sera considéré. Ainsi, un dossier `ray-scripts` vide dans une session désactivera les scripts pour cette session. Pour éditer les scripts, commencez par créer une session avec le modèle *avec les scripts de base*, il s'agit d'un modèle de session avec des scripts ne comprenant absolument aucune action particulière. Rendez-vous dans le dossier `ray-scripts` dans le dossier de la session, vous y trouverez les fichiers `load.sh`, `save.sh` et `close.sh`. Dans chacun de ces scripts, `ray_control run_step` correspond à l'action normale effectuée (selon le script: charger, sauvegarder ou fermer la session). Si un de ces trois scripts ne vous est d'aucune utilité, supprimez le, ce sera du temps gagné de ne pas passer par ce script. Les fichiers scripts doivent impérativement être exécutables pour fonctionner. Vous aurez probablement besoin de l'utilitaire en ligne de commande `ray_control` pour effectuer des actions en rapport avec tel ou tel client. tapez `ray_control --help` pour connaître toutes ses possibilités. Le modèle de session à mémoire de configuration de JACK utilise les scripts de session, mais on peut aussi imaginer moult actions possibles selon vos besoins et vos envies, par exemple : * définir un ordre bien précis de lancement des clients à l'ouverture de la session (un exemple est fourni dans le code source) * faire une copie de sauvegarde de la session sur un disque dur externe à chaque fermeture * envoyer un raccourci _Ctrl+S_ aux fenêtres des clients non sauvegardables à la sauvegarde de la session (un exemple est fourni dans le code source) * Allumer la lumière rouge à l'entrée du studio à l'ouverture, l'éteindre à la fermeture * Lancer la machine à café à la fermeture de la session (exemple débile, allez donc appuyer sur le bouton de la cafetière, de toutes façons faudra changer le filtre !) * Faire beaucoup, beaucoup, beaucoup d'erreurs qui feront planter votre session, soyez prudents évidemment ! [#memoire_de_la_configuration_de_jack] == Mémoire de la configuration de JACK Il est possible grâce aux scripts de session de rappeler automatiquement la configuration de JACK spécifique à une session avant de la charger. Ce comportement pourra rappeler à certains le fonctionnement des studios LADISH, en beaucoup mieux fait, du moins c'est ce qui est espéré. === Dans quels cas l'utiliser Celà peut s'avérer utile: * Si vous avez besoin d'utiliser une interface audio spécifique pour la session * Si vous travaillez sur de multiple projets avec des fréquences d'échantillonage différentes (telle session sur 44100 Hz, telle autre sur 48000 Hz). + Ainsi celà vous évitera d'avoir à reconfigurer, arrêter et redémarrer JACK vous même, ou encore d'éviter d'oublier de le faire et de se faire insulter par certains programmes. * Si vous voulez éviter de charger une session très gourmande en DSP (par exemple en phase de mixage) avec un tampon trop petit (128 par exemple). + Notez que sur la plupart des interfaces audio, il est possible de changer la taille du tampon à chaud (sans redémarrer JACK). === Utilisation Il est nécessaire que l'option <> soit enclenchée (Cette option est enclenchée par défaut). Pour utiliser le mémoire de configuration de JACK, créez une nouvelle session à partir du modèle *Avec mémoire de la configuration de JACK*. + Il s'agit en fait d'une session scriptée (voir <>) qui lance un script fourni avec RaySession, mais qui lui est complètement externe, ainsi RaySession n'a toujours aucun rapport direct avec JACK. Lisez la fenêtre d'informations à ce sujet puis validez. JACK redémarre puis votre session se lance. === Principe de fonctionnement À chaque fois que la session est sauvegardée, la configuration de JACK est sauvegardée dans la session, dans le fichier `jack_parameters`. + Avant l'ouverture de la session, JACK est redémarré si la configuration de la session est différente de la configuration actuelle de JACK. + Après la fermeture de la session, JACK est si nécessaire redémarré avec la configuration en cours avant l'ouverture. La configuration des ponts *PulseAudio -> JACK* est également sauvegardée et restaurée avec la configuration de JACK. Si vous ouvrez cette session après l'avoir copiée sur un autre ordinateur, la configuration de JACK ne sera pas rappellée mais sera écrasée lors de la sauvegarde. Seule la fréquence d'échantillonage de la session sera utilisée. === Cas particuliers ''' *Pour ouvrir une session sans recharger sa configuration de JACK:* * désactivez l'option <> * ouvrez la session ''' *Pour changer la configuration de JACK d'une session:* * Démarrez JACK avec la configuration désirée * Désactivez l'option <> * Ouvrez la session * Ré-activez l'option <> * Sauvegardez la session ''' *Pour rendre une ancienne session sensible à la configuration de JACK* * copiez le dossier `ray-scripts` d'une session avec mémoire de la configuration de JACK dans le dossier de la session * Activez l'option <> * Ouvrez la session *ou* * déplacez la session dans un sous-dossier contenant le dossier `ray-scripts` adhoc * Ouvrez la session [#sous_le_capot] == Sous le capot RaySession n'est en réalité qu'une interface graphique pour ray-daemon. Lorsque vous lancez RaySession, l'interface graphique lance le démon et s'y connecte, et elle arrête le démon lorsqu'on la ferme. L'interface graphique et le démon communiquent entre eux par messages OSC (Open Sound Control), comme c'est le cas entre le démon et les clients NSM. Ainsi, vous pouvez connecter plusieurs interfaces graphiques à un démon, même à distance. Tapez `raysession --help` pour voir comment faire. Il n'est pas interdit d'avoir plusieurs instances de démon lancés simultanément, ainsi si vous lancez RaySession alors qu'une instance est déjà lancée, celle-ci lancera un nouveau démon. Toutefois, cette façon de travailler étant peu commune, l'utilisation d'un seul démon est favorisée. Ainsi, si un démon tourne et qu'il n'a aucune interface graphique attachée, raysession se connectera à ce démon par défaut. [#ray_control] == Contrôler RaySession en ligne de commande la commande `ray_control` vous permet de faire a peu près tout ce qu'il est possible de faire avec l'interface graphique, et même un peu plus. tapez `ray_control --help-all` pour connaître l'ensemble des possibilités. Au cas où il y a plusieurs démons lancés (voir <>), `ray_control` ne considerera que celui qui a été lancé en premier, sauf si vous spécifiez son port OSC avec l'option `--port` ou la variable d'environnement RAY_CONTROL_PORT. On pourrait penser qu'il n'y a pas d'intérêt à utiliser `ray_control` puisque la commande `oscsend` permet d'envoyer un message OSC au démon, c'est faux. + D'une part, parce que `oscsend` permet d'envoyer des messages mais pas d'obtenir des informations de manière simple (quels sont les clients actifs ? quel est l'executable de tel client ? ...), d'autre part parce que la commande `ray_control` se terminera lorsque l'action demandée sera effectuée, par exemple `ray_control open_session ma_session` se terminera lorsque la session sera chargée. Pensez à affecter `ray_control save` à un raccourci global de votre environnement de bureau (_Ctrl+Meta+S_), celà vous fera gagner un temps fou ! == Foire aux questions - *Est-il toujours intéressant de lancer Ardour (ou un autre DAW compatible NSM) directement plutôt que dans RaySession ?* + Sauf pour un projet vraiment tout petit, Non. + Si vous utilisez Ardour, lancez le toujours depuis RaySession, d'une part le cliché automatique à la sauvegarde peut vous être d'un secours inespéré, d'autre part, vous n'êtes pas à l'abri d'avoir besoin d'un autre programme même si vous ne l'aviez pas prévu. - *Puis-je lancer dans une session RaySession un projet Ardour déjà existant ?* + Vous trouverez dans le menu *Fichier -> Utilitaires -> Convertir une session Ardour en session Ray*, celà crée et lance une session RaySession à partir d'une session Ardour. Il n'est pas surfait de faire une copie de sauvegarde de votre session Ardour avant de lancer ce script. Bien évidemment, il ne faut pas que Ardour soit ouvert avec cette session pendant l'execution de ce script, mais ça vous l'aviez déjà compris. RaySession-0.12.2/manual/fr/manual.html000066400000000000000000002431361417052567600177500ustar00rootroot00000000000000 Manuel de RaySession

EN FR DE

icon

pour la version 0.11.0

Introduction

RaySession est un gestionnaire de session audio pour GNU/Linux. Il permet de démarrer dans une même session plusieurs programmes audio, de sauvegarder leurs projets ensemble et ainsi d’éviter de multiples manipulations pour retourner à une configuration donnée.

Pour être lancés dans RaySession, il est très largement préférable que ces programmes audio soient compatibles avec le protocole NSM, et beaucoup le sont déjà, entre autres Ardour, Qtractor, Carla, Guitarix, Mamba, Patroneo, ZynAddSubFx…​

RaySession part du principe que votre configuration audio est fonctionnelle pour de la production audio, si ce n’est pas le cas réglez d’abord ce problème et ne perdez pas votre temps à essayer d’utiliser RaySession.

Maintenant voyons comment s’en servir.

Exemple d’utilisation simple

Pour la production audio sous GNU/linux, Il est largement conseillé d’utiliser le serveur JACK. Avant de créer ou de lancer une session, assurez-vous que le serveur JACK tourne, RaySession n’a aucun rapport direct avec JACK, toutefois les programmes que vous allez lancer dans votre session en auront besoin.

Prenons un exemple où pour composer un morceau, nous aurons besoin des logiciels Ardour et Guitarix, assurez vous que ces 2 programmes soient installés.

Pour créer une nouvelle session, cliquez en haut à gauche sur Nouvelle Session (ou Ctrl+N). Apparaît alors une fenêtre de dialogue.

Nouvelle session

En haut à droite vous apercevez le dossier racine des sessions, c’est là que les sessions seront sauvegardées (une session RaySession étant un dossier contenant un fichier raysession.xml).

Rentrez le nom voulu pour cette nouvelle session dans le champ prévu à cet effet. Pour mettre votre nouvelle session dans un sous-dossier, tapez le nom de la manière suivante : sous-dossier/ma session .

La boîte à choix multiples de modèles de session vous permet de choisir entre

  • Un modèle de session vide

  • Un modèle avec mémoire des connexions JACK

  • Un modèle scripté avec mémoire de la configuration de JACK

  • Un modèle avec les scripts de session de base (pour les utilisateurs avancées pourvus de connaissances en script shell)

  • Tous les modèles de session que vous aurez vous-même créés.

Dans un premier temps, laissez le modèle sur Avec mémoire du patch de JACK, cliquez sur Ok pour lancer votre session.

Session lancée

La partie session de la fenêtre devient active, en haut est écrit le nom de votre session, et votre session contient déjà un programme client qui s’appelle Connexions JACK. C’est lui qui sauvegardera et refera les connexions de la baie de brassage de JACK.

Pour ajouter Ardour à votre session, cliquez sur le bouton Application (ou Ctrl+A), apparaît alors la fenêtre des applications (plus de détails à la rubrique Fenêtre d’ajout d’application). Dans la partie droite, cherchez Ardour (selon votre version d’ardour, il est possible qu’il s’appelle Ardour5 ou Ardour6) et double-cliquez dessus.

Ajouter Ardour à la session

Un client Ardour apparaît en dessous de Connexions JACK et Ardour démarre (normalement directement avec une session Ardour vide).

Faites de même avec Guitarix.

Session prête avec Ardour et Guitarix

Dans Ardour, ajoutez une piste (Menu: Piste → Ajouter une piste), dans la fenêtre Ardour qui est apparue, nommez la piste Guitare et mettez la boîte à choix multiples configuration sur Stereo.

Ajouter une piste Ardour pour Guitarix

Vous allez maintenant afficher la Baie de brassage de JACK. Pour celà, dans RaySession, appuyez sur Contrôle puis Afficher la baie de brassage de JACK (ou Ctrl+J). La baie de brassage est apparue sur la partie droite de la fenêtre. Connectez l’entrée de Guitarix à une entrée matérielle et les sorties de Guitarix vers les entrées de cette nouvelle piste Ardour. Assurez vous que les entrées de votre piste Guitare ne sont pas connectées aux entrées matérielles.

Baie de brassage de ma session

Voilà, vous avez une configuration où vous pouvez enregistrer directement le son de votre guitare traité par Guitarix dans Ardour. Si vous n’avez pas de guitare, vous n’avez qu’à chanter faux dans un micro ou taper sur un coussin, ce n’est ici qu’un exemple.

Retournez maintenant à la fenêtre de RaySession, et sauvegardez la session en cours en cliquant sur le bouton en forme de disquette vers le haut à droite (ou Ctrl+S). Il est vivement recommandé car très pratique d’affecter un raccourci clavier global de votre système à la sauvegarde de la session en cours. Celà dependra de votre environnement de bureau, mais il suffit d’affecter le raccourci Ctrl+Meta+S à la commande ray_control save (Meta est la touche Windows), ainsi vous n’aurez pas à retourner à la fenêtre de RaySession pour sauvegarder la session.

Maintenant, fermez la session en cliquant sur la croix rouge en haut à droite (ou Ctrl+W).

Une fois la session fermée, cliquez sur Ouvrir une session (ou Ctrl+O), double-cliquez sur la session que vous venez de créer pour la ré-ouvrir.

Vous devez retrouver les programmes et leur projet ainsi que les connexions de JACK telles qu’elles étaient quand vous avez fermé la session, et tout fonctionne donc sans aucune autre manipulation.
Un des avantages de la modularité dans ce cas précis, c’est qu’une fois qu’on aura terminé les prises de guitare, on pourra arrêter Guitarix pour ne pas surcharger le processeur inutilement, et il sera tout de même facile de le redémarrer si besoin.

Vue d’ensemble des outils de la session

Ligne du haut

Ligne du haut de la trame de session

De gauche à droite:

  • le bouton menu vous donne accès à

    • sauvegarder la session en cours comme modèle
      Le modèle de session créé apparaîtra alors dans la boîte à choix multiples de modèles de session dans la fenêtre de dialogue Nouvelle Session. Attention toutefois, L’ensemble des fichiers de la session seront sauvegardés dans le modèle, il ne faut donc pas le faire si la session contient beaucoup de fichiers audios. D’une part la copie sera longue, d’autre part vous risquez de multi-copier inutilement des fichiers qui prendront beaucoup de place.

    • Dupliquer la session en cours
      C’est l’équivalent du bien connu "Sauvegarder sous…​", sauf que RaySession est obligé d’arrêter et de redémarrer la plupart des programmes pour passer d’une session à l’autre. Évitez de dupliquer une session avec beaucoup de fichiers audios, celà pourrait être long, mais fort heureusement une telle opération peut être annulée.

    • Renommer la session
      Il faudra alors arrêter tous les clients.
      Alternativement, vous pouvez renommer une session en la dupliquant puis en supprimant le dossier de la session initiale.
      Vous pouvez aussi renommer une session en renommant son dossier, mais ATTENTION, cette session ne doit surtout pas être chargée !

  • le bouton en forme de crayon vous donne accès aux notes de session.
    Écrivez ici des informations dont vous avez besoin, des réglages physiques, les paroles d’une chanson, la recette du cassoulet de mamie…​toutefois n’y écrivez pas un roman en 3 tomes, d’autres outils sont bien plus adaptés, et les notes sont limitées à 65000 caractères pour des raisons techniques.
    Le crayon est vert quand des notes existent, il est orange quand la fenêtre de notes est ouverte, sinon il est transparent.

  • le nom de la session chargée (ici ma session)

  • le bouton Abandonner la session qui permet de fermer la session sans la sauvegarder

  • le bouton Fermer la session, qui sauvegarde et ferme la session en cours.
    Notez que vous n’avez pas besoin de fermer la session en cours pour en ouvrir une autre. Certains clients sont capables de basculer d’une session à l’autre et ça peut être beaucoup moins long que de tout fermer pour tout relancer.

Ligne du bas

Ligne du bas de la trame de session

De gauche à droite:

  • le bouton en forme de dossier pour ouvrir le dossier de la session avec votre gestionnaire de fichiers

  • le bouton en forme d’étoile jaune qui déroule un menu contenant vos applications favorites s’il y en a

  • le bouton Application qui permet d’ajouter à la session un modèle d’application d’usine ou que vous aurez créé vous même. C’est la méthode conseillée pour ajouter un client. voir Fenêtre d’ajout d’application.

  • le bouton Exécutable qui permet d’ajouter à la session un programme depuis son exécutable. Vous en aurez besoin si vous souhaiter ajouter un programme pour lequel il n’existe pas de modèle. voir Fenêtre d’ajout d’exécutable.

  • le bouton de marche arrière pour revenir à un état précédent de la session. Celà nécessite d’avoir le programme git installé, sinon ce bouton n’apparaîtra pas.
    Voir Les clichés pour plus de détails.

  • l’indicateur d’état du serveur.
    Les états du serveur peuvent être en réalité très furtifs, mais ils sont affichés pendant un temps suffisament long pour que vous puissiez les voir.
    L’état du serveur peut être:

    • éteint : pas de session en cours

    • prêt : la session est en cours

    • lancement : lancement des programmes de la session

    • copie : une copie est en cours, pour une duplication de session ou une sauvegarde de la session comme modèle

    • fermeture : la session est en train de se fermer

    • cliché : un cliché de la session est en train d’être pris, donc vous pourrez revenir à l’état actuel la session.
      voir Les clichés.

    • attente : Le serveur attend que vous fermiez vous-même des programmes non sauvegardables

    • script : un script est actionné

    Une fenêtre d’information ou de progression s’affiche si vous cliquez sur cet indicateur d’état s’il est sur copie, cliché ou attente.

  • le bouton de sauvegarde de la session

  • la corbeille, vous trouverez ici les clients que vous avez supprimés. Vous pourrez alors les restaurer dans la session ou supprimer définitivement tous les fichiers qu’ils ont créé dans le dossier de la session.

Vue d’ensemble d’un client

trame d’un client

Un client contient de gauche à droite:

  • L’icône du client sur laquelle vous pouvez cliquer pour faire apparaître un menu avec les actions suivantes

    • Sauvegarder comme modèle d’application
      Le modèle créé apparaîtra alors dans la Fenêtre d’ajout d’application. Celà permet par la suite de lancer directement un client avec la configuration souhaitée (Ardour avec telles pistes, Hydrogen avec tel kit de batterie…​). Attention, celà copie tous les fichiers du client donc évitez de le faire si le client contient beaucoup de fichiers audio.

    • Renommer
      Changer le nom du client situé à droite de son icône, il s’agit d’un nom purement visuel qui peut vous aider à retrouver vos moutons

    • retourner à un état précédent
      Permet de faire revenir uniquement le client à un état antérieur de la session, voir Les clichés.
      Vous ne pourrez toutefois pas revenir à un état antérieur à un renommage de la session, pour celà il faut faire revenir toute la session en arrière.

    • Propriétés
      Affiche la fenêtre des propriétés du client

    Ce menu est aussi accessible par clique droit n’importe où sur le client

  • Le nom du client (ici Carla), qui peut-être changé facilement par clique droit → renommer

  • selon le type et les capacités du client vous pouvez voir ici

    • un oeil (éventuellement barré), celà signifie que le client est compatible NSM et qu’il est capable d’afficher ou cacher sa fenêtre en cliquant sur l’oeil.

    • un bouton Hack, celà signifie que le client n’est pas compatible NSM, en tout cas qu’il n’est pas lancé avec ce protocole. Cliquer sur Hack permet de changer la façon dont il est lancé en ouvrant la fenêtre de propriétés du client sur l’onglet Ray-Hack

  • Le bouton Démarrer qui est grisé si le client est déjà démarré

  • le bouton Arrêté qui est grisé si le client n’est pas démarré. Si vous arrêtez le client et qu’il n’est toujours pas arrêté après un certain temps, le bouton devient rouge et vous pouvez cliquer dessus pour tuer le client. Mais restez détendus, et ne l’utilisez que si vraiment il vous semble complètement inerte, celà pourrait causer des problèmes, même si a priori personne ne vous enverra en prison.

  • l’état du client qui peut être

    • arrêté : le client est arrêté

    • prêt : il est lancé et fonctionnel

    • ouverture : le programme est en train d’ouvrir son projet, patientez un peu

    • fermeture : le programme est en train de se fermer

    • lancé : s’il reste sur l’état lancé, celà signifie

      • si c’est un client Ray-Hack, qu’il n’a pas de fichier de configuration

      • s’il est lancé comme un client NSM, qu’il n’est pas compatible NSM, et qu’ainsi toute sauvegarde est vaine. Il peut être pratique de lancer de cette façon certains programmes tels qu’une baie de brassage (Catia) ou un utilitaire dont on n’a pas besoin de sauvegarder l’état (Qrest).

    • bascule : le client change de projet pendant un changement de session

  • le bouton en forme de disquette qui permet de sauvegarder le client.
    Si par dessus cette disquette vous voyez

    • trois points rouges: le client contient des changements non sauvegardés

    • un V vert: le client ne contient pas de changements non sauvegardés

    • un point d’exclamation orange: Ce n’est pas un client NSM, et il est impossible de sauvegarder son projet, vous devrez le faire vous même

  • la croix rouge qui permet d’envoyer le client à la corbeille

Fenêtre d’ajout d’application

Le fenêtre d’ajout d’application se lance en cliquant sur le bouton Application (ou Ctrl+A).

Fenêtre d’ajout d’application

La liste des applications disponibles est à droite. Si le logiciel que vous souhaitez lancer n’est pas présent ici, regardez Ajouter un programme non fourni.


En haut à gauche, c’est le bloc de filtres

Bloc de filtre de la fenêtre d’ajout d’application
  • le champ de filtre permet de rentrer une chaîne de caractères, seuls les modèles contenant cette chaîne de caractères dans leur nom apparaîtront.

  • la case à cocher Usine affiche les modèles intégrés à RaySession ou fournis par votre distribution

  • utilisateur affiche les modèles créés par l’utilisateur en faisant Sauvegarder comme modèle d’application

  • NSM affiche les clients compatibles NSM, ou lancés comme tel (voir Ajouter un programme non fourni)

  • Ray-Hack affiche les clients lancés sans protocole NSM


En bas à gauche le bloc d’informations sur le modèle sélectionné à droite

Bloc d’informations sur le modèle sélectionné
  • en haut à droite de ce bloc, une étoile, cliquez dessus pour l’ajouter aux favoris ou l’enlever des favoris

  • Si c’est un modèle utilisateur, un bouton Utilisateur vous permet de supprimer ce modèle

  • le bouton en bas à droite de ce bloc vous permet d’accéder à toutes les propriétés du modèle, comme dans la Fenêtre de propriétés d’un client, sauf que rien n’est éditable.

Astuce : Cette fenêtre est conçue pour un ajout d’application très rapide, et se comporter comme Alt+F2 sur votre bureau.
Par exemple, depuis la fenêtre principale de RaySession, pour ajouter Carla tapez Ctrl+A, puis carla, sélectionnez le bon modèle avec les flèches Haut/Bas, puis Entrée.

Fenêtre d’ajout d’exécutable

Le fenêtre d’ajout d’exécutable se lance en cliquant sur le bouton Exécutable (ou Ctrl+E).

Fenêtre d’ajout d’exécutable

Vous aurez besoin de passer par cette fenêtre si vous voulez ajouter un client qui n’apparaît pas dans la liste de la fenêtre d’ajout d’application. Cette fenêtre se présente très simplement, un champ pour rentrer l’exécutable, une case Protocole NSM, un bouton d’options avancées.

Laissez le protocole NSM coché si:

  • le programme à lancer est compatible NSM (s’il n’est pas dans la liste d’applications, merci de le faire savoir !)

  • le programme à lancer est un utilitaire dont on n’a aucun besoin de sauvegarder un quelconque projet (QRest, Catia…​).
    L’état d’un tel programme restera sur lancé et ne sera jamais prêt, c’est sans importance vu qu’ils n’a pas de projet à sauvegarder.

Si vous laissez le protocole NSM coché il ne sera pas possible d’ajouter un exécutable vers un chemin absolu, l’exécutable doit se situer dans un emplacement prévu à cet effet (vous ne pourrez pas lancer /usr/bin/mon_programme, mais mon_programme). Vous ne pouvez pas rentrer d’arguments ici, avec ou sans le protocole NSM.

Décocher la case Protocole NSM revient à lancer le programme avec le pseudo-protocole Ray-Hack.

Si vous cliquez sur le bouton d’options avancées, un bloc options avancées apparaît avec

Fenêtre d’ajout d’exécutable avancé
  • la case Démarrer le client, si vous la décochez le client sera ajouté mais non lancé

  • la boîte à choix multiple Mode de préfixe, celà définit le préfixe du nom des fichiers du client

    • sur Nom de la session, les noms des fichiers commenceront par le nom de la session, c’est la valeur par défaut

    • sur Nom du Client, les noms des fichiers commenceront par le nom fourni par le client lui-même, comme c’est le cas avec New Session Manager

    • sur Personnalisé, les noms des fichiers commenceront par la valeur que vous inscrirez dans le champ Préfixe juste en dessous

  • le champ Préfixe qui n’est actif que si Mode de Préfixe est sur Personnalisé

  • le champ ID du client (identifiant du client). Ne rentrez ici que des caractères alphanumériques ou des '_'.
    Celà est utile si vous voulez attraper et lancer des projets existants dans la session avec un exécutable. C’est pratique si vous voulez charger dans la session des projets créés en dehors d’une session. Aucune méthode ne permet de rendre la chose plus simple, celà dépend énormément du programme utilisé. RaySession vous insultera si vous rentrez un identifiant de client qui existe déjà dans la session.

Baie de brassage

la baie de brassage de JACK n’est pas affichée par défaut. Vous pouvez l’afficher en cliquant sur Contrôle puis Afficher la baie de brassage de JACK (ou Ctrl+J). La baie de brassage contient tous les ports AUDIO et MIDI de JACK que vous pouvez interconnecter.

Évidemment, si JACK n’est pas démarré, cette baie de brassage sera vide.

Il est conseillé d’avoir le pont A2J lancé si vous voulez travailler correctement avec le MIDI. Vous pouvez configurer celà via Cadence, Studio Control, ou via l’utilitaire en ligne de commande a2j_control.

RaySession n’inclut pas d’outils pour configurer le serveur JACK, QJackCtl, Studio Control, Cadence, ou l’utilitaire en ligne de commande jack_control font très bien ce travail. Notez que cette baie de brassage fonctionne également avec PipeWire.

Vue d’ensemble

Vue d’ensemble de la baie de brassage

Voilà à quoi peut ressembler votre baie de brassage. Ici il y a 7 boîtes :

  • une boîte system comprenant vos ports correspondant aux entrées matérielles

  • une boîte system comprenant vos ports correspondant aux sorties matérielles (enceintes, casque)

  • une boîte a2j comprenant vos ports correspondant aux entrées MIDI

  • une boîte a2j comprenant vos ports correspondant aux sorties MIDI

  • une boîte PulseAudio JACK Source

  • une boîte PulseAudio JACK Sink

  • une boîte Guitarix

Ici les ponts A2J et pulse2jack sont lancés. Vous observez que 4 de ces boîtes sont entourées d’une décoration (2 system et 2 a2j), ce sont les boîtes qui contiennent les ports matériels (votre interface audio, votre piano USB, n’importe quel contrôleur…​).


Certains ports audios sont regroupés en sous-groupes, que l’on appellera portgroups. Ces portgroups sont pour la plupart des paires stéréo détectées automatiquement par le nom des ports. C’est le cas ici pour :

  • system:capture 1/2

  • system:playback 1/2

  • PulseAudio JACK Source:front L/R

  • PulseAudio JACK Sink:front L/R

  • Guitarix:out 0/1

Ces portgroups facilitent les connexions et permettent une meilleur lisibilité générale.


Les lignes incurvées bleues correspondent aux connexions audios. Vous pouvez observer que :

  • les ports audio d’entrées matérielles sont connectés à PulseAudio JACK Source

  • les ports de PulseAudio JACK Sink sont connectés aux sorties matérielles

  • seul le premier port de system est connecté à l’entrée (in 0) du logiciel Guitarix

  • les ports audios de Guitarix sont connectés aux sorties matérielles

Faire et défaire une connexion

Vous pouvez établir une connexion entre 2 ports pourvu qu’ils remplissent les conditions suivantes :

  • les ports sont du même type (on ne peut pas connecter un port audio à un port MIDI)

  • l’un est un port d’entrée, l’autre est un port de sortie

Méthode Intuitive

Pour connecter ou déconnecter deux ports, cliquez sur un port sans relâcher le bouton de la souris, glissez le curseur jusqu’au port désiré puis relachez le bouton de la souris.

Méthode Alternative

Faites un clic droit sur un port, celà affichera un menu déroulant, choisissez Connecter puis le port désiré. Cliquez ailleurs pour faire disparaître ce menu. L’avantage de cette méthode est qu’elle permet de connecter rapidement un port à plusieurs autres, le menu restant affiché pendant les connexions.

Les options

Un clic droit n’importe où sur la baie de brassage permet d’en afficher le menu. Ce menu est également présent dans le menu de RaySession (menu Baie de brassage). Il vous permettra de :

  • basculer la baie de brassage en plein écran

  • Filtrer les ports: n’afficher que les ports AUDIO ou MIDI ou les deux

  • régler le niveau de zoom

  • rafraîchir le canevas: redemander à JACK la liste des ports existants et leurs connexions

  • Préférences du canevas: afficher une fenêtre d’options
    Tous les changements dans cette fenêtre prennent effet immédiatement. Survolez les cases pour afficher les infobulles.

Raccourcis à connaître

  • Un double clic n’importe où permet de basculer la baie de brassage en plein écran.

  • Ctrl+Molette de la souris permet de zoomer/dézoomer.

  • Alt+Molette de la souris permet déplacer la vue horizontallement.

  • Le bouton de la molette permet de déplacer la vue

  • Ctrl+bouton du milieu de la souris permet de couper toutes les connexions passant sous le curseur

Connexions en rafale

Il est possible de connecter un port ou un portgroup à différents ports assez rapidement. Il suffit de terminer ses connexions par un clic droit. Une video sera bien plus explicite.

Ici nous voulons connecter les multiple sorties d’Hydrogen à des tranches de Jack-Mixer. Dans la video les ronds bleus apparaissent avec un clic droit.

Passer les connexions d’un port à un autre

Il est parfois moins fastidieux de passer des connexions d’un port à un autre plutôt que de tout défaire pour tout refaire. Pour ce faire, partez du port qui contient les connexions et faites comme si vous vouliez faire une connexion, mais allez vers le port vers lequel vous souhaitez basculer les connexions.

  • Celà ne fonctionne que si le port de destination ne contient aucune connexion

  • Celà fonctionne de port à port ou de portgroup à portgroup mais pas de port à portgroup

Dans cette video nous avons un cas assez complexe où la source est branchée dans 3 Band Splitter. Les basses et les aigües (Output 1 et Output 5) sont envoyés directement dans EQ6Q Mono tandis que les medium (Output 3) passent d’abord par la distortion GxTubeScreamer. Nous voulons insérer la reverb Dragonfly Room Reverb avant l’égualisation EQ6Q Mono.


Notez qu’avec la connexion par clic droit et le passage de connexions d’un port à l’autre, il est très rapide d’intégrer un nouveau greffon dans une chaîne, comme ici où nous branchons Plujain Ramp Live entre Dragonfly Room Reverb et EQ6Q Mono.

Les ports A2J

ports a2j

Les ports MIDI fournis par le pont A2J (Alsa To Jack) présentent un trou à leur extrêmité pour les reconnaître. Leur véritable nom est un nom à ralonges, mais c’est à peu près la seule chose qui diffère avec les autres ports MIDI.

Les ports de tension de contrôle (ports CV)

ports CV

les ports de tension de contrôle, appellés communément ports CV (Control Voltage) ont le même fonctionnement que les ports audio classiques, cependant, ils sont faits pour piloter un ou plusieurs paramètres avec une précision bien plus importante que les ports MIDI. Comme leur flux n’est pas fait pour être écouté, il n’est pas possible de connecter simplement un port CV de sortie vers une entrée audio classique, celà pourrait endommager votre casque, vos enceintes, et peut-être même bien vos oreilles.
Si vous souhaitez quand même le faire, faites un clic droit sur l’un des ports, puis Connecter, puis le menu DANGEREUX.
Vous ne pourrez pas dire que vous n’étiez pas prévenu, et il est quasiment impossible de faire ça par erreur.

En revanche, connecter un port de sortie audio classique vers un port CV d’entrée est tout à fait possible, ça ne pose aucun problème.

Fenêtre de propriétés d’un client

La fenêtre de propriétés d’un client s’ouvre depuis le menu du client, en cliquant sur Propriétés.

La fenêtre des propriétés du client comprend 2 onglets, un onglet Général et un onglet spécifique au protocole utilisé par le client. Selon le protocole du client, le deuxième onglet s’appelle NSM, Ray-Hack ou Ray-Net.

Onglet Général

Propriétés d’un client
  • Le premier bloc de l’onglet Général affiche l’identifiant, le protocole, l’étiquette, la description et l’icône du client.
    Si vous ne les éditez pas, l’étiquette, la description et l’icône sont tirées du fichier .desktop associé à l’exécutable lancé, s’il a été trouvé.
    Si vous tenez à connaître le fichier .desktop utilisé, tapez ray_control client IDENTIFIANT get_properties dans un terminal (en remplaçant IDENTIFIANT par l’identifiant du client).

  • Ensuite vient le bloc des clichés, voir Les clichés.

  • la case à cocher Empêcher l’arrêt sans sauvegarde récente ou possible concerne la fenêtre qui peut apparaître lorsque vous demandez à un client de s’arrêter. Si cette case est décochée, alors le client sera stoppé sans qu’une fenêtre ne vous prévienne.
    Si la case est cochée, la fenêtre vous previendra lorsque

    • le client est non-sauvegardable depuis RaySession

    • on sait que le client contient des changements non sauvegardés

    • le client semble ne pas avoir été sauvegardé depuis plus d’une minute

    cocher cette case ou non dépend seulement de l’importance de la sauvegarde de votre client, à vous de juger. Celà dit, si la fenêtre d’avertissement vous agace, vous n’aurez qu’à cocher la case Ne plus empêcher l’arrêt du client dans cette fenêtre et la case Empêcher l’arrêt sans sauvegarde récente ou possible sera décochée.

Onglet NSM

Propriétés NSM d’un client

Le nom du client ici est fourni par le client lui-même.
Les capacités sont celle qui sont transmises par le client à son démarrage. Si le client n’a pas encore été démarré, ce champ est donc vide.

Éditer l’exécutable permet de changer la commande qui lance le client. Ne le changez que pour un autre exécutable capable de charger le projet du client existant. C’est utile par exemple si vous avez deux versions d’Ardour, l’une se lançant avec la commande ardour, l’autre avec Ardour6, et que vous voulez changer la version à utiliser.

Éditer les arguments est fortement déconseillé, et n’est surtout pas adapté au chargement d’un fichier comme argument.

Onglet Ray-Hack

Si le client est de type Ray-Hack, ici moult champs s’offrent à vous. Ce n’est pas forcément une bonne nouvelle, l’idée est de pouvoir charger dans la session un programme qui n’est pas (encore) compatible NSM. S’il est bien implémenté dans le client, le protocole NSM sera toujours bien plus confortable à utiliser et plus fiable que cette bidouille. Ceçi dit, si l’on peut attendre l’implémentation NSM dans tous les programmes audio, ce n’est pas le cas des autres programmes qui peuvent tout de même avoir une utilité dans la session.

Le pseudo-protocole Ray-Hack reprend les attributs des proxy (nsm-proxy ou ray-proxy), sauf que le client est lancé directement dans la session.

Propriétés Ray-Hack d’un client

Bloc de lancement

ray hack lancement
  • le Dossier est le nom du dossier de ce client, dans le dossier de la session. Le programme est lancé depuis ce dossier.

  • L'Exécutable est la commande qui lance le programme

  • Le Fichier de configuration sera le fichier du projet qu’on souhaitera ouvrir avec ce programme. Il plus que très recommandé de faire référence à un fichier dans le dossier du client.
    La variable $RAY_SESSION_NAME sera automatiquement remplacée par le nom de la session.
    Si ce champ est vide, le client restera toujours sur le statut lancé et jamais prêt. Dans certains cas, il peut donc être utile de taper n’importe quoi ici plutôt que rien.

  • Le bouton Naviguer ouvre une boîte de dialogue pour aller chercher le fichier de projet et remplir le champ Fichier de configuration

  • Le champ Arguments comprend les arguments passés à la commande Exécutable
    les arguments sont découpés comme ils le seraient dans un terminal, n’oubliez pas les " ou les ' si nécéssaire.
    par exemple pour reproduire ma_commande mon_argument_1 "mon argument 2" rentrez ma_commande dans le champ Exécutable et `ma_commande mon_argument_1 "mon argument 2"``dans le champ Arguments.

Bloc des signaux

ray hack signaux
  • Le Signal de sauvegarde ne peut être que rarement utilisé. Il peut être SIGUSR1 pour les programmes compatibles avec le vieux protocole LASH. Sinon laissez le sur Aucun, s’il n’y a pas de méthode de sauvegarde, on ne peut pas l’inventer.

  • Le Signal d’extinction sera généralement SIGTERM. Ne le changez qu’au cas où ce signal ne ferme pas correctement le programme.

  • si la case Attendre une fenêtre avant d’être considéré comme prêt est cochée, alors le statut du client ne passera sur prêt que lorqu’une fenêtre apparaitra.
    Si wmctrl n’est pas installé, ou que le gestionnaire de fenêtres ne semble pas compatible avec, alors le client passera sur prêt une demi-seconde après son lancement.

Avec ray_control vous pouvez affecter d’autres signaux que ceux proposés dans les boîtes à choix multiple. Par exemple
ray_control client CLIENT_ID set_properties save_sig:22
définira le signal SIGTTOU pour la sauvegarde du client CLIENT_ID. Tapez kill -l pour connaître les signaux disponibles et leurs numéros.

Bloc de gestion des non-sauvegardables

ray hack non sauvegarde

Ce bloc n’est actif que si le Signal de sauvegarde est reglé sur Aucun

  • si la case Demander à l’utilisateur de fermer lui-même le programme à la fermeture de la session est cochée, le client sera alors considéré comme non sauvegardable et un point d’exclamation orange apparaitra devant son icône de sauvegarde. À la fermeture de la session, RaySession attendra que vous fermiez vous-même le programme car il est impossible de savoir s’il contient des changements non sauvegardés.

  • Si la case Essayer de fermer gracieusement la fenêtre est cochée, alors à la fermeture de la session, RaySession essaiera de fermer la fenêtre comme si vous fermiez la fenêtre du programme. C’est très pratique lorsque le programme réagit en se fermant s’il n’y a pas de changements non sauvegardés et en affichant une fenêtre de confirmation de fermeture dans le cas inverse (la plupart des programmes réagissent de la sorte). Si wmctrl n’est pas installé ou que le gestionnaire de fenêtres ne semble pas compatible, vous devrez fermer le programme vous même dans tous les cas.

Zone de test

ray hack zone test

La zone de test vous permet de tester les réglages de lancement, d’arrêt et de sauvegarde réglés dans cette fenêtre sans avoir à Sauvegarder les changements.

Les sessions réseau

Une session réseau permet de lancer une autre session sur une autre machine en même temps que votre session. Ça peut être particulièrement utile si vous utilisez net-jack pour décharger votre machine d’une partie du DSP, si vous avez des effets gourmands qui tournent sur une autre machine par exemple.

Les sessions réseau fonctionnent selon un rapport de maître à esclave. Une session est maîtresse et peut avoir plusieurs sessions esclaves elles-mêmes maîtresses d’autres esclaves, mais un tel scénario semble complètement farfelu. Organisez vous simplement: un maître, un ou des esclave(s).

Pour lancer une session réseau (esclave donc), lancez le modèle d’application Network Session depuis la fenêtre des applications et suivez les instructions.

Ajouter une session réseau

Vous devrez lancer un démon sur la machine distante avec la commande ray-daemon -p 1234 (1234 est un exemple, mettez le port que vous voulez). Ce démon vous affiche dans le terminal quelque chose sous cette forme:

[ray-daemon]URL : osc.udp://192.168.1.00:1234/
[ray-daemon]      osc.udp://nom-de-machine:1234/
[ray-daemon]ROOT: /home/utilisateur/Ray Sessions reseau
Configurer une session réseau

Vous devrez copier dans la fenêtre d’invitation de la session réseau l’une des deux URLs. La première (qui commence par osc.udp://192.168.) doit fonctionner à coup sûr, la seconde ne fonctionnera que si le nom de la machine esclave est correctement renseigné dans le fichier /etc/hosts de la machine maître. Toutefois, renseigner le nom de la machine esclave dans /etc/hosts et utiliser la deuxième URL est préférable, parce que l’adresse en 192.168. bougera si vous branchez votre machine esclave différemment (en filaire, en wifi), ou si vous réinstallez la distribution.

Vous avez à présent 2 fenêtres RaySession sur votre machine maître, l’une contrôle la session maître, l’autre l’esclave. Vous reconnaîtrez l’esclave au fait qu’elle n’a ni barre d’outils (Nouvelle Session, Ouvrir une session, Contrôle), ni boutons Abandonner la session et Fermer la session.

session reseau fenetre fille

La fenêtre esclave est cachable comme c’est le cas dans beaucoup de programmes NSM.

session reseau client

Si vous lancez raysession -p 1234 sur votre machine esclave, vous aurez la fenêtre de la session esclave en double exemplaire, une sur chaque machine.

Conseil: Mettez ce ray-daemon -p 1234 au démarrage de votre machine esclave.

Ajouter un programme non fourni

Si le programme que vous voulez ajouter ne gère pas de projet à enregistrer, cliquez sur Exécutable, rentrez le nom de l’exécutable et cliquez sur Ok. Sinon suivez cet exemple.

Nous voulons ajouter ici Audacity à la session. Audacity est choisi à titre d’exemple parce qu’il est connu et généralement installé sur les distributions audio. Ce n’est pas forcément un programme très adapté à la modularité d’une session audio étant donné la façon dont il gère JACK.

Cliquez sur Exécutable (ou Ctrl+E).
Dans la fenêtre d’ajout d’exécutable, Décochez la case Protocole NSM, tapez audacity dans le champ d’exécutable et cliquez sur Ok.

Fenêtre d’ajout exécutable dûment remplie

Un nouveau client est créé, sa fenêtre de propriétés s’ouvre sur l’onglet Ray-Hack et Audacity se lance.

Dans Audacity, nous allons directement sauvegarder un projet vide dans le dossier du client. Le dossier du client se trouve dans le dossier de la session et porte le nom donné après Dossier: tout en haut de l’onglet Ray-Hack. Nous allons appeler le projet EXACTEMENT comme la session RaySession en cours. Pour celà, dans Audacity, faites Menu → Fichier → Sauvegarder le projet → Sauvegarder le projet.

Sauvegarder le projet vide d’audacity

Cliquez sur Valider à l’éventuelle fenêtre d’avertissement.
Dans la boîte de sauvegarde de fichiers qui s’ouvre, vous trouverez le dossier de la session en bas à gauche (voir Fournir des raccourcis du dossier de la session), cliquez dessus pour rentrer dedans. À l’intérieur de celui-ci vous devez voir le dossier du client tel qu’il figure en haut de l’onglet Ray-Hack, rentrez dans ce dossier. En haut à gauche de la boîte de sauvegarde, tapez le nom exact de votre session dans le champ Nom: puis validez.

Où sauvegarder le projet Audacity

Fermez Audacity.
En haut à droite de l’onglet Ray-Hack de la fenêtre de propriétés du client, cliquez sur Naviguer.

Fenêtre de chargement du CONFIG_FILE

sélectionnez le projet Audacity que vous venez de créer, son nom commence par le nom de la session et termine par .aup.

Si tout s’est bien passé, le champ Fichier de configuration est devenu $RAY_SESSION_NAME.aup et le champ Arguments est devenu "$CONFIG_FILE".
Cochez les cases Attendre une fenêtre avant d’être considéré comme prêt, Demander à l’utilisateur de fermer lui même le programme et Essayer de fermer gracieusement la fenêtre. Cliquez en bas à droite sur Sauvegarder les changements.

Onglet Ray-Hack du client audacity dûment rempli

Lancez le client Audacity et vérifiez que la fenêtre d’Audacity porte bien le nom de la session.
Cliquez sur l’icône du client Audacity, dans le menu déroulant choisissez Sauvegarder comme modèle d’application, et rentrez Audacity dans le champ de la boîte de dialogue qui est apparue. Maintenant lorsque vous voudrez lancer Audacity dans la session, vous n’aurez qu’à lancer le modèle Audacity depuis la fenêtre d’ajout d’applications.

Notez que le bouton de sauvegarde du client est derrière un point d’exclamation orange, celà signifie que RaySession n’est pas en mesure de sauvegarder son projet et qu’il faudra le faire vous même.

Selon le programme que vous souhaitez ajouter à la session, il est possible que ce ne soit pas toujours aussi facile. Certains programmes vont exiger un argument qui précède le fichier de configuration, dans ce cas tapez mon_programme --help ou man mon_programme pour savoir comment charger un projet au démarrage du programme, et adaptez celà dans le champ Arguments.

Importer une session NSM

Pour importer une session créée avec Non Session Manager ou New Session Manager, déplacez ou copiez le dossier de la session dans le dossier racine des sessions RaySession (par défaut ~/Ray Sessions). Ensuite cliquez sur Ouvrir une session, votre session doit apparaître dans la liste des sessions, double-cliquez dessus.

RaySession ne ré-écrira pas les clients ajoutés ou supprimés dans la fichier session.nsm, à partir du moment où vous ouvrez une session NSM avec RaySession, vous devez continuer avec RaySession.

Les options du démon

Les options du démon sont des services qui sont activables et désactivables via le bouton Contrôle en haut à droite de la fenêtre principale, ou via le menu options de la barre de menus.

Options du démon

Voici le détail des différentes options:

Fournir des raccourcis du dossier de la session

En production audio, on a souvent recours au fait de créer un fichier audio ou midi avec un programme pour finalement le charger dans un autre. Cette option offre quelque chose de purement pratique: un raccourci vers le dossier de la session en cours dans votre gestionnaire de fichiers et dans les boîtes de dialogue prévues pour aller chercher ou sauvegarder les fichiers. Ça permet tout simplement d’éviter de perdre du temps à parcourir l’arborescence de son dossier personnel pour chercher un fichier que vous avez mis dans le dossier de votre session puisque c’est bien sa place.
Bien entendu, ce raccourci est supprimé lorsque la session est déchargée.
Techniquement, les raccourcis sont créés pour GTK2, GTK3, QT4, QT5, KDE et FLTK.

Cliché automatique à la sauvegarde

Cette option est très loin d’être triviale, elle permet de prendre un cliché de la session après chaque sauvegarde. Celà signifie qu’en cas d’erreur technique ou artistique vous aurez la possibilité de retrouver la session dans l’état où elle se trouvait au moment du cliché. Cette option nécessite d’avoir le programme git installé. Voir Les clichés pour plus de détails.

Mémoire des bureaux

Si cette option est enclenchée, RaySession sauvegardera (ou tentera de sauvegarder) le numéro du bureau virtuel sur lequel se trouvaient les fenêtres des clients à la sauvegarde de la session.
Ainsi lorsque vous relancerez la session ou les clients, les fenêtres seront redispatchées sur les bureaux sur lequels elles figuraient.
Cette option nécessite d’avoir le programme wmctrl installé pour fonctionner, et ne fonctionnera probablement pas avec Wayland.

Scripts de session

Désactiver cette option pour n’actionner aucun script de session, et ainsi ouvrir, sauvegarder ou fermer une session en ignorant totalement les scripts associés à ces actions.
Ces scripts sont utilisés par les sessions avec Mémoire de la configuration de JACK.
Voir Les scripts de session pour plus de détails.

Se souvenir de l’état des IGUs

Cette option ne concerne que les client NSM capables d’afficher/cacher leur interface graphique. Sans cette option, certains d’entre eux vont toujours démarrer cachés, d’autres vont se souvenir s’ils étaient visibles à leur dernière sauvegarde. Avec cette option enclenchée, les interfaces graphiques seront affichées au moment où la session est prête si elles étaient visibles lors de la dernière sauvegarde ou si le client n’a jamais été lancé.

Les clichés

Les clichés nécessitent d’avoir le programme git installé, si vous n’avez pas git, le bouton de marche arrière n’apparaît pas et il est impossible de prendre un cliché ou d’y revenir.

Un cliché mémorise les fichiers et leurs contenu à un moment précis. Les fichiers volumineux et les fichiers ayant certaines extensions tels que les fichiers audio et video sont ignorés, sinon le processus de cliché serait trop long et celà doublerait inutilement la taille des dossiers de session. Celà n’est en fait pas très gênant, au contraire, puisque vos fichiers audio récents restent présents quand vous retournez à un cliché précédent.
Si malgré tout le processus de cliché s’avère long, une fenêtre apparaît et vous pouvez annuler sans aucun risque le cliché en cours. Si vous l’annulez, Le cliché automatique n’aura plus lieu pour cette session.

L’intérêt des clichés réside dans le fait de pouvoir revenir à moment antérieur de la session, avant d’avoir eu cette idée artistique géniale qui s’est avérée nulle et non avenue, avant d’avoir tenté un redécoupage des échantillons au microcoscope qui a finalement tué toute forme de musicalité, avant qu’un programme plante pour une raison inconnue des services de police…​

N’ayez crainte, revenir à un cliché ne vous empêchera pas de revenir là où vous en êtiez.

Pour faire revenir la session à un cliché, cliquez sur le bouton de marche arrière situé à droite du bouton Exécutable.

cliche

Sélectionnez le cliché vers lequel vous voulez revenir et cliquez sur Ok. Un nouveau cliché est pris, la session se ferme, le cliché voulu est rappelé et la session se ré-ouvre.

Il est également possible de faire revenir uniquement un client à un état précédent de la session en faisant un clique droit sur le client, puis Retourner à un état précédent.
Si vous le souhaitez vous pouvez éditer pour chaque client les fichiers ignorés par les clichés dans la fenêtre de propriétés du client.

Avec l’option Cliché automatique à la sauvegarde, un cliché est pris juste après chaque sauvegarde de la session, sauf s’il n’y a aucun changement depuis le cliché précédent. Pour prendre un cliché à un autre moment, cliquez sur l’icône de marche arrière à droite du bouton Exécutable et sur Prendre un cliché maintenant, celà présente l’avantage de pouvoir nommer le cliché et d’avoir ainsi un repère temporel plus parlant que la date et l’heure du cliché.

Les scripts de session

Les scripts de session permettent de programmer des actions personnalisés à l’ouverture, à la sauvegarde et à la fermeture de la session. Ils sont notamment utilisés pour les sessions avec Mémoire de la configuration de JACK.
Des connaissances en script shell sont nécessaires pour éditer ces scripts, mais tout un chacun peut les utiliser.

Les scripts de session se trouvent dans un dossier ray-scripts situé soit dans un dossier de la session, soit dans un dossier parent.
Par exemple, pour une session étant dans:
~/Ray Sessions/avec_script_de_foo/ma session

le dossier des scripts de session peut-être
~/Ray Sessions/avec_script_de_foo/ma session/ray-scripts
~/Ray Sessions/avec_script_de_foo/ray-scripts
~/Ray Sessions/ray-scripts
~/ray-scripts

L’intérêt d’un tel comportement est de pouvoir scripter un ensemble de sessions sans avoir à y recopier les scripts, mais surtout de livrer une session non scriptée lorsqu’on la transfère à quelqu’un d’autre pour un travail collectif.
Seul le dossier de scripts le plus près de la session dans l’arborescence sera considéré. Ainsi, un dossier ray-scripts vide dans une session désactivera les scripts pour cette session.

Pour éditer les scripts, commencez par créer une session avec le modèle avec les scripts de base, il s’agit d’un modèle de session avec des scripts ne comprenant absolument aucune action particulière. Rendez-vous dans le dossier ray-scripts dans le dossier de la session, vous y trouverez les fichiers load.sh, save.sh et close.sh. Dans chacun de ces scripts, ray_control run_step correspond à l’action normale effectuée (selon le script: charger, sauvegarder ou fermer la session). Si un de ces trois scripts ne vous est d’aucune utilité, supprimez le, ce sera du temps gagné de ne pas passer par ce script.

Les fichiers scripts doivent impérativement être exécutables pour fonctionner.

Vous aurez probablement besoin de l’utilitaire en ligne de commande ray_control pour effectuer des actions en rapport avec tel ou tel client. tapez ray_control --help pour connaître toutes ses possibilités.

Le modèle de session à mémoire de configuration de JACK utilise les scripts de session, mais on peut aussi imaginer moult actions possibles selon vos besoins et vos envies, par exemple :

  • définir un ordre bien précis de lancement des clients à l’ouverture de la session (un exemple est fourni dans le code source)

  • faire une copie de sauvegarde de la session sur un disque dur externe à chaque fermeture

  • envoyer un raccourci Ctrl+S aux fenêtres des clients non sauvegardables à la sauvegarde de la session (un exemple est fourni dans le code source)

  • Allumer la lumière rouge à l’entrée du studio à l’ouverture, l’éteindre à la fermeture

  • Lancer la machine à café à la fermeture de la session (exemple débile, allez donc appuyer sur le bouton de la cafetière, de toutes façons faudra changer le filtre !)

  • Faire beaucoup, beaucoup, beaucoup d’erreurs qui feront planter votre session, soyez prudents évidemment !

Mémoire de la configuration de JACK

Il est possible grâce aux scripts de session de rappeler automatiquement la configuration de JACK spécifique à une session avant de la charger. Ce comportement pourra rappeler à certains le fonctionnement des studios LADISH, en beaucoup mieux fait, du moins c’est ce qui est espéré.

Dans quels cas l’utiliser

Celà peut s’avérer utile:

  • Si vous avez besoin d’utiliser une interface audio spécifique pour la session

  • Si vous travaillez sur de multiple projets avec des fréquences d’échantillonage différentes (telle session sur 44100 Hz, telle autre sur 48000 Hz).
    Ainsi celà vous évitera d’avoir à reconfigurer, arrêter et redémarrer JACK vous même, ou encore d’éviter d’oublier de le faire et de se faire insulter par certains programmes.

  • Si vous voulez éviter de charger une session très gourmande en DSP (par exemple en phase de mixage) avec un tampon trop petit (128 par exemple).
    Notez que sur la plupart des interfaces audio, il est possible de changer la taille du tampon à chaud (sans redémarrer JACK).

Utilisation

Il est nécessaire que l’option Scripts de session soit enclenchée (Cette option est enclenchée par défaut).

Pour utiliser le mémoire de configuration de JACK, créez une nouvelle session à partir du modèle Avec mémoire de la configuration de JACK.
Il s’agit en fait d’une session scriptée (voir Les scripts de session) qui lance un script fourni avec RaySession, mais qui lui est complètement externe, ainsi RaySession n’a toujours aucun rapport direct avec JACK.

Lisez la fenêtre d’informations à ce sujet puis validez. JACK redémarre puis votre session se lance.

Principe de fonctionnement

À chaque fois que la session est sauvegardée, la configuration de JACK est sauvegardée dans la session, dans le fichier jack_parameters.
Avant l’ouverture de la session, JACK est redémarré si la configuration de la session est différente de la configuration actuelle de JACK.
Après la fermeture de la session, JACK est si nécessaire redémarré avec la configuration en cours avant l’ouverture.

La configuration des ponts PulseAudio → JACK est également sauvegardée et restaurée avec la configuration de JACK.

Si vous ouvrez cette session après l’avoir copiée sur un autre ordinateur, la configuration de JACK ne sera pas rappellée mais sera écrasée lors de la sauvegarde. Seule la fréquence d’échantillonage de la session sera utilisée.

Cas particuliers


Pour ouvrir une session sans recharger sa configuration de JACK:


Pour changer la configuration de JACK d’une session:


Pour rendre une ancienne session sensible à la configuration de JACK

  • copiez le dossier ray-scripts d’une session avec mémoire de la configuration de JACK dans le dossier de la session

  • Activez l’option Scripts de session

  • Ouvrez la session

ou

  • déplacez la session dans un sous-dossier contenant le dossier ray-scripts adhoc

  • Ouvrez la session

Sous le capot

RaySession n’est en réalité qu’une interface graphique pour ray-daemon. Lorsque vous lancez RaySession, l’interface graphique lance le démon et s’y connecte, et elle arrête le démon lorsqu’on la ferme. L’interface graphique et le démon communiquent entre eux par messages OSC (Open Sound Control), comme c’est le cas entre le démon et les clients NSM. Ainsi, vous pouvez connecter plusieurs interfaces graphiques à un démon, même à distance. Tapez raysession --help pour voir comment faire.

Il n’est pas interdit d’avoir plusieurs instances de démon lancés simultanément, ainsi si vous lancez RaySession alors qu’une instance est déjà lancée, celle-ci lancera un nouveau démon. Toutefois, cette façon de travailler étant peu commune, l’utilisation d’un seul démon est favorisée. Ainsi, si un démon tourne et qu’il n’a aucune interface graphique attachée, raysession se connectera à ce démon par défaut.

Contrôler RaySession en ligne de commande

la commande ray_control vous permet de faire a peu près tout ce qu’il est possible de faire avec l’interface graphique, et même un peu plus. tapez ray_control --help-all pour connaître l’ensemble des possibilités.

Au cas où il y a plusieurs démons lancés (voir Sous le capot), ray_control ne considerera que celui qui a été lancé en premier, sauf si vous spécifiez son port OSC avec l’option --port ou la variable d’environnement RAY_CONTROL_PORT.

On pourrait penser qu’il n’y a pas d’intérêt à utiliser ray_control puisque la commande oscsend permet d’envoyer un message OSC au démon, c’est faux.
D’une part, parce que oscsend permet d’envoyer des messages mais pas d’obtenir des informations de manière simple (quels sont les clients actifs ? quel est l’executable de tel client ? …​), d’autre part parce que la commande ray_control se terminera lorsque l’action demandée sera effectuée, par exemple ray_control open_session ma_session se terminera lorsque la session sera chargée.

Pensez à affecter ray_control save à un raccourci global de votre environnement de bureau (Ctrl+Meta+S), celà vous fera gagner un temps fou !

Foire aux questions

  • Est-il toujours intéressant de lancer Ardour (ou un autre DAW compatible NSM) directement plutôt que dans RaySession ?

    Sauf pour un projet vraiment tout petit, Non.
    Si vous utilisez Ardour, lancez le toujours depuis RaySession, d’une part le cliché automatique à la sauvegarde peut vous être d’un secours inespéré, d’autre part, vous n’êtes pas à l’abri d’avoir besoin d’un autre programme même si vous ne l’aviez pas prévu.

  • Puis-je lancer dans une session RaySession un projet Ardour déjà existant ?

    Vous trouverez ici dans le code source un script nommé ardour6_from_external_to_session.sh. Avant de l’utiliser, sauvegardez votre projet Ardour. Téléchargez ce fichier, mettez le exécutable et exécutez le avec un fichier .ardour comme argument, celà ajoutera le projet Ardour à la session en cours, ou créera une session si aucune session n’est chargée.

RaySession-0.12.2/manual/fr/rs_manual.css000077700000000000000000000000001417052567600235722../en/rs_manual.cssustar00rootroot00000000000000RaySession-0.12.2/monitor_capability_api000066400000000000000000000040051417052567600203530ustar00rootroot00000000000000 The ':monitor:' capability allows an NSM client to get informations from the NSM server about other clients in the session. To become a monitor client, the client MUST check if the NSM server has the ':monitor:' capability, and its capability string MUST contain ':monitor:'. Just before receiving the first /nsm/client/open message, the monitor client will receive for each client in the session the following status message: /nsm/client/monitor/client_state s:client_id i:is_started 'is_started' is 1 if the client is started or 0 if the client is stopped. A monitor client can query the state of the other clients at any time by sending this message to the server /nsm/server/monitor_reset At each event, this monitor client will receive : /nsm/client/monitor/client_event s:client_id s:event where 'event' can be started joined ready saved stopped_by_server stopped_by_itself removed open_error save_error start_request save_request stop_request the 'joined' event happens when a client is started from the outside, for example when it is started from the shell with the command `NSM_URL=server_url executable`. in RaySession, the 'removed' event happens when a client is definitely removed from the trash. Note that a monitor client does not receives /nsm/client/monitor_event if the event concerns this monitor client. ------------------------------------- In RaySession, there is also the possibility for an external program to become a monitor. This allows to get informations on the session clients and be warned of clients events without being a session client. The program becomes a ray-daemon monitor with: /ray/server/monitor_announce it MUST send to server the following message before to be stopped: /ray/server/monitor_quit It will receives the same messages than a monitor client, but for logical reasons, '/nsm/client/monitor/' is substitued with '/ray/monitor/' in paths. it receives client states and events at /ray/monitor/client_state s:client_id i:is_started /ray/monitor/client_event s:client_id s:event RaySession-0.12.2/resources/000077500000000000000000000000001417052567600157225ustar00rootroot00000000000000RaySession-0.12.2/resources/.directory000066400000000000000000000000741417052567600177300ustar00rootroot00000000000000[Dolphin] Timestamp=2018,2,27,13,18,37 Version=4 ViewMode=1 RaySession-0.12.2/resources/128x128/000077500000000000000000000000001417052567600166575ustar00rootroot00000000000000RaySession-0.12.2/resources/128x128/.directory.part000066400000000000000000000000001417052567600216170ustar00rootroot00000000000000RaySession-0.12.2/resources/128x128/raysession.png000066400000000000000000000247211417052567600215720ustar00rootroot00000000000000PNG  IHDR>asBIT|d pHYsItEXtSoftwarewww.inkscape.org< IDATxy|Uչ{d&!!I0$ j8jjo֪:bmvWZ VgE"2H@B3{}9; p2ŋ^{g^p p p p p qzl2l{фw8s(//w(r0 @,`'.ʀ|S=׀Kc]fqDFŊfduEQD- L T_C-ԔqvEk'4bH&uB R0cz7 ,Fc N[l1&&& 4Vyl[6F_*$e0뜅>Ҳr_mkk{zف|ި@uu>m|G11țv^u%_JtX?Zصkb<]cԔF)βoCVTB۹C{T54.""15_Ϥd2^dɏ"yTa>f?>m^֘8&Nd$!eه_$pC g^좢A!@UUՓTn V$f-ހhҿ*Xg羠jʥ+8@ mQQj6OBQ YVțq:3^Hva1 ZoҎA @h+=(b8^Zq/uU{هdǞcc2B?XMFu~߿^j;0[#B1Y|9G. kإPqQ3F ܂E9k/w.uC9mSԖxi_."&!512;cS`UjIW0m`?El]O Lf 9yyyf̃"n6hU_(#Ko1N$R(IOL?|> X.ƙ7l4v0+MtQ`bYGy}Dzj_Gt{+^1[Bbp'w6C f}_M=pp#1Gg,+|7! ۫W ޑi.` w`7cz0]ԸNfLU`.uw!TkL;i}V,okFtt =xR8^]$7c4;JP]H\Aǰqx9o<$ uj3y:w<BzEQ"!/ lQ \pͭ%'S(wR弓z2T5`ob {Lf{)9E$Ŵ3)aLPMvu, gJ KoUO54 <& F#_-fH.&o0.<,j\_>07 XC55tWW;g'j0`4b0:ۇ4{wR}PU&wTUU&ߏEU! 樇I.t_C6\mLJ߷wf9o3As,ȱS8]"v-}!?Bzv v)P-=_շʶUw#޼~~ ;ӆjxKn5>NW` ;ڟB`K+i1$1cB\M]ԞAacGpw_|~k}';~N4*=U*`OxBwoeǿߢͣf/,{zi9m. u^dY7HrBfʺ@`@&@K+aeT: 9)yWܬO@'dznŪps9~O~s^z>۟Q}O> Ik/l[4sI6NQn{PǨ 5U>:Z8乜:UX:ch ؗh'5]?y70!`{r`kϜ]_P^^kF%܋0H]dNPPΖF6r8- V|6$דb~Iu[D$R4)>Ų_1 {ݬyQ>Z1< - u4!pTWWDjCܹeăIrŅZF{$(43'k^Khi`3!@#Ta cg]ztlq(QȬ`SKTLxtj*yM Q EŎBEj0|W?Mԥ5!ss)jwoh;}͌ rػxҳ 8y1=d ~,)7΀M߳t6E7 56$IHm"$IuG4ITr&qƝؔj|ėklJPLKH)w=Y ϖw1]@UՌJXzk&Gju# 9cB^!'?g1EJ7?`g̲0M4FA>Hbs 2mGoYǣӏoA6mㄪ%H8дUhgw V[/%waSi񟍷Ut4ЇgG;B$IMyG̞4)(uN#$4yFP(߮εO#$ L$վ&4n}c5aCUC}^***̀qh{,SMd$ c8[pBWRFK=Douc7{MszIv]͏>LpUQ3tgP[{pphd#'bzU9_G@hA'O‹BH d 2㌥E,fmt47A!MQ1,f$Ԇ_!<'JaE9In30Mdh>:"T5ϣEx7`]3Ў$DhOdD34]s8h - UUUaB =*bKT j`A+z u;uOX`4bjUh¬?&h뵲C!cV/O!@rFO!a?Piqi$ؽcPuBezOvDzIV' @SCʇM iCz +0a{ &rFj MhncDV4@"3ħS5bm8Pk=|!diˡKW0X`Ōɘ(f81˚Jկ9ێ0ͻ'"*Z|.۳uum~͟e-iSJrQCnSY%‰BRƓ7CB3DB~OvK+|`P tm c4"*`4ui @hj?.1s. V-.g KY3M-"yH0j&GQ!ܯQrº,(XB3L %3YT`Ů7FEdXW-`ًbQE&-ǃqD赇Gqh7;@3B?zʶgً̠+PHi6l]^9aC~9@0B7SWT-YPqu-ú RKw}zP(Ȱh!.:) Yv`,Wcljr"$w} |#5ql;M i[,^NDx\؇ @E *29c"t$!K~&YQKIlxEޫ 1O`dэw訁@.?.+A]ɋ5vC ދ`к=lhpq}lqo .[K _/1q\mȴHuT94_R+*L~ Z8.bKGDc@ݏ8""KJᚻT;·hw?:X;M]'xˣGQ'ppdM%F 9\(qO0!a Kaa!f Kȏ}4wgBd8&sݏ7?î.R"^[Y}ab%$o^`jle?K!غu+7nD=x<466qFfΜIII f =[[_8vt.W_} 6~͛7SVVUt]?A"uRbU D8@bj. !goΖ^~ejktLΘvvZޞ5폡 b" s'Lc1s  bW`8;455j*\'nh楗^Ya 1-/aڙ2yVg`Z@V44+^e,֭d͚5|'_dZbJQ@3&'G8pjM m#BTt݃@Ao}R#Xf MMZ|wX:1hvy/X &ٝjyRGo1vm8|8rϚ5ktA6*[1OItpA  fa7U9-4>)c 蟀@I)~T}>vk;]$lw3ڈJL`t3H1!;VdʨB!-UM.K> 84BԃBd ch C~"k/h<93o ;.\P"`UXNXx2@Ux0z^퉊`2tV#c4J0ػBG#r0爊 p-`0>Q̢XtrڍZ%i<* Q/qtTpdjҿ;nHIWx`0yPUU;G"?2L*Aƽ{Q׏eAAA'< ci4/HZrgwWX,,^X0,Z{T/pȫU|#&Hd;={螱&fYK@S,XpRfK*b iEW@"RVV6"OqGAI_@`&- G {:AHXȏYh2e sΐv" >>+ThDnEU;:'.bb0#Aۣc1FMM ;wj1`.λQ$/SO!1c?8AAAW_}nN4mbjh?p:Gv@uk&"!MC1ơFEԺǢfzd^^RR… 1NM& ,`ѢEX,ZtIR3UmmW?!D$IdeeEjB. 5e;CA]Pr ׉%K/DCnn.^{-ӦiO 1 bCfvu䓨y$I"##rrrxq'o5!0P﹒oV>|@uuעU%g~jr8۷}p48`08|0+W.#))@1[J~ QMos%0˩f׮]8p`TX\HܹI4i̭3 Ohަ>@M8RSSB_u'I^B,?D=)x0dʕ\tEP Rokr# E+Hpt:ٳg dY&--LrrrHO!I*ɦɴtt 6z;ŧ~ʞ={F}??q@mCzդI'IA,5~?k׮c4i-=0n]_|iG`$&&9s0gn7tӫhnDjj* H*5Y!6fhϥ}~.1hE$oΖ-[M~~>$TUu@nnn{eeW/rzA(#Z0~x8*wSYN1%j ޅ4.Ԏl:g Lr3Z!N4[A5= !(//gÆ # YYdIՑ@1(Ymmum387xO$ fێVZŴi8ӱlxBY9v5%2q'CgP?4r/H0m%96C Jtf]D9UUYf͠р(8NJVVV-H"InEBHQ?j{{wVZezӋ-l yC+XlڴW^y%b۴4̙CRRmmmlݺ8rssΎ(E]]>f3FEQx^hooȳ ,wO$jϡ3l[$IJKKy嗻5mL&/_NQQBa0pNVQQq,˯Jcc#/ #@JJ ]wǏGʲ|8+?+gȲ$I1~7|M6t[‰Y;w.-¤U  u?b>fꫯeFvv6K,у]$IuٳGIU\UUmu Ӊt ?|\+//Qˮ[2qĿ_jm۶;v)pl$%%Q\\Lqq6.IRX}k,O]QQ'e^*jkkinnЧHNN&99,TBBUB[$&I !i}||JO fsiwIvF{RH1YeDž^\ @wQܶ-ǣaέM)nA/=D1]R{qt91;ѺˤkygVo{Q' (z S$*)i#t:7&F>eQ6ss?&ļק%pbdQAQ)l|1ZZ+WgvPc 9Ph욖<CCs*+g%dAwZU@6g*a#D)0 Xn<M< 1h5"`08U$XfsbLX$@UE^#5U In2\t&)tZmRa? ~M $= 덹 yS|5S&8eڦ BS;Cl!Bu;66%#8dW+ V5!k/شjXISߐ@`(IOO{(-)`M>GfZZvM:YMu/' bh=Itn\ko`q 7E"ITHRh4Z 69q IENDB`RaySession-0.12.2/resources/256x256/000077500000000000000000000000001417052567600166635ustar00rootroot00000000000000RaySession-0.12.2/resources/256x256/raysession.png000066400000000000000000000543011417052567600215730ustar00rootroot00000000000000PNG  IHDR\rfsBIT|d pHYsbb8ztEXtSoftwarewww.inkscape.org< IDATxyxTǿξd!{ * (,*kڪ՟ֺԽںTE[uZE*" d}>s9gH2If<=sI2}/ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!p=ph4y 8$ ֜p#9 @}}d28n4qcBr830'ցJ7̄NBJ !eQQQe)))2 @eee `.yHM%!;6<1''rJF0jBbB"tOaDdc㸵ǭi[a!hMYrсGp`Z`5v9;PaA&WBVCZ/zvB'<Ͽ8qm*++SAxBR_ch1jT[.4O %tQHLBbz2,%5-*9{WsrrC=P" =_8I}KC-*ܹ-C3HDoEӐ;nrNDzna_AGhA# h,$r !a58} :Zx#$M^ '3Ns!⠈pСxJ4!%^枏 +ʇF: 6'n"@OfſqtNg2q(0 ^~#FO[sss°5 !85B܊oVatݤo3p{^^ގ!Z;@FP[8^q-#7(6 #8N⡝2GIdB҈ツ $$E9!.9<_Nnð1F,qߜv`a$$B¹݀s/rFz8KX< ڊRPS9,㒐 ɣr1/2`8싗bKqL^#HR8VhdA|(*Dl4φCSȞmq;q2w1 OMY J    np9qM-"Qphù@U xhsL‐q6)"Q9'Շ@U8f^ CBvoW1(*u鍘8{!8-AQ$HPn?7N; 6! !N!!. QA F眐qV8hlw_{ ǵ1cǎm  ѣs׻jk_~syXj-Y$eRqkH| &\+E ϐYFnswhuxw7ʡqX.$ EiO!՝Nx]0̇ l_ ?߃ꊠORWVʋ7% f***BSwd`}ĠxK~kxqJNGt8' 0dGz 2]p>ۏZ|?@&W`Βe2wIJ 随^ 9ᅡwL9Y ܐ퓱{30.//,xr}u-x㩻u00sѕT;'E?86Q{w7_OGK#ڛjF JD$">5Owx|.kW Sujmq cli/>ѡ%&!{$g#~Hl44CmC7c;/G^w^^wP @yyy&#@>w^V9H(4<fVFm[-(߿{~/*5R2[Qc9fBU|Gj] Ttm0gjoFkCpAӱpٝPit~zHU,[PU *4" Uk} oswq\Ann#e^p[6?Q2ÆZ~_.£_[c_;ŵGc3QxP6eQ6|ndr\r}ϩgCpv)[/S <鰣tuKWX͝n,Pi] ĊxcEQB+w 6F1E xU}74|*\pa$Wȣ4بՌM+Bɶ ! I .)gt50%6L|QQio:^C<7߇J%T-jסz9g;M-?#kh=hCB֘bo{7 E^fff`;hPQQ!=e{~krMKn{jɍ+ ^ZX/NlRf.fD5i>;`3przGvnP2jt1.y3 يuȎ.1 ~&Kvd'j!@`GsA{^}8/}jq=L1>s^*FE/Jis}/;VySz6n@_"Zr sĥ"Zq127"Xshb.:fB|uk3!-'A,Ljs(='CO3/=g0ုy>m@&V!a7NjYkoW+rߩqm0*$A-XN?V5xa*g=U,Lt>LvجXIn0|݁sπ:ֆZtuAE0`)xPu˩>6ۺ>ڛKH7^sp!SK d=n 2 dzīw]?{ yJ\"9^.Č}?)=J^wqg,]XRi@Ya.}P9KR%f޵:pjkEɏtMD7sbal/іJ jOS6ħ>0D*_ABocea=n2U O|k ,߷dۆo8ضc* 씑Bb4D 5*WC}~|'qzBh+NE+ctIgk؆ΖF`F|QƠI񩣘To'Π88$9XYi`уyj]b`q7{ar<FxVǙTC;6hӎoGEѹA"%?I?a& 2OYA.ES{+pj:]aϘK*K)=6w .8ұ 7m exĞ"r0 L@IT{R\FGet$ vH4~{czO"jGq2(š;hVL7$FA3 %g2]q*3f?Mޗ1eu j` 5v"2wGHn9/UbE%zI)t򣢐,O{qD"p\o)5pGUb@ PcW Iɾw诛D. 5S;kT{ӳ.[N Hˡ GHI SdvCgl6(a^=A9(1t9<1ax:\IZ&K(ǥG C.UVYr· _@ y^GKL3#M&ܣC T6*)=z6!hmM瑞GF@0L!xF*F,>*ibn# KDO`Jy.W!%4)]g,G2NYLpJr!}N!㯞ȪEs;]򿱺"(}# jV- JJYm.AOn5YT[\bՔ;Ֆ=8b@䔗[Hܠ]%kSi5Yߓl`NU8O`o!TM%Se?V]@V\o"Q"OrR Wao^@FtT!7B0TV蛈4Z}43H+$]Df>>`e'Dm\v~`&|C%ƒ4񌧿,n4;%P %4zZSy\]B:T`dXgODVz3.:G8vJ`KJqpC%gjk|Ot +Jk%4 6RtmapP/b}%$ڻTV7a|~:W ODD:F]WY+㧦Hͦ!>&{ ^JLxH ?i_&ܓ L!fZF %+jݡ]NH3w;nERc$I /g8G#IE{O3)XoN&W0i7* lbFټ|zTDŽ IDAT\,1DQjy^lnipJz2Q{' JɈr!⯂{f*auyF^Gqo^"D'! G.Cg멙SD+&e;{;bRcuUW&zov{*qpB+?[% c1\Zؑ3S3>CSm].qص^^JIglE$3$M?9fĻfS)Ro=8E5caPdԘ T<q@Ge=+T\J+%{-Mi rςDxQ@T1JuY+s'-x9RQit>2=ZWTq&}%?~ۯϱvux%-lU3[wPbhQFDO@,THeƂˡҢE׵_P}ZjQ]jGtUl6 Y1tQŖqQZFT9MJse}bbU']1i׆.]{S01ڠ:4Q@=gKR)#s3O"[躲:[P(UoO ]}3κ&(]@Bx.D-ݫTg^#zoY*4VӉCCCDmXrN<]+dG3oA{" mGi'aa-Tqe#ڏsbQ1e}Dp0@Mg 0Nytx^~ڕ.Av?oaw6`@k%߆5,` ' OeZ!! wCT~uFə8 @8xYoCc$~Xk%WzJVgN,DU\\Bk8v~.$T}Ͽ*(eX+N<BO2\xLndh=!Q0U?Ryp7:,׋f5+њ_By$BO-X4pU"{S$Ϥ6 8nU{Ïk?ڜB j^T˰%BGd2-k 0r . v.5Q昆:T_S{ |NvdϏL!Z3zc?3C IXNI5h0@18η0%*)+qƜ%lY~9 OݝR-tF%,t`ӷ`p>Xr@*MN\CHD0RGO9 JQ4G acb=ݲ~8*JQNjwLFs&5<"T0}eXHgXDz=i{tDrϋ*~Ng1շWq7ƮEQCֿɼyWϘ1JtsJHf3pѯLKQhx 9;nuVZןϿ?[yTq16-C_S}9ǂ`*IhXH7l\x}ɯCQ!|mH#ۺ)frCVQψҕ{8 ]s;3 \b@w|ڼ%XteFV 1wB%bvP㔿lr_è\&\Hܛ;>&>d=U W;Դ7W/g¡HDΙ0!wdY JrbADMJ^܈1B "tlg|fXݠþh@8(HIΙP}784Z̿v\K3ed@d`=FBZ&s;^~w}B,t<@l[LX!oW*zy"x fj38w9=$eb/}SϽ)'?"u_ aiV4\{sKUz V&7 I23iaիOM=DӁO_}-tf/mF(z<,}\u3U0>cDp !nr_Btm>[S?Ow_Lfw\]N|ϧ$=מbq omewcif/E=O㊻DZna>R|I9F (+pWcK&߆BÓQ9 1']X` iXx8ɱR޶%a]N|_qd϶;Ԗ/>Wvv,Q;7_ⴸ017HPmd?p7:Z/T'W>6;,Glfsq+jZڏ{]&[Z.gn=Ŕ g?%=6q 84_!K&2A^աzE'[Gh\dN· re*?3 j8+FoɯP}rt&SAI_N~KW>~ማ=4'NlQHS߈lw%/QHEb/~ IA"2L| W!KLt(KN^g퓠ڈ)q7Q'Ήo9h_;gcG9!f6aˏcW+^lѾ;[ϣq|#>e iO0-*IU&h (tz0dP[T"O[ߞu8əGճ rQ"A嫩ϣr5̷0 1_;eڨ£y;NV~ !IV$ /м2ߌ:`=T.P(2e܏:T\)2SYc'_=w؇1'D!`spg:11HJ,Lw݉J-H| GsȹN_@jv݋.gpo"׳a85|B`31!һÌ-)gȜ' C>c~GMFn{8111#z?`@rr2tBDj2loƮ["n/Q7fMH*qu~<ЬL~{]r`9h|1@&!11_b t>WqnAZh/j-l ?ǔ[պ(\qד*K#A46ұݡ^zX+~aw1JcQjz!}+++yf8Gq T*=cǎ@WE 0߉(zNTY-ĘQiYQ(Ub{/~B466"keZkyԄcB|K~B#{D~l7r--;^Nxywغu+V\)M~܌uO>Amm~6w*vB绠WaRysy D XtXΙPdO$es`o?`rcޫ +V?2CDZj*^]] ]`Ǔeo`PP8|/ 'lMDv(o2+ ?frfN_t%sN~ZyUo[_ e/>S шkD[sc9BBoDq݈Q!2y?N}D`ӏH ]7S YD+^%2O !ؼy36l#1p6oތ+W] ]*Qm;hO˅/Gu%fի?0N!۟*WÄY 0z!PQ?L7`W,e ,\goK}!tKB֭[ꠍI?ڵ k֬an\$ %5c(4<d;=R#@Ԝ1ȟ8jOQXOv!]w1i&ƠGF|giX;D(v"CWܫn X7t`y,YFe Y7? e`Jwڵ DxHVFZ8( [rRQ~7Do k$MN|,*Qo[vT_]]m ;Lss3 fnEc2-^spH/),զJDlnߪLs>զ;MԨ2Hs\o0k׮P :f΢kw~ iY(>-ID` AxMD34Zd۲efTUUaT; ?%^t ړFoU`K3S'^֧?? >'R~+H DV,әÑB_7 34M//喷d'M"Ci)-l?[t 6΢#Arh?`Y厧 @zbOCCÐKIζmA_x] Hzob#A`c PUt$PK?EWWCgdr&׀8eț8#c #` ЏPr *:'1!%D {d9ׅ&9K3e`%/ThV-UYYyʫF"6-śī~dNd;oU(-@bF(K?,} rQʒ+* 0 Rk0*>: ̧|=ISSS1r΄(!ONQm" H@bF#MQ7773$"6NI˕V@?HLϦں=˙GinngI,`r)x{>qtp' @B$Bk;#)F>p8><\\Z1}Y &x Ȭ @WU͒nii$" A*Q&h |ЏH@V:C-A - {~GmmmT8hdc\ C?[@zr+  ֯jc$"V569DO(p@[:ػԗ+!!Sm6A<}RkC6PQMߚlXUc]#R b=(ID<hqS@HK L1% @JMF[On cuʢȘ0hH+ k@!<8!Ã.2PDVш7*Ԃ7$6x~]9 H\ o8 dC DުQ88p ρS)xXр8i+0jCohOMA:t9{2X+@rX =N+8:P8T`zs'E-K "<8 f- (eUsao|+qAd__WjpqqtDa06m+j`.7Xp;Wt-CBB€?K"HLՠrOS#-, +͝ W8h@Ԉ.%ѽWTX(!g"O2'dGG#YvTTD䐜L֔| Mijj8pDi sFQ6!++jR1THT(l@ž>21Tk ebj=Gբ-(dgg3#UE tS}F:&$(Zt1CYYeDg Ow>$SmZ:VT±c@h$0"bW`pz0ͨGiߧ L8j?4ͧv-7R}"@D{,?WWZZJ;,۠M>] _^ۅ9gPem#>pQfgjQ SoRYg5ϗ-y^^SgYBe:22F6@md֍oςY6ƫGr/77& PPbȘ={6C΍ Ui@h_@QGp`Hu 2999L1Л{2byͿ_bŞy 3e̘8*{sPk ]$r; zП3PlnPhj}'q3$ տ"j, {1X_ zgX@0C}ٽ{7sWa.2!VI ,ZH  ӱxb6Cg}iPzO!\fy? N&IDATe2Yx|ÁYlt͝J˭^-FGITK4wyf0.)܁L۽Q|bփJx݆0e @@&@0qL\Vk%߂¡g`(,,_̜jY- !Zm67]wΝ=H8"i 3C  شiq(3= 5( _>8L:D"4p3gb޼yUo t|-[N>t=BȀY3o{ pGeD }&O9sHg!"55W]u3v/G)D`3p(ii)34|8]}s7` Hw<(ra}`m% {M8 ,6m.RDE L55w;҂M6hq6aP `?]Q*#6l`f4 6O (zo pKF@BB ̜9>AѿK)`Nj0vk֬֨?_|jz@1/wCll%]xЗRڵ #{8 cx *)==W^y%bbs}LJ 0T8N|LaHp9s u#OXћaK$=J3gĵ^{oG15< 9 'P8lzLzO~Sd2:d $$$ :Δ sl,lEcDh'jO|"}s&=qW*+ڷ05v)%p)|n_ill, N5BދΈ'=E'PYYYHHH/ 8tq'g%dz,,]8 #ֶ]wM觜Zy睇c<J%0y~%% G 2Cm>*w)В=8p[l=I!Ozg u &iҤI~z܀Egg'VXw9cO)YbnNF+{:$Ɯ9sp7b֬Y}Nh>L c SNGI_Pjzw8Xn6n~t儐aÆVHa;||ZOh"oNǞאN@[QmՖe8øq0f`׮]p8dffbK+3"G:S Prj,W8Ѐu֡33pɓ'6<{,///89!//GgiӉիWcܹ7nhQj#ڝӐ2 ;h(ST[Py?L.@>y„ (**BII VQk¸q0nܸ~bt ҾDFV{Q؅dpؾ};vY}%//Otq3''s+|big}vH ] 6l؀f̚5y.`[Ng OB/?ۮ11v.D8vp!(..FUU݋갪YVѣG#==02u!^|TN']Ǜzlذ)s9kBȶJ2(pbsכ",fhl0Dxٻw/ZZZh"+=m!]_dU8ϑ7z)?qFvv6:::PVVa^j=ϟwy'ї ܷm۶Qo͎yڕʏozl &}PTwuu]]]0ͰZ) t:h4 66vP2Ό$$V#JqodX~q"Oł۷$pBwRh/A1 ;v,ƍmA@NMM }q(**b,|;m!K&u U#O"uBuۖ8zqڀ86Q^7Q~.WU}].݋;wp``U.8.(O  ''g]EE!BHoE]G< s7`ظq#1w\ ;;12djFz3 3#] ҵ,D<42ΌXN+ ^=do_z] @vQRR;vbHCT zNjd#ĩLLL >l|W'wG(p;v ~!fΜbcsp8H|D7T (aD)#GΉhsLGs:\k=xU8vn-3Po4q紅[V)"N+@Q5bhu\%s/#qfv ,w!]KPV=jL1RZjBH DVVx^ Iʈ\=`Lc3@ŋ07$IZ1߅?1Jޯt:?"?o[z5Pc̏<]3ZI;G"[LtBx܂6xG@xֆE1?7?KH⃠xv[nɓ])>"1o@d2VwܙyӅ X~=jjj&({ aFB90$'MV_h3+ᓫ&3M% n}ѦnܸYN/-磪 .B' #K#9 !req jׯaٳLI^ .D3`)Db$8a'].%UU;qۋ/p9?ѣ.Z wޒtZ(//GqqqZ|#\ t:Ο?3CDZK'HJ^!>O'nFCCÜu ۇRu֡ wPQp nA3gZC>>"G+ʉl6n߾=bHAnLLV"Yk֬ʕ+~w 2ߏ~|r=O1cǎ+bĔI5$@D!҉[ZZp%1.Z-L&S8;0??a%~?zzمPcoÇ&zW$Id EKCGFęc2ϸE999KZ-A@ w™###6K:'O0j||VG:;; "֞ڵk*z={kdju6lH|),0qgggavvv;QdGƁ444,ف;nq3L8}tLr$|j::: "Ba ݻwni۴i93BD}(ng#tCзFlw^Ư6F`vI%U~JO͛ K%T*((QXX/UIN~CD+VTUÇsN޽Md-cL3I"?=m8r󡱱6-q3TQQJ>Ƙ'$0*C%wuu))%9nf3on}I%#>.s:u(nOO:se|`dzaqIa2P]].q`(>0++fٳJGkkkWM\xy@NJzA`{rBU YmlF[O"o a'%Eww2<@#9}6؃-g/QQnP.MUhnZbs:}@oǽ] O5,ZSA 5<nFH;%9 PtMVj |suGq$ٸnEuROp{t:\SUqtTz{ hA-vl%$INwҧP#ttIIg낎O eЂZl`lpWG3tP**3I'&3HK޽ C>Hx6]ׅ8ХD,Zm3t5sA&W&`4@UU`%tw5[YMڿj@9Ԅ+Q]#G`馝ٛ@{<:W[)wټoMh6[,1*&3[^z+[i/GU$Hm.hFJKwp:#22!p( ("b$i4Al`O^x~#ތGBxp| ų ?_a,Eaƥ>5mϿɩeT}qlBiƫ5e+ٴ?> H5@LL q!sq'I4NR֬zDb̨v$I^$$tpN5PM\Bi`XBA$b^ F&y ADLx jBt]|DƌzJWk?<^999MN~6pruQ{gYj92o+nFQ4fCG+T\#D1 8sWaYi۷TlPyq``bGL4.R0ox [(TzRilOG[7W(m&jNU_CBeQ2 l\8?]b[QvuwUojn77dYj o6''ovVڈlrkk_cܳh2l2o3 N{b/ IENDB`RaySession-0.12.2/resources/48x48/000077500000000000000000000000001417052567600165215ustar00rootroot00000000000000RaySession-0.12.2/resources/48x48/.directory.part000066400000000000000000000000001417052567600214610ustar00rootroot00000000000000RaySession-0.12.2/resources/48x48/raysession.png000066400000000000000000000057551417052567600214420ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYsbb_'StEXtSoftwarewww.inkscape.org< jIDATh{p[bY- _$lYv6NaRHSlti'.N)mw74]趥,&ͥ $!llq!vbc;''d˶dI9"}f4<}#o!DcLpSt{RR(J,{5qjwC)C =SkS1t{1@&$rK*^3-MHLaX\_st}8٨ԭ9Pq +*/'MHb u~o}ZezڍYnkP(Ul΋#/)ײ;Vx M 7*Fu$i0O32v-@ogcbud-)%l%9ˊ޴M/Qaj?-lwX)-ڶ5)̛y'?8q|V D'ukaktqT=+V?C1AdY+M`IO ̉y},~J_. ~䘃X%%XMXto0:]A93_{ dyKA)_~M<^uAj|E 8']Sy̜ٶL~♿?TVrk+-g~P3-{q4'~+diOXiJs>'i9YƻogSXu/|mWs=uqgaۮ͹eyyys3=5B{1rt6εDo,UR^O~]so_g'7GpOw /}Da!Nي˗ގ5Z$~9 , F6jDdXFqI_:#QNY^laoe2a|z,]QIsa {G W{h$+H" e]Gs$J^|霭 ﴇ/.53ZFe+oi_Tg2pO^;8kyLN.~feI i>o>oy$Iԃ$i> *O'0ցd 0 uas)[I-hvVLLN,8c.>}"?Ph,Y3Rakí֢, T}&:>>@BAB, `2 Q(͵z sn36};7:$%%äPDk´:\:::!Es˗ҥtRnSK6 x Ppt~):E^EEEĠt]Q12|A乣AF1隚_SiVZZ͚5kXwOqmiN<`0  dGnÇӤ瞊)֯_V(G.i M#s3<K*#ADQUZR϶ftrQ&dwV'C)O)xgz{ÿ(.)$]sۨf3YYYi===A {gz=˲)Zwb3rE@ZZi$jN~Q|>=jin ~ھCB_ݰ@~6(СCSY]2MwWfD(ډ y}ߥl {po@PiFh8ob7YVp:@0IJ _x _?aiEw&eIENDB`RaySession-0.12.2/resources/64x64/000077500000000000000000000000001417052567600165155ustar00rootroot00000000000000RaySession-0.12.2/resources/64x64/raysession.png000066400000000000000000000107501417052567600214250ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYs\rtEXtSoftwarewww.inkscape.org<eIDATxytUչs1 $ $d!8@V)">V`|Ytouj}ZWĢQ&A$LMHBB pG $prVhjjnc3%6^$c0 ^(b pVQMc PYY|'GvW\8{:#2``E̺n#9s:*HGԘPET6͇[^z\K`px_AiOUgT<.擋{;._o x_tN4YRSSG*;w/-{ c6,5NJ ֦:©{QIjn} + fKHFB=TE,+{ab&ڙCRk?(2At}^Quh7U%{Q.q4٢IΚIBrM4z:>ʃ7~6?~-dMuU?=Tȳ|i'W/_CDi3Q7,2$@Adzt h.]^dձEYseƵKILAݘrFNT` {yr  >+.)ӦfLTWWݯ_9_tw_@+YO/@84ht%8/a)?15%wO}qIнFl#c#GVteCϿ4[m)vkgE=ӯ^Kf݈ßGjL &`5AY4_/(JH(R6毸8RK뇸xtnՎMJ# SM3oъǀkg臦&x[K :=1P .*?y ?!gN>馧Ш:uni|T~(JlWMءҰ* b"V)_a׶WGT9]_Ͳ$2i~i>QEkc`YAYqFeA:P}̮mvP<^NVsV/(Ȟitz_ɆM4yx#^CQn>xw4(1x+_t3L}_{5$;ܸ?Ǒ;,}.C 3KG 2ŠKh_āq@1e /8%Ii: &G|4_P]7|-GD!(>fZUHyDk+pQ{`&܁dJ4fk:jL&.QliF' }6hEQI6=9 ؁%*nܲ#!"lh68g;=tF3ҲiJ\;N7S1N(ƐtDdKt,ZU^y  :Zt7}:毸;BoG 0ȫ4h(-?̤~,點ZFNAʻ`]@-fGMaUb΢yG<_B( 7"AlcE.v@ZZ6u Yx illûxv0Lud$%%a6ûC4@~~~?0>vv7xA2:| 1JX 3TDQ(rހqD8䋠,ˊzCq@[s?HqR),,rc!I˗/>IOyN簾wd$I_AчM@ XFisMݻl#̞5k沏hn6MZ}x3f=;l2 l|~ ^|tww^;B̙Ųej/=V)((`͚5dL%=hr,dx#ԔQ<50-k3f1Qe 㣏>u?y3mkג"I3f`̟;,ۓ$^ :gm۶Yf)Za~h4G C@f`!TUUqRȵ&ZL_[ASS3y̨1&&,rrr0Lo%^5:7RS['10 $&% $=3v{WEE񢢅ypc뺺:n 7܀3L1?D߉܃uzzsi^Ffcĉvbcc1Jk@v/mޥ#=2ĉ/h,**"Ov(D(,;w^޽ ,5Ζ-[(((?X5L67ih7.ar\>?fu%6h)%] pJKKDEEqܹ`BRYYv[[^xῆ5aGsXwV+###EFU  P v.:|PZZJMMMD@ >>+2@yYYCUuUeYFFtwwcǎQ}H 233IKK#>>~0 #n YimmBpYjsr&~L<Jm"|8T*hZ8K'J7V$+;ۣj'fdd;Ofl#iӦM&DEEqwլrFRXyyEQ ş|`h!sSDv8tUTrO55)G"#T*1110sL%).&eɓ`0#M!QJ("_3P$`0 pJo4&ө7W|*IENDB`RaySession-0.12.2/resources/96x96/000077500000000000000000000000001417052567600165275ustar00rootroot00000000000000RaySession-0.12.2/resources/96x96/raysession.png000066400000000000000000000170571417052567600214460ustar00rootroot00000000000000PNG  IHDR``w8sBIT|d pHYstEXtSoftwarewww.inkscape.org<IDATxy|T9g2I& I $$,;( nkֶ߭׫ZڪնViR\WD!lI !$,3d29@3 ̄{59>9yEr,˅$kflɃ5_#MxP=MCue\g,s X7Liibop4M BLb+2OH҃N遮 c5M}Ii⽗4RHŒ4Gu Z:Q СC7 MG G;rpO$G!$n%ɞ#GQ Nl S~ my?-((x[555wiܩ1[m Ojf6z YhDagAoW p_/:t&IN/]_^vl nn@ ɩdEJ0Rc6[ћ- hû7д|\\4[QGÇǢinh#Ntm3 6>tGI atJ*qqd.+4VE=o=j SS4`l}g}'$[Qm9{.ܧo0[;N=rhunc%KHf%eSi6T̀^r`*ٴ蹂fGSUvozMoB3~b&]=C7IҕcbաtYt!ܝ"u$7ǫd VJ) I#pwD]tSRRn~sFbdž/?䗗̌% B'upN( mǏDS,I)f7ey˟Q5A]nf oisH6|Nyl}aKiLY}ƛ6ˋ:(//=Ҙ^PSSE [N^jgT9u; ~V?0dx>KyY腃|bg` p&a PK:\}~/MQ8vh>LI?U*((x8Ҙعs>)Vk=~H[=_j2+ڽu/0Ng{Q⛿O7i}Fs=rw4ZȢ $DzV<:Fp;T~&}iٳ/Pei%t>7Z@cDqfꟋʺ??&vmk︟\Qjf1"2sG1mUl{wu{NaM#Ph/MvAj4Mcϧش099vGȖl jbf]Y͒i0%H5lªM>}s˾p0~?]MQB\rkR{,$$Ifפ7aWzX_+T][tZzTVV$G=9230.e- Tmq0'@n̺ZCo02+z{ l) 1Om*\?1_Tۅ$f}ZȲ\TW$YQn Ű&_8*۰6љس]k**94@cq$&R2}o}FLG[3>DŊ/^!!D@sѨ&)?tFBZ"m|*v~=ǽ@4+ k0 $I%[<{ܘ/]ӓi~Y PMUY¯)Zz}Eɪцj &2;rFr[G% 9EL Ͱ_)A5h>W^ _Wj0VV@BJg FF.upfPw qx6:XV^!ch^"Qg`wo%~WB$~4M]+Bdli˽!X#R3$&!F ]JX67(iZ|_ M_WF@vXLg_tĎ,H%1ɩ䰮i=8Ċ }J:%4 U U5=!/>D;:V437nXW$U†H%\hont9D>JX9O dY,Cr!fi6J*Z-NON8P`u{uuįdh&taU1G tA fX0(f-/M)F~:@ݡnfKc- yc ?"v$F] ~eXFɥe~$<Zlw@;_"Ű ˆ.@c7Vjx5t:Zb%&&sD!fV{ =?k#0$P)FєكW, "YGA{:EH G~;>ܝ+@pZ{=ؾ 8!3WpktF> R2m.3/ "fh, !ŸERL9#·0[md"7T=8>|slX<:F,NI&Jg@쳟2'XTޘ\$ؒb|QYAj|7k{v|;eEHr fclwn\z7(٣o,Yi!N ``UY)z_(=Dw9Gn# us/pj/P.OacBwuy13J9 ѓMLI;d7 K!F%܄?P}tݎ _ k{ƚ Qv>I)dT/1ʍd(d-?dfc-MݟE{ 'fŽO2lh,r-E#~Ng~o;̦UOˡݟW3|J#Űt76>ӳ춻XH6iCeޝ=mBͺf]vYOxP>¯ E r+o7; DBJ:⿔TfW1!v/Q㾃g㣗ewcW6dMz#E:OPg4$VA\󯹕 DGI3n{ۺ+Z>4D bFi&{Ia[+cڀPH}G!'A `+ 7c,ױ״( }ݻw{@qq1SL Sn+#%I OxFK̀X#|{Nal̻N &hNիW矟#\m۶Rum KzĹK}q?nQH =# Ȓ?DHŪd_#xG@[ܡB,M3 N ]C:Iy> $`SٺNE #n4P432?N<+bSO$5M Iϲ}8 'g]*B Cb5K G(;W30J6H \s$Y@]ZR彭zv(|n`#%%g h T`pTKGGx 7Ew I@0w !Uww0󲵵5fquCOd"Mpg  Ű^ᱻr4.\qI56Nlĉ4:C%ǎ/ MT:Ex< l ї oj-"ݸLnn.Æ ~@!2ŀ{555qaE:@&m9ݘ***B4.'Mx_`ĉX,M!QBz1YC'ZF^Þ={P5=Gneq=Iv. c 9s& Lǣv25F,DzRNINpN8ܵk~fWpfQl䠰9sk1cưd$IP`}5]ϣ;d2Z=ʉ$Qܷz ~7ĎIp3qDfϞO] zSZZ$T !ӼJOrill"*iiᜑ_IM"ޝ8/\fe_ǣV$Yx|"33믿qơt/馏8yn֯_ `2zlh!]*yyvY9?xUqrAjE l2I61~ V?#0^ծ PUU񶋈BEEEQ3@Q֯_OCCe{,mCdffr 70vASI&ӧb JJJK]Xd\ҝ9_Okk+W棁BK$Wl6FLg B]:p?OĔgUzRӅ`٘;w.r 3f@d`ҍS1\T^pF^^VUU#K b6p+bIu]w'XD?u~_ˎj糩ٷoSNeر4x{-6^2LfpJ@¯WbD(`Q47⟇RR[[î]hjKf3˗/GU}}ÊƞSWTWW_\sHrr27xY'|ByyoHLLdь=2աZDMLJ6PQn***~TIn!#Gk|uuum[n7q=773f`2`ǎn( ''<n? 444P__ѣGt(3f4+[ne͚5D?h$##͆jE$4Mvvq\8ΘUb IK. gOz_g!D宜XjտTc`/))An~~7j UUos\꫽zG[˱lH/s&䰟4$XVV|0Bng…L4 UUBH_;gvi/*} > 1}t&L kѣGW鞓fL566zާUU$ɢ*inn_ Ft222(((Պ*MB bz_);;Gr$t`>3a0i!j?._}}3Oђ$+bvn\4Me٥j(t:EqqqݎIENDB`RaySession-0.12.2/resources/app_icons/000077500000000000000000000000001417052567600176755ustar00rootroot00000000000000RaySession-0.12.2/resources/app_icons/.directory000066400000000000000000000001121417052567600216740ustar00rootroot00000000000000[Dolphin] SortRole=modificationtime Timestamp=2019,5,29,14,1,17 Version=4 RaySession-0.12.2/resources/app_icons/ADLplug.png000066400000000000000000000024041417052567600216730ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ< pHYs  tIME 7+\8bKGDIDATHUk\U{7/3cf&MBҔ65-i`mUB )p+q nōb~BMښi41غ.߹;:[x!c`߇ ցhz $FX&|iZVlWR]zZ G@I/&e4ŶYese$-#I;nލ%юt!"$ƋSAV,?=ty0L_ꄎ^K c; 1fi[V7F~,YZX˿r+ne@쾹/l}#::Z~sC!Flw;m[e_JF;RdOğŸnm-vک"GR)w6%SA5OF1%B%"H]Z}|1;&_eT[#b&9&tOnyw^Ь$1 aic_*bFIK,,R&;#FP ?ywU^h$T{Y#BP^͆$gRJNl6 ijү+c#Po\PC2A(z{\pLk{& djT܁,:6wUuhVtW\rogּhi*Nj{ :q5 fOfGQsaj]hO_Y k)̭孎'ԵÇV:`r\zD&x#Ir9Ptho̔+1Ӗ q ‘dfXT(1W@(Cff+AhAưpb9<` e&ȇe4w1[Hېf6Q_K]ZWc#@KAW% ww WZ'U%tEXtdate:create2018-09-17T22:55:43+02:00n(%tEXtdate:modify2018-09-17T22:55:43+02:00IENDB`RaySession-0.12.2/resources/app_icons/Mamba.png000066400000000000000000000116121417052567600214210ustar00rootroot00000000000000PNG  IHDRש zTXtRaw profile type exifxڭZYv0*z r9y;xHO8ǖTHߤ/dN1xgmt~܎t?`a۽v 끲iw:rfupP 9{w=ǜy:[}|x6hۃ9f|O u1t6PW;t;&;q~e[7SO &};7_|s~G kKvЗ4cwV í1}cbQ& :=s4X+>bq6C٫$^b2^ piȱ~L6Aƛnd~iFoelm龄Xdr㼼̴.!Ra-F_ N\>9ל%chcƬ[!̐'NCDN 5!w`B ,G]M`4l u4w1!G4.h#T̑"&aE @ׄk6ص,H˄aC%C1pH!]Q趰cρ#3'\K>r*f6p)\ ,hD*8`OU_Ckir+vׁ;sRih#@~/ӏ) y:3fw5X'gpY.b:bXtcn:r6V6YW:Y78q^F a@{4#ȓ,m MðʯAEmbtppFrzF 7njqϒ73@FGb6hɨH΄R a;u ;W+1bŖWԑĀq́ 'F\ Q( 9VaA "3"{-ȻaІ7-$GV Ae#pФN> Q26YRi(QU(r$j[|ĸV83ukhuFНڐ GfJ&P##:;E*D``inL#e7dYk H@ !6VuydL'!QOʌހzMcKFn]n%p;`;ڐk 9X%-k>!d`!F@*{ I /xP^l4M5;)wPKw4!ã/}$4p!"^` dF;GFdhFg]6;="VjSgW-ReV +:$TԐoh\Ri_1 ]WvfABʬa oS"Ҋt˽|ohsYlXW.YL#ȡ l"BA9 <ѦlܘdȍEXD@"C@[#}#EBC}"#Fqr x`$?p ܍K6H _d3 Q.9L\™5*^'qSs3G\"Q?q8l"sE''>lc'uBgyrUY\U't'W UuBgyrUY\U'X.:˓:U'ɧ~[UI7V~6UH3[=4=tvd"qv\7[}e:[P(Q.lSx/ĀVcf 6Y/dqYvf?ѯ"}tm+PU %L!uBkd + z+kJ@ W@I(ZzX]?foSǖ6Π ٯZ{>+>tOMdPL0nT!eU8|]󸯦#5 m$$6MpnU칣 {3!S? Bj{BR_ӏU(_l6X{kF"f_ D~s=In칊w!D[ pt$/AĆ QZ2h+e/ Hv=sK0vOa좛CfQښZ_ bDY7̑ J#O !*|@ lL{(dwKpl1W][cqS|di.#rN? +xtpr+g޵VN5.Neh/](` &,WI QJ|Ui :rrxi0"]Oz9,z>og<. @eɝ0\%_^+O@ATgH0@lְƯ"^cR=%5 s49<iCCPICC profilex}=H@_SKT:A!Cu *U(BP+`r4iHR\ׂUg]\AIEJ_Zhq?{ܽFiV8鶙N&lnU "BDf1'I)x{zY}jbO$eioOo}(+*9I$~7E53y(XbYԈcSmyV= y}e4" AʨFV iOx]D.\e0r, ZɉVR8^cͺ|;N?Wz_m3;ZlM.w'C6eW )Vo}>*uE^xwowoi r}-PLTE               !#$"#%#)=&(%*>')'+?-J,@)+(!,;.<-P-L+-*,., /M2O!0N2@3F3P#2F5=/1.4Q02/"4M#5N!7@2312428P$6O"8L9Q%7P464&8Q*8M$:M$;C!L'=Q(>G(>R,>M&@N;=:-@O)@^!DP(BO+BK+A_)CP=?<,B`*DQ-DL.DM$Em?A>?A?1C]/EN+E^)Et0FO,F_AC@*FuCEB0Gq-IxEGD2Is.L_,Lu/Mk.MvHIG5KvHJH/Nw4Ng5O\5Ns6Ot7Pu;R[1Sw8Qv9SaMOL8Rw2TxNPM7Ts9Sx1Wu>Tt8Vu6Xe?Uu9Wv4Zl@Vv:XwAVw4Zx;YxSUR?Yr2]t:\tA[t9_qB\u=^w;asB`sZ\Y=cu@cp7fw>dvEcv?ew]_\DfsEhuFhv`b_Giwbdacfcfhflnknpmtvsuwtvxuwyvxzwy{x{}z|~{}|~}~¾ bKGDH pHYs.#.#x?vtIME itEXtCommentCreated with GIMPWeIDAT(c?`[@nH8@$p߻ =Hd$>>޶g$^7@A"q]xʕ6l zA |i?Қ:IENDB`RaySession-0.12.2/resources/app_icons/OPNplug.png000066400000000000000000000022111417052567600217230ustar00rootroot00000000000000PNG  IHDR DgAMA a cHRMz&u0`:pQ<PLTE:F9F:FJKbQdNbQLLPMhRdPcQRN;F?HeRePcQ@H;G`QfQfRCI9FTNeG2%!0#bEXO7EbPF0%0#/"-!Z>ZOFIfF&H2dR?GkL+ _AOMCIjM",$^B_B/&iKDH]K5)gGdG.%jOIG[A`DVLbGT<8ESKU?!"gKLIyGChJ"#Q_P]LI<./VCSB52P?gSDEfK-.pNE9ȂW//aI8DTI]I;:rU@H}F:E{:B}>C@F>G}9C| image/svg+xml RaySession-0.12.2/resources/app_icons/ardour.svg000066400000000000000000000040411417052567600217110ustar00rootroot00000000000000 RaySession-0.12.2/resources/app_icons/calf.svg000066400000000000000000002575111417052567600213360ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/app_icons/carla.svg000066400000000000000000000760501417052567600215100ustar00rootroot00000000000000 image/svg+xml Carla Carla RaySession-0.12.2/resources/app_icons/curve-connector.svg000066400000000000000000000032001417052567600235250ustar00rootroot00000000000000 RaySession-0.12.2/resources/app_icons/dark/000077500000000000000000000000001417052567600206165ustar00rootroot00000000000000RaySession-0.12.2/resources/app_icons/dark/curve-connector.svg000066400000000000000000000032001417052567600244460ustar00rootroot00000000000000 RaySession-0.12.2/resources/app_icons/dark/network-wired.svg000066400000000000000000000011051417052567600241350ustar00rootroot00000000000000 RaySession-0.12.2/resources/app_icons/drumkv1.svg000066400000000000000000006261471417052567600220270ustar00rootroot00000000000000 image/svg+xml Jarle Akselsen RaySession-0.12.2/resources/app_icons/fluajho.png000066400000000000000000000262561417052567600220460ustar00rootroot00000000000000PNG  IHDR\rfbKGD pHYs(((btIME y&tEXtCommentCreated with GIMPW IDATxyPTg}ieEE D4" ݙ?RTfIj$e\l%12fЉ( b *eiӾ|^n߾}9ys@AAAAAAAAAAAAAAAAAAAAK% Ap/--{F'{0t T*mD@x+J_tqHo2~aa,^f. MdggcժUV B@x?ydر* & }}}>HWq;0ydN˲/---F@CJ(((@VVqtHoW\ L1D||___Ӆ& K,7Z$PXX8ڣ=$'PPyĈYtIO5~TM6[Vw B`@OOψ8qhs  !蟘͛7#00PqXEEE:::F|RtJhA0ܹ!qkT*Ŕ)S  <SO=tu~JG  e{D@@$;_R&M|7oރV ˏL8pKRlܸ;;;~477 % @ppCC"d-q@|||; +P ڴiشiCq pQ,kcB`'pf͛xwkx'HHMMى={FQ񂂂K? *{1[!_qxBiӦ ||CyfϟǑ#Glt:A HJHgPP~8r_~{yotP 'H 66VZ 13 68с{֭[0͂aϟ  F j*}qTTT B`6'3d2RRRR0 ?&&EEE qfرc6q߂2e # 4#..Nnܸ1(ϟ, 0̙3B̸ݺumnw8$M0X`eb5k8=z}n{{H$#))~8btt4~i]xf3Ν;cǎ>>ʢb4qڵk1oNRRM^y$^/\PpoSo .^8ydmADZcD10(Ž{F}3f`ŊtGxoܿsNq?˲(++'|hhh=Q|}}#**2~TB$'';aVԈr,J'|r|X$HƼbDDDq!t:TTT*)hGmI]`5k฿{U]?À;T-J6ۅ) 7bKcuuua޽.Geee fڴix'hB`((( h4ĉ(++󔯖13gΠCd2\Ν;#8~q;hQ}}=jjjDT*)C`|?0GZZ฿ {Yns?Ʉ'O:\2Dsbٲet3}ϟP ۷ׯ_8>UUUyrk֬A||2 lٲE_Ʉ/_~帻F'O5ExPBlS H6~.HMMqKo}}ww7> NZ͛7~ВFbDcLTVVqd2Aimm{gSnbF '-TVV/ HM6l.N8Ė-[*8:WR+/}Ʉ#GQdXbm*mAaK  ^z% 7/۔r90 ( "!!jf3F# z=ڊ(ܹSpbH\zlV(9tRqO2~n8Bjj*HaH$'8qN7Ǡ0C(---)FzJp7ٳ-E50$''cHIIA`` rzNiR梺gϞHH7lݺႎc)mW'>0PXr%͛X]vg hU@t,K~YŅ paj* +WDnn."""-u7SNE~~>|Q7-% 4sbʕo>g  ,ƍ+{y >>>Xx1._?82%`BBByfK~ÁZ۞W^K/1kQPPsy]uagI=BĀg-SO=q6116l{GyNrrl?ߒ3~R"⋘2eʸ_/ɰdL6q BQQT* ]PPPq{M86m)&J8d<999{z|ǨvGEEW_ŢE'kH$Cѐ@0:WTXvp˒߉'J鍎+ Q8˲00L0L0`YV-T*j*{.MZ+⏕}ccc{?<<?ϐpoI5 Ľ{ݍC`0<,! ???@R!44J.$LLLD^^JJJ=Lw6 /㉊’%KMn7~Jg3gCo؈˗/N`\.RRĤI3f ""N˄`iikF|ii[d$ÎO<"##yDzo`"KP6, 娩[:~(//B@jj*1o&4iݜuuu裏\gmRxxǡ/^g}zQxXtp.^H_>(&L@*bٲe8}4&gD999СC67;PsrrvZ`z.]ᅬZކ?wnd2oN:Bddd8e."" .'|2(E.* ˖-=,3gXoG\-\ (**qZ[[qa?~|B eY|իWcݺu\.GNNN<)jRq:k4A?O?.|׬M6!..?OTWW\)(i9=!jqMB>}:p9HFT"33wdӧquwVXcieQUU6\qC ˲(//GOO^xݕF.]rm2:k.&&3f7n?w5k֌X8TUU_kWC}/-H"`ڴi{ab='H!::E̳gqBףXx1B1ȕ6 Akk+^ӧOfpj)SFH$ <<ܦE {Jss3]s8 Jq=`0`…HNN\.[PPHJJqE?~}\ ^wpL0&M"9A&ϢRʝˬYF|]`` Ν B;h4կ~۷۝gpǼ@KK ܹ#ʱx 'X߼J^A#;8guG&O0/~a6Τ7oeE"I|KVL`L&Cff&^}U[?˲lqqq? x,9\O,BBB `̙صkģGM ##K@@RRRYj[h-Oss#""7 99۷oIv)Kۃ]T*֣͛Qf .ҥK{R?" QmĉnɄ̙3zaՂ H L8qG^)|{zzsv&,9ɓ'c…n ڠE9Vhhu>E" 7r3JXdB $$ xZOB^pjAMJIDD222͢U pF>0wwwZpGoiL:N; $o _!Gk8qqqh<*{¼ P(Qי4f-YwrD0~o`^j,`0xĨIknHn߾- HLG=q!"ܶ"q 00pc eH<w/ l61 e+ oI7D"W׋'1yeRI}h{L&ZZZ-y) Q[[;w~̙3C^`D!ىj)X|95pek4ܿ߭u I<, }}}+H0{lddddT*ϟ/jׯIAB B"?;;W&_X) @Z- O6 +VBlQ/߿:$AaXj&OL^Fd̞=[hmmECC]l[z{{qiA5OیR$׬Y#D+˲v$^ Avv6rssNq={6RRRD3(++'rqYA^B@~~>ON^ƯT*n:Qmͮ^J`x>s477 zODDmF+V@JJeY/_6$TPma-['?O4 Wm߿V Z#G/MMM Jl2xDP)]&h yEnoo,8cXh@,YG}T]Ir{PUU% 3G!9'''cӦM  /_6# ljZ-=QQQ(..ƬYHF!!!زe """D,Ʉc9x jkkq)za׮]vgUT*EQQRSSE]p->/MQxh43g6oތ|fss3 :/N X駟`08$x嗱fļ@GLL ~ӟw zF{{$ǎ7|pް0ر[n;Wo;jKHLLtJq\sY?Aw2 ^VŻヒׯ;|̀lܸ/s?^D@lMO0DxP,٢vܻw%%%8r? .\z 5I1={pI2~ `ժUXx1BBB(,wb(--`|0HJJ1w\b%XE]]~mԐxraƍ:uKSk=^r{ud$^,BFq/ǡGnp"'J!HIIA^^Vd^GUUmӹ !R={6}Q$&&BV#00ĀeYtuu=4[Ո)x!11AAAKE8CӡϟǥK8fKcF \.ǴiDFF"22/$$얿-EIZ[[܌ׯÖ7 jE@8A ,rrB&!""ј8q"B???r0 P˲0L00 jBgg'ܹzhڇ#?C4xF 0`&wYr2|b yp!D2v                   kש^GeIENDB`RaySession-0.12.2/resources/app_icons/gx_head.png000066400000000000000000000340371417052567600220110ustar00rootroot00000000000000PNG  IHDRddpTsBIT|d pHYs fmtEXtSoftwarewww.inkscape.org< IDATxy\W}995]UAR-<؎혀1&s LX$~ˉ+!@p pWb&6QnMR]\uGޮnIVcjUթ3{w)j(^@]=4 Ԁ2K^rK"y^QQV<+ !hO;ePVJ@ZҀr뻀 W?{ܲQly;0P/^ Go uԦo_} /V z6?u]UvװXt]X0t5M{EoVǑMQJ=OUծ(G-zhee=3:o~`gff.* ZW~)K("N3>>>nk߾}Cv;MW?S1 ݻwO\199ǥTE}k:CQEAUU6u]nF^נ( 177Ǿ}뮻!<9G~q󶷽|J_tӕp.X^ַ}h:[?.#H׽vWU/gﰴĝw'> rIGWMLNNwm۶IOKu"R,fy2 LNNrwK{%rxjxxA}Y NU!?7pxiXD"(E>|~=[l3$ rȑ5vZ200Ο277۹{{( ͗E<EQ-3GGO% IX~qiֺyRXF,.ݔ@UlӦQ00C$E+&:Al /eٴj]QC>u=*+Mf!,σjE29gqڍT劢0zܰ弲ސQ n~*ffyL()gr2 N08^lӭ|4<>CHd LMQTOce9=]SRCQV+8G*Y ,L&BnT C/ZDbJV* A& *ۄ~>Cu]rin~$;C32g+$"(ғ.O? O={K3EtY*?ykz-6_ϣݖM| H(r&!GnJe '.7!25I lt]O9"dX2fG2eply~PG~dFclޑ nh5<kD!㜣oq'kL\>Sr-fiz#cxkx*i70<˧+$QQ?~Hf#LO.rY4zo~b6< 6 MΨeN]*jwxGakx~S8C9`THRd2Qy߯!N,o}j` BȌQ-tBUpBϧ22>co ; I8 mSiO%;@k4evVf P)2+FE$3ZNSCersO,83D74<#X! 5:9T.&A@ȠXX)4]ȞS+7 >" fM!7MpAd ΜGeQIf#^M! a68\fC&RL~ VK0 r@QSG(j .ct׆ :D8>Mly6ŎKG6yA> ‹G9Tvͧ^/қbMj0L0 /UItTM=[j:ٱC={><4Me`0me۶ {^\(@{h gVL~3߄T* g*Dݻw-z}nMd2+<_ֿp?[sK~cg{]/l]EDr?SO]*MMM AVu]6Բ,4MLiC Ny*YRbT?iu]|>NV?~C|^•Ą~7 8j.N4iZ8N/VvuvVZ-(Us]W[Or4ufNCZY(VEZy&rjJP\.jjRf/vuf۶ǑZ뺄aj8}k)l޼9%맙(!gK+f=yKx<ϞX?sElj Bv58t~U81Y1t]QB\w6u8 ,4CyV+j+5^"k~I4& bY֚~qd5'{:q-t:B!y8&:[BdTA'Q]\m{M=E&(k;j[֙p m>#yCCC,//cY=i&<vrٖ-[PU|>/(077A&jQfQUr뺴mFGG{ E<#166,..( [lAuj+++~.rm۪agu]ǜ^WǡP(Hmzir47 ER`0Hݖ+ժ4rг!B7]*>SUHRD2RH':YVDVRՕe"fSֽX,8Jeli48Cݖ)R5iY/eUx*,kMD"ضG>o~UU,X,^ пٞXR2q]Ű,;`xxUUW]w݅mR^bF׿w! Gx&eeeM<* fp8u]G(c``kٿ?˘ɮ] O*bqqnӧOSOa6Xh4yTUjTU<0Ml6K(0 N>ya6net]g޽CNT*|;vÇit{ӟTkN?N"JPU\eppPjeTU%Ji[c(|jMh4Jѐ#\. qݻ|#A^}e*Ҿm&''YZZ"r뭷:7ٷoFcqT*RV MdS.I$T*W\f``\.ǭʻ.fff8pǏšz*(ϓ[n?1nOԷ{/[[ G<8O>I:'> &&&>'-4u4ϸp]宻o~3SSSضm| _lu?z(GeddG}{_=GF>n+"wr^:h۶eF NP eLӔ#JIW,N >jJ!JIo$h,.. +H*R ˲HhF0dii UUi|H$B*q$333,//.LjJ(Y8`V#.Pr8d2,~9ZL۶iubT)x1u^."Qp~9b\塇ⓟ$RPT( V ,eVՈFj5u(J Dal6 j5tuժ O}SQ(h,..DZeppB@Ta岬g$nl6e]T8rwy'_qMӤmZ|369WِeYv[o׾5wJ) !wͦK&1 1+NTU=c?HW" 77rm.EZ;]%jm??7oHY)Bӑj|eC;9Fi&fff6pX}WNpB($IKO\ZQjZ%H8pjc˖-J%4M\.F *ft:1778Ad2EB àVH$d_.,K>B'cYX qRV,// je,Qa/D"g?Y* a022BXP(P,& Ih4D`0Hە5MAxT`|#X #j*Ǥ߳grH STvj5٬ `믋@E}>v>@d2IѐF6=oHZu]LJ?aOmۦhH*0z~ZB!iDtq PV رcDe m)H˲h4ٳ`yyzNѠ^@0fizuR}j59H*A^j_"^xoo#ߝWe ߶mB|!fggL$QVIRj5eYNX$~ժL􈜂eYRW /Ķm* pXZm$IBDRD("l_X$H%:l6q]nA"vT*o?0OZJTQZJEz"X+H`0i2fD"rVXG ΢aHLO B% L&ȑ#5'ɻn|A\r,H9Yt@<^sN*333~9 WVV h|>O"X\|>$N{94nfff =388ȉ'$X:::*A!T*E^g֭Ç > Y=SVI2]+fVO?3( +~|>/=u]e&L2::i<\~\vePβk.!LdIUUH&"oZ FFFdeZ^r%EJ̥8!g[L&d2i8-[h۴m麮N9y$r ,--adR"B`0H:y}~?dRڌvM,0 4tBIb*AxTKKKrJ%.fS ZHLt8 p8,`Y4RJB"  IveRa۶m$IbmAiߚ&\N|^&ǡjn%9CB.m"so!yUҰ}Y*>yF4~I|>vf``@bFnV8p/}KzWr>u]w?i9{~P׹i,//sQ|>W^y%~Yn)>(벲‚_t]\.s ٵkiY^^sEqqj]e,R`6 wR ĩT\.G,iWRuJnFFGGd2|>x}Q[b&sssTUaw:w}7v/ӧOK‚6QRHqb o/2dL$EO x<.DCR%91DW,aN$ $WvӦM("9N}vN8>9AHӬȟҒDrrA.RN<)Sôm Z-nL bG x<ΓO>(OBa( Bd2I"rPJP FnT*%u]E"e"JUzidpX,FzH$0MSIm$t<쥨9uUUe6Qg``@@RL[C܆␁)~. u*jL&C$ѣt::D8ƶmPU+رc'L3Ϡ( RHE"oD1rB!oߎeY ͦ%!ɑ;00,Vi,aOc&bTUc˖-,n?O,rIlСCLLLȼx^'QFr)eY,--f b1iPo.eѰEj333[XXqx n*ĉl=99IɓE ÐP|?Q|qȆ,^4RlΝ;YZZș "ܦMH$LOO˩w^```Gr/'Jqnf2P(Q9<,kp8,c~XP{2$.$I:t]6o,T*g޽n8rT%ʉlԔ̵^K:q~a* o{l۶/LLL0::%k?E zlCQln$2y{9dJ%jVr駟ns/ h4$v,'rL&lbH&T*8v<55ť^*ՑՆ8x v'O233#74v-SȍFCXDUW6LHK H D\[~bqDbyyYf3QNm[2BI"EQ sR,9r isn݊LOOKLnllJ"שeb'~z jeymŗLk3{LjjeI淰/wy AR($!@, PRD!p7T8F*aWl۔J5) AD Km.k6X1Ľ7deU(֬e}EQ<g'"t7=_[Qz;0q]N!M,^0iT_D½8&{zB3,^ųHl'"#@<(L#J5222l6"!rV@ ISObŔ%E.Zp^B R ) H$"-¾$Ig"UEBJ8!b$r:Aʭ?bՋTo\.')to]XXXXCض!۶ Zs ~s@RTO4;}NgϹߺ||1Y(Jv}>_|[^^ί!õZ7;E")/l$J}e /Wf w]tXP(m۞ ŶSJ=嗾EEmۧVe=S(jo{Y D"Ų:εV+NM"@|^\ image/svg+xml RaySession-0.12.2/resources/app_icons/jack_mixer.svg000066400000000000000000000541201417052567600225340ustar00rootroot00000000000000 image/svg+xml Lapo Calamandrei Jack MiXer mixer jack audio Jakub Steiner RaySession-0.12.2/resources/app_icons/luppp.png000066400000000000000000000127131417052567600215470ustar00rootroot00000000000000PNG  IHDR>asBIT|d pHYs?F?F[`@tEXtSoftwarewww.inkscape.org<HIDATxytuE#if$[U1͖,IH 4lZ[خNMsBBCV %mW,Ҍ4fCZb;Gǣ<޻g"m64sDdUJ)J5{;73v(a '+TAee˖x|aEd 45ݿaFH* /?W؝Ls\^*VDVgwϼ>nz DRœ!~+0x</މ[o1[ !6G TjؼyBw"DWbr %& ;kՃo&:0VדBω˵ݿ֯hCFm5 "FԿ!]?en> tb<-PUUu-PP>yvbDjC8 <*ؒd6mڴf^W|ou }PGCU'=|uJ6zZU9Y&KZ9 F\vkR4QNpzh2'x~ "iQp =JWWW:L]S56u?'3V.b _MXYYu/7Qٿ}Row|Rg8 &w ~ @eeR0Kxz9HZ)aW&M 4,NO䦄 nyܗ(~Z"KYy]Yn#yLKh5TbEcǎ{3F7߮g#ґB<< MeeJ'( YgY5 Kw Mރ˷xyp"nݺ8)wk~E2dG޴jp!j3OwѸ mB!jjj>hX}RZ"xK )#YG0un7tе%ׁ:$IKKQZ)+er1hsf:%-+U҅Ę@y\4-oPUOp7=%&{v]T}hͤα=T\ ~wb>l^sڥCamځ9Ŏs]/)2ajScǸ(g^)y 9\)|Břڣ.B|CXK1PJ͆ޣվxxt%AVu?Ίs`l)%n뱄h^~wc-cv)PrMIxui 'z3ㇴ5L~@WwNNJ}){+SP/fݾ4E\(%֟Q%KĎA9%,6 xq*&J)RqFoiBHyi`?b[Ns5x5ia\.e}(iquہF4@6~OA1{+ TZGfGhՑd2Ցzi_̺ i ;(~4"yykLsZ(ZuȚw}֗) +Ӄәk?6;Q`5g=ŬWNS_X ]]34-)Q!+߈1=jA45LC)җ4_:`#K4ᐮDNڣeze=Ŭ[Ns߳RWh5n>ex'{5[o^?x<͖|B-C^llŬv.M,ԱRK?x`JŔ=ucv">v-(Ek/-Q9<$)M0zQ湴=j owh ,ug!ݝZDۡ*N3ӉSp7{**8Ȕy[^:udl]}pz|veNbT?g;e'cKI~zeeFFn:B<0o'6 6:ͬ6"OwM2LyhUWn"cA$}1?)-ݠ ;y`xS[P)fg,kvU0?v\ lӧ,,jkL˞A(|D2g ޠܪ3OgǏ 翮3U Í`0*+[R?ȥ2E[&;"lX&<3EFMNU{ټ JvLccЬCV ;^MH>lR_, =>K'gZ猌Fأ,/j೓۟(Ktq]_FwRlrpa!*;SS jK Ĭ5=V(>2oK&x'W+)Ex+QJtK(TwRU¡hjJa9=msOr#gW}b4BiX|Bi'Ww?e(7Ls̼nYS#::x'+ڶ i pr NT>h6 '_-cozSk0X܊b3gNL @NnR>,Y> FJa离FkU}]U'$ vd <.J!`0r3pL#c(#]jG3ׅ,@VYL%M6m0~d W &imVO! ]~" j=f3JGpV| $H#3 C=D˥AV@?NgOcpSne59aNzaU9(^yp\ `8=d9rȢ:`'k(^בIrF/;i1ysf(޳<}Af!lՕM?ؤ?-yIENDB`RaySession-0.12.2/resources/app_icons/network-wired.svg000066400000000000000000000011051417052567600232140ustar00rootroot00000000000000 RaySession-0.12.2/resources/app_icons/non-mixer.png000066400000000000000000000044351417052567600223250ustar00rootroot00000000000000PNG  IHDR 1gAMA asRGB cHRMz&u0`:pQ<bKGDC pHYsHHFk>IDATXWiTSg~f.I@Pj pZ"akգ eQƈk1!BQ+*j*@7ΏeѶy~|=}ᄍ'?a,ӏ3'pHtHSLT桉j4Q//e2*߫4 53 Y}0f*B"%DB rJg~ A')t艜QiՒXXҀyc^NTyH0RT+#޺ 3[sj"0)Ro+X6AGGX(f5A}M#>VwFs@~H#<w inh= DŽIHoMcPt# et>f$t$#a%aXvu #0# bJ-UT)9׀hk%Gu)6;iJHBLᤉybDi鶈ѕ\U̥OjFPT%צGoHkNwui?1,m )4}IhE&ROQ?zr]l:š5f+ٌ r _O=3\rwS**Ze|[n%4Lq𫕐!7IHByO^J ?j2?]Szs[tB TZYڃڳkxV; qf##C8nU?=r3q6|#n%F=0@ozQh +XR|cׁYnm?5,!ݜm/ŝbҒO5V^uaͱeHASt9eϨzԓ{=1T˴Ѧ.fCv9"g]w,D޳Zb^|Hs9' C-RfM 1͈x;!@-;_ؿ:pغIXTdP ƨB|ڞ=]k ecGĿ;@w$%tEXtdate:create2013-03-04T14:25:30-08:00J %tEXtdate:modify2013-03-04T14:25:30-08:00;iFtEXtsvg:base-urifile:///home/male/prog/non-daw/mixer/icons/icon-small.svg/!iIENDB`RaySession-0.12.2/resources/app_icons/non-sequencer.png000066400000000000000000000054401417052567600231700ustar00rootroot00000000000000PNG  IHDR #ꦷgAMA asRGB cHRMz&u0`:pQ<bKGDC pHYsHHFk> IDATh{xMW\s$$54Qԑ]D/.1aԃ*#ZEѸ"DF **"䜓>)ԥ3}zo}>kIR.ρA1M3i)*)aKmv(?k!l>ٯ4nM9sh{-௏;&?J3F̩g3ZTQgi^/`8b# q7'<~/+0RZEc)Í4RT"l5r})P蓝wZHAdt+7[_ r7 (i+k?NZgr0}ofGՂ,*}A`N2{ݽޥgDY;6*WA g5XkYêb?|d`<Y{*Py&cn*[1@l"W\UE/D8 `9G@CIQ)-#%8 ,:5^sPV}4 ;(0%01r`ϔ<֔*$k|Kw= iNv%JqP}ư-v@^oX?,rzhj ՙ65=7A?<^psvCQ:_*իpOo3xǁkc@j.QwSr[zfí׿/R^MvY'n=JJwLFΉ_ RsM{e+z@K&U<&W^9f{P "=L1CW@fW3`W׶.}&lGtz,hK:^wZ@};kAlЬP_-!!U#n)pho ]ԮO V(zڷ Oիtn!50 o,U?$M'w݀%tEXtdate:create2013-03-04T14:27:13-08:00=%tEXtdate:modify2013-03-04T14:27:13-08:00LxJtEXtsvg:base-urifile:///home/male/prog/non-daw/sequencer/icons/icon-small.svg.IENDB`RaySession-0.12.2/resources/app_icons/non-timeline.png000066400000000000000000000054611417052567600230070ustar00rootroot00000000000000PNG  IHDR #ꦷgAMA asRGB cHRMz&u0`:pQ<bKGDC pHYsHHFk> IDATh{\UUǿQA P143eQSGG( L#JD 5LIQ!"<=sq᧜Ϻk^9kﻗ*CJMcVCx1=E,edf%#T٪y4-0hȱr 3oXVìA1FOUO@E&`P+ dW^VkL(uuwuϜXb%" 'Edgm%iiqiB`ˆ۽a۹&S_9U;I&}k|Qk}XX]RǤ/: 򭄱+27gG eV6n[u7n/M7~ͨo  ׄjAkVk~=RY} mDmPf5#AYg6Ojj2fP[NAS(#D2R"#SƘdDH)NϫWYTeH1Z#FY'L5~yexV8ɓ'>KWςtRNĥe)W?jrllz{{%Q?FЬmڪ_ŔOo.4m.D.z!wݳpcy]yW—uNk<̅8dmBn,$'!p0i)sUW7‡=Oy> 8 A[7$UE׾o޼#R2Ӑ N[mcym@LK!rk~2D {/{IjX6OU,XX7\Cb͆?steUf];y$}|UXT7,_5__οt3IuuР~B (߯U=@Ĉ81V r)!17VPWx :ǭ v}Ν2l#t#b.IsӻiCE"\?P[-Y  ц@rNy9lت˫JFw\DO^5VGAml oE pSBp ~ . خNf25"T_V= 1p6@$ОQ1U7%]=>6̗E 'O28I9hun0kK߂`Wi%CYNA1R*Py5Voj%H^|*v@EzX41W-nܩoS2VkR~ H߽<[]x e։S!l^mBZ-7πx[\\=PR\=hiX]r?ue0 `,TbPayA,JhPR )_JA9hھH r\:S{TO;DN?T@TҀuU?/r/Y%tEXtdate:create2013-03-10T18:37:30-07:00,A%tEXtdate:modify2013-03-10T18:37:30-07:00oItEXtsvg:base-urifile:///home/male/prog/non-daw/timeline/icons/icon-small.svgyIENDB`RaySession-0.12.2/resources/app_icons/org.hydrogenmusic.Hydrogen.svg000077700000000000000000000000001417052567600276152h2-icon.svgustar00rootroot00000000000000RaySession-0.12.2/resources/app_icons/padthv1.svg000066400000000000000000004334631417052567600220020ustar00rootroot00000000000000 image/svg+xml Jarle Akselsen RaySession-0.12.2/resources/app_icons/patchage.svg000066400000000000000000001000571417052567600221750ustar00rootroot00000000000000 image/svg+xml Lapo Calamandrei Patchage patches audio cables jacks jack RaySession-0.12.2/resources/app_icons/patroneo.png000066400000000000000000000067531417052567600222450ustar00rootroot00000000000000PNG  IHDR\rfsBIT|d pHYsXdtEXtSoftwarewww.inkscape.org< hIDATx? )"!t&44A}AIK*6r,>M$h(" "@bEL9s<;g޽ IIZ+; lI濒~6~.CI[PSX~"9tSLa?Yt:/JzFp$8;D3Lw@'1F1!a#CW~TSY"Pmw@%!;cG~i_"1:wF!1)C a[~dԆȄ-"S;D SXے wbr6 OJwƽrBfbVOk}*"9_nh#k0<9S} 0s_Cx:`_~"PS;ړdԮD`' ,ԟD`~''0/?`G~"pi<ƖИ+|{z5!Qׂ4 [Fu#+|q /'$=3rQ@ $r0WuxoEn6a@rGG!+"#P@@~:Yk;R##StxF0r_W4_>9忩ß'.1(wHG nt+@kw1{ǒ<|8@ywΗ3׫axt~_̝o# \QBG c ߨ_DN_t X~iDALs=yB;-F a':'8;"ґ)"#*0y;#E`N x{1-Y+F-D~|ӰD~4)M~'5W$9o-"CRw@,@;-G`SE~!b+sYFi)9w@E7pO\Z@M>4/;1 0߉E))S{J1m#t8TlsybRte<Ӷ)$ߒ# o)|Q㘐 "S:O_ bB-' 0!u:@LȿD`D`&A~"" k,5OAf`B' '0! u&oI~""p [[c: {cG: {߇uL+߇eL+߇UL+߇EL+ ǐ߇tL+ ǒ߇dL+ǔ߇TL+ǖ߇DL+x@UG"CCҨ2ءI? O HX`G&!$3D *"`4v?e@D NBIȿf@F MBIȟc@D LBIȟs@E#` OBI_b@E"` NBI_r@Y#` MBIȿ4D!iEv!i$E";ȿ4E";_4fEݖty$~d"p?]F,uq}=û*#Z7#DZ廌Xv&3F/ HK\I<ߔu/6J*p/CQ:|C9rS?%\$}m~Tڣ*S)OC_eޡEv!xLGe"" w@|i$X%CCE~ćO#?ȟF""o?;D >D` A46!!E~ćOcW""p U UӨR~ć?w@|҄@4!1ȟF;D >#EhZ~g ]O+"#it)CS?w@|z13ȟP;D C>"i -CڎG6#i "V? ?h#ȟπO@ "i @@4?D` ȟ"O? /6ȟlO7 $=y'u}g2ȟƙۑ,ZCD@2OK&V/f)-+֨}R"#)oJz?ZdjCIw#?䯈8Ww/~ƌ@W| 9;E@%;D5\@X#Ъ CD`N]uZ~'5 K"C~vj%]I:܆sXo9)vj9hA~S#TZݘe@EiKhNZg@B_DNۆʈEX9@K9=ӁG|6R.@O$=>Oཋ{?W;z:GS"̣қ+6sIew@YRG3 񜤷$|Kw@Y\ ;9"kw@Y"Y!CBN"PV~*R@@}pk;"ۿyA",!C"p=o;ͼ(+tx<֝@G<e'؝-# I.&7Ȗ +i5"i%P#5E6 ?Nؙ"u2TJ ?@唊4B ?@c4 ?@F:ai3F: ?@O{"aNl򜊀[p0HZwn/MIIENDB`RaySession-0.12.2/resources/app_icons/petri-foo.png000066400000000000000000000063361417052567600223170ustar00rootroot00000000000000PNG  IHDR00W IDATxb Q0 F(<|"NުNjRRjnnnFv:t ݀x$AqW\8LpX⌻˺7t_'$_&g;PTTdgg 233AUUU[HAAA MX}#UQ^nļz~ѢEJJJ.^j&--M W]uiizjLRԏ=+//  w1::C]CCC%"RTakXv/vw^}ԩ[7nu={gͶm4mmmͅ 4.]Ҝ?^344ijjҬ_^se3GB B0 !p6;Q#lmbo4oEtEZr%uwwC/"˴o>uٳgܹst1=h =3tUpjii R}}Bőd2 033)~7+QRb%_A0?-]`1A400 Gw^joojh<4?k, C`b͍۵Y-8|ݻ†...U4J őO&&&&\.Fp_- DL&744,.Z ?w%%ݻ׮]+ kSPD"! T722'{{wrt[Ruu5M>ěJ%5_`55njxj ͝LO=`ŋSjj*9;;`zlr-6 mHP*YZ:҉iÆ ,0 buf3)rJiy]UI/O?́'+[7en88A/c``4*i(^Q짅xAM3gZ| tR(:r;[wwRxX<]ry\ɉ7럀 XSɟIL=ݽz:֚((0x]>v|I[@+kp\(ΟF*!0ad8;ssI~h|K8pb7⵾bNz&T%kS YFh0o&144,,Yu23#-*-͘+:˗RC} w} ±M]qZj6%eВ؈MjllꙖZԢZFAAfꍴo >}|M|?-Nmgg;-Y0%QPPM7V>OX|QrMjJf|j̾??L5jY};ovJSRRzw aJbMAHoܬ7] C2 6 55u]ss4\YTUUK۷o'___1kmP4%\""c^G]R~uzW֖sSEE#ʬ} \)9RhRabbZZ\T}[)rmUnqC¼O312VJڮ- /ӧ~-rGG`ZnиŖ{xxp&? -ccmuY{Μ9#[n .RaEFF|q3xܦGD$l޳ WWzr^dWy>V!|x1h7 پcq[׍;Ҏ;q$J掓OgxLwP}~qmUE/v?=/EΣ`gg0"+O l[$mܸO"Kо nȂϞ=pCb <ncUuj-'ܹs)$$paE͛7%]}U4=! +ܙ5NӍ7]Hy`u /jhԥT:Uh%&Lb jhhep!%3=Qr?Vc\^u[yS*Gё8LN6'*Ɯ:?ML-]]ѯmGОb'8#k?㒊 W^\V\ ^RBG)3XÎR8#ϥ9~6ο޶.fnn^7j6RAdR|x[\A ްGi$huu ?p9Bb,Fu_-,m]DT;y2qNP¸#0`2BGRy|`PO0 S%_90|`'@ \ wA뵏cb{X6#aQshĂz$GP NӾUB [ OU3 %!ړ$c;/_>oe'7P+ՊCRpV "'l^ؾ\@cKW`aッ+36':& X8F@4[8& ʦ46VN :H8a)Z&{-âڏ`yΝ|١Z Cjz@ҢZ7ZW|g8 Ε y6y&Th- '.|M\ |pݦ]v'܎8~‘7O1? Ϗi:!z8kU&I+^5+QQ 4 Cߦ^}=kM gDJ PzzEѨiO2lH6Ie0u} m&B-VTFgaE VP~&9a!i`Y&uc F BYg&uo4| =&섳3aF9dӧf>bY.V tdHefkYs?6t 揞g!oVu+K0љHC}>8k+8N?lz^s(smܽ2ÎF,qc "Ni)L8Y9rSڼm%T#~`*4b闾O' !CFX? X^H VD0p/UDX©sgBr" ubiS|x~ލ)MsA4.a21AE:MRmHByǽ}ov KցBSa5n!-9iACJuBE l} sגm莥EA|!rS۷}<4Fr2q{_m/{܀f,0l8DJZ Ȃe*˴</.AWj'+^b!QJ b:@ TZ`:D r%,`z1&0\GȬډ\rTJT3\qj*o@y/ pÜ_Ksk0Fׁ\ f?ZfA !D8GY_ȦߥYIENDB`RaySession-0.12.2/resources/app_icons/qtractor.svg000066400000000000000000000511021417052567600222540ustar00rootroot00000000000000 image/svg+xml Open Clip Art Library 2009-05-01T00:45:54 A Gramophone icon by Andrew Fitzsimon. Etiquette Icon set. From 0.18 OCAL database. http://openclipart.org/detail/25563/gramophone-by-anonymous-25563 Anonymous clip art clipart etiquette etiquette gramophone gramophone icon icon image media music music png public domain sound sound svg RaySession-0.12.2/resources/app_icons/rosegarden.png000066400000000000000000000045401417052567600225370ustar00rootroot00000000000000PNG  IHDR szzbKGD pHYs  d_tIME $ IDATXå{pU{#7 ($@tZQ:m>FX:UQfd""h<ַ֚ugڙ*f} >s\׿WrT;"2#Ոp0(2sRsY=BJc5?pj=B|3k']\Z]#~QqpWo.+v'^"cjN/G5LWWIfnn[(}>}_zEI]UuIo^[ɕU|k3z-aD/&ƐI9#U=֗pVL7OΊpyn5Dl٪?'V]\ۛ}DPII pğ@Lۃp9jN.RLµņ7>ڛjY m pdDlX˦y\w kkk;y.(Q4Cpn/6S߰O |c;6m-VGWQ_α?v\キ P_'ۘ4U\45OQTm( :VQۯw^jH5/ʄ}]sH_z`o|GM8pIENDB`RaySession-0.12.2/resources/app_icons/samplv1.svg000066400000000000000000004357741417052567600220250ustar00rootroot00000000000000 image/svg+xml Jarle Akselsen RaySession-0.12.2/resources/app_icons/seq24.png000066400000000000000000000007231417052567600213430ustar00rootroot00000000000000PNG  IHDR V%(gAMA a cHRMz&u0`:pQ<bKGD̿tIME  *IIDAT8cO0 w `;9vy{\bH)$}9h&2=\?!-ĉW/_ߕ<T Nj%%% @JWﻒq8߭_'?.,>q\Д  ".8u`W??߯-?~sz@4#kTQ`ױz%tEXtdate:create2018-09-22T11:41:52+02:00$?%tEXtdate:modify2010-12-06T18:08:57+01:00F@IENDB`RaySession-0.12.2/resources/app_icons/sequencer64.png000066400000000000000000000043021417052567600225460ustar00rootroot00000000000000PNG  IHDR szzgAMA a cHRMz&u0`:pQ<bKGDIDATX͗[l\}Ι{f<=c=v\! "PE U)T/T*T-R(HB)5p@h$63㹞LfV0{׿{n?Wu2P<.͑"&Ii^G;u`,s8PH6  $R)!(;7Mk։[[_:sܡVPKK׉)x_<ߔb*ڌ 8ssdl*K4.9NCw7wF8'Չq#>vk+,ZFFF/m۰gӭN❞fgpf?/(YKK 4b+,8Sغ&4sX(Jwd vt)$MO=g>˾f 6kBeͲV<2? 7O`4>וqMJ^/ƍ8,>]-feYaʫ<=;CnvV-#@4 %,RMh{7v>^,)E$hYX睇zﻏ@|6o.P(^` p "u RJE^j)zQTd"PJF}?>Ʃ2 ,bᇳ\'a8@\ßir|}وhvd|WN8RIq3\w]7[R"jॲΣN, Rȗjֶ(@q3r|XR7+ _VfkcLލZinү/|;b< E:ndppPV%dj*!^o▹fY=<2 ?}0lt#Ə2 >a0"_]9~g[XVv)+h\uM!gRUr³6>Bs Q#{>fgΝ%[vo_{QZZu6'c_GR4\n0*lڿ|y@ +<ƓOj{CS>\z/6C\τm۴'n *FE|;9(T*ܳ3FF8æMiyX=Ϋe81u.۷Wlٲ>8$t MsXl%iduPr=G4O#F`%z0M6/+tCWW\ye#Dz)FUx}WatJucx|*QxoTò ڗRKS_ǘf]4n曕.h3i΢SsO*&ɦMi33< oG=@ GqlHgK| win5M9'`)J%5׆xWB Ç ?縚q|M8th3[q.ܷjNjJJuS b\wp ?gELy2˟ a c`Y2z2i:,Joɨ: q;H$ziZ〩K4Q45A0B04_D/hmkHLPHL^ޯfTi ÓXX`LNcНJ{{$wltPZ[/`/?y%H]t-Ōդ%tEXtdate:create2019-01-07T10:40:37+01:00 K%tEXtdate:modify2018-09-29T17:41:30+02:00MIENDB`RaySession-0.12.2/resources/app_icons/shuriken.png000066400000000000000000000117101417052567600222330ustar00rootroot00000000000000PNG  IHDR>aIDATx]{pSW~ιW_e<LH` Pvtt;I۝tn6!MBw4됬p PR2 a8~`[tuO#پe]tw XRۇ  .۷vuugB ?_^)7j4Y\YY///!䇁@vhA`h4PRR3ջk.Aٌk"//8Z]]]]4-`X1X,lڴ @s Om׌ <3VeT|dl۶ D)MUUU@mԄK|l&0ͨhRJO\rʮy#`X^o$5,VW0/0m6{nt:'cBU @)qjuuK-?Հ0U3Ν;A)-jMMM.l| ++ ;wۢUVUr;д~dZ'%?jE}}=._ܤ@)<\'ȯؼy3!wt_>5дcy~&i0\.lܸln^f0LNCUU 轩{?&A@UUz!ca E @UUt:!!EEE;@l`^ 1Ʉ*<gb6!;+˖-!DQR2,[ BM X6mT&`ٲe(--!@ jA%$It"0Ɛ LP]] GcP'c 999(++98R~z94+M&t:x)ɗCmm-NR'jė,hV30q`)G$##fs*%_򐟟?i͏g34+BH!<WAAn!_t`M|*,,51h|ڏg34+ 1b8& ᙉ)`&@LC f"Rl6_NbCp@tn RVVx[˴M @Se[^ L Ф(kĆ@|eRKn-?ݡI0jOeSJQ^^Ѩ,9={t'xGYYA0Һ x8Rt:|Jm^%K8LyIpW8?mT`F\hJ?a?03e{dt~n@3hkkRڐ*d2@fM CM*4!CUBAt<%IG4$"O6\wǤ? 36QMM Y>M̩t|r߻wѺz\ɗmAp(掎ԕBr嬊 h|1Ko !&ɳrʲ*,]<ϧ͟nii;#y̙-5R>|xq(j"ȘtDQp7JNhbAAAMO$I@SS0!dӧF)rrr J'^t:n1(Ԑ/xquEEEyA)z>mȗ#_}՚-^k.b;Y*++O{<PJӂ+WpIr ˶Y*icVp-!ͦ|Av755}x 3pUDD N;7 v;kkkKꦌ;Q@SS?8e9515|k"q t'*SJx>VLxg}QB!*eJB wqݺu6Ǐ tsj.?@gYMMM¿ &IS pBiy///H|@Ahnn^$YcD6n{dnk>n7(F`҂9}4ёDR\u:jll\MIxuq tNr)&8x9A$IZ߿Yiܼy gC" %L]ccL"߳Ld<3FT/oee%v;%D'NX\M~4b |>#IR !7Ȝ6? %Dl|>߷) ;A̩[[[ qܽ$%I$)$'`0(iNZMVSןvQJŒ10[F1JN=Y8|YTeZ Z[[ D L;^mtnnlXTğ,W_z@A+**R,  lL>l8gdR*uvvnhhhvi-@ qy`<>z꩸Z\_cgjooL̀@IEo= i/*bJ&y:;;qƍgR# "Xl<+jǜL!T$N:>ݴ/ۃ융U9EķtMeS,5H{_)"zzzF46DQ;dCɱ`i_!.]>@T@ (oL-f3g!į"Nڏ4@~c푃>d"S:FxRc6L]TC O~p8 Bz$2Tyhz*cJ4Ӹ|o"MNCOO ΆjC fgSK4 邴06OvB! )BD0WiӦΒML`0JY?_ `͚5W|>N9B"9O"4!ظq9b"@>}&@Ќ`֭;]f0us}Z 24%رc^ocFFF9r@Мࡇoh@L924)رc+.믍Fc|t x|ٳ ́\嵃*4-صk 'kdZUh^k׮.,, a`lڏ3`z?y^kKZ`߾}.((8qd 8E*`߾}8>w{/..~%ZǼ!_hQ Ǐy) H[ ޠtbue[? zuyyyoM^Uk@EEEt]AAi`Zżlذa? ֭[{nwV رZła˖-?t:G.MbAq}_0$TS {y|~YTT!'NRۏ,` H>zN'6YIIENDB`RaySession-0.12.2/resources/app_icons/sooperlooper.png000066400000000000000000000022041417052567600231310ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<bKGDtIME  *uIDATH]OG{f`!D*4Դ ߑR+EBUlƞӋ5TEʫؙsY-;ՏKr !"CBT&oS$e0?> image/svg+xml Jarle Akselsen RaySession-0.12.2/resources/app_icons/vmpk.svgz000066400000000000000000000252331417052567600215720ustar00rootroot00000000000000َוѬ yEEhŮ)iK։1L\U2`>{XkG?ozÛwo?dsWo޾~wŋ^{{wOvy7oŏgq㳧O~}ᯯlܷ/ϟ\sS~{ryzy8|_}/Oo^]|I ߟy߼zDOJO}][IO8{ۋu:/9pFW}xtD'W?\r~~ٽ|w|ݏ/^YvɻpЪ>a{5Y?,^>ۧ7?3e>!qREJڒ:@Kh~ϟeyP~Ȯtt}_t49\;zLxen&9Ͼ'tt{}8o.D?8sֿw/.޿acJm۷Vsrї>PGw ߐ>(rמENilѓrJZmrmÐƾ:oKL巡N& 2c,& tSJSx!r sOJ=DJ&n7ʾ&rCRiP IZ۷$'u?]z5~RT!r %[/]ߏ7wtv;}^CC FY>Muz~ŬEږ*V/>Lr&S7} cUmR˜TIQ=D~am up^y}crOAnI-f' /oRV8LrK[P> L)2$"RJ7Ԣk3:W;9Qגb~RUk$%l $#q7wBBMܐ{і%O{ _TSc6A^n KS7R&BJ~覠|RP ΚqwZF} սjl7i4{KN9lU$VM닋э:Z9=Lᾚ'5 {R<WTyP( Uj:&Oz/oC^MSfPglmJxұM93M1 @_߳a"[D)ʇ\!"Ro?˃\Y81VT^oҦ?^7x0;dل\KOcBnVǺVYۨΖ]_i^//ϛ~akD!6$Fan^Vd#2_uC^2oIGcr>,ԽKpZ1y'ltn]$1勪}// u#Xc+kDA>J(41 ,iPGI.^"Qt4py[XOStpY꾆Fѵ Y| 9%aEc w=D.=o[%8y}1Lk-GHjGIY/7$̸%.ݧm0zdfފ!nr6Z}\ϛ:6UөC ;iIrwmX3֡%dlN-^=ܷuFze=WDXX8&9vEPj:/ci6B(1M}qNv$ kAG3z_ك"]gh{WBJҭ& `{W12 Vw..n֬б'-f&U5pd֊gH~& SZҺ^FXː}$ 'o#5w^(*Zռ=eR֐SZ*%j:CkUr+nH,T {\7(v7ubQ>NzCB|R[>y\=gw59xew_ D:J{UzY-}擛"T>^;d;{ʦ5b(EA*._[e2d9p!u.)mZ tXԻ.r:Zt8S)N +[u@/qT~T&3ń&-9~T$!VeKw( M|^vFᬣ/-5M^L@iuI(01k ʰ'N\*ƒ hq F)T] P%n*.8YC7}rUp_}gg={ի?|xήuם[t%>zg/׏wo>ѫ2>B?]n*4:A}ԾҗPϪ. T_^bO“),˷ 6Xj0ֵ"y.|Hr1#mpMJ!v3.+3uGl%rAV"jQVxȈ`}O, y-KGkNP.m"VXd,;ϮQT\k))SW RY^ḏCy|iKV󔈪*xIJP%X.G028MX\F)$Q,ћ=@(:?iGR^I"M O,ψ9rJFk'?u\=%$nO,%E`ghSHHݫN"Z]Y,>V^bq#v9.;[Eyoq}+5GeS%,A¹pe\s0拣]wo^>J_>+G~}E.ͰXzrgT9@;%*~sS^ʣnjTGfm5| 6Z7ͮRHU$WbiQ,g!y:@j]Y굛MA=qQ]u<_ !F|rǭ %:Hb(.|FxϚ@c;88Mzvi5$陳2d1.Y q I)KX; N6G rp-QE}{ƒ}ZK% zSŋyC!9ʴbԱ*1sɧjC\)FK~V(4s5PP3UNJczU:]=s5|)H>^CZn+WIVI_x!V݀ðaG"sPj22$}rpN"T^<4ihvMYRd2:R&w CkHa$AsHKoRI:]bH@+%O7it X5F3GْTVi )$(pS~k04gXUA2,zu]٭r+Yunq;k Pz맛DH}5Jelǒ<[4 F0r=u8X>V6 c&UJaGF/'|ZKr- |W@jcɵ:.5ּ\@'2↔Odo"''͟6dXtaR$Y|'9c?{)yU* ).\>6/.ttp)ʩ;[%`z^%,. )  q΍1UB/bqT^#a*v]Ku"2&aTUi]Þjxbh~1Ɉ3$帩@ܖ+zw^_ߗu%,ܫܰi&=+8ph"֐QذQra~ /;[^U$nkTx"DsAH%ڠ7Dt&]c/H AV@3^Fn{X8M,!G/9^@Õj ՉC 鴮p!eT|gYIyDeZH;tJBˇw/q=[M$Y޹V 7Q'yKˠud S4j5lBB %ыyg/(q XG'G`UdAF=&fkiM\dlFiM%&5C_JƤkYxZl#v0I+ 7*g\I :]ݐg %PihO+ .:}|Dl e*F/?o+,`g.*(B?J+kn((GmX#wPP`p,B{8$eh 0L D~J:F/n˰uƧzэXhxfv 'pHp?He˲aM2Pet$mݕcu C15w]V_$jd,'$<ȝV$J%Gy{#)PSWLRL*i4wl;32YVTZO) vEHфeaH&(]H@TXhCOQyb;û8+õY(b~NhoӁF0Ԇ[h+ƢD s+:EZJ]%PԷnЧ耄Xf8c33׳Ҥp{HX'iA2vc22ĹAbt}Z[,Y N!1@C5i5qӓ·ץŒ Yئ\-M%st (7Wm6`Fj$˻ e鱱QPar= c:f5qn'|bAnaZ#И24&FUd I GZb.%dD""{ ކȬJAÃtz>b@ydF%i ʼnN0?IWD^ b2a4S ̝I,mJdt@^u2'aQ\o_x\;Dger)r&s)-T~ckZ l%aXÂ1 QH8 JyہgK#Op]SX|I`@Yz_c{cd4dz]w14CKK {g~NF鿚I- 0El*g~l+@wgbgc}Dv ҲktP ~beҀ,eI|VHd1 زLjh('%k~(xz1mBt xXQgKx,}Jld.o^'Uq!"V(^QVAXk;E)=v"0Wy\}5H2v9Џv!sp䏩W"62\5q1NaSFΘE)Z(|ַ'mvA%"yw8o c PhU8fѓ zgGBq1gvlN2 M{!z7 "wZ%srYU!Bmvw jJ I1,JLzRtcs,_@0B]2c17 хpZHk&WCMn=ǹ P]Nғt\ӭ WtӀÉ)ORDՆXMk.9'RYԱ|-IMn4_$,dC>3VRiJ@9O63܅rdZk^FՓϻSMilucN*-Gf081!" Ź)SJ( < 0E(dAVm\8}ƹ][V'طXuXdBD*2}IfC0״- ttztI\̐/-QYE:/PVHπ,[0F<Њ4ML0"*TB/ ah20yd$ǣ9Q^uXA4ax44]c ِSq9wۚX˔t@ *UhgeekU[}{u&gԐ;R5#r9dOTqG]{uV}f[J+^P4ߓ1dDU*D Yȁ`D€|W("JC- r*#Bl.\qeJ<ζuݥhm.[u%GSDf%͚3pud\~79*{ }q$eZx:W h"qj:lA*I4494rH0ѧ :57SH&bǪ Ɯ_W"-X?:{փ!1(PWSB]EfL5^]:X겏#^Ã0pʉ N+fb=VuS m lx"ء:NjNlT#{&11432WjVQ4/0A@ p3:pe--ZKN'tufPRNrh5Dd@Lt6صsG\ΊrRX)O>|FĎ?7 ٙDQ,^Hɪ5Hf%YSWAd=cj0d( ZV6.ct1 \zrcm?yv\:`%Urj,;iTG\#][/PO4aFPeGo3`"]U(aK#\%^>oN:QsPh+DĶf@zH溒{,ғ񗳋)dPEkl0pRU OC.Ⱥ|HcA wUBӂ1hJ ZJP p*ZY0:6þ gיqqf8sjHPupH#eߋ7eH3@ULŸu}va#o4g.{*>2&Obrd?@#v!Q\n_!cΊ%cD!35R(^~%98U77j(RpApF{͋Wb_*\ 9I\J3nȐ0';%ӷ,rhL$g^3nT՞FWk[+je475B{ ǁeՑ|{pҟ\f (,s[(kW;@*y!,S*"6om'FG 9U~Yv$be?!82{]\[R! Ǹ{"=Nyvk-GM04w֫%kk$ћ t,Ml]f|?ƌ$Q#n8n'[-A#Ia}:lJ㸳d'X01uɌb必ø~Ἱ5R>eep#yޔ{AlۼvIU l ]  r+:\S*[l(@hd"Q x:ZHcZ'b` uH{Nn&*<2.~.XI|zZy[pC2WuCz [;mi+wo܀986k\*vga띇%-o+4zP=l eBc'-|b r.䆘^@E EOF^DofNp#mQsޭvhDs]yiOW;Hdi6"љΟ]zn5ȫS |IeS4nv) 9&O9[F7goY)qB~d;ϧ7VOZym؍S=#%Pj+uteYVf uz.eoa,M7Ut[!UlW ^k@(ْR٘Kknb`_{{liߤ73V@(GL8q:[vv5F@Ep̏F*Zо]aݰ҂ԲhhԽ,1\ܸBmN{g9L{N6$H[_[c5{-1Ce:N:'WFsCxI6o,W]d&UVe5ȿDR! I;'LQ(G-d[*\[8\4Cc[I d5/@2D'TZ9P0ߝDN?SC[o~% image/svg+xml RaySession-0.12.2/resources/cursors/000077500000000000000000000000001417052567600174225ustar00rootroot00000000000000RaySession-0.12.2/resources/cursors/cut-black.png000066400000000000000000000015371417052567600220030ustar00rootroot00000000000000PNG  IHDRJ~sgAMA a cHRMz&u0`:pQ<bKGD#2 pHYsmtIME 0-IDAT8ˍ]HQ9zBtLrl16(*/a B/FxQAH]E.0( ,/\Z1&},\5{t6]>s"oщ@{ @ g41ċ̌fMt?zR(%k}I![+4zRb=rf,D߄5N}8 qͨJH\7@TPBP;a ,6|Q̷ΊL"l&}5>;2u/yG@s+UcY5(.|1qJ ]d4e!M + ʖ]o@RIf(Ӝ&1G[z,ekӭ?U܀MɃ_-O{Lr]kF@%vojPTɍY};l9Xߛ=WN>^| Q%{WrnE\ ۆm N-@[c8&B6Y%tEXtdate:create2018-10-01T12:08:48+05:00fw~%tEXtdate:modify2018-10-01T12:08:48+05:00tEXtSoftwarewww.inkscape.org<IENDB`RaySession-0.12.2/resources/cursors/cut-white.png000066400000000000000000000025511417052567600220440ustar00rootroot00000000000000PNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs+tIME 1,3IDATHǭ[LU?gv]wv\l j)Q"(^*ABh*J"FMc &1A}1n̈:BH,IIOhJ, 'DdUa[[&VNҒ͘76|)$tiiKEp57ɓ165 |QY:0D[Rj!G1KKx?k^~,X,I"\ڮH^b2㛶 Jiiǹcc}MɎ`?^Ш ~296"Jt_pO^^CKIrL 򾰰LD"#= . 4-VƜ%tEXtdate:create2018-10-01T12:08:49+05:00|%tEXtdate:modify2018-10-01T12:08:49+05:00vtEXtSoftwarewww.inkscape.org<IENDB`RaySession-0.12.2/resources/cursors/src/000077500000000000000000000000001417052567600202115ustar00rootroot00000000000000RaySession-0.12.2/resources/cursors/src/cut.svg000066400000000000000000000157731417052567600215420ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/cursors/src/zoom-area.svg000066400000000000000000000175421417052567600226350ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/cursors/src/zoom-centered.svg000066400000000000000000000147661417052567600235230ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/cursors/src/zoom-generic.svg000066400000000000000000000146271417052567600233420ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/cursors/src/zoom-in.svg000066400000000000000000000202101417052567600223150ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/cursors/src/zoom-out.svg000066400000000000000000000167151417052567600225350ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/cursors/update-pixmaps.sh000077500000000000000000000022641417052567600227260ustar00rootroot00000000000000#!/bin/sh svgfiles="src/zoom-area.svg src/zoom-generic.svg src/zoom-in.svg src/zoom-out.svg src/cut.svg" filter=Gaussian for svgfile in ${svgfiles} ; do filename=${svgfile/%.svg/} # Imagemagick with rsvg support convert -background none -density 1200 \ -define filter:blur=0.75 -filter ${filter} -resize 24x24 \ "${filename}.svg" "${filename}-black.png" convert -background none \ -resize 384x384 \ -channel red -negate \ -channel green -negate \ -channel blue -negate \ -define filter:blur=0.75 -filter ${filter} -resize 24x24 \ "${filename}.svg" "${filename}-white.png" # Imagemagick without rsvg support #rsvg-convert -w 24 -h 24 "${filename}.svg" "${filename}-black-hd.png" #convert \ # -channel red -negate \ # -channel green -negate \ # -channel blue -negate "${filename}-black-hd.png" "${filename}-white-hd.png" #convert -filter Sinc -background none -density 1200 -resize 24x24 "${filename}-black-hd.png" "${filename}-black.png" #convert -filter Sinc -background none -density 1200 -resize 24x24 "${filename}-white-hd.png" "${filename}-white.png" mv -f "${filename}-black.png" "${filename}-white.png" ./ done RaySession-0.12.2/resources/cursors/zoom-area-black.png000066400000000000000000000015621417052567600231000ustar00rootroot00000000000000PNG  IHDRJ~sgAMA a cHRMz&u0`:pQ<bKGD#2 pHYsmtIME ,@A@IDAT8ˍMHTQ7c>^HEEbn6(A&M(HBm(R,#Qyɐ ́d3;mRms8p{.#@6%*, Tc$Ҁ=!Au7+ (-r m ?wU˼˲'r„o)!]f^}FpOok"{K\ibٓ8W!9J3eQ) ZND6}/-^XQ&l.ni@BKTwο{L\yے 7Ԟq?/^H@N^:y&l3WJ*|wvD mhħ}X[d8fO_g yr5(Pu>yN- p!K[fG#behÝ?_oT5A ~FeDw {W@v ;@b1?!_Gv"5X(@jU1-v p!}Y lSŘν mԳ`/ќ8l$o`g)%tEXtdate:create2018-10-01T12:08:44+05:00j %tEXtdate:modify2018-10-01T12:08:44+05:007tEXtSoftwarewww.inkscape.org<IENDB`RaySession-0.12.2/resources/cursors/zoom-area-white.png000066400000000000000000000026651417052567600231510ustar00rootroot00000000000000PNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs+tIME -pIDATHǝ]lUǟ9=/]G[>XŰ(؅L0&\B@>L;.\, ba00I(KAm2uڵtm9^t$'yO^`is5UϘLæ" %cZTo45t0i+ڴiohkpӢEo34r@3puEb:OVk/p{ JџG]/kn~ϵ|y>+p8>HB3g.p8v,(*Z-PD -t}s.NB}6)5AB6Ɣv_L~ԩVZ) FaF#wcjiS$@=tb.)[k&g;<d>(PJR̙UFPpp']"=b\ьX(2P)sG8xbx67DPn/&w ڋ<+ d?LŔ)U<J/v:D,/oD&o~]_C#MBGfX}]F8 P.^@$ yDV1(d2fa÷iHKp8RPK'u}Bu 10G(bٜYql֭/&!R;;W+&rMLIF:6sڊW\^25qB+^U޾ԤQ*CR2~7Z ( J=w!ΝbѝDl2sG",^yЊe--DÓLe2R&}0;)%۶}q4Frl՜"n-?౔i)SQr!P 'l@)R&$b9M^2MTUzWJK '`6 r^^R]wkOO#!JJCD"]e>ߞLBzYԗ,7&fvbK]϶<~u_v&{_g"3/)ɒSC#1%VkܽwP-IĪbn{;VK bE.ɢ*Tw- I; +u:^ur!ƥĆTdix7Q$1<3}7*\,?)5 Bg/w?*f`8ck!%tEXtdate:create2018-10-01T12:08:45+05:00%tEXtdate:modify2018-10-01T12:08:45+05:00v@tEXtSoftwarewww.inkscape.org<IENDB`RaySession-0.12.2/resources/cursors/zoom-generic-white.png000066400000000000000000000023701417052567600236460ustar00rootroot00000000000000PNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs+tIME .l!mIDATHǽOH\W9qꟙ)1gRM H4ƍH!]daB$)d%l颤. i%ؖ&8UjØ3V'Ϙ̼{O϶VgFw|<`/> Jʴ ac! °LM-,~dg$p6;h(-};8Pl0 HH$z?,9LfdvW08^ssMH"XfVG,/pP{{ݑuɻFeeoRk|QVvQG D4׿2^z@jDRBGRۿDQJ15RQ=7FRfYs"X^\0;Y:u ș/E?%0;,Y"6+ @Qon@$`ŵ{͸. xQ2Hc| @(" wugBV>&ej*?20@kVcwW9V͛#J=y y>':=h9 V ;\=)Exo+'RNut^zz"nw2s BUյҥ΃|_KKQI(xc̖?E^TjKoO-Ѣe~Bg{=&QYB*~ǖK*QJ=й5f꠹ im蔦ռ- U^3:wrn.:2?pmt:jJ2(d]<$AN',kѣOzm-J!=GDOe3"ORlifV%tEXtdate:create2018-10-01T12:08:46+05:006 #%tEXtdate:modify2018-10-01T12:08:46+05:00GtEXtSoftwarewww.inkscape.org<IENDB`RaySession-0.12.2/resources/cursors/zoom-in-black.png000066400000000000000000000015621417052567600225760ustar00rootroot00000000000000PNG  IHDRJ~sgAMA a cHRMz&u0`:pQ<bKGD#2 pHYsmtIME .l!m@IDAT8ˍMhao$%ШD6A+M$/w/9ZfhODC- Cz`SٶՀ5(mTwnͼ3Sw͛mU4Ⱦ\(SL8ƯzDe0vgj4|7|ɨj%. 4WX,d"3F62,1,f[b qA @E_Vu+x *T0H0ۃ70Cj 4X<ɞ+>++FPWKB7m?{@Ws}&@`Es}YslAT0P tev汅흅0e`B \p#*~ pj٠4<;zvڹXIޣ(Ȍ. +0FT^;n՝8ݷ]w Ĺ.H ##E9y+I WܤuOüzOTW̐; ?>3J=X]t4q\ ntd+ l@3tq'ኗ5%@S=%C{vLP0%tEXtdate:create2018-10-01T12:08:46+05:006 #%tEXtdate:modify2018-10-01T12:08:46+05:00GtEXtSoftwarewww.inkscape.org<IENDB`RaySession-0.12.2/resources/cursors/zoom-in-white.png000066400000000000000000000026551417052567600226460ustar00rootroot00000000000000PNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs+tIME /wIDATHǝlSUǿ^ [&102,Ju,&  h a!1ǔ¢&A qC~ 6:d[XGF۵GAhKINnr9{r 笒) JzYG@DZJ+TpTj Pl5*+{aykw.l̹A)JB2Q'SJJ紶wѢ':Itj`Y+릦H8ٿXz,v+zOTT?xI0a)Y>;],vkY R(HV0x"r9L1'4֤I74:F J<Y />2ҥ14pS{Fy۷LU02 Y9 mw˲*38\=7&G/0UyK̹f:S~ ҹ4Ĕ8$S|>WYd]uR9B5" ^ZVK~LǷ=n$tuطRuXgUNH/@B0j*n`@m7*gsu14K?>yqZmg4^4NW'W ^yõ#[E,a. =uOKHnI:%3ӏuT&)gϗ;A-HkH'? O@eH,L6!CjAWNH8ɌU/[, ź Ev-Hވ;I%tEXtdate:create2018-10-01T12:08:47+05:00%tEXtdate:modify2018-10-01T12:08:47+05:00߿+tEXtSoftwarewww.inkscape.org<IENDB`RaySession-0.12.2/resources/cursors/zoom-out-white.png000066400000000000000000000025341417052567600230430ustar00rootroot00000000000000PNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGDC pHYs+tIME 0&IDATHǝ_lUǿ~%csqCaT0AL6ѐH41HHL faȃApnYxmEF_ ]Civ'9/w7?lqԷBa@0_DdZǮLM]H&/% feۏK<ի=؀H.@Кg6opX%#I@g֬ƚ5-'O"f{b|?_aCop_E@EEKظs_UT\UR"r3)KJV>[O?~Xl|yE@lsNx;89xq"I#bPcDqo~$O K0  # "ba*HYk#uZt{E4DR΋_]hua:7D s= SeeO协)swu$Y^ήh}`pxy{΍ =? ) bHH$r Ϭ@ȥԜم2X9]$P[55tY{J/-}n`_ȊHe(+"x^oʽ{ƌRvxi200zq́1D{wjikk}>cW@;e5X^oS{oכ(%yiwDRlgҭx@d#@_#sdCܴ;t_Н;cT1w_ @Q3Wˬgno nNL ]wv/11@"ZRٕ(0XOXȘ1fF_>:ɀ0D ,1QÜ߽Y\^^Uַ^XoK 4ٰAdY˪wo2&EС˭{w篬f.Fڵ{BZZ>r>P4g!}~&'G/eBn\aa+Xy00I$&: GDR ,W> W$ԕ7~Ӳ(ƃf^RvW!bEz%tEXtdate:create2018-10-01T12:08:48+05:00fw~%tEXtdate:modify2018-10-01T12:08:48+05:00tEXtSoftwarewww.inkscape.org<IENDB`RaySession-0.12.2/resources/fonts/000077500000000000000000000000001417052567600170535ustar00rootroot00000000000000RaySession-0.12.2/resources/fonts/Ubuntu-C.ttf000066400000000000000000012543541417052567600212520ustar00rootroot00000000000000PDSIG?GPOSr}oGSUBUѼ 6LTSHyjOS/2.5`VDMXs{cmapίcvt  k, fpgmvD#gasp glyfhdmxGb mhead_\6hhea $hmtxT8kern%6*z(loca&j8 maxp _ nameh`h 8post=slX,preps{#Ϥ_<ɯ83=1 CH1n /YC"O P [DAMA@G8 V 2HzF7/70,FL#+&94F,**2?-/99.+.V8? T7@STT 7@TTTTEET]8T]8T%N(^o:)Ma0012N0NANLNN0M0HNU$AHG=d! % ^ ""1%%:*088'='H2o:sU$*1HH,  ^):?=$?:2 + :kN)6:6 l)*&V7TTTTP@ET]8]8]8]8]84]8%N%N%N%NTL)))))))a01111>1N00000+(GGGGM)))7a07a07a07a0@S0@0T1T1T1T1T1 70 70 70 70@T.@JNATATNTTND)T)TLTKL ETNETNETNETN]80]80]80THNTHTHNU$U$U$AHAH_H%NG%NG%NG%NG%NG%NG(=d!d!d!NU$AH:]:*:2:*:e:H:L:'(=(=(=  gA305U30*530*5&3*5P,'+Tc2+9$+++dNNN%N%NLNWN1*of #j 1l )(    :s:]:U:sL8?^ % H2o*H*V?TM7z0@x,01-717N.T" TN TEN]8]80D80MTXAH AH%NGc2'Nd!#km+ni-N ^^*HSSF0@TTVT6TN)]80%NG%NG%NG%NG%NG1)))70 70T.]80]80k SS9$ 70KT TETN))]8()B.T1]80]80;HTHN%N6%NG a @T.)T)1/2d!)T1]80]80]80]80G<NG007a0U$d!~ A % T1q80Hk :*: :D::2:::::D:':':::TTDT7T- *TRTET2TT TTET ETETTC E@T]83TT7-=T8TT! TT<T)ANKN 1nNNNbIN0NMa0xI(N,NN NN~ N-11KN1U$ANNNN1']801 JTNTMTPNM TNU  n%TN,TN8 LTN{TN%TNj817a0x d8*8%TN{ { T  TNH @TNETM8,EdIT)))T17171 nk ETNETN]80]80]80~ 8,TJMTNT 6 TTT@T]8TTEET-]83TT-k?c20N0-|&N5LNN|(0NHd00XHY0jH7 z<w;|0-NG0HHA7:t:\:00000000|GhBB------  NNNNNNNN  %21DD000000B.HHHHHHHH777777777LB00--NN%00HH7700000000t?`::NNNNNNNNuu77777777z?50000000 :[:S:[:*:NNNNN%%3T::7: __:::HHA@HHHHEc':::77777U2:T:P|GhBB  %LB@Tc24 HI* //& 1 !#**!!+ ! /&%/   /'///      11  &&&&!!!0*  *** . !!!*/-11&.       /1  &/    !!/- !& &1&&/*! //10 11// &&& //&  /-- 1 &/&/ /&. 1+#  !!& $ "1 %0 00&.!!!$ /.Z 4  !!""##$#%$&&'&(())**++,+-,.-/.0/102131425465768799:9;:<;=;>=?=@>A?BACADBEDFEGEHGIGJHKILJMKNLOMPNQORPSQTRUSVTWUXUYVZW[Y\Y]Z^\_]`^a^b`cbdbecfdgehfigjgkhljmknkolpmqmrosptquqvswsxuyvzx{x|y}{~{|}~                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           %                                                                                                                                                                                                                         %'                                                                                                                                                                                                        ' +                                                                                                                         !! " #" !      +!-                                                                            !   !                                                  """#!!$$!"!!     -%2               "                                          "                     %"$  %#                         "          !! !!'&&'%%!"((%'%%    2&*9    #          " '                           '  #$  #     #    *'##)#  *'##     "" ! # "   &      "! " #" !## "  &%#$##%%,++,**%'.-*,** "   $ "! " ## " 9(.>    & !#     &* # " !  ! !     "        #  ### +!!!!!!!!!!!!!!!!!!!!!!!!  ''  & " "  $&   .+'&-&! " .+&'"    %%!$$#&  !% " "#*" !   %$$%## &%#% " '&#%## ""*)&(&&))0//0..)+22.0.."&   '%$$%##'&#%##>-2D     ) $&  #  ). & % $  $ $ ###$ !  !     &  &&&/$$$$$$$$$$$$$$$$$$$$$$$$ *+ ) %  % '*"   2.**!1)$ $! 2/)*$! ##  )) $!''&)"""! ""$ ("   % $! &".% $!       ! "!!" (''(&&  "*)&(#%# "**&(&&  %%-,*+)),,433422 -.662422%!!)  #!#!+!  (''(&& "**&(&&D16I #   -'!!)  & ,2) ("' & & &&&'!!!!!!$      #     #!!!)  )))2''''''''''''''''''''''''! !.. -("( *!!-%!62--$5,' !'$!! 62-.'$!  !!!!!!%% ",, #'!#**)-! %%$# %%! '  "+$!!""# (!'$#!!!)$1(!'!#!!  !#""" ##"!%$#%##+**+)) #$-,)+&(&#########%.-)+)) ##'(10-/--00877966########02;:6866'$$, !#####&#&#.#"!##+**+))#%.-)+))!I5:N !%    0!!*"## ,(! /5, +$) )) )))*!"###### &!!!!&#"""&"###      ,!,!,!,!6************************ # $ 120+!!%+-"##0' # :610&90*#     *&##:601"*&###  ! ####!(( $"//""!"%"""*!#!&!-. ,0#"(('&(' #!")#  !"%/'$$%%%"!"+$*&%""###,'5+!#*"#!&$##$&%%!%&&%"$""(&&'%%.--/,,%'0/,.!(+)&&&&&&&&&(10,.,,&&*+43020033=;;=::&&&&&&&&46?>:<::* ''0"# &&&&&(&)&1&%"$""%%.--/,,&(10,.,,!#N8C[" &+"7"#'#'#1')!)"%!3  /  &7>32*0 00!$///""""""1''))))))%%%%!!,  """'"'####' ' , #(' ' ' + ' )))"""% % % % % % 3&3&3&3& >111111111111111111111111"%) )$$%%9972'"!!'*"$"#2#4' ))8.$"% )%#C>88,!A71")% % % % % ""1,$##))C?7#8#' "1,)""))""% % ' %%$ "))))&.."#%!*# ' 66(#' &""#'+''#'1')&! , &"45%2! 7"  $!!!)! ' ..-, .- ! % )& '!!!"0(%%"&'!+#6-) ")"""# +#+#+$#'!'!'!"2)""1,$$+$'!'!)))    "2-=2"#"')#!1')&!, )) ! !!  !()+"#**&+  !!!+ !,+')''##.,,- ++644633 !+-8735!!!!!!!!&/2/+++++++++.983533  !!++ 12=;8:77 ;;FEDFCC++++++++<>IHDFCC ""#!1 %%--7!!!!!!')%+++++/,/,9 !,+')''++644633+.983533"')[CKe&+ 0&   >&'#+" '+'6,-$-' )%9#"  !##!#$ 4$###$+  =E98/5" 5" 5 %("555&&&&&&7#""""+,----- -))))"$%!!!!!!2!!!!#$##### #$$$$#&!&!&!####+&+#"!"!"!"!"!'#'#'#'#+$+$1$' - ,$,$,$1$,$-#-#-#'''   )$)$)$)$)$)$9+"    9+9+9+" F666666666666666666666666#'*. "  .(())?@ >8""#+&##%#%+/&##"( &(8' :,$--#?3(#' # )$.)(" !#"!KE?>1$I>6&!-#)$)$)$)$)$!&!&!72(#'#' -#-#KF>'#?',$&!72-#&!&!"!"!-#-#'')$)$+$))($ &!"!-#-#-#-#"+44&##')%#!/#'#"",$==-',$*&&',"0 ,,'+6+-*$# $1#+&:;)8%$>'!#"$!(%% %.%#$#,$"43"2 1!!!#33$ %$#)#-#*#,%% $#&!5-)#*#& +",$0'<2.$# ""& .&&!&!'$0'0'0('",%+%,%&"8.&!&!72"!(!(!0( ,%,%-#-#-#$$$$&"82E8 &''" +-'%6,"-*$ "1#..#%#$% %#$##$-.1&'0/+"0#$#$$$1########$%10,.++''3213$$$$$$$$00<;:<99$#"%!!######03?=9<$$$$$$$$+4851111111113??9<99##$$##$$11########78DB>A>>$$$$$$$$BBNMLOKK11111111CFRQLNKK#######&&'$7$$$$$))22=$$$$##$$"",.)111114151@$%10,.++00<;:<9913??9<99&+. "eHSp*/$6* $$$$$$$$$$$$$$D*+'0&#,0!+#<02(2+!#.)?'%$$$''$'(#:(&''(!0!!$$$ D L!?! >4;%$$$$!;&$;$),&;;;******='&&&&0022222$2....%(($$$$$$7$$$$&(&&&&&$&((((!'!*$*$*$''''0+0'&$&$&$&$&$,',',','0(0(6(!+#1######0(0(0(6(0(2&2&2&+++!!!###.(.(.(.(.(.(?0%!$$$!#?0?0?0%! M<<<<<<<<<<<<<<<<<<<<<<<<&+.!3$ %$$$$$#3--..FG#""""D>&&'0*'')&)04*''&,$#*,>,#"@0(22&E8-'+!$&#.(3.,&$!!$!&%%SMFE7(QD<*$2&.(.(.(.(.($*$*$=7-','+#2&2&!SND,'F+0(*$=72&*$*$&$&$2&2&++.(.(#0(..,'$*$&$2&2&2&2&%!/99*'#' +.)&$!4'+'!&&0"(!!CC1+0'/**+"0&5#00+0<02/('#'6'0*@A->)(E+$'&($,))#)3)&('!1!'%99&8$ 6%$$' 98(#)!('.'2&/'1))#('"!*%;2".'.'*$/&1(5+C83('#% %"*#3+*%*%+(5+5+5,,%0)0)0(*%>3*$*$=7&$,$,$5,#!0)0)2&2&2&( '!'!'!*%">8L>$$$$*+"+&$02+)<0%2/($#%6'33')!' ()#!)! &(''(2!36*+54/%5' (&(((6''''''''()750300 ++9768((((((((55BA@C??(&&(%%&&&&&&58ED?B((((((((/:>:6666666669FE@B??'' ((&&((66''''''''=>KIEHEE((((((((IIWUTWSS66666666JMZYTVSS'''''''**+(=(((((..88D((((''((%%03.66666:6:6G()75030055BA@C??69FE@B??*03$&pPJ ~17HQS_awx67O_cuEMWY[]}    " & 0 : D p y !!!"!&!.!T!Z!^""""""""+"H"`"e%  28IRT`bxy78br HPY[]_    & 0 9 D p t !!!"!&!.!S!U![""""""""+"H"`"d%gfBb'aII {A;+߷2nUyT04*ߙߖߎߌ߉߆z^GD# vhlNVTp<hisj`lxmynzopdqrftubcdevf   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ah~sw}eg|nztuqrop{ocmyidfk jvbcdfe`@?XUTSRQPONMLKJIHGFEDCBA@?>=<;:98765/.-,(&%$#" ,E#F` &`&#HH-,E#F#a &a&#HH-,E#F` a F`&#HH-,E#F#a ` &a a&#HH-,E#F`@a f`&#HH-,E#F#a@` &a@a&#HH-, <<-, E# D# ZQX# D#Y QX# MD#Y &QX# D#Y!!-, EhD ` EFvhE`D-, C#Ce -, C#C -,(#p(>(#p(E: -, E%EadPQXED!!Y-, EC`D-,CCe -, i@a ,b`+ d#da\XaY-,E+)#D)z-,Ee,#DE+#D-,KRXED!!Y-,%# `#-,%# a#-,%-, ` <<-, a <<-,CC -,!! d#d@b-,!QX d#d b@/+Y`-,!QX d#dUb/+Y`-, d#d@b`#!-,E#E`#E`#E`#vhb -,&&%%E#E &`bch &ae#DD-, ETX@D E@aD!!Y-,E0/E#Ea``iD-,KQX/#p#B!!Y-,KQX %EiSXD!!Y!!Y-,EC`c`iD-,/ED-,E# E`D-,E#E`D-,K#QX34 34YDD-,CX&EXdf`d `f X!@YaY#XeY)#D#)!!!!!Y-,CX%Ed `f X!@Ya#XeY)#D%% XY%% F%#B<%% F%`#B< XY%%)%%)%% XY%%CH%%`CH!Y!!!!!!!-,CX%Ed `f X!@Ya#XeY)#D%% XY%% F%#B<%%%% F%`#B< XY%%)) EeD%%)%% XY%%CH%%%%`CH!Y!!!!!!!-,% F%#B%%EH!!!!-,% %%CH!!!-,E# E P X#e#Y#h @PX!@Y#XeY`D-,KS#KQZX E`D!!Y-,KTX E`D!!Y-,KS#KQZX8!!Y-,KTX8!!Y-,CTXF+!!!!Y-,CTXG+!!!Y-,CTXH+!!!!Y-,CTXI+!!!Y-, #KSKQZX#8!!Y-, IQX@# 84!!Y-,F#F`#Fa#  Fab@@pE`h:-, #Id#SX<!Y-,KRX}zY-,KKTB-,B#Q@SZX TXBYY-,Eh#KQX# E d@PX|Yh`YD-,%%#>#> #eB #B#?#? #eB#B-@ρvn)trd_rorrqF@4q FpnHnniagedeH)cadaDYQ)XU*WUdUUHTF@zTFSQHQD MDLD)JHdIH*HFDdDDDDCABA*|U*{U~*zU}*yU/z_zzzz0z*U * U*U*U * U*U*U *U*UTSKRKP[%S@QZUZ[XYBKSXYKSXBY+++++++++++sst++++++st+s+++++++++t++++++++s+++st++ss   GZ`NHPUFVZpJMGT>VZKL@Z`wNPwHr2FIAA""""Xj>,v,XRr` X d x ^  t 2 ^ (@t@(Zp$Dd>Nf$Xr(b $ ^ ! !Z!Z""6""""# #F$$$%b%%%%%&&&^&&''''(*(()j))**+,8,,,---. .//(/n//00H0001 1 1111122333334 4$4:4P4j4455$5<5R5l56D6\6r66677777888.8999999:::.::::;;(;@;<<(<<h>~>>>>>>??(?4?KrKKKKLL(LNrNNNNNOO@OTOzOOP P@PXPpPPPPPPQ QQR,RRST>TNT\TjTxTTTTTTUUUVV(V@VXVpVVVVVWWW.WDWZWpWWWWWWX XXYYXYYYYZZZ["[.[~[[\\\h\\]4]<]H]T]\]d]l]t]|]]]]]]]]]]]]]]^^^^&^0^:^D^N^X^b^l^^^^^^_____&_._6_>_F_N_V_^_f_p_x___``aNabbfbcHcPcd dzee>ef2fxfgzgh h8hiiPijNjjkhklmmnnoop(pzpq>qvqr r\rs*s~st^tu(uvvw wrwxndhܶl Fvr~PfȽ<F*NV^ŽºpJĪ jż^Ƣƪ@n 6ɦtZ˦>̌&Ͷ;"*@T\0JdltϊϠϺІќ2Lf|ҐҪ&LvӆӠ.6*Xְָ֨HPX`hpx@Hض0~ڎHۺV^fd4t޲d$4N^n 4L`|.F`x,8DXl&8Lb|(:L^jv 8JZl~.FXhz $753.#"w;=M&A<",*!-$*M1,$1') 8[~C3)&  +9(3+!vo D .2$ +90U '3ݵ' H# H!@ H H MM MMMسM@ M Hس H@J H H/ 5("". 41o%%+` ?]?3?3?]]2/]]]3/]]10+++++++++++++++%4632#"&74&#"326#4632#"&74&#"326k;::;;::;N;::;;::;Z^^ZZ^^ZC66CC66OKZ^^ZZ^^ZC66CC66,*4@@4400&&%fEU@{ Huf*:J     VE&8/;p_!!!.' *ppB5p02pA&8 .'/** >t+t ?3??9/993/]3/93/]910]]]]]]]]]]]]]+]]]]]]]#&'#".54>7.54632>7267'>54&#"& W  N(2G-)'NB$4!)w 7&4 +! a?k+"I! &&) 3@'?2*&U2FU(4"7.& N.!!F40@";>-&&-F n  /9/10#.= , 21j66i31LE [ M  @L MMM@M  p /3/39/2210]+++++]+.5467>8E>II>E8>+^&aa&^E V@9 L M9 *  MMM)9  p /3/39/2210]]+++]]]++4&'7'>{>8E>II>E8>+^&aa&^#`,L@$"#,+  '.-+,,#"/2239/329/33]2292210.=3>?'.''7>7./7B9X6B3G G5B $AA% T )4>>4* R+v .@/n    r/329/3]2]103533##5#+JJPI&fr @ p  9/107'>54&'$=r@v73i.  T //103#TQ9j @ q u?9/107#"&54632! !.$$$$G(0@ M MY?3?3//+}10++#36PP4z'x@Uy%%v!!v{     c )c(#g g??]10]]]]]]]]]]]]]]]]]]4>32#".74.#"32>4(=,+>((>+,=([fT%%TffT%%TfRnBBnRRnBBnF A@#u  a   ?33/]?9/]3/310]]>73#F)&! BV-+ %'K- ,qz@ u M M @4M4%jc  c e g?32?]2/2/10]]]]]]+++]]]6323!54>54&#",;UQV*2."-6-**/;UZ*LGFIO-NChTHEI,5/*j(@P4%%%f{}c&&c*  )g#e # g  ?32?39/922/2/3/210]]]]]]]]]]]]]]]#"&'732654&+532654&#"'>3227]^%F339?E<:.&/"G#NT-u[H`oF?EEFI@965?bQ9O*ع M@ M M(M0M(M M(MM0M M M@M M@(M 'MO@Hxk\J<+i a ?  e ?3?222]]22+}]]]]]]]]+q++10++++++++++++++7>733##5#7*8<7XDDO''$ >h;GGRPZ],2j]@~]mL{c a@ Hgeg ?32?9/]2/+323/10]]]]#"&'732654&'>73^X5H*<+-0BY[jH` n^5R8GFHOE2SOO-K?)@v"";*   @6 H& 6    'c +c*g$g$g ??9/32]22/10]]]]]+]]]]]]]]]>32#".54>7"32654&\&?2!'HOKQ)>)AiM ')q1P< qcjz IwVKoF   .S?%SEKG-z%@cc  e  ??29/103>7#5!s$$M:3&0orsiZ"LC']/~-=@~4411,*v&##|#5&:) )9  9 * 6 $ %36c c?.c(c> 3%3+9g+g ??9]3/3/910]]]]]]]]]]]]]]]]]]]]]]]]]]]#".5467.54>324.'326>54&#"u9&*>/< %>,7.&0-87,K#&-'!1 #( :_#Wa%Y<-A*)@_-' H66A; 1% A4=/$9z'@'v''#{! &6v@^M M9 (    M   M:)c)%c   (g"g "g ??9/32]2/210]]]]]]+]]+]]]+]]]+]]]]]]]7>7#"&54632274654.#"W&A2#'"HQKQ)>)BlO'+G0O<qcjz IwVLoEU .S?%SEKG96f& @ H+5.O8@r/332222/10]]]]5%.-%%>AA+@  rr?2210!!!!+XXIxI.O8@}/33222/210]]]]7'7'7S%%-OAA>@".I@*  } p n#q))/0,u&t?32?9/3/3/2/10]]]]"'>32#&54>54&#"&54632+"@'-@(!%!N",! !yB+8#7/+/6# #5,&)/)-$$$$?g?N@luNvJ>c:R::k6Z6[0k00#5#E##v"7"v7DED))F=PLF F3OFIJ J8B@J(%J)./322222?222/210]]]]]]]]]]]]]]]]]]]]]%"&'#"&5463232654.#"3267#".54>32%27.=.#"^&1+QT_V*C)!?cF>fI(&Fe?.? $)M^47`JOY0P0-&+vrk}*%ngBrU00]VW\/E3iplk65eZLNRIWF@MMMMMMMMM@MMM M@MM M'R  'R  'R  L 'R'R 'RL0`p  I ?3?3?33r9/32]]9/++qr]r++ć++qr]r++10++++++++++++++++#.'##>73.+/--Z W.-/...Km-X,,X-mKfSXXT /~@T)q)))%%##w#s|mYjz$F!!F'1 D/0$ IJ,J??9/923/210]]]]]]]]]]]]]]]]3254.#"32>54&#>32#"&'>|"-%2%CG#I$-Q>%4)3B#@Y5#L)p#-  1$>Fe )C2>ORH6J/7a@?uE6F7 u  u h Y  F J J ?22?322/10]]]]]]]]]]]]]"&54>32.#"32673z%BZ5,L7$PHLV)3KaT%KGS  Z@<;{{:  F EF"D!J J??10]]]]]]]]]]]]]]#"'>324.#"32> )MmCDL&H!DmM)`.K4 5J/[aT& &TaJhBAhT 0@  D I H H??9/22/2/103!#3#3T7MKMT )@  D IH??9/22/103!#3#T7MK7 s@"H'7w6 ' IY@&MD"F!J M L J?32++?9/2/10+]]]]]]]]]4>32.#"3273#".7$C_;-J6#WL*<%ZP,6\C%[bW'KLlD  +YT ;@! D D H   ?3?39/^]]2]2103###33ZZZZKBT@ D??9/103#TZZK<&@%D J ?32?10]%#"&'732>53<)C0&F9! Z.I4G  /$TW@/  L  L D ?3??9/33?322/+}ć+}10#.'#3>77:;FD<e7=?ZZ:92"RWT$[eh,.`YL!TTMT@ DH??10%!3ZMME.-M(MMM@6MMMMM)(M(M'(M'(M'M'(MMM@\M(M0L(M M M +.'.M'"$M "D!0 D /'." ?33/22?3?32229+}]3+}]10+++++++++++++++++++++++%.'#>73>73#.'E*'$V Y./,*.-Y V `Hu`$9BZK+w66w+KZB:KX]VGTԹ @ M M @ M M سM @ M M سM @MMM0M@=MMpMPM M  DDpM8MKk{ M H?2++??3]++?+}10++++++++++++++++!.'#33=CF"TK&G@9T;;>{7K8%'|@Xx&%)%9%!&!6!u w&6:)yTEI Y IYRDF)F  (J#J ??]]10]]]]]]]]]]]]]]]]]]#".54>324.#"32>%=]??]==]??]=`$9))9$$9))9$ZQ_44_QQ_55_Q?hK**Kh??hJ))JhTV@6jYkZ usFD HJ?32?9/2]10]]]]]]]]]632+#32>54.#"TFC4U=!">W5*ZZ$"7&#25T;324.#"32>%.H0VD(I;) 8Q6=]??]=`$9))9$$9))9$ZGx\= */ F $8,9^~LQ_55_Q?hK**Kh??hJ))JhT'|@NJ#j"j  s D uuL    F)D( J%J??3?9/2322/3+}10]]]]]]]]]]632#.'+#32654.#"TFA4T32.#"#"&'76;&2)3G)(D11;)0'3M40H7><3*"$0@+*D0G53*"$/?+'F5H @D H??29/10###5ZMhMN9@$s { DD  J ??310]]]]]"&5332653aaZ.<>-Zdnw)OOQM!upL@) L L   ?22?3?39]+}ć+}103.'3>73.-,^ $%%$ [,-.KnM??MnK((@MMM@MMMMM @aL#L(#(M  L  M0#@###  *)@'((# ?3?33?33?33/33]]]]9///]+}ć+}ć+}ć+}10+++++++++>73#.'#&'3>7 !" X9&[#" "#[&9[ "! c<|38P1x>>x1RP83|<v@B   L  L ?3?3?3?32/2/+}ć+}1073#.'#>73wZ/-(Y #%&" W(,-\-aa\(GJM$$MJG'Z_`,I`@5LL    D ?3?3933?39/]33]+}ć+}10#.'3>7).0Z2.*aB##B/jml1 1nnl0OLLO7@ L H H?2?22/2/+}10!!5>7#5!JIA(.11-Zn56M7(`ghbW!M^G@n rr//9/2103#3#^ccDDG(%@Y?2?3//+}103#PP8G@n rr//9/210#53#53ccD@D8P@0vym_;K?33]3/3/332210]]]]]]]]] 'HqqI`Js//10!!wmIF #@ //]10'Yv+ %)j*Q@1   &6#Q,S+&X#!X W?32?329/2/210]]]]>32#".54>3254&#"3275&#"V:"FX$K$$?/,<#!(-*)0, " W\ (=,)=)0:. ., #M O@2{ j Y ZjzS Q W W?32?32?3]210]]]]]732654.#"5>32#"&'7 :9&!!1F,cj%HVF]l8L.K 'Ge? 0RgM@;MM M   S 0 W W ?22?32]]2/10]]+]]+++".54632&#"32676H-_`.&63 ) #5 *Id; Gbg+I4 C 0 O@1 t U e euV Q S W W ?3?32?32]]210]]]]]&#"32677#"&54>320!&9: VH%la-F0!.L8l] ?eG' 1!_@6@ +  Q U X?22??22/10]]2.#"3##46,VL D'IJ=VU]0D+m@Eu'f'U'U#e#u#  +Q-%S ,W+(( "W X?32?329/32]2/210]]]]]]]]]%#"&'7326=#"&54>32.#"32672C& @418$^W1N8%GV <7628M0H 8D v?eG% 8\h^MNH@-y   Q Q W ?2?3?32]210]]]]]37>32#4&#"NV-!:+V(7$2U?6NH >A-@ TQ/ x ??^]9/3/103#3'"&54632VV+!!!! ]D2@TQ/x W??^]9/3/10#"'732>53'"&54632L?!   V+!!!!VJ I"$]Ne@   YYQ@ H  ?3??3?39/33+22/+}ć+}10#.'#7>7*M&2.(^(,,VV)($  Hw4FKK"!HE>#<=:L &@Q   /  U ??3^]9/10.57J@V# EKq~#Nr$b@>6   Q$Q&#Q$$ $$%$   W " W?32?32???]9/2210]]]]]]>32>32#4&#"#4&#"#N#R"#9<$$;*V$2'V$2!V 2U?6NH :$6NH >NQ@ (M M (M M@ M Q Q   W?32?3]10+++++>32#4&#"#N%V$'@-V(7$V 2U?6NH >0'd@Gx%i%f!v!fviy   S)S  (W#W ??]10]]]]]]]]]]]]#".54>324.#"32>-E//F--F//E-Z $# #$ >eH((He>=fI((If=,I55I,,I44IMG M@1{ Z j jzYS Q W W??32?32]210]]]]]732>54&#"#>32#"&'!&7< VG%7O1U`$O.L8l] &GgB 0G Q@2 v e V ucV Q S W W ?32?32?]]210]]]]]]].#"327#"&54>32#0 <7&!$`U1N8%GV]l8L.K BgG& HN@ 0@? O  Q X   ??3322]]10&#"#>321 (% VK-0 @$;-@TV%$%4%D%%%y;K* K K,S$/**S  .{j'+X*' X?32?3299]]]3/3/10]]]]]]]]]]]]72654.'.54632.#"#"&'7&'" QE4$ &%QN(@3=+# #-AP E %# #/!ET GH25@)9 Q  W U?2?32]210]3#3267#"&57'! ).JIV J6+ ES`G A@)u Q Q    W ?32?3]10]]]]]%#".5332673 %)))D0V/0 V 0S?CM?~ ,#$L"MMMسMLMMгMMMMMMгM@M #M !M M M M M M @#M #M L M M M M #$L سM M M L L M #$L !M سM M @MM M M 0M ML $M "MMLLM0M(MMM@M M Y  @$M Y   / ?3?3]3?39+}++}+10++++++++++++++++++++++++++++++++++++++++++++++++++++++++++7>73#.'3 V #%&Y&%# [e(lsr/B~..~B/rsl) (*O*(@ M'M'M&@ M"M!@M!M!MMMM M@ M MM@ MMM@ M M @0M M M  L  MMM M MM @MYZ$$$ YvgV MX Z$$$0 @ P $ $$ Oo**?*)@Mo $@M$d$$ @Mo    ?33]+?3?33]q+?3?3]+3]r]]r9///rr]+}]+]]]+}ć+}r+}10++r+++++++++++++++++++++++++++++]]3#&'3>73>73#.'W7U Q R7Tg +syq((tzs''r{t((rxs+gano..onay ~@P  M      Y  Y?O_@H   ?3?3?3?32/+]+}3/+}10+#.'#>7'373%$ U53R !$%WZ[TFHH!:i..i:!GHED "@&(M0M0 MYiyC 1 $   سM@nL8 M|]mOXI6RY t S c @ 3  6RY   M$#@H X?3??39+2/9+++qqqqr+++qqq+10++]]]]]]+++7>73#"&'7326?.'30U#%%#)0!$ $ '%"[mdrIu08M/ F **4E/ppi!F 7@ Y U U ?2?22/2/+}103!5>7#5!?871275%fkg&J>,lla J%G=@! H H rrr//9/99/332210++>=463"3"&=4&'%! QM*"EE"*MQ !L?8VFC+-u))u-+CFV8?^Gn//9/103#^QQ8GD H@ H nrrr//9/99/332210++#526=47&=44! QM*"EE"*MQ ! ?8VFC+-u))u-+CFV8?xC@ HYJ9 @ H ?3/2//10+]]]]+23267#".#"'>*#;))# ;)x( /&( /&3@(M'&M& M M M@g M LkM  L M !5c2,)/3@*`**42),/ !$ /32/3299//]]3232q2222222]22/2/]2/]10++]+]++++++]+3>32.#"3#3#3267#".'#53&45<7#R &5@#2#35 | j <5( 9+F4#PLLH^8E SUB ,B^O E<^CB   "r @ p  9/107'>54&'$=r 9h1-\)  DuH@)U D % 5  Q UXX?32?329/22/10]]]].#"3##"'732654632b .)IB !VN)41QI&LUF".{U["Jr&ddj&' @%o[*@Q    /?9/329/3210#.5#535332vvJvUCDUHH%o[F@!  Q  ?/99//32329/33222210735#53533#3##.5#%vvvJvvvv2vHHH)IDA!!ADI)*E*@ M/223+/32210'7'T*ss*IE##U0f '3?K@> M> M;>K>[><@ L332!#3#3!#".73267.#"8)KjA. (AkK)`Yb cY[_U'MKM'U_8 @  n /9/10&454679$= 9h1-\)  ' @ n  /9/10'>54&'$= 9h1-\)  =f&oo'O&pp2  //]10#".54>32****a))))sQ ///10!!wQIQ ///10!!QIn4@ H@H  /3/3//10+]+#".#"'>323267 ' 2( 0303lB$,_@/$   P  .&'*+-'*, ), ?3?3?2/2/2/322]2239332310.'#>73>73#.'###5< KK <P@P8972GQT499994TQG37:8 99$;&V`@ 1/*#P0O++4*?@@$o/222]22310]]]]]'7'^BB1)=H@}u@f@z;i;f7v7f1v1z-i-#%###    euCS**DS& &J4SIUCC>X!/W9W W ?322???29/2/9/29910]]]]]]]]]]]]]]]]]]]]]%3267#"&'#".54>32632%4.#"32>7"34. -#1  =*6JC./F--F/.C/R->' $# #$  &?/E ,**,(He>=fI(.+Y$B_:  ,I55I,,I44I+:!!9+r&<D@) P!OO+++44HG "@n q u /?9/3/1074673##"&54632U 3 ]j! !TDDT$$$$Hq#\@5 z 9 9{f fQ!% S$W!#W/222/2222/9/3210]]]]]]]].#"3267#5.546753("94 ,!$.O$1 ?BO, G [a)D1 C  /BR/e,!T@0 # a 0  "g e e ??39/322]22222/]2/10]]#3!>=#5354>32.#"3S  EE/@& 5'/2/ 1t3JFIE.G0 H ;8nL'@H&&$     ")(    %/93/33/32/33/33/33/393/33/310]]]]]]47'76327'#"''7&732654&#"C;:3#*+!4:;;:3!,+#2::F*%%**%%*\>/Q2GG2Q/>=/P2EE2P-?;AA;;AA "z@ALL   !D$#   !  ??399//]32332?39/333223܇+}ć+}10%##5#535#53.'3>733#3yvVyyy\,>U    R?+\vvyyyB^BgK'SSO""OSS'KgB^^G!@n /3//3/9/32103#^QQ)h<O@f+Ii6%'E'''t#EI+ |j)J$A&@MEpC"=3p%%Q=pp--PM8M*"CC .0t-*t /32/329939932/2/2/2/999910]]]]]]]]]]]]]]]]]467.54>32.#"#"&'732654.'.7654.'.')0+9 ';1"/#)!*->%&D7;$2 #-$O$,45K5&"5$A $# '2!3I7*#7&B'$ &5/% &A" 8j( %@H@H  /22/++10"&546323"&54632J!!!!!!!!j?'?@?*?6622*)Y&&j%+%%e!$!! U Ve$i,Y*p{ y & %r*--;A4( @.1-+:7;=##?q22?q222/10]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]#".54>324.#"32>%4632.#"3267#"&0Qi::jQ00Qj::iQ0D!3254&#"'>  &!1 + 69E!+!$ / ;!- 7<* "" : ? e @H @'H     /33322223]22310]]+]]+7'7'7BB^BB^\o//10%#5!5!oJXIT//103#TQ?3G@FYFjE,EEeA$AA@W@V<<f;#;;j7,77X66(2s1|-%,%(|'r#*"4 s d R 4 D     4 I@>*H 99/CC% ?q2?q9/2]q]2]q3/3210]]]]]]]]]]]_]]]_]]]]]]]]]]]]]]]]]%.'##>32"32654&#".54>324.#"32>))B1=)'0Qi::jQ00Qj::iQ0D!324&#"326!+,!!,+!>""""},,,,  + 2@ n  rr  /33?9/3222103533##5#!!+JJXVII 2 b@?   t b T C " 2  y " !} z??323/2/10]]]]]]]]]]]]3#54>7>54&#"'>32 !1/<S*%!%A.(% , 58+-@'e%D%T%sUeD& M& M@+ L  #/*. +*(~}?32?329/92/2/3/210]q+++]]]]]]]]2654&+532>54&#"'>32#"'7o"-  .* !1!-*k ;  6" )4 *!< kF #@ //10]'7+v֐%NG <@${Q Q    W ?332???]210]%#"&'#332673 %&% &7VV/0 V  C$L?:)G#@  /3?9/10*#.54632#.0HS[r K#H tl^mo )6b q u//10#"&54632! !&$$$$6C`@"teTRbr@ H  3/9/9/32+10]]]]]]]]7#"&'732654&'>7<,$   # #&*7  6  2 +@ z @My?3+]?9/310>73# :3F"a*}! )LC P@8 # 3 +;*:%5  }z??10]]]]]]]]#"&546324&#"326CO>>OO>>OF%"!&%""% _^]`a\\aB==BA>>*? Z@4 opo  p  p  /222222]]2233310]]]]'7'%'7'^BB^BB&'oq |?55&'o|?5&&'o$q 8|?55DE".Y@6z* :   #q)n) p ))0/&u,t/32/9/3/3/]2/10]]]]]]267#".54>5<'3#"&54632+"@'-@(!%!N",c! !pB+8#8/+/7# #6,&)0*-M$$$$&$C^@ PO++4&$_@ (PO++4&$j]@ PO++4x&$v^@ 'PO++4r&$^@/P'OO+++44:%1@%X%i$$$#f!!!V @S H Hx&@, " L #%  L32)/ I#"""/ ?3?3?3339/]329+}ć+}3/10]+]+]]]]]]#.'##>7.546323.74&#"326P--+Z W+,-2##2V.." Hj-X,,X-jH "'..SXXc@4 L  D IIH H??3?299///2/2/9/23+}10!5##>7!#3#3%3e"WJQV)b-V(-Y+WJMKMmU]7C2@700r05* r iZL ZjIsUeзHS@' H2 !!/4(F32 3.+J/2 "%J!?32?3329/2/9/32+10]+]]]]]]]]]]]]]]]]#"&'732654&'>7.54>32.#"3267#(<,$   ^c%BZ5,L7$PHLV)3K1( #&*7  !aT%KGT&(CQ@  PO++4T&(J@  P O++4T&(jU@  P O++4Tr&(Q@  PO O+++44&,C@ PO++4P&,@ (PO++4&,j@ PO++4 r&,@POO+++44 $}@Oh$y#<#y<h    8 9F &D%I"JJ?32?329/322210]]]]]]]]]]]]]]]]3>32#"'#%4&#"3#326D&H!CmM**MmBDLD\gll g]|/ 'U__U'/!BTx&1v@ PO++48%&2C@ +) P*O++48%&2@ '*( P)O++48%&2j@ )+ P(O++48%x&2v@ 4( P*O++48%r&2@*< P4O(O+++444z ;@      /32292/3292210''7'77 o4oo4oo4oo4+o4oo4oo4oo48%%0@gx/:.+.5#&#HFVYJ ()  M&F2F1)(!,J   !J  ?3/3?93/393/3/+}10]]]]]]]]]]]]]7.54>327#"'.#"4'32>?4=]?,G)95=]?V9( 0 )9$-0 )9$Y0QQ_5G!\0PQ_41F~aB*Kh?^Ds)JhN&8Cv@ PO++4N&8u@ 'PO++4N&8ju@ PO++4Nr&8v@&POO+++44&<D@ ' PO++4T <@"kZkZF "D!H J?22?2210]]]]>32+#32>54.#"  4U=!">W5*ZZ$"7&#2o5T;@m6===$=3%9%$$E%55 S(S/?O.S/?O@5Q66 66? .1W:6 W ???9]2/]3/]9/10]]]]]]]]]]]]#"'732>54.'.5467>54&#"#4632%  ':'($ &$"#*-VXR&;(t/E  G4$@0 K##7" ,0$#/1AGd]'7)j &DCA@ .,P-O++4)j &D+@ &-+P,O++4)j&Dj;@ ,.P+O++4)j&Dv<@ 7+P-O++4)j&D<@-?P7O+O+++44)j&Dd<@ 0+P.O+4+44)f7GN@sNIfIvI %%*%*!! !teuVf;;>**K S>>#LS  PES# 555#O;8X @X(( UKKW HX41W5?222??329/3/?322/]2/9/2333310]]]]]]]]]]]]]2632#3267#"&'#".54>3246=4&#"'>267.'&#""34&)A-LYJ -#1  =*'; A($@/,<# (-*):1*"/+' $Dy  &?/E (>*)=)*:. I % K- #'3VHIU0CR5w@% #9#t U e rSc @$ H !''7-S !!66 6*W$2W ?3?9/]2/9/+10]]]]]]]%#"&'732654&'>7.54632&#"3267R2<,$   &5 _`.&63 ) #  #&*7  " 0FX3 Gbg+I4 1 &HCL@ %#P$O++41 &H6@  $"P#O++41&HjA@ #%P"O++41&HB@$6P.O"O+++44 & C@ PO++4> & @ PO++4& j@ PO++4& @POO+++441 -@[z,i,f*v*e'u'    #!S/(S .&X   +W ??39///]9999]9/99910]]]]]]]]]]#".54>32&''7&'774'.#"326Y#%+F3-B-1C'$ PM$=*_R$e/&4+*I_?nP.#A\9A_? =3%9$-*+-4-N83 \PxN&QvT@ PO++40 &RCT@ +) P*O++40 &RA@ *( P)O++40&RjI@ )+ P(O++40&RvJ@ 4( P*O++40&RJ@*< P4O(O+++44+_+@  r/9/]3310!!7#"&54632#"&54632+XPI    ()$.@Vi,y,w"f"('   Z   %S0S /(' *W   W ?3/3?93/39]3/3/+}10]]]]]7.54>327#"'7&#"4'32>(.-F/B,"2/-E/@+#0*# ($ M$`9=fI()8M#^7>eH(%:(.(5I,.&"4IG &XCO@  P O++4G &XR@ ) P O++4G&XjS@  P O++4G&XT@* P "O O+++44D &\&@ *%#P$O++4MIZ@9{jYk{Y  S Q W W??3?32?32]2210]]]]]]]#7>32#"&'532>54&#"VVc_U`$!&7<  K.L8l]D&\(@%7P/O#O+++44]&$a^@ PO++4)j&Da<@ +,P-O++4&$b^@ &PO++4)j&Db<@ -6P+O++4E#** M%@EM '%$$L (*$$L$$,+!+ I('''$?3?3?339/]329/+}ć+}10++#"&5467.'##>733273.",8$" W.-/_/--'+.. +& 2-X,,X-mKKm)SXX)El.;@P5$&$$$  [k{4Q&)&=/S<,<W"57X"42X& ?332?39/3222/3210]]]]]]]]]]]]#"&5467"#".54>3254&#"'>323273275&#"l",8 $?/,<#!(-*):"FX'+0, " -(-(=,)=)0:. I W\- ., #7&&~@ DPO++40R &F/@ 2PO++47&&j@ PO++40R&Fj:@  PO++47r&&c@ $PO++40R&Fc;@ %PO++47&&`@ PO++40R&F`;@  PO++4S &'`p@ $"P #O++40&GT 0&]@6d"t"U"euV Q( S'W&#W ?3?32?39/32222210]]]]]3573##"&54>325#&#"3267rVMMH%la-F0!rr!&9: N]B ?eG' `.L8l]T]&(aV@ PO++41&HaB@ "#P$O++4T&(bV@  P O++41&HbB@ $-P"O++4Tr&(cV@  P O++41&HcB@ $*P"O++4TEL@)(H D I H H  ?3?9/22/2/2/10+]#"&5467#!#3#3327",8!7'+ +& 2MKM)1E)0@Wu+te6% {l[$  .S2-S 1'1U--*XW  ?32?9/23/3/310]]]]]]]]]]]]]]]#"&5467.54632#3267327"34&l",85I-`OYJ -#1  #&+' .)*)Gc32#4&#"##?V-!:+V(7$V?N]B_2U?6NH =jx&,v@ PO++4& v@ PO++4]&,a@ PO++4& a@ PO++4&,b@ PO++4& b@ PO++4E7@(H D  ??39/2/10+]]#"&54673327",8$"Z'+ +&!;K)EZ@7|mT Q! !!/!X  x ??3^]9/2/3/10]]]]]#"&54673327"&54632",8("V'+(!!!! +&$8)Jr&,c@  PO++4N !@Q/ ??^]9/103#3VV ALT>&,-AD&LM&-jq@ mPO++4F&^j@ 8PO++4TD&.T д% P+4ND&N' д#P+4Tw&.oN _@ M M Y  Q@ H  ?3??3?39/33+22/+}2++10#.'#3>7*M&2.(^(,,VV)($  Hw4FKK"!HE> <=:D&/@ PO++4)&O@  P O++4TD&/4 P+4)D&O ش  P+4T&/@@H@ H0P+++4L-&Of@ @H @ H++1T&/B J P+4LU&OF  K@%  D       H ??99//399399222210]7373! SZd"162M<8QM^@+ Q U ?3?99//33//9/332}3}10777.=TV8!Y# J@3s/W ;2#HEKT&1@ (PO++4N &QM@ PO++4TD&1k P+4ND&Q8 P+4T&1`@ PO++4N&Q`T@ PO++45 &1D_ &Q_`@ PO++4TB E@$MD"D! J?33?3?2/+}10#"&'732>=.'#33C<   ;@B TK&G@9TVJI"4:8>{7NBC@)zQ Q  X W?32??]9/10]]]>32#"'732>54&#"#N%V$'@-H<   (7$V 2U?VJ D"TNH >8%]&2a@ () P*O++40&RaJ@ () P*O++48%&2b@ *3 P(O++40&RbJ@ *3 P(O++48%&2f@.*, P-O)O+++440&RfK@*, P-O)O+++44T&5>@ *(P)O++4NA &U#@   P O++4TD&5R ش2*P+4D@&UѶ  P+4T&5`Y@ +)P*O++4N@&U`*@  P O++4y&64@ /42.%P3O++4$; &V@ &0.*#P/O++4y&6j5@  35.%P2O++4$;&Vj@  /1*#P.O++4CyJ@gu222d2V2E22&2q0R0b0/)6$u" z {  z>1+.D8AA&GF&LGGF K.AAD;4KD!+D ??399]9/3/3/9/3210]]]]]]]]]]]]]]]]]72654.'.54>32.#"#"&'732654&'>7.'76;&2)3G)(D11;)0'';(<,$   *@7><3*"$0@+*D0G53*"$/?+#>3# #&*7   H$C;F@.t..c.4.D.T..s,,2,B,b,T+++U&e&u&"%Zj+;K { J {:-'*@3==$CS$HCCS  G*==@60Gk@DXC'@ X?32?33299]9/]3/3/9/3210]]]]]]]]]]]]]]]]]]]72654.'.54632.#"#"&'732654&'>7.'7&'" QE4$ &%66<,$   #93=+# #-AP E %# #/!9M  #&*7  GC!i@ U e u  c s R D @! H D #"H! ?39/?29/333/+10]]]]]###"&'732654&'>7##5  <,$  M  #&*7  &hMHC2+@' 'teTشH @/ H &##) -Q)) )),## ,& W *+U?2??39/]22/9/32+10+]]]]]]]]3#3267#"&'732654&'>7.57'! ',<,$  /-V J6+ E #&*7  # RM&7`8@  P O++4H5&Wn N P+44@  D   H?2?9/329/331035#5!#3###OYYYZYMMB>H2O@.: Q U W U??329/?3]222/2/10]]]3#3#3267#"&57'! ).JIV JBN6+ ES`Nx&8vv@ PO++4G&XvT@ " P O++4N]&8av@ PO++4G&XaT@  P O++4N&8bv@ PO++4G&XbT@ ! P O++4N&8dv P+44G&XdT  P+44N&8f@(POO+++44G&XfT@! P O O+++44NE&c@=${s   l[! D(D '$' J ?3?39/310]]]]]]]]]]]]#"&5467.5332653327",8_`Z.<>-Z$   .))nv)OOQM!/C0$ GE $\@:u   | [ k  "Q&Q % %#"W ?332??]210]]]]]]]%327#"&5467#".5332673'+",8)D0V/0 V.? .)-0S?CM?(&:j@ *, P )O++4)&Zj@ *,P)O++4&<jC@  PO++4D&\j'@ $&P#O++4&=@  PO++4!F &]@  PO++4r&=c;@ PO++4!F&]c@ PO++4&=`;@ PO++4!F&]`@ PO++4N>*@ Q/ X?22?^]9/102.#"#46,VL D'VU]Dy&6 <4.%P+4$D;&V 80*#P+4D&7  P+4HD2&W ߴ P+4F &@Q/ W??^]9/10#"'732>53L?!   VVJ I""]= @ n  /9/210'>54&'$<  2[+'P# *E*@ ȴM/3+22/310'7*ss*I##U2 //103#2D*g @ @  /2/10"&53326738;: :<gIB!00!BIej   //]10"&54632!!!!jHU 5 @ H H H@ H  //10++++#"&546324&#"3262##22##2-'..''..'LE(@(H 3/9/3210+#"&54673327",8&"X'+ -'!5+'JN?@/333223/]2/]]10'7'7p.`p.`)(&:C@ ,* P +O++4) &ZC@ ,*P+O++4(&:@ %+) P *O++4) &Z@ (+)P*O++4(r&:@+= P 5O )O+++44)&Z@+=P5O)O+++44&<CD@  PO++4D &\C(@ &$P%O++4#@i ?3?3//+}10#KK+h@ L M  L M Lس M L@ M ! ~}??]10++++++++4>32#".74&#"326+,,+7M//M78L//L8HAAHH@@2 M@- Mx  0L     y z?222?3]29/33210+]+3##5#5673**@*N $E:__&xTP)+e@@eVD#3EUe3$!  y ~?32?9/2/32]3/10]]]]]]]]#"&'732654&#"#>73# 0/ "'.9 r>E-# ; !)/f->)B+@8z j \ J b u D T uTdC@ M  L M  M M M@= M MM@ M} ~??9/]]2]2/]10+++++++++]+]]]]]]]]]]]]]632#"&54>7"3254&6F /<;8<:"9H&V1+/4 @<=DWT7#53C%'#2'XVOA2HZg3+$0継@HHCSzK[k{  HTdtEu@ MMMM@9M(+/?2%1( .}" ~??9]3/]3/910+++++]]]]]]]+]]]]]]]]+]]#"&547.546324&'326'>54&#" ' *3>9 <0198&\W //%&<,:)/!,::" !! +@.vTdEy K [ k  Hiy0M( L L M M @ M M( M@$ M! ~ }??9/]322/]210+++++++++]+]]]]]]>7#"&54632726754#" 9G -::7=;$:J'\  2*b-5@=:EWN@X8 rG$p ?55 |?5  |?5(?5q |?55r?5s  ?55t|?5u  ?555v ?55R( M M M@ MdUC@x Mu( M M( MziJZ M MiyZI MM" /?*n)% t ?323/3?9999]222]2/10++]]]++]]]]]+++]]+]]]++++327#"&='74>32>54&#"DL? % 3$F=7(_) + * gbIv'.?ZH4-\b/>$,:9{P*/,-Ac!34@ 3!5-4000' ?2/?9/]23/310"32673#".54>32'4'.#"3!25 0|IO09ER\0Sl??lSSm? 0|HH|0Q 38A6 3$9aKKb99bK 06:0 &'o6?53&'o.M?5&'ou |?5550&'o&u =|?5555&r'o'u /|?555U&tA'ou |?555&'or|?53&'o3r@ ##*|?5^]^100&'o)r7|?5*&q'o)r|?5&'os |?555&r'o3s@ ""/|?55^]^10&'o t|?53&'o)t%|?50&'o)t2|?5*&q'o)t|?55&r'o)t$|?5&&s 'o't"|?5&'ov "|?553&'o0v 9|?55*&q'o.v )|?555&r'o+v 8|?55P&t<'o v '|?55,&u'o/v I|?55',u@L,,v(e( 9 I Y ;*  u d dt#p.+p-#&tt t?32?9/322/210]]]]]]]]]]]]]632#"&54632.#"2>7.#"P26EX30N:TUcW4$5$)o!- ,+ =fIXqAup6Y>" ?_n0$73!.-.2Z1., $('#jSSjE!dWWdT@n nr?3?10###ZZ,"yZ@0 L   L  H H ?2?29/32/2/9/+}ć+}10!!5>7.'5!u#L-.Q" #R0+T#egRLRVN323#5>54.2 6(>.q$#@Z76Z@#$q''7x=aDc=;LBNZ0O{S++S{O0ZNBL;GPY1Da=+P //10!!+XPIo9g~@ (M@>L 'R v'Rv ?3?339/33/399//++q++q10+q+73#.''Ul  Ck%BU0UQN( +7@W444000k&J&Z&;&*&" HvdEUvTdE 22$9,$8 5) //3/23/29/9910]]]]]]+]]]]]]]]]4&#"326'>32#"&'#".54>323267.#"[ *($$(**($$(*v +*("00"(w' !6**6! '' !6**6! 'g*("00"(G@n tt//9/107#"&'53265463:#"MO+%MN +*XiJ<9@XhJ<9&aga+0$]@-       @ /3/22/3/]2222/22/}10373#3#'7#537#+,F"Rn.-E"Qm-tZIxIv\Ix+ ?@t   /33?22/2/2/10]]5% !!+1""X)HCCAI+ ?@{   /33?2/2/22/10]]7'-7!!R""1XCCHI w@MMM M MM@M;K4DM@M (L/3+?3++/]]10+++++++>73#.7.'>)Z1 1Z))Z1 0]5445[[[\[[\\[7j55j77k55kNp&II2N"O@0*  TQ$ Q #x  U X?????]22/2/10]]2&#"3##46#3'"&54632&$'VL2VV+!!!!D /:IJ=VU] ]NN l@F* yjYJ;, Q  Q  UX  X ??3?32??]22/10]]]]]]]]].572&#"3##46J@V#&$'VL EKq~#D /:IJ=VU]NN '2INE&I21wT L# B1r X)x(i<p 6 <<6q6r=s6t<u<vpV  U UV qU rVsV tUuVvVs)?/]10#59]D@  9/103#"&'53265J<, 2 ?64(Ua @  /9/]210#&454>7S &$  a $5$- #sF//]10#59Lt@ /t@ /1.v(>/? #D^v>>/v(>?/v>@/%v>^/v>`/}7m>2s5s~t-5~u-*}7y>H}}7>*}7>E&i@@y"j"Y"k{Z  Q (Q 'W &$W?32?32?39/32]32310]]]]]]]3#>32#"&'#535732654.#"!1F,cj%H>>V :9&!B` 'Ge? [BN>]l8L. /9@^9|96{6" * | k Y j{7F F ;,4D(:I44J(%3) 0J?2/22?329/923/210]]]]]]]]]]]]]]]]]]32>54&#%.54>32#"&'7*3254&%2%CG4O^*.WC(4)3B#@Y5#L)& >|GF 1$>F:A!*E3>ORH6J/\ '#{p?3T]@:\KZKd  d t  eF  DHJH??329/22/10]]]]]]]]]!#32#"'732>54&+T7+6X?#">V4EFZ3$PG%M5U<;T5A!6)O@M T@5zYiZjzS  "Q !UW W?32?32?]22/10]]]]>32#"&'!32654.#"!1F,cj%H :9&! 'Ge? J]l8L.!U@4Zj[ks sS#Q "W !W?32?32?2]210]]]]]>32#"&''>732654.#"!1F,cj%H=!I) :9&!  'Ge? jL$ >]l8L. Z@8[kZjtF"D  ! HJ ?32?9/2]210]]]]]]32#"''>732>54.++6X?#"=W4DG=!L*3%'8#%5U<;T5"L$ !6)(6"Y@9{;):) ~ 9EUF  J  J?22?322/10]]]]]]]]]]]2#"&'732654&#"'>v(D[4*J4#SJIS'2IŲcV'GG7+*f@@))r)5#E#"D7  Yi (,!F+JJ '$J( ?22?32223/310]]]]]]]]]]"&54>32>32.#".#"32673z%B\8$:0   =#SJLV)3KcV'-*H& G0u+]@8u#f#fv   )- S ,W (%W) ?22?3222]2/310]]]]]]]]".5463:>32.#"&#"32676H+]` =2    (61 ) "4 *Id;3)C& bg+I4 C  A,j@Cz+;+x*:%z%F8)(F. D- J #J?22?22/210]]]]]]]]_]_]]]]"'.54>32*32>54.DL&E5Qa+GqN)(KmS   7K.1QX '# :A!&Ta_U'tChHIhB,U@6EUDTi ykiy DFH HJ??9/2/210]]]]]]]%#".54>;5#5!#"327GD6W32&#"32670H%la-F0!!&9: J ?eG' K.L8l]1G(8@]&&&"""iy% 5 E   UE6V%,)S/S:)S 9,,4W$X ?32?93]2/3/9910]]]]]]]]]]]]]]#"&'732654&'.54>32>54.#"<<# 0?"#I B (0(B8%-F00F-8(0. %$ 0Vy) # - F1FaB.TA''AT.Me$gE!9++9-t 0@D  IH H??9/2/2/2103535#535#5!-7MKMK7&m@FxkM] TCEU y j :(!F("F '!HJ J ?32?9/2/210]]]]]]]]]]]]]<7!.#"'632#".2>7#7G$=0!5>TF_;vc8O1, +97^E'G,4_O.Uz$>U10U?$1,@ ''u@GIru q :)  ".FF(-I!J"% J ?32?329/93/22/2/10]]]]]]]]]]+]]].54>32.#";#"3267#"&54>),0C)&I967DN NTL=<D(mm&tO9(C.H=06BGL;CFFqb8.#FI@*UD2#D IHJ/32?9/22/10]]]]]]#"'732>5!#3#F>"  7VJ I"MK71-h@?J++&6w5&$D %/F.$$#!J&) J ?3222?329/3/310]]]]]]]]]4>32632&#".#"3273#".7&Ec=#W  8'\P*<%ZP,6\C%[bW'XH ! LlD  +YH+@Xf$4i*:)F L L  F @PO_ - ,#  J/?39333?399//]]9+}ć+}10]]]]".54>733'2654./ , ZZ ,   (/+7M;r;M7+/(J% #..# %N!f@B; *   Q!!Q# Q "W W   ??3?32??]29/10]]]]]]]]4&#"#7>3232653#"&5I*8%VV-";,'-.'VUU6MI =2U?1992`VaT."@: J DJ ??32/10]33267#"&5TZC  ,J?\F XR  +@D    ??9/329/3210333### XZXXZX*BIT#n@<#!#L#L%!D$! J?3322?3??9/3322/3]+}+}10>32&#"#.'#3>L70  K&FD<e7=?ZZ3Qg0$A ,l3[fh,.`YLCvN"q@A H  Y"Y""$Q #"W  ?3??32?39/33]32/+}ć+}10+#.'#4632&#">7*M&2.(^(,,VH<  )($  Hw4FKK"!HE>hVJ I#4<=: 8@0 H Q X ?3?9/329/3210+373#.=# ?VDD# J@?G?#HEK)@oE4F 5 $   l_{'!!Y"'""'Y"+"*())'!)) "!  W ??3?39/9333/993992/93/+}ć+}3/10]]]_]_]]]]]]]]]7.#"'>327#.'#>7'1W'  ;BQN&((X  W')*Zg"L17?/Z.prk).kol0F~64T$N@-u D"D&D%#J " J ?32?32?339/3310]]]]%#"&'#".53327&533273'Z%%=J&%@/Z"2(Z-4$"Z0Q=+7 *EN?gFZ@+ LDD ZKJ @ HU?2]+/?3]]?]+}]]10!.'#"'732>533=CF"E<"  K&G@9T;;VJ I">{7KNI:@$ z  Q Q  W?32??]10]]]>32#4&#"#N%V$'@-V(7$V 2U? NH >8%)|@T()(9(y'v"!!&!6!wyTBJ Z YJDT%F+$F *$$$JJ ??9/]2210]]]]]]]]]]]]]]]]]#".54>322>7!"!.%=]??]==]??]='6$$8&&7%,$7ZQ_44_QQ_55_$A\99\A$6$B\88\B$87! 4@Zx32)292.6.'.v-v)(&(6($*$:$X J  [JUFD!F6+F 5&J0J ??333310]]]]]]]]]]]]]]]]]]]#".54>32>54&'34.#"32>%=]??]==]?Y;V$"`$9))9$$9))9$ZQ_44_QQ_563  0Z$0}L?hK**Kh??hJ))Jh0y 4x@Qi2y2f.v.u(f(i$y$  !S6+S  5&W0W ??33]3310]]]]]]]]]]]]#".54>32>54&'34.#"32>-E//F--F/C- R" Z $# #$ >eH((He>=fI(+/  /W$"U2,I55I,,I44I8$8@U)696&2626,',9(((yK JF,M(M""F%% D:/F 9J"*J4M4J ?+?33??9/2310++]]]]]]]]]]]]]#".54>32>32#4&#"4.#"32>;[>>[<<[>M6%K$)C/Z,5.`"7('8##8'(7"ZQ_44_QQ_5*8\D+]M 0Q?hK**Kh??hJ))Jh0I`$8@_z6i6u2g2u,g,{(j(3%   x""S%% Q:/S 9"W*W4W ???32?9/2310]]]]]]]]]]]]]]]]]#".54>32>32#4&#"4.#"32>-E//F--F/C,9"!8'V ,!Z $# #$ >eH((He>=fI(*2U? NH #X4,I55I,,I44I+\@8j*Y*j$[$ts) 'F-!D ,H!! J??239/210]]]]]]]]]3.54>32+*32>54.&E5P_+5W="">W5*(  $"7&&4a'# :A!5T;32#"&'532>54&#"VH<  c_U`$!&7< VJ I#4R K.L8l]T*{I&Y&@BMVfEcdL#F, D+I(J ??9/23/3229/Ƈ+}10]]]]]]+]+#36232#.'32654.#""XX  4T7>54&#"'>32"6I-2I0)3' 5-6J+)C0*3&8>H3G*&>2' $+35G0D*)?1&"*3<2/v@K++%5!$!!!i ; K *   S##1-S  0+(;( ((XX ?32?3929]]2/2/10]]]]]]]]]]]]7267#"&54>7>54&#"'>323@(NQ ')#1!8(##+=G TE!/" !' F %6!-# #+Z@0 L   L  H H ?2?29/32/2/9/+}ć+}10!!5>7.'5!#L+.Q"#Q0+R$egD?EHN3226754&#"KC7: .E<# EK SA!7(UBd# F#$1!&/HE&$Y@6 !!, E4%Q  &Q"" ""%%#$ W U??2?3/]2/2/10]]]]]3#3267#"&'732654&5.57'!!  0'  $IFV J6+ -+E1D-2Q` '@ FD H??29/10###".54>3Z4$H(2Mh)   &5 H8 U@5:JJ;*  "Q !X W U??32?32]22/2/10]]]]]3#3267#"&54632.#"'! ).JILM, J6+ ES`U] D'F,@j DH J /32?29/10]#327#"&5#5  ?IM~"DJVMNC! C@) z t  D"D!  J ??310]]]]]]"&53326532654&'3aaZ.<>-:R *dnw)OOQM%!   .'dupGy$E@+u !Q &Q %$W ??3]10]]]]]#".53326732654&' ) %)))D0V/0 5y  .'E 0S?CM?"$ 21-h@>,5,&,v+IEy*: F / $$)F!!.$$ H #J ??32232/2/32/2/310]]]]]]]]]%2>54&'53##".54>7#531 6(>.q$#@Z76Z@#$q''6==aDc=;LBNZ0PzS++SzP0ZNBL;GPY1Da=NI@.DvYiK9 u F!D J J ???9/10]]]]]]]"&5332654.+'6232e^Z27E9-% 7I+3Uju KJ:aF&Q1Y}LJf<"[@1  L  L D#$ J ?2222??39339/2݇+}ć+}102.#"#.'3>7>.   Z2.*aB# 5B 2NEC( 1nnl0OL19F3*0D0`@3"%"%Y+2"Y 1,/X+%("X ?32?3933?3322/2/+}2+}10#"&'732>?.'3>7>32.#"U   '0 %  %$![ # ?+2 (;ja\-7L0 F %4|E.lmf)8a6/ >x@<       L   HI H ?2?9/3222/2/2/+}99993/103#!!5>7#53>7#5!> i!:=#Po<Zn-v@BG2M79JB@s*M!F s@9       Y   U U ?2?9/3222/2/2/+}9993/103#3!5>7#53>7#5!?-Ee) *2R* Q->/W!J>&_0>,KJp"@Q} l [ ziZ& r F  wIZjF $ ""#"J J H?2?329/32/2/33/3]10]]]]]]]]]]]]]]]>7#5!#"&'732>54&+k&F 7!G'LX7Q4$E>-"PA9rE$4Q7WM'H 7 G&MGE!2! J  8L+Ul;w?2M7>54&'5>7#5!$0"C@ <%?"3&*4" $ + #317%Q+J90[*&7%(9' +u$a@6$4F  &F% HH$!J?32?9/32]2/2/2/2/999910]]6323#3!54>7#53>54#"+=XSY9o& (cW1;YV&E L6;A%N4UI>L B'dtk@Am\Ji[t u&F!D HJJ ?32?9/22/3/]323/10]]]]]]]]]]#"&'732654&'>7#5!he!;P.!C27#5!KZ1D'8)%9QAE3? QG)>*H -.04:V/KJ-D'f@?4%5S)Q $$  (YJ!UvX! ?3?9/9]9]]]2/23/10]]]]]]72654.'.573##"&'7&'#V %QN(@3=+# '4$J)$ "/!ET GNG >@% |kS Q XW?3/?32]210]]]4&#">7#>32B9/$;)Z(DZ2VI&+H3,LQ ^1@S6HpU>;W^G_^Ga'__*GD@    ??99//32329/332222107#535#5333#3##QQDpDdDpDH #@n qu ??9/3/10#.=3#"&54632 3 ]! !TDDTy$$$$S&''=@`{S&'']@`V0(&G']`T&/-TDR&/MVD&O MT&1-DTD&1MDND&QM&$`]@ PO++4)j&D`?@ .,P-O++4&,`@ PO++4& `@ PO++48%&2`@ +) P*O++40&R`K@ +) P*O++4N&8`u@ PO++4G&X`T@  P O++4N&8u@*P"OO++4+444G(&XT@. P &O O++4+444N&8u@$P"OOO++++444Gn&XS@* P /O "O O++++444N&8v@&P,OOO++++444GO&XT@* P 0O "O O++++444N&8t!@*P"OOO++++444Gn&XT@$ P 0O "O O++++4441#e@@#)9 {j S%!S $U X W ?32?9/]2/210]]]]]]]]]].#"'>32#"&5<7267#+ -#1  =*7K..A'YJ+'!%@/E (Hd@1CP;O/O++4+444&$_@ '(PO+4+44)j(&D?@ 78P+O+4+44c& @ QP O++4)f&@ OP"PQO++47 (@W"""u"&"6"!w&6tJJ ((('D*F)J(&$J ?32?399//32223/2]10]]]]]]]]]]]3533##".54>32.#"3275#TZEEP,6\C%$C_;-J6#WL*<%T LLB +Y^bW'KLlD 0D"3y@Gt-e-V-t)e)V) 332$Q5+S 42$$1.W4%(W" X ?32?323/329/32]2/222]10]]]]]]]]3##"&'7326=#"&54>3235.#"32675#??2C& @418$^W1N8%GQ <762Q9B8M0H 8D v?eG% Ǝ\h^M7&*`@ ,$"P#O++40D&J`M@ /-P.O++4T&.`p@  PO++4.&N@ PO++48E%%9@yy8887)7&363v2u.5--&-)9)*)y(T#E#IYv{l[UDUC &F;0F: :+J!5J ?3?229/310]]]]]]]]]]]]]]]]]]]]]]]]]]]327#"&547.54>324.#"32>%*$",8(>Z;=]??]=`$9))9$$9))9$ZEgM6? .(/(6^PQ_55_Q?hK**Kh??hJ))Jh0E%9@gi7y7f3v3u-f-i)y)###  |k\V &S;0S : :+W!5W ??22]9/310]]]]]]]]]]]]]]]]]]]327#"&547.54>324.#"32>&  ",8$*=)-F//E-Z $# #$ ;S:) ? /*/',Ga:=fI((If=,I55I,,I44I8E%]&Pa@ :;P 325>54.#"Z'U0ir/Qn?*K7!"0%'GRlU![?RgB3I-T&1C@ PO++4N &QCU@ PO++4%)5@ydtCS4# H/ *0&((00 " L%#   L76&@)(''-3 I#""3 ?3?3?3339/322/9+}ć+}3/2/10]]+]]]]]]]]]#.'##>7.546323.'74&#"326P--+Z W+,-2##2V..7 " Hj-X,,X-jH "'..SXX92N)j}&D@@ -+P+444&@ P O++4)f &@ 5QO"PPO++48%&@ '31P 2O++4( &A@ 1/ P 0O++4&$6@ "P!OO+++44j&D@ 2,P1O-O+++44&$^@ &PO++4)j&D<@ 6-P.O++4B&(9@  POO+++44.&H%@ )#P(O$O+++44T&(V@  PO++41&HA@ -$P%O++4&,@ P OO+++44& @ P OO+++44&,@ PO++4& @ PO++48%&2w@ /) P.O*O+++440&R,@ /) P.O*O+++448%&2@ 3* P+O++40&RL@ 3* P+O++4;&52@ /)P.O*O+++44@&U @  P O O+++44T&5^@ 3*P+O++4N@&U)@  P O++4N&8L@ POO+++446&X-@  P O O+++44N&8u@ PO++4G&XT@ ! P O++4 Iz*@W*u*)&Zjn\l[=.DCtF((F, +J#I # J /?39/922/2/3/210]]]]]]]]]]]]]]]]]#*/32654&+532654&#"'>323A0X}N s[J&#EN<71C#0L510lJIkF"QagQRKTK9L H8N.?g JB0w@K4,,&,,'{{JeVS..S2 &1%"W)U&) X ??39/922/2/]3/210]]]]]]]]]]]]]7+'232>54.+532654&#"'>32'-Mg; (F5!,62+'0?&%=+, "-58S6I$8' 1!GC9)5 E-=%4TT&+`@  PO++4.&K@  PO++4TG1@[ k u D D J?32/?10]]]>32#4&#"#T,e*.K5Z5G,Z?hLgbf 1D3#1=@ju-d-V-v(U(e( U F 4   % $4UD ;#1Q5?+S >$&W# 421.W8 ?3?33/3/222/32?32]223310]]]]]]]]]]]]]]]]]7632#"&''75#"&54>32&#"3267"32654&1V$(0"$>00O  la-F0!!&9: J'43*$#J!?eG' K.L8l] -)0'*'./;r@F31z$$$ujk ed85F9 F=,/F+((%F"<%%J228+J??39/9323/3223/3210]]]]]]]]]]"32>54&7#".5467.5467332654&'3 8H#./#H#%'7R67S7:1%# Q 0440 T QAB"1!!1"BA=V $09,L77L,=dV=-?$#F#CGGC#F#$?2 9@X00z0,,u,y utz63S7 S;&)S%""S:W..6% W ??39/993/3223/32210]]]]]]]]]]]]]]]]]%4&#"326#".5467.5467332>54&'3P4..44..4?%&72E()E27&%U  U[PP[[PPAPiU?]>=]?UiPA*Q*#G#,;##;,#G#*QE#D@$V D  L%!!$ H# H?2?22/އ+}3/10]!#"&'7326=!5>7#5!JIA 0'  $(.11-Zn56M+E1D-27(`ghbW!M!EF !D@$T QY#"U! U ?2?22/އ+}3/10]3#"&'7326=#5>7#5!?871 0'  $275%fkg&J+E1D-2>,lla Jt&$c`@ #PO++4)j&Dc<@ -3P+O++4TC%@$udUscT@+ H !!$'#D&"I#H#H %?39/?9/22/2/9/32+10]]]]]]]]]]!#"&'732654&'>7#!#3#3# <,$  7  #&*7  &MKM1C3:@Ju55.5.&...,'' '&ubUqSceu@. H %""*8S0 0<7S*;"" ;U774X-W% ?332?9/9/22/9/32+10]]]]]]]]]]]]]]]]]]]]73267#"&'732654&'>7.54632'"34& -#1  6$<,$   *9$`OYJ+'&?/E #&*7  "-E[6y  VHIU8%&2@.@ P8O,O++4+4440(&RK@.@ P8O,O++4+4448%/C@yBA9A*A5==&=v<w87&767*3:33y2V-E-Z)M)I#Y#TF HteTE@O&0FE:F&D 5J+?J! ??2/3/9/3/]10]]]]]+]]]]]]]]]]]]]]]]]]]]3##".#"'>323267#".54>324.#"32> ' 2( =]??]==]??]=`$9))9$$9))9$B=0303Q_44_QQ_55_Q?hK**Kh??hJ))Jh07/C@@zAiAf=v=v7g7j3z3--- ))) ###HI:@8 H@?O0@&0SE:S &&D 5W+?W! ??2/3/]9/]3/]10+]]+]]]]]]]]]]]]3##".#"'>323267#".54>324.#"32>} ' 2( i-E//F--F//E-Z $# #$ 7B=0303=>eH((He>=fI((If=,I55I,,I44I8%&2c@ *0 P(O++40&RcK@ *0 P(O++48%&2@ 45 P(O+4+440(&RL@ 45 P(O+4+44^&<F@  PO++4D&\+@ #$P%O++4DQ w@KJ9, E U 4  %  TC%5Q!  ?3/32293?32210]]]]]]]]]]]]]]7632#"&''77"32654&$(0"&?30UV5R'43*'&P!! -)0'*'.NDF#/@  H H@9 H%5- Q& 1"Q## ##0# $ &$*W??3/32299?]22210]]+++]]>32632#"&''74&#"#%"32654&N%V$'@-$(0"&?30U(7$V 2U?'43*'&P!FNH >) -)0'*'.DQ$m H H@1 H"Q %U  ?3/39999?3?]2233/310+++7632#"&''773#"32654&$(0"&?30UV5R'43*'&P!Jf -)0'*'.0,:@[T6d6t6d1t1V1z(z#      Q::%S <4S;,--*/W::"7W  ?3?33223?3332239/32910]]]]]]]]]]]]]]7>32#"&'#"&54>3232654.#"#&#"3267/T!1E,ci00ka-E0!T :9&!T!&9:  'Ge?  ?eG' =]l8L..L8l]0I,:@\z6z1v(U(e(s#U#e#   -Q, 4S<%S ;:7"W /-,*W ??333222?332239/3210]]]]]]]]]]]]]]]]#5#".54632>32#"&'.#"327332>54&#"T!1E,ci00ka-E0!T :9&!T!&9:  'Ge?  ?eG' ]l8L..L8l]$#((سM'@-M&M& M&M%M$ M# M# L"M MMMM MMMس MȳM@ MMMM سM @4 M M M (M MM MM' M'0M}'MMгM гM @u M'#("?$$  L  != ,  L  *)I($"!!    ?33/3?33333/39/333222?32/9+}qqć+}q3/]}10+++++]++++++++++++++++++++++++++++++++++##>737#.'#3.'<8 W.-/T$44$##Z j>;.83:7.'3267#"'#"79%BZ5 7& }-)3K10(/tPHQl)~aT%V T K G]Jp&0Rj&@G#(#X#  $# ( S 0'#W $W  ?3/33322?3223333/3]3/2/3/}10]7.54637&'3267#"'( _b/  B#5 / Qԕ#TM$G;>@]++s%d%%%U%%%Jz;) 00$S$@';;S  ?-X3{j)'<X;' X?32?3299]]]?]3/33/3/10]]]]]]]]]]]]72654.'.54632.#"#327#".'.'7&'" QE4$ &%PQ "  '! (3=+# #-AP E %# #/!ET F! ?G!Cn "X@6+;{vY   $#U" X U?2??22/2/+}10]]]]]7>7#5!327#".+!275:93#."  #0% '4&>,lla J@$hol)"'*"D*1* b]@=wS&6e| FD   J ?32?9/10]]]]]]]]]]]]]74>54&#"'>32#d$*$=289I)*I6%*%Z7K6))2$-4"G+B,-@1*1=,)!C@)veep6%S Q!!#"!  W?32?9/10]]]]]]]74>7>54&#"'>32#W   /*-32#"&'5#73#32>54&#'3254.#"D#I$-Q>%4)3B#@Y5#L)Dgg%2%CGH>|"- )C2>ORH6J/`BX 1$>FHp#-  \@6t{  D  D IJ ?3?9/3322222210]]]]]]]]33333##"&=#26=# DZZDDdcaaD>-.BupnwQM{{OO@ LMMM@IM  L  L 0 ?3?3?33q9/+}qrqr+}qrqr10+++++#.'#>7).-,^ $%%$ [,-.KmM??MmKT@_0 M( MXy  M M  /  D? I H H?33/2?3/39/32]2/]2]2/2/9910++]]]++7#!73#3#37#37#{E6h+AJ#c@KMffEKMu1g!).3@_#g*:  .-  !23&'  *S5%/S!4!! 3U.&&2W -'"X  ?3/3322?239/32333/32/22/3/9910]]]]]]7.546327#3267#"&'"37.4&'7n-&`O+/(''1  =*$G+'@&D o EY!|RP Tx[  E O!VH(?{F"9rB@$ %  DJ ??329/322210]]]]333##"&'732>=#bZDD)C0&F9! b+B.I4G  /$F$B@!"TQ &%x W ?32?9/329/323/103##"'732>5#5353'"&54632??L?!   UUV+!!!!4BVJ I"B]8F 4@Yx32)22..5.'.(5((&($$:$($EI x 6J!FD6+F5J&J 0J ?2?/10]]]]]]]]]]]]]]]]]]]]%#".54>32327#"&54.#"32>M5?]==]??]=  ">F$9))9$$9))9$Q.24_QQ_55_Q"I JVt?hK**Kh??hJ))Jh0F*R@2u&V&f&d!t!U! *Q,#S +W W *(W ?32?32?32]210]]]]]%#"&54>32327#"&5.#"3270$`U1N8%G   =E <7&! BgG& "I JV]l8L.,@Q~(I(Y(k'h#~"l"Z"I"  L%F.D- H,*J?32?3?9/3222322/2/+}10]]]]]]]]]]]632#.'+##5;2>54.#"UFC4U=!60 #&$ Z ##*ZDDZ$"7&#24R:K]CPW'JJD O!5&'5@>@! Q     X ??33229/32]3210&#"3##5#535>321 (% ssV??K-0 BB$@T! R  R "RR  L   DL%&"!  ?3?3?9/9333332229/݇+}·+}++++103.'33>733##.'#>7#: a  ^ :V-Z/U  ` (M#$M''M$#M(B4e0 0i6q99D '.@P  + ( ,(&#( ( Y   0(Y##/#,+& (##X ?3?3?9/933333222/2/+}3/2/+}103.'33>733##"&'7326?.'#>7#8  [ s  U  8G$78A-$   $ -G  X N0`/+a3.^31_/8o2 F**;P*T+0V DM"@Q { z 6 %  V f jYzS $u  #!X WU?2?329/32/2/]3]3/3]]10]]]]]]]]]]]]7>7#5!#"&'732>54&+O&F"H)RV7O1 80-"LE9q=J2Bw=iU/L6 J !4$?F*l @   y?3/102#.#"#467<: :;IB!00!BI J00@/32/3]]2]2]210/'`.pK`.p)DA}K@ H  H H@ H  @ /2//3/10++++'7#"&546324&#"3262##22##2-692N'..''..'P$(5@H@H   /32/3/+2/+103#"&546323"&546322(B2O( ! @ H  //+3/10"&54632'3#!!!!OBP$n ; @H @H@ /322//++3/3210"&54632#"&54632'_+nP"~P$n = @H@H@  /222//++3/3210"&546323"&546327'7Jn+_P~"P$O G@  @H@H  /222/223/++9/32210"&546323"&54632''7J vvWP*__*<U7h@AHX HUeu@ /3/3//3/10]]]]]+]]]]+3##".#"'>3232672 ' 2( 7B=0303D6@//10'7o92N';!@ /223/32210'7'G vvW;*__*<'3!@ /223/32210'7 vvW*__*<YO@M``@H@H  /33/322/++3/]3]210+'"&546323"&54632r_+n#"~Y2@ @ /33/322/3/3210'7"&54632!"&54632n+_]~"Y G@#  /223/]223/33/]2]210"&546323"&54632''7H vvW*__*<T&(CZ@  PO++4Tr&(Q@  PO O+++44  c@=Yis%  /  HI F"D!H J J ???9/32239/+]10^]]]]]#632#"'7232654.#"##5()^o\N-/!,'ZM vmboL=E*9# hMT&H@ !PO++47h@Ar6  p YiLL  FH J J ?22?329/]22/2/10]]]]]]]]]]"&54>32.#"3#32673z%BZ5,L7$IILR)3KaT%KptMGy6T, r&,@POO+++44<-  #1@^j.[.J.Y(i(H(vzi X   { %5E1D#D## +F3 21H$&J" H H ???329/99//210]]]]]]]]]]]]]]]]]#'>7>=!32#"'32>54.+ cL +<C+6X?#"=W4DGZ3%'8#%i2lom2UWM0<*ahn7g5U<;T5_!6)(6"T#s@J\!I!kJZ v   vDF%D$#HJ ??32??9/3229/3210]]]]]]]]]]332#"'##3332>54&+Z+6X?#"=W4DGZZZ3%PG%4T<;S4Q !5)N>N@.is    D DHJ ?3?9/322]310]]]]#>32#54&#"##53%B2V1C#,ZM2O9KI hMT&.l@   PO++4T&C@ PO++4~&[@ & P"O++4TG ,@ DD D  H?3?39/105#333#ZZgK$TT%T@ DH??10#!Z.hMG'G@)D DDF DH H?222?]]9/105!#3>=!33V='@B#5乹2x]5!kT( y1@Y L  L  $$*/*L)$))$$$LD/3))20/ $$*)?3?3??3?39/33333?2/2/9/3223+}ć+}ć+}ć+}10>73#.'##>7.'33k.,'Z+//75-_(-1S2.)\-581.)Z (,.S!TTM!SVT$Xdi02aWIMIWa2/idW)WUO MTT!2.@a..u.****u**)t)%l[Zj   srF,,F0$$ /# J'I$' J  ?32?39/922/2/3/210]]]]]]]]]]]]]]]]]]#"&'732>54&+532654&#"'>32 2A":O-'J< /#SD009J90 <K&)D1/tYC5O4H!4$@GG;=67 F.C(4RT]@)JZ M DD  l  @ Ise?2/3]]+]??3]]?+}]1033>73#TT4|RGT"FC=yK;;T~&@ PO++4T. M@1YyzkD 5 $ DDHH ???9/10]]]]]]]]###'>7>=Z  cL +<Ki-3jif.UWM0<*`eg0yE0T+8%2T@D DH?3?10###ZZKhT37&7h@AtLL / J??39]?32/9+}ć+}10]]]#"&'7326?&'3>7UB N@ "  %( =[ZD*$;aUKL1+_UkkU-a;TG ,@D  D D  H?2?3]105!3333ZZBh8?@&fv D D J ??39/32210]]]]!5#".=33273Q3&A2V1C#,Z.L9EE oKT -@DD D H?2?3?9/10333333TZZZhhKTG:@ D D  DD   H?22?3?]9/105!333333ZZZBhh K@/ZjjYsvF!D  H HJ ??9/210]]]]]]2#"'#5332>54.+6X?#"=W4DG3%'8#%5U<;T5_L!6)(6"T",TT@7ZjiZ    v FDHJ ??9/]210]]]]]]]]]32#"'32>54.++6X?#"=W4DGZ3%'8#%5U<;T5!6)(6"v@KEF:xx ;)z F  J H J ?22?39/22/2/210]]]]]]]]]]]]]]]"&'73267#53.#"'>321K3)QLJJ;H,4ZB&GMwmI%TaT.@jx-,),,((&(w'""&")xF5K:; J;5EF0%F  D / J H  *J ???9/]?2210]]]]]]]]]]]]]]]]]]]]]]]#".'##33>324.#"32>;Z>;Y; uZZw";U9>Z;`"7('8##8'(7"[Q_40X|KFqP,4_Q?hJ))Jh??hJ))Jh'k@B]KK[kJZ   L  'D) #F(I''J ??3?9/223/29+}10]]]]]]!##"&'#>7.54>32&#";X"$$! Z %'$ .6!32#".54>7>7"32654& 4NZWZ5F* FNN!"?8.0,)9)**@7# ux0VyH#JIF ;A! M * $xQcSYN ,Z@74%(SS.$Q   -U$$#!XX ?32?329/9]23/210]]]]732654&#"&'>32"32654.!!*:75.RO.!?0& %23F09-0!'13&  "9(*9B-.=$"/!N= "@Q U ??]10##3=V=  o E@(Q@ H Q QS  Q U U??222]3/+1073>7!3#5!#3 5@TT F*bpJ9בT6f^Y*}1H ,@[  YY**%Y,*,,*Q$*%*Y$$,.,,%-..%$ **   ,?2??3?3?9/33333?3]2/2/9/3+}2+}ć+}ć+}1053>73#.'#5#>7&'j !"O"! P#A!,(# T "%%O&&" Q "(,AD :<<<<:Hv4FKL" HE==EH !KKEfH,c@;5)$)))3$S**S.$$ -# W'U$' W  ?32?39/922/]2/3/210]]]]]]]#"&'732>54.+532654&#"'>32'4_L"B< "-";8/ 0+=N`@&Z  Q Q  $  Y  I @Ir d    ??3]_]++]??3]]+}10##3>7Q43-DP021|'dhc&)_]U N&Z@  PO++4N  =@% ; VfvEQ Q U U ???9/10]]]]!#'>7>=!MlL9 +-5`655M+"-TnI (e@9(#(Z#Z Q* Q   )#( ?33/2]2?3?3]2229+}3+}10%.'#>73>73#.'  Q ^77^ Q  F&^^X -ork'=7574&'>3O77O3N3O66O3=BB=K32#"&'732>7#R65#0fa.L9 7&* 1TI G ;gM- C ->%N`.v@Nj,e(e"k{  S0%S  Q   / W U  *W ???9/?]2210]]]]]]]]]]]]]#".'##33>324.#"32>`-D.+@,VVVV-?).D-Z #" "# >eH(#?Y74T7.54>32.#";)&X %)1C(!?V  \(5)-i0:;8I6,@* d*71 &HCL@ %#P$O++41&HB@$6P.O"O+++44F(w@J!!z!5E$ %Q*%Q(&& &&)& W$"W 'U ?3?39/]322??]2239/10]]]]]]]3573#>32#"'732>54&#"##?V-!:+H<   (7$V?N]B_2U?VJ I"KNH =jN= &@ PO++41_ P@/fv   "S !U W W ?22?329/]22/2/10]]]]".54632.#"3#32679L.af0#66 *&7 -Mg; G ITH%>- C $;VAL& @POO+++44DM .l@Av$e$T$E$Q.Q...'S0'/ WU.'W& W ?32??9/3299//]210]]]]]]]%32654.#"632#"&'#'>7>=  33 & Pc4F*#AlL9 +- G.4$ ZS1C) 5`655M+".TnN (m @> H4%Q S*Q )U(%W W ?32??99//32?]29/3210]]]+632#"&'5##33532654.#"(B/4F*#AVVV  33 &  ,@)0C(  :-3$N &F@ PO++4N &Ce@  PO++4D \No 4@Q Q Q   U ?2?3]9/10333##5#NVVwTx =1*;@ky9h9g5w5W11x.i.(($$K < * Z yj0+S!!=S2S <07W& X??9]3/2/9910]]]]]]]]]]]]]]]]]]]]]7467.5467>7"#"#".%4.'32>1D9 FE)<$ !! (" 6,-F00F-"a $% \- (7HI! -FfH2[E**F[/6L7$ N%?//?%u@IZ"j"jYu   u  u F 'D &I%HJ?32?99//]32]32310]]]]]]]]]3#32#"'#53532>54.+銊+6X?#"=W4DGZ3%'8#%QB5U<;T5EBQi!6)(6"&g@=&F  % E S (Q'U&#W    W ?3?3299//3232]22310]]]3573#632#"&'#32654.#"hVPc4F*#Ah  33 &  BZS1C) |.4$8%(=@^3/&/6/'5'e'&'v:)yEUI Y XIFV6F?,!F >,)J$69J!$$$1J1J ??9/]32222210]]]]]]]]]]]]]]]]#".54>32267.#">32"32>7#".%=]??]==]??]='$8''9%%)"!%%8&'8$ ')# ZQ_44_QQ_55_N7\@$%C^9 6X>"#@Z8 0#3|@Tt1f*v*j(z(j"fv   &S5,S 4&$$$,//)WW ??9/32]222210]]]]]]]]]]]#".54>32"3267#".727.#">32-E//F--F//E-/23. Y..0/ >eH((He>=fI((IfASX_Y IOUN A j@> }jYLL   ! ;/  J?322/3?33]]?3/39+}ć+}10]]]]>32.#"#.'3>RD>- ! #! a.-,^ $%6%MSB *)Zv:KnM?c  j@>y&'   Y  Y !)X  ?33?3?3223/3]9+}ć+}10]]]]]#.'3>7>32.#"V  Y&%# [ # :31  5mg\$.~B/rsl(8ZA= @ T=:~&r@&$##MD/F (D'@I`p H$ ?2?3??3]+]2+}9/1033>733'>7#267#"&'7TT4|RGI79B+ ="FC=? D00D ?y D:*P-;;6"&A88A&"Nd(@$$ H9$ $$*$ @R H  Q&%%% Z Q@ H*Q ) &"p U ??3]?2?3]+2+}99//]210]+]]+]3'>7##3>7'267#"&'7B3-=# 943-DP021b? D00D ?7 ;u*';"|'dhc&)_]U "&A88A&"%s@IZ"j"Zjtt     F 'D&I%JJ?32?99//]32]32310]]]]]]]3#32#"'#53532>54.+ll+6X?#"=W4DGDDZ3%'8#%QBn5U<;T5BQ!6)(6"(&w@ %5E @: HS (Q 'U&#W   0   W ??3299//]]3232]22310+]]3533#632#"&'#32654.#"?VNa3E)"A?  21 % KKBPZS1C) .4$T#@n"jY\l  v C $ 4   ut" #   @ H F%##D$ H"0@J?32?9/3/]3322/223/3]3/+9939910]]]]]]]]]]]]]]]632'+#>54.#"327'TFC4U=!70*;+#&*Z(#2$)5T;M_eic7)(7!dMG'@lk{Zt 3 C   $ Ra&' ?OS )'@ H''!!Q (&! 0@#W  W??32?33/332/]222]23/+33/]9939910]]]]]]]]]#>32'#"&'7>54&#"3:7'VG%7O1'*&=&$b(7< ! . &GgB[{\] cL9l]qT9@D DH??10##35Z9NB'@Q Q U ??]10##35BV= } /@ D   I H??9/3222103!#3###D.ԀZD*MFE ? 5@Q U U  ??9/32]3210#3##5#5353?ggV??îBBTF#s@I|Jj{j)I R   U##F%D  $J H! J /??9/322/23/10]]]]]]]]]]]]]632#"&'5232>54.#"#!&%7R6ql )6 !0&Z8h )NoFN#@Y5>T4 MNF Z@7zkiyS "Q !XU X???9/32]22/2/10]]]]]#>32#*'532>54&#"#3L %A0\X  '2/VÏ;_CxG#5@_R  G5@c"L  L00+L50550*0+0L%*%%*%"#D$$+/D755+65+*%"00$H ??3??9/33333?3?32/]2/9/3223+}ć+}ć+}ć+}103>733#5#.'##>7.' (,.V.,']+..,+(GV8(-1V1-(b-47/.+MTT!2!TTM!SWU$CMT)2aWIMIWa20hdW$UWS! oK /G-M- M+M* M#سM#M# M"M"M"M"@# MMM M M L MسMM@ MMسM@-MM M M  M  M L M  MM LسM LM M M M@ MQ@BMQ,@M,@M,! ' M 8M L 8 M /?oO_1سMMM@ M/&гM&M&гM&M&@% M&&'0!,,,'/&' U ??3???3?39/3333/32]+++++2]++++]]2++++9/333++22+2210++++++++++++++++++++++++++++++++++++++++53>733#5#.'#5#>7.'x !W! X!= >ET1 $$W$$ \ &) /I00;>#&J " /?339/2?39/922/2/9/322/+3/210]]]]]]]]]]]]]]]]]]]]]]]]]]#"&'732654&'>7.'732>54&+532654&#"'>322A,;# <,$   %D< /#SD009J90 <K&)D1/tYC,F4  #&*7    H!4$@GG;=67 F.C(4RCHC@*5@$@@@U e S c #34SAA @2 H  )SE;;/// D:7W>/U00;>!$X   /?339/2?39/922/]2/9/32+3/210]_]_]]]]]]#"&'732654&'>7.'732>54.+532654&#"'>32'4G; <,$   6< "-";8/ 0+=TGm@?L  L  /  D D H???9/33?3]2]2/+}ć+}103#5#.'#3>76:;674BV,7=?ZZ:92"SWU$DMS(.`YL!TTMNo o@A  YY QQ  U ???9/33?3]2]2/+}ć+}103#5#.'#3>7*M&%KDT-(,,VV)($  Hw4*q9ב!HE> <=:T"@M!L L !"@ H$D #!H ??9/333?3?3]29/+]3223/+}ć+}1075##3353>73#.',ZZ,B&# [',*64. `%)+ڒ!NLF"RWT$[eh,+YTKN "|@F Y Y !$Q #  U  ??9/339?3?3]22/9/3223+}ć+}1075##33533>73#.'#*VV*< U5$! W  q gg885Hw4FKK"A@;q"{@FL  L$ D" #!@ H  ??3?3?99//+333222]32/+}ć+}103533#>73#.'##DZAA:92b7:;FD<e7=?ZDgNNB!TTM"RWT$[eh,.`YL%0 @K  YY"0Q  !@ H    ?33/?3?9/339/+32]22]32/+}ć+}103533#>73#.'##?V44)($ \*M&2.(^(,,V?;;B<=:Hw4FKK"!HE>4\@2  L  L D H ?3???39/3322/+}ć+}10#.'##53>77:;FD<e7=?Z:92"RWT$[eh,.`YLiL!TTM  `@5  YYQ U  ?3???39/33]22/+}ć+}10#.'##53>7*M&2.(^(,,V_)($  Hw4FKK"!HE>J<=:TG.=@!DD D  H  H?3?39/]2]21033#5###33ZBVFZZBNo B@&QQ Q   U  U ???39/]2]2103#5#5##335@TBVV 9ב Tm >@" D?O  DH H  ?3?9/]32]210###333ZZZiB%LN 9@  Q Q U U   ?3?9/?]2210##5##335_VVV J= TF%[@6S!c!eTI:)%%DF'D&J" JH???9/32/9/22/10]]]]]]232>54.#"###!632#"&')6 !0&ZZ&%7R6qlj#@Y5>T4 h )NoFNF "\@:jzziQ S$Q   #X U!  X ????9/]9/22/10]]]]>32#*'532>54&#"###! %A0\X  !(2/VVC4;_CxG#5@_R = 8H80<@|;v;;z5/u..t,++++&&6%5&u5#  K4-01F 7F(00(>F =:J###J4J- 0/?332?329/]/2/2/9/]999910]]]]]]]]]]]]]]]_]_]]].'"#"&54>32.#".54>32>54&#"#Sj {*If< ?/WcIG%;)&9'(:%K: 03 !$Y9[\- I 9k%;^B$ 9P03\L;*6p1^*ySI>T1q(6@Tg&U&{ d V hZvgV,))S@ H/S  8S 72X@ H$X,X ??32?9/+]/]2/2/9/+]99]9910]]]]]]]]]]]]]7&54632.'#".54632.#">54&#",.7B9<:3&G!0J 4K1ma(-"   Nh ER[^ZNIu8!=B+)Ha8B5R[-I S93- )7C0CRG 2@DD    H H??29/]]10#3#5##5BVFMhMoj *@QQ U  U?2?9/10!#3#5##\@TB Jב< I{ P@+YY  Q  ?3?333?39/+}ć+}107>73#5.'3 V #%&V'&$ [e(lsr/A/.B/rslk@<LL  D   I  ??39/332?39/]33]]+}ć+}103##5#53.'3>7(-/cfZf_/-(aB##B/gkj1BB0jkh/OLLOI u@FiyY  Y / Q   U ?3??322?39/]33]]+}ć+}10]7>733##5#53.'3 V "PcVcK! [j(jqq/7yxs0BB0sxy7/qqjG@M     LL DH ?3??3?32/2/+}ć+}10733#5#.'#>73yW!JGV) #&&# T(,-ZFFGKL$$LKG'Z_`,Io l@@ YYQ U ??3?3?32/]+}3/+}ć103#5#.'#>7'3739@T$53R !$%WZ[T.l6ב:i..i:!GHEGU8@D DD  HH ??2?2]10#333#5!#5VrZBV|MhhMo F@+Q?O_@ H Q QU U?2??2+]q10!#333#5!#VV@Te J9ב8GI@+  HDDD J H??39/32]210+]]5#5#".=332733F3&A2V1C#,ZB.L9EE o*o Q@2J Z + ;   Q?QQW U ??39/32]210]]]]3#5#5#".=332675t@TB,!9*V # 9ב+I7(8U@0  u d   D D J?3?9/332329/3210]]]]]75.=353673#5 7(V(E"ZZ{v/G37C pKw%j K@)  Q  Q W ?3?9/3323]29/3210]75.=3536753#53&V>VV  d^,F419 SWbTE@)}i D DJ ?3?9/32210]]]]]]>32#54&#"#3%B2V1C#,Z.L9EE NKE)4@^v---6,F,tc5E'eSZD 0F  6/F#5H&//J *J??329/32]222/10]]]]]]]]]]_]]_]]]]>32!3267#".'.5467%"34.QN t\8N0$=0!5>TD\;!9(H) , (H.UzK7^E'G,1X|K#5& $?T10T?%'.@cv)e)eugeu&6(8,S  0+ SH@ H^!/ U$++W (X??329/32+_]+222/10]]_]]]]]]]]]]>32#3267#".'.54677"34&M"^HYJ -#1  =*4I/>ED+'"*wny  &?/E $A\8FE CVHIUGE-8@bv150E0sbD5'fTZFD"4F  :3F"'9"H*33J .J??3329/32222/9/10]]]]]]]]]]]]]]]]>32!3267#5.'.5467%"34.QN t\8N0$=0!5A%V/B*!9(H) , (H.UzK7^E'G 9Um@#5& $?T10T?%o(/@cf*v*fv dt6%8) Q-S  1"0, S( U%,,W )X??39/32/]222/9/10]]]]]]]]]]]]]]]>32#3267#5.'.54677"34&M"^HYJ -#1  3"TE=>ED+'"*wny  &?/E~^FE CVHIUT, y~&@ <6P8O++4&k@ 71%P3O++4TG'j@?X#R"LHLF)'' D(J$ J??339/3/2/23/+}10]]]]]]]232654&#"#3>73#"&' EB\QZZ:92b267ah6N2  jopq`!TTM KPP# |BlM*ND )c@54&#*#3>7&E# 9*/E-&,?K VV)($  Bl0!:T89^C$I"5A SY <>: =8^@8iXE4 D D D  HJ H /???]9/]10]]]]]3'>7###'>7>=I79B+ C  bL +<  D:*P-i-3kie.UWM07##'>7>=!3H# >lL9 +- B2.u;"5`655M+".Tn: ;u*TF6@DDH J/??39/]22/2103#"'732>5##33ZG?"  ZZ1VJ I"WNF <@"QQ U W???9/?]22/210#"'732>=##335H<   VV VJ I" T=5R@.p D DDHH ?/???9/]2]2]1033'>7###33ZI79B+ CZZ D:*P-BMd Q@. Q QQ  U U ????9/?]2]2103'>7#5##335=2.=# 9VV : ;u*';" 8GP@0fv     DDD JH?/?9/32?210]]]]]!#35#".=33273eVB3&A2V1C#,Z.L9EE oK,ov I@+ :  QQQW U ???9/32?210]]]##535#".=332675vBT@,!9*V # ׀+I7(E=5@ M$%(F 0 L5.5M.)D@4 LM / 7 D 6H)%$.5 ?3/22?3?3/?22]29+}+2+}+10+%.'#>73>733'>7#.'E*'$V Y./,*.-Y I79B+ = `Hu`$9BZK+w66w+£ D:*P-B:KX]VGIdY 1@Q"#&Q1,1Z,'QYiZ @ H3 Q   2U' #",1 ?3/22?3?3??]22+29+}]2+}10%.'#>73>733'>7#.'  Q ^77^B2.=# 7  F&^^X -ork'=32#"&5<7267#+ -#1  =*7K..A'YJ+' %@/E (HdO2O+++44&i@ /A%P9O-O+++44r&#@ 1C P&;O&/O+++44H&@ /A P&9O&-O+++44p DMT]&@ PO++4N&Q@  PO++4Tr&@$POO+++44N&P@ & POO+++448%r&2@*< P4O(O+++440&RJ@*< P4O(O+++448%)}@T()(9(y'w"!!&!6!wxVDY J YJVE%F+$F *I$$JJ ??9/2210]]]]]]]]]]]]]]]]]]]#".54>322>7!"!.%=]??]==]??]='6$$8&&7%,$7ZQ_44_QQ_55_$A\99\A$6$B\88\B$0!i@Fy!j!ve   S#S  "UWW ??9/]2210]]]]]]]]]]]]#".54>32267#"3.-E//F--F//E-/++0.+*>eH((He>=fI((If]NN]XJJX8%r)5A@_()(9(y'w"!!&!6!wxVDY J YJVE3-9?? %FC$F B0<*6I$$JJ ??9/22229/10]]]]]]]]]]]]]]]]]]]#".54>322>7!"!.7"&54632#"&54632%=]??]==]??]='6$$8&&7%,$7,!!!!!!!!ZQ_44_QQ_55_$A\99\A$6$B\88\B$0!-9@Qy!j!ve   +%177 S;S  :(4".UWW ??9/22]229/10]]]]]]]]]]]]#".54>32267#"3.7"&54632#"&54632-E//F--F//E-/*,/.++%!!!!!!!!>eH((He>=fI((If\NM]XIIXr&5@ !3P+OO+++44 N&@ #5 P -O !O+++44]&b@  PO++4D&\+@ #$P%O++4r&^@0P(OO+++44D&\(@%7P/O#O+++44&ff@. P!OO+++44D&\f0@*%'P(O$O+++448r&W@)P !O O+++44,v&6@, P$OO+++44TG $@ DD HH??103#5#!BVF.hMMo< ,@ QQ  UU ??]10#3#5#3<@TBב Tr&',NR& @%7P/O#O+++44T^!-@\6 % 9*)9&6  M  D(S"S/ D .%X   +XUp?3]??3]??2/]2/]+}10]]]]]]%!!.'#33#"&546324&#"326K =CF"TK&G@9TmO>>OO>>OF%"!&%""%F;;>{7K _^]`a\\aB==BA>>Qu8@P6*-:-"u""D 147/F'':82 F/ /9714444 &#J'* J ?32?3299//32322/22/99210]]]]]]3>54&#"'6323#3#3267#".547#53>7# 6*,5?(A.+NH :+1? +C/0LC 08 D0C(=!3=5: D1D)!=$3p@9   D   I ?3/32?29929999299////9/33]]332210#77#5'75'75#5ZxZxVZxZxJ/;>n/;>͡.;=n.;=J +@ D  II?2?9/2210!!!###ppVJ^J= 'b@9z##z!F )D(J$J??9/3/_]222222310]_]]]]3>32+3##5#535#732654&#" D!@!-I56L-'UDDD$8>:0  UV 4R:;R4[BnnBcG=MN;a   /2/10267#"&'7? D00D ?"&A88A&"$T%TT(=T+8%+@fx*)()8)%&%6%w$v &6;)xUFYJZ I VEF-"F,H'J'J ??9/]]10]]]]]]]]]]]]]]]]]]]]]3#%#".54>324.#"32>ҷS=]??]==]??]=`$9))9$$9))9$O%Q_44_QQ_55_Q?hK**Kh??hJ))JhT,T.D@% L L  ?3?3?339+}ć+}10#.'#>7).-,^ $%%$ [,-.KmM??MmKE0T1- 7@@    HHH??9/2/2/2/2/]10!5!!!!!]h'dQQP8%2TT37<-a '\@6&#uu% D !F)F(%J$J /22?229/332210]]]]]]]]%.54>753#4&'>7X>"">X7V6Y>"">Y6VHLLH~HLLHV-Ie<53# alS6DSD6Sn_SstLVLVL ru210%d@@u%s!g!      Q'#S & WW U ??32?32]]210]]]]]]]]]]%.'#"&54632267.5.#"#  4^\il G   ;?7 !H  @ ?\meaNG,u@J*($${$Y Zj  ""&S S.Q -"U##)X W ?22??9/9]23/29/10]]]]]]]]]]"&'#4632'32654.#52654&#"+V\KQV3(:D4J$?A 1#(9')&+ _^cQ9VjQ6V= \PM#<,G?D3=8<G{ M@(6  RYS  ??3?3999/+}+10]>73#.'g2V JHM(- Sq,fkm3y*X.aƹA0%7@aY5i5y5f1v1W1g,i)y)## #iyZjz+&S9S.S 8+ 3W! X ?32?99]3/2/9910]]]]]]]]]]]]]]]]]7467.54>32.#"#".%4.'32>0DH ,'68,D&%5*-F01F- 51 %% W.<-!/ E 6.7G[;3_I+*G]9.E4(#tN!A3 3D-e.i@@+ H +;*  &0S,S ,,/U%"X&) X ?32?329/9]2/22/2/]10]]]]]+.54>32.#";#"3267#"&546 ,,<#@)#13; #,!% 2>#Ue/:02$ E "&!/H $  ENO2?&Ds"@ZJ!KziudU3$cst U HI~lK[ S$ S# U?2?992/3/3]10]]]]+]]]]]]]]]]]]]]74>7#5!'>54&'.& :P/'lz%6!8,E0'?+8vxx:J@q*4! @,#C*& 2FNG@@( z  Q Q  W?32??]10]]]]]>32#4&#"#N%V$'@-V(7$V 2U?NH <5#s@Mj#[#"fUeVZjz v ty!S% S $U W W??9/]2210]]]]]]]]]]]]]]]4632#".2>7#"3.5\e4I.\e4I/'  '' 1|Ϳ/af̽.a FnNNnF }CiJL "@ Q    U ??]9/10.53J@V& AKv#N ~$l@?[k{!Y$!$$!  Y  0 $& %%! W $ ?2?3?9333/9]+}ć+}10]]!.'#>7.#"'>32&  W')*   ?C)./.prk).kol0F~69B! L6?&gNG ~ Y(Dw3@W+ **&$yeuCtc 00S5%S(( S"4%U-1X0-??3299/993/22/3/10]]]]]]]]]]]]]]]";#"'>54&'.5467.54>32.0:J:&)$13=E0'?,<53+4E&9&==@?I)3  99#C*& 0G4N^O@/G/ F 0RN HG ]@=ts j jYS"Q !W  W???32]210]]]]]]]]]]]732>54&#"#4>32#"&'#),--'V.@$-C+Wc$O0N9f^?=8N0&Ge? 0DN%k@G Yx  f % 5 E  v v%%S'S 0& "W%"??3299]3/10]]]]]]]]]]]].#"'>54&'.54>328&71*#0'E%*4 2E( . ka*;+ ?,#C*%.;#'"32654.'.A(%B18O0o((/--, A`? @cDKiBJo-O>X`_[ =5* C 1@YQ X U?2?322/9/10]5!#3267#".55}   !3'JJG 8-;H @@)   Q Q W ???]10]]]]]]32653#"&5'-.'VUUUV 5::6\Xd^^\0I) N@/ DTCSQS"S!W W ??32?29/3210]]]]]5.54>324&'>dr$B]::]B#qd@@@@M?@@? t?gH''Hg?t Qo  gQQg t oy [HG" G@+ZjzEUeQ Q Q  X ??32???9/3210]]#5.533>5"e_S_dT69S97 huuh7AN2NA:7R-@c,,y$$$h$fvfv &S%%/%%"Q "S)/ S S   .&  W ?322?3/3]]9/9]10]]]]]]]]]]"&'#".546732=332>54&'7#;(I,<$,&P"(>U>("P&,$<  ?*G]4L?:E$B1YY1B$E:?L4]G* &$RP+4?5&(<?5&&+:?5&,:?5x&,@POO+++44?&2+?58&@/B+&PCO@O+++44-e&(@ 3B+&PCO/O+++44-&2@-/A+&PBO@O+++44-}&E@3A+&PBO/O+++44&(B{?5&(DϏ?5}'(Ѹ ?55i'(и ?55a'( ?55y'(и ?55NG&U@ P$O++4NG&U@ $PO++4NG&P@ &P'O$O+++44NG&E@ &P'OO+++44NG&<@ %P&O$O+++44NG&Z@%P&OO+++44NGq&X@  P6O+4+44NGq&N@ P%O+4+44.&+B{?5.&+BϏ?5'+Ѹ ?55'+и ?55'+ ?55'+ٸ ?55'+'+2&@  PO++41&@  P O++4&@  POO+++44&@  PO O+++440&@  POO+++44&@  PO O+++44q&@  P-O+4+44q&@  PO+4+44&,B{ ?5&,BϏ ?5',Ѹ  ?55z',и  ?55r',  ?55',ٸ  ?55f',f',0&RH@ (3 P9O++40&RO@ ,9 P(O++40&RQ@ (; P@ (&P'O++4-e&X@  20+&P1O++4-e&+@ "1/+&P0O++4NG&[@ PO++4NG&A@  PO++4&@  P O++4%&@  P O++40&RZ@ +) P*O++40&R=@ *( P)O++4H&[@  PO++4H&P@  PO++47R&@ 1/ (P 0O++47R&@ (0. (P /O++40D&&pZ@ 7+PHO++440D&&pU@ ;+P7O++440D&&p[@7JPKO+4+4440D&&pL@ ;JPKO+4+4440D&&pM@7IPJO+4+4440D&&pP@ ;IPJO+4+4440Dq&&pb@D;PZO+4+4440Dq&&pH@ D;PIO+4+444&$&$?5&$&Ϗ$?5w'$&Ѹ $?55b'$&и $?55-&$Z&L $?55N&${&ٸm $?55(&$U&G(&$U&GND&&U@ 0P$O++44ND&&U@ 0$PO++44ND&&W@ 4&P'O+4+444ND&&E@ 4&P'O+4+444ND&&<@ 4%P&O+4+444ND&&Z@ 4%P&O+4+444NDq&&X@ BP6O+4+444NDq&&N@ BP%O+4+444c&+B'{?5c&+B&Ϗ?5'+&Ѹ ?55'+&и ?55'+& ?55'+&ٸ% ?55'+&'+&7DR&'@ .E (P ?O++447DR&'@  2E (P .O++447DR&'@.A (P ?O+4+4447DR&'@ 2A (P BO+4+4447DR&'@$.@ (P AO+4+4447DR&'@2@ (P AO+4+4447DRq&'@;2 (P QO+4+4447DRq&'@;2 (P @O+4+444h'{&$ ?5&Ϗ&I?5-&Ѹ'L ?55#&и'B ?55&' ?55&ٸ' ?55&'&'0&bL@ (1P&O++40&N@ &'P(O++40D&&qp@ )'P(O++440D&p  1+P+40D&&Op@ (&P'O++440&V@ 1(P)O++40D&&pVB9P+44&$b]@ &PO++4c&$^@ PO++4&$C?5&$k?5 &$[@SD /10327#"&5<73 ,<J?(46? [@@ P   //2]910>7.54632[# "&a'*&" *l   /3/102#.#"#467<: :;IB!00!BIP%a )*@$%% !$ /322/2/10"&54632#"&546322#.#"#4><0$8&##%8$0P .&&. ND&&[@ %P&O++44ND& P+4ND&&A@ $P%O++44NG&V@ PO++4ND&&V&P+44&(]C ?5'k(]?5I&+]C ?5I'k+]?5T!&+@>;*@    /3//2910>7.546327'  #T/ha'*&" ε7>Q*@   /3//292/10>7.546327'77  #h/Ta'*&" @!q#*@#   #/2/3/29102#.#"#4>>7.546320$8&##%8$0. #q.%%.  # &b@  P O++4 &@  P O++4)&!@  P$OO O++++444*&!@  P#OO O++++444&@   P O++4a&@ PO O++4+444&,b@ PO++4c&,@ PO++4 &,]C?5 'k,]?5>(&@ /3//9210.546327'p" ET/h@ "&*'>8&@ /3//9210.546327'7g" h/T@ "&*'@!q#*@#     /2/3/92102#.#"#4>.546320$8&##%8$0J" q.%%. #  H&bV@  PO++4H&W@  PO++4A&V@& P,OOO++++444@&U@& P+OOO++++444HG&Z@ !,P2O++4HG&L@ %2P!O++4H&U@  PO++4Ha&U@  POO++4+444&<bF@  PO++4c&<G@  PO++4B'<C?5`'k<?5&3BϏ&?5LO (@   /3/32/3/10"&546323"&54632''L2^nLOG//10'>#.{7DR&'@ B3 (P AO++447DR& 93 (P+47DR&'@ (A? (P @O++447R&@ 90 (P 1O++47DR&' 90 (P+44&2]C(?5T'k2/?5&C\?5^'k-?52C'bTG,//10'7,#{.P@ H //+9210.54632&" #@ "&*'D&$&w$?5D&$&Ϗ$?5D'$&Ѹ# $?55Dr'$&и $?55D=&$Z& $?55D^&${&ٸ $?55D8&$U&D8&$U&D.&+B'{?5D.&+B&Ϗ?5D'+&Ѹ ?55D'+&иs ?55D'+&k ?55D'+&ٸ ?55D'+&_D'+&_DU'{&$ ?5Dz&Ϗ&I?5D&Ѹ' ?55D&и' ?55D&'T ?55D&ٸ'u ?55D&'LD&'QD&$ & P+4TD&+  P+42D1&  93 !P+44#u@@F V v F   L %$ I II?2?399//2322/2/2333/+}210]]]5!#3##.'53267#53.#4C4 fJ01-Z/33*?S 97mHH2HQS AJM#JJDJ0;H*8 Y +7I[my@;8AAC?Y<_FkM jN/"MF<5N?N?N"SJ32"32654&467'7.723&'#"&'&#"6"'327>3267#-    ":O--N:"":N--O:"  2T"/)##)/    b-N:"":N--O:"":O  $ $%  $$ $j, /! ## !/ ,1'p''u'p0I #'+/37"@&6Ff= &6Ff= &f&fIYIY i i6f 6 f  9  9=11i1y111@ H 11/4;H/((^(n(M(>((@M(+H((i(y(((@ H (($4;H$$^$n$M$.$>$ $$$$$i$y$$$@ H $$6@ 4;H6652@ H2'2722+@-1H1+ +++++@ H+'+7++'-1H'@(,H'@ H'''7''  "/ ;^[Ly  ; ? o =O   { L   9 i   /_ ;{L8 f3`=PSDv 0`=ArD@=f7  0 = !   T   F   9@ 4EH",585@91;Ha5@5P5!5155555555555c5s5T5C555@ H55'55"@H"""""X33,,@@ &HK,[,<,,@H,,,,HZ,I,,@ H,2EH11&40;H4,/H4@3#+H|44k4\4K44HZ44@ H4#+#;##H#W))+-$'H-#H-H-@H-@ H- -@2EH$$& @P`;`!Arc$DfG6'  <wC i3/?<O `@*IL\l )i AL\  /O_o;Oo.Ll| +Ii8) >xK f  3  `=AScDe@:' APA`p ?r2_]_q_qqrrrr^]2^]]]qqqqrr^]?^]]2^]]qqrrr^]2^]]]]]]qqqrrrr^]9/]3^]]]qqqrr^]3^]]]]qq+rrrr^]]^]]2^]]qqrrr^]]2^]]]]]qqqqqqrrrr^]]]?^]2+2^]+++++?]2+q2+]+qqqq+++9/3+3+]]+]+qq+q]2]]+2]+]qqqqqqqrrrrr+22+22r22]]]]qqqrr^]2^]]]]qqqrr^]2^]]]qqqqr^]^]]2^]]qqqrrr^]]2^]]]qqqqrr^]2^]2^]]]qqqqrr^]]^]22]+++2]+qrrr+2]+]+2]+]]qrrrrr+2]+]]+rrrr2+2]+]]10^]]]]]]]]]]]]^]^]^]^]335!5!35!3335!5!35!3j444555k**yhk**L**yhk**  $ - 6 7 ; < =  $ & * - 2 4 7 9 : < D F G H J Q R S T U V X *     %                                # & F G L [ r s v w ~                        F & * 2 4 7 9 < M7 \ F                    F G L M Z [ r v          $ & * - 2 4 6 7 9 : ; < =             F L v ~           $ & * - 2 4 7 9 <                       & ' G L M r s                 &*-24679:;<=FGHJRT  FGLZ[rvw ~ $&*-246789:;<=FGHJORTWXYZ\    #&'FGLMZ[rv~  $&*-24719(: ;(<(=FGHJRT#((2& - # (#&#FGL-Y[rsvw~26(- $-789:<=      # 'LMr #$#-#6#7#9#:#;#<#=###############L#~########$ $ $ $$$$"$$$&$*$-$2$4$6 $7$8$9$:$;$<$=$?$@$D$V $X$Z $[$]$^$`$o$p$"$'$$$$$$$$$$$$$%$$&$$$$ $$ $!$"$#$$ $~$$$$% % % %%%"%7%9%:%;%<%@%]%`%%' %%%%%%%%%P%% %~%%& !& & #& &&&&&"&#&$&&&*&-!&2&4&6&7&9&;&<&=&?2&@&F&G&H&J&R&T&X&[&]&^&`&m&o!&p!&y&&&'(&&#&&(&(&&&&&&&&&#&t&#&&&!&"#&#&$&o2&q&~&&&' ' ' ' ' ''''"'#'$'-'7'9';'<'@'D'['`'o'p''''''''''''''''C'' '"'# '~'''' ''''''( ( ( (($ (&(*(-(2(4(<(= (?(Y([ (\(^(('(( ((((((S((("(#(o(~((() ) ) ) ) )))))" )#)$)&)*)-)2)4)7)9):); )<)?#)@)D)F)G)H)J)Q)R)S)T)U)V)W)X)[)])`)o)p)y)))))) )'2)*)))))))))))))v)))")$ )%)C)o2)~)!* **7*@*Y*Z*\*`** *****H* * *o**++++o ,,,,o--$------o. . . .... .#.$.&.*.-.2.4.7.9 .:.;.<.=.?.@.D.F.G.H.J.R.T.V .X.Y.Z.[.\.] .^.m........ ...... .....*.X.(.. .# .C.o2../ / / / /////#/$/&/*/-/2/4/6/7/8/9/:/;/</=/?/F/G/H/J/R/T/X/Y/Z/[/\/]/^/` /m/o/p/y///'////#/////////// ///~////0<0X0Y0Z0\0 000 0<0 1111o2 2 2 2 2 2222"2#2$2-27292;2<2@2D2[2`2o2p22'222222222222C22 2"2# 2~2222 2222223 3 3 3 3 3333$3-36 393: 3;3< 3?3D3F3G3H3J3R3T3Y3Z3[3\3m3o3p33 33 3'33333333&333 3i33 3"3# 3$3o3!3334 4 4 4 4 4444"4#4$4-47494;4<4@4D4[4`4o4p44'44444444444C44 4"4# 4~4444 4444445 5 555 5"5#5$ 5&5*5-525457595; 5<5=5@5D5F5G5H5J5O5R5T5W5X5Y5Z5\5]5^5`5m5555555555555555555O555 5!5"5~66" 6$6& 6* 6- 62 64 69 6; 6?6D6F6G6H6J6R6T6m6 6666 6'66 6 66 6 6666b6666! 6"6o#6~67 7 7 7 7 77777"7#7$7&7*7-727477797:7;7<#7?27@7D7F7G7H7J7Q7R7S7T7U7V7X7Y7Z7[7\7]7^7`7m7o7p7y77777 77<77777#7#7 7'27*7:777777(7777777777777 7!7"#7#7$7%767C7V 7g7k7oF7q7~%77)77888$8-88888O8o8 9 9 9 9 9 99999"9#9$9&9*9-929497999:9;9<#9?#9D9F9G9H9J9Q9R9S9T9U9V9X9]9^9`9m9o9p9y99 9(999(99 9'(9*99999999999!9999~9999 9"9#9$9%969C9V 9o<9q 9~"9 999: : : :::::":#:$:-:7:9:: :;:<:? :D:F:G:H:J:Q:R:S:T:U:V:X:^:m:o:p::::: :':*:::::::::::::l:: :!:":#:%:o-:~:: ::; ; ;;; ;#;$;&;*;-;2;4;7 ;9;;;<;= ;?;F;G;H;J;R;T;W;X;Y;Z;[;\;^;m;;;;;; ;';;;;; ;;;;;;;;;;;f;;$;;; ;! ;";#;$ ;C;o7;~;;< < < < < <<<<<"<#<$<&<*<-<0<2<4<7#<9!<:<;<<#<=<?(<@ <D<F<G<H<J<Q<R<S<T<U<V<X<Y<Z<[<\<]<^<`<m<o<p<y<<<< << <2<<<(< < <'2<*<<<<<<< <<<<<<<<(< <|<<< <!<"<$<%<6<C<E<V<g<k<oF<q<w<~!<<<$= = == = =#=$ =&=*=-=2=4=9 =< =? =F=G=H=J=R=T=X=Y=Z=[=\=^=m====='=== =========k== =!="=#=$ =V =o<=~ ===>$>&>*>2>4>6>7>@P>M<>\>>P>>>>>>>>>>>>>F>Z>r>v>~ >>>>>>>?$?%?&?'?(?)?*?+?,?-?.?/?1?2?3?4?5?6?7?8?9?:?<?D?E ?F?G?H?I ?J?K ?MP?N ?O?Q ?R?S ?T?U ?V ?W?Y?[ ?\(?] ???? ?* ??????????% ? ????F?? ???????????? ? ?F?? ?? ??<?? ?&?'?F?L?Z?[?s ?v?~?<? ??? ?? ????? ????? ???? ???? ????? ? ?????????DD?DYDZD\DDDD!DE E EE E"E?E@EYE[E\E]E`EoEpEE EEEEEE$E#F F FFFF? F@ FFFGFHFJFRFTFYFZF[ F\F^F` FmFoFpFFFFF F FF FFF$F[FF #F! F#F$F$FFGVH H?HYH[H\H HH#I 2I 7I IIII"I?<I@'IFIGIHIJIRITIYIZI[I\I`2ImIo2Ip2Iy III(II#II -I(I7III<I'I2II II!III (I#I$I6(IEIVIgIk IoqIwI{ III'I"J?JJ+J!K K K KK"K?K@KYKZK\K`KoKpKKKKKKK!K#LKMM MKNN N#N?NFNGNHNJNRNTNY N[N\ N] NmNNN NNNNNNNINN N!N#NO O? O O OO]O!O#O$Q Q Q QQ"Q?Q@QYQZQ\Q`QoQpQQQQQQQ!Q#R R RR R"R?R@RYR[R\R]R`RoRpRR RRRRRR$R#S S SS S"S?S@SYS[S\S]S`SoSpSS SSSSSS$S#TMT,U U UUUU"U@UDUFUGUHUJURUTUY#UZ#U[U\#UoUpUUUUUUlU (U!U#UU!UVV?VVVVEV V V#VV V WW W W?W@WFWGWHWJWRWTW[W^WmWWW WWWWWW$WYWW W!W#W$WWWX X X5Y Y YYY"Y@YDYFYGYHYJYRYTYYYZY[Y\YoYpYYYYYY^Y Y#Y$ Y Y!YZ Z ZZ"Z@ZDZYZZZ[Z\ZoZpZZ\ZZ #Z#Z$ZZ Z[ [@[D[F[G[H[J[R[T[[[^[m[[ [[[[[[W[[ [! [#[$[[ [\ \ \\\"\@\D\F\G\H\J\R\T\Y\Z\[\\\o\p\\\\\\^\ \# \$ \ \!\]]?]@]F]G]H]J]R]T]`]]]]]]]]]O]] ]#]$ ]]]^$^&^*^-^2^4^6 ^7^9^<^M7^\^`F^^F^ ^^^^^^ ^^^(^^^F^Z^[^r^~^^^^ ^^^^^`$`-`6`7`9`:`;`<`=````````````L`~```````cccccm- m7m9m<mmmLmZmmm m m mo$o&o*o-o2o4o7o9o:o<oDoFoGoHoJoQoRoSoToUoVoXoooo*oo%oooooooooo ooooooooooooooooo ooooo#o&oFoGoLo[orosovowo~ oooooo ooooooooooooooooop$p&p*p-p2p4p7p9p:p<pDpFpGpHpJpQpRpSpTpUpVpXpppp*pp%pppppppppp ppppppppppppppppp ppppp#p&pFpGpLp[prpspvpwp~ pppppp pppppppppppppppppy-y6y7y9y:y;y<y=yyyyyyyyyyyyyyyyy yLyZy~yyyy y}7}9}:}<~  $&*-24789:;<= "$& * -02 4 79:;<=?@FGHJRTVYZ\`mop#"~ "? @D YZ[\m op   "? @ `     "?@Y[\]`op $#M- (DEFGHJKLMNOQRTVW o(p(A-K77 7MDFGHJRTYZ[\]FGHJRTVYZ\))* * * **"*?*@*Y*Z*\*`*o*p*******!*#&*24 ? ~  ? ~   ?   op   ? ~   ~?2~ 2?~?~ F&*2479<M7\ F  FGLMZ[rv$&*-24679:;<=FLv~$&*-24679:;<=FGHJRT  FGLZ[rvw ~ $%&'()*+,-./01234567'89:;<= FGHJRT#((2& - # (#&#FGL-Y[rsvw~26(- $-679:;<=L~$&*-2467@PM<\PFZrv~ $%&'()*+,-(./0 123456789:; <= DE FGHI JK MPN OQ RS TU V WY[ \(]  * %  F   F  < &'FLZ[s v~<         $&*-246 79<M7\`FF  (FZ[r~ $-679:;<=L~$-79:;<=LZ   $-679:;<= LZ~ 79:<$&*-24789:;<= :;[]DE,I,K,L'M'N,O-QSUVW/XY9Z6[6\9]**?! >!9#7$<%:/@7   "?@Y[\]`op  $#&*24FGHJRTVWXYZ[\]d ! "#~$79:;<=+ !&*24789:<YZ\~D VY[$\]'6 !"#$YZ[\]{ %!#$"9< M>  * * F G H J R T  &*24FGHJRTXYZ\DEIKLMNOQSUVWXY4Z1[1\4] *-% 8!!#2$*%-62$-D[]$-9;<=D!"~9(DFGHJQRSTUVXYZ[\]2( (*,.06:DFHLRX," ! "-#$%468<>@BEagikmoFq(~.$DFHRY.Z0[%\)]q 8#1$/0'    #$ &*-249 < ? FGHJRTXYZ[\^m'  k !"#$ V o<~ D Y[\ d  "~&*24FGHJRTVXYZ[\] %n" ! " #$~M?V YZ[\(]g -!#$)5 , Y Z  [ \  B #  !9!<!!!O! !~!"D"F "G "H "J "R "T "Y"Z"\" " """g"" "" """~ ""#Q#S#U#Y #Z #[ #\ ##*# #A# # ## #%##$$=$$ %[%]%%%% ]$]-];]<]=]D]Q]S]U]]]*]]]]]]!]%~9~<~[~] ~ ~~U~~~ ~~ ~#~~~~ ~~V[]1 !#    9<M&*24789:<DFGHJM@RTVXYZ[&\]'3+ 6!#$$+1- 7(oZMDFGHJMRT\FGHJRTYZ[\](u "#$ ~DF G H J R T V YZ\]  I "#$ $-=DVY'Z%[\']p '!#$#$#!MV]A ! #$ ?      "@op #'FMZv    "#?@^`mop          #&FG LZ[rsv~   "@`op         #&'G LMZ[rs w~   "@`        #G L[s  `mopy   #'+FGMYZ[qrswy}   $ A ?@`op$A( (   A#&'FLMZ[rs ~(     #?^op   #'MZr~  "#? ^m (    #'FGL MZ[rsvw~   "@`op G[w   "#? ^m (    #'FGL MZ[rsvw~  ?op&L   "#@`opGLZ v ~    ?@`op   #&'+FLMZ[rs    "#?#mop#  #&FGLZ[rv~    "#&*24?2^` mopy2  #  #<#&'+FGLMZ[qrsvwy} ~   "#?^mo p y     ) #&'+FGLMZ[qrsvwy}    "#?@`op ' LM Y[rs~  #& 'GM[w}   $ A ?@`op$A( (   A#&'FLMZ[rs ~(   "?`op         #&G LZ[ rs w ~   "#@`opGLZ v ~   "?op #'M   "? @`op  #'M   "?@` #s   "?mop    #'+GMsw < ?@`!<!  'M[   "@`op 'M     "#@FGHJRTmop   ' GM [sw   "?@`op?     "#@FGHJRTmop   ' GM [sw??#'M?   "?@`op #'M?   "?@`op #'M    ?@`mop  # ' GM    "?@^mop   #'+GMsw   "@FGHJRTop ##'+GMs   "?@`m op  #'Ms < ?@`!<!  2'M[ ?     " ? @ o p            # ' M [    "?@`op #'M   "?@`op #'M?      "#^mop G "@^`# # # #"#?#@#o#p########## ###'#M#[#&& & & & &&&&&"&#&?(&@&`&m&o&p&y&&&&&&(&&&&&&&&&&&&&&&&& &#&&&&&&~&&&&&&&&&&&&&&&&& & &&&&2&&&5&#&&-&'&+&F&G&L(&M&Z&[&q&r&s&u&v&w&y&}&~&&&&&&&&&' ' '''''"'@'m'''''''''' '''''#'!''' #''''#''!'+'G'M!'['s'w'+3 3 3 3 3333"3?3o3p3333333 333 3#3[5(5 7#8#99(9#9E E E E EEEE"E?EoEpEEEEEEEE EEEEEEE EEE#E'EGEME[F F F FFFF"F?FoFpFFFFFFFFFFFFFFFFF FFFFFF FFFFF&F'FLFMFZFrF~G G G GG GG"G?GoGpG G GGGGGGG G'GML L L L LLLLL"L#L?L^LmLoLpLyLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L LLLL!LLL!L#L&L'L+LFLGLL#LMLZL[LrLsLvLwLyL}L~ LMMM#QQ(QS<U<X X X X"X?X@X`XoXpXXXXXXXXXX XXXX X#X&X'XLXMXZZ Z ZZZZ"Z@ZZZZZZZZZZZZZZZZ ZZ ZZZZ Z Z Z# Z'Z+ZLZMZYZ[ ZrZsZ~Z[ [?[[a a a aaaaaaaa aaaaaaaa a aa#a'aFaGaMaZa[asa~ b bbbb"bmbbbbbbbbbbbbbGb[r r r r r r#r?r^rorprrrrrrr rr rrr r#r'rMrZrrr~s s s sssss"s@s`sospssssssssssss ss'sMv v v vvvv"v#v@v`vovpvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvGvLvZ vv v~w w w www"w?w@w`wowpwwwwwwwwwwww ww#w'wM~ ~ ~~~~?~@~~~~~~~~~ ~ ~~ ~~~ ~ ~~ ~~ ~ ~G ~Z~s ~w ~ "#?^mG[   "#&*24?@^`op!!!           "     "#?2@^` mopy 2  6U#A7%&Q R[\^klnUU#-   "#&*24?@^`op!!!          #?    (( #?^`         2((<<   "#?@`opr  " #^m  #      "#&*24?@^`op!!!             "#`op o p  -##   "#?@`opr   ?@op   #?^m222    "#&*24?(^`mopy( #K#-#&2Q R-__#-    "#&*24?(^`mopy( #-U--#Q #-#   "#@op      #&*24?^m   <(<< #?@    "#?op               ?@opy        ? opy      "?op #?@^my    # <"?2@(FGHJQRSTU`(mop*#<2((%(<<(Q  -<   #?op  ? @     ?@opy   #mo p    #?@`opy     "? opy      <?(@`#op<(#  F2  Q ((  "?op"  "?op   7@#^`#mopy7##   "?@opy   mopy "?   "?op      "#mop "?  "?op#AA##R(--#nI4E%44 M@Y% %  4E4     J    .z    4 2     Copyright 2011 Canonical Ltd. Licensed under the Ubuntu Font Licence 1.0Dalton Maag LtdUbuntu Condensed Regular Version 0.83Ubuntu and Canonical are registered trademarks of Canonical Ltd.UbuntuCondensed-Regularhttp://www.daltonmaag.com/Copyright 2011 Canonical Ltd. Licensed under the Ubuntu Font Licence 1.0Dalton Maag LtdUbuntu Condensed Regular Version 0.83Ubuntu and Canonical are registered trademarks of Canonical Ltd.UbuntuCondensed-Regularhttp://www.daltonmaag.com/O  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~.nullglyph127Eurouni00A0uni00ADmacronperiodcenteredAmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatdcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonek Idotaccenti.loclIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccentkgreenlandic.case kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaronnapostrophe.case napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexuni0162uni0163TcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongs Scommaaccent scommaaccentuni021Auni021Bdotlessj apostropheuni02C9WgravewgraveWacutewacute Wdieresis wdieresisYgraveygrave zerosuperior foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperior zeroinferior oneinferior twoinferior threeinferior fourinferior fiveinferior sixinferior seveninferior eightinferior nineinferior afii61289 estimatedonethird twothirds oneeighth threeeighths fiveeighths seveneighthsonefifth twofifths threefifths fourfifthsonesixth fivesixths oneseventh twosevenths threesevenths foursevenths fivesevenths sixseventhsoneninth twoninths fourninths fiveninths sevenninths eightninthsDeltauni2126uni2215uni2219f_ff_if_lf_f_if_f_lzero.altone.alttwo.alt three.altfour.altfive.altsix.alt seven.alt eight.altnine.alt zero.supsone.supstwo.sups three.sups four.sups five.supssix.sups seven.sups eight.sups nine.sups zero.sinfone.sinftwo.sinf three.sinf four.sinf five.sinfsix.sinf seven.sinf eight.sinf nine.sinf caron.alt commaaccentrevcommaaccentcaron.alt.short Parenleft ParenrightHyphenSlashAt Bracketleft Backslash Bracketright Braceleft Braceright GuilsinglleftBulletEndashEmdashGuilsinglright Exclamdown GuillemotleftGuillemotright Questiondownuni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019FOhornohornuni01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEUhornuhornuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BCuni01BDuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DDuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5Gcarongcaronuni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F0uni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F7uni01F8uni01F9 Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217uni021Cuni021Duni021Euni021Funi0220uni0221uni0222uni0223uni0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0234uni0235uni0236uni0238uni0239uni023Auni023Buni023Cuni023Duni023Euni023Funi0240uni0241uni0242uni0243uni0244uni0245uni0246uni0247uni0248uni0249uni024Auni024Buni024Cuni024Duni024Euni024Funi0292breve_inverted double_grave ring_acutedieresis_macron dot_macrondieresis_gravedieresis_acutedieresis_breve tilde_macron acute.asccircumflex.asc caron.ascdieresis_grave.capdieresis_acute.capdieresis_breve.capuni0400 afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061uni040D afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097uni0450 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109uni045D afii10110 afii10193afii10066.locluni0462uni0463uni0472uni0473uni0474uni0475uni048Auni048Buni048Cuni048Duni048Euni048F afii10050 afii10098uni0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CEuni04CFuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9 afii61352 afii00208uni20B4uni20AEtengeroublekratkaAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsialphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega Alphatonos EpsilontonosEtatonos Iotatonos Iotadieresis Omicrontonos UpsilontonosUpsilondieresis Omegatonos alphatonos epsilontonosetatonos iotatonos iotadieresisiotadieresistonos omicrontonosupsilondieresis upsilontonosupsilondieresistonos omegatonostonos tonos.cap dieresistonosuni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFE uni1F88.alt uni1F89.alt uni1F8A.alt uni1F8B.alt uni1F8C.alt uni1F8D.alt uni1F8E.alt uni1F8F.alt uni1F98.alt uni1F99.alt uni1F9A.alt uni1F9B.alt uni1F9C.alt uni1F9D.alt uni1F9E.alt uni1F9F.alt uni1FA8.alt uni1FA9.alt uni1FAA.alt uni1FAB.alt uni1FAC.alt uni1FAD.alt uni1FAE.alt uni1FAF.alt uni1FBC.alt uni1FCC.alt uni1FFC.altuni20B9uniE0FFuniEFFDuniF000 8cyrlgrekJlatnVBGR MKD &SRB ."AZE *CRT 2MOL :ROM BTRK J  kernDkernJkernPkernVkern\kernbkernhkernnkerntkernzkern,r%2<Ldh|^j4rxHNt.DJ $*06< &,28>DJPV\bhnx~ &,BXn  L R X ^ d j p ~  Z h v t   F $*06HNTZ`flrx~BHR&TjJx06<Rh~DZ|Z &Xntz"(.DZp $*0~hnl"(.4:@o2qo o2oo ooo2o  o  o# <## :6V gkoFqo (( 6V o<q  o- o7 2(  6EVgkoFqwV o<(# -(6(EVgk oqw{   o#o 2(  6EVgkoFqwoo2qooooooooooooo 2(  6EVgkoFqwM--^-V-o2qo2qo2qo2qA-K77 7oooM^Vooooooo o oooooooo2A-K77 7TFGHJRTVYZ\xz,.08:<PR[hjln ,8KMQSY[ekmsuoooo  o#  o#  o# <## :6V gkoFq <## :6V gkoFq <## :6V gkoFqoooooo o- 2(  6EVgkoFqwV o<V o<V o<  o# <## :6V gkoFq o- o- o- 2(  6EVgkoFqw*&*24n+-/7JLPRZdrt(# -(6(EVgk oqw{  o2 (( 6V o<q o  o M>>^>U*V>*** <## :6V gkoFq <## :6V gkoFq0 2(  (,.06:DFHLRX468<>@BEVagikmoFqwV o<V o<oooooooooooo2V o<oooooooooo V o<M^Vo 2(  6EVgkoFqwo2q<## :6V gkoZqM^Vo 2(  #6EUVgkoFqw!? qy} )qy} qy} <qy} )qy}} ? quy}KS qy}  qy} ( ##(#<qy} <qy} y}y}} (<<)qy})qy})qy} qy} #6U#A7%&Q R[\^klnUU#-((2((<< #   -##222#K#-#&2Q R-__#--U--#Q #-#  <(<<  (<<(Q  -< F2  Q ((((-U--#Q #-#-U--#Q #-##A((((((((((((A##-U--#Q #-#-U--#Q #-#-U--#Q #-#-U--#Q #-#(((((--#-U--#Q #-#-U--#Q #-#-U--#Q #-#-U--#Q #-#6   [    $#$V # <<2 '222'27!('"7 +KK I   ]     ,###l (!E  Y  $ 5 ^   !\ #  W  ^   !O   ,g  ((( &   "% P ((! 2!!t##!###(C    S    #v  2! H   X  *(  b  # < C !& i   C O      b   %(2##)2 O" !(#~# zil  f$     (|!$2#!#(    k     #  FF7PP<FF7   fۼ#W ( P  1( ((#((2  7FF' #((2<PP (( P   7FF      2@l26*,,,'',-/969?!>97<:/@7+ {%"1 414-%8!2*-62%.0)q81/0' k    &'@3+6$+1-7( ("-.$,   d $ '6  d %n "  ? (g-)5 , t2BO g   A  =A  U   1  u (I"   p$'#'%'VdD   (                  F F<<   -#(-&  #  v(g  -& - #(# <  FF < (           (( A $Ai a ($A    (        (       ## 2 2 ##    ^j`       ($A$A( (A    !!#       SΚe         2(~(&#( 5-     < <! !      E@     # !! < <2   #!#!!   9L@BCEGIKMOQSVXY[\_acegikmoqsuwy{}c$%&'()*+,-./n  *-035DFHJLNZ`bfhjlnpX/0123456789:l!#%'+-/13579;=?ACEGIKMOZ\gik  79;=?APR^drtvxz|0 :;<=>^`gmopqrtuy{)OQSUW_gikm*W* #?cg}~  T !"#$%U]~e #'24>?EKPQRS^`gmopqrtuy"$&(*+,-./0_ 78CPQRS_derstu".02np5$468:<>BHJ^_cmtz|&(*@DFLNPRTVXZ\agik1 !%&/1579;=?C`ajoqruvx{}~4    #%')+-3AEGIKMOQSU[]bdhlsswy)*+,-.b #'24>?^`gmopqrtuy+-/_7PRdrt  "&)..48<=?# )17:9CR=YxMm|}  #(/6;BSX'y-5=EEFFGGHHIIJJKKLLMM NN OO PQ RR SSTTUUVVWWXXYYZZ[[\\]]xxzz               "" $$ && (( ,, .. 00 22446688::<<@@BBDDFFHHJJLLNNPPRRTTVVXX[[]]^^ hhjjllnn       +,./ 12 6688 ::<<>>@@BBCC IIKKMMOO QQ SS VV XY[[\\__ ccee kkmmooqqss uu wwyy{{}}       ""##2??@@DD5FFGGHHJJMM1RR TT!YYZZ[[\\]]^^"``ggmm#ooppqqrrtu yy/zz # /5$ 5551,, .. 00 PPRRTTVVXX^^1__hhjjllnn, 4 -.0.03%&     '!!##($$,,44588 EE5GG5II5KKMMQQ SS UU+VV1YY[[aa5cc5ee gg5ii5kkmmss uu )5    !*+V$$%%&&''(()) ** ++ ,, -- ..//nn             ** -- 00 3355 DDFFHHJJ LL NNZZ ``bbffhhjjllnn pp  [.// W0123456789:;<=  !"#$%&--'_(`)*>  ?6X4)Y'<XY000000@14444448888< ####+-''''''>>>>a0001111 2!2!2!2!""####-##3$%&&&&&---S-e4'4'4'```6)6)6)77*7*8>8>8>8>8>8>:<===6)7*$:::<PTQRURUO\1bf,]A49%&BC-44'4'^*778>DE=FGHIJc&-0#4'8>8>8>8>8>d00@2!2!%4'4'FN$2!-0@4'00 ##4'4'``8>8>KL"=0 4'4'4'4'<-(017)ZVM0 <NK001122334455667788 99 :: ll !!##%%''++--//1133557799;;==??AACC EE GG II KK MM OO ZZ\\gg ii kk      7799 ;; == ?? AA PPRR^^ddrrttvvxxzz || /./012434-HH567OP8QRI9:J;+SK<=TZZ[\]U 4IQ33]+3777777OQQQQQQ+=======Z ^ 7=7=7=OOOOPPPPZ8TTTTTZZZ)ZaQQQ\\\I]I]I]99U9UJ + S S S I]9UJ J J + !"#$%&F'G(##*(* >OLV?YQ:TWZQQQM@,U99 S AXBCN_TZ7=Q`7=7==PPQQPZ7==Q7=7=QQ\\S 7=QQQQ+ Z7O9] DE7+ *   ;;<<==>> ^^ `` ggmmooppqqrrtuyy{{))QQSSUUWW__mm**WWEEFGHHI !"#$J%&b'(K)*+,LM-./0aNN1O2PQ345678R9Sb:%TUTUQV1*:V!!!!!!;"%%%%%%*MMMMMMM-////<N11111144448W8!M!M!M"-"-"-"-../////#0#0#0#0N$aNNNN%1%1%1PPPbQbQbQ''3'3444444K6*8+R+R+RbQ'3aUK6K6K6*8cfgdehZD[\_"-=>%(XN%%1%1`3'?'48+R@A B .N!M%144444C!M!M;M#0#0%1%1a.#0N!M;M%1!M!M//%1%1PP44 +R!M/%1%1%1%1*8YNY.2!"-]'QR^!/*8% ##??cc }}~~   !"JRJCUKUP !"#$%&E'()*+,LF-. / 012 33 45678HUR,(STSTKK6 OKV $$$$'((((((9------- 3 :--- " " " " #0#0$$$$$3$1%2%& & & & & '3'3'33A( ( ( +5+5+5,6,6,6888,61T///////B;<=>?DMQNGIMM...!(%2 '3(( ( +8@ && &&3-$( ---" " %2( ( 1 " '3--( -- $$( ( +5+5#08- ( ( ( ( 3 68        TT  `=`>a ??b@4ABCDE5[678c<F:G;H !"#$%IdJDefef ;7J 4444449ADDDDDD[[[[7<::::K;;;;;;""""%&%444A<A<A<A<FF:::::BGBGBGBGCY3D;D;D; 55!5!["["["["["["$7%888 5!f$$$7% UVgWhXZXZTA<LMkD6'\DD;D;ij(!55["]^%8N_)*+O,-.F4D;["["["["["449BGBGD;D;N2FBG49D;44::D;D;["["P/84:D;D;D;D;7%00FH4A<Q5 R1S4:7%2!!""##$$%%UU]]~~     $$*--+99;;,<<==-DD FF GGHHJJMM%PQRRSSTTUUVV&YYZZ[[ \\]]$xx&zz{{*. !* * *   +%""$$&&((**#,,..0022446688&::&<<&PPQQRRSS-TT$UU-VV$WW-XX$[[&^^%hhjjllmmnn1   /0-$  !!'""##$$(%%",,2233*44 88DD*EE FF*GG HH.II KKMMQQSSTTUUVV%YY[[__``*aa bb.cc eeff*gg hh*ii kkmmssuuwwyy~~  -$* ))* &$*W  ##''2244 >> ??KKPQRRSS^^ ``ggmmooppqqrrtuyy""$$&&((**++,,--..//00__  7788CCPPQQRRSS__ddeerrssttuu==<@@&@?>":;<= !>>?@@@"A@#@@B@@@$' ,0 7(--. /0 12030800945 0 0.-  )*-2<0<0@0 7!(?.?.?.?.@0@0@0A##C@ 70 @0@0#/@''+= 66 7!(%>->-   ("""#<00        "" ..0022 nn pp dC C D \ EF]FGH""I##J??K@@L^^M``NggFmmOooPppQqqPrrQtu]yy`O]`__QT^_UVWXYZ[_e[e*) --,+ '()*  +,- - .--/--0162345678 A!a6"  9  6  #  6R:;<6$Sf6b43A!!""##=$$ %%&&>''B))3++c--8..)//600)11622-33644 5566 77288,994::,;;4<<,==4>>,??4@@-AA6BB-CC6DD-EE6FFGG%HH IIJJKK LLMMNNOOPP.QQaRRSS TTUU"VVWW"YY?ZZ[[\\]]^^-__ ``bb6ccddee-ff6gg-hh6iijj"ll5mm-nn oo0pp qq0rrss@tt*uuvvww&xxyy&zz {{|| }}2~~+3+3   2AAA")661        $$ 446688::<<>>BB HH JJ ^^__ccmmttzz||       F $%""&##&&Q**R22S44T??@@G^^``Hggmm'nnSooppqqrrtu$yyU'$UQSSQQQQRRRR++S--S//S__!D" # ED`E`QSSS77SJJRLLRPPSRRSZZRddSrrSttSSSSSQ-,*-I()*V+,-IM.K/012WZ345XY6NZ7[\89Z:  ]  Z    Z;^O3<Z=_L6Z>YX!!2""-##$$+%%7&&J''))X++P--\//Z11Z33Z44(55466)77599Y;;Y==Y??YAAZCCZEEZFF?GG@HH,II8JJ-KKLLAMMNNAOOPPMRR-SSTT.UU:VV.WW:ZZ [[\\ ]]__(``4bbZcc*dd6ffZhhZii.jj:llNnnoo1ppqq1rrssuu3vvBwwCxxByyCzz({{4||)}}5~~XX+7+7+7/5III.:ZZ  ((**@@DDFF LL NN PPRRTTVVXX ZZ \\ aaggiikk- - . / 02123R""4##5??6@@7^^Z``8gg2mm[oo9pp:qq9rr:tu1yy\[1\__:$%&'()L*M+&,+,ATY;@AB<=>?@]STABNCUWDEFO^GPHV_          Q  PXI_ !!O""A##$$S%%&&''))_++--//113344>55H66?77V99;;==??AACCEEFFGGHHTIIJJAKK LLMMNNOOPPCRRASS TTUUU VVUWW YYJZZ[[\\]]__>``Hbbcc@ddffhhiiUjj llnn<ooFpp<qqFrrss uuPvv!ww"xx!yy"zz>{{H||?}}V~~K#__SSSDVB B B U /         !!%%&&//1155 77 99 ;; == ?? CC`` jjooqqrruu vvxx{{ }} ~~ Z   % &'""(##??@@)FF]GG^HH_JJ`RRaTTb^^``*ggmmEooppqqrrtu&yyFzzaE&F]_caa]]]]^^_____````,,a..a00a__!>?"#@$A[?\[\]da  a,,^88aKK`MM`QQaSSaYY^[[`eeakk_mm_ssauua_aaaa^b]_.I-./+,-GHI./J012B3KO456LM7NO8PQ9:O  R  O    OSTU4OV;7OWML!!3"".##$$H%%8&&X''))L++Y--Q//O11O33O44+55566,77699M;;M==M??MAAOCCOEEOFFGGHHIII9JJ.KKLL<MM NN<OO RR.SSTTJUUVVJWWZZ [[ \\ ]] __+``5bbOcc-dd7ffOhhOiiJjjllNnnooBppqqBrr ss uu4vv=wwCxx=yyCzz+{{5||,}}6~~ DLLH8H8H816///JOO.            ##''))++ --33AAEEGGIIKKMMOOQQSSUU[[]]bbddhhllss  <     "" ##=??@@ FF1GG2HH3JJ4RR5TT6^^)`` gg mmooppqqrrtu zz5 13755111122333334444,,5..5005__>'?0((185  5,,2885KK4MM4QQ5SS5YY2[[4ee5kk3mm3ss5uu5355552613* 9!"#$  + %:!!##%%!''++,5577GG&II"KKMMOOSSUU$WW$[[;]];``ddjj$ll9oo*qq*ss-uu ww.yy.{{}}/!!!$wwyy).R    ""## ??@@^^!``ggmm"oo pp qq rr tu"__ +,-..# $  %&'  $(!!###%%%''55 77 GG)II&KKMMOOSS[[*]]*`` ddrr/uu${{ }} %%% D   ##2244>>??^^``ggmm oo pp qq rr tuyy  ++--//__ 77PPRRddrrtt 2 2 3 4556""7##8&&9**:22;44<??=@@>^^?``@gg5nn;ooAppBqqArrB9;;9999::::++;--;//;__BCDEFGHI9;;;77;JJ:LL:PP;RR;ZZ:dd;rr;tt;;;;;9$%&'()*+,   ./!0 - 1" #(/!" /!#(/6";BKLMNOP/QR!STUV"WXY`ip/y/!""        ").   ""##&&@**A22B44C??@@^^``ggmmnnBooppqqrrtuyy@BB@@@@AAAA++B--B//B__ 78 9:;<=>8?>?@BBB77BJJALLAPPBRRBZZAddBrrBttBBBBB@D !E"#$%&'F()*+,G-./01H23456%)+,-5)+ ,-#(/65;BKL)MN+OP,QR-STUV5WXY`)ip,y),-535%(0         7:CJKLMN OP QRY`ahip qx   ""##&&**2244??@@AFFIGGJHHKJJLPQMRRNSSOTTPUUQ^^``ggmmnnooppqqrrtuyy zzN IKRMNNSIIIIJJKKKKKLLLL  M""M$$M&&M((M**V++,,N--..N//00N22Q44Q66Q__"F     ITMN  N%%U,,J22M7788NJJKKLLLMMLPPQQNRRSSNYYJZZ[[L__MddeeNkkKmmKrrssNttuuNwwQyyQKNNNNMJPIK!"#$%&B'C()*+H,-./0D1G23456E789:;<=>?@)-0127=-0 12#(7/6=;BKL-MN0OP1QR2ST7UV=WXY`-ip1y-12=9=),    #(/6;B STUVWX y  H  )  '""##*??@@^^#``ggmm$oo pp qq rr tuyy!$!__ ,-%&"&"  + (   #(;BKL STWXY` y  zcyrlgreklatnBGR 0MKD JSRB d !/;HU`k  )0<IVal  *1=JWbm +2>KXcn "3?FLSYdo"AZE BCRT ^MOL zROM TRK #4:@GMTZep $,5AN[fq %-6BO\gr &7CP]hs '8DQ^it  (.9ER_juvcasecasecasecasecasecasecasecasecasecasecasednomdnom$dnom*dnom0dnom6dnomnumrDnumrJnumrPnumrVnumr\numrbnumrhnumrnnumrtordnzpnumpnumpnumpnumpnumpnumpnumpnumpnumpnumpnumsaltsaltsinfsinfsinfsinfsinfsinfsinfsinfsinfsinf sinfss01ss01"subs,subs2subs8subs>subsDsubsJsubsPsubsVsubs\subsbsubshsupsnsupstsupszsupssupssupssupssupssupssupssupstnumtnumtnumtnumtnumtnumtnumtnumtnumtnumtnum                                             8@HPX`hpx*,R)l))**+*+X++++++++/+/+/++a+2pqrstuvpqrstuvpqrstuvpqrstuvpqrstuv+d+b2wxyz{|}~yzxw{|}~wxyz{|}~wxyz{|}~wxyz{|}~+2*2*n2*&oo*$0fH:, F 8 v .TtfX>rd  Z"<#.$ $%&&0bjrz "*2:BJRZbjrzoooooooooooqorosotouovoyozo{o|o}o~oooooooooooooooooooooooooo2:BJRZbjrzoooooorotovozo|o~ooooooooooooo2:BJRZbjrzoooooqorotouo{o|o~ooooooooooooo&.6>FNV^fnv~oooorotovo|o~oooooooooo2:BJRZbjrzooooosotouovo}o~oooooooooooooo&.6ooto~ooo "*2:BJRZbjrooouovoooooooo&.6oovoooo2:BJRZbjrzoooooorotovozo|o~ooooooooooooo2:BJRZbjrzoooooqorotouo{o|o~ooooooooooooo0bjrz "*2:BJRZbjrzoooooooooooqorosotouovoyozo{o|o}o~oooooooooooooooooooooooooo&.6>FNV^fnv~oooorotovo|o~oooooooooo2:BJRZbjrzooooosotouovo}o~oooooooooooooo&.6ooto~ooo "*2:BJRZbjrooouovoooooooo&.6oovoooo0bjrz "*2:BJRZbjrzoooooooooooqorosotouovoyozo{o|o}o~oooooooooooooooooooooooooo2:BJRZbjrzoooooorotovozo|o~ooooooooooooo2:BJRZbjrzoooooqorotouo{o|o~ooooooooooooo&.6>FNV^fnv~oooorotovo|o~oooooooooo2:BJRZbjrzooooosotouovo}o~oooooooooooooo&.6ooto~ooo "*2:BJRZbjrooouovoooooooo&.6oovoooo0bjrz "*2:BJRZbjrzoooooooooooqorosotouovoyozo{o|o}o~oooooooooooooooooooooooooo2:BJRZbjrzoooooorotovozo|o~ooooooooooooo2:BJRZbjrzoooooqorotouo{o|o~ooooooooooooo&.6>FNV^fnv~oooorotovo|o~oooooooooo2:BJRZbjrzooooosotouovo}o~oooooooooooooo&.6ooto~ooo "*2:BJRZbjrooouovoooooooo&.6oovoooo0bjrz "*2:BJRZbjrzoooooooooooqorosotouovoyozo{o|o}o~oooooooooooooooooooooooooo2:BJRZbjrzoooooorotovozo|o~ooooooooooooo2:BJRZbjrzoooooqorotouo{o|o~ooooooooooooo&.6>FNV^fnv~oooorotovo|o~oooooooooo2:BJRZbjrzooooosotouovo}o~oooooooooooooo&.6ooto~ooo "*2:BJRZbjrooouovoooooooo&.6oovoooo0bjrz "*2:BJRZbjrzoooooooooooqorosotouovoyozo{o|o}o~oooooooooooooooooooooooooo2:BJRZbjrzoooooorotovozo|o~ooooooooooooo2:BJRZbjrzoooooqorotouo{o|o~ooooooooooooo&.6>FNV^fnv~oooorotovo|o~oooooooooo2:BJRZbjrzooooosotouovo}o~oooooooooooooo&.6ooto~ooo "*2:BJRZbjrooouovoooooooo&.6oovoooo2pqrstuvpqrstuvpqrstuvpqrstuvpqrstuv0LP6-N$%&'()*+,-./0123456789:;<=ln{  !#%')+-/13579;=?ACEGIKMOQSUWZ\gikmL "(ILIOILO "(ILIOILO "(ILIOILO    yzxw{|}~Lw DR pv  p ( p  qu x (oowpv #>?@^`mstuy}Y^DEFGHIJKLMNOPQRSTUVWXYZ[\]xz   "$&(*,.02468:<>@BDFHJLNPRTVX[]hjlnIahqx0 *H 01 0 +0a +7S0Q0, +7<<<Obsolete>>>0!0 +{GS%xNM#pb040l.60  *H 01 0 UUS10UArizona10U Scottsdale1%0#U Starfield Technologies, Inc.1:08U 1http://certificates.starfieldtech.com/repository/1604U-Starfield Services Root Certificate Authority0 150316070000Z 200316070000Z01 0 UUS10UArizona10U Scottsdale1%0#U Starfield Technologies, Inc.1402U+Starfield Services Timestamp Authority - G10"0  *H 0 xo(QQ`L~&aF=Ӌd="?\̈bDطl=HSN̢A;C) (TXA-Nفk1 ag,4L{I hEKbK!(7pOX_Μ8Bk[4e/ ^S7AboB \ 2%|cA˫FkT240BpN0J0 U00U0U% 0 +0U O fer0U#0C̛u]/KQ0:+.0,0*+0http://ocsp.starfieldtech.com/0DU=0;09753http://crl.starfieldtech.com/repository/sfsroot.crl0PU I0G0E `Hn0604+(http://crl.starfieldtech.com/repository/0  *H 33%ýB6,phiDmBϯi e̷JݙadrmDҺ?03ݶ")fPNwqcZ>,/H t87ޞ[Vb4˖ }{Z+Rrc"r(^&a D{-RķT=ayP[,e՞^T\m?^a_+}R00Ơ0  *H 0c1 0 UUS1!0U The Go Daddy Group, Inc.110/U (Go Daddy Class 2 Certification Authority0 061116015437Z 261116015437Z01 0 UUS10UArizona10U Scottsdale10U GoDaddy.com, Inc.1301U *http://certificates.godaddy.com/repository100.U'Go Daddy Secure Certification Authority10U079692870"0  *H 0 -&L25_YZaY;pc=*3y:<0#0=Tߙ %!e)~5T29&UXמ* BΧ?Rifھ],fkQJ/Hǘuع)fm x|z%.enjDSp0Ü+X+=tJQL'Xk5ŝ1 6:%IgE96~7qt0? O20.0Ua2lE_vh0U#0İґLqa=ݨj0U003+'0%0#+0http://ocsp.godaddy.com0FU?0=0;975http://certificates.godaddy.com/repository/gdroot.crl0KU D0B0@U 0806+*http://certificates.godaddy.com/repository0U0  *H ҆gf :PrJtS7DIk3ٖV0<2!{ $F%#go]{z̟X*Ğ!ZFc/))r,)7'Oh! SY ;$IHE:6oEEADN>tvբU,ƇuLn=qQ@"(IK4Zц6d5oownP^S#c͹c:h5S000  *H 0c1 0 UUS1!0U The Go Daddy Group, Inc.110/U (Go Daddy Class 2 Certification Authority0 040629170620Z 340629170620Z0c1 0 UUS1!0U The Go Daddy Group, Inc.110/U (Go Daddy Class 2 Certification Authority0 0  *H  0ޝWI[_HgehWq^wIp=Vco?T"Tزu=Kw>x k/j+ň~ĻE'o7X&-r6N?e*n] :-؎_=\e8E``tArbbo_BQe#jxMZ@^s wyg ݠXD{ >b(_ASX~8tit00UİґLqa=ݨj0U#0İґLqa=ݨjge0c1 0 UUS1!0U The Go Daddy Group, Inc.110/U (Go Daddy Class 2 Certification Authority0 U00  *H 2K>ơw3\= ni04cr8(1zT1Xb۔EsE$Ղ#yiML3#An 剞;p~& T%ns! l l a+r9 ͗nN&s+L&qatJWuH.Qia@LĬC Օb ψ2 +E (*ZW7۽0@0(5y0  *H 01 0 UUS10UArizona10U Scottsdale10U GoDaddy.com, Inc.1301U *http://certificates.godaddy.com/repository100.U'Go Daddy Secure Certification Authority10U079692870 120807154320Z 150924134423Z0k1 0 UGB10 ULondon10 ULondon10U Dalton Maag Limited10UDalton Maag Limited0"0  *H 0 YZ=&ȯ p)ZrYyW ,=|QQ7 Ex>+3>L woZ"Cs0J1*#\>xOh+w{wܘe,̵>%]D@E*v1,g6Fpgm# O8(z;+uKXF[cK d^<3 MD4ݽP;t#wE EiP%~"9":I00U00U% 0 +0U03U,0*0(&$"http://crl.godaddy.com/gds5-16.crl0SU L0J0H `Hm0907++http://certificates.godaddy.com/repository/0+t0r0$+0http://ocsp.godaddy.com/0J+0>http://certificates.godaddy.com/repository/gd_intermediate.crt0U#0a2lE_vh0U=QCo vڧԚ)0  *H !.w*=`oi e̦d`zBe+kCz~KMO> !X0jVfjݥ!rewQY!ivԣpƠkOw?szg9ӽd\:Nz %[n@Ԝ7*暹мmew"ɳ0oH;@']&l6$FM: Ej?:,aAr%'l3YZ5F9QY10001 0 UUS10UArizona10U Scottsdale10U GoDaddy.com, Inc.1301U *http://certificates.godaddy.com/repository100.U'Go Daddy Secure Certification Authority10U079692875y0 +0 +7 100 +7(10 *H  1  +70 +7 10  +70# *H  1c@kWRV0  *H ;y,#Z=xGM6z w_En v0r *H  1c0_001 0 UUS10UArizona10U Scottsdale1%0#U Starfield Technologies, Inc.1:08U 1http://certificates.starfieldtech.com/repository/1604U-Starfield Services Root Certificate Authorityl.60 +]0 *H  1  *H 0 *H  1 150710120401Z0# *H  1zJ|1"?240  *H 2M쫟\#C*L0 `'@+䤥e泹PN3MPM3P(J>J $M(`M4*4-!!b''x42!#:<!<!h4x(#(3VG4V4<4,4`+x#.A&45+.Ax.L45gg xDP+8xEg2+(j2j2j l:;V;V;V;V  D  V : : : : :4P :QQQQVaVoP + + + + + +[,3/3/3/3/3<M3>PN3N3N3N3N345N3>J>J>J>JMP + + +l:3l:3l:3l:3Vn3M3;V/3;V/3;V/3;V/3;V/3:B3:B3:B3:B3V;5;      KPBVBuV PVPV;V'VNVqNV>PV>PV>PH>V>P :N3 :N3 :N3uVPuVuVP!(!(!(5J5J5JQ>JQ>JQ>JQ>JQ>JQ>J V=!$=!$=!$P!(5Jxtx4x.x9xxUxGx$   VYggg(g%g%g ggg2gg gg(g%g%g gAj2jj2j j(j%j2jj jj2j(j2jj jj(j%j2jjj(j%j I)V445Y84 Lq4*454545(PPPPP PP42u"3&1"/gg2gg gg(g%g%g ggg2gg gg(g%g%g gx@xDND+AI`IM(M#h4#(G(MkVMPM ll:3.q.M3F3;%8<3:{PxVEV PV>P : :N3953MPuV'3!JPJ5QUJ4Q:=!$772(!(/;P``9,G VV(3VVNVV?P +  :N3Q>JQ>JQ>JQ>JQ>J/3 + +[,:N3:B3uV 5 :N3 :N37 VV(3:B3!VVV>P +[, :N3 + +;V/3;V/3   :N3 :N3uTuVPQ>JQ>J V;5V31O4=!$ +;V/3 :N3 :N3 :N3 :N3VP33 :3l#& SV>3#:M3jx6xx_x!x=xxxx"x]xAxAxxx;V;VVl:! V  VuVVKVkVVV;V<VVuV gCV :V`Vl:5K`8wVw:VVXVhVlV{$ +S>$PP[/3,UPUPPV CJPN3BPMP32JP.7PBPVPP"+P$/3/3;P3(B_ SP;PUP?PL3V :N3 4V`Pu `VMPVP pV P<,V"PVkP,_VUP/VPV\P:a3l:35VV N: .~:'V;PC C  VwV P a VJPVUP~A.CC V + +[,;V/38/68/6<,7VUPVUP :N3 :N3 :N3l"KKKw:.VPXVPjV4%4(404x*VV;V=!V : VuVgCV(% :V`V3!5V`8w/A4^3cPM374>PZ7NPDP2N3BPSJ3e3@J3JF9zQ #V&^37>P9N3@J@J@JF9xxwx^3^3^3^3^3^3^3^3 777777zz8)"=>P>P>P>P>P>P>P>Pqq>/LL N3N3N3N3N3N38@J@J@J@J@J@J@J@JcMF9F9F9F9F9F9F9F9:e^3^377>P>P+N3N3@J@JF9F9^3^3^3^3^3^3^3^3">P>P>P>P>P>P>P>PF9F9F9F9F9F9F9F9,O z^3^3^3^3^3^3^3xxZxxx6x!>P>P>P>P>P::Vxxx7  xxx7@J@J@J@JSJSJ@J@JVVxxx/F9F9F9F9F9qBsE%4xnxo qq:eV44CI   /( & ^z* !(x Zd   z //////z dd/ / / !!!!(((ĸĸĸĸ -+     ^Zzd* * *  ^Z^Z^Zzd0-+1KK  /(7f   -z*  ( / / /  !  (!/  / / ĸ   ((* / zd  /   / d (&T2 &  h/U!d = .( (d f& & #g`/ {+ zz # (dh#( |B/ /  ((dh/ ddd  /*( 1&zT=-. 2 ! /w/"z2///w//#/1 &0////////!wwwwwwww +//ww, wwwwwwww////ȸ//////zz('wwwww///  +/(-(Z$ 8 L  !!"!#"$$%%&%'&('))**+*,+-,.-/.0/102131425364768798:9;:<;=<><?>@?A@BBCBDCEDFEGEHGIGJHKILJMKNKOMPMQORPSPTQURVSWUXVYVZW[X\Y]Z^[_\`^a^b_c`daeafbgchfifjgkhlimjnkokplqmrnsotpuqvrwsxtyuzw{x|y}y~z{|}}~  !!"!#"$$%%&%'&('))**+*,+-,.-/.0/102131425364768798:9;:<;=<><?>@?A@BBCBDCEDFEGEHGIGJHKILJMKNKOMPMQORPSPTQURVSWUXVYVZW[X\Y]Z^[_\`^a^b_c`daeafbgchfifjgkhlimjnkokplqmrnsotpuqvrwsxtyuzw{x|y}y~z{|}}~  !!"!#"$$%%&%'&('))**+*,+-,.-/.0/102131425364768798:9;:<;=<><?>@?A@BBCBDCEDFEGEHGIGJHKILJMKNKOMPMQORPSPTQURVSWUXVYVZW[X\Y]Z^[_\`^a^b_c`daeafbgchfifjgkhlimjnkokplqmrnsotpuqvrwsxtyuzw{x|y}y~z{|}}~! % * - 1 49>BEIMPVY^afimquy} !"#$%&'()*+,-./0123456789:;<=>?@AB C DEFGH!I%J)K.L1M6N:O=PAQFRJSMTRUVVYW]XaYeZj[m\q]v^y_}`abcdefghijklmnopqrstuvwxyz{|}~ "'*.26:>AGINRVZ^bfknsvz~~||{{zxxxvuuurrrqqonnlllkiihh gfeecb"b  !!"!#"$$%%&%'&('))**+*,+-,.-/.0/102131425364768798:9;:<;=<><?>@?A@BBCBDCEDFEGEHGIGJHKILJMKNKOMPMQORPSPTQURVSWUXVYVZW[X\Y]Z^[_\`^a^b_c`daeafbgchfifjgkhlimjnkokplqmrnsotpuqvrwsxtyuzw{x|y}y~z{|}}~ '                                                                                                                    ' *                                                                                                                                              * .                                                                                                                                                                                           .5                                                                                                                                                                             58                                                                                                                                                                           8<                                                                                                                                                            <C                                                                                                                                                                                                     C F                                                                                                                                                                                                                "F J                                                                                                                                                                                                                         #J Q                                                                                                                                                                                                                         'Q T                                                                                                                                                                             (T X                                                                                                                                                             *X _               !                                                     # ! #                                        !!!!##!"       -_ b               "                                               $!" $!                                #""# $$"# !      /b f               $                                               %"$ %"                         !         $##$"" &%#$!"      1f i              %                                            '$ % '$                         "          %%$%## !'&%%"#      2i p                '                                !"        !    )&"!'  )&""     !!     !! !   !   $         !  "! !!!(''(%%"#))'(%&   " ! 6p!t               ! ( ! !                              "#    !    !"    +'#"(! +'##   !!    "" !" "  %!         !! "!  #"!""")(()&&#$+*()&'   #   "! 8t#{    !       # + # #  !       !            !  $%  ! #   !$   -*%$+" ! -*%%! !!   %$!##$ !$ !  !!(#      "!!" ##!" $#!" !!%%#$!!%%++*+))%'--+,()! "   % "!!"$#!";#{%     # #    !  %- %  % #        #         #  ### "  &'   #  % !  #&   0,'&-$ #  0,''#  ##  '&##% & #&  #  # # *%    ###$!! &%#$ "&%#$ ! ##''%&##''.--.++()0/-.*+# $ !!'###$!!&%#$ !>&& !   $ "#      &/ & & $     !!!$ !        #  ####!!!!!!!!!!!!!!!!!!!!!!!! '(  $  & !  $'   1-('/%  $! 1-(($! &&  ('"""%&!'  ! "'!    "# $!"!+& ""      $$$%!! '&$%!# '&$%!"  $$((&'$$((/../,, )*11./,-$ %  ! " ($$$%!!'&$%!"@&( "   & "%    "  (1 ( ( &  ! !  ###% "       "%  %%%%######################## )*  &  ( !$  ()!   40+)1'! %" 40+*%" ((  *)$""&(")  !  #"%!)""!! $# %"$"-( ""!   "   "! !&&%'##  !)(&'#%""""""""" !)(&'#$ ""&&**()&&**1112..""""""""+,4312./& !!' """""#!#!*&&%'## !)(&'#$C(* $   ( &!!'  $!  *4 * *  (  " " %%%' !!!!!!$       #!!!'!  '!'!'!'%%%%%%%%%%%%%%%%%%%%%%%%! !+,  ( * "% *!!+" !  62-+!4)# !'$!! 62-,'$! !!!!!!(( !  ,+&&!$**$+  "# " $$!' "+$!$## & ( '$& !!!$ /*! &!$!!   "  "" "!  #""# (('(%% !#+*()$'#""""""""!#+*()%& ""'',,*+'(,,433411""""""""-.663401' ##) !"""""%#%#-!   (('(%%!#+*()%&!!G(. '   ,! (!$$ +  ($  .8 . .# ,  % % (((+ !!$$$$$$ ( !! " # "    !!!'!$$$      +$  +$+$+$+(((((((((((((((((((((((( $ $00  , . "!% ( ,!$$/&! !$   ;71/$8-& $     +( $$ ;711!+($ $$   !$$$$!,,! $# 0/"! !*!!!( $ &!,.!'/$!"&&#% ('!$#"+% "!%/($'&& *$! !*# +(  *$!!$$$'#4. $ (!$ &%$ "$&$ %!% &$#!#&%%&##,++,)) $&/.+- (*'&&&&&&&&$&/.+-() &&++10./+,00988955&&&&&&&&13;;8956+  &&- "$&&&&&)&)'1$#!###,++,))$&/.+-() $$M,2 !+!    0! $"# -$''"#/  +' 2=2 2&/ )) ,,,!!!!!!/ $$''''''""""+ !!!$$""""#% & %$$$*$'''""""""/' /'/'/'/,,,,,,,,,,,,,,,,,,,,,,,,!#' ' !!45 02%!$)#"!,!1$''3)$$'#!A;53'=1*! '"""""!!/+#"'' A;5"5 $!/+'!! ''""#"$"!''''$11! !$!' & 43%$#! $-$$#-#'#+ $ 12$+4 '#'(*&) ++$'&%-'!# %$)!4+'!*!!  *"*" -' $#$ .% !!/+##-'$$''' +&92! !#' !-$'#+ )'''+! ' ($(+!!'&$&!" )(()&&0//0,,')32/0#+.*++++++++()32/1+-++//5423/044>==>::++++++++57A@=>9;!!!!/##))1 %'"+++++,*,*5!!'&$&!"&&0//0,,()32/1+-!#''T16 $.$    3$#!'$&"/'*!*"%%3"   / ) 6B6 6)3 ,,# ///$$$$$$2!''******%%%%!".    $$$!!!!'"' $$$$&'     )"('''-'* * * """%%%%%%3)3)3)3)2//////////////////////// #&*  *####89 36 (! !!$'," &$#/$5'** 7,& " & *%#F@97*B5-$ * %%%%%$$2.& $"* * F@9$9#'$2.* $$  * * ""%%&%'$ $* * * * '33$#!#'# * #!)!87("' &$!#'1''"&/&*&!! /"'"56'.!!8" !)  )  + .- ), /.  ' * )(!"! "2*#&!#(!' ,#8.*!!#.$#"#-$-$1)"'!& ' "1)$$2.&&1)' ' * * * !   ".)=6$##&*"#/'*&!/"-*!! !  !++-$"*+',! -!!!!!!!!$$*)')$$""-,+-))433400 +-7634&/2.--------+-7634/0!! --!!!!!!!!3398683388CBBC??--------:?!!!!!!!$$$$3%%--5 (*$-----0-0-9$$*)')$$))433400+-7634/0$&**[5: '!2'!!!!!!!!!!!!!!7&%$)!')$2*-#-$"((6%"!!"" "!3!"""!-!!:G::,7" !!!"/!/!"%333&&&&&&6$!!!!**-----!-(((("#$2 "!"""""!"!!!!"&&&$$$$)$*"! ! ! ! ! '"'"'"'")!*!-$+*!*!*!1!*!-"-"-"$$$"""(!(!(!(!(!(!6-"!!!"6-6-6-" 6333333333333333333333333"&(-! !"!!!! -%%''<=!  7:"+$""$$&*/$""!)!'&3'8*!--";0)"$!#")#-(&!!!! !!KE>;-G90&-"(!(!(!(!(! &&62)"'"$-"-"!KE>'"=%*!&62-"&&! ! -"-"$$(!(!)!'*'"!&! -"-"-"-""*99&%$&)&#!."%$!!,$=<+$*")&$%*!4!**$)2)-)#$""2%*%::*2$$<%# # -###+""""-"/0#,/ !21!#!"*#-"-!+#$#"$ 5-!& )%% +#*#/&<2.#$"""&1&& %%!0'0'4-% *#)"*#%4,&&62! ) ) 4-!!*#*#-"-"-"$"""%2,B:! !!&%&!!)-$&2* -)#!""2%.-##"!#"""#$!-//&%-/*"/#!"!!!/########&&-,*,&'%%0//0!!!!!!!!--876833"""""".0;:78!!!!!!!!)251////////.0;:7824##!!""!!//########77==:<77!!!!!!!!==HGFHCC////////>@KJGHBD#######&&&&7!!!!!((009!!!!##!!""+-'/////3031>&&-,*,&'--876833.0;:7824&)-!-b8C"-&9- &&&&&&&&&&&&&&@,+*0&$-/"*#;14)4*$'.->*'&&!#''%'&#<&(''&"4"! &&C R$C!C3?'&&&'!7!&7&'+!;;;,,,,,,?*&&&&1144444&4....')*######:%%%%'&(((((&(&&&&!'!,#,#,#****0*1'&%&%&%&%&%-'-'-'-'/&1&3""*#2$####$1&1&1&8&1&4(4(4(***$$$'''.&.&.&.&.&.&>4'!& & & $'>4>4>4'! >;;;;;;;;;;;;;;;;;;;;;;;;',/#5& &'&&&&%4++--EG&!"$!% %%@!C!!'2)''**,"17*''&/&$-,<,#"C1&44(E70'*$&('0(5/-&& && %$!& &VPGD4$RB8,#4(.&.&.&.&.&%,#,#?:/(-'*#4(4(& VPG-'G+1&,#?:4(,#,#&%&%4(4(**.&.&$/&-1-(& ,#&%4(4(4(4('!0BB,+ $* ,0,(&#5'+)# &&2"*$"FE2*1'/,)+"0&=&11*/;/4/)*'';*0*BC19)*E+#(%(%4!(($(0'(''!4"'$68(3#!6%%%&!:9&$(!''1(4(3&2)*#)'"#*$>4&!,%0)+%2)1(7,E:5)*''"'",#9,,$+$+&8-8-=4*$1)/'0(+$=2,#,#?:&%/%/%=4&!& 1(1(4(4(4(*!'!'!'!*$"93LC&'&&,+",&&/4*,;1%4/)&'';*75))"'"&($"'"('()'4"68,*461'6)"&('''8)))))))),,4312,-""""""**7668&&&&&&&&33@??A;;#""#((((((57DC?A''''''''/:>98888888857DC?A:<))""&&((''88))))))))??GFCE?@&&&&&&&&FFSRQSNN88888888HJWVRTMO))))))),,,,?&&&&&..77B''''((''''24-88888;8;8G,,4312,-33@??A;;57DC?A:<,/5&4qCN ~17HQS_awx67O_cuEMWY[]}    " & 0 : D p y !!!"!&!.!T!Z!^""""""""+"H"`"e%  28IRT`bxy78br HPY[]_    & 0 9 D p t !!!"!&!.!S!U![""""""""+"H"`"d%feAa&`HH z@:*߶1mTxS/3)ߘߕߍߋ߈߅y]FC# zlpRZXt<ghri_kwlxmynocpqestabcdue   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ag}~rv|df{mystpqnoznblxhcej iuabced_@?XUTSRQPONMLKJIHGFEDCBA@?>=<;:98765/.-,(&%$#" ,E#F` &`&#HH-,E#F#a &a&#HH-,E#F` a F`&#HH-,E#F#a ` &a a&#HH-,E#F`@a f`&#HH-,E#F#a@` &a@a&#HH-, <<-, E# D# ZQX# D#Y QX# MD#Y &QX# D#Y!!-, EhD ` EFvhE`D-, C#Ce -, C#C -,(#p(>(#p(E: -, E%EadPQXED!!Y-, EC`D-,CCe -, i@a ,b`+ d#da\XaY-,E+)#D)z-,Ee,#DE+#D-,KRXED!!Y-,%# `#-,%# a#-,%-, ` <<-, a <<-,CC -,!! d#d@b-,!QX d#d b@/+Y`-,!QX d#dUb/+Y`-, d#d@b`#!-,E#E`#E`#E`#vhb -,&&%%E#E &`bch &ae#DD-, ETX@D E@aD!!Y-,E0/E#Ea``iD-,KQX/#p#B!!Y-,KQX %EiSXD!!Y!!Y-,EC`c`iD-,/ED-,E# E`D-,E#E`D-,K#QX34 34YDD-,CX&EXdf`d `f X!@YaY#XeY)#D#)!!!!!Y-,CX%Ed `f X!@Ya#XeY)#D%% XY%% F%#B<%% F%`#B< XY%%)%%)%% XY%%CH%%`CH!Y!!!!!!!-,CX%Ed `f X!@Ya#XeY)#D%% XY%% F%#B<%%%% F%`#B< XY%%)) EeD%%)%% XY%%CH%%%%`CH!Y!!!!!!!-,% F%#B%%EH!!!!-,% %%CH!!!-,E# E P X#e#Y#h @PX!@Y#XeY`D-,KS#KQZX E`D!!Y-,KTX E`D!!Y-,KS#KQZX8!!Y-,KTX8!!Y-,CTXF+!!!!Y-,CTXG+!!!Y-,CTXH+!!!!Y-,CTXI+!!!Y-, #KSKQZX#8!!Y-, IQX@# 84!!Y-,F#F`#Fa#  Fab@@pE`h:-, #Id#SX<!Y-,KRX}zY-,KKTB-,B#Q@SZX TXBYY-,Eh#KQX# E d@PX|Yh`YD-,%%#>#> #eB #B#?#? #eB#B-dA  0P`69F AU UU/(F@F߳@@ F@P`` }G2}HdOo@8;F}>"d 0P`@ʇ69Fυ ~y3}{7|yd{-z_yoyyxtwu~vsdu}t`spss sssr~oUq~pUh[[Ug[_Uf[]Ud[ZUc[\Ub[YUXCVUWCUUSMURKUQJUPIUONU/NIIIG[CUF[BUE[AUoATSKRKP[%S@QZUZ[XYBKSXYKHSX@YKSXBY++s+++ss++++++++++++++++tu++++++t++++++t++++++s+++tu++++++++stu+++++++++++++++++++++++++stts+ssss++ss++++t+++tu+EEGGGo GbHNgCDh;aIfNO :TCn]D`LETPk=\`3LQuY2EH]O>Bn /rRn=*X<R5NPH>b]`TP DDDD$X0  t p x@0` th$  l ""l"#h$$&'|()+D,D-.P.01334d445(556H789:<<<>8>?d@ A`ACtD0EEGGIDIJKOPR RSlSTlU,VVWWWXdY Yp[L[x[\]@]]]^$^P^_4`X``bbPbPbcdefgii|k$lLldllnnop`q,rrlrststttu0uHuhuuvvvww@wty0z{||<|l|||}(}\~H~t~~~(\LxDp<8@lt@p, Hp(T|(T|@PT4\$LxDp<(T|,X 4D\tPXHt` Hp0 $Lx8`4\|hhP,T$H|HpHt0XP0xLL|8l4XŠƈƜư(<Pd<|ɼ,ʜ |˼<|,lͬ,lά\ϴ dмD4DX֐ 8 0@P`pۀې۠۰ 0@P`p܄ܘܬ$8l<tބޔޤ޴$4DTdxߐߨ߼d(Xd xpH |Ld Xx      t8 8d|,<T  4 L d |    !!D!l!!!""L"""#,#d##$$%(%\%%%'(\((() *,,H,p,,,-- -8-d-.@.//@1D1l11122L2223 3@3p3344,4T44455D5x556686d6799D9p9;h<=>?L?x?@BTBBBC(CTC|CCD D4EF|GpHIKMN\NOQtRXS\T`UVVWYPZZ\X]H^@^`0abcdcde<efghiijXjkxl4mmLmnnppppppqrspssstXthtxttudutwxxyyyz\zlz|zzzz{ |P|`|p|}l~<~DPdLdt( `p  lXD\t $lpPP, D<`0T<8 Ĕ 0@ƴ,ːL|8hx\׀אר`pH$|,x(hx(| ,D\t $<Tll ` 0@P`pP`pPdP<( p 0P   P    $ x    8 `    $ T |  8|(TP4<(T0H`x,`$<Tl<p<p0XLd|0`(XpH|  L d |     ! !8!`!!!""4"`"""##8#d##$($p$%%H%%%%&&0&P&p&&''D''((D(((())$)D)d))**D**++X++++,,<,\,|,,,-4-\--...4.L.d.|../X/0011<1d11111223d404\4455,5h555567,788<8t8899,9d9999:::;;H;l;;<<(<@><>\>|>>>>??<?\?|????@@<@T@l@ACCK|OQ,2@  //103!'!222vG #@   c[??9/3210#.=3#"&54632 : d$$$$TDDT((((HZ&  1j@              ?        /!0 yA y B BA???]?]]]+}]]+}10]]3733#3##7##7#537#537337##T#Xg"#T##T#Xf"#TT#JJJJL=3@4))(W%%h Y  +) `'+- $ $s  $ 0'--0'''''5 104jw & f   10,*--g-w--Jx?O/]3]3]2?]]33299]]]]]]2^]]]]9/99+}2/]2]10]]]]]]]]]]]%2654.'.546753.#"#5.'7M>-;;.UQS,LH6,GW ~ K2(3?C@fCA@ABCBCB@B@*  )  : 44)44?***&**E  &  & )DCABBAB@A%}7=}/F}}E??????^]]]]]]]99//+}104>32#".74&#"3264>32#".74&#"326#2+:"":++:"":+*''**''*+:"":++:"":+*''**''*7&54>3267#.'#".73267'4&#">.)6J/A'(?+'2" M!#;b #)lFAV5] 3&1S %-',/D''=1%JO(@,(8#8.&?M )a0&J#*)3%9D!*#$! #0Q"/5'A> ")H @   Z?9/10#.= 7 21k55k21NG= a@B *           m }   W db?3?3]]]]]]]]q2]]qq210.5467JHBN__NBHJ+]-__-]G a@B % brX bd?3?3]]]]]]]]q2]]qq2104&'7'>JHBN__NBHJ+]-__-]%7,@yvxi#@]H#""t@{ H,,**' .- 7' !'##+de+[?2/2]3]9/93233]339/33333/3/3/3+3/]3]]3/]]3]]3/3+10]]]]>?'.''7>7./7.=3$F)(P*!:I##I:!*P()F$Z*M)&T 5#3$G&&G$3#5 T&)M*55! 1@ P  /]3/9/2103533##5#5PPSO&ar .@ H  ? O  /3/]9/322+107'>54&'% Hr?{83i.  W-@@@ $H/+]10^]3#WW8y " @ H  c?q+q107#"&54632$$$$6((((G'@ddbb????/և+}10#3G_S]2 ݵMM@ MM @M M MMM@*M M M @M@ML L!MML L M @M WMMX?++?++++++++++10++++++++++++4632#"&%4.#"32>2{mm{{mm{n 4&&4 4&&4 [9fL--Lf99fL--Lf]q P@5 _o 0 P ` p  UV??9/]3]]9/^]]3910>73#]9l-B] #)-&E4K4 8,@/ @M@ L.$%k {  -$M$M$@M$ML LLM %L% M%*L*M* L*@ M*X U??++++3++99+++++2+++q2++99//+}10!!&454>7>54.#"'>320<-(?\2>-# +0&. $2>$mm$CA?.2.O /QH@//2* B e78@!!!MM6M4M@bMYi#####+{&]&m& & &5jIY++++:659&& 65M50L0W LX?+32?+3+29/9=/22^]]]]]99//]]]]]10+++++]]]72654.+532>54.#"'>32#".'7YM 4E$!5,!+0C$ %.57P4>,2%AbC70$ODF;&4 L -"( G 1C'6M.<%-M8  Q( k@?(+(8   ;_o   UV?3?9/3/22r^]22/^]]q210^]]7>733##5!3(BS_0YRRZ6=:3,u|x0HL OVZ+A'@ M M M@;MM"j)##    (#" LMM@ M M V M LW?+3+2?9/+++++229+}^]]10+++++#".'732>54.#>7!#Ǘ?`B6.$M8-=&BnTNxg.N8  Q"-&;(1VRQ-O374?--M$MM @9MMW0Y++w/  !GW. &@ L&WMX?+?+9/32]2]2]]9/]]310]+++++4>7>32#"&7"32>54&?8g\;aL4 A#;R45R8rw#< 4(!. Aej7N4S= $;M*&PB*  ,N;#,3DH<%@U V?2?9/103>7!5!-BO&!PG3P-QM&]7!3E2M2@ M.M MLEM@M4@!LCA A1//M/A / A//A@7MP M_   ,vG>L" M F 9 LX'M'@ M LW?+++?+9/3/++]]99//]+]++}++10+++++++%#".54>7&54>3232>54.'4.#">9V8AW4)b7N08P3%v 2&"3 -?(-1 , - "7&*2*G5%8C5.%8m&E4"5@3," 8'!( 0$ J0$%,& C3-@ $ M MMMMMM@) M ! L!wOh/+M+@M+M. @ M &M&XMW?+?+9/+32+++^]]9/]]]3+2210++++++++'2>7#".54>322676454.#"?eL3 B#;R45R89W;#> 4(!. AN5T= #;M*%PB*(Lm  +O;#+3DG8&@  PO++4&a&@ PO++45L `@& M@ MP/]++//+}/+}10%5%cP+MPM5.@ ?O0@/]]9/33/3107!!!!566O$O5L d@"@ M MP/]++///+}+}107'%5PcMPMy!- M MM@6L"(@8H((Xhx ' 7  ///. ++%cMLh?3+2+?q2]]]9/^]3/+10++++"'>32#&54>54&#"&54632B?"U09I,&.&N$($6 $$$$w"H0;"5.*-5!  4-'(,*5((((AguEU@DCCg?U?X5)##i IM.//VxYAAAAAAWS y  v&&&'&7&W&&777VMP3232>54.#"3267#".54>32'267.=.#" *>0O: ;U63U' ,RuIIzX14]L;M Y3YvEDsTRn@4H+"GFD+ ;V90U?$ $:I&?oT01[TXY-J3iplk65eZDhG$Q  XCGTܹ@4 M     L s  @C M s  @py_o B A AB????99//]32^]]]q9/+}++}+10+!.'!#>73.'%?e(FCB$Y$BCF( ?"#?-W-nKKnWKKWVP)8W0vML@ M$v@ L@L@ M0M::@ M8s985| *y)) E|F?22?39/922+++++++2+10]".'>3232>54.#'32>54.#"11001032.#"3267IxV/5ZxD+E3  "+37X>!:W:CX$6H0\WW\0 P &Hg@>fI( P V@L M MMv@ MM@L@ Ms M| M E@ M|MF?+3+2?+3+2++++++++10#"&'>322654&#"8fU*e))e*Uf8)- -[ZW+  +WV 5@   s y y ByA??9/2^]103!!!!!V"_SQSV (@ s y ByA??9/2103!!!!VSR:^'ѵ M@,M M's@M@M))@M)@ M)M@ Mv @M M @ M @M (@M M|@ LME'$M$ M$|F?3++2?+3+9/+2+++++++]++]++210+++3#".54>32.#"3267a -;F$IxV/5ZyE/I4!`25W=";W;*; U 0\WW\0 Q&Hg@>fI( Vk 7@ s  s yABBA????9/2^]103#!#3! aaaaSK@V$@MsBA??]+103#VaaKy@ Mgs@ M@ M @ M @ M  A @M|  L MMMF?+++3++2?^]++2+]+10]+%#".'7326535YC"9." &C2HBa2VA%  M!IYVo@`MYy M   M H  (  s Ms)9 @/M0 P `  sA{AB BA????9/]q9qq?22]+]]+}]q+3^]++10]]]]+]+#.'#3>7WNUT%+`\QrNWY*aa#TRI"SWT$Xdh//_WJ!STMV@ sAyB??10%!3_aTTC%)J%M$M!@Hf!! fMW@9M i iWs+ M+ Ls@$ H"sO)vO@& H  L s  *@H|))BAAA" M"L@ H|A B??]+]+2+????9/+^]++]]]]]]2+++]]210]]]]]]q]]]]+]+]]]]+++%.'#>73>73#&' !&+&! _  U>>::>>U"_ !&+&! `JV[Q@vZK,x66x,v@Q[VJV@  w  s  s@ L@C Ms BzkZIbr@P4A A ABB?????99]]_]]]]]]]?^]+++}_]10]]!.'#3319BGFB_M/ki] _%\cf_T 25K:' M M@M MMM M MMMM@MM Mv @ M M @M @ M ))M@ Mv@MMM@M(M M@ M|F#M# M# M#|E?+++?+++++++++]++++++10++++++++++++4>32#".732>54.#":5[yDCwZ55ZwCDy[5f ;U55T; ;T55U; [Y[..[YY[..[Y?gH''Hg??gH''HgV=R M M Mv@L s y B| E?22?9/2+10+++2+#>"32>54.+QtIMa)e2>!I2P75Fon32.'.732>54.#":5[yDCwZ5(G_6'32"32>54.143j/0/ Wa)e*I>!E2P73E"AOV(&NG> nmEb- 3*'4 !0@9'  &"%!!!s!!v%L% L%@a Mp%%2v M M M  M .-@H-1y=M tBG..g|-MX--(FwV|@MwVE?3]]]+2]]?3]+]2]99//]]^]]]]+2++++]+++99+}]]]]]210]]]]]]7254.'.54632.#"#".'7.;!&D2|m?gS70$(5 -K7y)E6' ^Eh -! !->,[fO  %& $2E1[b P %:@$ sByA??^]]]]]10###5%aTaTQ_Y@. M M M MssAA | M MF?++??]^]10++++".5332>53XDd@a\J%=,aAc*Id:Xh^0K4M:dI* @*xg7 G w   x 8H@0 L s  L  s   LHs@L   A A ABBA??????^]]+++]Ƈ+}++}+]]10]]]]]]]]]#.'367&EBA"["ACF%k6h77h5nKKn܀% ^@$8  M8x7w @ Mt@U Ls""7 6s { L s@`M6)IY sp   !BBA Mxf ` D T  AAABB?????99]]]]]]+3???^]]]qՇ+}]]]q+]+}+]]q]q+}]]q]]]+}+]q+10]]]]]q]q+]q#&'3>73>73#.*V+a5Q#f (Z'T'\( c$Q4a,TֆlTN9ii8Nlc㳠@, HM        L L@ L  s  @H LM Ls@P`/   BAAAA B BB????????^]]]]+}+++և+}+++10]+]+]!.'#>733*2661+k-wCpoDx.IOO##OOIX`GaYP @R L  s  o  s Lso B A AAAB??????9/3/^]]2+}+]3+}+103.'3>73Ez6r&^21^'l6zDkdRNNRdj!M@*   s yA y B?2?3^]և+}ć10!!5>7!5!=DHE> 9AFEAhIYced-SA(`df^RS`GA@  //103#3#`ኊIIG)@bbdd????/Ƈ+}103#]S_8G@  //10#53#53ኊI6I/;l@B8hx7gwJZ/]23/3/3/2/2/10]]]]]]] 'CJJ&&TG@ K?3/3/10!! jO=D7@ LM M/+++10'y/*+5@ ! M,M"M@M M)M)@ L@ M8 L7723@ L3 @ LM@MP L@M6)$@M@ M@L@MQ2/3P?32?329/++++32++++++2]++++10+++++%2675.#"2#".54>3254.#"'>!3 - /'@/8M/ +6?,J6#&-# MP! M@+ MMMM L#!"N L M Q!L!@ LMP?+3+2+?++32?22++++10++>32#"&'732654.#"E-8W<%D`32.#"32672?_A #@]9#F 7NS)@.%< &+ (Hc<32@&(9$ZK&3] dA<`D%32!3267#".%6&#"3(BV-ipRW1C U6Dc@eA9 1"EgD"QTN )Hcn?Q(4PD@!  J ILMO?+2+2??210]^]2.#"3##46);  , A4]b P G<-NF7dm3D-( M' M#س MMM M @ M-@ L@ L/%M% M%@ M%@ LL@M@ MHM.@!LR" P- L-* L/^]3+2+?32?+32++++++++2++210+++++++%#".54>32#"&'73265.#"3267 E./S>$"A^;Aa!|~1W Q,SI/(KQ'3%>4?^A9_E'0xl Q BHbQ-@*Pn MK L@,M  @ L @ L OJ JMPN??+2??2]q++10++]+37>32#4.#"P];>R1] 2%  #?X50D*PB3@ @ H SIJ???+22^]103#3'"&54632]]/####^!!!!EO L@M  @ HS IR?22??+32^]10++"&'732653"&54632 &  0)][,####L;9da!!!!!P@M MM M @ M  M  M MMMLMM@LM M LL@MMMM@" H I LIN J JJJ??????9/+?+++++}+++++++2++10++++++++++#.'#7>73 CA:m7<>]]:82m6:;DOQ##IC8&:<7<==N =@ ML  L @ H  N Q??+10+++.57VH] FJp P-!@# ML MLMгM L M سM M @M M MLMLMгMM/ L/@7 M/@M O+-.,JJJ+&&M M L P?+3+3/32+2/3???^]q29]+++10+++++++++++++++++++>32>32#4.#"#4.#"#P iE2D,6".B,IPn@M M MMM@M J JMP?+32??]^]10++++++>32#4.#"#P jE>R1] 2% ]#?X50D*I3س M@ M( M( MM!!@#M @ L @ L MMPMMQ?++?+++++]+10++++#".54>324&#"326$AZ55ZA$$AZ55ZA$aODDOODDO>dH''Hd>=eH''He=XggXXggPG!z@X  M MM0 MMMMMM L#"PK L  LQ?3+2+??322++++++10++++4&#"32>7#"&'#>32ZK*/@&(9$a32#5#".$9(&@/*KZa%D`  3(3]!bQ K (-:%س M%@M 0 M @M M+@M& L%M"M"M"@ M!M!M! M L @ M M M@BMMLM L!!!$/?/ *.MM+M+@M+*'QMP?+32?32++99++]]99+}10+++++++++++++++++++++++72654&'.54632.#"#"&'7976>7(fX,&@-': (%:)kcENFC!"( "0#EQP! $3%HJPJ^@/? M  @ H O @L  L MQI??++3+22]+310+]3#3267#".57 $*3 F-5E*]N'3 M6O4JP@!MT  I I@ LLQ?+3+2??]^]10]+%#".5332>73 iE7'i1T1i'd !%&&%! jj 1omf((fmo1$@ @&MMM MM@M(MM#M@ MM$ M$L$ L$@ M@$4$$&*H$@ %Hr$@$P$`$$@H$  !$!$&!M!M!M@J M ML M M[ (+H}_oJM@M(M M@ M LMM@ MM@M M M@ M6vdRF?OM MLM M MO;@&*H %H}O_o H    M@ MMLLM MT@'+HvDd@HMM M M@MM ML M M6 gVJ?O_@`@    %$J!I II$dt+k{I I IJJJ??????99]]]q]q3????^]q]q]q+}]]]qqqqqqrr+++++++++++qqqq+r++++++++}+qq++rr++++++]q+}]]qqqqqqqrr++++++++++++++]qqqqqqqqq+r++++++++Ƈ+}+qq++rr++++10+++++++++++q!.'#&'3>73>73?>Q.X'd "! M !!  `'X.HddHg/nnf&/ikg--gki/&fnn/g@$F  I      L@ L    @0 L L   JIIII J JJ????????^]Ƈ+}++և+}++qq10!.'#>7'373 &((% `#a0i|}c0e#698996D@AED MM@ MMM  M "@L@ M M@ M    &M '*H       ! RII I I?????329q^]2+}++++++Ƈ+}210+]++]+]++3267&'3>73#".' #7>?m$d &,&8`$X3+4A) a 17x -hnn3imv-A*$A@%  I J??^]]և+}10!!5>7!5!EOOsFMIwTfp3N>,ji] N(GE(Z@   @( H((b(r(("" H")(  //9/3/+]2]]+2210^]]2>=4>;"3#".=4.#(" ,I691# #196I, "O#)@+I):BHHB:)I,@)#`G//9/103#`WW8G%(^@$g    H"m}@ H*((  //9/3/+]]]3+2210^]]]"+526=467.=4Ȕ3%" ,I691# #196I, "#)@,I):BHHB:)I+@)#*~!X@: y!Pp$ )"!  /223/]]]10^]]]]]#"&'.#"'>3232>7 1#32 @1#32 e0+ 1+ -'3@y'X&.!"53*G1+(....F...4!!!%11((+"""%%Q T?]]3]]2]?]3]99//23/33/^]22]]]]2222]2222]22299//3310]]>32.#"3#3#3267#"&'#53&45<7#5j,:9&9)YC*=T3uZRRuu P (9#H   HYF O qH   H!r 4@ H  ? O   /]3/]9/322+107'>54&'&Hr  4f,,Z'  E_@  M(M L@$M M R IO?22??3222210+++++2.#"3##"'7326546';  -D4[Q)  /(a P F=-NPda L;9.dm!er&ccby&*'w'oF@* O_    L?//9///^]]]]210#.=#53533 . PTDDTMM'ox@L O_O_    L?////9/////^]]]]]]]]223310%#.5#535#53533#3 . PQCCQMMMM4FD.@P_/3]3/2/]2/]10'''aa',XX,23?CWc@CA@ABCBCB@B@*  )  : 44)44?***$** DD)DD^ XX)XX&NNNNe  &  & )dCABBAB@AI%}[7a=}S/F}}E??3222????^]]]]]]]]]]]]99//+}104>32#".74&#"3264>32#".74&#"326# 4>32#".74&#"3262+:"":++:"":+*''**''*+:"":++:"":+*''**''*32!!!!!!&Gf?! ,?fG&Qe9:eQ8P`9[@dE%%Ed_,XYYX,QOQ< KM@&M: + @  /?o/]]3/]22^]]310++<7>7<&H  4f,,Z'  ! )@  / ? o  @/]3/]]3210'>54&'&H  4e--Y'  <&nn!e&oo44 /9/10#".54>324!//!!//!a.""./""/S/10!! SOS/1010!!SOg`U@7iy/  4D9I/]3/3]]]3/32^]210]#"&'.#"'>323267`## 0##   h0D0@SH0  p  p++"K&@H&%!!!!"10[%[+t++[" /33?229/3]]??]]+9/]]]]+9/]10###5!#.'#.'#>73>7.iEi F 1 E B ==3{99832, ,23899{308::80(&V_#@ .2*#P 3O++4(?(@@H/322+22107'7'7iAooA?##3}'3<@hw$%<V.f..  =<gP7I+Y++P$!!F1V11Q%hQ?]22?]23?]2?]39/^]]]]99//]]]]2]99310]"&'#".54>32>32!32674&#"326%6&#"Oi b?5ZA$$AZ5?c!e6hqSV1C UODDOODDObA9 1! :368'Hd>=eH';386  PUN XggXXgg?Q(4Pz&<o@% POO+++44GG #@   PK??9/321074673#4632#"&X : d$$$$TDDT~((((V$l@C@H &&V%FV  J IY P?^]33]2?]33]2]]]229/+32104>753.#"3267#5.V1H-S:47NS)@.%< D$S0H0#1VD. M ^Z(C0L -CV<"M@TMMM M M$"s L 0#|y gEy B??]39/^]3/22]]+29/210]++++++3#!!>=#5354>32&#"!v ]]9P0,<5<,uK2n2PGGKSJa9 P&@0,mI2@`4/4O4 e u   jz))3jz eu$$$$..../]]3]]3223]]3]3]]32]23]]310^]47'76327'#"&''7&%4.#"32>YI:J/;;.K:JJ:K096J:I7 ++  ++ [=-J:KK:J5 4J:JJ:I->.!!.-!!-$@n s os  s  o   yyBAA A AB??????9/3/222^]]22]3]+}2]3]+}2]1035#535#53.'3>733#3#6a+g$T-,Q%e,a6jGfGXRNHHNSWGfGj`G@  ZY??9/21073#3#`WWWW+;Q @%67++(WE7 7432/e+  JM-58 6* *27227--S?B;#8R w?2 22J*v**k*V*?z?m?J z i Z  J?*S;;8Q?32]?3]9]]]]]]]]]]]]3^]]3]]2/]2]22]2]]99]]2210]]]]]]]]]]]]]]]]32654&'.54>7.54632.#"#"&'.'>54.DH8896@$A1 aX3XE4'9 ($A1$jbCW $)8! $(4 !$#' (8(-% 4"EQM !! (8(,$ 8%KM 3# 2##hU )@ H@ H  //3/++10"&546323"&54632]########h!!!!!!!!A'I@7EEhwXh( K>>>>>w--gwW g   &  J88;}7p2a22}gHXEDA}E(n((#####}hGWF?]]]]]]]22?]]]]]]]22]^]]]]]]]]_]]_]]]]]210#".54>324.#"32>".54>32.#"32678^|DD|^88^|DD|^8I(Gc;;cG((Gc;;cG(+F34F'+  5#3D><'3"+[U]11]UU]11]UBmN**NmBBmN**Nm4M21L5 <GD>O< &IP1@*HXHW%%%%Wg&6F3/@ H/  IYi@$ H2.+%""" /h?39/]^]22+]]+]]]10]]]]]2675.#"2#".54>3254.#"'>, "#/")8#R)!7(,: " 7 =d ;$3  , , ? ?&ll55@ //99//10#!5POWA'=HE@V757E754E4U4 w4((BBBBw5+++88==5j5'5W55w(Xh J,HHHHu.Y.i..@.)..w  & V f  I>>>{8 +0+++-E}2a2U22F22}gIYE=-n--I-Y--#####}hFVF?]]]]]]]2?]]]]]]]]9/]3]^]]]]]]]]2_]]]]]]]2}/23]]2}/10_]]]]]]]#".54>324.#"32>.'##>32'32654&#"8^|DD|^88^|DD|^8I(Gc;;cG((Gc;;cG(9CG<VZ'$  &-<9(  [U]11]UU]11]UBmN**NmBBmN**Nm-Q@A%7 $,0'%.J@0/]]3/2/10!!.H2i@H   @ H  ! F=&h H/+]?]]]]]99//+^]]]]10#".54>324&#"3262&33&&33&C++++} 4$$4 4$$4 #))##))5l `@:   /P   \ @O  _?]]]3/?9///]]]3]23103533##5#!!5PP6OO;8!_@; # 3 gwV    #"I  fvUFq?]3]]]299//33/3/]]10]3!&>7>54&#"'>32( *!&"+!$E-EBV(''! ?!3*#1 1#: 36-g@$$7gv" *"@H"/+`**. +*'q?32229/9]22+9/]310]^]]2654.+532>54&#"'>32#"&'75((%.C"I=7#)(?,@1q!9 7 ;.1 3#+! < D;8@@L@M M/+++10'7;/͉*PG8@    IK0 HQ I??3+??99//21032>73#"&'#>E ] e<7A\_L9g+G!1@uu CEC??]?9///10"#.54>32#.No|-TxJ*`)N*o hf7R8 #8iEC2@  ij??29/9/310#"&'73254&/>73 (+ $ @%! 9   "2; .@   { p?2]]9/]210>73#2&J1F9m )~&+HZ@>     ! hg??99//^]]]]]]]10#".54>324&#"3260B''B00B''B0J73287337+F22F++G11G+8CC87DD(?&xx2R&'nkp2;&'nV R&'nzpD!-a@>f "((p/@ H.+%Py  )  R?]3]2?+]29/3/^]10]]327#".54>5<'34632#"&~71B?"U06H-&+&N!(!%$$$$&1"H,7!4/*/4!  4-((*((((&$C@ P O++4&$@ P O++4&$i@ P O++4{&$u@ (P 'O++4z&$@-P %O O+++44G '3" M @H .@H..1@H(@RH((11 !"#$$$s'&%$$s$$5@5p5554HW@- H+1 y'@!!!$$z$Y$i$!$!$1ABB???2/99//]]]]]32+]+^]]]9/+}+}ć33/++3/++10+7#>7.54>32#./.'4&#"326?e%B?=!%%!>?B&j ?"#?fG*%%)Gg-X-OWKKX@F Hs syy   yAyB?3/3/?299//329/32+}+10!!!!!5!#>7!3i FZ/h9mhe2s5r=dOQ,Y-lGLHj:CS@@LB@ Hd.S.B.#.3...U*#*3*C***h)9j/z//.s***b*E*U*@~H*>:>>4,::"#BvhWA18>)J"Z"j""Wg|J#Z#j##h&x&&W&&FEUeXh|EUe g X  E?]]]3]]]2]?]]33]]2]]]]]22/39/]10+]]]]]]]^]]]]]]]]]]+.54>32.#"3267#"&'73254&/>J>dG'5ZxD+E3  "+37X>!:W:CXkR (+ $ 7[}OW\0 P &Hg@>fI( P  ! 9  V&(C@  PO++4V&(~@ # P O++4V&(im@  PO++4Vz&(m@  PO O+++44&,C@ PO++4D&,@ PO++4&,i@  PO++4 z&,@POO+++44%w@M)iy vVf''p''# s & y !!| WE#|XF?]3]2?]3]29/3233]]]]^]]]10#"&'#53>322654&#"3#8fU*e)PP)e*Uf8)- -[ZW+ 9K +WKV{&1u@ # P "O++4:&2C@ +) P*O++4:&2@ *( P)O++4:&2i@ -) P*O++4:{&2u@ 7( P6O++4:z&2@*< P4O(O+++44Pa @X `          /3]qr33]qr3/]23/]r39/3]qr3]qr3/]33/]r310%''7'77888a888:$/l@&E.e.6-f-,xh9(JddfMY  @TMF j l My..Z-Z,f)U(H#VETWejY j w)9 L@ MMMM@ M % M M- M @ M.-  @ L @ M*M*M* M*v M @M @ M 11M@ MvM@MM@M0L..%M% M% M%|@=L MMMF-L- M  M  M | L  M MME?++33+2++++23+?++33+2++++23+++++++]++++++99//+992+}++++333++++++]10]]]]]]]]]]]]]]]]]]]+]]]+]+]]]]]]]]]]]4>327#"&''7.7&#"2>54&':5[yDjR;>@'-5ZwC5_):>>(.f,?7O5U; 5T; 5[Y[.8M.S-RY[.K.P-TmF+'Hg'Hg?5W#e)Q_&8C@ PO++4Q_&8@ PO++4Q_&8i@ PO++4Q_z&8@,P$OO+++44P&<j@  PO++4V=RM@#Mvs | y  AB??99//299//22310++732>54.#*5>3 +#I2P78N/')7+QtIMa 6*(5 q54&#"#4>32  /#af*$!'20.9!+ ,  44C=]6P46N1h'! ! '5%NT Q ,%'2(6 ,1LC*2R: +;+&DCR@ 97P8O++4+&DE@ +86P7O++4+&DiK@ ;7P8O++4+&DuL@ E6PDO++4+&DK@8JPBO6O+++44+ &DcK ?6P+44,%;LU @VRc4T4w+%H y, M9-''fUG%'UUfUUF22B?JJ! w---{;   - -WV0WU111BEEEP'w*h***P !$P?<Q859Q?22?32?32?^]]]39/]323/]]9///]_]]]]_]]33]2]]99]]]]]]_]10]]]]]_]]]]]"&'#".54>3254.#"'>32>32!3267%267.'.#"%6&#"e9U !.9"2O8#&-# M/*-,  PUN O @$!3&?Q(43C:@ O<_<<<@H@ H &`666<<W--@DMW;'X*I**&#P5W2F22  H 6M )iyQ?2^]+22+2]]2?3]]2]]+]]]9/]10++]#"&'73254&/>7.54>32.#"3267>  (+ $3M4#@]9#F 7NS)@.%< "' ! 9  "-F[632&''7&'774&5.#"32>4k ,8_H;Y;!327&#"4'326$AZ5O:156$AZ5'E15}$1EO("3EO#]9>dH')@(F#^9=eH'@(A-gY>/gJ&XCg@ P O++4J&XZ@ P O++4J&Xi`@ P O++4J&X`@*P "O O+++44D&\C@ .#! P "O++4PG%h@E#ZIX)9I'&!PNK  Q?3]2]???3222]]]]]]]10]]4&#"32>7#"&'#7>32ZK @&(9$a733267#"&5467>.'&?e(FCB$Y$BBF( (  #86 W ?"#?-Y-nKKm=)#+ WKKW+EK@u(7&0 HB8)& '''!!??'M/MH I0I@II 555,555L!$ 0?:-0QHEIP?32?3329/^]]3222]_]]_]]2]]]]]]10]]]]]+]%2675.#"23267#"&5467>7#".54>3254.#"'>!3 - /'@/8M/ (  #861,J6#&-# M:S&&@ B*(#P )O++43&F]@ @$"P #O++4:S&&i@ (-)#P *O++43&Fic@ ''#P $O++4:S|&&b@ (*0#P (O++43&Fbc@ '$*P "O++4:S&&_@ ((,#P -O++43&F_c@ '"&P 'O++4V&'_@ "P #O++43&G#@"@H"@H"@H"@ H"@H+++++103G)@^  7 G '%+VfVf*(((('%%%"""P  QN??3]2?^]3]2]2]2]]]]3310]]].#"326773##".54>325#53@&(9$ZK&3]JJ dA<`D%7V"_ (  #86 SQQ=)#+ 3E09۵%0H@M.M% ML@ M)&&&  @M1;_;9M9 M M@ L:#,9  ),@MG,,Q4M4 M4P?++?]+339/]2^]++++]+2]2]210++++++4>32!32673267#"&5467#".%6&#"3(BV-ipRW1C "  &3;!Dc@eA9 1"EgD"QTN   =$(4)Hcn?Q(4V&(_d@  PO++43&H_b@ $(P*O++4:^&*i@ +-) P*O++43D&Jis@ 3/P 0O++4:^&*a@ +,: P(O++43D&Jap@ 2@P .O++4:^|&*b@ +*0 P(O++43D&Jbs@ 06P .O++4:D^&* 4* P+43D &J@ 708P .O++4Vk&+i@  PO++456Kf@>s   Ps y yB BAA????9/^]2222]322]]22210]353!533##!##)!PaSaPPaaPSRccccG@ w!@DL@###_##  "!JJ   @LPN??^]+]2]22??]323]q]10]]+]3#53573#>32#4.#"PJJ];>R1] 2% fEM]El #?X5 0D*T,{&,u@ PO++4$& u@ PO++4c&,>M@&M@ L@ L@ L@ LPO++4++++++ & >M@&M@ L@ L@ L@ LPO++4++++++ &,a@ PO++4& a@ PO++4E7@!0Hs BA??3]]]10+33267#"&5467>7Va  ( *95 K = )#+  E$S@ 0H  &&&"%@ HSI J?222??+22^]]]10+33267#"&5467>73'"&54632( *95]/####= )#* ^!!!!K|&,b@  PO++4P@IJ??^]103#3]]BLV&,-BE&LM&-i@ PO++4G&]i@ J P O++4VDo&. ˴' P+4PD&N д' P+4V&.n-@@H@H@H@ H++++10P @%z Wi 6 ) i (  h@RH$+vtf Ie)9II J JJJ??????9/]3]?]]Ƈ+}]]]q]q2+10q]]]]]]]]]]]#.'#3>73HE<n;@B]]>?6l;?>CNQ#"GB8=?9=@?V&/@ PO++4;6OVD&/ P+4'D&O Ѵ P+4V&/{?@H@H@H@H@H@!"H@%%HP+4+++++++10NJ&O[ H @ H++10V&/b dP+4Ns&Ob{ H @ H++10  `@;j {i sv    )  A yB??99]]]]3]3]222210]]]%!'737 _I!jat TT%B6D-V&>6 V&1@  P O++4P&Q`@ PO++4VD&1   P+4PD&Q $P+4V&1_@  P O++4P&Q_f@ PO++4&1p^&Q^&@ #PO++4VE @/ Hg  s  s"s!@H]K@ I@P`4A AAB?3]322???99]]+]]]+2+}]210+%.'#33#"&'73265##]db(_M/ki] _ :-% %9-25K.F/I1-PE%fh ж H@'L''#%&$JR J#LP?+32??32?]^]210+]+]>32#"&'732654.#"#P jE>R1 !:-% % 2% ]#?X5.F/I1-!0D*I:c&2@ () P*O++43&Rk@  ! P"O++4:&2a@ ,: P(O++43&Rah@ $2 P O++4:&2e@**, P-O)O+++443&Re@*"$ P%O!O+++44Vc&5d@ +)P*O++4Px&U$@ PO++4VDc&5 δ5+P+4Dx&U |P+4Vc&5_j@ )-P.O++4Px&U_)@ PO++4!&6R@ "31-$P2O++4(&V!@ 0.*#P /O++4!&6iX@  62-$P3O++4(&Vi'@ 3/*#P 0O++4!CI8.@DH "54>,))))(A (%:: %!!!s!!v%@ M%%%@_ H%%Kv M   GF@HFJ18>Ay=MRGGGg|FMXFF(AFwV|@MwVE?3]]]+2]]?33]+]2]99//^]]]]]]+2]]+]+]+99+}]]]]]29/993]210]]+7254.'.54632.#"#"&'73254&/>7.'7.;!&D2|m?gS70$(5 -K7kd  (+ $ &?2$ ^Eh -! !->,[fO  %& $2E1Q` ! 9   P (CH/@H%%   F&*&:&v"!r!% 5  zh)956?-g*w**'BE'$;;E$!!!!$J EI29?zFFFE'BQP?]32?332]]99]]]99+}9/993]210]]]]]]]]]]]]]^]]]]+72654&'.54632.#"#"&'73254&/>7.'7976>7(fX,&@-': ($:*PK (+ $ ?G FC!"( "0#EQP! $3%>H ! 9  PC%#@OM L( L!! % s$   ByyAB???22^]]]2]]993310]+++#"&'73254&/>7##5!##& (+ $ %! 9 (aTT JC2l@O4 H00 ",-@H-4#3,)0  -0Q" I??332222+29/2333310+]]#"&'73254&/>7.573#3267 (+ $ (5 ] $*3  9&%! 9  ! 4I/N'3 M %&7_^@  P O++4J&W^!@H@ H@ H@ H++++10%J@,s B  yA?22?^]]]32]]10#3###535#5%ڂaTK>KTJ]@ @ H @)H  ( QI??]]3]29/22+2210^]+3#3#3267#".57 $*3 F-5E*]NF"'3 M6O4Q_{&8u@ 'P&O++4J&Xuc@ %P $O++4Q_c&8@ PO++4J&X`@ P O++4Q_&8a@ *PO++4J&Xa]@ (P O++4Q_&8c !P+44J &Xc` P+44Q_&8e@*POO+++44J&Xez@*P O O+++44QE_+'0HȳM@LMI';'++i+y++(((!"" `s-s,AA"%! | M M MF?+++22??^]9/]993]2]2]]10]]+++".5332>533267#"&5467XDd@a\J%=,a;?%(  #86%*Id:Xh^0K4MQ~$=)#3JE-p@J  )0H  +---/" .,I!I+F&V&&  iyQ?]3]322]2??^]]]210+]]%3267#"&5467>7#".5332>73 (  #86154&'"C  3U&&I& 4JD4@_Pp/]23/3/]3/]310774'aa',XX,.J9bE.@ @H (/^]+]210".7332>731%<<%1b#4!  !4#f @ @ H /9/+10"&54632####f!!!!U?# t@'@H@H     ! @&H/mHk?+]q?^]qq+]q99//]]++10#".54>324&#"326#%%%%2%%%%GE/@0 H   B/22?9/3]2210+"&5467>73326786 ] (  #)#+ =$DtT@+@DT/3]222]]10]]]]'7'7{0s{0sЌ$8$&:C@ $"P#O++4&ZC@ (& !P 'O++4&:@ #!P"O++4&Z@ '% !P &O++4z&:@#5P-O!O+++44&Z@'9 !P 1O %O+++44P&<Cv@  PO++4D&\CP@ $" P %O++4Y7'@ABBA????/ԇ+}10 #7yWK3I <@& !   q?^]]]]]104632#"&74.#"32>PFFPPFFPahhaahha3&&32&&2;OF@(p p?]2/22]]]222103##5#5>7322D,4:@v;]].@DAS Q&(3>_@  @+ H#30 p?229/]2^]_]+10]_]#"&'732654.#>73#>PT A35))D4 ؜^V5E <# 2f/?(A%3I(l@J&&p6FV *6 F V  ) &!)9IYq?]]9/3]22]]]]10]]4>7>32#"&7"32>54&%$D_<!=2#%&6!#5$KM'$0$7V;= $#,.%Wk7C  "%;CD@+MziO_o  p?2]]2]]]+9/10>7#5!_'/2-";*[VKA7GYd2 3F+7@a75,&o 9)2   O_8555)) k { 4 D T  # H0 H/ H Hq?++++9/]]]3]3]3]]2]]2]]2]]210]#".5467.54>3232654&'74&#">FLH*8"$$2$4!$)#93%%*/2? '1/(%-.#  " &  9C#z@O :JZ4kZK$%"L\9$*  &q?]]9/]3]_]]]]]9/]32_]]10]#'>7#".54>322676&#"CIh%&6!#5$KM'$0!px=0/#,-&Wj7D  AIo28 6Op(>q%Ir%Cs FtCu#1@X   7GW% 'w?  3"# $1s!P  2H!"!#$|,E|F?3]2?9]+]2222]210^]]]]]]]]]74>323267#".='7>54.#"l.;!*5 6M//3 +%H02B)B$?I !EZ4 1=5aYS',EA E2B$/5:U! !;0Ac!3G@&" 5-54*$$'0!!'y'''T Q?22/?]]9/339/210"32673#".54>32'4'.#"3!25 0|IO09ER\0Sl??lSSm? 0|HG~/Q 38A6 3$9aKKb99bK 06:0 29&'nV HH@ H+++109&'nk& H&H&@ H+++102I&'nVtM; H- H H;H-H@H;@ H-@ H@ H+++++++++10 I&'nktM^ HP H2 H^HPH2@H^@ HP@ H2@ H+++++++++10(I&q'nktMN H@ H" HNH@H"@HN@ H@@ H"@ H+++++++++10%I&s'nBtM? H1 H H?H1H@H?@ H1@ H@ H+++++++++102A&'nVq HH@ H+++10A&'nzq& H&H&@ H+++10 A&'nkq2 H2H2@ H+++10A&p'nuq HH@ H+++102L&'nkr5* H H*H@ H*@ H@ H++++++10(L&q'nvr5= H" H=H"@ H=@ H"@ H++++++102F&'nNs HH@ H+++10F&'nks& H&H&@ H+++10 F&'ncs2 H2H2@ H+++10F&p'ncs HH@ H+++10(F&q'ncs" H"H"@ H+++10%F&r'ncs- H-H-@ H+++102F&'nVu5& H H&H@ H&@ H@ H++++++10F&'nsu5= H& H=H&@ H=@ H&@ H++++++10F&p'nsu5/ H H/H@ H/@ H@ H++++++10(F&q'nku59 H" H9H"@ H9@ H"@ H++++++10%F&s'nBu5* H H*H@ H*@ H@ H++++++10 F&t'nku5S H< HSH<@ HS@ H<@ H++++++10)"2@u.y.u*)H%!!K!  y hYLJ Ey    0  4(30##v++QT?22?]9/32]^]]210]]]]]]]]]]]]]]]]]]]]]]]"'>32#".54>32."32>7.@ P#WqBAkO/N9 #B_=2H2N/@(I74C'G O @jKFtJ:T6@jK)!7Y?##9H&MG;Yi- @~H Xudszks  Iiy*s 0 ` p  &Ffvsy B  } l D #  AAB???]]]]]q?22]]]2]]]9/]]]]]]]]]10]]3>73!."ABE'Y'EBA"dFFdlRRlF-Vc%@  /9/9/10#!#caa2"cMM@&M vvv A/2?9/322]9/10+++!!5>7.'5!!d>v-o!({B@<409?0TQSCN\-ZUK?TGRW45N/3/10!!56NOY7n8i @@Cx            //9/3/99//+}+}ć+}10]73#.'  RT D$YZ4'EFJ,UN. 3?@ ==@3H 7**D*t****$*D*T******t***@D H*A k{\8H, @444= = %/////:::%/3]2/^]393]2]_]]]]+]]]qr9/]+q]9=/3107267.#"7#".54>32>32#".72654&#",,++  &0++0&   &0++0& p++,,#**#'&&'  !7))7!   !7))7! '&&'#**#GiH@.  Ry'O?^]]]?]]]9///10463:#"#*'53265bi ?7bi ?77dmPE9dmPE9*o6ala5:i@Ay v     /33229/33/399=//^]]10]]]]]]737#5!73#3!'7#5DBB0qDBB0qO$_OO$_5N6D5N6!D #n@GO  !O$@ H p!!!Q!0!@!!/]]]222+]^]]]]222]]10>7.%.'>#@<::<@##@<::<@i&$$$$&*F&&F[7aXS))SXa77aXS))SXa7"<7447<"Dk44kP&IIP@#@1wf !%`%p%%%%/% $@ HSIJJ IhxO?]2]2?????+2^]]22]210]]]]2.#"3##46#3'"&54632#2 &A4]b]]/#### P G<-NF7dm^!!!!P@P{@wf  H @ !@. H pPNQJ IhxO?]2]2????/]]]+210^]+]]]2.#"3##46.57#2 &A4]bVH] P G<-NF7dmFJp PP&IP&I2#31/I=ox25x8=x 6=xO5px(>5qx%I7rx%C5sx F=txC=uxIoN2 N8N 6NO pN(> qN%I rN%C sN FtNCuN)@ N?9/210#5>D4@H  @ /^]9/]10+3#"&'52>5UY +  2  , 8 @a &@Y @ /2/]210]#&454>7Y!(! a $5$- #F@Z?9/]10#5>Nv=> /v> ///v>/Au #D`vA>>/v>?/v>@/(vE>^/v%>`/}7l>44r3s/3t/(}7x>G|}7&l>l>(}7&x>x>)@Wh!!h9IY+)*N V f  Q)))&hYP?^]]]3]222]?]]32?3223]]]]]10>32#"&'#53573#32654.#"E-8W<%D`|3y22E#(|F?22?9/93]2]^]]]]_]]2]10]_]]".'.54>32232>54.#'32>54.#"+v110[M:cH54.+2VIsP*110'G6 6O2R  $b5S32#"&'!32654.#"E-8W<%D`32#"&''>732654.#"E-8W<%D`>3 #"&''>7 9O0'  #'H7!);*e)F$U.*8  5 pp !L$ 2% Mv@LM@ M' @ L &@ LM L|M M!M!@ M!E  L M@ L| M  M MMF?++3++++2+?++3++++2++22++++10#".'732>54.#"'>322/VwI*H7$WB:W;:X;BU#6G*IxV/[U]1 P (If>>fI( M 1]:3ߵ''@ Hw x  .//?/o///5W&&&&vhW4EUe!!X!h!!| |W  U u F  g X  EJ.Z.j..++W+g++|J/Z/j//hxF?]2]]2]?]]]3]]]]]22]2]]]]]]]]^]22/323/]10]]+]".54>3>32.#".#"3267IxV/5ZxD)8??&    ",37X>!:W:CX$6H0\WW\0 4.G$- &Hg@>fI( P 30u0e@?6$F$%$$$"(/o2F1),@(%I" PF  Q?3]2?3]222]^]10]]]].#"3267#".54>32>32.#""NS)@.%< &+?_A #@]9>;$ b^*F2N (Hc<322654&#"#28fU*e)\M;bGUf8-1  #[ZW+ VH ;@+W.#?@$s%FvY  $y|FyA??329/]]]2105!#"&54>;5:767#"o020*PsIVb$  R2O6 6GdQUon325@&(9$ZK&3 dA<`D%32>54.#"+<$!,5D$2,!J404*7ES8_H;X:" 6'#5#.;! "#E?42&$2  L&lT*YH.*DW  )3:!;-1;,$% @@ s   y y y A B??9/9/9/9/9/1035!5!5!5!5!%_"SQSK8)"@MM M MȳM MML!M @'M)MLM M Lv@ M@L@ M+ +*M@Mv@MM@M M M@M*y))$|@ MF| M M E?3++2?+9/++++++++9/++++++++10++++++++++.#"'>32#"&546732>7" wz 5* $4D'WT)0TqBc-C,3K2r} P 6`M\\-O1R;!(?P(38"M4 M$M#M#L#M@$MM M88+:2v!vMM@ M MPM9,@M,/|&7y+M+&@L&E |MM MF?++3+2?+3+9/92++++++29/10+++++++++#"32>7#".54>7.54>32.#";>-M9!_U8.%  (6D&?hI))7;=$@X4=3) X7@M$8D!4F 3(D9 P 2O7(<-T0/E- O 9-#. E8@s| y  H GyA??+39/2210!!!!#"&'73265V !:-% %QO.F/I1-:5@}  x !#o##W###_5s7?7o77g-&--vx g   6##u#T#E##((||FgXE5W222|hF?]3]]2?]]3]9/22]2]]]]^]]]]]]]]23/]]]3]310]]]3#".54>32>32.#".#"3267a -;F$IxV/4YxE-:??&    #.75VfI( H'3@91s+s""$(2* * )* *%&' $   $2 $* $ s * *322s22$  54*$2$t$$?$O$$.y) C A A?.??^]]9]]333]99+}ćć+}]3/3/10]%.'3>73#".54>732654'!@@B%e5i;;h6c%C@?!  "8))8"?':zQrttsQx:1,*1((1*,15@ '' P1)@'&)++$+T+d++++:++++4+T+t++++++++@+`+/+++++ +@+p+++++! *!M$L$@  L$P NJ@MMM LQI??++++???+++322]]]]qqq_qqqqrrr^]9/10^]]_]]%32653#".=4.#"#7>329<<9].RAAR. 1%: ]]6?Q/XIIX,TA''AT,30D* P #?X5Vp0@   s|  H FA??+32210^]33267#"&5Va/0#  9"`R>6 P ak7 0@s  y BA??9/3/29/3210333###daddad&KDV$@dy '$#"! +;M$4Ks  I :  (  /OM H(s@BMD0& s % |tE;   {6 A BB???9/]]9]]]?33]]]322]]+2^]++]2]]]+}]]]q+q10]]]#.'#3>7>32.#"+c`SrPY\*aa59<7-*:,%9UtYdi//_WJAED #E:fP(@# F 9 8  xL#M#@]L M LLt#$##$* )$I9I#I&6O J JJJ?????^]]32?9/]?]2]+}]+++++2+10q]q]]]q]]#.'#4>32.#">73 CA:m7<>] !:-% %:82m6:;DOQ##IC8M.F/I1-:<7<==G@ 8  H @ H   NQ??9/3232+10+].=#5373#VHNN]\\ FJFCF '@Vf3 $    #!$$ $% %     %  ' %%$%$$$  W0  ?$$)0(%J$J  OJJ???392333]??qq9/9q]3+}ć+}ćć+}]^]10]]]]]]]]]#>7''7.#"'>327#./' _,6? jd' %5$?"K;0+?)R?^Vy/j@D///|/x1)s''s s 0(AA A*--'"V"f""Vf|F?^]3]22]333???]]10]]]]%#".5332>7.5332>73#"& %1<"EW1a 5*+$ a 5)$"a%zE3P- )Jf<j9R5  M'j9R5cW E!@1wss@ #s"@Hm[@*IP`pD!BAAA|  H   GB??^]+32????99]]+]]]+]2+}]10!.'#"&'732653319BGFB :-% %M/ki] _%\cf_T .F/I1-25KPGL@ L J KXLP?+3]2??^]10+]>32#4.#"#P jE>R1] 2% ]#?X5#0D*I:%@LMM M M@ M MM@M!M!MM Mv @M @ M  '' M MM@" MvM@M&! yM@ M|MFM|ME?++?+++9/]2^]+++++2+q]+++++2+10+++++++++4>32#".2>7!"!.:5[yDCwZ55ZwCDy[5K1P:#: wddv #;O[Y[..[YY[..["?Y8p*~o7W>!:!5@\))$/h )  v,hw77g&vx$$$$63,X |g)))EW|hF?]]]?]]]33^]]]]q]]22]2]]29331032>54.#"#".54>32>54&'3 ;U54U; ;U45U; 1)&$*5ZwCDy[55[yD7d*^[?gH''Hg??gH''Hgc0V$-|OY[..[YY[. 5#  3Et ,x @= M Y'i''*.V!f!!-G$W$$$QH*X***@ L[P?3]+3]?]^]]3933]+2104>32>54&'3#".732654&#"3$AZ5.P\R$AZ55ZA$aNEENNEEN=eH'3#  eI P.>dH''Hd>XggXXgg9';@n y yv v--)-i---=< s ==&7f77v##<((|x)iF BIY|fv22|w&fE?]]]3/]]3]2??]]]^]]]9/]]3210]]]]]2>32#4.#"#".54>2>54.#"w3_'U:ES-a 0" 1!'2WsAAsW33Wt@3P77P33P88P(&Ec32>32#4.#"4&#"326$?W33W@$$@W3'EI,dH''Hd>=eH'#@X4#.B, "T2XggXXgg(u@K( GW$vGWg*0** s s P p  )y B |@E?23?9/]]]222]]]10]]^]]2+#.54>"#32>54.t+QtIMa\M;bO..I2P75Fon7#"&'#4>32.#">32ZK @&(9$a54.8AFhHz'aa%2M ,E2P73E$MhG.RkmDa+ 3*'4 0-M)M(M( M@M M  M M M@L(L(,,(s(,M@ M, Mv%M%M%M% L% H2/M/vMM@M M L @ L HM 1M|"M M@M,M,, MML"M"@M"E|L M F?+3+2?++3+++99//++++2+++++++++++++++99+++}++10+++++++++%267#"&54>7>54.#"'>32D^ '6E)y7K-6($07Sg?m|2D&!;.E P b[1E2$ &%  Of[,>-! !- h'+@wv'v& 8'$ 6F%'   :J+ !$' $ '$'$ ''''  0-)   ,8''PQ?32?399]2^]2]299]]+}10]]]]]]]]]]]]]]7267#"&54>7>54&#"'>32:FNEbl*:$75:'-@&+Xf(7>67CPJH%3$$#!PQE#0" ("!! @aWV    s   s   z  wy AyB?2?9/2^]]]9]+}ć+}ćć10]]!!5>7.'5!!t7|/y5=@=91-5:iHCSIDIL'&LG>=S9AGE(V@. H (( @  ) @%OgwHR?+]?23/310^]+.5#".54>32'4&#"3267 VH!+"1 !7*UF]"" !  NFJ9%0/*`U(+)  JE|,R@1  H$  .,*-  $ '')''QR,I??32?]3]2232210+3#3267#"&'732654&=#"&57 $+:  6,$ & "UI]N'3 +E1D2-gi@9@!  * su@   ByA?22?^]10]".54>3!##*2P 1=ad+% -;"QdJ#j@D v  %#$h  vO  ( QI??]]3]2?^]]]3]22310]]]3#3267#".54632.#" $+2 F-5E*aj*:  , A4N'3 L6O4ndm P G<E%Z@;  ( O_syA|  H G?+32?2^]]]]2]]10]3267#".5#5!#K% %-:! -1I/F.dQQQ!(K@.s% s @   **s@)({!AA|I'7F?]]??]^]]]10#".5332>532654&' 1$AcDDd@a,=%%=,I#! .':dI**Id:X4K00K4"$ Jkt$f@1 M"!@M@M@ L& &@%"II@ L L Q?+3+2??]+++2210+#".5332>732654&'3k 1$ iE7#5!32>54.'5!#AuY5$. 6( :R22R: (7 .$5Yv+U~S/VJ=RD=JY6;^A""A^;6YJ=DR=JV/S~U+Qt#[@;e V IJs(8Hvh% s $|A A'7|F?]??]]]10]]]]]]]#".5332654&#"'>32tCpUEa>a*9!aaAM @V4dBkB*Id:X4K0Q3[} @[MsK[k8$ "ss!(H B|EAAB????322?9]3^]Ň+}2]]]]+}10+3.'3>7>32.#"Ez6r'^1 ')#4/,:0+.,jdRNKLA +,!BLVSG8/@ g&&.-7"G"""'((@YH""((hW6F%10.(-*P II K?32??99?333^]]9]]]]]]]+}]+}+]210]]]]"#".'732>7&'3>7>32&A&*4A)  #*! ?m$d &,  :>)vY-@)K 'w-hno3'LMQ,7>H !y@?   s      yy A y B?2?9/3223333^]Ƈ+}ć103#!!5>7#53>7!5! \1,O S/w-T#h$qDK?|8QA7EK?n(Q$y@A          I J??9/322333^]]Ƈ+}ć103#!!5>7#53>7!5!A%p9"s=#X8wK0B*T'L:)^0B)FL,~@OX sx  H&X&&vwi.-{Y+++#|XIF yA?2?3]]29/]2^]]]]9/]+}10]]>7!5!#".'732654.+74..8<-Q<#)Ih?&D6(  %.8U_!9M-<<8Q::?@1J16O3 P :D(5 2,@P'''#s,',,',&.#viyV7-'#&y%,{YH%A |IYF?3]2?9/]]222]]]9/3+}^]]]]10]#"32>7#".54>7.'5!!-M9!_U8.%  (6D&?hI)#7.'5!!_&H8!VQ/R]7;`E% 7K*50) )/2 1'AG P 6Q61E-AA;6N7=<C-@&  ,Z7H W | #"! $  <   $ $ $ $$  x  h //*.wfx$$5$$$$+   0  +I?2/9/]]]99]]]^]]]]]2]]]]]]]9+}qr^]^]+}^]10]]^]]]]]]]]4>7>54&'5>7!5!.'2$B3Xk3S W60H/%AW2"I r!) ' -/>-SN9)[0&8'0;'  $(*@] !)X))$v7###,,!v%%*$+%!y#y))#By  h  |&E?]3]]]]2]?9/3/2223]^]]99]]9910]]3>54.#"'>323#!!&>7#U#1)!4(.'2?&gq) W8*<?W*9ti#I,* Da\*O&I9+K Q.OF?+@hX%vc@B I@--'s" ###,yH)9&y"y$A|h  HHF?+]3]2?9/]]+^]222]]+_]10]_]#".'732>54.#>7#5!!Ř CfE;3&!+5/A)GtUawg.N8  R "-&:(&D@> QQ274)U@2(+$ *$HI Q?32?9/+2^]222]10]%#".'732654.+>7#5!#32up91$+3GC2T@2Q9]B$KW N +)' 8Z0JJ !# +B/%@f$#x 9" "" " " ""   e  %''%&J ;  *: QI??399]^]]]22]]99]]]+}10]]]]]]]73##"&'732654&'.5J^ %$:*qbESL:9<6>4%M& $2%HJP!") &9,PG  T@4 g{  WgwPvGiK?]]]?]3222^]10]]]4&#">7#>32NF*/,ZH-a8`~F] dA9Z?",EO r(>W3232>7(BV-hqdSV1C U6Dc@A9 1!EgD"PUN )Hdm?Q(4&$@-P,3O %O O++++444+"&DK@8JPHPOBO6O++++444&$@%&P'O O+++44+"&DK@BCP32.#"32675#53aPP -;F$IxV/4YxE/J5"b45VfI( pI3G@"5M@sMM"44#17W)g)F)7))UeHI6fvR#& 43 P111./^]3]2]?39/322?]32+]]]]]]2]]32]210+]]++%#".54>323##"&'73265.#"32675#53 E./S>$"A^;Aa!NN|~1W Q,SI/(KQ'3%>pp4?^A9_E'Dxl Q BHbQ-@*jD:^&*_@ ,(, P-O++43D&J_e@ .2P 3O++4Vo&._@  P O++45&N@  P O++4:E,@*@*M. >   I:i @ L!@L!'@M 7M7 M7v M @M @ M BB-M-@+ M-vMM@MAL LM2M2 M2@$ M2|(M(M(F<M< M< M<|MME?+++++?++3+++++++++++]+++++9/9+9++210]]]^]]+4>323267#"&5467>7#".732>54.#":5[yDCwZ52D)&(  #86Dy[5f ;U55T; ;T55U; [Y[..[Y@iT< =)#+.[Y?gH''Hg??gH''Hg3E(4@i(<L\ +@ Y)i))6V/f//5H,X,,,$PYi G2W222Q?3]2]2?]^]]]9/92]2]10]]]]3267#"&5467>7.54>324&#"326F<+(  #86 2S<"$AZ55ZA$aODDOODDOV =)#+ *Ga;=eH''He=XggXXgg:Ec&O@ AB PCO++43E&Pk@ 56P#7O++4&_[@ -1P2O++4G&_@ )-P.O++4G &]_@ L P O++4V&'=V~&']3&G]Q:^&*@ L*( P)O++43D&Jd@ .0.P /O++4VX@4s ss  yBu f U F  |F IAA????]]]]]?9/9///2103!332653#".=!#VaSa=II=`4YEDY5a"Nb[[b7]D&&D]7SVGSM@-   vsI|B9I|EC??3]2?99//]]2210]]#>325>54&#"a19@!@oWAqS0cU0<G ~WjQ![=QmKQWV&1C@  P O++4P&QCm@ PO++4#/3e@ M20Hwew e $122 @zH ****-300@H@$$$$--   s#"!  s 5@5p55540H03211 HW  @- H '-y#@  z Y i   -ABB???2/99//]]]]]32+]+2/+^]]]9/+}+}ć33/]+]2/33/]+2/3]10]]]]+]+7#>7.54632#./.'4&#"3267'7?e%C?>!7&%8!>?C&j ?"#?-gG $+11+# Gg-X-OXKKX<7N+&DK@ ?6P+444&w@ PO++4,%&@ XV ,P#WO++4:&@ 20 P1O++43&e@ -+P,O++4&$j@ P O O+++44+&D!@ =7P54.+532>54&#"'>32#"&'7O9lT4-BN!&(I8!ME7Sh?6ZA%!2LUCoN & d,I92A&N%9&BH O6S:60( rHPlBT G3@lK:Uw  wvw ((w5t  ""54./4g  #!!wR.+/P?22?]]9/2]^]229/9]]]]10]]]]]]]]]]]]]]]]2#'>54.+52>54&#"'>,L7 ) 2"DlA>?=/'7> =/;6-J *.,C0+' *1F\6O "1"&,M , 05P Vk&+_@  PO++45&K@  PO++4VGS?@&WDEs s  | 7GE BC???]32^]10]]]#4&#"#>32SbRZ(&" b7AH&Hb>Org )Jf<3D(7D3@e H4'$G3iX&(# ###77;BGF711E%$? KO)),f W  P8874Q?32^]?]]3]2]??2]]]2223]]310]]]]]]]]+]%#".54>327>32#"&''7&4.#"3267"32654&8<`D%54.7#".54>7.5467332654&'3O)C23C%%C32D-03%MlF &20- ^ ELLE ^ O 1"#22#"1 9T +9#bq7N1$8+ T90D&#F#CGGC#F#&D4 9e@>637 ;*-)#&:#v00D0T00RI6N)NF V  Q?]??9/]]]]99^]22222210%4&#"326#".54>7.5467332654&'3ODDOODDO>0',!$AY55ZA$!,'0 [;:9;[ MZZMMZZ9X )7C'8[A$$A[8'C7) X9*Q*#G#QHHQ#G#*Q!E#a@7v   s%!$ !y"Ay  H GyB?32?+?3^]և+}]10!#"&'7326=!5>7!5!#cje$ :-% %f9AFEAh&~CQ.F/I1-A(`ef^SQ$E!e@:##" I  H RJ?3?+32?^]]և+}_]210!#"&'7326=!5>7!5!EOO 6,$ &FMIwTfp3N+E1D2->,ji] N|&$b@ !P O++4+&DbK@ 8>P6O++4VC'|@K H @$''@ H    )s( H$@ H$ y y ByA??39/+^]+2]9/+23/]10+3!!!!!##"&'73254&/>7V"_  (+ $SQS ! 9 (3C6? @  HcD@M4M944*4 4  HL@"M2//&%++@M7 A?M? M M@- L@%"H"&)/@ H/?  2@MQ:M:P?+?+339/]2+2+2^]+++++29/]3/2]10+++]]]++]]+4>32!3267#"&'73254&/>7.%6&#"3(BV-hqSV1C K1 (+ $8P5eA9 1!EgD"  PUN ! 9  "-G\h?Q(4:&2@*< P:BO4O(O++++4443"&Rk@"4 P2:O,O O++++444:&2@7( P32#"&''7&457"32654&,1#$8'9HK0h]L"(##%$H'43*/)[*~$,+*PD,9@fvdt  vvD117;p;O;+:+J{ %5   ---4 K*X%%P?3]2?]]33]]3]3]]?]]]2222]310^]]]]]]]]]]]]>32>32#"&''7&454.#"#%"32654&P jE>R1,1#$8'9HK0h 2% ]"(##%$#?X5'43*/)[*~0D*I$,+*D)x@J  ''++  *IS& J$    R?]33/?^]]2]]]2??2]22/3]10]]]7>32#"&''7&4573#"32654&,1#$8'9HK0h]L"(##%$H'43*/)[*~Ne$,+*3j@@=B433!BB< P11 P)A4117  L .7@L7P3N!$$ LQ?+23333??+3+22333]2/]]93/310^]%32654.#"#.#"3267"&'#".54>327>323&KZ$9(&@]@&(9$ZK&3-NM-<`D%32>32>54&#"$9(&@/*KZ<`D%73737.'-[6ehD__?c(FCB$V/FE#CaSV  .j-X-nKfNX=z:a %0@ *)h)W#$ $k{9Y)* $% %$ $ %$ @ H2a202$&&&&vhV1))IY|$#i[IkW!!F*V,|FV XE?]333]2]22?]3]3]]]322]2]]]]]]]++}]]210]]]]]]7.54>327.'3267#"''&#"BK4ZvB/ G '5B[%8I*@4+G&&3T327#"   u"%@ (,%#>==#@]9  >nNSN N PQ!}S '"',,("+'()I"!JZjI:K?]]]]>]2?^]]2/+}10]3267#".'.+5>7!5!EOQ!(  !#' & !1($ !*6 FKIwRgs7 "O$ >,ji] N'@T  iyJDsi y  v)(yH"6"("""|@ HEBB???3+29/]]]^]2]]]9/]]10]]]]]]]3#54>7>54.#"'>32a!1!!&27X )5<sy#/% );/% !%  P _S&7*! * %@eJ;J%%2  '&vE h 7    wVfPJJ???3]]29]]]^]]]]]]2]9/]10]]]]]]]]3#54>7>54&#"'>32Y*.@/,)"  '27bg&  !0'+&  M MD.#  ]1B@bH*g8vgsf,vgw D DPDD" Bs CB=|2y1y    1 1 E"'|F?22?399//^]3292323]]]]]_]]2]10_]]".'5#53>323#232>54.#'32>54.#"110PP011=!KaLaKKAcDDd@KR%=,\KS:dI**Id:S0K4HHh^V3@d()  )8H* s9( y y ByA?3?3339/32223323]]2^]]]+}]10]]3'7#!73#!37#37#1E&XzFFgfYfv\EMP3g%,15@u# '&54#" "" &   10 ! ?!! ! -7?72,VfG66"!G444W1&,5# @ HQ0Y'' v e  IP?]33]]2]2?+3339/]3322]]222]2^]]]]]99//]3}]]]3210]]4>327#3267#"''7.?&!4&'73)DX0  >|3'2GY62*>>90%:)*/)EgD"TP4 $  SU#{}+91>DT,e@= swh yyA |  L  M MF?+3++2?99//9////]]210^]%#".'7326=#5333#5YC"9." &C2HBaPP2VA%  M!IY\K&KE#e@)!   %$   @ HSIR???+99//9///^]32310]"&'7326=#53533#"&54632 &  0)\\]NNZ+####L;9FFda!!!!!:E?$8@  L  L$@L$M$ M$s%M% M% M%v/@L/M/ LL@ M//:94M4|@ L ME*@M*|LL@ MFy G?2?++3++?+++9///++++++++3+++210++3267#".=#".54>32!32>54.#"% %-:! 3>D!Dy[55[yDCvY4 ;U54U; ;U45U; -1I/F.c*.[YY[..[Y?gH''Hg??gH''Hg3Es/a@<  H/'''''10( 8  G,W,,P" H"QR?2?+3?]]99//^]3210+3267.#"3267#".=#".54>32$9(&@/*KZi% %-:! E-8W<%D`32"#32>54.243j/0/aPP)e*L#  X.H33E$BOV(&OH?KM nmDa+ 3('4 :@ J  P?2222?9/32332102.#"3##5#535>  3(3]JJ!bQ FF Z$@"!   $ s     s  s  & &P&&&%By B A AAA?????9/923/3?^]2/]]2/9/2+}3+}ć103.'33>733##.'#>7#S)n&'h*T~:a ;}($# &J%%J&&J%%J&I0`01a0w: :G*/y%M@M.+*- &*)&* *   +++ &  &+&+&&&&& &   vU7G 101@1p111 *0 #*&6@ K I III?????39/]9]232^]22]]29]]]]+}+}10]++]3&'33>733##".'73267.'#67#K&a  ]BX0*4@*  #6? ;eu;jc-i73e56d3DH<-@)K .7<CLOTG(@e     H( 8 X   "vi 0**)g((K I?2?329/]^]3]]]]]]+9+}]]10]]]]]]7>7!5!#"&'732654.+x2/()05*K7 %E`;7]R/QV"7H&<=7N6;AA-E16Q6 P GA'1 6bB.@@H'  /3]^]+102#.#"#&>1%<<%1#4!  !4#DdG@#DT/32]2]2]]10/'s0{ms0{$8$_?t@ HiH@@H  iH H @ HH/++++]2/++2/]10+'7#"&546324&#"3268%&77&%8-E<7N+11++11+!KW" A@H @H  @H/+/3/+]+]10"&546323"&54632'3#W K@=K;" 1@ @H@  H /+9/+10"&54632'3#  K@K\V @,tE4%Dt6$T1A"@; IKktcT@wVv~o @.H@H  @Od@H/+]]]/3/++9/]]]]]]]]]]]10]^]+]]]]]]]]]]]]]"&546323"&54632'R `-oK &K\V @Lv  Huv v@ H{o @%H@H  @O@H/+]]/3/++9/]10]]]]_^]+]]]]]]+]_]"&546323"&54632'R L323267'3#U " - "      j@]30@ZzM@/10+]'7o<7NA67:@  @/]3339/^]2]210]''{^^_-==-A675@ @/]]9/32210^]]77A^^{-==-_zp@yjy @"H@H  @/329/3/2/2/++10]]^]]]]]'"&546323"&54632`-o  &zb@Ue@H @H  @/329/3/2/2/++10]^]]'7"&54632!"&54632$o-`\ &z @@6H@`@H@ ` xH~xI]N0 H/+]]+_]+3/3/3++10]]]]"&546323"&54632%774 ^^{-==-_V&(C@  PO++4Vz&(m@  PO O+++44'MM@%MM L`pvs@0M@`)(#| MyyAB |F?32??9/+29////^]]+22]]]10+++++%#"&'732654&#"##5!#>323K1 <;^T#Ca $&DeB!,M9 MJ9LF aTT 32.#"!!3267IxU//VxI*G6#UB5R:!0!;S6BW$7H1]VU]1 M !&v (ssI Y   21 I Y  1) ,||%% FyA??339/2223/]39///]2210^]]#'>7>5!>3 #"&'%4.#*32>  )=S8 FM)4*NpF*`*|8M.'/%F5 bpZ-O;$THJU8T8 *8  5V)T@/v&ssIY+*y|##AAB| F????9/23/9///]22210>32#"&'!#3!32>54.#"\)*NpF*`*aaDa[%F5 8M.'/ls8T8 M 5**6 t@Jf  ss|wVfHyyABB???9/]]]^]29////]]]]]2210]#>32#54&#"##5, $&D[7`DS#CaT 7!3#5!l\I37W\,(= :VbB;V(r1 @,$$ssr$$% %3'', && ,''s--'  s} s%%%----2-B,B&B %BBBAA A AAA?????????9/3???^]]]2]]q+}+}3/}]3/99}3]]q+}]+}10]].'33>73#.'##>6IIEq=EG ]GE>pEIH(PKBnDHI!]!JHCmBKQp#UWT"LSU%5%UTK"TWT#$Y`d0.]WLKLW].0d`X 8@!!fgO8_888) Mv@ M0L2vM@L: *)))9y77*@ M*/|)M)$F | L L M ME?+3+++2?3+2+9/2^]22+++++39/]10]]]]]32>54&#"'>32#".'732654.+4!D8$M@7X )3< 4X@$=;7))Ih?&D6(  %.8U_!9M-> .#-9 O -E/0T-<(7O2 P 9D(3 V@   v   s s   @Ps B B;   H9 *    AAA$rc@P2#B?2]]]]]_]]]q2???33^]_]]+]q??]q]+}ć10]]]]]]]33>73#V_ ]ik/M_BFGB952K T_fc\%V&@  PO++4Vo. mO@2(s s    ByA F  y F?]]??^]2]9/]10]'>7>5!#C)=S8 FMab8ic^--O;$THJTKbC%0Vk+:2Ve*@s sBByA???^]10#!#eaaKbV=3:S&%7C$@sXs $! cs4DT' &&o& &P&&& % AXAAA | F?32.???9]?^]2/3]]]]9]]]]]]]}+}]+}ԇ10]%#".'732>7.'3>73+;S=  %-$ ,NB6n!g?(I i....Q<"R 'Gw2Wu[lHuo8(c;VG 1@s s s AAyBC??2??9/2/10%3#5!3!3eW\aMaSb:!L@, s s|y A B A???9/^]]399//]]31032>73##".=3%?0'$ aaO-L`7`*?)_K #A]9V @w s s s o       0 P p 90 P   0 p   0 P ` yy AA A B????]qr^]^]qr_]q9/9/9/1033!3!3VaaabbKVG]@9 s sssp_ @ yyB C AAA?????2^]]]]]9///2/1033!3!33#5VaaaW\bb M@-v sYi"! |y A|F??9/29///^]]]2210%#"&'#5!>3 4.#*32>*d*);f 9O0'- 'H7!pp XS*8  5V $O@-"s$VvsI$$&%&|!#B!AA |F????9/2]9///]22]10%4.#*232>7#"&'3>3 73#8M.'""%F5 f*NpF*`*a)4iaa*8  5*8T8 KVC <@ v sVI  |A|F??9/299//]]2210%#"&'3>3 4.#*32>C*d*a);f 9O0'- 'H7!pp *8  52(@$v&W gy )vh)vM@MM*    )@ L|$yM L$M$@ M$E  L M@!M| M M  M MMF?++3+++++2+?++3++9/]2+^]22+++]]]]9/10]]]]#".'732>7!5!.#"'>322/VwI*H7$WB6S;!0!:R5BU#6G*IxV/[U]1 P #@Y7R4T2>54.#"@sW32WsA?pU5aa8Tk;3P77P33P88P.[YY[.+T}SKrL''Hf??fH''Hf??fH'$%/@3 s 11vx&&+0 M+@Hl+/+?+O+++ s!@! H!!!0H&&y BB | ||E???9/33]^]+3/]_]++3]2]]10_]";"'.'2##"&'#>7.54>c&E6 __d  #010aS**)f,/+2**Opg 4'J9UU@HN%'TLA.E06R7+D>"7@WV&%f-Y-i--95#f##g8g OW(F(( Q5I22P?3]2?]]?^]]]]]]]22]]9/310]]]]>32#".54>7>732>54.#"S&ps;Z>G^7Bu\) -$cj !8,&6" "9+*Mz4`J,4ZxCWrK T b/T@%2C&"@2$ (P6b@<4&*/',7,, 2x222 228#7'/ $'P# Q?32?39/222]]]]]310]^]732>54.+72>54.#""&'>325'$1oc-!'1/a;dd;)N<%& +3%AXF!!E  !9*&6;5/>&P@ IJ??10##!]BFoFX@4  GW L J LI???22?]9///]32]2/1073>7!3#5!#%#8!'UFXzX!L0fmwBDݑn/_]Y*3H- @'$$###g#w##*-- *)*)     4));(hx '('(/ (.-I)I(I$I#IJJJJ J JI??????????9/3??^]2/99}]3]]q+}]3/3]]q+}]]9ć+}]]+}10#.'#5#>7.'353>7267@=8h7;;Y;;7g7=@762g$^?Y?^$;?>DIM$!ID;;DI!$LID>?;-nHHn-,6@ M%   M@< M& 87' G  8127 !Q1,2P?22?329/]2^]22]]29/10]]++]]]+2#"&'732654.+532>54.#"'>-N8  .5xg?[S:?B&,WT'! +*( "+0$6$&G6JH O''#J  P P@8y   ZjI I I J @I a q R 4 D  JJJI????3]]]]+????3]]]2/2]^]22/]]10##3>7ZHHBSZBGG&fmj)+ge]"P6kP  N@'8H      JI H Q?+??^]2]9/]10]'>7>5!# !0@+ 19Z]!KKI 8+N 6'"V]^*C$@K)9I +&&&   & 6 F   $%JJII0@@&+H| I? O  @&+H |  IJJ???9/+q?+q2????2/^]3]]322]2/]33]]10#>73>73#.'#. Y U V88V V \ *)$ N %)*cW=<4vv4<=WcWZRR[WP ;@"      IIJJ????9/2]^]210!#5##3353]]]]3RP*@ IJJ???^]10!###!]]FPGS3F.@ JI??^]]]10###5]NFND\2G /@/1**% /$"##0 @3M&6//v//J)9"y%%%%I#$OKK???3?]3]2?]]3]]+2^]]]}}]]10>54.'#5.54>7574G))G4)G44G)Z;hO..Oh;Z:iO..Oi:,D/r/D/D,+D/$Ca>>aC$$Ca>>aC$[Po5 1@   IIJL??2??9/2/10%3#5!333FXs]]MޑE.T@3)        I JI???9/]32]^]310]]]]326753#5#".=<4&3]]!$+G3;/*E4P @s    ? O   H     0 @ ` : P p  P p   @ ` p  @BEH II I J????+^]qr^]^]qr^]_^]r9/9/9/10333333P]]]EEPo-_@;  0`p J L III?????2]]]_]]9///2/103333333#5P]]]FXEEEޑ8'b@> &)"@ ( "#QI??329/32^]]22]]]10]#53>32#"&'72654.#""+L9" 32#"&'#33 =B#,]A)J8! :R1/`-V]].3$ )A-/B* P%P@0'' &  #QI??329/3222]^]]]]10]%2654.#"3>32#"&;D#.9]"+L9" 32@`@8V %(QQ MK)> !'*?_@!32#".'##34&#"326r)>P.3W@$$@W30S>'q]]MAAMMAAM14T< 'He=>dH'#?Z7XggXXgg'u@L ) )   ##(& JJ PJJ???32??9/^]33]]]2]]2]210]]%"&'#>7.54>32#=.#";' ;^ !"$ !:O/B\\ 3!9FH9]0m/=:4 $),B+ /32&36HCi36HbE/@  H @IL#@111_1 .0/J R.h)) @LPN??^]+32]2]2?32?]323]q]210]]+]+]3#53573#>32#"&'732654.#"PJJ];>R1 !:-% % 2% fEM]Ek #?X5.F/I1-0D*SP6J3$]@ &P&W@ H%  Q  P?32?39/2^]+2]]229/104>32.#"3#32>7#".3!@_?+'! =*KM QQ)% U9A_@9bJ* K OCKKU O )Id(VBL6 @POO+++44EM A7r@F8+)+7"#66"6"6. 9-..8"7I.f.v... -!Q?3322]]?9/32]2]99//]210]]"32654.'>32#"&'#'>7>5!g3 =B#,zA)J8! :R1/_- !0@+ 19Y.3$ @)A-/B* !KKI 8+N 6'"V]^*P5+Z@7  '&-, IIJ$ Q????9/3/2^]9/]3210]2#"&'5##3353>"32654.i)J8! :R1/_-]]\A3 =B#,M)A-/B* L.3$ P 6[P6CxD6\FPo 8@      IIJJ????^]9/10!##5#333X]]E3(8@&''* 0WE4%$#"&"..i.W.,&&&",&,"&"&"", i))/:hf11   9v"""7"G"g"",NF6V666Q?]?3299]]^]]]]]99+}]]]]]10]]]]]]]]]#".54>7.5463267#"4.'326;\A=[<*9" -]NAKI-0:  .T@%`.5AL#8'HK3bK.)G]3-OB5;+EKO# 1AY@1F1 sJ"@1h)r@D$s+Yivw+*y### yD%| B?32?]22/9/^]]]]]99//]2310#32#".'#535332>54.+2VIsP*110ak'G6 6O2R  $B5S32#"&'#2654.#"]"+L9" 32#".%267.#">32".#"3267:5[yDCwZ55ZwCDy[5-#:Q23R;"<-$<99$<99!&<t\^t.[Y[..[YY[..[T9]A#$C`;L%bowf 3$5s@0!8Hx(Y"i""7.Vf   61@H1@H%%Y++PFVQ?]?]9/++^]]2]210]]#".54>32".#"3267'267.#">32$AZ55ZA$$AZ55ZA$&$#& L<>M ! LdH''Hd>=eH''HerEOVK B FPVK  @V(7hs   vG  s    s  A B B |E?222???^]]]2+}]]]+}10]]]]2.#"#.'3>!9+  ["ACF%k6h7 $2F &0Kn܀ 4&:@R(x     PIIJJ?????322^]]]+}]+}210]]]!#&'3>32&#"%T1i'd !%&f *)! j 1omf(3+H VC-!@/x-, v+*#$$ ss  s  /@/P///s. yBG; H9* A#+$****'''' AA$rc@P2#B?2]]]]]_]]]q2??]]22?33^]_]]+]q?3?]q]2/2]+}ć9/10]]]]]]]]]]]33>733'>7#"&'73267V_ ]ik/M\!-C TBFGB9>PG&!!&FO52#JHA* ', T_fc\%@9 (( 9@PZ^+@f- )(!""y -P--,ZjI!)"((((%%%%IIJ@IaqR4DJJKI??3??3]]]]+???]]22?3]]]2/2]^]]222/]]9/10]]3'>7##3>7'"&'73267X'@RHHBSZBGG>PG&!!&FOE#E?7("'&fmj)+ge]"T@9 (( 9@P(d@3 #"&'#535334.#*232>F);*e)PPa 9O0'  #'H7!fpp IMMq*8  5"+k@ '@4 H-,$  0  QPP???39/]32222]32]3+]10]3533#>32#"&'#"32654.J\A)K9"!;S1/_-J3 =E#.EEAa'?-/A( +3# V=$@\H"6F  s0 vGWg& s%6vy 6  B|E?22?9/9933]322]32]99]+}10^]]]2'+#>"3:7'7>54.FA@@K3Ma)e2>!I.?:&(5FonN_o% UP&e:1(4 PG'@eeu     ZIX)9I)( #PK  Q?333]2]23??322]]]]]]]99+}ć10]]4&#"327'7>7'#"&'#>32ZK*/@&;==a416>9 $-E]!cA<`D%[bg%kO0Mx#\$b  &FeV9#@s syABB???1053!#XaP)@  IJJ???^]1053##HT]F 0@s  y y AB??9/323310!3###53ʛaPPTK>K, 6@    IJ??9/^]323310#3##5#535!咒]JJBFFVGJ'@V/Iiyv8))s(8|##yABB7 &  yC?]]???9/3]22]]^]]]10]]]]]%#"&'732>54&#"#!!>32J$Ec@ (D1gQ#Fa $&DgE"AqU1O;V8rp S,PsPF"a@=vg%/?  gV$#IJJR????9/322]]^]]10]]]]2#"&'732654&#"#!!> si6P4   ?EEK6]b"@x6]E'JW]_PMG39@ +&&s% % %3.33s .-.- sr--s    }  , 55  +,+,   s ,s43A-A ,A&A%ABBBBy B CA??????????9/3??^]]]2/]]]]]99}3/]]]3]]q+}3/3]]q+}9ć+}]և+}10]]3#5#.'##>7.'33>7bFJG>{3S\3DHI!]!JHCmCJP'GJGq?EF]FE>"SWT$:N.]WLKLW].0c`Y$$TWT"KSU&5&USKo/5@11)&&% % %g%w%%,// ,+,+  H x   4++  ;    *   HH)*)*1W*0/I+I *I&I%IJJJJ J LI??????????9/3??^]2/]]99}]+]3]]q+}]3/3]]q+}]]9ć+}]]+}10]3#5#.'#5#>7.'353>7267-_)GX$7;;Y;;7g7=@762g$^?Y?^$;?>+k8ޑ!ID;;DI!$LID>?;-nHHn-C S@==&<<3-,@ H6''%''!---{-\-l-K-fg32*8OS_SS8S8DXvMvfvU EDDDTyRRGEEJ|?2/36'54&#"'>32#"&'73254&/>7".'732654.+4!D8$M@7X )3< 4X@$=;7)9Q1 (+ $ &C6'  %.8U_!9M-> .#-9 O -E/0T-<(0H2 ! 9   P 9D(3 ,CQ@H%)5)))5('2#sRbC5#%5SE@Q H  4&$;$;SRB G5  SLM/...R <:::/2+"(.+QLGMP?22?332229/]2^]22]]299//210]]]]]+]]]]]]]]]]]]]]]]]]]2#"&'73254&/>7.'732654.+532>54.#"'>-N8  .5[Q (+ $ 9US:?B&,WT'! +*( "+0$6$&G6@G! 9   O''#J  P VG@)ss  s @$HT  sCAA AABByB??????9/??2}3]+ć+}2+}ć10]!.'#3>733#5NWY*aa#TRIuNUT%"JKGR\/_WJ!STM"SWT$AKR(Po@`          p d  IIJ JJII????9/???2]]299}^]ć+}]2/}+}]10>733#5#.'#3>?6l;?>453EX%;AB]])=?9=@?/6<ޑ"GB8V"@    /""   s   s    $o !s#AAB"! BBBAA?????9/3/22???222]}+}qև+}q3qq10^]]>73#.'#5##3353?B@8pEIH(PKBm?DDH@aa@H$PNF"TWT#$Y`d0-YRI֘P] @;4  4    4   " !9   t + ;    IIJ JJJII?????9/3/???/_^]]]]]q22]}+}q]+}q3qq10_]>73#.'#5##335.9R"f267@=8h146D=]]=lAf*;?>DIM$D@:srs{"@\Yy M   M H  (  s !"""M""s"")9 @8M0 P `  $s#"A{AB BA????9/]9]2]2?323]+]]+}]+3^]++10]]]]+]#.'##53533#>7cNUT%+`\QrNWY*`PP`aa#TRI"SWT$Xdh//_WJ"FMMF!STM""@ !"  $+ ++;6tf$$    #III J JJJ?????22?9/3/?239}]]]]+}]]]q]]]q+}ć10]#.'##53533#>73!HE<l;CG"]JJ]NNC@6l;?>CNQ#"HC;@EE@B@:=@?@xYy     H (   s  s)9Y 0 P `  sA{yAB BA????9/]9qq?22]]]]]+}q^]]]q3]]+]10]]]]]]]]#.'##5!>7NUT%+`\QrNWY*a#TRI"SWT$Xdh//_WJbS!STMQ@*z Wi 6 ) i (  h@\H$+vtf Ie)9II J JJJ??????9/]3]]]?]]Ƈ+}]]]q]q2+10q]]]]]]]]]]]]#.'##53>73THE<l;AB]>?6l;?>CNQ#"GB8N=?9=@?VGE@'ss s  A A B ByyBCAA????9/????221033#5#!#3! aW\\aaS@Po@H@*   I IJJL?????9/2]^]210%3#5#5##3353FXK]]]MޑV ;@! s s  y ABByA????9/2^]10!##!#3! aaaST@P ?@$      IIJJ????9/2]^]210!#5##3353#]]]NVG)}@RvY#i#y#(#8##v(8+s*&6yC)&y  yABB???9/]32?]]]]]]9/3^]210]!#!#!>32#"&'732>54&#"Qaa $&DgE"$Ec@ (D1gQ#Fb,PsFAqU1O;V8rp PF>"`@9"!i$!#v!IJJV R?3]2???9/^]]32]]29/310>32#"&'732654&#"###!Bsi6P4   ?EEK4]]1 x6]E'JW]_PF:H5E@M*vDvC+*y*wv6A>v(( gv-f-"65--56"GFG@\H|;;;;;# |5522Eg  wAAA&A6AFAAyw(g((((FW""y#W###G?^]]]]?]]3]]]2]?]3]]]29/]]]+]]9/////]]33]2]]]210]]]]]]].#".54>32.'.54>324.#">C"9^C%cX 1O:6M0"A[9:@; 'WRGExX37^~G/ZB (96 *F2Y $FgDp&Z47bJ+(DZ12]L6 % N)@.2ZVW\0 o!:,]d9V##7I3p3 A@d< 6'!fv$ A#))%44V9/9.A99A.CB I>&6   @% H 4A>PFfw)))4Q.w///L?]]?3]]2?39/+]]]]]]29/////^]]]33]22]310]]]]]]%>54&#"7.#".54>32.'.54>32L :F('%*&"=-?< &=+(;&.B*+-* C@85YA$)E[24&>V<->>1I1Pe>$+J61A%'G:* D 2#'EcABdC# :CS3CG% G@,s s   yBC yA???^]]]]]10#3#5##5%Y\^TaTo ;@"    JL I???^]]]10#3#5##5FXKNޑNP<G@RG(       __    IKI??9/3/?^]]]]]+}]+}]10]#5&'3>7&g0]0f&d !%&&%! jj1omf((fmo1P@O  sos  soyBAAAAB??????9/3/2^]]3+}]3+}1035#53.'3>733#Cx5r&^21^'l6xBJicRNNRciJG@qyD3:J(x_ 5E     _   IK  JI??3/2??^]]]+}]]]]]]+}]]]]]]103##5#53.'3>7"X,r]s,Y!d !%&&%! ~bDDb1nme((emn1GZ@@MM7'W MM@8MMMx        s  @M{m\K=+ GgMsMtbZC: )so   CAAAA B ByB????????^]]]]_]]_]]]]]]++}]+]]]]]]]]]++}]10]]+++++]]]+]+]!.'#>7333#5*2661+k-wCpo4_)R\IOO##OOIX`GKEo@LF  I        | Hv@N Hz\l+;K    LIIII J JJ????????^]]]]]]]]]]+}+]]]]+]]+}qq10]!.'#>7'3733#5 &((% `#a0i|}c#I FX698996D@0f4ޑG<B@%ss s  A yyA yBC????9/////10%3#5!#5!#!3W\MaSaTTboB@%   I I JL????9/////10%3#5!#5!#33:FXsn]MޑNN:Gx\@8s s s|yA yB A???9/^]]399//]]310]32>733#5##".=3%?0'$ aW\\O-L`7`*?)_ #A]9.o l@D)     @/I J LI????9/]32^]]]310]]]]]3267533#5#5#".=<4&3]FXK!$+G3;/Eޑ*E4:(o@B  s us/f|yAB A???9/^]]332]]9///]]32310]53>73##5.=3 ,!K&;aa;&K@R.`$9({~ _K'@X6'|@L)     +; wp I J I???9/]33]2]3_]]^]39/3210_]]]]53>753#5#5.=*&E%]] )E'?.23_` ^\*C1VEI@(fs s  |VHAB B???9/]]3299//2210^]]>32#54.#"#3Q-Mb8`'@1'Maa $B^;+A* PK /:@:g)8**u*)u)7) Hx& 0v/',,,<:@LMv"W;""0y@X55|''7'g'w'''EY&|Z  hxW(F?]]]3]2]]?]]9/3/]22/22]2+2]2210^]]]+]]]]]]]]32>7#".'.5467>32'4.#"! wz 5* $4D'T~T+&?.M,36Qi32!3267#".%6&#"!8'IM,?M)hqSV1C U6A`A!bA9 1!#5& F 7R6  PUN &C\}?Q(4G 2=@Cg);--u-,u,7, Hxs/3v 2'///?=@RMv%W">%%3y@X88|'*7*g*w***ECY&|Z  hxW(F?]]]3]3]2]]??]]9/3/]22/22]2+2]229/]]10^]]]+]]]]]]]]32>7#5.'.5467>32'4.#"! wz 5* "2@%[@_@"&?.M,36Qi32!3267#5.%6&#"!8'IM,?M)hqSV1C I0X/G/cA9 1!#5& F 7R6  PUN ,?Qv?Q(4V,r66VGL+!@ #LM MM@ M7MLMM@2M  s   L( M L  M vMM@ L@ M- @,L M ()s+,*B(%y )ByCAAA????]?9/2?2}3++3/]3+++++++++}ć10+++++]+++++>73#"&'732654.#"#!QPHrEJM#;gL,!Aa@ Oa2KU$a"VWQ!MPP#"BgI73#"&'732654&#"#3??9m7;:gv7Q4   ?Ia[#]]%=?;797r0WC'JUQ_X C!l@C H(s ss###    "yBG!yA F  y F?]]??3?^]2]9/3]]310]+'>7>5!3'>7#C)=S8 FM\!-C Vb8ic^--O;$THJT#JHA* ',b Z^#k@8H8H!  "!%`%%    $!JY#I H Q?+??3?^]2]]9/]3310]+'>7>5!3'>7# !0@+ 19ZX&@U!KKI 8+N 6'"V]^*E#GA6("'VEkU@/ H ssyAB y GA??32??9/2^]210]]+3#"&'73265!#3! a !:-% %aaSK.F/I1-QPE]@5 H&  IIJ R?32???9/2]^]2210]]+!#"&'7326=##3353 !:-% %]]].F/I1-VC`@; Hss ssyAByB GA??3???9/2^]]]2]]310+33'>7#!#3! a\!-C VaaS#JHA* ',@PZSW@5 H  0IIJ JK?3????9/2^]]23210+%3'>7#5##3353X'@U]]]M#E?7("'AG(T@2s s ss|y ACy B A????9/^]]3]99//]1032>73##35#".=3%?0'$ a\\WO-L`7`*?)_K  #A]9.o_@;)       I L JI????9/]32]^]10]]]]326753##535#".=<4&3]KXF!$+G3;/}*E4CC~6D.@cHf..-j))(fW i iWs&%%%8,s s++@* LO+_++/s@ MW6v@ M@6 LX 0 s  7@H|66 y,B&%GAAA/L@ H|A B??]+]+2????3?9/+^]]]]++]]]+]2]+2/]3]3]]210]]]]]]q]]]]]]]]]]]+%.'#>73>733'>7#&' !&+&! _  U>>::>>U\!-C P !&+&! `JV[Q@vZK,x66x,ў#JHA* ',v@Q[VJCZ0@b0H)9I &&+&&&#2p222""",+  & 6 F   $1#J"JKII&0@@&+H| I? O  @&+H |,, IJJ???9/+q?+q2???3??2/^]3]]322]2/]332/]33]]10+#>73>733'>7#.'#. Y U V88V V X'@Q *)$ N %)*cW=<4vv43nrr6#E?7("'WcWZRR[WV,6$+6DHz6$+6DK,%V6(a36H[8)@*& M&M(MM0M8L0 M MLM@ MMM) M)v @ M@:L@ M+v@ML@M*y))$|L MF| LE?+32?++9/++++++9/3+2+10++++++++++++.#"'>32#"&546732>7" wz 5* $4D'WT)0TqBc-C,3K2r} P 6`M\\-O1R;!(?P(6#@Y!x e!j x #I#Y##%x$  gXPhWQ?]]?]]39/]2^]]9/3]]210]]]]]]]#"&=47!.#"'>3232>7(BV-hqdSV1C U6Dc@A9 1!EgD"PUN )Hdm?Q(48z6u66vUrz66 z6C,6+GVc6P6qVz6P6q:z6236Rk:3!o@MXh8H#Wg7G   "P`@PIYPFVQ?]?]9|/]q^]]]]]10#".54>32267!"!.$AZ55ZA$$AZ55ZA$?MM?dH''Hd>=eH''HeXLLX~QFFQ:z636j2z6>"6 Cc6vD6\ICz6vD6\IC6eD6\ec:!z6x.6=VG &@ ss y AyBC???10!3#5#W\\TPo &@  IJL???10#3#5#!FXKBޑVz6P6 V2'37@uGg H5(((9?97...o    sxs s 8775 )1 ++)++##&##EA ABB?????^]]]]22]+}ć]]]]]10]]]!.'#33#".54>324&#"326!!6+g&w&&|/ 7{8{@,///F  |  E?]]3]]2?]]39|/]3222]2++2]210]]]]]^]]]]]]]5!654.#"'>323#!!32>7#".547#53>?%U"+3E*O);Q1 4[A&,?H/'#.e0BV4 5]H-%C'  Q !4C!C)C!/6 J0>"&C)( @U''   s      ByA??9/333]222222]222^]]]2222]]22222310]]#77#5'75'75#5 tt[ttP7?Es7?E6?Ds6?DP0 1@s  y y AB??29/////10###5%!5[+NFNNN )x@JH#x#"Y"i"% % H%   %+*X  `_U?]2/2]2/2?9/////+2^]10]]]%!#5#535#53>32+"32>54.[RRRR'_))MoE:[&,50L5.=GjjGfHJ ji9O2f5'&2 *\U 6@       i?]]2210^]"&'73267?OG&!!&FN\@9 (( 9@$VP%VV(!=Vk+:'+@ )h)v M @M @ M  -(M@, MvMM@M,+y))?)O))))M M@# M|MMF#M# M# M#|MME?+++++?+++++9/^]]+++++]+++]]104>32#".732>54.#"!!:5[yDCwZ55ZwCDy[5f ;U54U; ;U45U; Q'[Y[..[YY[..[Y?gH''Hg??gH''HgPV,Vo.y@I7w8 x w  s   s @p BIYAB??33]?^]]]9/+}+}10]]]3>73#&'%FBA"["ACE&k6h77h5nKKn$۞C%0V1% 3@     y yByA??9/10^]!5!!!!!6,"6raTTT:2VeV=3! %7P<8( $/@@ /%$" #1x9s0s0w*6**v0$B/L| "M"L"@ M"#BD %L%|LMD?++2+2??+++2+2?^]]]]]]]]]]3}310%2>54.#".54>753##"30S=$$=S0^@w[77[w@^@v\77\v@^0S=$$=S05M22M5&IkEEjI&PP&IjEEkI&TB5M22M5c;A@Mss s @H  dK$48$4T$DT @/ L M @ L |MMAAAB????9/+3/++++2^]]]]_]]qrrr^]]]]]q9///+^]210+!#5".=33326=3#_QpG^k^_^k^GpQ+Kh54.#"!53.54>@vY5$.7( :R22R: (6 .$5Yu+U~S/VJ=RD>JY6;^A""A^;6YJ>DR=JV/S~U+3I,a@: YJ! o.P.(-  Q"%(%8%%P?2]]2?3/322]]2210]]]^]2"&'#".54>267&5.#";92)  -=N6;Y<%Eb*)?5P[$9 # N!(Hc;?eF&3 !  b[(E3PG085M5@ M" M @M))0M0 @.L %M%::89 (**J3M3MMOK??+++?39/3/22]+++9/10++++#4>32#"&'532>54&+532>54&#"]5T;.M863);%%E`;)A=3!<-]c5';:#02U?#1H0-U +8@!:W: V $7%LYL-1B*9!G^@+H8H IKK@ HQ I II????+???^]9/]]+9310>73#.'z "" +% ] #3E-X%'%$eru3+ioo12~FVX:uf'3>@*F*WC404*,,**,:Y i  0@( fW:::?Vf5Q#O,v,, ,,7WI?^]]]3]]]?3]2?]]]]]]99+}qq210]]]]]]]]32>54.'.54632.#"#".54>-HR$8'$7%)2`&/eW1( ", #3-'K:#;\A=[=/AmK$C30A&-C0#=>+FF J  +7DX=/[I-*H`6.P@079@` +&7710 0000+)+"#;5---:?00""w#(Q  P?2]2?3]2]9/3/]q^]2210]]]qqq]]]2.#";#"32>7#".5467.54>$0)&,6J&Y[,"6-! &4C'$N@*2) 9QO #&I !S M  ">1(F$%8&4D(@25(E(#((('I :I: hx)@T HU 0 H9I W!w!!!xg  *)*NW&& R?3/]?2]9/////^]]]]3]]+]10]]+]]]]]]]]]]]]]]]'>54&'.54>7#5!P 9A3H/32#4.#"#P jE>R1] 2% ]#?X5#0D*I7#)f@Cx%+w$*$'7g H  Q(8GO?]]]?]]]9/^]2]]10]]2#".54>2>7!"!.-=]==]=>\==\>'8$$8('7$-$77g[\g77g\[g7:(JhAAhJ(t&Ec==cE&N ;@    @ @ H  I  HQ?+?+^]10].53VH] FJ P "@ ! L L Mس M M@2 M  !"    LسM@" M$# JJO JJ??/?32??9^]29/++++}ć+}10++++++#>7.#"'>32#./' _,7> $ %"5( Jp$aA6sog+:>*A,K$1^PGY2D>@sW>:W: j FV5$v g  5&fv@@v//ihV<G<<?'*#755&#OJ R?3??39/3/2^]]]]2]]]2]]2]]10]]]]]]]]]]]%'>54&'.54>7.54>32.#";#").@'P 8Bdd.5+"<3RPJG !w@Oif hXI#!"XI PKziFVziQ?]2]]]]]2]]]??]]2]]10]]]^]"&'#4>32'32>54&#"1,I]9R6w =YB(:&DQ?D  6X?#;cH)z3F([bR[3D)h@EEU$4fvTf T  +7%G%%Xh*"PJ R?3??^]]]9/3]]2]]]10]]%'>54&'.54>32.#"1&4!P (->R2 @_?#C6RT+9Q +&G  +>R58dL, O iW4?&3U']@;Yh)) W    (HI%F%%Q?]]?]2^]]]2210]]]]]%#".54>3!#4&'#"326#@Y52XA&-Kd6 _.&!<5#'5DN:]A#$D`;JhBN.5:>l"*M>)B.[J@,   @    I HQ?+32?^]]]210]%#".=#5!#3267)5B' !! 4O4NN'3 J:@%IIW g  yQ?^]]]??]10".5332653 AS0]=<<=]0S 'AT,+XIIX,TA'3G$q@&L L"L@ L%K!@LQ" L P?+?+?^]++22++105.54>324.'>%TBkK)/W|LQ|U,0I3f\"aaaa)E_;?fF&&Ff?v (C3 } fPPe  i[JGR@ II L@ LQ KI???++??2^]10>=3#5.53S]]BfFZGeB]\T?^j9bI++Ib9j^9 8@6++.L.M.@M.)M) M):/L/гM/@!M/44 L MMM@G M L0M M   9./PP& MM MLMQ?++3+++?3?3^]2+++++2+++]9]2+++++2+++10]]]]"&'#".54>732>=332654.'7=7SS7-L8"S:9(+\+(9:S #8L 1,,1?cH0WH7 /AQ-Sa.@EE@.aS-QA/ 7HW0Hd>6$H H++10U&(?l@ @H @H @ H+++10&+Dl@ @H @H @ H+++10&,Dl@@H@H@ H+++10 z&,@POO+++44&2l(@H( H( H+++10&<~l9@H@ H@H@ H@H@H H+++++++10Pz&<o@% POO+++44&l0H0 H0 H+++103I&[@ /- P.O++47&7@ <:,#P;O++4PG&J@ PO++49&@   P O++4&@   PO O+++44E &!@ POO O++++4443&RS@ " P!O++4J&d@*P"OO+++44J&L@ PO++4J &d@("P&OOO++++4449 &@ ;9 3P:O++4?F;@"BR@H@/]+^]]10'7F6qݞ&w)@A`?]?9/]q10'7DD.B Q @,H @H@H /O/]^]+]++10'7"&54632!"&54632 h4Y 3I &u@ -8 P>O++43I &p@ 1> P-O++43I&x@ -? P@O=O+++443I&Y@ 1? P@O-O+++443I&@-> P?O=O+++443I&x@ 1> P?O-O+++443Iq&s@ LB P5DO=O+++443Iq&s@ LB P5DO-O+++44&$c@$%HHH@ H@ H&'H&'HHHH H+++++++++++10&$Π@$%HHH@ H@ H@ ''H@%%HHHHHH H H H+++++++++++++++10&$vǹ*@$%H*H*H*@H*@ H@$%HHH@H@ H/@H/@H/H/H/@ H/@ H/@ H/@H*$&H$&H*HH*HH*HH* H H++++++++++++++++++++++++++++10&$gH*@$%H*H*H*@H*@ H@$%HHH@H@ H/@""H/@ H/@H/H/H/@ H/@H/H/@ H/@H*03H03H*''H''H* !H !H*HH*HH*HH*HH*HH* H H++++++++++++++++++++++++++++++++++++++10&$>T*@$%H*H*H*@H*@ H@$%HHHH@ H++++++++++10&$Y̹6$!1O+&$ !1O+7 &U@  :E,#PKO++47 &P@ >K,#P:O++47&X@:L,#PMOJO+++447&9@ >L,#PMO:O+++447&x@(:K,#PLOJO+++447&X@>K,#PLO:O+++44U&(?_U&(?m'(ǹ'(¹'('(̹PG &h@ #P)O++4PG &c@ )PO++4PG&k@*P+O(O+++44PG&L@ *P+OO+++44PG&@%)P*O(O+++44PG&k@)P*OO+++44PGq&f@7-P /O(O+++44PGq&f@7-P /OO+++44&+?_&+?mh'+ǹY'+¹R'+m'+̹'+'+> &@  PO++4/ &@  P O++40&@  POO+++44&@  PO O+++44E&@  POO+++440&@  PO O+++44q&@ +! P#OO+++44q&@ +! P#O O+++44&,?_&,?m',ǹ',¹',',̹g',g',3 &Rm@  + P1O++43 &Ri@ $1 P O++43&Rp@ 2 P3O0O+++443&RR@ $2 P3O O+++443&R@% 1 P2O0O+++443&Rx@ $1 P2O O+++44&2 _&2.m'2ǹ'2¹s'2'2̹J &f@ !P'O++4J &a@ 'PO++4J&i@(P)O&O+++44J&J@ (P)OO+++44J&@%'P(O&O+++44J&i@'P(OO+++44Jq&d@5+P-O&O+++44Jq&d@5+P-OO+++44&ONQ P-8 P+4+4+3DI &&p-O@ NQ P1> P+4+4+3DI&&x&@ @O=OPT P-? P++444++3DI&&Y&@ @O-OPT P״1? P+44+4++3DI&'&@ ?O=OPT P״-> P+44+4++3DI&&x&@ ?O-OPT P1> P+44+4++3DIq&&s&ad P@ LB P5DO=O+++44+43DIq&&q&ad P@ LB P5DO-O+++44+4&$&&$&δ &$v&ǹ&$g&¹&$>&&$Y&̹&$&&$ &PD &&h@9<P #P)O++4+4PD &&c9<P@ )PO++4+4PD&&k @'&ǹ'&¹'&'&̹b&U&i&r&3I&ap@ 1? P-O++43I&s@ -. P/O++43DI&&y?C P@ 0. P/O++4+43DI& :? P+43DI&&m@@C P /- P.O+++443I&s@ ?1 P2O++43DI&&sRU P@ ?1 P2O++4+46$ac6$6$C6$&$x?  ZD!@ H@ 10+3#".5<73  + Y? 8 ,  x?  .@  H H  /++]10>7.54632x !$'a &&$6bB1@@H& H /+^]+102#.#"#&>2$<<$2#4!  !4#!KWa +W@ Hp %p&&&@H ,@H"@ H"%O /]+++2/]]+10"&546323"&546322#.#"#54>W {0%5&((&5%0K.)).PD&&l+.PP+4+4PD&'*P%P+4+PD&&`'*Pݴ%+P+4+4PG&f@ *PO++4PD&&f@=@P*PO++4+4&(yC'b(y&+yC'b+yV&+?hT@ H  @H /2/3/3/3/+]+10>7&546327' $"%m4~a% &&$Ъ&?]f@ Hd$4D  @H /2/3/3/3/+]^]]]]+10>7&54632%'7 $"%~4ma% &&$&7?Aq$Z@/  @H %@H@ H/^]+]++qq3/]1067.546322#.#"#54>l) '40%5&((&5%0a " 2.)).&a@  P O++4 &@  PO++4E &!@$ POOO++++444E &!@ POO O++++444&@  PO++4a&!@  P*OO O++++444&,a@ PO++4c&,@ PO++40&,yC0'b,y?^V@0FV@ @H /2/3/3/3/+]]]10].546327'&"$ Lm4~?$&& %&?hT@/JZ@ @H /2/3/3/3/+]10]]].546327'7w&"$ ~4m?$&& %|&7?Aq$R@# @H &@H@ H/^]+]++qq3/10.546322#.#"#54>' )P0%5&((&5%0? " .)).J&aa@ (PO++4J&d@ PO++4J &d@.P&OOO++++444J &d@("P&OOO++++444JG  &s@ "- P 3O++4JG  &n@ &3 P "O++4J&d@ (PO++4Ja&d@*P4O"OO++++444P&<al@ # PO++4Pc&<o@  PO++4'<C'b<|&3?mB Y@H @ H@H/O  /]^]]+]++10'"&54632!"&54632Y4hB   tB /D @ </10]'d(49D &'LO P@ <: 3P;O++4+49D & HK P+49D &'@LO P;9 3P:O++4+49 &@ K= 3P>O++49D &'@^a PK= 3P>O++4+47&2gC'b28?&cC'b54 &nDI-@3 H@/]+]10'7I(4o? (@@H@ H /++]10.54632'$! ?$&& D6$&D6$&δD&$v&ǹ9D&$g&¹*D&$>&D&$Y&̹D6$&D&$ &D&+?'_D&+?'mDh'+&ǹDY'+&¹DR'+&Dm'+&̹D'+&D'+&D&'_D&*'m*D'&ǹD'&¹D{'&D'&̹D1&U&UDN&r&rD6$VDk6+4D6C&)MMLMMM@M s+#MMM@# M"s$)*y))y 0@@314H 0`p_$B#ByA?2??9/]]]qqqqq+qr2/9/32++++3222210+++++++32>7!5!.+5!#3##.'C]=6) !%/E:1HY/?C@mAB@d %H&HH2H,=&BMR&'OI?+?Xs@)]<#0Wz EF??910#".54>32"32654&4&#"326%467'7.76323.'#".'.#"3267>32>7##"&2654&#"8bLKb99bKLb8!&.  .&!1! 1&F!   1 !/   !F&1ZKa99aKLb88b%=<?' &>>=<#.&F :  F)0#-!t'o'g't]'o+I #'+/37@&6Ff= &6Ff= &f&fIYIY i i6f 6 f  9  9=11i1y111@ H 11/4;H/(((,/H(@#(+H((i(y(((@ H (($4;H$$$@!+/H $$$$$i$y$$$@ H $$6@ 4;H6652@ H2'2722+@-1H1+ +++++@ H+'+7++'-1H'@(,H'@ H'''7''  "/ ;^[Ly  ; ? o =O   { L   9 i   /_ ;{L8 f3`=PSDv 0`=ArD@=f7  0 = !   T   F   9@ 4EH",585@91;Ha5@5P5!5155555555555c5s5T5C555@ H55'55"@H"""""3,,@@ &HK,[,<,,@H,,,,H,@ H,2EH11&40;H4,/H4@-#+H|44k4\4K44H4@ H4#+#;##H#)+B-$'H-#H-H-@H-@ H- -@2EH$&A @P`;`!Arc$D6Ff'  <wC i3/?<O `@*IL\l )i AL\  /O_o;Oo.Ll| +Ii8) >xK f  3 B `=AScDe@:' APA`p A?r2_]_q_qqrrrr^]2^]]]qqqqrr^]?^]]2^]]qqrrr^]2^]]]]]]qqqrrrr^]9/]3^]]]qqqrr^]3^]]]]qq+rrrr^]]^]]2^]]qqrrr^]]2^]]]qqqqqqrrrr^]]]?2+2^]+++++?2+q2++qqqq+++9/3+3++]+qq+q2]]+2]+]qqqqqqqrrrrr+22+22r22]]]]qqqrr^]2^]]]]qqqrr^]2^]]]qqqqr^]^]]2^]]qqqrrr^]]2^]]]qqqqrr^]2^]2^]]]qqqqrr^]]^]22]+++2]+qrrr+2]+]+2]+]]qr+r+2]+]]++r2+2]+]]10^]]]]]]]]]]]]^]^]^]^]335!5!35!3335!5!35!3j444555k**yhk**L**yhk** (7Me}@LL[ LTMSMDMD@L=M=M1(M.M.гMM @LMM~{igfXA VNdKM@B/7&A (  @ A8ov}ifd X ^QcNLBF;(,#4 ???????????????????9910++++++++++++++++%#".5332>73>32#"&'732654.#"#".5332>73>32#4.#"#3#3267#".57#".5332>73%#".54>32"32654&32654&#"'467'7.723&'#"&'&#"6"'327>3267#72654&#" iER1] 2% ]u $*3 F-5E*] iE32"32654&32654&#"'467'7.723&'#"&'&#"6"'327>3267#72654&#"":O--N:"":N--O:"    T"/)##)/(  0-N:"":N--O:"":O    u$ $%  $$ $j- 0! ## !0 -  {n` ` $ & * - 2 4 9 : = z        E u }       P & * 2 4 6 7 8 9 <       E K Y u     $ & * - 2 4 6 7 9 : ; < =              E K u }          $ & * - ;         u }    -79;<=EKu}$&*-246789:; <= EKYu $&*-2479 :;<"= EK" "&*24789:<Ku#$#&#*#-#2#4#6#7#8#9#:#;#<#=##################K#}#########$ $ $ $$$#$$!$&$*$-$2$4$6$7$8$9$:$;$<$=$@$F$G$H$J$R$T$V $X$Y$Z$[$\$]$^$`$c$l$n$o$"$$$ $!$$$$$$$$$}$% % % % %%%%"%9%:%;%<%@%]%`%%%%%}& &&&"&#&$&&&*&-&2&4&6 &7&9&; &<&= &>&F&G&H&J&R&T&X&Y&Z&[&\&^&c&l&o &&&&&&&&&&&'' ' ' '''"'#'$'-'6'7'9':';'<'='>'@'D'`'c'n'o'''''''''''' '!'}''( ( ( ( (#($(&(*(-(2(4(8(>(@(F(G(H(J(R(T(W(X(Y(Z([ (\(^(`(l(n((((((((((((()) ))))" )#)$)&)*)-)2)4)7)9)<)>)@)D)F)G)H)J)Q)R)S)T)U)X)[)])c)x)))))))))))B)* * *@*Y*\*`**++,,- ---$---=-@-]-`-c------. . ...." .#.$".&.*.-.2.4.7.9.: .;.<.=.@.F.G.H.J.R.T.V.X.Y.Z.[.\.].^.c.l.#... . .. ..".........B/ / / u/// /$/&/*/-/2/4/6/7/8/9/:/;/</=/@/F/G/H/J/R/T/Y/Z/[/\/] /^/`/c/l/n/o/x ///////////}/090<01122 2 2 222"2#2$2-2627292:2;2<2=2>2@2D2`2c2n2o222222222222!2}233 3 333$3-3;3>3@3D3F3G3H3J3R3T3Y 3Z 3\ 3`3c3l3o 3333 33333 3344 4 44"4#4$4-4647494:4;4<4=4>4D4M4c4n4o44444444!45 55 5"5#5$5&5*5-5254595;5<5=5@5[5] 5^5`5c5l55555566 7 7 77777"7#7$7&7*7-727477797:7;7<7@7D7F7G7H7J7Q7R7S7T7U7V7X7Y7Z7[7\7]7^7c7l7x77777377 7)77777777B8 8888$8-8=8@8D8]8^8`8c8888889 9 9 99999"9#9$9&9*9-90929497999:9;9<!9@9D9F9G9H9J9Q9R9S9T9U9V9X9]9^9c9l9n9o9x99 9 99)99 9)9999999B: : ::::":#:$:&:*:-:2:4:7:9:: :; :<:@:D:F:G:H:J:Q:R:S:T:U:V:X:^:c:l:n:o:::: :):::::; ; ;; ; ;#;$;&;*;-;2;4;7 ;9;;;<;= ;@;F;G;H;J;R;T;X;Y;Z;[;\;^;c ;l;;;;;;;;;;;;;;;;B< < <<<<<"<#<$<&<*<-<0<2<4<7<9!<:<;<<#<= <@<D<F<G<H<J<Q<R<S<T<U<V<X<[<]<^<c<l<n <o<x<<)<<(< <)<< <<<<"<<<<B= == =#=$=&=*=-=2=4=8=9 =< =>=@=F=G=H=J=R=T=W=X=Y=Z=[ =\=^=`=l== == ===== ==========>$>&>*>->2>4>6>7>8>9>:>;><>=>@P>>>>>>>>>>>>>>>>E>K>Y>u>}>>>>>>>>>@&@*@2@4@:@;@=@@@@@@@@E@u@@@@D D D D"D@DYDZD\D`DoE E EE"E@EYEZE[E\E]E`EnEoEE#EFF F@FGFJFRFY FZ F[F\ F^FlFI 'I IIII"I@'IYIZI[I\I`'IcIlIoIx II(II(II(K K K K"K@KYKZK\K`KnKoLMM NN N#N@NFNGNHNJNRNTN[N^NlNNNOQ Q Q Q"Q@QYQZQ\Q`QnQoR R R RR"R@RYRZR[R\R]R`RnRoRR#RS S S SS"S@SYSZS[S\S]S`SnSoSS#STMU UUUU"U@UTUYUZU[U\UcUlUoUWW W@WFWGWHWJWRWTW[W^WlWY YYY"Y@YFYGYHYJYRYTYYYZY[Y\YcYo YYZ ZZZ"Z@ZFZRZYZZZ[Z\ZcZo ZZ[@[F[G[H[J[R[T[[[^[l[[[]@]F]G]H]I]J]R]T]W]X]^]`]l]]]]]^$^&^*^-^2^4^6^8^=^`P^^^^^^^^^^E^Y^u^}^^^^^^`$`-`6`7`8`9`:`;`<`=``````````````K`}```````bbbbc$c&c*c-c2c4c6c7c8c9c:c; c<c=ccccccc cKccccccccc l7l9l<llKlln$n&n*n-n2n4n9n:n< n|nnnnnK nnnnn nx$x-x6x7x9x:x;x<x=xxxxxxxxxxxxxxxKxYx}xxxxxxx|7|8|9|:|<|=~~~~~~~~$&*-246789:;<= "$-79;<=>@D`cno# !} "@YZ\`no~"@ ` "@YZ[\]`no#  <"-?Z@FDEFGHJKLMNOQRSTUVW X`Fo>VfffN(M(]) ) )")Y)Z)n)o}}}}   } }} }}$&*24< P#EK Yqu $9;<=K`q}%&'()*+,-./0 1234578;<=EKYqu}$&*-2479:;<!= EK!q   !$-9;<=K`q}$%&'()*+,-./0123456789:;<=P#EKWYqu}$"&*-246789:;<=#"4EKYq#u}""" E&*24P#EWu7;=Y }7Y$-79;<=Kq}$&*-"246;=:;[][]#&*248FGHJRTWXYZ\~$79:;<=&*24789:<JYZ\}~YZ\~9< F G H J R T   &*24FGHJRTXYZ\~$-D[] $-9;<=D !#}MYZ[\~&*248FGHJRTXYZ\~> 9 < M O W X       } !Y!Z!\!!~#$[$]$$$\$\-\;\<\=\D\E\I\K\L\M\N\Q\S\U\\\\(\\\\\\\\ \\\\}9}<}(}}}}}}}}9<&*24789:<FGHRTXYZ???&*24789:<YZ\}~$&*-24DFGHJQRSTUVXYZ[\]) "$~DFGHRT$-=D    "L~    "#>@` "*ELXYu~   #@^`clno !!  "EKLYZu}~   ">@` "*LY~    ">@`K  "#@^clx   **EFLZrv|~   *@^`l"3""AEu}~    #>@^`ln  "EFLu~   ">@`  " #@^cl ""  "EFLYZuv}~    "#>@`K   "#>@`cnoK}  >@`clo   *L Yr "#>^clo   EFKLZu~  "#@^clx   **EFKLZrv|~   "#@^clnox    ) EFrv   "#>@`cno Xr}    #@^c l  "FKLZv~   *@^`l"3""FEu}~    "#>@`cno}   "@`oL   >   "@` "@^`l *LZ~  "@`~   ">@`oL   #@^lFv   "@`  #@^lF   "@`no L    ">@`noL @^`l  L  "@^`l *LZ~ "@`co   *L~   ">@`no ~ "#@^`lF  "@`T~    " @ `     L ~        " @ ` n o         "@`no    "#>  "#>@^`lF  "@^`    "#>@`" " " """@"`""" "L"~% % %%%%"%%#%@%`%l%x%%%%(%%%%%%%%%%&%!%%%%!%%%%%%%%%%%%%%%%%%%%%% % % %%%,%%%,%%*%E%F%L%Z%r%v%}%~& &&&&"&@&l&x&&&&!&!&&& !& &*&L!&Z&~2 2 2 2"2D D D"DDDD DLDZEE E E EEEE"E>E EEEEEEEEEEEEEEEEEEEEE E EEEEEEXE}F F FFF"F>FFFF FLK K KKKKK"K#K@K^KcKlKn KoKxKK KKKK"KKKKKKKKKKKKKKKKKKKKKKKKKKKKK K KKK!KKK!KK*KFKK#KZKrKvL L LLL"L@L`LcLo LLLLLLLLL L*LLL~WW W W W W"W>W@W`WWWWWWYX X X X X"X#X>X@X`XXY Y Y YYY"Y>Y@Y`YY YYYYYYYYYYYYYrYvY}Z Z Z ZZZZZ"Z>Z@Z`Z``a a"a^ale e e"eeFqqqqqqr r r rrrrr"r>r@r`ruu u u uuuu"u#u>u@u`ucunuouuuuuuuuuuuuuuuuKv v v vvvvv"v@v`vnvovvvvv vL} } }}}}>}@}`}}}}}}}}} }}}}"}*}L}Y}~~ ~ ~"~#~^~l~~~F   #@^`clno !!!!    ">@`  "#@^clx4h?O/  P Q*^^ 4   #@^`clno !!!!    #>@^`ln 4  #>@^`l   I  " #@^cl """"?)?4 >I !    "#>@`    #>@^`ln  I   "#>@`cno  >@`clo     #>@^l*S?I  "#@^clx*SII>PQ)^^4  "#@^cln ox " #*S)T 4P)^^*   "#>@`cno    #@^c l   >>> #>@`l*   "#>@`no     "@^`lno  "@`co     ">cno  #@^`l # ,"@&`&cl##4^   "#no  @`c   @^`lno  #@^`l   #@^`no   "#>@`n  "@`co    ">@`cno  ">@`n    ">@`cno "@^`cl "@`c  "@^`l  "@`cn    ">@`cno "#@^`l   "#>@`cn   "@`cno>I \"F  K @ 7 7 h  W  W   d  D  d   d :   F 4 4Copyright 2011 Canonical Ltd. Licensed under the Ubuntu Font Licence 1.0Dalton Maag LtdDaltonMaagLtd: Ubuntu Regular 0.83The Ubuntu Font Family are libre fonts funded by Canonical Ltd on behalf of the Ubuntu project. The font design work and technical implementation is being undertaken by Dalton Maag. The typeface is sans-serif, uses OpenType features and is manually hinted for clarity on desktop and mobile computing screens. The scope of the Ubuntu Font Family includes all the languages used by the various Ubuntu users around the world in tune with Ubuntu's philosophy which states that every user should be able to use their software in the language of their choice. The project is ongoing, and we expect the family will be extended to cover many written languages in the coming years.Ubuntu and Canonical are registered trademarks of Canonical Ltd.http://www.daltonmaag.com/Copyright 2011 Canonical Ltd. Licensed under the Ubuntu Font Licence 1.0Dalton Maag LtdDaltonMaagLtd: Ubuntu Regular 0.83The Ubuntu Font Family are libre fonts funded by Canonical Ltd on behalf of the Ubuntu project. The font design work and technical implementation is being undertaken by Dalton Maag. The typeface is sans-serif, uses OpenType features and is manually hinted for clarity on desktop and mobile computing screens. The scope of the Ubuntu Font Family includes all the languages used by the various Ubuntu users around the world in tune with Ubuntu's philosophy which states that every user should be able to use their software in the language of their choice. The project is ongoing, and we expect the family will be extended to cover many written languages in the coming years.Ubuntu and Canonical are registered trademarks of Canonical Ltd.Version 0.83http://www.daltonmaag.com/O  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~.nullEurouni00A0uni00ADmacronperiodcenteredAmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatdcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonek Idotaccenti.loclIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccentkgreenlandic.case kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaronnapostrophe.case napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexuni0162uni0163TcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongs Scommaaccent scommaaccentuni021Auni021Bdotlessj apostropheuni02C9WgravewgraveWacutewacute Wdieresis wdieresisYgraveygrave zerosuperior foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperior zeroinferior oneinferior twoinferior threeinferior fourinferior fiveinferior sixinferior seveninferior eightinferior nineinferior afii61289 estimatedonethird twothirds oneeighth threeeighths fiveeighths seveneighthsonefifth twofifths threefifths fourfifthsonesixth fivesixths oneseventh twosevenths threesevenths foursevenths fivesevenths sixseventhsoneninth twoninths fourninths fiveninths sevenninths eightninthsDeltauni2126uni2215uni2219f_ff_if_lf_f_if_f_lzero.altone.alttwo.alt three.altfour.altfive.altsix.alt seven.alt eight.altnine.alt zero.supsone.supstwo.sups three.sups four.sups five.supssix.sups seven.sups eight.sups nine.sups zero.sinfone.sinftwo.sinf three.sinf four.sinf five.sinfsix.sinf seven.sinf eight.sinf nine.sinf caron.alt commaaccentrevcommaaccentcaron.alt.short Parenleft ParenrightHyphenSlashAt Bracketleft Backslash Bracketright Braceleft Braceright GuilsinglleftBulletEndashEmdashGuilsinglright Exclamdown GuillemotleftGuillemotright Questiondownuni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019FOhornohornuni01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEUhornuhornuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BCuni01BDuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DDuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5Gcarongcaronuni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F0uni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F7uni01F8uni01F9 Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217uni021Cuni021Duni021Euni021Funi0220uni0221uni0222uni0223uni0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0234uni0235uni0236uni0238uni0239uni023Auni023Buni023Cuni023Duni023Euni023Funi0240uni0241uni0242uni0243uni0244uni0245uni0246uni0247uni0248uni0249uni024Auni024Buni024Cuni024Duni024Euni024Funi0292breve_inverted double_grave ring_acutedieresis_macron dot_macrondieresis_gravedieresis_acutedieresis_breve tilde_macron acute.asccircumflex.asc caron.ascdieresis_grave.capdieresis_acute.capdieresis_breve.capuni0400 afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061uni040D afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097uni0450 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109uni045D afii10110 afii10193afii10066.locluni0462uni0463uni0472uni0473uni0474uni0475uni048Auni048Buni048Cuni048Duni048Euni048F afii10050 afii10098uni0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CEuni04CFuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9 afii61352 afii00208uni20B4uni20AEtengeroublekratkaAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsialphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega Alphatonos EpsilontonosEtatonos Iotatonos Iotadieresis Omicrontonos UpsilontonosUpsilondieresis Omegatonos alphatonos epsilontonosetatonos iotatonos iotadieresisiotadieresistonos omicrontonosupsilondieresis upsilontonosupsilondieresistonos omegatonostonos tonos.cap dieresistonosuni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFE uni1F88.alt uni1F89.alt uni1F8A.alt uni1F8B.alt uni1F8C.alt uni1F8D.alt uni1F8E.alt uni1F8F.alt uni1F98.alt uni1F99.alt uni1F9A.alt uni1F9B.alt uni1F9C.alt uni1F9D.alt uni1F9E.alt uni1F9F.alt uni1FA8.alt uni1FA9.alt uni1FAA.alt uni1FAB.alt uni1FAC.alt uni1FAD.alt uni1FAE.alt uni1FAF.alt uni1FBC.alt uni1FCC.alt uni1FFC.altuni20B9uniE0FFuniEFFDuniF000ubuntuuniF0FF Bcyrlgrek latn,kernkern&kern6  $,4<DLTH-^|i .8Ndr*4>H^t~,6@N\jp~DJTZ|.Pfpv| "(.4:@FLDJPV\TZ`flrx~  3  )  )(   (((((()( )( >VfffN    >VfffN3 3 3  )(       (((3    )( ((( )   3 3 )(         )( )( *|)*|*|)*|*|*|*|)))*|4h?O/  P Q*^^ 44I?)?4 >II *S?I*SII>PQ)^^4*S)T 4P)^^* >>>*4^4*S)T 4P)^^**S)T 4P)^^*444444*S)T 4P)^^**S)T 4P)^^**S)T 4P)^^**S)T 4P)^^*44*S)T 4P)^^**S)T 4P)^^**S)T 4P)^^**S)T 4P)^^* Lp.g  ' ''      <-FF Z !" !      "# "u       lP!      !#"    #P PPz |    "  P ! P#"P" ???>zx@NPRTVX[fhjl)MV-/AI    6789P$9DFIIKUWW%Y[&]])dd*kk+mm,-DIPQ\]^opqrstuvw'x)688::<BDDFFHHJJLLOOSSUUWY[]ggiikk  *8::<<>>@@BGIIKKMRUUWY]a cikkmy{{#$&*278:t #9:;<=>@^`bceflnpstxz|~(NPRTVfhjl  !#$)STV\}%  ## >> @@ ^^``ccefllnnppstxx&)+CLT Z!b(-j69pBIt| $, 2:"'B.5H:Pi #>@^`ceflnpstx!#-/13579;=AGI]^blmosy{q     $%'()*,.0468:<>?@ABCEHIJKMOPQRSTUWY[_`cdfghjknpqtuwz|} "&2DFLNXZ\aervx~$ !"#$%&'()*+,- * %&&&&&&,,,,      !!""#####% % % % & & & ) ) ) ***+++,,,,,,*+&&-"% &' )++!! & ,,,,, "& & % &   & & ) ) ,,& & & &  )V? ++!@67Af89B:;<=C>DS*50$/.-,334 12%&  B8 2>@@@@@@E6888888;;;;>5555555....3&&&&@5@5@566667777//.......A-,,,,,3333a888111B2B2B2:%:%:%;&;&;&;&;&;&=>DDD$B2:% ===>$$$$$$$PLTMNQRU^OTT`O`000\6c"]K8<_-#F3888dW%':;&GH>DXe(YZ,3@5.8;&;&;&;&;&b@5@5E577-88X(73@5E58@5@5..8811;&;&I)/D@58888>3 @6[2J@>(n    ##::;;<<==>> @@ ^^ `` bbcceeffllnnppstxxzz||~~((NNPPRRTTVVffhhjjll*+,-./0123 !"#$%&' ('()45<=6>?7  @ABC8DEFG  H!!I##J$$K))SSDTTGVV\\L}}MN:;O9GLm7''!`#abc$de"fg@h%i&jUB:D (z)*+{,|}T~x--./012E5896 C T 'mU %2 .l !!!!!!#bbbbeeeeah%%%%%%BBBBk((((((()++++}}}}-......66!(!(!(#)#)#)#)a**b+b+b+b+b+$,$,$,$,d|d|e}e}e}e}e}}e}"Tf~fgxgxgxgxgxh-h-h-h-%.%.%.j1j1j1U2U2U2EEEBBBBBB86:::{U2ET8886{{{{{{{XY_VZW\^[]A> ?K>>zzzR#)43tS=;c%Ff~qGh-%%.%.vME<Bno6:NyrpwOsaa*ggxgg-!(e}%.BBBBB!(!(($,$,f~%.%.NpTaa*$,h-!((%.!(!(b+b+e}e}%.%.j1j1BBPud|*:!(b+%.%.%.%.6H-H*0!#)IQ2J!b+6p$)* .))))))+  )))*!       ...   "( #, .-$%&')     ))+-%)+))  .)))%Y      ##>>@@^^``cc ee ff ll nnppst xx  !"#$%&'()*+,-./01234!#%+04! #!%(-+690BI4!#%0-+4#44O( ( " : #@#+9"";##>><@@^^``cc'ee'ff#llnn%oo&pp%qq&st@xx??^^&47K82Q56L=3KJ3J     >P.ABNC/DE-F M!GH*)0,$1I>BCD!,I>B CD"'!.5,:AIJK>LMBNOCPQDRS!TU,VWIX_>hoCxI>CD,H,I<       "' .5:AJKLMNOPQRS TUVWX_`ghopwxP"    #"" ##&>>$@@^^``cceeffllnnoo ppqq st ^^ '!,*( +)% ',*%', *"'.5%:AJK'LM,NO*RSTU%VWX_'ho*x'*%%b      ##>>@@^^``cc ee ff ll nnppst xx " ,)&%) !"#$%&'()*)+,-))*!!##*-- // 1133#55$77&99&;;&==&AA-GG,II-]])^^#bb'll)mmooss"yy#{{$%%*** )L, , ' M !(I(-N""O##">>P@@%^^#``$cc+ee+ff(ll&nn)oo*pp)qq*stIxxS&S^^*ECgHBFGhQDgfDf      V;W[5.6JXY7Z[/\]0<123[=^  _  >  [  8`9.T[a:iR7[UYX1b  ;!!""?##$$/%%&&1((X**K,,]--..[//00[1122[33 4465566J77 88Y99 ::Y;; <<Y== >>Y??@@[AABB[CCDD[EEFFcGGHH0IIJJ<KKLL4MMNN4OO PP3QQRR<SSTT=UUVV=WWYYZZ@[[\\@]]^^ __6``aa[bbcc7ddee[ffgg[hhii=kkZllmm nnVoo ppVqqrrdsstt.uu vveww xxeyy zz6{{||J}}~~AXX///J111=[[   !"#$%%&&'&&"%&% ! $%%% %%"""M6 6 / 0 W1.17+""2##(>>L@@*^^)``Kcc5ee5ff1ll,nn3oo4pp3qq4st.xx-,-^^4JHIU V%$a%!GS"#$%&']%`:;<=>NO?@ABCDEXFY          >8  PQA9@?X   ;!!%""\###$$C%%&&X((?**,,D..002233G44N55S66O88@::@<<@>>@@@BBDDEEFFGG$HHEII%JJKKZLL[MMZNN[OO'PPYQQ%RRSS]TTUU]VVXXRYY_ZZ[[_\\^^G__NaabbccAeegghh]iikkBmm!nn:oo!pp:rrtt>uu^vvww^xxyyGzzN{{S||O}}T~~??#C#C#COXXX]""&&22DD FF LL NN XX ZZ \\ aaeerrvvxx~~Q   "" ##>>@@ ^^``cc)ee)ffllnn oo pp qq stxx&&^^ '(#    (  $$&&**$4466FFHHJJLL!NN!PPRRTT#VV#ZZ%\\%__cc(ii#ttzz||~~"# ZcyrlgreklatnBGR 0MKD JSRB d -9FS^i  '.:GT_j  (/;HU`k  )0<IVal   1=DJQWbm"AZE BCRT ^MOL zROM TRK !28>EKRXcn "*3?LYdo #+4@MZep $5AN[fq %6BO\gr &,7CP]hstcasecasecasecasecasecasecasecasecasednomdnomdnomdnomdnomdnom dnom&dnom,dnom2dnom8dnom>fracDfracPfrac\frachfractfracfracfracfracfracfracligaligaligaligaligaligaligaligalocllocllocllocl loclloclnumrnumr"numr(numr.numr4numr:numr@numrFnumrLnumrRnumrXordn^pnumdpnumjpnumppnumvpnum|pnumpnumpnumpnumpnumpnumsaltsaltsinfsinfsinfsinfsinfsinfsinfsinfsinfsinfsinfss01ss01subssubssubssubs"subs(subs.subs4subs:subs@subsFsubsLsupsRsupsXsups^supsdsupsjsupspsupsvsups|supssupssupstnumtnumtnumtnumtnumtnumtnumtnumtnumtnumtnum                                             8@HPX`hpx*,R)l))**+*+X++++++++/+/+/++b+2opqrstuopqrstuopqrstuopqrstuopqrstu+d+b2vwxyz{|}~xywvz{|}~vwxyz{|}~vwxyz{|}~vwxyz{|}~+2*2*n2*&nn*$0fH:, F 8 v .TtfX>rd  Z"<#.$ $%&&0bjrz "*2:BJRZbjrznnnnnnnnnnnpnqnrnsntnunxnynzn{n|n}n~nnnnnnnnnnnnnnnnnnnnnnnnn2:BJRZbjrznnnnnnqnsnunyn{n}nnnnnnnnnnnnn2:BJRZbjrznnnnnpnqnsntnzn{n}n~nnnnnnnnnnnn&.6>FNV^fnv~nnnnqnsnun{n}nnnnnnnnnn2:BJRZbjrznnnnnrnsntnun|n}n~nnnnnnnnnnnnn&.6nnsn}nnn "*2:BJRZbjrnnntnun~nnnnnnn&.6nnunnnn2:BJRZbjrznnnnnnqnsnunyn{n}nnnnnnnnnnnnn2:BJRZbjrznnnnnpnqnsntnzn{n}n~nnnnnnnnnnnn0bjrz "*2:BJRZbjrznnnnnnnnnnnpnqnrnsntnunxnynzn{n|n}n~nnnnnnnnnnnnnnnnnnnnnnnnn&.6>FNV^fnv~nnnnqnsnun{n}nnnnnnnnnn2:BJRZbjrznnnnnrnsntnun|n}n~nnnnnnnnnnnnn&.6nnsn}nnn "*2:BJRZbjrnnntnun~nnnnnnn&.6nnunnnn0bjrz "*2:BJRZbjrznnnnnnnnnnnpnqnrnsntnunxnynzn{n|n}n~nnnnnnnnnnnnnnnnnnnnnnnnn2:BJRZbjrznnnnnnqnsnunyn{n}nnnnnnnnnnnnn2:BJRZbjrznnnnnpnqnsntnzn{n}n~nnnnnnnnnnnn&.6>FNV^fnv~nnnnqnsnun{n}nnnnnnnnnn2:BJRZbjrznnnnnrnsntnun|n}n~nnnnnnnnnnnnn&.6nnsn}nnn "*2:BJRZbjrnnntnun~nnnnnnn&.6nnunnnn0bjrz "*2:BJRZbjrznnnnnnnnnnnpnqnrnsntnunxnynzn{n|n}n~nnnnnnnnnnnnnnnnnnnnnnnnn2:BJRZbjrznnnnnnqnsnunyn{n}nnnnnnnnnnnnn2:BJRZbjrznnnnnpnqnsntnzn{n}n~nnnnnnnnnnnn&.6>FNV^fnv~nnnnqnsnun{n}nnnnnnnnnn2:BJRZbjrznnnnnrnsntnun|n}n~nnnnnnnnnnnnn&.6nnsn}nnn "*2:BJRZbjrnnntnun~nnnnnnn&.6nnunnnn0bjrz "*2:BJRZbjrznnnnnnnnnnnpnqnrnsntnunxnynzn{n|n}n~nnnnnnnnnnnnnnnnnnnnnnnnn2:BJRZbjrznnnnnnqnsnunyn{n}nnnnnnnnnnnnn2:BJRZbjrznnnnnpnqnsntnzn{n}n~nnnnnnnnnnnn&.6>FNV^fnv~nnnnqnsnun{n}nnnnnnnnnn2:BJRZbjrznnnnnrnsntnun|n}n~nnnnnnnnnnnnn&.6nnsn}nnn "*2:BJRZbjrnnntnun~nnnnnnn&.6nnunnnn0bjrz "*2:BJRZbjrznnnnnnnnnnnpnqnrnsntnunxnynzn{n|n}n~nnnnnnnnnnnnnnnnnnnnnnnnn2:BJRZbjrznnnnnnqnsnunyn{n}nnnnnnnnnnnnn2:BJRZbjrznnnnnpnqnsntnzn{n}n~nnnnnnnnnnnn&.6>FNV^fnv~nnnnqnsnun{n}nnnnnnnnnn2:BJRZbjrznnnnnrnsntnun|n}n~nnnnnnnnnnnnn&.6nnsn}nnn "*2:BJRZbjrnnntnun~nnnnnnn&.6nnunnnn2opqrstuopqrstuopqrstuopqrstuopqrstu0LP6-N$%&'()*+,-./0123456789:;<=kmz   "$&(*,.02468:<>@BDFHJLNPRTVY[fhjlL "(ILIOILO "(ILIOILO "(ILIOILO    xywvz{|}~Lv DR ou  o ( o  pt w~ (nnvou #>?@^`lrstx|X]DEFGHIJKLMNOPQRSTUVWXYZ[\]wy  !#%')+-/13579;=?ACEGIKMOQSUWZ\gikmI`gpw0 *H 01 0 +0a +7S0Q0, +7<<<Obsolete>>>0!0 +Faܶ9eՔǠb040l.60  *H 01 0 UUS10UArizona10U Scottsdale1%0#U Starfield Technologies, Inc.1:08U 1http://certificates.starfieldtech.com/repository/1604U-Starfield Services Root Certificate Authority0 150316070000Z 200316070000Z01 0 UUS10UArizona10U Scottsdale1%0#U Starfield Technologies, Inc.1402U+Starfield Services Timestamp Authority - G10"0  *H 0 xo(QQ`L~&aF=Ӌd="?\̈bDطl=HSN̢A;C) (TXA-Nفk1 ag,4L{I hEKbK!(7pOX_Μ8Bk[4e/ ^S7AboB \ 2%|cA˫FkT240BpN0J0 U00U0U% 0 +0U O fer0U#0C̛u]/KQ0:+.0,0*+0http://ocsp.starfieldtech.com/0DU=0;09753http://crl.starfieldtech.com/repository/sfsroot.crl0PU I0G0E `Hn0604+(http://crl.starfieldtech.com/repository/0  *H 33%ýB6,phiDmBϯi e̷JݙadrmDҺ?03ݶ")fPNwqcZ>,/H t87ޞ[Vb4˖ }{Z+Rrc"r(^&a D{-RķT=ayP[,e՞^T\m?^a_+}R00Ơ0  *H 0c1 0 UUS1!0U The Go Daddy Group, Inc.110/U (Go Daddy Class 2 Certification Authority0 061116015437Z 261116015437Z01 0 UUS10UArizona10U Scottsdale10U GoDaddy.com, Inc.1301U *http://certificates.godaddy.com/repository100.U'Go Daddy Secure Certification Authority10U079692870"0  *H 0 -&L25_YZaY;pc=*3y:<0#0=Tߙ %!e)~5T29&UXמ* BΧ?Rifھ],fkQJ/Hǘuع)fm x|z%.enjDSp0Ü+X+=tJQL'Xk5ŝ1 6:%IgE96~7qt0? O20.0Ua2lE_vh0U#0İґLqa=ݨj0U003+'0%0#+0http://ocsp.godaddy.com0FU?0=0;975http://certificates.godaddy.com/repository/gdroot.crl0KU D0B0@U 0806+*http://certificates.godaddy.com/repository0U0  *H ҆gf :PrJtS7DIk3ٖV0<2!{ $F%#go]{z̟X*Ğ!ZFc/))r,)7'Oh! SY ;$IHE:6oEEADN>tvբU,ƇuLn=qQ@"(IK4Zц6d5oownP^S#c͹c:h5S000  *H 0c1 0 UUS1!0U The Go Daddy Group, Inc.110/U (Go Daddy Class 2 Certification Authority0 040629170620Z 340629170620Z0c1 0 UUS1!0U The Go Daddy Group, Inc.110/U (Go Daddy Class 2 Certification Authority0 0  *H  0ޝWI[_HgehWq^wIp=Vco?T"Tزu=Kw>x k/j+ň~ĻE'o7X&-r6N?e*n] :-؎_=\e8E``tArbbo_BQe#jxMZ@^s wyg ݠXD{ >b(_ASX~8tit00UİґLqa=ݨj0U#0İґLqa=ݨjge0c1 0 UUS1!0U The Go Daddy Group, Inc.110/U (Go Daddy Class 2 Certification Authority0 U00  *H 2K>ơw3\= ni04cr8(1zT1Xb۔EsE$Ղ#yiML3#An 剞;p~& T%ns! l l a+r9 ͗nN&s+L&qatJWuH.Qia@LĬC Օb ψ2 +E (*ZW7۽0@0(5y0  *H 01 0 UUS10UArizona10U Scottsdale10U GoDaddy.com, Inc.1301U *http://certificates.godaddy.com/repository100.U'Go Daddy Secure Certification Authority10U079692870 120807154320Z 150924134423Z0k1 0 UGB10 ULondon10 ULondon10U Dalton Maag Limited10UDalton Maag Limited0"0  *H 0 YZ=&ȯ p)ZrYyW ,=|QQ7 Ex>+3>L woZ"Cs0J1*#\>xOh+w{wܘe,̵>%]D@E*v1,g6Fpgm# O8(z;+uKXF[cK d^<3 MD4ݽP;t#wE EiP%~"9":I00U00U% 0 +0U03U,0*0(&$"http://crl.godaddy.com/gds5-16.crl0SU L0J0H `Hm0907++http://certificates.godaddy.com/repository/0+t0r0$+0http://ocsp.godaddy.com/0J+0>http://certificates.godaddy.com/repository/gd_intermediate.crt0U#0a2lE_vh0U=QCo vڧԚ)0  *H !.w*=`oi e̦d`zBe+kCz~KMO> !X0jVfjݥ!rewQY!ivԣpƠkOw?szg9ӽd\:Nz %[n@Ԝ7*暹мmew"ɳ0oH;@']&l6$FM: Ej?:,aAr%'l3YZ5F9QY10001 0 UUS10UArizona10U Scottsdale10U GoDaddy.com, Inc.1301U *http://certificates.godaddy.com/repository100.U'Go Daddy Secure Certification Authority10U079692875y0 +0 +7 100 +7(10 *H  1  +70 +7 10  +70# *H  1?{s.dpL0  *H ֏R:"hLrOT{q+; <58+,i @^aΰ=W~)hau>#^"s1PQ+RaySession-0.12.2/resources/generate_resources.py000077500000000000000000000015211417052567600221620ustar00rootroot00000000000000#!/usr/bin/python3 import os import sys if __name__ == '__main__': resource_dirs = ('48x48', '128x128', '256x256', 'scalable', 'app_icons', 'fonts', 'canvas', 'cursors') contents = '\n' contents += ' \n' os.chdir(os.path.dirname(sys.argv[0])) for resource_dir in resource_dirs: for root, dirs, files in os.walk(resource_dir): #exclude hidden files and dirs files = [f for f in files if not f.startswith('.')] dirs[:] = [d for d in dirs if not d.startswith('.')] for file in files: contents += ' %s/%s\n' % (root, file) contents += ' \n' contents += '\n' resources_file = open('resources.qrc', 'w') resources_file.write(contents) RaySession-0.12.2/resources/resources.qrc000066400000000000000000000245011417052567600204450ustar00rootroot00000000000000 48x48/raysession.png 128x128/raysession.png 256x256/raysession.png scalable/audio-input-microphone.svg scalable/raysession.svg scalable/pb_hardware.svg scalable/raysession24.svg scalable/microphone.svg scalable/pb_generic.svg scalable/audio-headphones.svg scalable/raysession64.svg scalable/raysession_little.svg scalable/raysession_old.svg scalable/audio-volume-medium.svg scalable/raysession16.svg scalable/raysession48.svg scalable/DIN-5.svg scalable/raysession256.svg scalable/breeze-dark/document-saved.svg scalable/breeze-dark/lines-connector.svg scalable/breeze-dark/document-edit.svg scalable/breeze-dark/run-install.svg scalable/breeze-dark/folder-new.svg scalable/breeze-dark/system-file-manager.svg scalable/breeze-dark/link.svg scalable/breeze-dark/media-playback-stop.svg scalable/breeze-dark/list-remove.svg scalable/breeze-dark/lines-disconnector.svg scalable/breeze-dark/notes-nonempty.svg scalable/breeze-dark/im-user.svg scalable/breeze-dark/configure.svg scalable/breeze-dark/emblem-symbolic-link.svg scalable/breeze-dark/visibility.svg scalable/breeze-dark/document-open.svg scalable/breeze-dark/xml-node-duplicate.svg scalable/breeze-dark/view-list-icons.svg scalable/breeze-dark/list-add.svg scalable/breeze-dark/notes-editing.svg scalable/breeze-dark/window-close.svg scalable/breeze-dark/document-unsaved.svg scalable/breeze-dark/media-playback-start.svg scalable/breeze-dark/hint.svg scalable/breeze-dark/media-seek-backward.svg scalable/breeze-dark/document-nosave.svg scalable/breeze-dark/trash-empty.svg scalable/breeze-dark/zoom-centered.svg scalable/breeze-dark/media-playback-stop_red.svg scalable/breeze-dark/draw-star.svg scalable/breeze-dark/document-save.svg scalable/breeze-dark/document-save-as-template.svg scalable/breeze-dark/notes.svg scalable/breeze-dark/application-menu.svg scalable/breeze-dark/disabled/run-install.svg scalable/breeze-dark/disabled/folder-new.svg scalable/breeze-dark/disabled/system-file-manager.svg scalable/breeze-dark/disabled/link.svg scalable/breeze-dark/disabled/media-playback-stop.svg scalable/breeze-dark/disabled/list-remove.svg scalable/breeze-dark/disabled/notes-nonempty.svg scalable/breeze-dark/disabled/configure.svg scalable/breeze-dark/disabled/emblem-symbolic-link.svg scalable/breeze-dark/disabled/visibility.svg scalable/breeze-dark/disabled/document-open.svg scalable/breeze-dark/disabled/xml-node-duplicate.svg scalable/breeze-dark/disabled/view-list-icons.svg scalable/breeze-dark/disabled/list-add.svg scalable/breeze-dark/disabled/notes-editing.svg scalable/breeze-dark/disabled/window-close.svg scalable/breeze-dark/disabled/media-playback-start.svg scalable/breeze-dark/disabled/hint.svg scalable/breeze-dark/disabled/media-seek-backward.svg scalable/breeze-dark/disabled/trash-empty.svg scalable/breeze-dark/disabled/document-save.svg scalable/breeze-dark/disabled/document-save-as-template.svg scalable/breeze-dark/disabled/notes.svg scalable/breeze-dark/disabled/application-menu.svg scalable/breeze/document-saved.svg scalable/breeze/lines-connector.svg scalable/breeze/run-install.svg scalable/breeze/folder-new.svg scalable/breeze/system-file-manager.svg scalable/breeze/link.svg scalable/breeze/media-playback-stop.svg scalable/breeze/list-remove.svg scalable/breeze/lines-disconnector.svg scalable/breeze/media-playback-stop-red.svg scalable/breeze/notes-nonempty.svg scalable/breeze/im-user.svg scalable/breeze/configure.svg scalable/breeze/emblem-symbolic-link.svg scalable/breeze/visibility.svg scalable/breeze/document-open.svg scalable/breeze/xml-node-duplicate.svg scalable/breeze/view-list-icons.svg scalable/breeze/list-add.svg scalable/breeze/notes-editing.svg scalable/breeze/window-close.svg scalable/breeze/document-unsaved.svg scalable/breeze/media-playback-start.svg scalable/breeze/audio-jack-connector.svg scalable/breeze/hint.svg scalable/breeze/media-seek-backward.svg scalable/breeze/empty-icon.svg scalable/breeze/document-nosave.svg scalable/breeze/trash-empty.svg scalable/breeze/zoom-centered.svg scalable/breeze/draw-star.svg scalable/breeze/document-save.svg scalable/breeze/document-save-as-template.svg scalable/breeze/notes.svg scalable/breeze/star-yellow.svg scalable/breeze/application-menu.svg scalable/breeze/disabled/run-install.svg scalable/breeze/disabled/folder-new.svg scalable/breeze/disabled/system-file-manager.svg scalable/breeze/disabled/link.svg scalable/breeze/disabled/media-playback-stop.svg scalable/breeze/disabled/list-remove.svg scalable/breeze/disabled/notes-nonempty.svg scalable/breeze/disabled/configure.svg scalable/breeze/disabled/emblem-symbolic-link.svg scalable/breeze/disabled/visibility.svg scalable/breeze/disabled/document-open.svg scalable/breeze/disabled/xml-node-duplicate.svg scalable/breeze/disabled/view-list-icons.svg scalable/breeze/disabled/list-add.svg scalable/breeze/disabled/notes-editing.svg scalable/breeze/disabled/window-close.svg scalable/breeze/disabled/media-playback-start.svg scalable/breeze/disabled/hint.svg scalable/breeze/disabled/media-seek-backward.svg scalable/breeze/disabled/trash-empty.svg scalable/breeze/disabled/document-save.svg scalable/breeze/disabled/document-save-as-template.svg scalable/breeze/disabled/notes.svg scalable/breeze/disabled/application-menu.svg scalable/test_icon/dessin.svg app_icons/qsampler.png app_icons/padthv1.svg app_icons/sequencer64.png app_icons/zynaddsubfx.svg app_icons/non-timeline.png app_icons/jack_mixer.svg app_icons/non-mixer.png app_icons/ADLplug.png app_icons/org.hydrogenmusic.Hydrogen.svg app_icons/gx_head.png app_icons/vmpk.svgz app_icons/seq24.png app_icons/fluajho.png app_icons/rosegarden.png app_icons/shuriken.png app_icons/h2-icon.svg app_icons/luppp.png app_icons/carla.svg app_icons/non-sequencer.png app_icons/calf.svg app_icons/curve-connector.svg app_icons/network-wired.svg app_icons/ardour.svg app_icons/OPNplug.png app_icons/amsynth.svg app_icons/qtractor.svg app_icons/Mamba.png app_icons/petri-foo.png app_icons/drumkv1.svg app_icons/samplv1.svg app_icons/synthv1.svg app_icons/patroneo.png app_icons/patchage.svg app_icons/sooperlooper.png app_icons/dark/curve-connector.svg app_icons/dark/network-wired.svg fonts/Ubuntu-C.ttf fonts/Ubuntu-R.ttf cursors/zoom-out-white.png cursors/zoom-area-white.png cursors/zoom-in-black.png cursors/zoom-out-black.png cursors/update-pixmaps.sh cursors/zoom-area-black.png cursors/zoom-generic-black.png cursors/cut-white.png cursors/cut-black.png cursors/zoom-in-white.png cursors/zoom-generic-white.png cursors/src/zoom-in.svg cursors/src/cut.svg cursors/src/zoom-area.svg cursors/src/zoom-generic.svg cursors/src/zoom-centered.svg cursors/src/zoom-out.svg RaySession-0.12.2/resources/scalable/000077500000000000000000000000001417052567600174705ustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/.directory000066400000000000000000000001531417052567600214740ustar00rootroot00000000000000[Dolphin] GroupedSorting=true SortRole=modificationtime Timestamp=2020,10,28,15,51,50 Version=4 ViewMode=1 RaySession-0.12.2/resources/scalable/DIN-5.svg000066400000000000000000000076231417052567600207750ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/audio-headphones.svg000066400000000000000000000055371417052567600234400ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/audio-input-microphone.svg000066400000000000000000000040501417052567600246070ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/audio-volume-medium.svg000066400000000000000000000047421417052567600241040ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/000077500000000000000000000000001417052567600216635ustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/breeze-dark/.directory000066400000000000000000000001671417052567600236740ustar00rootroot00000000000000[Dolphin] GroupedSorting=true SortOrder=1 SortRole=modificationtime Timestamp=2019,11,20,12,14,42 Version=4 ViewMode=1 RaySession-0.12.2/resources/scalable/breeze-dark/application-menu.svg000066400000000000000000000006731417052567600256570ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/configure.svg000066400000000000000000000013301417052567600243620ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/000077500000000000000000000000001417052567600234325ustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/breeze-dark/disabled/application-menu.svg000066400000000000000000000006731417052567600274260ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/configure.svg000066400000000000000000000013301417052567600261310ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/document-open.svg000066400000000000000000000011331417052567600267260ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/document-save-as-template.svg000066400000000000000000000021021417052567600311320ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/document-save.svg000066400000000000000000000012331417052567600267240ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/emblem-symbolic-link.svg000066400000000000000000000016001417052567600301630ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/folder-new.svg000066400000000000000000000012741417052567600262210ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/hint.svg000066400000000000000000000024571417052567600251250ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/link.svg000066400000000000000000000017421417052567600251140ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/list-add.svg000066400000000000000000000007521417052567600256600ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/list-remove.svg000066400000000000000000000013071417052567600264220ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/media-playback-start.svg000066400000000000000000000013411417052567600301500ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/media-playback-stop.svg000066400000000000000000000013471417052567600300060ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/media-seek-backward.svg000066400000000000000000000004561417052567600277400ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/notes-editing.svg000077700000000000000000000000001417052567600305702notes.svgustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/breeze-dark/disabled/notes-nonempty.svg000077700000000000000000000000001417052567600310162notes.svgustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/breeze-dark/disabled/notes.svg000066400000000000000000000015631417052567600253100ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/run-install.svg000066400000000000000000000026161417052567600264300ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/system-file-manager.svg000066400000000000000000000224411417052567600300270ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/disabled/trash-empty.svg000066400000000000000000000006121417052567600264270ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/view-list-icons.svg000066400000000000000000000010441417052567600272060ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/visibility.svg000066400000000000000000000020461417052567600263440ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/window-close.svg000066400000000000000000000010501417052567600265610ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/disabled/xml-node-duplicate.svg000066400000000000000000000011251417052567600276450ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/document-edit.svg000066400000000000000000000015631417052567600251520ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/document-nosave.svg000066400000000000000000000062361417052567600255220ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/document-open.svg000066400000000000000000000011331417052567600251570ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/document-save-as-template.svg000066400000000000000000000020401417052567600273640ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/document-save.svg000066400000000000000000000012311417052567600251530ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/document-saved.svg000066400000000000000000000044471417052567600253330ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/document-unsaved.svg000066400000000000000000000056631417052567600256770ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/draw-star.svg000066400000000000000000000010501417052567600243040ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/emblem-symbolic-link.svg000066400000000000000000000016001417052567600264140ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/folder-new.svg000066400000000000000000000012741417052567600244520ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/hint.svg000066400000000000000000000024571417052567600233560ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/im-user.svg000066400000000000000000000012431417052567600237650ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/lines-connector.svg000066400000000000000000000045461417052567600255170ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/lines-disconnector.svg000066400000000000000000000063051417052567600262120ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/link.svg000066400000000000000000000017421417052567600233450ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/list-add.svg000066400000000000000000000007521417052567600241110ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/list-remove.svg000066400000000000000000000012661417052567600246570ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/media-playback-start.svg000066400000000000000000000013371417052567600264060ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/media-playback-stop.svg000066400000000000000000000013451417052567600262350ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/media-playback-stop_red.svg000066400000000000000000000013451417052567600270670ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/media-seek-backward.svg000066400000000000000000000004561417052567600261710ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/notes-editing.svg000066400000000000000000000052171417052567600251620ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/notes-nonempty.svg000066400000000000000000000052201417052567600254020ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/notes.svg000066400000000000000000000043301417052567600235340ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/run-install.svg000066400000000000000000000026161417052567600246610ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/system-file-manager.svg000066400000000000000000000224411417052567600262600ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/trash-empty.svg000066400000000000000000000006121417052567600246600ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/view-list-icons.svg000066400000000000000000000010441417052567600254370ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/visibility.svg000066400000000000000000000055441417052567600246030ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze-dark/window-close.svg000066400000000000000000000010161417052567600250140ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/xml-node-duplicate.svg000066400000000000000000000011231417052567600260740ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze-dark/zoom-centered.svg000066400000000000000000000114461417052567600251650ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/000077500000000000000000000000001417052567600207445ustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/breeze/.directory000066400000000000000000000001671417052567600227550ustar00rootroot00000000000000[Dolphin] GroupedSorting=true SortOrder=1 SortRole=modificationtime Timestamp=2019,11,20,12,32,14 Version=4 ViewMode=1 RaySession-0.12.2/resources/scalable/breeze/application-menu.svg000066400000000000000000000006731417052567600247400ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/audio-jack-connector.svg000066400000000000000000000022711417052567600254660ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/configure.svg000066400000000000000000000013301417052567600234430ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/000077500000000000000000000000001417052567600225135ustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/breeze/disabled/application-menu.svg000066400000000000000000000006731417052567600265070ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/configure.svg000066400000000000000000000013301417052567600252120ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/document-open.svg000066400000000000000000000011331417052567600260070ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/document-save-as-template.svg000066400000000000000000000021021417052567600302130ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/document-save.svg000066400000000000000000000012331417052567600260050ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/emblem-symbolic-link.svg000066400000000000000000000016001417052567600272440ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/folder-new.svg000066400000000000000000000012741417052567600253020ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/hint.svg000066400000000000000000000024571417052567600242060ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/link.svg000066400000000000000000000017421417052567600241750ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/list-add.svg000066400000000000000000000007521417052567600247410ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/list-remove.svg000066400000000000000000000013071417052567600255030ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/media-playback-start.svg000066400000000000000000000013411417052567600272310ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/media-playback-stop.svg000066400000000000000000000013471417052567600270670ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/media-seek-backward.svg000066400000000000000000000004561417052567600270210ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/notes-editing.svg000077700000000000000000000000001417052567600276512notes.svgustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/breeze/disabled/notes-nonempty.svg000077700000000000000000000000001417052567600300772notes.svgustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/breeze/disabled/notes.svg000066400000000000000000000015621417052567600243700ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/run-install.svg000066400000000000000000000026161417052567600255110ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/system-file-manager.svg000066400000000000000000000224411417052567600271100ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/disabled/trash-empty.svg000066400000000000000000000006121417052567600255100ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/view-list-icons.svg000066400000000000000000000011441417052567600262700ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/visibility.svg000066400000000000000000000020451417052567600254240ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/window-close.svg000066400000000000000000000010501417052567600256420ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/disabled/xml-node-duplicate.svg000066400000000000000000000011251417052567600267260ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/document-nosave.svg000066400000000000000000000062361417052567600246030ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/document-open.svg000066400000000000000000000011331417052567600242400ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/document-save-as-template.svg000066400000000000000000000021001417052567600264420ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/document-save.svg000066400000000000000000000012311417052567600242340ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/document-saved.svg000066400000000000000000000044541417052567600244120ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/document-unsaved.svg000066400000000000000000000056571417052567600247630ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/draw-star.svg000066400000000000000000000010501417052567600233650ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/emblem-symbolic-link.svg000066400000000000000000000016001417052567600254750ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/empty-icon.svg000066400000000000000000000030721417052567600235530ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/folder-new.svg000066400000000000000000000012741417052567600235330ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/hint.svg000066400000000000000000000024571417052567600224370ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/im-user.svg000066400000000000000000000012431417052567600230460ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/lines-connector.svg000066400000000000000000000045771417052567600246040ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/lines-disconnector.svg000066400000000000000000000063361417052567600252770ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/link.svg000066400000000000000000000017421417052567600224260ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/list-add.svg000066400000000000000000000007521417052567600231720ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/list-remove.svg000066400000000000000000000012661417052567600237400ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/media-playback-start.svg000066400000000000000000000013371417052567600254670ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/media-playback-stop-red.svg000066400000000000000000000013451417052567600260660ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/media-playback-stop.svg000066400000000000000000000013451417052567600253160ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/media-seek-backward.svg000066400000000000000000000004561417052567600252520ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/notes-editing.svg000066400000000000000000000052241417052567600242410ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/notes-nonempty.svg000066400000000000000000000052251417052567600244700ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/notes.svg000066400000000000000000000015631417052567600226220ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/run-install.svg000066400000000000000000000026161417052567600237420ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/star-yellow.svg000066400000000000000000000056641417052567600237620ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/system-file-manager.svg000066400000000000000000000224411417052567600253410ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/trash-empty.svg000066400000000000000000000006121417052567600237410ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/view-list-icons.svg000066400000000000000000000011451417052567600245220ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/visibility.svg000066400000000000000000000055571417052567600236700ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/breeze/window-close.svg000066400000000000000000000010161417052567600240750ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/xml-node-duplicate.svg000066400000000000000000000011231417052567600251550ustar00rootroot00000000000000 RaySession-0.12.2/resources/scalable/breeze/zoom-centered.svg000066400000000000000000000114461417052567600242460ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/microphone.svg000066400000000000000000000156251417052567600223650ustar00rootroot00000000000000 Svg Vector Icons : http://www.onlinewebfonts.com/icon image/svg+xml RaySession-0.12.2/resources/scalable/pb_generic.svg000066400000000000000000000206561417052567600223170ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/pb_hardware.svg000066400000000000000000000135651417052567600225010ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/raysession.svg000066400000000000000000000153541417052567600224200ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/scalable/raysession16.svg000066400000000000000000000470031417052567600225630ustar00rootroot00000000000000 image/svg+xmlRaySession-0.12.2/resources/scalable/raysession24.svg000066400000000000000000000523051417052567600225630ustar00rootroot00000000000000 image/svg+xmlRaySession-0.12.2/resources/scalable/raysession256.svg000066400000000000000000000561001417052567600226470ustar00rootroot00000000000000 image/svg+xmlRaySession-0.12.2/resources/scalable/raysession48.svg000066400000000000000000000560341417052567600225740ustar00rootroot00000000000000 image/svg+xmlRaySession-0.12.2/resources/scalable/raysession64.svg000066400000000000000000000561771417052567600226020ustar00rootroot00000000000000 image/svg+xmlRaySession-0.12.2/resources/scalable/raysession_little.svg000066400000000000000000000357321417052567600237770ustar00rootroot00000000000000 image/svg+xmlRaySession-0.12.2/resources/scalable/raysession_old.svg000066400000000000000000000562171417052567600232610ustar00rootroot00000000000000 image/svg+xmlRaySession-0.12.2/resources/scalable/test_icon/000077500000000000000000000000001417052567600214575ustar00rootroot00000000000000RaySession-0.12.2/resources/scalable/test_icon/dessin.svg000066400000000000000000000140371417052567600234720ustar00rootroot00000000000000 image/svg+xml RaySession-0.12.2/resources/screenshots/000077500000000000000000000000001417052567600202625ustar00rootroot00000000000000RaySession-0.12.2/resources/screenshots/Screenshot_20190724_084844.png000066400000000000000000001514271417052567600247420ustar00rootroot00000000000000PNG  IHDRxQ pHYs+ IDATx^u|ݥIS lƆO0e0swgo. acp{]iFGiB*m;r{s;cC2 q l,A?     cuN@9sf@A̙3='v9u< ǔ Pd0&D*?"uZUcnnrAAN\\OGC)))RMX\\\m  7aoڪ_`ñBHJJrW Bm޼`0ti\\'8(óNCs̙… ep1$KJJ$Z pZ:@XXOn޼`;[UUMQMUUd2p8L&p؃~n5Pz$+t:-u]$IQUUeY4MVEu]4MvdEcA`Y:%I5M*{i6]mWfi6N"V!AܖCv*{~NjIDTMv4kق sMk7̀g;=mLFj:-fdE!=5UUQU̴tO%8=ܶ3Qtޕ0!7;5+<$4?_fȲL4n֔ sEذf=% \lLm r Dr.$6nDl|<;'n#i4?+ٴn9HDI4i Ť`+`X9 YK'#5\;#]{u':6I)9X̪cj|^ ik];vsvI∊n@yy[6lYMiق:ٵm'wi$wLHKg&͛Ѷc;V+eelݘBVF&5=yoް:q}uN8=^ǫGJx3{FpoJz70ydgW,ށTSo*nzXf\Bag@_V.Y]NNvaǏ$IGӰI#(RfѲmk_e=p!D6bߝҒR гooRm[3Ϡ?- SR\LNf6u!#5;v( aUK@l|Avmwϙmݮ YJEy9:%ѵW0ꥬ@tL4{v&m~ }g굤(os I,Nа0vȨH3V1,W˶сy\;6S_*+-e}w, F %7;̴ bԭ /@! ߗ%?w '|ZRYYTsW=j?I;XC؃;Yl}أ LUX+i\rpVF+]PL&.. ʶ۽S0"$PiX4n@N҅Pt3 dгtK~nG_)Ir]jY9oԆq[V똦֏aM6p߳wҳong]8C{wW>]ڧd2ܵ3aHDiI)7l ZNݺ2s$26^KyY5O躎`8*ˍWږISԥQ (//g( ;'i~Ziæuѷ` e%Zsby۳u$Gʘ3r+7kLQILfiVEQBt]4-B{U c!}Hp_ Յ%w4kުZP>=)/+g*A8,($I5M+*,!˲B rss8-..NONNgˉ~Bz[dY?p8XϲzPqz` ;qzcP$ICŔ{qA8Eי[y;2MfZ yA8B'44\ʛP7&&.p<2RMOA3&SKUǦTpC]'7;爯#  MAAMAAMAAMAAMAAMAA q+AAi BDh BDh B^{^:AA8H3gx_MAŢ) Ғ(..qA%LJJAMLLL@y<>k>Scpn|bnjiwԱl_"''LNz̈́cIbr\5qX8;c:=w%8B]wtcA8mO&Əa1b#3 'SlWu ޺u췭‰RЌJKKQUU GƂ[_}cNqqqL:l6*^zYuynF~WSǹ#ss}MLjgz-Zp(--_12ڴnS<պs72~XsoMsQQQ>0ݻ1~앴mIaTGbe\rPTTĆM)<ԳZ20s/vLHmӚҩS2!V+/cZk߮-ݻSIo8I+IѶMkv'дIcYؾc @q3ǟ /aڥ3w6hqcO^L??ΝYӦuN1{99L>cqusO??۳B7u}Y|͓$ u:-=iB3O?뮹 vzc5IIiܸ1yy,֭O}Ìd|姤l'`ӥs'h >. 7]}G3 ;xW&<b QUrtIae,HLHog3+ a<8PLnr#s{~)۶}W}̇|ʕ_FbbYYڛl޼)7Mf@~t֕k;g<쓼k̘>Se5WNN١#u`>`;6VO<ʷ.|c̅Ft 6z=v[bīYTI~L門sɧ^f2?k2Vsfdee`bXI^~>ztkޭ++IOOKNL&:wJfgKÏr֠3nzBBB1|}::oOll $u}@$^s^^35mJӦMhԨ!IOQU,Y/Lt ψ5k))-IFz\n6"""x<{JfV\tqHKKgo={݋HHsdf}v2f}'44/faX2>ʵ]sr3O_BPP&lsɧNgu]t]p}K;opbtMТy3KOb&44Vd2~7J3 Ya# [xG:bcf? i[QQADx8_b^9[g_~oAZzMƄc8n >D=C$;' jt(Oɢ xv$HxSo 2֛8eff;1~야Lfr5]׹ir47n⍷%7/_{.8AiI o>7mZTZZzA$"##Tk>7p:U>νccbPp] ^@s±W$hTu:{Urrr=N~:UPp۶s]w{>@CDTd$R6S^^#22OxWeG>3cS5roזg| ֭}y爎nc?WL{||BY ٻo`}>u쇪T[[HHj2vvOoGf,--> ΣU5֊|Lq27;@4~W~7=y/gڂ Ąt]'77h?o*ʮYi}U>.='|N@Ψʯ!77/Sd2Zhι d2( mZ\f-W^q9.[ܵ 4U~<`@3iҸf(.8\l݆i̙'II$ Lhݪg1-=b Eq]Ą=Yi0їbU9z#}.8?wq+|)_t e{?5tm-7@HH$@0]:wm6`Z9 Iٻךd"9#,cٵgm)9 Ōl۾Y!gd)e37\w 믽/8lDxg䷟g>Y>K/IѨQC, M7qFu>MրkŸ=w:8%{G^<.,,dƽ06&TUc=<4q***o.8o$3+9s<W"#"())aͺ-7ןdeekoԺ01 d{C!Ī^kqТysY ||M(.)_0EcOrǭ73/*X|:=ަu'{^ѣw:esƍ+.L~~oG>[fLʈ)ei;H?>fΜ)HRqqԪU+)77W6JiiiZPHHH0,z 'y<ꯇ‰Smlt4}<+YX%#=L~A>11!նN}!ABMӊTU-$b9###Uݮiw8=99Y9sX~J4o N/U F-\1z+F:/'ZuhA<S /´we6ycAmhI4‰S_؉Wc,''{{X,)u  K"4A!@"4A!@"4A!@"4A!@"4A!@"4A!@"4A!@"4A!@"4A!@"4A!@"4A!@$a Be$Y܂IAivsc4%IlA1)"0A:%Il9.=i DAXvCS"A1_A7<4AT!BSA$BSA$BSA$BSAt\t{cQl6=7A~fmmEvLg_)`+I#$+VT:)8XI5k" $Dlqju^& ظ)}A pladoλj9ٕ!/IO cn+2c`KÎ6$aabanyX%'04^={J&`Fw)Z1?iUlI5~l<,! w)aL]JC7*Yj5cD/߯z@{qS X, Q d2iV?嗎BQ[Xy G\Be2&ZJce+i&QRU()X 5bMZ#N8hޜ7^}7Bff:`,/_SOgLd(!E:Zƣ0jC6dK:' FOs(߰٫X$uH2yK64X8u2a.bJKKǟ):xFҷOL&׬a=+$Eͱll۾={r%I~gаa"˖`ދ rf~qA֭_OZzIdDSR8OoTʚػog-)90+u6[3?1~}d2q&Cvmܩ,?55kzdYfHLL 33]yHQmIJI1zZKpp0cі['/H)u PyK-18И$YRG8H6 4M#=i)syKUh KN US;/:vwOCQTMc[|EEE^}6#@miִ){aaa Q^^j={һWBBC0) WO#=uޭ+|]ױ[cޟ;hތ/!C?_~咋/knw &Y|Ȋ༑(nl6s9#uq4 Ijx>3y_9S{kC8% 慎iXp՝(}${ |E4[t-8 tXVFOMBQCdff!2?$y}mv^xi&_{5K-O^XǟzLYa#<|Soז8c~"#"HLL"""|W4nԐ7^}sG glܸ7zp3Oq;޽}kp0>$& ؿ?\wv;I;{^"8xi3%7/wgѴidI/eyQ DI&OuzcU /}5洢LuL⺫'1cڝH*2u,1|~v܅i/L> ZjIgxn>Xp@!}+:d0 M}p%y3Wkcƍf4owƤ(,]⦅=HXX_xmU32hۦ]%Ir 0opzufph||fZk$)5X:izfΜ)HRqqԪU+)77W6JiiiZPHHH0,z 'yT_/x"wϿ/M /n$I3IxNqI ϽP$&u~êGC[y쉧YjASK݁·jy=d8tԒwWڢ;yI-ve"CFZ&IRb94MsFFFv]vޭqqqzrr0sLEOfB-tWUyѥHs/r؉@"2 9k+y{cp<9V51OVwkN&1L23W1WUj޼=poZ cԋ_60a\Y0E` xgEpJqi,]WQ|W2ͺǴd1;Y2y杯NЬM kc siv._w,] ` BSA$BSA$BSA$BSA$BSA$BSA$BSA$BSA$BSA$BSA$BSAT//^(2jՖcPmV$YF;V_UdpCss=$$Iv%*T߲FŶ;ZjKFV&99y*]lݺSСnSUKN+IY2$ w&Lƹ!VrrrB=C- ۭ~j{/2:4j 6V*HK#X[$4w,U>$$qӦf>}XT5ګcP?^I&ؿYƪSBbB"M7'--XŜ7Ͽ/X|ZCi SI(99Pw3TZ É6!S60hסcE~3j~Q28Oٳ뷻X0߶ pdrCп__ƏX};=MI16Lo~u8=23Ajc&ttI1>6 6εP4LL 3+fh!'>4U y3tybF( 4"hۦ5#/_~`1ҤI#TU5APwhc_~3XtBnqZcA(9=*; t,-gKߺ[]hH身hHD4>{ N{<>S526;*6n2V _ATxQt]?q&6nko*HSO֧xMN@MM:vwI|\aX]]}`ٍE'%SUCU9!zCs8K*ShT߫tVj{1 r9ѧ7˖06kAi׶+ZQQ,['0zl&Y^-]t "##}ʫ3jg&IM:DS1W+.G6HUWwڴiMvZY~=;w[hޜwy6mB]PL k֬!--3=ӴISbbhܨ{Ͽ"77D̼?"/]h/w*鄇Sʊ\îYt]m4ԑ= Ktuy|@vŢK>yw?5ݻѡ};r65{;wpyO@Nhղ%eee,\}Uk|O|:d0]= DYޙ>_}1/*׬`sqqdeG3蔜L䎔_ۜg]xiۦ5w5ço>э*8z_ȫ/=Ǡ:VӃ{FfLʵoƍΛ2m}l߱v4nܘܼu:͚5MچnaSmۆz*w~F3 ;xWʮ $&$p]wҾ};cUuG+>>{kᣏ?.KGQ\RBDx8/_-WM!I&S7t6qt:1\vމaC[_/#'<45 K(z Eי^ Rrs*|yylݺgɷGټy E MU5-zzOA?vzemoWV7אqU9Xc i,:L-HLLdɿPUἑ'e Ep9O~׀r{ݷg/PQq(Kcn H?^rsaOm5X|ww.[Nz-%4nԈ M+Ts=o:Rxx7x'4/]~X|yynh IDATѝ۶Ӯm͸Z\ nCݵ v Uٱs'}853bo~`!//r Fz(((Mhٲ%Æa( ٓ2`""iӦ5sCu8%sc7ѠAݻw/ MMs}id AQQ8$GCdzM|-.U| Sm} .`$|헀[ZZ'}9FVXT= D@D7h`2tYw9 >}>>.;]C\\qnАV]_;٧n7׾ó6sοȧ*zoLl6wv <4ؘZ4oP4,^ taa%/?k&6&q "ë [p1[lc;С}uud Ӧ~O}ճ'?ɗ_vlN!;;kp˔g݄3OPд^aeIAV$MG:^}PS U@u]g亖S@ն}X, 6;}{Fω1:p =Yz ?dnI>n;r'MgڤMhjAq"" Dz^W{DFe2i&i&)MKUkg;C%omIUԔ[SS))- }5 wxFniS&_9l?^z0zwċ Ą^=~Y3Xq.*Bcʍu֍=z}te ^Itgk aJhdSZYҶ-?i޴]ʕW\dϡ:֯yE Kƌ ct58sؑwDg /. I u4BP k @HC7m{E\Rk8mmiu\϶;X*Bo_ppQ#No3ǍGIՇڵޝs> ZM||_|ocɤ?0ktdR?FkX,0c:ϽϽϿe\6}5, 6m_ׅ=j-~e˖ /5*lظ_{`Hy؎n2ٷBJj6yټ`+kALh?FG6wÌ0czW:6syE^u>kO宻ٳsl|>?{rP__>97dѻH|,k|x NzUl:6l@ŗ_9=x忯1{RQÏS6 (` HMM⧟~aGNjǎ<+7͞%:d]{3ӛmݺzwywdƬuޝ03Ym]rr$Ck6SzHm6bQl6EVVb(Zn+~Fk<R*1$Id>i|-г/<| :Dži`H6 GC`J 6\G~hޒڷ垻bi{駝cN} nՓ~^?Ȗw.mpe wN Hk&~9 Sӹ{|ng2R\\d2H=rR4ಐ4yҀ~op$0ypL!xX~`pou6Z1kuZ{ Νt\l޲;L|7|uǮ?f<$:>nбZRۦ G_{9˯K6gh>\.Z64KqpAj:=4 {PU+@#xh0^O:xHwEMV/4N?l)׆ A?NM cAR(PB0Ժc㐔w׶I[p(\aAC!Ale6 >!,iƳnexo vQ =1l](k!mQ2k{t:1)-k9- 3cQ8ᖋ+kM{9tzhlb?LZaix 95O7"Av߾ᠨX^ }=\cx@6I 7|KH4!_$891AzUp80MXZ @&)lUo]SKhKbAHfOA~7?y5C){nzMVVOyvc7Jϑo]SKKH~y юCR(nRCBעBJ}pXj~ ±kfP(P7<@8v&BG# ! ! :SZ\$/AbNϐ1) ) ) ) ) :gA% 8p8TVVb"BSAtZ4RRRP)Kd=YAS)RHII!== E::DKS?Rɐ!ÈWllڸ?ӣP`OlL uv;6[-i餤PUiV+#BS:IDthZ>^ N.?((`pkX[ƺQbM!'<=&;Cb6IOK#oGua*GAA!*+tJي˙:e 7Ϲyyv;/<~g|9:XG$>.aVX*0YBI\l` t ]*4CFKs buH?酪^%;ev{P_d[xDzZ[mkW7km8`.-qcs:e ӦψL>7_/eytdpVVVb2Q)UlRRB] X|~.*S7|U%U'7\|>>x)>jAafe"oG^3vk.Kݖ¼Ms+0˹λ ϱ}Ga]KLGf<$-I]\ll(0ʱunc Mo>bN*)_U1t] -~Uy˛pjѣGqݵHIMw%?D[f&eeewJNyY9WuY,h)yy;Um>oÏC^e( Tʏ!sw_;4%I fQqI ԥBӱbs8YV%bG_}_n[_;8PPc<̈Ͽ:H'ҿ?~J´:$7nW[Qq1C(fs*cFsKUo%ͩm^r\x>rƎhߵjʋv*$CdN'6zH. 8vϝ;#Kis`}7̝s3Æ 84/x7OlZ>^IrZR5?7P\\' /T>sJq:j6oΝu3g㧟bǐ$C"*kYAe8#VYI6$:)(7'V% ͗;ȅ[&aYj css +룩 IN]ٚ.*_(4ryEfG'==Ihx :f<?._Au}d&=i_oqMp͔)߰>f`|fT*m\uͶ9k67u\#=|"01Deeg NHB'դGdGˋۊ+ҋ;44O87裣ٴy3waȐу]`tɠRذaEk 6nHNN #=SN9wSѰ.hC˅fH%a`6䒋h4\8~] ӳO?MBB4 }S9k( j ffm<<.p^:vo:>Ɵ^Bnh&ZMΘsXtt4{˖HFF&MwC$9,L&#,xE|U+s9pםw'|ǤqWcRPPWp1 k!I/O>95rӍ~ǝ_կWqmsq( 4 O= /\бMhHjzIjj*oҘAiw'd ӑ,m:-eӦӇ|~g>#3#{: Dž.^wkqӍTTQ#G6t(۷hZ|]649q<Çi9gELL ~=wOu߿?˗T5r慝1hC)w-7֭_ϸqcnG'޽[<zteċem`Pr II9C>.`KCw+{ERq^oIyu|w/L8pTUUvAttqpBo[$Ij2qogc0$2t}PtLMM7 *JKRYٶ yyZtmu%v{ۧ1 n'Mo)ͤv{Ջy!,k 6۶ۺu,[#SNmr߻*L)O=V+O>'W8p|x_O=M]kCE$~]~?{e˸IOK װr*nq6/]ҥpޅ(AE륰ҲC^i4ܞֻ-LF# Ud4ly;.O޻oPSb4&SVV{ŗ_qM7r"..e~ |1^NbA1KBW]MIi۷6?u-qcs1C_zI!ּ<ȣW?cͺ,W=7NY׍n'N#[gJEGT^iSCNM̶džxM M'e@_k}r:M[̍xk5!rz8[C$J(p"^h7Bzuxhfe~֭_Omm-KqI [ ѣct58sؑrV)>SMTqn~$tPku:F8Z&%_krpp߼&]Ȫի~uDbZ[-?oRRRxᇚ͎lڴ$77I]>D^O^=ٿ@ګbƝycrDž}} DQQQ?^_jB]R R\شPj5~\31+ Zm`ǫ =_1p@.r!w֭cȑlEs߫ XDEE1d`=sBbb"wnx;xA.gz^6l(^p%߻ٌB00JXUj233QW8;T* I "hXf^OLLL/Y KΘQ_@^n ?&e[n3λav2c MʺwTWWwڬٶ~04۴Qpr-͒N''&H„1z臎8Y&,?tQ:].;\h>&~? N9e8{g{Ys 0?3ϲu6f0aC6ۑǵӯgٲK.f/ SR䞿j|Ŀp͔[=j$99cxwزw֬|ʅ.`g6ƞ={smTUUqݻ7 ^//&ǵ~cذ0k&css`ÄvVYɐ1>TUU@ii+VfuNeU]v7Kffw/`r00=].Z:ᭉzHm6bQl6EVVb(Zn+~Fk<R*]d IDAT1$Idlᢥŭm ?aP\5gju+ 6w2͢bm8o&^3Vq]w˫ḣj4$v;?111ח-[~x]db{os˭8NpkX,jrrDzrryqu65sa^5JVs9 z$|>Bpt:~oBBvL&???_L&4` ࡇj6+-zn{ĎDT" kMeG^>JKn=n }ٳ'MװX,S^{V;&&MIc>L$75C(|+ma'tBlgҡVMW/&YĎ2ބ}u Ÿje˖`!XXq8^!1C6aʕb54{-]UkXr%{CFzCΘQX+n] mqOQqFY vc Yh|k:dɉ nRXTLRb"))thvxܸ]XV "%1N9ܜ.4 RL- X'/XYuu6̩fJ:`NKm8ry_'stt{99d m.X$ Gt6v܅&Z"(].J(-k[(u2}Ƀ:¦$NAb 's,0CJ%$ՔujCq`zx^|>^A}}= RRD$n7ߏ㡮RT*TTVEp ŸRdȐaʫ uu66m܈WuY}ѡf%ܺ{Н؋^&򓳖-. GOB@Qf $ ׬qfu$q:f TVYC ٜʸMFF&"V^͏WPZZ&;chu:  DEhxn]XZq\3maPvfN53xP6nX/bˋڥByqB-Lğ=:Oqg@řOs$IhZ^ Bj[2y$z%Ipl4RQY%ZЂn=1Yj5H~^,Fz맳bj^rٕG-3CkrN.O`,K`H$33kBnJ PZVJv߾␟E^ĈO[̓vuÂ38^lj59O:鱝CS(p biz..7VQ6Rq5z H׋FFĥ 3K?‰`p,_z }G'W&IY(/+gMaƜ>zUHOOcР߳*kpy<^yPDcjTTFz=6l@ףT*@-LA+/g)<6vɫò|~Gy T.Z,?,"f4vQ&|bN8nEv=.F~NEk =+yv ۙOS$f0z=={d2R@pjZj5* Nj]6CV $'BS76S0mL>i\yuHOKcmfcuv;[m#--$CZ8DffMV:jp7؟oSwAˉg GMS.JNݻ7 ..BALL * Ʉh$99109ARhh4n`0)M0﾿swָdyy9y/)))iZzk׮%qڵ޽6L <ո~|hUڹ'PU]5;NGU f0bz1 j* Zt.ZOee%zF"4AٳXRvʫ,/o'} 70S^բn)WgS^VNffMRRkEa[X\[uաgz,UtM")WWWf#)) Ia0h4jWFHMM 8<  ͩo-j|ܜ1ͩf:$%v+*.&)) m s JзoPPgLfKx~hJjʘg96+[lw<^.wpu@ Eh$IvnJ||<jJ%˅^>!**=z|5<$u t%99X:,٠^x'~{ɫ²\9N J2$b% ͗;ȅ[&VYI6$vȤ'; g8tFu$Z^ nIbѩ0[%B3( Nk9KJJ$ ֬嘘`}xDGGѣGO hZ|>uuuܹ ڷo_l۶ BG=j$K>X^x{|#^Z!ͬX.4$vfZSN9$6/R^_ UV+ ++?vŰl߾]^Vm"ӌeذ[ؼy NVKBB<Ûعs';wƆ :?=H- [R8sxe|xICdd> {}8QQmݻ7o:B?a]$ƴiSzUZ UnF._p:DGGSTTĬ7!Io?^/$Vdū VX**j233x lT*YfM/W]RoV լqyYhMyvjLn:c[oʫH\=*|F7בf1+ILL䆙3Bx5&%} ffx'3d {Ɲy#Kf $fouuuoN3ynnwZC.u\ܹ~Rի'.D***x֮5k~g@k>5S8N}UUUv\#;)DKt28c6׋d"::8#PLLL5VXҸ~$''p@識1AN"&&_-tڷo_bd2`2q:-^J\.IIЦ555ŸCłh@A*Z濲~tYQ hpZhp{2\|޹rM|7(MVHLLDC"-ظOX۱;nMir̹Z IGnLS\czɄnj <$lpRVL~_Nk7ٓO>١݉?iʁ([޹G t:11zFW*ToC񫠠^c1&eej6{=W}=zh+^O}}۷[;ep@qI EF6v;[Oʽͧ}OKRRSL||ž_RRBII-Y&e%Mllhັ;vȋUy6?,[߯. WLF^բB :ʆY#&&l]^uT]-ٓkBkDhA @'y^oެj$ɮ@cA+Wfwg}yͷn *NعkW[11dggSRRm/GB$)s<J ]ɗвS\Rʋ?ǟ|kjxpݴ\<"y쟇ۚ2]nKyy9EEŭիT*2IIM!+r(?ߏjnۖ0|Lχx*A"Ը+Wqki,>[ְbJ6+0de"7'1XrW^=ݺYVl ʊaF|pFAcHLĐd-[~]Q顩P(p8$SWWb6~Ǎ˃[$a6)++k֊ٜJnNOHff) ;S[,zO_ YmvKaQ1IҡiKqwaZ)(*j,ٺ:T3ee[sZuXnHִA$Iى%55N RQ)/jFd# B{ulا  WxfcG%x$) tAJ  DH  DH  DH  DH  Dӌ 1C4A!B"4A!B"4A!B"4A!B"4A!BGwlJP6-  q1$ 8N*Vluv.Īc64/2k)W VC9c2**TɘDyE%ťeݞFg}dlFÐ$ A0ilA*tsj?L)*Tx8?>׫* T*ү1BMw;CWq1 -L%ťPp`H7I1&SUUMm] G1}tGX<uT0hZ1$ӢjԻXkjvƍEΨd1TTRTR5?5mfpL^u\0ܿWqvڛ[vK6B-̸8,J$c` )pUJIRSWkWTTsNL, j!bA8icHLZ]Cg'TQ!1t3 ;l)dג;j+̢>!>,UՓ#yVzbm`ݷ8d3El\CrhgLW{Â38 VG2JY0BN}tT;1cb1ttE>zF`Wb'?E6HJL g-l}0SNgjT*GTUWo#y;/k;C8PXā"ZC^ϵW__ǟf5Åf憹wuxp+Td5:({RX^N$c9%ts yvS&|`֐}B:@ tS︇;Wew8xa*#SL,\T~::8'z9TTTaN5YBA\L` ٳ$ 5&^/|Ő泮Ah]!ts [vF9lI9DyubU3m]0mMcFɫ# gSmRiz5l6&S2q11`2%c}TV^o:&B3Z$'@6  ^O#Z ӥc,]V!Gwv?qIîdVW(dd qp-xb2ʫ#VgO IDATL\L "L7[*;o#yn\<1Jt"}"y(^ND3sL[z:eKZru 2U-qƵ, v)> nZyUP(HK3T)OWEL$K(8}[*(*-]KR89.LuJ^//C+1&A7͜%/.CbHLm6D KTŜBByUBrG"2.p}(d= `_PDޮ=[٨(-k xQ|oyqQ< -N|^U:vKÝ.VZr9k\.K>RyuJV _~Je%f>} qG6a!91IAGbagBrIVGvIAnבYz8Z^ $Q[Wש0[ӥC3S_Q1(}~^_) `7#[^f&͘6cFVyjA8)TʋHg~Y*((*{ Ԑb4O?%~!/>l+eҡy Fͦ͛ٽ{C gw6-A' BVa B6l(2@Fz:r }=Kf3ƍᄃmŇ^cUHQ73gC -;'X dLdƌ< K k`\I,_sǟ_xEIB|ya߻6&%%7K.ᒋ'a#>.'z>`ԩ5L jYgu6|`N׋al_o ?dgp[z 鲡_VK@0@!0=H`BTr*:g[cg>#3#{: Dž.^wkqӍTTQ#G6t(۷n?Etɉ@JIb|lJ U`]ϋjlXrϋ?*wQ?% ɦRHE)[NAivONE<*z*"*bCDBz$!M2c%Iz <3SFRZՁF#qa} |@a.n*7zw6`n>FLOͽ sx8wM>Imv ^zY`q&S ը#됡y?aq) V:].owTe;vPRRU&'7}{0z(Y&jk;vbZ㏱jg :wV7e^RٸN Ʀ pI:\h7,AO@,G Bv{P<2nHe& ynpF^x߬ҷ/~Ib^{vkܼ>ϻwCNn./*3OI9q998{?;͞{q ]z };-ZD=6,@ 'Lr&PO((ìѡxx085]=k՟C}.F^xS:E웦RV^ά:_FGj\y1uQZ-d6e>{:AT07GpP#/wZb0삓Ngͷ*XJV|R]LJ!ns{nݺ1p&Oqqq͚mZ3lk7$w;eo5w\n.T  =.dN_+TM$xhzZ=xgͦgdw߸J\uyj~wW|D]q,-\_{Ln:4 {i 5~ߙӘ1z67n"Ӊ1Vhé-l$Ӹ٪f` ynsg|`B -ut.S⬠YIrpUr"\QVd|Gp` !7/[qԶlbҿoI7_eG @g ER+xzOnhԇڽ{V0rv++)Dx={8=2:E|\IdN(2B$LhG)o'g\KN'{c),$;7AմZ-1HMhtnS>+rym?x. dM70y%m> l Ĺ$Dn,uĝM~O%RJU]Ldr:Jth4j5x?E!@rvcv;]q* !H$㦟EB">S^Od9p('(+/Uݞ^#0 Sξ*{lQlC~Ϻ;oOW/lgRSPX>Kzug$- o?X ^~WL:Y%kvM-c4uGn!]#QӂX"ITJ :Փd(˃NQV5Yso |jU&w3,c /?}> ÆHkP7hOx ͂z@pPJxyȨ_ 0C&ʼn KQ1VZىK1[NJgLxI$l )BM&z%Br.<=+*ڬhӵDGG1hй;fU"cG5\y223-I1kt>YOY~ܒ>\hc6︻̓Ϣ]CZ70zd0ԩRO)wR [PohjQVRxdE` BmDGEr0zª>,lV zr[يz_qMuϽLIQWpoͼ"##djaBk,++^pPXPHdT힕$ `tYy} HZ $db2W/h4 QΛ ev@$hN @hh(QQۿفYS&nҸcqM̼ffM))y̜>c:8'snUWHQQlK711 7WazdEE5O=ڵSnykԣ )f\.]?tV zՓd@ji GϞqL9qIÇۯ/{J}-{7{\>|́)t-yڪi۱X,fk1=X-KOoi 2trVl=уPQ8[7)**BSTTDFFXV4 \=Gt3T {gz[mǸOkl,ja:X-ƨt9|WRWXJ!r w~C$3bBbupΝ\QrrrX,gMՁۮk4& 6ȲX(sAvOIϞ= D.] B(~#e܍c[gJ6PXXHyUwvXfh䞻b*AhW~P99V!44?A]UGddcFVZ0&q41+`횯o=3ls:gryPRRB^~>)ռދ?RhvIpKpiV+^Mee$NG`` %%%aZ}_㑑vpJ'W5PuMO՟mC3&&]d{paaM fhZ~gu PS6YKZz&)FSH$&ezgBj-p8$mc; ge5^Pb/iuM)nizd#6ix<dY&88;v 2Ȳ\Z ~0zɋ놦$!IM75 Οms撼kW2A2o|/$$:w&??̬,؊1M樑#/ŧlKRw6 ޽{O`@vc |=w#8x]ct :-;w$++w!Cە.]b9~F dl~#UROn>uh$<TUMgM\.Ws品,m:4oqӦ]yqKOK#<<wB$6>}h4ܙ}8aaa]qK^r1qZo|A8 $H"??ѱfu=vKjqu)KM=NLLUb6䣕MソLakhdKdէ̜1I' I:9so~BrnoֿvϘ8a<5_C&#&5C٪%'h4Lz%%%ؽ323;2{LNxOnzFAv-tܙ:p:~CףS\\>5-݆-=o>vo>|=j ;vdڴ1&>Y)K^z׮%6&=O+.W_gŇ2{Lc.b|3$$p!BSz̓v>^OpVJg%.N}6t( _Ȇ J%މ-aa]=~]w#?hdӦ;:)iB ohj$ΝڧyGrPn?7@/3 ʀ"IMiVIPx ^K : R=SOk R^QEQjD@**~Iff={ƵyhGv 8mE~dn߱>ZEpp09띛0z( ;vj,W IDATct@5V+o.))o1^tT2C3, =q!.**(H<`YRBj]v3dHc$E0tחjӘS=_ڒ؆F63‰mgƌIl$&u骶̻>>ϻwCNn./*3OI9q998{?;͞{}7  ]z };-Zlq!BS]Dz W/w]vOdSTThb :=H;Kntr H<\doA翞 G.458Z2Okd6]Z̓-ܩGb 5ٌޖ$nҚ`GeUfXvkYeŇ+YJu1))uʺu8~<6kskLx_i"i$L-llz!7? =z T1FM7),,IƻE[|O9if| 6m&>>)S&3rE|b>FpPP&Жج6bZ:c11Xf=://-[qV=k[a@~<`1<8Kki*Tj}(I.,Dj18L&EEEywe=eTmnz8z<@] ++.`ѓOɧkֺKm|A824\S l6g^uU>Z~mZګiUw:qg!B@t2kP߾};,U{G epw~Js4lt:I=Jx짓'>cR[t|^|9f|kNb6yX3MhVe,UmWʩjBee%1w>_g9[[@}OA6 -nqOnnN6ޒH4Ug0j2a ߀IEE%b6Jՙm#22qcǐ8j111PPPHvv6I۶-ly C$YDFDrwPWWuQmZպtka(XP jej5Zuِ'NPVVk׮].RRRuܱcx뭷ɡnݺQV^]4|8̺VuiuuS5jdBϏBMج6-Qr` d !66FfVV5f;1Ge6VFϞqm̖xeX,Օg >c /?}> ÆHkP7hOx ͂z@pPJxyȨ_ 0]CJ 8q"$O?1|ƍ<kƷ~?lf޽<dgg^W}* ©3VF.>>sTW5*dgX-$'覆W㡼͊6]KttKXmV-2&q4O,|/ZÕLp!#3L~ܒDPPfL瓕?-IÅ6fٸ<8,54k VVVr ֮]ĉkM43g{=IOOgt'*Çgݺul޼ Ʉ_Uג =.j7;wT5*22(RPZOX񐙙j#>>AOn+[qSo+3n))z9^M~ؼ@ddZ>Lhcmeet2vcDFEYI` Akꖦj3bĈZuմZ-:Æ Ce~ZYӸqظq#'N$44vR44.j7 PطYKt9nft3oݬ5bͷw-Ӡ-0-v{ fKV4% Tg^#(^6 f5,Y?Oyy9T3|p,XfeffMc5ѳgnU`Vs:>|ZԳc6YأC j|?>i jM><QFpwrqYYMbfs9j>Ku)ے]7MCw^ݻ9zG9|Ɛveйܹl5 IklWt8DGsƍqcfn>uЬn4j ,'DղtR,X#G3gl ˇ+W2mTuU-78iSo`׮ݼ%FBBɻv!IF>h4vLf}!I]x!s[nٴZǩ1z(/t)Nt< XBv&'E^H֭LM7Hqڵkp :NF#;v&;yg߳˕W_CEE}.l7&?e:$I"2202otlY]]ƒz\]|RSqզf>hsݔ)L|-R:,~q 3f0i$IB3g\_ȕW\w:߽n>]'g=w5Ёkh춫{l̔)S+t9rG}GR\\ٳj||9q=Հ7MA_0337^us=k&N I ` ~,xoL!Hœ&4W_u7L?y;mT4 ɀ+oy y嗈yOiNW_fС_#x;vI=r h4~YL ѣgeh׏[oEQxKuՇ]_o}Χ?[:t odLb"wbcbXn=;v~c1[szFV&^9t:q=zAzz:CﳟpN?m06lmyٵk7}Wkرc'Ӧ7ɪOYK|v-11Gx$ٳfrs)(,$%#G՟1$!6]-v Mjrr26g$Ix</^Lii)|LOOGe<O=F{[sjf06cԚ~-{㧟~&$$kK& ͊J>Z@<hؽ{/:&OnfCcİڵ[]]KdDӦZ{kaС[rwdcqi$ERV!  oN+/W_{Ɬ~׃4h/4?]'aС,z)&߷o_ϿfqsoqT֭_ϤIu,^,0a8Ə x{xZ-K^\̰C)++# N 6(uowd !!a0+?W't<:{zhNG̶mp:Mmۆjft:{=t:]J6RKU5'eddP`)`ĉL? BBBԇ#^ӦbXH<=p+:cjݺusWEaŇ+eiii1t _#1q4o/{qc6gj~nm5Zj:]6Now``` ZN 58dDK8]. m3YMZq`+lLGKA"  CZխ2o}<ȄI0a%\|e݋aC$!DXwXXd;$I⑇h4if_khS+>3/Zu|d,Xbҥ=zq5_UV_kK} ${j o=YFj'L=jÀj2b!""Y[F3kI޵K.-Ν:r}MϽ?K~sx8xI.:yFNCpٳG}W.R{4qx~};$艅kl=Οx7[3SXTD^wtKTVT.CQrH޵ܼ3M?$33=Գg''9}JJJXc\7e2f'a/Ԏ5I'\ێ;Zǘ]vsf :t?XA\~US#oW^+.Ϗ[j}ΜF['ssc. q\^6g}K vaGsx}ϸc}wgS^WηN}o-{pV}wYƚגkSoB6m+>~9|_VwڊmLؽgiii͚9 ` DqksgjLb"I[OUnۙw}K̟w7\WW^Oo0o/{3v{??V;uj1ML &PRRŒ3뮻ׯ:u"==o~ .Κ5_eN$I̟?~1c FEnn.۶mcҥ(`hK~~##=`=@\\#7>H_3]Ϣ⬬fjhVkNϖ۸D*("IDATy uU͞5-I[[p0?_xzoEzղh"iRAAdۥ={J???Ȳ Ի\.?_)bTdyoy9<|Z_7Ǵi|N9*V]tZ9^z2a8ϴsj6zHn瑓[g7Se2_v#ֻ^4ϏAS _ٳ8xcY wo߯ONAA1cI1y{݇MW֔Ωt>&UŲ,x;ڢk ϵ`]. ϱg LA8Uuʲ;ÏϬùW/ML!dDZZCN xDEݹ3;23I:zwp58zϫ_߾vӒja01p>gpPj-I[dCٯo_,~+VU]-m]CSҔeEqzu3fS4kSro21} 4+W--SG:Ơ?!CMKܼ|**BvvNQ5VKLt43ǎ5}j59yK|k}oy3|*mJbL LD@؋taHDUUϣ 2;vYZڽ v<iiiOEE͛I)-%00лaGǏQ1Odg  wvs!!)GAծ-SXsJK"6քV+n7AAA5zaƘLy<+,rs&*5vo4 NQl*. L,?]ugF}*u^g@CIfgf'7AhYAA3) $BSAI  4MAAh& L"4ADh B3Af) $BSAI  4MAekK I1p2AF/}y kArLڻrȴ$/r۱.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD 1"6M{1i@҃Di4M_&| DDD7}\{EFDt]WWUmޕ{Ef Wkڃ%I,{.NNNٺT4D4.|-Mҍ<>>8==}Q=>>q/IDDKIDDDDDDDDDD4Mx1DCA _vq𡚦MԶmOMmZk0> ܵi&N&$w41M>gmjU{G>w=|>l'\۶1ϧoZj4mT-o%hfnѶsbuӤYKMwW4G)%yF)ewS fj^߯Ţ/_W׾vLsF\\ G1uk5E].omM*Y7Eux 𥳐0b~|C۶7>RgIsxx}ZkVjn'͈p7Missb>fuooFDرOmaC>RJDZ4MS/Ӥqͭ<>>GGGF\\.쬞W^ծj۶u])7O뺱i: ծٮ<>>[y]fSm-]׍ORW_zU#"nmvY_E۵߿:{뺺ZjקLhfC)eL+}_y].$aޮhb=*8F0͆a㨛|zð0 2X,t2}N=Wt\W/nz.Rvmv?^ʟ0 ۈRʸ^j*.̩n'òlGG14M~Sk] '0l?c6]Rzb(?f3LZnϛ'OGX,ֳni&"jZ,"mqmZkSJikjo|]D].mNOO|m6)f~^Ju8]]3"hn\t]Y.5㝱TXFsqNJ۶cnLnɓŋ`F|`4'W駟殉sX"l6]8mMDZ8"HR /tmeǴm۫hPmn0pc}wF3uGGGŋobڶm"nm){,w>}N5sxouql6-8fmD >{,h".w>>qxfYu]l|ގ،ؔRbq̈#"ތMۧnl0 b(w>e'믇iWm0 znfi|r@Vq{b(}afGΉ_FD,v7gz<cWU?zo#XN7ZwNժ9??o?~DDl6&"b}q떽l6ZrŸhNn8>}ڼ|YVMDz~#SL}.>\.~ü%Cuy~~\\\4?CDD|" a\zrr{{{w3Esq~~DD\\\4SD!\_=5"`W,'͈3"bd(<)MxDsr5qFDLFaCGϛk7pݕXNn~/+^w~m1;+phN>M4wM;7*IENDB`RaySession-0.12.2/resources/screenshots/Screenshot_20190724_085017.png000066400000000000000000001304071417052567600247260ustar00rootroot00000000000000PNG  IHDRxQ pHYs+ IDATx^w|םey#$vE&$! ZlKm)@~ZPJ)@#28gyKqw?d)IeNyq`}>5$18$}  C` AA) I) I) I voEEER Bd/Iv FhͳpLX. =)// B~В >$ Gә\AzIq thEBR-].W H0-//tpЊ'Q`ñS(++ W Bm۶ 0'exhhVTTH˗/!t C6MHMM m۶aZ|ԨQkhƴ0/_.\.Drݒ>}>.7;;;a Ԕ0f`Xm6UUUiC;3ԁjqmHŴ0Át:e'~):av dHx555ifYX,ZNN΁jq70sssVp~_ R0 c(JrA`0$ 7Sn45׫B(PfgCl6l6 %EQ ݱl= ''כ0!Sy<`0hMOOW\.ZTT T _%#,0|>b~_l((bTUMjɎ' \dY1>O m6U׫fv] ShZ} [~ `2`0(fIU՘jFBQ Гp0ى,Zx,˚(jU( g[ɆUR-L(I4`e٠(l2$EQd(i Lb ' \$IJZ@8R8(%I҂&I&˲%I  $Apřl% f`Ql6@(E5Mb0z\ ɡT%<:<+ UQh4*@0F?M&3zB}jaJd5 )`b0̚$I2(beYVUU6 ir8F#ǂ 烾e %ITUUZi>M|uf>N&<{ >0 CŽ ł 0$Yd`aVLG%iaBޱ_+|`0HdT ->o~W p\hf&EQL>OzᐝN\RR"\.tJХC CGeeec"_+e`6 1QUլIe`0Ff~$Ozw?cЌ>r$-E!r^S4ha 'MU+~+r0%+Mk3NSz{*"l6) ʊ` IA?  GFY FQ6͑{'+tjVfYYN;VeEf eYeEQ #3T5n֖\.h BB]$j$JHE6phREE z͞8I4WK$M$EQdYnYVF,ƞj`Z6,uvGAE1 id0l֏ޫ>ZJ׽dUUܰ@U>Ϟ ^_A4UUUUfdX$BIB.vxFQKKbR:uD1 )bNX//>*gdA-tᆞ~H*:;;%-n.Œ>ݽG98n7vn#]t@(8G,)/><4 TpgdPRZBIiA`6tdp' lƍ/ &.d_A;UuN;fUT}{2d4QcB[[QRZ)p8pGyb fX J`QT`Q߷֘%θ :MR_W ׏((*j(*^}@ HmM-qTݎix=}UF쩩uq<|^[YmZmVBK,KadZ  $8-U2G#f̌BӞ,˽HKCUH$IB뺺W!!AUU6m؈$XmVF*Guh42ښZ RSS C~04ME_|LvԡIJJq}Mz֕KdBQ)>@IMp1OzzzLpq!-556D#2%%=W$1TƖbK }`eZ[OPx=Z۰l@::<45" ˈb*n$/??pf}><FMmmm׎JJJx=ۼ uhokhD---8Fe, @zIusNBn^cƎe{ee 7'/^P#ٱmnN=Şjf jcPs))-rK%V̬Lvlۆ(X,fa4>p@Xrsܲ`GZ=mtvz0~Z[gn=핕AGd玝x=F#rŀnނhd \pP8xpQRZ®hinT#>>fIGϵ }bg-Zƾq&>"[ٞVVpjO>)Ӧ1~7w\㶶6̖wZZ[1L@ ݻwx;n,ƏǑbjM|iwv$nGUU^ozYYj8H0bBBaFPX4`32|t9 e# |>>wHIu`ѵ{ڮN:;C0GxF[[Zz=] l6 cK~ pw`MsS3ikm#++*}$zni[$E~7~5>|stݳ>we\HL I:0!te1$ZR䜦,SV^{:$OZZHREϚDl<dfeQ_Wwd(P_2()-a呿eY-⮭fذa= %PWW\d20ߏt#ܺPuw=ASOCܱ}G.M&6I)e)v"x>狯 * yy(`+3+P_t0L;c ]njkk t-+תBWdfM@#a J>;49ɥsq}O8$]v&́p$B]ˣFIzD -* uچ*呞{ XV"4662~x0 E1i475:܌iTnݚ4Mtt:Φtlڄ f9&j <vܩ}0L?/嚝=:N<#hnnކЍ0RF#$p`pCwx(**|lD>\WOx:8^4jkk;n,M>|QG1E x؉ < v}GS_WG{>ɓ$ OMu5~̬LJJK4P @Qn S $ '"Iݻ{Ϡt:x#΢fCaQ!E#Fi^}{0= фt;8t  &OLKs 5ձ b"-UUiin鵥NM٤r?n;LAa))gUUeVf\2rhL&#>U >'oqEԯ8NX:|j$I2j2fUUm!E4Yk^aw,V+'mEa玝qWPOt;BeFlvH ) -#GnPP EN* I㸇&Nj]Ax_ BDh BDh BDh BDh BDh BDh B^ BRDKSA$BSA$BSA޳ѿAYeeTQQw5EKSAkh\.ANjeee\^{X{ MAAB Ͳ2^o+ CMvvv-@'C}Q5ksfǬ]V_,K4lwrG&fY̛;W_,DΙ͜9sInҥdx.]Eٛٳg1{,}qHbΙ99ze60>fvvс(RJJ,[-'|Nr.';`@_}uz_WQTy\S[Nj/5ɣI&N`} ͓Ʌ^l~|H3ͷފ{L&.\ȘL&3n|[ee%`P_R\\̬3Ae[Xa;vЏzL̘1SN륮7| MQxX20{oǝ\fϚEAaf77mfQ,//EUht6꫄ܐ d/Jԝ,?t{oj̙=ttxh^%=Vw! RTTęa QF1g,8NRSSP]vOx.>+,, /`ㆍXCVVրSg̠Ji$IG:H`{Kz$}9m~ [n,3pyʹOZ`„ ̞5 J d lذ\-: 44To5Wngae?_*[̙b1[h8o㉬PrTnU"eYf 3fL'=-v> ,\1QļyXr%+]Ȼ-c钳QT{9ah:C򣕜,dz]Y6 .2˖Ϯ](=/~||)jjj)**<|>F,F6P#طov9KĎ;P%RW\\ /駝ysSNE\<EEE?~ <ì6]x˗Ȏ;IOO/ϦM?~<?$%%/٣8%%,v[_޽{dP6u*~|~?O?;g,ryqa8.ZZZؿ?r}Tqq1\eg?4?u>Fzzu|,Yr6=/N'6  صk76lh4gsMMM<ēȲ%K8yHKs _̚5˗Gehln=HӦ˯9sX|Y<+>|86nb{W7ZZsݑ{NzWNzQAٲe+mm6oҒ#\Uv(..Q}him``p8=; ^eر\{5,??XV6۷Ԅi߰\RSSimm%??р9jvݘ&1ʹŇfѴ}4M֯,2N-[*n:2}mZ͆iqi=lM7zQիאAVV&zTU={0f̘"j:;;>jo~;72^O5MUikmeʔSp8xHOEKk cnj!/?`0Hc>JKK`x}`0USZbǟ ݳȼ4M6v4vFeV@R9aii}>Q{\yܵ+855LHhb6sOG6(),' R2z4`KKKKdh֒Ι/}^|TJF0nܸȸ@ʎ;d橧p>P෶^d̙̚5۶j,#55C=ZPIUV\JJJL@$l>v=G B-TBn[[[.+V`̙\zxgz|i~e]J}}=˗fٲ8ɜt)~+VRWWPt=B蹗@v(A6D%2b+G@w9ݞ{N|@ Ώր`%ѓ?w~O^^|KR[[KSSov/fd͚sn IDATiGLYzZZQ㡩cSWZZ!@l6cZ# USyɧ?UGV1y$egZdGfZ,p/"i&6oĉ _قbBZZzޏ8y<8aB5y*jdsr/Jږ-[pw9e){Eyy,`2aƌڇi8N cnj@TK$ژ1c]1ɓ8tRYI&1|p$Ih4@NNNN& xc4/޽{q8L8IIOOgڴiTn=rph*fLԩSbX3f g.ZĚkbaO2ݎ$ɜ~i466BKK ff$IBrss1͘f_k#]縠шi:tI0b֭444pia41͜vI1WۿI^[TTȢ3bu嵮Yb%:4`}qArrr`4 ٹk'''KbOAQ&Χ套_a YtB<lr6'}k3kLΙ,K4ܹ3fܝ;w.nOoiikp!\-$I? 7̚y*TU˯BiO?LE{B7?Mu;"^{u-:뮽&Zq^Lcc#o3fLgҥz*W5s&ӧO`4`ʕux1'+׏|}H]C Rr:JJJ$)fCGG)%%̀UeiM2T׼_$͚ӗXhջ[e"W ]Sv;]{~ s/Fy!Ъj(Ix߯UUUrrrr "3^;)Z7@~ 0xdƌ|zf̘Nm]4aС'BrhK9N>/o~oG  L#?'ēOꋄArx饗łp;A$BSA$BSA$BSA$BSA$BSAt~͛ANt#W蛓?4E g<|vhԋ@AHN2'qLDw GX$HOLa`"0 gaO>DC MO) EO}Ag c$a0$)W?+ a9M4 EQI zhJd<>% ]9[c,=c8r4  Kvf0 nKkC`AAH$gwipB3A>_oUAi1 h' g t,}}*N6ǂ  3ͱvfPBsW=%}(pRH33q&8ሃKӺ[1࡙h- >sJ?b#+t<4~go_/HԔ[44W gVqOB~@ ,[L Eff2bB7 .5HߏWQb#I P0E} l޲eu,{} ڄf 9f+~| Y4JKO]~#"=@0%u6@BcGyk n8Qpe9KS?Rq" baʔShhhV_-J")HteXР(4P^pyCQFc` Ibރ<4e֤\w5<׿ElŔE'Lw}}!n\a3 zϭlӉd21y$$$jCq.|,VdlHD$ҔT -6j}^Xql6ҌqsYmt>o cɷ,5-\d"]{M/p~k:qwoʅ+++ /^I%_ׯg]^_C} qaeFvc)5U`BjVi4@mICD]Z^dz} -4;ٿWzώAh7qbXĵL{VvNiٺN,.FehjjB!1b233Q Nf&Oj8NCL&#G$55z=zR\<MU%2mff&fZ[[A4=z;vdȑȒCb!''<$YPR4$YÁžP#aÆDm]---F&OƸ}tSNL>_U`ԓ6Yt-m2oL<MUٱc,\Y4S&Of5ٻ3-`05k)--NNcc,3w.v@0h)**di@(L{ާu&h`=Y4&ȑ#YL֭m۷S^^ƌQI%O}FMM ~13EQ1dJǔiӦMc&0e)_gcS./+G͡apuGD" SD>G]UQ6;eQl>uUNdhKC[}s*t6/{,~;a4/21Reet:%%HNS6͆YUUSJJ),vMe?PJb;0=AX}:рͮV~?qQ)$kX|'j0==]JNNZUU9-''G+//***S_$4Rǂ  Eg|p&bT#M_$ iD.$]6A ]iw5)BRADMUmPZUFHĴ)0yL*Ȱa466uvV~ 6kނ ש*HR|X€f*m cRYB 9gbn׏& fC3F2sRY ݮ3?<wmՂ 0(54$S; 0~|ːiq^y٥joc] I$"Sx i7x]eV֭5x~-[jsӍ7 !DRp٥qΚ;~ysg͎O1MW.1=ZN̤#0;}~nUkD)d՚5qH٤2N7_8,ߜٳQq}T}#̞7PgZy|O|; twƎ-eԨqk/q_WCquw {ǞҠ& ÂO;2>0st~[cs՚5s߃gpj:vz| ʘ>ŒiSC#%Kf0Ȇ_R<-#tsg[nǚf햛Cݵ j^˜~pO_{`qӁe}.BJF+Ofs^W~ًٿ?p=TRp9^T~a͝ _ߧ͝&O*#eY,&nϹ߲fmss[~̝wK23 <'Ï2+xM0} ̊__sfzǑ>}jCipGd1K,h2՟p>{qWq71o͝ |ks\M[Z쒋c[~ŗ={oEe/ip7˾Ο+-m,>~q;}rV^o^v:~u:R7~o[şW~:V|e}q%3gPS[ˡ 7Nů~γ v9{i.ȲMµW_w\r-f3|q66mĐwH 6-45M poC/$11fXf-?c͞)7{V(xkMחa{(JO=s;2ޠ` SO#QX@]]='cάH]c߫~RX2rrT^ߞ;~OG{~\)8=.+z Ho. 矆bMܥKxw."<2~uu Two-tՇ޾}h7lMix::ظqvٶ};yi̙u*5|b%kn>pedgu&>T*}Ə˰vʫlڴ?A QAң78ݳ]J7661P_9_=uĚUk?gxۺ^=@ݚ  2<O?ۿ.ٰ-̛3;n}gx۴e+l%??p=wK~|ш .eRhll-ԢvvvwŲr^dz=otd`0a9xx"<|IHKK*׺ei8xv`[q׽:}Ϟ>c"ywC1ޞ#90r"8p'z?>{dIM ]&ڟ-7N~|9,:caò~RRRHKs'O1nXu lܴ94pb܌=%{J iZ]d7~/|eg ] ՗M~p#?ɭ<Ј1iF._y4H}KK Q H=RK/G^MƱ;9ݳQo{ÕEX~Cp8GM\7dUkrpjڸ sg{xUkײjZ~}߃|Ӎ]ӧO~ڵ1}Z\PN7Lf3sرsWGeddk|~?f3.'33Ioo~kk))MZZP[_l-#8\VW@\ob6l\}7XrΘҒдCx9+WxD]ex띸fu50def'Ѽ- )))lٶUeڔ)~ѣF1{L43̏Lֻr0q$f3Ə[pCÀ4c6%#7ek%'Myǯ9cnPpUq;)RyV֯ߘԲYe0M7r z>߀/Oݿfga5q~S&tٰq3w6it?jۓr_wϒgŌ%33UUy}hJih~]q;fN?O>ȴ{OX<?LϏa0z^Vr~?_θqcjrd=>SX0gxgc#6oOYCp\x޻inn7~'2~sSww[r3`jOM6t#y|>V8ruqx9q>Ҵn%u 1***JtJ.K*))Nl6 S 0VY횦94MˬڷM/;nÿ(Y.o1u`0u8 ٧=̆UB]{Ux?a4C;J%8rҒ)$kX|'j0==]JNNZUU9-''G+//***Xfjҫ嗷ů=v;V_u\&}} G̝36zY\ً]ߏcK#Ao jhŖ[ď&OeV~G9ZygdƇ+bKcB<n}=ʌiSY`>LDN0F6oʊ+C7!+ IU"A8.mqjhi[_:Ac`|$BA  c>) IG%AsE00o/4Aa bBspW[AJ0  '  E'A 0HkMAa 6>45-nAX Acl02MAaJQE jĀ`  o p) Q}ǢS 0$F $ 6ɞAA}Ifͯ_'}9 뫏yӧ,?/y~S&Oҍ7y@m[_ұvΒyO'%<(1B_, NМ5sQyogx~~AƼsEE\ 7rߤA?ʠmO>Mվ}8_XD_4 ?zW PuB;~+/*Wz^߫8 3ol}qĈB>Dcc~__}Liǟvwc}M_GUU} !zW'CN׉0 FQ_0pif>XfiXF IDATϏgUL~9er9>_Qs8l"7^ q66~o 7']Oo]o`41m??X89Æ3O᷿[~#Ao|ZƏ{Fʫ_@4CKF=+>~xo~KվnqĈ"up!~ٶm;зg?g7E\yťɋ}o;E~^=F~gC0_dOB+/ݻyws!\h4r7E qsnyOTp=wiV׿m?eƴi|+4 ͗rI$G۬V2/Z|)I[䬳aXhjnOlܴy'4|+p`sVTX=Fdd  9gٜ:c.7gy[} ߽,Y unt/{zQn c ӛٸq3ӧMeyw|/w."rshll֟ںz.bt v\n7_tKgf! >O AgÚ: (Fպgmmm Vk[qϺWj{m]'* DAd FA{u2y֙>sN|^yAͅ= FʂEK_=۷iS+7{8sAL+3gБTcE_Fq]Z适B>|GDPG0m,9F6Nѩk ~ڵaDEEcccÔI;`AW&Kҳgعg|uΎ% R;C"<<zӵsG%*plױ &&m[3_t ߲h2h=z'8$ˣG̙zҦCgjzuN똑t҉R*tډ~?PvȘQgq3mݒʕ*ҫL6l܌|\.U7oRJ%.\ 4޽w/o uʕ*2exNXڵiEre mZJmXtA*V^:tڃgϞQحqqO?6aMvm YtL,6m+XYeԭS 2g>fLLXC9J]9|(۶`aBˬTVٱpl_ =wW|13\"2k|\]]v\҉62c\^y>]:w`8]nn}굿 66oL޽hݾŒ;SvuJJJ {aaaa܌Er( EI̙&{Bq/WVΣG;~54j9:rf|'Wpa7J,OH !!1+US3k<>|DJJ ?ƣDQ>|^[IKKqd$7nqq= GQ8En_g]p1|@AN[vyىظ8= 7.JdloRRlf͌{zݻ(lc;eJhPu7KZZlCRqʜ; h4TTq^ +W F-fݺ @$$&R-#4lM[OHj"su!AgOD( 3gϞq1:D]G?xEQw>~{>xF5(]))#OGQz~9c>(su ʞ&@RR+VaԯWahoXl\s/8::PȇlDȃ5vv$&>#1r"A###3B0HֿOKK#?JR'OӴiU2PLoQ~ef,7+W2wk~$*ȗ_T~ݺdl7&Vb82;;;Nyʖ)͗?\|zʻcڌG$pi44ckUY={H?Ӧe ڶj>,[J_6|ʔ.M섢@<ظ8{h{9f̞Kof!$&$0R\ d̴i/k깛:fY|@Irt>x`Uޞn\333Z6oFO?A1LJW}>/*::ro~K@zz:]*V`CӲm>ÍA88?kk+YRaW9 &&gLø~e#ˮ۫dzxrV^Kn]9|^;urt$6.tc\cTe18;;d3tqvpJ+P6j prtV<$"ŗs٭cb4.\ 4zɽ{0y v3-rZ cfnnδ&0}pԈe{W]]b:;wk Y&}EU 3cخ+}qp7kJ_2thbccpaV-_l\%;gZ+sKr)\؍*+Qsss*/Oev/<f-zu JqOS-ZF =h4Qx1,--ʝ;wՙyba"E> S>*Zƴɬ8yW<CVS+͚>o$똓F{jRSS sG%..{ r}ZhN<W-77_S\YT*y([Q iݲ9vh47kJrJ dΝHڵjܻwNǟgѪOM]Щ}[\]2lll(QQ2N!8ci}+K z:֞srt䛯V'G{9,,( 7nVWyݹ}U뎙1g''5@VS =pXϕ>rF ([4*gˆERѨNj_UAǎefgFMF-Ay777f=|Ȣ_xc~Gظvj35̜=^\ll,Cgٝt!w0{ɌG=غq- s7KA:6̚3ߠ]S1d(N=e=&h~ˎ.)ZZ-3}nБXǑOۨ6ܺ}[on2?ϲx _ȂK<..$p,VYڌ% VcCl/\`lܼU_?_W23eZ93ammM\S6lζ66:;hZ^u?* ,YM :*ktx2Jīkgٰi>ԫSޣѥOH`&ݎxݹ}U뎙>([4=u%%99VNΕ;~g'GF=##2|CY| O>eݯ;hيU݃+jYv2oooյkTxUbT' !! B!+ &lll2[hx6j !w4B$h !&)оmkmZ[6PPAl..kvuj䷉㌓9k*]$ڴ4^'O6zj׬sJotsz|sZ>' vOh۱3Of6ٻ\?ʕkӑ !Li6o#?8]&_T8R k++9=9-8'O^ nOb%d!g@͕=͞ݻRT\NڱpR;GzjNNGTNJJ*nc;W;CPJ;Kٻ ͠[@Fcoذf%'ҧgwJ,Aء-aa)Ny$$&fze^E̘>u̝=] <U*St)"Dxr} ѷwO)\Å +W>=F'_.ꗟYvNt'GG6Y_~#x3ԫSۓ*/7ndsnYISٷRұ=‚[@4W6[`kcKrr2[ζ>4w \ٽ+E%)) ]{ظi?176lB?ammnl_fÇLf)YB#ʠ9˕c.dP_REzvbQܺLʕ=ɉ0hTIޣGrv0M~jf 4xatZ9lgf-inP*L+'Ni0G`zz:b;Plr9ME <;wY ~5xLtL,6m+XYeԭSٽ+ev,,VPYS(B%BےUL+3gБTcE_UciԱ0Y..QRvJb/iӲs/ѺeoWȇԫ[N]{3 ".)!УwCB(`kK^˃ߴM4! te$={ƎpqqLR_ح[\;~ uEQp10csΚ3BBq/WVΣG;~52fS!e<'dȐur9MS( G 8Wgϸx NGBB"׮EAWW cZZ5kPt)RRR_#;aa)W _|*JcNN#G8DEUJ|jMhZRSS9uO> gݾ}UO<ښyb7/q^}oqvv"6.N?wif?ƣDQ>|ШA56BJJ Oolg˶B+{Yqvr"8ذG'GB3M1YeKisM+f)PYၗz]i41mgNg3;ʔ.M섢@<ۯ9l _+W14>͛ѻgw֬9GGm,,24}sZVsnW !}L-h۪l*Z-LX8o6W\eE/NN<4.c EFf}B/˵{mElsۈ!==m;dFHKK7Eh6t:,o#l;s:cƅs p!0sss6 珢(1T_Nӱcn|vA=NwMgΞs.UK_mqn 2iZӬ/sn׵q}&Lcnju\x/]k٭+#C b4Kf}B/˵óqORDq c}~x6O%PTT\?F^0nݢWw/PTGӧ|T(͋NT\ FJ۠jyۙ俬9K^:CN>VVV\vEx㿷{9,,( 7nVh4Yfŋ6|xub\S-ZF =h4Qx1}dfxٯun߾ gg'pllñ@^,jThpi\]\hPZM4kF\w㋽\ܰq3C~g[E5|(vvxc'p?4Ըj:^=q*fj#9{.G _~Qmsaf͙Ϝy ؿ%3:{rW.[}>8 MΜ& ^;RTI"# a%V0 DGE!{3}֫SޣѥOH`$&f,x>+QBMFp/W|W%'rePJ2"AS("Wg rvvb ^Lcf-Ex#x|%8YǏ)Q#EHooF1N"S#4$) B!$h !&)BHBa" ɣ"7S;MfwA<Δ#-BdEx2CS `՚uYHd\m%xC4y݅|N`vёM}[bkk{rrmw`aBXWgʔ.E]ڴl z:~׻wԷ8Dt{tI Wvٳgvs#..BCO NЭ[TT)&pibcciۺ+UWc2y<;uC/6L>Sƚ7k ~\IǚOٰqfff|qRTInܼI*p1LND!E!U+tqB{>nsFYj5zsb 6lkрu74>dvC_-#+Aj֠tR$'rWzzSHNN؉S|Wgpuu1s71qhi,[?… 5_5$o޼>i|BF=N:͠[( \ LBb"n (Ѡ>ko$::6VR~mc 8uko(pE?{ʻcfRŊ=|ĩ?PPRgΝiϞ%R xg`~L> !wQNQCPP_\ ~oP՜9{E%сzjlﵾn͘5~CHHHd%\rUb4mMƟZDO?AcfFɱqq$$$`oυ?ZжuKt*D>14rxn82;ɼM`zNI||e˔/>3gt }{`T(δMfϒdxV$h7c…kء-K2芕kJ9re4} vp67(sIYӹrW] &&rbAyc,9Nǎٵ:y?H_2d(bcc¬^Ġ666DEEp}OcMV-X*c?gL\.J@Ͻ?w*V?gф>ё5kq$ߐ'_j _yrYDղxrhMYdy7agWD޻g>ΠLTTweŌ9өC;\]\}TEſʻ"p3jZz;{>*WĈ>V^Gv0wX[[ 6rA,^ڌu t L;ϗϸv0z0֬XJӧعD2fƴ߰vp0(g!@r_۰ɠnvVYKC6 _V-8x033j^ 9|'OGz,YB3U*WBR}/ުk׮"##UbŊ"##y1KLLTt:s+++sVT֊W.8((:EO|VSNy8Y׮b3^;,^j8qq^ цmB(Q@NKOOR,,,R={ti驩NNN%x{{gSdxV G ;HoHDn&x7䞦\6퍓i7#"7S#4BIoD.En&xW$h !&A[$h7Ka6'''⍓x+$h7r_w/Kbg JHHTrI}4śQ+Pq:JLx$h7R0ӘfYB\ !&)BHBa" B!$h !&)B($ /qBM!q^7H~j^ȵA3_lNE?,U~BBVUbk4z/YkB˳~4B\FBa" B!) !AS!H| *WB!ɵ|v…݌h7DEE' !O?gdx]sM~lJۏWBó>g%NGzz>@_|677W?oE,?CضeʕKVZ|]۶ѝߧN1(۫g> M!Dͳg1c欗9c,Ξ=Gժ2UN䓪tؙ8} J g ꇅ=_}Cճ;l߱իJQÆڵ۠B r4S㗩+/_Itt4iiiYZMO?ͭJdEhZcbذiA;wrAAALBdEoQ/dwnڵm @ÆA~}jBCO\I\\QQQ\k++RSSw>!hkPlƏMdn!w/14JU^n 66'BIO3 U~l%n/,, oﱄܹCRXjSdI eu,,,puu%88Dvv0E|W9sfNg歴jՂ0 c=BQz4O;n5kЧt:fϙˤp!>F>?e !)$hf8ݻAAA}]\\ݫ'^{:to~}zcoo/޿b\L!D$hE|߸1(=*ʸKtXYY5:Tʗwg ݇[S6Φw~jPՌ՛sey3,YϏ%J0illlӸB#4ߒ*0jxu#((?=|EQt:BCC)^>ؕ(^{lЀC#G]u1e˖J-Z`ccÈC:|gII~nݾUi[ Ba o= dܗ888cccjU4 :{ұC{]F]۶ @pZjQQQR*>#cv!8p /o37iSٵV wr\vyRNmnܸiPG!D$h%'N$0>۷1_S{}S6~۔juqssg6t:zZvMBYl ssٸi3GEVIժ\v4 MKK#!!x?q"G&?p /XhPG!D$h%ZF'EūqVeӵ: `",t:M57N೿iB!L#B!L$AS!0M!D4BIB!L$AS!0M!D4BIB!L$AS!0M!D4BIB!L$AS!0HUq^<58x V80Hh@^={,PTeBdMzoQ/dwnڵm @ÆA~}jBCO\I\\QQQ\k++RSSw>!hkPlƏMdn!w/1={` (JB!#=,TqRΟ`9,, oﱄܹCRXjSdI eu,,,puu%88Dvv0E|W9sfNg歴jՂ0 c=BQz4O;n5kЧ;;9䈓6#o޼;~Y琚/'"k4` Mu] S_v ...=ttG'')^mu %3NNYpAY!/yzz}X[[( vvԯ_NʊxtR;'MW>ݺEڵ7w6#-};jqz3{,ukHIIat:Z-[nyf44ߒ*0jxu#((?=W7tRx1}+QG٠GPv-֭c4˖-C*)ZCƆŇRϙ;o>˗O")24+{{{ ɸ/qppRXq4w޳ckkڶe^_CPOR*ܸyÆPOy3F_Km7=wg$**'N2t ,,,prryf>rDB!'=ͷɓ6g6"? ?VY ݻ)T +-AcnNrr27mȑj>Zk׮FTTAiii$$$}e!!)){i:B!&A-j58Y/:&.^݌Z-'Ldt,X(:͚'uei|+S!D^'B!D$h !&)BHBa" B!$h !&)BHBa" B!$h !&)BHBa" B!$h !&)Pj4N˓ǜ1Fr@0p@ɪ6iطw7[6oQÆjg|yw`+Wr9f͜[iժ[a@z>xѣhPB 1vj֨Owvr'g'6mXG޼y9vf!55U_N!D$h19q] S_v ...=ttG'')^mu %3NNYpAY!/yzz}X[[( vvԯ_NʊxtR;'MW>ݺEڵ7w6#-};jqz3{,ukHIIat:Z-[nyf44ߒ*0jxu#((?=W7tRx1}+QG٠GPv-֭c4˖-C*)ZCƆŇRϙ;o>˗O")24+{{{ ɸ/qppRXq4w޳ckkڶe^_CPOR*ܸyÆPOy3F_Km7=wg$**'N2t ,,,prryf>rDB!'=ͷɓ6g6"? ?VY ݻ)T +-AcnNrr27mȑj>Zk׮FTTAiii$$$}e!!)){i:B!&A-j58Y/:&.^݌Z-'Ldt,X(:͚'uei|+S!D^'B!D$h !&)BHBa" B!$h !&)BHBa" B!$h !&)BHBa" B!$hΜ>IѢEBg8AZb8~0 \ٲ,Q8S~= ԬQϷT*-׭Caɓ'SͬmӚsgN'677gȠc|t"ʖ)cTK!YAs=/d=ٴy g*imP4j56hT*M^OȄ[?hEҥhۦA9cJQÆ~{*T@h7 3Bl s{}ʕ+Q޽&9}V}h4/8> @0Wov`>.^fff,Z8''GV._.8;;UwҹqO XɵkIOO'..KPdItR~>`ݭ'>>{B.zUqRΟ`y%l۲5}D޽Yx1T)Ww޻G^=4q;vJ4HLL> 66/PbE6o^}`LYӦL@>X|~BZZ}GEiO$''XZZ9*:UpYj% GBBjC|U#|jgIhZ&NG;~ztԅǏ{nI/133R4hP_~O9"qqOD IDATǡGt> g' ==y._LΝ:mA!A8Dtt4k׭gi|7ٳ;wX~#ڶɉǑgw ܤZ5k#pq"#g@`%6mޢS^]&6O3˒iڤ>?11˗q+TEQؾc7nN:tꥯى'O:_5ʔ} t:˖ŋDDD0|H}Z5kPdIzuק=-[׷6ի^ 4.&>h֮[Omt:Nԩ]F%%%acktENܩ#va >}{i˗O{ }1|4ִ4ʫW^} |>C={pu7`ذ/0q f guV|0=}lܴ 7nT9xg0+/kƇ [~ڬ~bT_yjS`Ԩxx?> 8ct UU0r||ګ=S p Dmm-***>v@]]{ |0=|G0 }I"f%aJJJĪUDyyp:H+VUQt]OLzV銢dI)sזDa6-zG_c15BQ|lXdhT?xmX{,XNN.O=l]+5Ms !jm6ryu]iGzYYɑv]K()) =g%9lcƎj',]j""&bhz 9닉wNɹjW϶_  \KDD&I M"""DDD&14Lbh$""2IDDdC$&I M"""DDD&14Lbh$""2IDDdC$&I M"""DDD&14Lbh$""2IDDdC$&I M"""DDD&14Lbh$""2IDDdC$&I M"""DDD&14Lbh$""2ņzyc1b'Q=rcibCuUHc)>bgZ&I M"""DDD&14Lbh$""2IDDdCȤ{G #sԽP 1Ĥm_ ׌;!4(a-:43G݋sZE1?(V{Qx!DDD 1DRxH܁ ʅP*""&``f1PYCiRIu),ě3^Ơài]٬ݫ'vUeW^cldݎgz\ mާZB|CVFi,jګ;oh6//?cqu)'#33XlJCQaЀ(((kXxw=x[d(m#JZ4޽w:N=?xcq( Jd%?riNݺ?X '9Ż> ~c,nZBM5¯Ű3b%-_~Ż3g>37x .{, 9h,[<7Et^}% Eŷ/3N #``~=jrPWWfYo[lEb,>55yłn {Dzz:6nڄmێ.xⱇ1㍷0f(lV,^T\.n@XTlܴi= ^<?#=on= At0VWyp 2YpVWg~5W]O:G9 M{ 6lh}/jj\xqUbM,~-\uݍظq.d, UUՏCҋ`郡*;oxɧ1h@\0<흱}NLgnƊGiG/Upkb10m6Tރy+~%:uĸG^p=xY5C ])Z~rωBB<ֻ3q!++9#juh; ̜5? W_y v,/76k˯Go|~p,, fvMB[nڲ2tCFfFwq_ƃ݃-×_-cO< ׇ&ގ#yӡaԘKn)w.O>sHHwR?( / BL.9OM}@}IeUy_p7^w-FS{=z?ҸX̾-ZAŗ^X~=ᒱg#1+}`̅1ŗB^HOOx>G5W]'Nš?>Gޒpø۰ peO> ʈk %_ ˅nwEeeUXQk(NZs(('ǦMl}}Uc¯1aY׮/s8sq?Zv;={AA.ŨłCL+,,@Ř6ex<\.L2N=$dee4 ۶oǿq pTVb۶-Ao~Z55ރԒ?@u,'ץKz{&^/x㭷q)'lيGp<cxx^x<,Zx-_W /Y.] -"kżc@ 0d@L8QWW>:c)f_o޼r2w?neևɌ7ނƷ-D-Ui; b;oPSk =WUb}nGM+l*vǎB //555r)%<8{IJ<=(8Zy}XoU~NpHvءmQYwy.t˃Wr:10ͷɧs Y fckWE<UU18ؿbQ}*V_ꋥ?Kzc۶8M4( ^o5c)۱vDcNtw>ߴysHy?-[q[0z\x|>j^w:`[K?S̾~ɧwGMu5>"~]2ω^'QK.?6 Mގ{c8iԐ+j332`ق!ïݽ{2 .R$N'^yu\ssxtxڀَwx<vﴰ6;cm.]pʰb˖ؾ}@E?\rI}]p88[7Ҵ`} WBuߗп/mێEt_Ų+B^Ŝ{ Ka跱VhÆѩSGL< FW^{,{ac#^u]s>Ƈ}A㑇?=?l>':0D-QT߰|׮c_`ؙC6mQ{GDU t,i֭XW\z1l6+232p%c0˯, { EQxvݺ@cXf <l6=GoCf&.5 _XsHQrG,N顋Fؾy^jkqG;v-[p8 CWVUE]6V_5s}pG&6w8*uvGD{7oނ?VW]L!Х}ݳl6+c(`焨-h#agO?;-0h(,,f՗^?cÆ'DzM|{17vK!৪ bb۶x쉧"˸ګ@ee%|ctX,iXt)^2Cpwj]Z%K@aIcqM7<[n ͚&MQ]w[axî6Wņ| O˂O?ģBeezwftF˖a҄ѱclݶ %SMt0U&QbczXYx]c5L^\{xW o߁'|Q0.gu5z1 ';;evDZJ )DyybZ՚E4k(J2GJqmٺ Kv;ȸd1;?Ⱦc6LҬO?+/Qkaa499?z<88t]4%lnuݗy<neee2''GvY\\,$|lӳ ?_gж6{]wʏi0׌;9^u*&m8_#B""jѡ)4\uh{J);b""JQ*9_$""2IDDdC$&I M"""DDD&14Lj77 "sΆ;$BzQE}71UUQܣUdB? Z}DmDvNj]\gСc{*ãgضc;vSCv +V[*Nl )c^Vv&v, HsNd5 K蕡IVHcLiC>dhš[܇~z|6s|~-t==EV+?~W8׋6j ,_K2Y|$X~CX]K7t`xm,[3 &9SWq꺎wfO,.77]<=o|Is1t`dggY]g}K pm7c˖Y\G3^|6$ťğkqBJCc#k;v_HH>RU5!/>/ˑE{hq/sƩ`AիWXb&9Gn5Ai|>x76 /XVoߎ9[lݻ@+~zt?0,X,[>8'MĔ?ÆF++йsgcq`y8ؿP-?\^;>/GJǎcΰz蜟N< !7'.Wm=`hQXRJ>x {_Qro+0Q:5 j?]ի'tV,]|:wFw.,!l‚qᨑ3_EfV&N`ddd@:*_tM#J"޽RƝG;k.%80\8j$V|T>7m:v؉矇[زu+&܋f}3^~UU`G1!i//<4l6X7|~i>; | Pv0”0%%%bժU\8NQTT$ժ(effy^+tEQ9Rʎk}R(QtEbC~Nص\%Kō FӇ_% lXΝnwマϱlX{ع\ CuR4f].Wu_^^x4ݮɜieqq7FrID ӹ1I-CPuVKC^DDDB\;}IDATdR CR"֯ZaM ChIE24ڊCMDDD&Y65ߺ+4j5I6 >___ USS {#5qIFTVU#7/Y*2󡲲 BK\zUdBuu5~]Yh?T M6BQTUVD!Em`._~]~nSb ? M6BբPUD%4 %DDD-T4顙 %""vy$""j6-;DD&"J~h lODD&#&GC4 uL&5O&4SDDDDgJ&4o9Q3K]h5СfjGl) M]׌DDD 4Y,41%嬂Hh2ްY UU {Y=wz6@ WM 3GooIlÊDDE4Il"RqJih;~chF詆% DDVcm hYM c kxDz#DD:@<*R)3&Cxq.A ]"jM=VPؖ%Lm&`NiM$8R<:C3qDD-QSH00IC>C !!Š@XG>QE +AM}ÒK@DíAcq܄hY"ADDXqGqo40#TSGtZQ-ھGQ(ڦJ80U M·8L~ECFh@ҷ95dHublÒImhKO"-+4+<㕂7=IFXZG4J}SBd:5౼afj7AGMOxX)+DF~ZOS<4!Dr3ܰ$%A"̬L&H}hD 1!wDDUxJA`f@&Lz:̤Q; RdHk+ؽA%Xc= q|ZhqP%Lf@#!٘8;8%"j<+%< "4LBHxhj7=;6\ "44-!Ĺ""jBjBH#DDmRkˀԅfD"'%"jMDc+ ˀ&Є]%NXla (!q%"jQ"Fb PI<a `%_-6C3QKC$8gRDDͫc`4QVB3Q ~0–J0xR"ӾC3%"jRqtn?BMDDT&$"6&U pzZHmX\iQ)0GDDj5))1Qr HŵDD !ˎx& #P6=t%o @DDqdDIDJC1dxQrH~h 8$"j3! SN %"j;&5r73vp!"g"MI M"",)ziZRӜR!EIJ>%%4 ^H)g&""BFMqrIDDdR¡#1iQK( W¡IDD%{09M*sRQYWW8`㤔B0)^/?NTU50Ҕ7\(B3PKDDB%uijz6==]fggK&Vknw/ijf,"""JHyȥhմl2##Ay4IiF M)%^/TUSDD4RJH)iZđ(za+',S#KKKnX,) !8;pѾȩ:!jJǃl.8bEQ)ҍDDD뺦iBZ,=0EkXbc4QCDK.y͌ YQQ!Nt\RUU(TUUWUUuIDD-B|9MUU%%%Q뢆f,VUUz<z뚪O%z``W?ȓ.K@EEEpafggUUUJ:K""j1^>]5ϧdXj999nKcCQ6Mfee/kː|iii>#\DDDt]-if@\D3p^ `׫nj꺮k^׫(v+.|>/==ݧvZjJkG nv]xMhSL7 |R4(^@N4OZZZNuinUU|n[֭VVV&srrd߾}Qfl,CH+VUx|R^^.b8m6[Q-ibXRhB1-- @ÐuvQne 4^/B utժ?*5ƍ̙3nXZ sNHn޼6 ?>(zj@(ZzXÝɵ$z=sWsx/뚦iiii^hY\\,gΜxOӮZJ8wܩiiiQVi4M.l6[00!i|NDDdnYV>OlzgZ6 ސ  rZŢ|>vLiZ`dx_h'n?6MX,iNS7@B3 3??_(| <'Q<azZ=<++Kw:zFTX$Z1Gt*<JDD_#IKK 浢B)4"8Duuv3DDD0l=pȐ2=(WX45"8N=zTWW (Q2ddd_vv,--EzzzQh4qPWW' DDDzOt999fBa'3 DDDP%ZHhGc%n';,ba 1LWI"e@*b7Z#̶3%UᕪţUf@ODDIR2x"""jC#P3,IENDB`RaySession-0.12.2/resources/screenshots/Screenshot_20190725_233420.png000066400000000000000000001477751417052567600247400ustar00rootroot00000000000000PNG  IHDRܕO pHYs+ IDATx^w|e̖lRR.@ {/y z]c靧g?Yxw*D: l6f3 @Wϴgghin{hiq4MӴNDiu":5M4q :6uJiti/''t:kx =Nii->|xn&v5=ւu4M:al O8ћѠn.kiڎ;wHC|Ohפ'mh/5M4mY$zca o[ 3gΔ=@]]]GM4x< K. y4;0#4wkRӞ;w|_~"Q8 HKKKXiRnxǣtU=%ؚԴ瓁@@Aah`BiZ't:4xTYYzVFFLxs."GFG\4M70hGp*-KIIݻ[%%%V{:ؚi^WhX,}l/x<-4M.uuu-j40 U[[ PCY f>}=]SA֦vEEt: aAxD0e -/9mN4M;H)RJR PuuurY@rn%a7 kna# J0p8,].,ѐ4hM4%@R*ߏR`PI),2pth%nSM; :iNSJiH)P(d8Nat8B)(Ngl]5MӴ"aB!aBEC\B(4-0b ; m o؅M5m \N]N 20MS*D4eFOi] n4 !Ttai0R&,+`f`;; iK)`-HBnݲ,)0,˒a,KBC ;+X4Mۻ<8K)-˲,)eYe2p8r:~4k3a 6״nߟr<^oU5uj͆iin8x^};܆Դ׬Y#*++% jò,p8vr0l]R^UevkiZB[ BJ^,BXN* ]RUUEee%)))Yf1w\`{#w^ƴ\H4cn˲.hi%Rnk*iv + hRzn| Cn{4M4˲b/m*іde]+Yr{.ۅIӧt%i"NIӧ>2|CzѳW/{if#]n;Zv{pF' oh0.[KK&jPR\R c&V43{铙8}]ᘓO rmw;?ӏ8^i;-.bwY0qNjlx0r1ddf4j&2~&aTTXȒL6%VNFfFa:ykce۫g^`vk-7;kn=ܭiHH5 ' de00mr_h&B=D/^Jykw8졝]-t-V>hNP0e+))*fRXŦ=(ܴ)VrM1M4R96ޝcIH2MSlztgѤx_q1K}lyrJ2Gxy(R2d0zb6V.]AuUGtkWaА$$S[Sˊ%V5bQ݋L&o* 6#-5z$}`3ߏP[[(*B~}lҒ~}R*_{n4Err#]4[-M0eؕnZ9J)/^AS& ݙlOorۖ!v_^/qme[ٴ~@cO z`,dSR֣;~?yyWB3jITx9èdK1#ƌpfZatIh졤gf_ x :/i9uu 1lKjY򕤦~]>6r|4V.YMdɄiOvJ~}BtB0  ѭ{7\n/>AN p▶e.nݻqGycuyfܯ,`>9hD>3a<_}%؝33(ذO_n7s1ʷiyl޸vgf$Gھp`fga"?iwm{p?dwFQa!-\\egB4-Ϗt9oiPTXȷe fI3NᐣِKl|4ŅE$DB`3nO=R{з?J5 -5ʙzL?ة.)5(z^}{=iRYQb]q,b?"geĦY.?lycޮظѳ~԰龸]=3to8j Ijzk?ʷnk42*+INI/\kR zF:Or2@Q?Z6~2ޮЏMl|[9%noHܮ==^㎊#]]Mܢ{Д@M{~ެ sR ,RthC=$>h%aw6 n4>5)) |>ACУWe+bgYBFxxi=)aBGjQ&wTIp'GC)Qx'mMtдB/(H{mˎL="pACd޽j>@.^/Gtl ?#g 8-)~~}z ,c-J)֯g|ǔC}i ~?ɍ:ycM56Os֟& $BUeNj={GS K-}/2M*+ڴNlotՓMDط};ښKZJ|l--0$MN<={b)F×j4rӑ(w؃O%am9nK9nMdaq/'r Yg~y=MȲo4*r8 =oTװfXs3O:!5\ZziQJ XBP+!s$Bʷn#`̄ߟ#?}[7 =cGsq]t$,bkY?_6_^{l޸Kѭ{w&MaHLӤ`æV[<Jׇ#O8]%>J4~nڰQ#ޣ;uuu,^: `xuŲ,jkXdYySZ\+7y"$75,^(YѾ>ҴmW=h|w0'3222jjjeYdg pIRQۅ<ekB_eو ֶ_|} 8:_>Jv;ok)V!DiRʺ`0RRaofff%%%Uvwwvb5n4.fv]< *rZIn ƪe+죴v УS]U돱Kꅦu2{EpCןm=z}~ޮ]| R~n/4m7k"5o zMZFz*:|n9k{hObm\_MۗU RKvei֑5͊iinM4MDtpkiZ'[4M:ܚi։4MӴNDiu"w"i ;}/]4MӴNDiu":5M4\4Mfyyy"''oiigkM4M4M4m4MӴv&ߥ-̻,^ƛ忾f/:^㿾&}M{` ד=l(k~ϣO}2MtvkJdggۋϚͅk/"ssX2FƍMRqcGs˜hZOԸ[sY9#9^u2~;Z[52:=pXH[+)++ͷ߱r<'9{\sąWobq1GsruUaw,Kx<Q[[[lcQSS+540~,n]Sx(--㣏?kt}ɧK{w7v gq: 0ذqǿ/f)'DzZ\>R;}Fn3CvK~&wApYg0bp=ʶOmȁ 篷Ҵ:Tp+viOxm픖i-w_x>j93<.ZnF>qŏ?uxm֖xu-k< 5kԴT}Yvܳ`mwnϤѯovmp8y_ۋ;7|x1G}Em+קϜE:;mYH ݥ=^{-.<;eWG=.޽{+-=+0;X{y5r0{ Fmw- 23Yj[Xs~{ g9ˏ?b^/7\{5#gplT]OEE<GPJq1G3~Xjjj8Omm-=xGx8Y$f<lV{~ɕ_>^~5VÏ?oi8}iŖ"|֬Y忻Ӧ0vh.<\{E~'{xixɹϜo}aWq C^x$hwCûOɋ/½w߁e= bUU59;f4,__;=hqc ~},~iwq r2 Ŭ373gByy9G‹/v0еkW}~>cN9t?h~cq9ˮdL65n)/5n޽;端b${X٩̵73uȹ6rǩn3Ng℃b>4^{MN:e= wدgO.Buh\sݻp8su#fl..]y_q39y-7o393ιo.tõYY r ]t 3fhgGֽ[7>>*0pwdE\Ui9Wsƛo]ѦϜ9>nEg))**y_pѷqи|d)cnj`).͛73j#G gwK~=zߒ 1Gɧ}Ά QJ?!CHOOcB eI!bRRRR8cHx(\HUuu*2i"[Ͽ@)Ea}w1i|R>0M_i)VqKCa@>sھch*ߙ&2c/< s}eR߯/&vHNN%Kp8L2 ~ɓ& V^NA|V\ŊدgOr.Ҙ:e2GvXlں:z|ŗTVU1{ R^mO(\Uצ4 IDATYO3NO?W_# mKzz%%нKپ股Pֹ+ujNkVTT"G***BЭ[W***Ȳ~HKM%w82%[(mRcO??gΞş=^xI5W^sg?=ŪUyW'm7DMu5>VQfF5f`{[XR 46> bFqg}қ҆}?6}k}=#h1G}MQ%%>enwnrm|Ï\{Ülݶ=ݺ:o uuuuǭTVV&mm)*W_?)%[n @1_)>X П9 Áa :``|˘5s.D)źq:z|$ҩn E9cYXǟ~I'@v0. ƚ 6RUUERR HJK}EGJ~di㏛?ٽҫ>4NHKKۥ OuW_KM{')%_x>a 6Ï?qYYdھb 4d<{4_~ip8= )%`ׯ]B)?CJ٤yk#x.8ϾP(h%33G?;=ϖzɜsn>{ѻWvp@'}35O׸wǟ|6o.-W^;L"z~~?K.煗^͓-'p\GW^F]f{'x//pW?`\~؟ E/ :` ι= Xf-omP^Qͷɕ]W\ζrߧgt[̹8 ;0ذa#<_|9Ѵ_|9'}gX{]ۯ4$EE' eKO>'?,ӢG]ĭr{xvuװ~z}If8ontl rr35T\.ee[y\XoM_1Gɟ ZoϜּćw;/ܜ'|>>O\.R:@ X;u"6y'iu^mٞng{WxɧXl}|9K(ZFZjᄑ}i^y_ ! !,˪N3X[[RRRR`0h|>+##PÇW999Cm痹oiS5֬eSx1s),_]kܚ3&mskk}x)j]<}M۫##h{NGy<{;Śҽ5M4iinM4MDtpkiZ'WwNkRimoYf nƚiZk'+:[wޞii;騁ޡ[4M}Oӝ4M4iinM4MDtpkiZ': !p9H)r4Mz{Ge :l4d-n ځwi֊oKVR`H!:lxyyy /E zB)%L.KX%Lam3nir:^C5MӴh.[v} e ˲[@8M~~~q+ObnoR_M43j&K'a.e+~ֶDvv6>OA!44'UlvM4mՖLh$qq ^>OI!BHe\.iY.˩rn'f5"A{'^S4Mv* Ps''9RʐeY!r,áեKu+uVk;'''<E]UU%D(`0(t\B)%,RJ8m86hi{!!{4),˒eIPJp8,5n-B@ |>U{"999bܹJD `0(jjj4t0 ep8,pD[wqoً44УQi{5MBfRJ!4olpz'JJJDr2''GYu+k78333e}[$YQQ!^D\h~Bei զ;oڋb pgً,ѴFK={|CruWOfXiiBpHb4H2bPY9Z[JpV_^k > $mR!RRDN9+ ﺺ:5p@ܹseNNU;lGQM;0p@QPP ^BQSS#nw4}ãZ !l PJ9fCոl͚q%m&Ow;_Νga)"?TJ{nR0\afà=l(RH 7rgMiS̠o%n">`@ 0Xb6m"Oh7G?n?Ztp3O٦0yɬB#WZX|i"\]5ԺHgy\?nǟ gb)L.ޯ_v;q;B),->hG,@XJ&K vSPPw[h \B$˲\.+ p8)"M0LtP_, xwlű͈O"5ljf1Ms@"5WxLСC,1FaZ&_|1+.GJ,N;^xjƎM r!ŗ_,@c֭پJRRRx$%%QYUQ;z$Oju#G n@)E0vy_ӧ7'<ӦNk*|wO9c8klB0R feXGP>R3N׿: eY 3O;?OݿIMw尡G k?]2yIr0-W0 OCp+6{<'n' @ ?X Q?WTI4,LB*BJ)Ja&!)e0 ʤ$eYZ 6i-\6Mi0 O(Jr8ZmȹkY?qRe4$)27'RWWG'fvouف@ ƒ0ϻR~Z>rrqrPRCJ7]OB|1 z33~s }˰C]뮹7zo_Ù蒒«Χ~K22 N'C޻b)Xyy]p8m7aXE8?̳!斛oN`W_1vhJJJsB!: %OEE%?0[n cdD"9#Yb{apUW_ͷ3Kv:\x9MwIXb3L|U,^,5x.;Ej;:Ym}i2!~ ?5Fɨf{#PD~RJRaj١c!DPJp\GWl%[y'8iD@⚶2v}h'XbuFtOaDi¡[}63zi֚p:A>}1UvX|ͻ!VӮ.˨w,+I)層^&䚦i+I)INa鴔R*XPHuڕ**++IIIQ555̚5 4oQ57MAA㑀 RJiPJzg4MӴ}RtO"EDvv66G%qDk8NYYY)R)eatOJd%]/C4MURI)C)BLT@@9NUVV֝P۳~k4MxD8ip8)i,1MSZ%<Oiiif'=׶;UTTRJvI)p8YJt[[^!;zOʈaPZZ5k,[2amM4MȒdhܲ)eiB`0hfddXNjju; "83MSJ)Eӻ\u9#ӧ7}cb5iuXJPC ,Bp8D(>6M]bĈl#׬4MӴRTJ )Le 4c=~jw;eYBJ)PJI8Lm VaNy}FjVo7ۘ7e$.Zdiu4R-,ZwjGnD6 !+RګV& qи)#/YJ#蒒µW]My}l>72iwq om8i{~׽QB`YHJJѫBi6kSpRJt=٨cF1bx9m aڔ)qS yG7Xوٌ3VMٱc w"Ls#羇e;&A. 4bsl>3DH:L4!s0w?{ns}<{SOp8f;)cjZZ!hh} #s˜:ib|꤉P|q,m2 Ïbnoo5C d͹r} = rϽ̯=<Gz7^};{xi`u௫# qe۶mCa{)3zTl sGY_30qxPcAIIIlyi陕Ųe+@)mÏ>v@g)nۺ~n9RfSUYɋ/k.[\7jLaZnrӉasa7sF|tY€ﰶxҸ9`_7Yn[uum2~G)'s7#3?7У\UHh2 ƍil%g"^~Կ?#\ɸW2Yj5<(% Ӱ3kоތ {i;G=fgn.>x<~aCng+֛p[_ϣ?3ki"nKc_䯭Ns+Ǝ;\.0B, ,+rmێ,+.؞Vy{Ӽy3ƌ~!p1HK:b\.AHms0^yoJD!OqiYa~iM,mПߴi`]Oڛ7#cUOysYRg!fwMD49Dze :?-sVUDze zgڊ؈¦iq׽tzzFNǓ7,aoѳύr_Hm 1`* " n  " n  " n B]_MDDDZ 5 " n  "{ v։ȡz˗))){=O5c⋈Hصkqq*sk n?jwvSZ n ,8LӤm6ݑ*gvf]*e9گ76JJJk^&m۶emddd9DDiO6YfJ,#22(((0Ls'!䎌PhLnXq%۶0:u|۶ n n9l0@hڶmQ7Vk6mVyM:[DD,?mc[VKy@ae?+x}¶mm,¶,"\thVMJJ(ȳ'4" OIdt8nQ(+d,e-]E4H!QC$РQCe吗C^fy, }Z!x li@aژ͡>?Puܶm"""Fڶ*:N$) &Ǧ0?>~n6PM 䲝=m~6!e1eQ|U""rԱmSmR.okeUysoR!@o}z /;^_i-""T`e%¶H\R WqHʣuʣ劶Grg((/89%t7ti?,0t0yf[8볤|>/~Y-"qa`oR@ܲQnEhra,q>l_uP" gSL vn*ef--ƶ-LUgTgzT)[|ф*eCÆ 9q̚=Y%""ӏТ# ȷm~޸,k߁[XXȉɄTJih꣠ nƽO&>ڷۯඏkWHh:$ [XEb6}OlzB6{nР 4pWSPP aU?40vr+Fameզv/0 ltlϓN{sɡY9Us8Vc:67oכ˯e$&&0tt/W^Ljgd%LI8}9-pн{7~^;']CbB#,fҤ)|4abTT/Ivb7=gn W_IhV^ÈF٬4hL S}bo}_㼾}t߰믽??}v ,8<w&5V=sm#2T+~(I{e߻ybb"111@ж `?bA{2g_l*?}'3=g.ތ zʕо9*v6nxf:23HJjY~~}>׬'1eg~}7~φs>)WFfdTi'#FrUsL{}5˶1rT 5d͇Q](*"cbwǎһ7ť>cmĊmO$556l@f͈%77M` QF4!tkWPXTSv`aӲe ~qmxx8QqqF5eufo.8/ۆ*k5;MFF&qUʠ5zJO>@Yaa! kܵ^غu^Cj/"(n(e)Ur3.Cx:,ˢuב;ji-Zb 2228HNNa&III4mڔo;Ć;PxNvTQ ޛ\{M&:[̂(,*"+++W1h0gv4TRZZ_&"<|w/Oǎq4dk֮`uĿWu4})=оaprϓh۶}ͷ\ 8 <7ndܹ^LҘ7o֕ #9"?}>KZZiiidg#n}ϮiA7x2 |oqLf<zq4sc5^6o.u=>(<У :'b6S}θdǟ}0wXpQ3wi´O?3f,K{΄h-`7uۡ=^o>Ο1wԸ1E̚=?Wt64 vŠ5{wk|2w/"`u?ɡ8YfTNKpޱr 'ٺlۼ^6؁k׮viL4ƍӮ];~7"""8uֆ5\eYn;$ 0Mcvm۱B4j.?XDDqU9@S{#$d=xRgq5eQZRL9o/7 jԈbΝ߹qx5k;viӦO$''ӦMfΜY6׀<ͻ_Ha CxzΙC:ea)Ҟx BB|wtb0 YYxbBBjGGG vǎ픔j{ [xLn?-~j٬*Uw}!;/""3'_~!,,,v܉&33۷rJ2331 +" _YiϕlτΗVm֪r3_( n<0 8msLRXWT nÀz>U . $+?8W#8>CkRRRBQP\\L Y1ǐS--^&""u[E<-v_e=#xhAկVA+ٔe v݉aF4\DD~[E< 5GrfPrKlZP%ѕò$2NU_)}T%iVuۀmj}Ucܼr?o+? HEɃg9zUgqwՑnHAKj",,Y\MII m8/--=u4+q6yoQLXW[O pjR(=z/[\E-_ ʈ{oذa^`ٛ7|m=+Ηە6sEDNJf-]<# ۶I˯X qӱ<2?BڏkkOSUa{c6daXlwYѶmf2G f187'&m`z r+дaC.Ё}PT\̜1-U~umpb"gh[QW3""6 JlZDhq-޶[O"+&].'qw>:11tNrrݷܲe M6W^$&&NRR'tv]vmΩr*c۔ݾ :>ACnU2.Wwc+n};˖-KoORib-<+~ǔy<1iK-",j1> pt*q[M;u"4. _f0 6n܈mہ͛K"ɽŲ}:(|yF9n#6S؇Q|]1ҭ 9/p[Vm6؁K.ٓiӦH۶m?>Ӈ/˗c@x%ectϊQZ&wPAqzSUz@09C{JJJYZNשCtj#nb^F?eb"M‚ q4mڔ !!( 11< ^lY;3ˏ5~{/N  㬳z}zwf͞lԮwfQpHu:>a+U}Ǘrή2:_ '333p[OKzz:Wfǎ /J*fw`WlaTy:Yf-3fEJp?pp.ZBn]}F/F<#_/ URЅ{(< dҧ׷ѝ"Nu%%qѠA4KO>C~ /8/W_}% Yz #Ezzٗ ?0~~_JRR۶3,_'nȩB'0yulݺ;NfͰm_SόV'4hL S} fS9VG+)3-"#;Rn>TֳrhB9wݺ d~}>nvؽc-`Gzq4Rzt";fM=nVZ]iv֙y-{}Lnyx3c^}ȧS?{gĤSYeY,Z-[U"쎂7ӵPZZJ\EדovVedvi`VUpjՒ&IMul~?gąh˘3{}oiھ}Ps/)S7q`!4o@sͷ߳)WFf]r)>_lޜb?YrM1rHDG9n,K.fy}%77Y|P,`e]_AB6lO? 44|}"M*w!>>Uѵ[NίT|7''''OHH'FzJO>{bBDzw AIi .?ݍzq4_t!3Xa#˗Yo. ̟~;W_'H۶m7qU+ˣsNe}_i/7ȃ3go hӺXlG;w]|AǎDZzZXj5i }]Æ2YpJD/akë}? è6_J1 Du,v/Vx]Uº}x\1^9+B|8mȷn+f'AB+g1_]sI _g|Ls^̙/ |f7ǍeΝlKO3*a̟1wԸ1E̚=G޻;f,?z1,ˏϗώ 0ڵ +Vx"< 穵(?ol&r(6isn$+ڵב3#=UlW^p1l+-0%%X|z gnzfXX+??ߴ,+vizlێm;W_mХ3/p׹^}Œ?;DDd?ѝK:)8szA6˧nz!~z)b߁]6\> IDATjƍƨ>~raO#\mϲ|0444cT;::NHH;vh͈@ѤIVsک'Ӻu+TDD!01L?2p_Wn!x]BDr{D"EQQ)Y[2N"{k&D'(&32ƃ/s'lr3e$?;0e4!: ތ͛2 /B:;<EDMW՗\RvLj*#I-""՞HS6([4U_S}#H>8qDDD)EDDH jQF$Sq]J۶iղJDDꙂ֮Ku!V۲,V^,rj\DDDM-""D"""AD-""D"""AD-""D"""AD-""DXLӤm6ݑ*nWAk֥bYꈩWݶm[vlFFFJDDkO6Y\ճ^M##""RoddfvGT n7HQpHQpHQpH9j ѽ8G>hqh :_,xqH.BgԘg|rVH=R.yڵk˵W_ENvGɔ)1IU-vY@5lؐ;ǬsU|7*,tԉ Νe):vYٴlmΦdffY7R}F/:o^zHDDmp|_} x+PrJ-v;o.|n|;AѼy3 ^~e,,ʦz]]~)IIIlۖΨG|}Vox=!!tލ~WƎ|(o8;;\rϋ8}?X8GeO:sgu |;ݺu/WkHLheL4&L<:<7lkfO+vED iHv Ϊ4d3O1L1{SOk{}Lnyx3?86mӰA}کpEKzp6lg.䧟q6²,-^BږΪj|<7pY6DEyغmO?3 7Үm^~>;vp)'BRTTDllL_DD\Ӱ,dv:jjv'3=g.ތ zhix32mϤE@8i|Dz,G69ш?c7Cvw̫|y呞7aF֬]GffII}-bQRTT(PS92r],Q~/:KhO˖-ǁpĿw_DDq̚=x__JXXy5cQWvNw A dK]σ=Ja-w?pک0Oat^|egcxDDD|wf՘A׮]XrzaC3uDlfʴywYt&|>^E0woή{5w/""QUb,_z3Znmx^3,,̕oZvCKJJ€4=mG۶+OsNҹY"""SYd֢#\mϲ|0444cT;::NHH;vhT;S"""E n  " n  " n  " n  " n  " n  " n")1?z hghժ%\7@y/]6<Գ]vmxH22323&~2TDD\7@HH FxY&O«cǑMv[Q >7,\Y @+.1c|VYˋ_f .י1'-79E̟1c)**|ȃf& ?aϝU |_} x+Pr']CbB#,fҤ)|4a"7н[WzыϽ˖_DD>ǽsg.: g5,Aq?/ev*\n2y)çS? /7wbeL]{5w<\ޟc뮮:aY/!mVgU11 i߮_~*`m'lk]E+qFHWaT ǥx )[a߈{R4).) ?v @BcqcAش9Rj/""Qwqor=w_ʯwv*ws?99$s ROkWvv6O>, .rV99lܸsڱtx=ACf:Nz~z_6ED:jN}%;v_\(esZ99y[opu кu+GqװtY\kɿu ]s͚6%"<͛ѬYSbccN;qqED# #{y#Iywݙ˧S?#//RλuDyѺukaaa|ӲPZRRDm;ڶX_suB5.9z%Kŵ0l0|e%ix<؟`vBBݱcG;%%̣f\DD@-""D"""AD-""D"""AD-""D"""AD-""D"""AD-""DkIx*AA~+W,gUr:t -m#ӷ;DDIhߡ=+W|SBSAq+EDPt<gq " n  " n  " n  "xxzt,΀w6AϏ|~_,9mp`&HeG_q9ߗ(|>/˼~ԷoߎaCǺT%6m @\\w9Ν;QTTĄɤO}4hL S}r?4xRLaw RzӸ}dRHy0xGرCWr҉P,EeJDD^sr3gMO r}>,Gr1$''ӬiSxo.~۶/S?F ""wM\._ُ7BB\B0GrC/8JKKہАP~}4ȑt.N{';'cqq4hMff~eR!].aaar4sr0 ;ٍK.X\.^s7nbӦMlNKcU VIywݙ˧S?#///Ʋ,~=^~iqYSDzm|1 O&~iogԋپcG`itڅ+W:DD/.h{wz*Ͽ~W^eeggO;xEe\u b*QpHQpHQpHQp|WNR&HW0 HUV?Xg //U85w,Ҩ""* " n  " n  " n  "w3M:U""RZDD<1g"""?/GsV2$447ଳzqYv-òmsWo獷f׷ѝ|z (`藱l!4hL S}/7fw=:3^|i4r 7<ƉX&L>^@.]HMM7;w""r5}ܹoFIIl]O`r=zZu=|uufoF0/B\\o6 /:rxXŢKH۲Yߞ,֥.زe ))~=۷'=={"44K ךȡ>`֭if9oU`6 .b친@^/}%~˒h"9P$98Krr2w챌zEr}>|>[m` _իȠi&mOsNj/""Q3⎍ewJLL`ڵUʶoNBBBy7R- ?F呗笢Os䢋x<ضMlliҶ+""rh:ٙCbbb`BVV'V)KJjmtԹC-+;(n7Ν:0[Xz5~eǟImȡqLϘ\ݟ\.m۴૯osоaЭ ^ :bbcy8^A׮]Xrju=;n+Iym,^|6ӦLf,Xٳ8լٳ8|"%%X|z gnzfXX+??ߴ,+vizlێm;W_mХA/ѣ;?4Y,""3==ztgZp]lFa>˲₂4K<U\\OHHRSSh;!!رRQ3U.""W " n  " n  " n r$5NrH-$5iB~~9gAy4mժt8==Y%""5cժ5zM,bşiT * " n  " n  "* o,9"5jDAAW_[.m[ӪeKgaWPPu#^eY^Y,"""T웂[DD$(EDD[DD$(EDD[DD$(EDD[DD$(EDDHrim;Y%""r*(`ͺT,rV1*۶mˎrVviۦ5ԟq׫rwdB[DDꍌLnW-""" " n  " n  " n<{\.JDDѦY1d]:w¶mҶl7fߜM_P@-r=_^@mH߾*xɐq˭"G[JLH>"//Eo8ii[x?#y|4oތaCӲe BCB`!<;RۇΤp>>mӾ];z;͚5öm~}O=3YgMnfʕ\py 2Y%"uG,^Y\k 6 gYV>PZ\PPPbf㱊 Vjjm'$$;vSRRTH2*NH9n 779E/@#n  " n  " n  " n  " n  " n  " n  " p^>KC.11)&f-8oKNb#"Ŀx/MfӤIYP༾΢eee1RXTK9^xngq{wXY,"rDMp7'R:3ο&>2 74h$'Upר3rɐxUun[ IDAT9EDgA}հaC˜>}&EEEϿ?0~~_JRR۶3,_'=O:믻ĄFXͤIShDo87mGn{l2̚=s>kOÆ UXǟLf)@Y6f?K_ƲmsWo獷f카jْ||/~;.:oGFf&7!o]gǐAr ] _g1fX IyoCv ~s(;w ?Iɐq=))->Aǎ1tm4o 7_ 8qpl朳gͷ(>^߲}09眳q/):tb`63zsď{ֹِG<4jx @zurcN'%ѥ[/~:unyTrCeʔ7^i> ^OD2Lbaaa<@'"+zӠOfUkX:׿ Wߠo޼̛]/m[of@VVs&rdeguZjW_Kzz:N~*vk=Oں[rr /*IYBQr233bڗL5-7W_acٱ7DN&yo%À2-gϞ<HII!**00p(=zt&?𣉤9vӁjh+u&%%aZ}N8ɀAЧwݓ0yT 3GEErEϰ6_~mmEPU2KsE?/[6 gLزu+z?}RIMMCusoֲQT|=?ϙI ",CÑGپ}'6/{%*,Ϗz`R\Cmp:0˖cѽ+C`W0nVa$'I˯ {/ !DQi,Iԭ[yeqq0 ƁtoY˖y^\,w\C~6f0h@^<\'si8\ӧOyoGDFFڸݫS}_#-=BpP*pRy@jZ bcu'U?--MҭvRw~z:VkY%$![ZZ:Ǡ!Wunͪk]o ?qKAk-lڼ5s)v漷RsC}Shq^V{I!"i1T븵^]ʔ)M@@r3n?w%2" .pk; 22ҧ=M͚5hѼ) 7`6S;.UUJH,ȂiӪ%5WCQnWﺓKp9@Ub ={S :ȡy7bXxNu)s7| BCCy~,["ߞ'ػo>%4EQ\3f:ztJXXf3鷆K֮[ +Ӯmkf3&jUo$880NIIIaKBPP|7Tawp*1w-MW?_ 2"N}Bq׿ߊ0`+bu"`pX,n׬V`VՈ3sͽKQ^]QJ{.-PbEnŘ# m|4bB!q͝d3_,$CB!D "[!(A$p !%n!-B BDBQqJ5XBB˖q{kԨGI:%B\ؘXר޿g[%jb -9t0?X+Q[!-B BDBQHB!J B!D "[!(A$p_*UbƗX|)Gdܟ 1rs{?ֱC{&:?X*Iz%ԭ[%x[Xt1WI_WVR=ǟyQA""֫v8ń7ԩSE{J+PYW̼y,e{dn۞T쫪}Ҧ]Ea *]_+fѪM;ڴӧ;ybWU"&:?k^9,EիWM8NJ*g7k>pL&V\͵k{ oy޽whx=rg_ӻ7 S`A4o;TFF<Lp2fq3o,[)?B zu崩lX%ҲEsyuM|>SV,_ysHOw~;?| W.g'ѻWO^"c:Ǝy˗dtLm9Z{K˗+ysy,?˖0.eOXz YYY8ou^mSysC̚=kVdgZF}-VXƯӖL֭=VXO'Q^k*WgLOzA*U}ȂXxG@@6dт_QKӀ%b6E3{&K/Y?|S{b4cV._ʏ~VZO:ҶM Q_5@4mNvzq&Nr oE;qf)t:Yd wJ68zr6˖-ˇ/~iӗ-[Wti>C~gZlSOྎCDDwbSY >x\jaiݪ۷oE֌ F-֣:܇|S>&&իC/_>IUQzӛWzǟx0c4fΞͽZI8vOֵ O<-[e޽5 O~@@&pvS0ii|Wtx?>ܙ8Zl P;nڶi….׳Gw}}4mƪkGdddж]} tF%K/dzn=È2|{|ͷ4mޒ?;oEdD֢aCYj5]'U̜5Q#GW~)EQ$$UvۄqqnWL:uظi3!aϙ3g(_  AZz:u!5d<3t4i܈7|l5jH=g9vZ}aX0 H5}'?)9! sN UҽS(dB4""ЭkWrvnwx!ot:IOW=l6ʖ-KYkYn{“_TqqӫA 81{6z?M67Ic9¡CP8xϜիSF ǥv'ۓ1r 7Z:,, (} m-LQ$**Æ1p4Md}oL&>҇wߍll6_օb; p'V''HMMeDDDkddds96 r͌})=Yx Biެ)='ENNOcyhӪii(Xjj*1>iʗtϡa-k/]qa1t?PVN8 @HKO(=,ӿcB >r'?/Q7EgҥK°gr}J̟7s@a K-A$$$xy `˼y믎'>̑#iܸk.[qym~)~1>{匯=TO>W0Emʹ/>Io8ieʔYӦ 2tz~Uq~)$b!$$L׷ʔ.)+DA١]:ӭkMЧwoV^߿Z4o&DܠDy Xv{cǎ{vA"##믽viݲ'ouP2;l6Stiʗ+UVYCh׮-RBz_UoQÆ⠖^YXG;=(AAAX,˖-&M(Su2 Ѿ<Vxa aPUr!;_⁇:ӽgoOStٛG}f\b]c˕)_Jm[./ˋgqfc /XGSO^Q'Z*7Vᾎ0͘L&WNHHHڧmu'm2kl:sl{~dDFFr1QrW:q$'mwVslQ:իW<ߴy3UȪUǟL஻ofݚU̟ 5kdР!y~5\X׿K٤,_*Wfu6l[qPh߮-۷(rOzWT1ٌFE  _בǎ%00s3sl-wI%_!FOQXr*1w.TwOEPaq#)or!-B BDBQ}\B!rx=KuU}Q:kB!.ۅ طrVgBQʅB: B!D "[!(A$p !%n!)V;##QB!DٲeO*V_;x(UpCYB!UC S*pBX !`BDBQHB!J B!D "[!(A$p !%n!-B BX`B{G?@Cd|5Eg !׌bC{'s/hWE0nBhd|9EQBkB#UxA@s50t?K!f7 a„=5@5yegȠw?g0jpRR0u ,!O(ۭ 8pg{_E4j;իp:IH8[\/!++mV,\īĿCaJ.E\Zlظ?Kq kgSҢM{]ɛ'88ؿ : IDATP,nO^rq*UH]JK;IF4Nd!5qa֏<һ'Œoƻ#өǩU&?*T &~:;v'ǂEe|:'}Kdsiۺzt#<<{r:)ؘM9]`篽Lx]Οo3ds9y=wSnçz:Z6oFn]Zr:)/}M=y!Ԏlʫ9֨^rdff2w|aaЦUKV 4ov/YYYu|;1qǟ|L^=n=1 5jWxRRΰbjƿ"11|tRΜaȰ "3# `6͚ۧ6!<,}O|X=7};oN:۾FozuiҸ!!֬~}iټ&ʚudgdgб};:? 1VΜIe c9qT/<{3iѬ)zvtdee1{O\f3#}[j&88cǏ3wx1r,̙ رE!22=sL*O jo^<7?2Kƫ0s{3SƸRL-^B<뼮Byn W[xx 䥱=ecbY:<$w녪 M1z, {>A`⧟s!&~:z:ֹ䍷ޡd>?T `00ң7t'>ٳyTRƫ:i۪%wlY_g_tz+#˃ƍ^eԫs &Ԩ^zco^9z>DRR2{m֭Z2}`&.CL2ٝunaa<й;۶ 詟!/O>ޏnZ>zPM}IK޽;x!Ƽ 'O%r!f| :=~+WE\ f cko@n<=h(r>9NV\Mǟ䡮=HKKWn?7ѲEsz4n#GHH8\> !\~__3O 3|h|':Hvv6 ӧXz 7oLj*o򕫩V*мYS6l̹siղ9K-c9?QF ʖlW|Gvv6٬[J*z.WYt0 v6Ӳťn'OM5ipם(u; tK0 NJd9iS&14V0 =Kil۾ka6[NJdӖ-4n[v߆ /r]lьo8N~#rkݺޫGs7? YYY8NZj?vgQhv/,]t:9r(ar۰q3{ ;} x4@tΑxړyVΖ)z/^M|E,\}B\=ϧNg=ܽoe|}%~[OZPP Ɔhټ3͚2X˖wӼiSO,J @Jʥl"jСdZ,[6ݻvfЀ|w_ȿVkYSR|Ғ#<{W.9CZ>iGfM5kpwiV~'CgQ;|IMyt8=mmվaBDD''|bϠiUU=###k>@/7,a ,ݻvO?'~Fʙ3DEFһgwU@Rٲu37׎#147լK B3lZZ:{g^%.Yd? fm1租:+ҽIKO'::'-&6Ƨmmlٺի1LPPev اKipם4i3LNoW pYFÀO0x@4M'a^OVVd wLǞ۾c'>ÆMVv66ns4/SgyfHN:30Zh'>cيLl2cEDDN%&?5UުXƿL`` Y,_[ywc=ȿH._~-&>AUUc^ ~ɧ f0͛5%3#e+WW~^P/>x¹sn,aD[DEFǒxWa,[= Ǚ߲b*>h'dRyG|O0y4|:ܹ,]V-/]vqSm-˶헮;(hWWvޭ(6MR.^p8`UU-aars'6z# P>\ mZmV !]x~EQE~ gdd8TUuX,nkVUOHH0 jĊPvڮa L\CĿV!ĿuM3ChwU l3Fc'B!JbNtq7P0L*=hђ,Zr%!b5L+_B!WB!J B!D "[!(A$p !%n!-B BnEQ (wJB!?rEB! B!D R,oy*%(Ԩv#?KP/^䯽@)>([!իrIRD M5{>LWZ0 Bq,Ar:9jիa:tYsܩd2233 UUȧ!6)teFffa2֊/+p !(: bW BqBq-B E {!$$}BbȐ[]NJH[!C;<<> !򄄄{)R̕q !S9wIdgg숑l۾?K|\<{F\\aZ !D w=F숑:no'i߮-'MOE`Z8#>>>,=n!R<^mw0xhҬGHp0ÞJƍ !%%~eW_ה)S'=4 *2mlٺq_dJ-Wȕ:o۾ d=JSbB\IKf)#n݆ ZjEppgRSyرc{=e5!ՠQKQ-[:c9N,YFh>Τҷo~mZ{VxժVeҥ~{} |FuݻƏv]w`BOKzu9r(:O}iܤm%ZtދuBU}ĕ_LzsS}IVm8Seʔw~eLoMx֭C-ѫv`c8pࠧnIiB!5k4o֔_!Fu6mLXt5kԠBnՊu7p9ڷk˂9|?PMXVz""ʐT/%%'3ΙT~}+_oݦNNVVYYY^SQ{8z(˗0 ڻe˖{5nԐӞu7wNJJ 0:vhOhh(Ǐfy2T.WQ`PkV.OQԞΝso/_=;oM遃)EGRFuEtR$'py֬]G6btZjVkY7jHV.̢TpRR\Ξ=g@_p`6NAUt`6FtR' 9907Pfp |i>҇GaLt2SKB+3M.ĩSLl2ӾUUyH:cyjy)ϟCqfBBCظi3i0sM);vҦM+fΚhw:P6ça-['TRǩiO==Ы%qDEE2H>1/ !D toTxDDD_Ndd${nL}nڼKh(}…= x\6D\\-n_~U_j jRFuy*l aFn i[h_f-U@0͘L&WFHH011Txg9uWj+AzBq\Ŏ٭ST).\;xa̋|$>gϱpbڵm㩫: -wt˓eV>#^x~dggf:v)㖔LǟSO}@xx86c߾s)l r&5/eX%$vzPyzz:CgA<;5J.+/Ddd]ɗ3 U>^ٽ{*URM&EQ̺b2B u=Җ]TBzf; pm;gc4wbzƒM(MӴ UU3v]UUaά,-::Z;vaZ|&sBq1@|4lx۷ 33nL۶mx]׫MB\A$ء=c^M`@ۘX_$[!( W'gUB!D "[!m_q[QwB!5n!O˵+B!|]xEBp1xC,1h.dd'O㯃j9ww:Bq`իUUD u1"DQ~?WQC40 f?}-"{0U+Q2)jJہd2qn7,B\%`2s:((FNd2/[!BB]V;00UU5 tsB!5JQ,=qp.B`FXXdz6 ;;PUOB!ᎏٞXWⲆ #[!&O7yn6 (t: MӮ؆ !M 6Ll6 #,,ș.TwATU BEUUuO/x#..ΰZCBBTf^dM&n!‹dҽ322 yg j|wAܷl3Ln7f24B!dt]4MӝNåXz ?,,sd2233 ۖ !^ ܽn٬gff!!!>_;/AAAbs&uM4t:L.B\N8p聁l6,no=eв@]up8TUKKB!ΦA4nw꺮kٺL-o$n;ԬVnZuݮY,bhSQlxH[!LR"I'EqNŢY,nkZ?xeժUfSճgϪAAA&\7q1;@EQfs(za|UUUMLjcEQLrzn,Wved2ei(JYu]sMQaN]םfn:GGG [qX-99Yl pL&k dej(#SQLEQ2UUPU5\QL 2 îj6QQ\<բy4;SWHq!%9Y?,hGQ@]f{3 cXiفف&ɡ0 gVVymъPeժUt҅/t:IJJ"**tEU]2w_|< @7 C3L]Q]u0 P纮df;:y^ص^c2.^r)3Ws9B7/o)?ٹj Na&)SQlEQ=na]AAAUUNp8éif=11'h{k96Tx#>>ݻwp1RJZrrr<4FFF:%00Páv]5͚ls``iqޝZ80?0EjJ{x^!D^yH | WfAE.iSRXw NM9ߦ3뺖kt:u]םKWosZ+rADGGL@@b6U@PCCCMTɤj&ݮ+bv\#N#.3⶧r}(ڢo5#\ދ!(tzTx\.2 C7N0404r.DSUsZN;hk!!!fӯ:=!! ˎ:}Zzvv\X,TNsV0rH'((Hq8&EQ4Piz~` YޭwjGV!D;%DKϽlr:0gIDATii!!!iK.l6L2={{n}qZ#g!-)))z2etݮeggkEw:,it:5M4]5٬뺮,u3v]Q=7,.rJ^B q%wJ ,;((@+hkKRSS #fǗ\UUuEQ ɤkvCUUO, 333@#<<\ 1CO浽#>>ްZ`XV=$$ 2l6nXL=((H7L;pvCӴ\?6iK͝!+5eEYd)K.| 㗘;`ݏfp8L###0F@@atp:s7cǎjxzv]w8r7Nn\-_A?tBQ\ >Ofq'g4z9N=nvPPon=;<<\ 4{9s(tm^!ŵdEYdx--qc[*` <'Id>OO'zC#v8Pb"Yr.塻DఃέB07,[6sN{?J-dӧOEG;Gp&uRr{keۖGlE6;z=nit:է'urx}ܡTU]^_\k:\LLLLLST}ڰs=Cj$IVW{ewŽp*Su{Mִv wڻ q6QwhEP4KpjTݽW9or w~]+Uok#w׮tym#Њ^1ʯop;gT{<~jj{,kjDj3btcwpok˄:vxPEU]af#o@46j̖%բE.2b[Vm;1yv^,Vg+ஶ*+> LjlMp&QwѮstʂ*vcȉ3x"8 𾄫mHȃ{]AS`Rfۊ* } uʈD]f[/{@@z|D͡oc͇h#}G'3l}A 1*Obxc*S2pEZf{] ^= t<]4q.d~_{Y^iYӏ h]YV ]NFT=t4ɗ/_Z._fFWgcHG82&mhTb㝫g)8sykÑ.[аC; @ @ @ @ @Ht_2bUUU97p,cLD @DSq[kUD,1F˲TU$ITTՃ9L7Q*BDw,ųM,Ղ{2H$ZĒc)o,&d1FZ9h: .yY'""ph_z5MSt:k`]UM 4s@dTySmkZk5˲U u:MToooRmSˆ2{Τ,z(eIYmq/b˗/""r{{u9ͲlKoڍ2v: vs*\Dt<p8pؘap;\1Zey?ײQмh4ݮitիZEQ1Fse1\;|tӓN|SY;>OOOSZUTU \/˲EQ4M˙KXpF#Wx,~_'7Ee$, E$lux2h߿H_,©pKXeYI(Ƙ,nE.EQN"sODonn`0LIDUp8`sy^fY16(^zp-9k<{_z22x<`z}{-O!.ߴ|>/onn|1>t:M\CQ2j$HqssS|^CӧO㐜/83#"2ϟt:5?]u"equ]UEuΥQՎ֖e&:㽷IU5""gE}[ UYFۿxmc߱2htaɗA\œ>w:,aY? /e}*ҁz_><|`}zt:.wQi$,Ip[sn-]zཊu,S,wZ˲9/EEQ4ͼBׯPmiuՑԾ~www㣊:,KQU_,w$I,1C)ˆt: j}TAdqO8%w|9&/۶}iyϝsY]eמo4/_m,+mk.MS7EQf0cS`MɶrgIŀ`>I_eJ;h|SV<>>p;2$KԖeiʲ4{vWl rD6:o7~Yk5MS?},2C#{0$I\Q&2+"vHq~bLEUdYݮODgo 톡Mmp{+``յ``538>lik?LtOh=k;l63Om|f@u:Y)t0~;B[; `kGl6[mey jZd-ݮ} ߳ ۨ?lEDөy~~6!Uc/ ㎏cz2f|Kl*,G"eX@EDBD"xt:X[á, v|[\D)8V |1V vk6u!xu*[׷-8DC@[1^} _-D؁/"8w$TIENDB`RaySession-0.12.2/resources/screenshots/Screenshot_20200625_142130.png000066400000000000000000001211011417052567600246730ustar00rootroot00000000000000PNG  IHDR2/ pHYs+ IDATxwXMOh -4 g;{;{{гT޻H'$R X1$!4QÓn;3X@ *xE@ >5HD t C $|ҁ@T:!J>Q@‡@ *HD t C $|ҁ@T:Mp{β(&z=;wA,^~+VNIM!J!rr)VcFlܸA=.R!T_ɓO^uk5a0nn5k.`]Ԥb+>B UMeEZe>D,ׯߔ>s@ЬǓH$Ϟk4ֺ7JU/x݋/DA5i⒙Q8Π;*5m[is=~2as gyyeVPw p'8G 4i2qqtH5jty)s^[yF*U[xIi2S,#>&pDDDh4&`QVVV`z>I,qMo>RʷWY|a0 EGGK$>>U_^nur=  Er{JBi q$s/s@R2h۷XEe0>\#<OTgXgg瘋Vx0h4\.GՕ򰆅1 :<9%x\ukϝch 8pjQZjZ.\;~t:`0q P |x<^^^^^^KGox  ktjb2ꡔN2}Ϟ'LzC0LQsׂa7|P{m##* {,)r07 SFZl1 lj[z3gGDF#" ظQ?ӧ%IP?Æ4(OR*,+GGѪ<=H+w{Ԉ;;wqFc06AxDĮǎj!$IXhܚ5j0YǏX:C._Я/HII=w~rrrl0lAW=#;>t`&alŪ;w͜>Ϳc-O8߶DE [lbYFFM>v_%tY˪7nJMMӇDU+͚3ӧkڹgß>{/"2vZV-[0 VۼY[f{?A۶.Zݿݦ7}z?a^A}>-M&ɚ6kִir`0pppXfoݺmoo[a't4oy  WQyGW^k4_ߚt&ٵK3jetW,z޿w苗.3~}{3.>>N{v8?Iz>ko5"-#: Ϝ>! l6F~?` a,&0X|ӧ&O -?k\0O{a_V 6t2&ٹs?C͜1߀^ǎE,s姾/t`&{׮ߘ7gax֭SRRjrSSӚ5w_Ю͛7i܈`4j{ɣ^:|oM]\sU񉌊tsǽ/0 $HMI4hϐˍMi>>֭ g9zk+W@PGDxx_ . YY pB9zxW[{||#"ZlAGvF||DxfJ>rǏW.[r&F)5MzbzV^=6X\n{(J޳7}E$y}Ϧ>;t[w(~ٺnXᣜbW:ƒq 6e]Ϝ7>!a܄IcF<ӧ}aSZD555M$t?K?X=Z B:99fffq ҂VLNQ("PՑ$9y5NT4yJϝ7yCIQ#{Ç6l$IO_~V\&~ݴPuqvR*WQjj*ZΰTZ *+E.4 7w-tZt$U K9믿͜9t,##)9yҔF1e;;ókV̺sᄍ{822^غ-(ε7]פ񺵿W_(׭Y5L5d}NNɜ-OkQ 7ovO]6yyyWHHqvvvRԑ8i.5//o mf7mڱ3.Y4itNwC͛:uNY!\= LQTjZH$Ob%ry۷:w 1 7w-^aj吨ȨA_oܼU'0f~rM$cb F`ݻrkܨ _&Iݺy{{qTOz4;;;Phkk ɑQ/ s~fUofM@ rHhqkӳ]C)`8ްAY3oy =d!Žyvq@(\|k 2ڶMk[7`xzzZ}.] "Ikl64GG :0 17n-+\]\nt-򶭛]]7ɐ ^=X,pHXkQ*nn&}e4 ~YAD2o?͞=s:hFh޽׫G߶NG~f߯O ÉzhRvFUo;T*>1}mZ3*55nߩ[k3!e[0gT6wE S$w]3V?n u:J>pа;2GpzO&0wF[[[FS.?(==_dl;33+ͳXB?^?:({~5 EQ%픛ktFyy@L&+U,FJðª 3I,LVz3rQgg[vB. 'y1t<LP* WfkȗXV%> whvRܩb5 =qPDdԲ++82M]W\./Q3s@TiiQ@K#J>Q@‡@ *HD t C $|ҁ@T:!J>Q@‡@ *bfp7@ \H$u&7hA|0bUD\1gP /߸cXHW 2 >@[b$q‡׋!C $|ҁ@T:!J>Q@‡@ *h{Ip‰nlzLF@:I>gE0Y #,Bݚ˜U.^8\O@ >O֓c3'Gq('F88 µu`8f5@ߎ-dը]|QE^`"OՍٽ}n֤֜B _ [wdIIQ's(Xj?^M()6uAC 2 QA;w "shРukN;oeK4n\nE|tg .J^tα$øU2ٖ31g5gj>>k׮~רa:ǧϋΞ3#>nnj|<_ܢsj| =ׯ%''>IFw+B#>3p;`2͕`9lRgDwyQAl/" SYGrԱmDO9nTYmAAW^iάΝ +++(hGQM7z 8߱ԫgȨ!r:LmҤ1\vfd~LZڶx/_FiZ@ЧnnҤ{brҿ^PT`0K$nn׮sdO[ ҍms1W%%uRRIaN$_#/Do?c+HO_/b#}uQeǬ𕲏]u7:;;T5{oVwϯI{{4o,##g۵5fL42 Zlq-V `\NV{tֹs9?Ç }O.P(:8aIo׶Bp8ܺu ߗB=&k*fEi,hü cII} ջ_6)N>{Bj>Uj֬Ѯm׮ݯo D)pˆCS};RuZn\ѣ׾ª2cVg2Ouk!I*>>ءI]TK >ߢEs6ݦ7a=OQԷ]@`T*7{@io*Q#GzjnnW]S(p3ШaC:Ƀ噙e4:k/PP(o߾.Q>>S\kӧOsf"IIIz߱Mo 5lbbғO;vSv*^.{hZ홳Fr{;#ju6AVmNJ6La@ۉt4Pu!$]p^5'Dϕ_ -1cD=x022NCLvڧI$))˻p rֶkrr#,WT|-W-)dj_Nۅ_L3I]sE/st}o4j)?ӦΘ65++ W\.oaG|(nٳf0$}Ū_SR\]Mr*jsf͜6urvvvll\j>G|nioV* 65r Kz=ϣ:'K#NYC j׮է@}O!`ƣfd)h0 CB1a^={;pzvuFaisĉ|a+U饜*zZQrlUTiԨቓL )/f_o߾( 7o}Yh)jZ:c_a^NNKa ~Ln_\ʂfh̬\_Y:+ZH%͙=>|{_wĤ>{AQԋ/o΅(';;r#?']$6"O@fk! =\)βT(662kӕ!8)>5ueBHDseZz@T:!J>Q@‡@ *HD t C $|ҁ@T:!J>QzQ^}P< gO00 CuX\ k˂(E_z0 p0 1?aV~jz%Wl186l#@uX\ k˂(- 0,?|0 0YO&߻PΥ_O T`PҪWJa=ݹc[\m,@k_}E5u1La5 0ώ?]] 9%ljS*8/վ"&5V%93#g0E.])KaU/AcGLHHQڷݿ gO <0S.ع{Ng^Y_kRƌik^+Ե$>${$z* ֬ZA߱ݝ;̘h`̟;ݻwqZ>ϕR%־'3T:h>Q^C_( 0 0Ia@FQ@FR@Q P@zf+X[[j>y^/'D77gKqcd2'<=kժyrhճRis o$[2 -<""<"b6ð+=reRFu{{;䔔of1_i|>)~YSd' 0pŊ}(̒%47H>vp((Y Q@ezգu$$`tL8cݾxz*}'#UG$InSp18TeGgwuuui԰AQW]6ketϚnBBvFGQN4zpw4II*$ae9UZzuΟlq&? |Ӝd}VbeW!|fe+I")(Z dH G^$| "#pcƍd..Z(Ww gqX׮su$Yd!6xgϝ7:LKͅ!|>_hvgYyzoߚ5煋Z4R@ IDATy.>VKsogo}^tkn߾gggg&|NVdl6 msUTA* < 8NNN0 xz!C qr` xժUxr˫ׯ222֮]`|BPI\]]8.|WWDFpܒsrKS$# ;-= 4IGpZ"Պɣ@Er@QYz =(H} `>:|c@bhG榪Yy?'V=9W_4^f͘M"A#$슅p=v4Ь) M[.^i߶qc0xk_~3 M^~;޳[vz0x mܽ 2efB<|\?֨^m̟!-[6oҤѡ#9W`]vmX?ۢyӧ0933Km˯uf~ӧNf Ƿ:773j6/_YxĉQ?5c۷ z>qʴ䔔ƍ]2勤ds8d2(H~ʵ^|9a4\w/]ZvïY0LfM 0iڌիoڸ.6.6:Am 5mtrHQMc"vu{/##b aH߃߹{#¿ءfj:ҟ<|tN2i_Ιy٘WB -yߚ56!"22%5u~OQ `0 ǠpELV WΆxҠMjѢg8A* 5bA``iSx\n%`0I'<ۃo۶mgӻukry3|߻'&Ok矣F1rdLLLRRR۶mϝ;ۼyoߦ`_E(p6'AwIP=H A?AQ$̢J5skVx/#3a 3C[rW.^:!쒉5Wx$ytv n߹>>5P߽i ÄBttt :\ MJJWo߾ߡW@w˘,kzzag5L}|^Ô( X,&^Dd3ڱsW,#p|-HMMRzWh$F GFV:m朼<-dd%(\!F+woPxDTt̫f͚>sN:vh[/'jSS{h[hID^\.4jhÜK"=wnAy.T(06 /GE XvRXаo;SghMj\ Y,rsq%aRˮ\`AL].666ܝr>T* ͅ!tpHK3^ jԈag<rǐciY&õZAd3y(}`nn#GF=,dv>'>eKIH(:LcI*AR[4De23 e PhJ$:D.Obxr!!Q ϭcЪ5X,& ΝM_׮[Ϙ>0MNp<Ǐ=f)S\]]/_*Qϙz˜\HM6  7Րܬ*[.AJ$\pp0R,MNa]]׾]sH~M֭\ip#"G?&mȰQ ZjixrH9S԰ W*^[jѭkYryVKTJ`@Kӯ^mM?n߽[w$l6+.}RRҰ@3#9%a^VT˷f-ߚ=6,jիvR@/<=M^QJt>svjjA[|dΜ 6 ޿}ǟMĜ:urI9V3T ?j贴4ڦ޻g/a:UʒZ%+Ţ>>i> < E8m} P`auM]rs k?~̡p-nI 0Dr廮]Q.a {` &v- sF$'n3foݶ= GSgg?q}:f蕫={t;{OyRp8[msOOxzyz#W%sܳR zlj=rl{ OO-[޽[|匩SN9)34G֝6l:~5W;?77Gqq WTЎ]&+Ng,fӖ z֝*^^oޤVx<~dԋy [_ccƍ>uJ֓Rk!/;88dggWXacc#i; yZ"+K,vZj׮]jc%/kYD5UF ^m|-#/]F3O$O$N,pYq4ҢeKg2%kdޜYi}r\́aZ)j{B, rE+i٢7L:Y;BB<5l`VƵgͥ?u`fggj&;;[Nj`kkV WaEL , Tj9_?}ּ,޽ZZ*M_pիWN1:GGgr1”,U)Q8c=AҎZ : I8i1gR*=H 7 EQ2G1L4GՖ@D[xܘ7nܴۼi}n@<{|ي_,ez@Q4k*\"oN }Jep (@uX\ k˂(Cf+ (xO/ ݭQ}UtAEP_1F ",QI@{{#J>Q@‡@ *}| Q (ޅŇ@ *HD t C $|@ mlm|>T*$Me6AFȈ6]U(ɤҤ$Z6TIJ?˴i8봴4pvv^ĉ6oޜj![_ %95k4cc˖-%>~%)1i<^CXږBv4̻v`D|DR߻k:ΖJ j4&:Z*M/VV:zh``R4<"Ǝ{EU}dÇFJIWY%vJW\~www btwp؉s6lذѣG=:22B4RiӦ/b\WMiORRLKMuswTmll@VWU©l٬^*ʘR V"rttx XB铆hGݿ X=QQQ?zhrr2X$4 2b1qƆ$ɔd"L>y.@-`y̔S]r"N`ǻL8!%ۻjrrI EJrroh ѦMvȑuȑS.\ibh{GdB|<:0NKINfNɭc t@-;Z߉ҒE?aqqqohӶ7}ngΜ~=ҳgW̘>666* \{׬Y3##ٳo޼@wovU^vݻ|zSFǎϟQ9ccG L?ghZ[ÆjʫWcǎqڵvjggے܏V0%.66))L+F3ekWllr99riS/^h.6m{lB;g2U_>lKST)V72hnn.29 W H$zZ[`0 c ϟ?wss;x}۶mٳ=(hڵ\3}ĉɓQGԶms6o۷s0c欖-[zzzZ޽{daR8aӧOjɓ'OKd~_6uVpM~իVSjU4=9ٸ3p@__իVrɟ^xnܸaΝnnn.tŋ Xv?9sL@`o2dhhhQ9ccc9J7uL&s뗙9u '޽VmWL|~W^mvA Ë('''fTFrr4-Z$g^ڨQ? svrxB^8/DG'ܹq8͛_pB/(/ر(H- T &W{{{CpߴUll,AÆ4yEB0 Q&E9rRSS/_U[u5}}r,H$:~Xff&8ĉ͛7͛t?<"_NNN7o>bN<߆-4l˲V}ddYҜ-"qrr*LHsҿD"׮[Ϙ>0zxhG3yWW˗.0eiCc`l(-] ð=B.+xItLN2E}rrrݺu|>{]1fڲmlTުJ]t2e&9)j2ի tttܰqׯ_#bرFIDZX,oookڵu:] ȄxǗ.]2r_7,'If=߿(7j@l\a>i*IK>cFq u#IMɤ>xGcF?=׮]/M \RH$snذap;l4&&ԩ'M:ioooJ-Ϝ1ǧZp.Z IDATQFnn{0SJYXauzd&#St. X+NOIjvj>(JooXQFсW^Qde͚=[(}ѣF@Z}ƍ;7I&oݺEw k~1Ŭ]8~X߾6mСC5}kiѣ%(>vX>}vСlаLS"4hpȑ$ILؔH$aaa]~0|Ĉܓ'N;3DBѓ' pQScRi*Av/29AB‹'44tȕJ;nٲfHII]W5˗rrrhCu+WtO;vh/ ZEVXVjծ]cǎ$6 Og`z6m0_bbZn޼D@ 'P,p\ r N׾r|„dqtt2LeG0oZ ŠA/]غM3gNoJ`lր~ٟ[tFt=P .Mm *m@  llTŇ@  BF|iE@| iڠ.t C $|ҁ@T:!J>Q@‡@ *HD t C $|ҁ@T:lڰ=EWV"9purrR$4EV뤖ZSy2D lOOWW1AtKJJrB|5;MS׃7uus>6qR㸇XW= b7OO/Z_#0w[d!~m>=7۫ack*q4WzJ%| {lV Z-8SJQ=JGDs Xž{'MO].NLvKaÆ=zё)M6]x1((H,jJ}*JeZj;8ncc*LJ5IbWa):jA sE3oJss/]I6--RR茨"eaDQqfԯ*( nSQ8UPVEPhKK[MӤ@&vIMz/_{ι'yJP1͛i6v-6'V8~Ѹ kjjV\䓫+N'VY{wWfϸoM%I$dH (.ƅH6\CQ% Վj;{p>0=k>g܏?LI zoOy<`…џ#J BP>x,hii~Ϟ9'Vr8N5O?$5-b+-ZB?ˍB磵^rcb4aa55 m!U hYr\.+JKKv|͟M6]vlټ7ܷoժ'sssmG>dIUUUsssZZy))Skkk O2RqxAΐ$P鴻B"˯HS1Px]F&ڢ'L>qAQTBBsȁz~w JKK'jjjR zQ8̺/kFFF,7$ɚꋧ~|6c{{p5 <>hvl{Z7jjl|w:;:0 C%D_Dr D'j}7̛21q}1q8Y M(W e0"6kas99mh`d( hhFqT~4Ak|ABG=8vH$fȚfsも**[8:v[o4][[ ~Xn8vM,l{innK111uuuCØ!wGy|v{llܱc"jJ]tp?X,>͛#t{CC}~Gn䑥(?0믾g<{5YZxV ^CN (ar ERɡhr(] 40˛0l׮]d/}5Wo\rkΙ>绞}w}ȑ#wY@vŋ'M|cV}xxɒwݰcBe?,7ADFF87(ܹA8.W(jPPPj*T+LqF_Kkk븱c?}vd>_~Y&F;|pt\"Iɤф5귿jݻwϐ 6< 2|~+W0,/f("].I$PMEJS4 IW@2MgKΜ7v!ć~ޗ_^ҳg|%-m/4iҦ?x0^?==wKOYK/eegG;wr3 E.2ZpߝY|yAA/IsznZz%$ ~G租Fb74w\V=uZŎ Wj4mI#y"y$P ]TB0[I'@qTƥN12 ?Ýíx{>/HP'\.W. ^ 50L.F6׈@ 8i"oK:}g9L*j˖-;_'&&n۶mΜ9}GffuB}ujV! j!y?H4QEg'nZHd4;.$]IMRr04@C tT=HĸbR}~t:$וc4U=``͏ᨪ0hOA||BeA37ڞM6UgERmڴ瞻憬zWZxoL|zoP2F,NKo3hYv[rPNM3 C1 8~!=aDl*kAMMPYAd'455|l۶mϞ=>ٳm۶B_"p6F{F3d; pWPm3Ff(2Rf%840  ``6®c{(^퉷%4d8E5Km۶ݻ>[J/X`'5 $'EzJh_X;\nETYI& mc@aJSa p - X 0L 3_XX N92**e4AtVtK$JRPD~~),,3gի󋊊 ;:: $$$&&&+++##_-+89Lw@(T B(p:v @\%u:{{ɆbcR[[|Fj5?$[ p^dmZӚ{G+|,,,#VXXXF𱰰8Xcaaq2`e  ˈ>+|,,,# 8>qp0wE*TћÌe81,A, %%jv2>7Drnw\E0 7 0y* MEx^B`0|,,,,D/ V9IBtwAG&|8wwwS: Ð$IQM4M8\.\.0Q0#0 ݍ8k hP9A>o0L/[/a8DN'pGRpL&jۗ8Nu/p8 Rd7f̩n ![/h}压@;Joܗ7[>b&J,&xλ^gHJv],D .r[yjhΌp.hMMMEEE/yG *J\.8f0:N_vq0)mwrQk'N=ȌCnhl=f\e;|'30dXdVs\0 kiiALJ<8 QTk֬,,,ܱcGuuu{{;dff\pÆ CV DE+hnnZ-|X,Q*HA]nn~qF^Gx04C p\drf~ 0apz9\.{1 {3Sdee+{Q3ffT^j+VmֶbŊ׫T*-A\ܘ2n^81cny}eVVM9*k5}y>`h- M(a GDDH$"I$ID@Ӵr:(z<0 B4TPPPpp0zk͚5w.//rw^zfQQZZ}<1ͭ--Z7m_s( 0zBAt:]llbZ|>?((ɓ&Ӏt:]T*Y$O;~h{֬{+*kkkH)ˑL;LOO߽{w> 6ERPPpOhnnfh|>H0LyY*TjGmzp(QѣjkjwT*Ч/00022*łr NԌ7t,M &|heA|. M)rQGkx1 lz%kK_/,,,66] f1 3 E($ӧOKbڌOф<͖6#h4Gf曼?s/FFFVWWt.Z{vduuuxx@#E"˝ bD>6h݋B~ISSK <,.륗^/bNɓV=! |iǟ#GTXV=H60ѣc4aafx!00pݺu1cF߳hY[|^8Nc㴴4RyN:8wuj}gwڙ:_n %Rx+V+ߙuĉyeB橧2YvV?6sfSL0g6F ;@7D)ry`` C%[PQ:KppT*EQ`  X{HL駟~(..F/:t+::őG9z{XaΟ?% J#/|cG(7;E:M4P_o>tٳE׷JraDֆaw^z=IB媫shA" Bŋnz8dӦMKIIQ( z>t:;:fj0pek75矆0R}}}LL@gIEAہ"`111ȕ/vM, ܈%us\||BbKJJbY~455Y֧vԩ<]ZzgΜ;iӦ8q3y򔔔UZg=z4jԨKOEE9EQΝ+>Tx<_gj|d2p8\."s89ht{:Pc$b@9e6j5O# Dn7T͸q:::PC kZvY ޏ<9LQ\\oÇꫵG***,a Jp (. 'NuY,^{pqqII/(jϯZVVAt駑oN$m޼aC[?P*}g1_FmTU*]]]yy6mz_VK(1=>a|>'8fCi.$DeP$zG 8NQW.^t:PX-v6M.#[3@D E.jqAQ'Nxɓ'wuu ;f&ZJ*M[l٠e2YFFƍj@DddT<?8_cJ"WwAAA6 w>MP˅ <Lk=ԚΡ!`6׬^e.e{.00h4!_~!; q8r|>G-R!$ M&IVs\$H Q* <е:::Μ9;vX˅ϥ~ҤI4MwvvZWW7qDQRRRSSV544xpOJJD듒~_ WVypo/_KiRn .ҥA,~EF&ucXw\}C<+~a¾Ng/uD9y|v;=Fzrm6M**((H h4٬P(\ӧM&0NS"p8с f;z(:GΝsxbmm-Iގ|v 444A[>|8r俹K555SYɵP=Ć wߝ?ޯϟ3gfuu&NoڇL&S5OW/x*Z[[' ӂ%)nr;fuuuL6kkkYp8(r82$z>@zvDG_:3fkzoڴ)''-*jӦM=ܠ]GU3gJ|w  阮OZ z{!(wx(g94t:}>[OAAAXX؞={x _쾄۶m+,,e| Bar2_>L6.>߽i)K4Zׂ$BQ^1݃`Z?'77Wo۶m޽|Aa@,Xoy^ooKjmmih%:]ZaKld{B+|>r;nsG3y0 ZHSΙ3gEEEyQPP0gΜ!l6d ӧ~J:@DbA|>_,(JBAO7o6qTr9-}]xC&=ӉN(z Bh4"CvCqFJOOt%p}D * B! |a /1I)􍍭-7{Fh"N|˵KӄG=Ar[q8ł|e]݇VmP gw=+'N 77uΜ>+|"E/<4m4Q0m N6Vճ rKPknk ‡|>f_/k YXXXфBp\IC-C_a3HTr y 4u ,aaaq2`e  ˈ>+|,,,#VXXXF𱰰8Xcaaq2`e  ˈ[N>rc2OW6=vl@@@NNJBYhGcXX2J KkawGޝ7ዋKOOOHHpyyy3sh>HfCvVXXX__"IpwP聮֝N9ބOVō?}S $$dرƍ>?zxb}r={ևdaaa| [C.p V[|Pp&LJ{nͦ3~[$e w|%Ď%͖ h4;3###<<ܽZSSSQQUvYS*r\$p:6`0t6aRJSS}۰ZhOk{V__W_W7 A|y]3\.2SM> ERY&33pǎr 6 a_]QQ V/KJ.2@uu+ UZ[c3}Ǐ%Oif%34`<lVXnM^y={dggxϗJ>׭[ "n֖?kgl6At8M4 :S\ҳg}Ç>[zhҥK.-++Ҭwo7oެhrss}_ ׆?Wj64(%s\|P(o-ïѾKk$dT$5 ,75*zFz_].]]ܔ,[,;;ۗ R~Lwsc6Ϟ)цG(J_ڏ)!QQ~u,p4MW\W\4}wHN.0v :+|,7/*ž tQ_~Ŋ~VX~zJ彥@ SQ^m QQ^7f@ -дj>iOq\.7((fY, >uJ8d:iSRR$ԨT8.U|'YYYb>W_ҽ(;;{(B0D ށrzeuPe B1(Gw>̳{fBwQ\peah}~di|/66VPtt=bbb+++3@ q|ruHwnSYVT֐.R.#3wvUUe3>{~O}6lh (|rEss7/DFDDaT*V;jTnCPU[Sc0DEE)ʶd=FFF8^UU6\n|B鬼p5cǍ#]_~wrs tuuiZO CWOpŋa$I\.EQ#zo_if|Y Mؿɳli3+*ʍFcxxloɛ3O2lddduu@g\E{oΝ' aM;H$Fg^R ~ISSK <,.륗^/bNɓV=! |iǟ#GiiiJ{IK/tpٿ.̳ڵ3uzݺ+J777N_+Wp8wfg8q^~YPy)L㏥͜ԟ${{5ͯN\.`h4GV1 s7hii).....pرcAzȑ"6y .:tٳcǎuwG-**jii?~<:??~<**/d! ;9"][y?,Z.Pg~JDnBaRR$yPщS.&SwSSӖ EIII'NJ[}=11II㋋8Ý*馺膆CBB*++`&\.g?^O4 Ǒ #v;455In}}}llD" .Ƽc:)vVўf_=bu^Wtwwoܸq׮]NuCBB،SfuE\d#Ǝ+>\ EB|>^ SP4EtC}}ҳg_z+q K@r2l6v[ ø6nir r=KWf4*zq&o# $|$Iڵkƍ^111ȕ/vM, G?jObpYfj>絹l٣˻KK}݁3gO6O>FL|W_vKVVVQQ@g T*Sn@PvO0u0 X,⒒_^OQ'We_y,O#ߜH$ڼy 0Ň~T*fϞc4ۨV^yUǻ'h IDATlJzŗPlc{"ˍ '|GP,^h4ȉ'+'>c |>?((H* ?gbss)SH$_Kl0 ZVmmmiZӡ@XL4j4KbB;VJ}S-[6hwLqƁ7+0r3}/ر믿H$ĕiE;nP(<^/\9=Ԛ l6Yd]] ڵ?\``hBF'6Cw>.T*f^o6LVQB1yHhÕJ%߅L&f5mll4iRZZauuuiښ<{,0%==$ɮ.4kVypo/_KiRn .ҥA,~EF&ucXz{f7YXX p:LW9rR|~ww1c$D"H$AAAA"e:tǏ_lX,Ç EӴ{Çjk50~g^r=}?c_e2B6lؿw}wy:&&&Ο?Μ9ޛ]8irggi2L֜>_kjښ<>i-M dߡiB(ŪdqBߴiӠuV/H \ ӧ~3\! - YYY ,t%7n8%GUe@X+4aBG(v :_bfIѶ;rhZSw?ezrc3ZXciiiپ}ۯY9Sݹm:sd"T}aCQT]Y5ބĝa{YgggkkbrvܹsB}aa0 "MJKKF\.G?jX,. $y+|,,,#VXXXF𱰰8Xcaaq2`e  ˈ>+|,,,#VXXXFފ^`jrpd!!h{[n6|R-D+C GDё@J'T hܪq\ 赫z L" 72f̩K! P5!0(X*@OOO+5jC{n#$$zA--*5q<$4 兄QhāBvfICšH.t1ahr+|,@5JPj8NbDT"# QWwihުT5kdffرBCCcbb233W\YXXan~}[yXUURMgдE3@*Tz=iv DRݘ;0E6 Ƶ;psva\qz\|6aP(ƌmmi9fg6fD':I*+ ӯ񳲲^y={dggxϗJ>׭[`0,^x87|>.O0*1;\>mq:\v9v9)ɥ(H&IhѤzՆkϟ+5^QUw9.>A(C-]tҥyw͛7k4\?f8gX-L6#recH/0,@rz,,7R ?{Ļ1gϔh# /.]N[999˖-i]wOձ.Fh]@QTG{*|lTt"5Xn^A\ܘ2v,n@ཥJZ~+zֶbŊ׫T*{ M&Skk M:Ld:[[ZfӠ*|BQ4p82t;; cK)c H4f̘1cƈD5G[ٚ5kv]^^w^zom%|4M7564rR _}|qyr쟃a.ܙB0$E*oGJ16Cep&L ~RD :;;8qb箝%O5@(+'aP2u@X?PFu֭/9.W_^iv=t8K!(kZ;櫾d 0|h V۪vH0#{ԟ2e 0LCc㿿fχ0ΐ{ͷv޽#׿2zty_}9s9NGGGA~>|IMM矫qLBa ~3loK(@Jb(GVVVaaa. +(;;D9$bqppВnzT"&_S e)-q.:?t֬YeeeJu'M8A$;6Dr;Ҙ??g]ǎK1cΛV]ʘ9c;w}}V!Wtv"'Mz$:劁Φx3RPP1bm6uԠ PTSM(M0aʔDꔔP$::2Batt4:~{rۛ*ucR -Ia1э-5WV"##?|K/37b\ii^$Q;MFdqq@EEwLQk.\)))Vŋkk<̙3.Vqh~ZP3444i|Rss/pIIIo|~CGl\q֛o^_c?l٣O‚ȿoO\IIJeڵ-[Ο;=r.yJ[ :P$Z-0,L Uꚛ'cddduu/CT*#޼fk8nٞxb?<0fʕO>bh]ڵs׿23}nCUH&"n2 $]2|L%|A4=idBA0E}[$IZ,s%SK/,qŋlټwd'VâEbj~»{ɒ'B",~./~'..t~/::{R@(ʇ/݂-- .B fϞol6$-;odggO$z-/|SN]bŢ?uo^&+pرO?`Ëso?{? hm\MXXmM@:t:|@}CCC}HBGGZ64\.}bҰ>߲yglӦMk׮[6o~7Db/[m[?|䑥/YRUUܜv`^JZӷ Nu]N{}ŏ&CCh"0  U]hܺt:xg}!-uӦn?SRR̙;vܸsiSSMM9qc=Z3Ro6u߾}n}ƌsr|woZ$|r|-..7L ƞ~byRO_5k tcK``ӧ?BBB,yg{rFZjZ+W"B;vt̺&oZ\k;"ؘʄ45{ O=ӧWV^=9w܆w7g#q|ܹw=:?ܺm]"X.'vgvttף<) SRR'qQ"] Vs <._Ƽf;,tٙ3gou:B ;vl ٽ(ӹw æLIA?v G13f-/EQqcƠA|G Tv"y„2ĉ)؀>y1co{ Bw  {q!I+>SjSN]#/VtwO?䉕+' j/ڌñ $$d6#<۱}k7|w0 E_]/$ɪ'T0oW04RKSp"^B ҠGYy0{`9X,7(󃂂=~;.# T*a@ eϗ6 r_,==|>Y]N 0MM?8! 7 OڑÇSSS.\SOMzw3a|m6X2YazwX"tx-6:J;D K nZAE$DMD&^qWU Bna, e 1@R.v3gZ(9gҩL'xw%K,]r]-{W޸qR%>ޟ3O?nIOdw/씂cѰi"uy#)i5MŌS{4Gh)尧LMîiBm%%%|f_|3gקsi466>H>/,[9(355p{1cƌ/op5,}`0Up+Ç coA)v͚^Yfu^g[l.-]nݻwϙsc-7{^7,쿗Jm>mnnUSs 8nvz%r:K.1coV_>Wg]n^U5dȐP(,-}cjho׮]gɉbg;vܹs֭=苾<a߅% ߠ!半 #f?-i*8yX_ܩs̟&Cel)M4Rz="Ԕ䓋RaTUUzRje7֬ybBx^|qY|gaS|/+V*:TZ뿻~G zjo2dN;ɐӉc^W!MԿGO1OrrCd4[iMSEN7?R?QhVWk,l*eSZMSZ:MR0|c3gtUh45X,Ғxb64M]%^9 ^/ pI&']gI&=z$.ͯjyyE2lذ+W^ ]kIF4 ǢX,liah8~W^F3ve%4caˈXF2"LV€uo~87ۮ鬨,..O<^K(1X$-#;pes-y],5}eOaK5--y<_ӏU.?5?#*vPMS<&W}8v{AA]z~ƍnb֭6lH\ .C=W$km>u)K)xl,iF,&S,=3Z\K 0/ >@N eswuݧ# iiirrrsuݗ^͛sm߾}ǎN*ٳg;^Jrrc@^OnVzFFnNnnnnFfFZZR* !]u~I^d̙]o/rjjjxwwA+nOu Ϟ9큽}\k .hq.\q.18$F|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|pIDAT!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!|!| iWv;`H\J罆iK)G4 _/XʺRV8~Oϲ@ fl\ L4 3Xy[e˾ap1       s@뤸IENDB`RaySession-0.12.2/resources/screenshots/Screenshot_20211203_162125.png000066400000000000000000006400131417052567600247030ustar00rootroot00000000000000PNG  IHDRpeZ&F pHYs+ IDATxw\Ggё `=b^cb75ػ1jX wqz9@>rs3ϰr%X" K>wYz~w!|KRVdƢ|$ TljjɔOc,_ EʕCBý##bgg[zǏEA_B SYwD~"˖)Q(f'_Gdt <@wu80.{" E{ "SSÆhNyy]oJh1u#og-T*a݄S%Μ022UxIk_W(_n#F'$&Qm[6o6c֜G+/^޳/*::tԿ_T*"=kFZ+ 2tR#G OLLic+/] Ms>B!V-,:lX\-ݫG2\ÖRq6nlll煿:/u1%>ڵjק\ٲ"?S\ͣsѭkN66qO}._ُUFlش+G Z' ?\2Z8**ԙ??ճW(_NVk~&n_R9ǘ≈^-Q5*_%byH1k]۷lٶQ;ulobb5kEG6m!foj5clmxh4?y m6l#[۵ɕ'Ɲ68;sl-ڹ&O![rD]{reWޣ{v=u%eJ:rJ\G.ۻ!#"OtJ6PVM"zqf=jgktBŽ]{2qP1#St^~s?ÆuF3SOavxW)t+ȴm…D`djjڼiSHԱCŞKy-gr6ʵ?IrJƍqttܸy'OO?{bɲDԷwժΙHwSoP"z]533{Ok 333U*ŢyY?L ZJ*:{lmC?AD!!!!TPm[ˁZZX(#N?q\ٲ's,QkѮF?vt5Dbѭ^6mi#Gmb"{ժ5kW Ǐ9⶝>u`Z;ӳ}hhغ6<{>~&֪Ycn͚U~ZS5nߖuPlh^~ݔdqqDᆱ_Q^^w:rlOj֤ɉScb.\[tcڴ&"##Geb.}eDTn!9oƬ9mZjPnZ5BwSgȓO]Z[޺}N9pɲg~=wDkV.{Ɂ/~ VT?W,[mjjZ w=޴u~LAMH;l!s۫fkr|y=no{?M NwݿLҿo͕y=bXACKr 3pX>~֭Çݺvvwoy dH kۦOYPpP(<NRÝ8c}|&No"mܼEc4a-zi_ǡK~f` oW_l.Gݭ{Uضc׿n޺ߠOp 9ahRٽwKΚ1] Y& 23.oA[y?DħۤQ?ϝ'3_!yB\nS_yѦ[ǍUVڵj=j֭>2ܫ|޵Sgs_{; >u RK$''<}7 :{!գ/1 66V*DŞԫ_:oѽ[׃.\,wMDw;z, ;owemK*U\وHwry8طOvP-"sCBF _ިaаo{QQծuZ5kQF ܽTZUHTj??;s,nִɑ{ǎ)Ɉ<Ɋ* \bcگ###MLLڵm-36 fiX^Hhإ<r؉mZkwEDD=w^DDFz8;D\5cc,>=9gl\Z޹{sɒ%K:(QJJ;h4!!7մIcm^wD<|X~cO277߻ky?jU0 h4!];wӎe jִI  [VJeRR5ilbbݻoABP(\`nd|-Nk{#_~P(2x[@nP='^1/0$k>1Fy恀Ott:^Tx͜@LLDV;q c=__"$''k_'%%D"~<̌ j-?SLoCffX?Oqh٘,kѬ遃G4w޿`?x84,LPߵgn}ki~(MIjUǍ=obZ 2ʲaԱCk*3?>޸u&~?iƭ[<|N-Фq#xȨkyRU8clllll+t?ӓWP~,8n֤Uj:<<|=w=Ç="oROFs]]N:L >j\@@~=W[ Lh4OV}y""#W?[U+< @Ai>>=w[Ӧu{)c``EKL-?{μÇq|—y v#nϝK[)~HU3:&ef>Ϟ'''/?7>>>}aa;vټ@}䩝s_|<?yljkk% gRY6u^:e=66_M7jh=ݴ)f}!ͣ4F7hRL`&כIJN޶cWKrMu{?fg~?}&qΜ=ǟ֬\ڥG]ޞbDT0Sxr{3]vkI[+m tĕs#ǎQNdog3x@T3|sQ?y+MuܱBLLdM7*S ctKگorđe+>&Ẹ8Q`Psɒ!.%-JLLԭ[?&s܅~|i)))'N=rFfsX$''+qjI5ʔ.he+Wi.!!͚6~P(lڤѻ;PB*_sI+WS'`}?y ?vжEi3WZ{2̭e ^ 222*]LllxxD*I[dD(xroܨтJqaᦦ&6x6݌!u~WS_""K[︺m!Ba2I<|ԧw[^^<}'7kM:IFN%$em_|q܅:vh_r%ƘT*T)]œlccCCq{{Vnxq^=``z|Au>ztڹXbfM76e{SR>.ҥsGkk+@0rw?zf21`ooȚժ+[V&oۚ{_H$R@ P*o߿JDTJeToX`gG&Jd#|j%";;+yOVd ڶcW_DqTX±Dl\K\||ٲe(Bon;jy?]b֮^`QÇsc~}[tБG0j܄^wۿcמzu~kټ&yVzu˕-#36ӫѕ׺ulaa^C֭߸^aխSL$I#CJ:9ZZZQVb8FD]E7 A5n2}{Ν9!_oP% Z~}׳G?_HUh*Jnh47n?f,oj֨}ƥbH$:eɣyڍu՟7g}y.7?99:8{V._}Hr: _Ԭi0U u*U_ID׮hԨ1g"< ߔ5k1hllsǍ5iX{E)))<ؾ;ܹס}۴+DԬQmʤ扉?Y친<|iNKQ(n{yU2y.H$Wݽo2RR<1qq37i)ƞO ;w[d`Ç  ~7o|媮•׮Yime"eڿ,0vаukkcV_=gv_(sGsuqQT!!kFDn-/Y4p +׬f.Y6e⸣+)ݲuG߬OfLVݫ3͘vn{ݙ`q{.H7nk9xSxoش5ܰB}>/}^dec7'm+ID\bi:0`$"c "))I.8uƱD=; 0(hUŭ߰yْE2ם{ڔnߩZ];ǵ ",@޽l۵II#njXXw.XMvȱ {V_qc1p.DZ+V`ŁT>SsJ+SU _B[SBZ|u>zܻ ":S^PppCm5Nb5SS_/uRVw揳gI;ڻͿ\[P+*:z9 f$eZb*VK$"$W.x"C }VgvY-k IDAT/RyࡣY;z(L>( hO?gV?x4kN)8K"k_W(ԯwmV"iL>6X>{uDFTk#OV~/Eڳ/zv޽=~ 9bIF F }|t4J ]@|Ⳕ1",\uӧNٻ{ۋV)Eq ,ݫǹs/>V* (d2dB}{oЯpB'<>>6phO׆ÅDl&1FnLs]差]Z01)WIuф^ѹ Ȏ1{2$nFND->Eϟn\^ꕋϟ}B qbH P929 c\],ZPjmˬ](Clkͤ{6j^Tux"ӫ`>f.H{|C<N~>EB<5cA bDCvڽ{])WW"OHibcrnWy̫#k exM$D{=a)|ϟWlo\2&vWj9aFFG(0vl;oy?尻-^𚍚)tф)"𪴉Cfd{9<|+xL|T8W*O;N&?7npJwTaNH6ev躡|Ê 5HJNvqqv,QфrSHmoV?B13E.uA+} I¨)h__A:#|LLdj:T" enhC|B kШ8 hsTbBY8q9HD4Mh6zFnpíkk(4[m&eNMr$q|8q*~4Dk5-8k E񹖔 .teABc1Q2HH̉ [}\ W?Ub$4D<WU0gR6B 5>.*hƤcbQ$qy.!2+ =>9z  -C,Bhh9@DE"YT s3 kDb1 5C@FR#YR#Y<@i4 kRSPQ#dD*A@F*A@5VyJ'!YYZXtD&kV rIFG[5i¸bŬ#TjC P$"\ zÝ4M~#_߷<}6;}w DF+Ҥqڵj۳{7SS33˕mڸѓڽ{}2e:w֢vR4$$+wqvYZXx8Sfmml9#"X7mZBҽ[]Azu4nTlYEFEH(lԨa 삂C ;[[wujײV(2qfԯ,'%$$ԬYBr>Ϟsw5,U52*:999k)8PI$2Q~?j\yBid$p+o&.6l2WZש]k{uŋ_quqٽ[V £N}ϟT)U VVjZ$mz֜y7no`޼m޴I:ʕ=zDCmߙqkA7hHPpp֭X#`l zvFJKt*{0thRDRw =`?m<*Wknqsvmԯ+͜ݣO&ڻBrvwoÖ,[֛yѶMի~`^}MR&Ok "aA (5Gԩ]G+獍bq: LHL'%e忯$'''%%}knn.2.ÐP罟='b֕+U$ΫTȨ[^^Q*?_K5s"Y:ikcCD˗Z^x8 }]ttf͘Vdo\JeO:q\@`^2y-yA GaCwY$$$dDX:a<<6Bj1) cL;6pFD\]8?FeJjؠ~pp0M}Ͼ?KW o߾[cƇG[$n۱kQwsk٢`XݬPZ ϣ+ Zh,,,7lPɩwuxoƍ&Vny׷{ޏ6d[Td2ن_unddT*U($4o+wU<߼\)Wnv.YӫׯN޽>~$wrtT(ϝG~~fɒNUT9yZλ" J@AT0y҄c'N-C󜣣czu_̣)y=sǎ111Ozר^9+_~Ӭi,,<|>ψh"wNѼ 'թUzJ;RIBѡ]PӲ BײŞCҹSTtԁC=G I<ϳ5H$RT* ?4%sHCD={V5:<($ w,9>?J$#׫un[!͛5-_m;Mr؇.|ɢ6m Uh4oߵȧ@h> (p"Vn-mgks[h\JU*%?t|Ӷl\2Sԕ4hPv=pJ^r헵5mu jM ~F T\mj/x3L!K!,#:uhw?7fMxDo~M/3(tvmxkk=lq% s ^'??eJoZkׯ\Zt) ֮*5jL7f֜yo|}kլh3޾{GD}z5g/Ԯr-/,^w7uP( %ɐAZr_i6ݮSףcdZ6cU<>ԺXK378d%_hGzY[^۵ݵgO}O;}lDzѰA3ID))/tk&]"z;w=ZnyG~4nx+WuoܼuYVV! ,ȓ-%K:} #Οs'Oj7kT޵KŞPVfD*JuckCMVꝻkf0=<"b,/ԯCTvWjzBeϕ)z忯>Q?.\UO}/dCkur;V.<&P:RM@byQhfϝÇ{kRT*%'O.\pDh5@ 4yE4ͦ-۵5ir~D]ASȥhE^0;5?gƌӧU(¢c'g8]!7 f:|—Z4o}ߜtfץ;ePH^Ƨ`m~@4J8pH m ,X |xȶ0@!d Lwe湕C"*@A{V766/Y&|Zۉ&$'+ oEnlml#""rTbkk+Xj0o-,IJ^"HT(2()A+D@RR8OV b"aFD$TZ#\@@'6,#iHʫT\C4Ӥ&:9}2%%4ψξFZ13Qq1&&JQFMb@( y~M\Tr#H[#UysRGK''x"&HRq1F&JEEED᜹02VMG+r6@zqؘ/_8N"n.$$XT2"DzDdemVn޸RcM4/^DHp>T&@f<d#b8 "| JmMMuT*U`@~VxHᅂO  HT绺fF"GGEQP`@xVf1e&2KK+m@U< YƴҌԌ8"c5]\j/mDsJJ qVVV_V UI$*A$"8"5 XhBLL"9Yva^lz IDATo֭ۊg5T--W^&]|㸚j BZ$(:ME kUD*"sWNj7ibmbRRL(i)p}Z<3~6hhdlLD"R*RT*#33s++IxB}h" ED*,쑙1 # XJr231QTYVBbF6x!7nҔ(MC@ XM5#5QtJ#G*:: T(* <~D<<" vo'}I[ G*ဂsۏcL@1#&`1A)M`ʫ_#3P /H"hF 7['zS@;_w`R]wѩ59)`@aSŎKsp036 'D's"#>P@4 t<0QԪԟ">홉D錆@aiT;)͛Z+JRibb͛ INB! ZC"Rkg BM@hO/K;$!3Q(rSߧWN hOs(3ILNDׯ_k4Ba\\QjT"%&S"%tc]<898MxXۻK?U4c2Tm޹ TÆ 4[o;|8(JIʘx 09|FS8ow)G},1HFIIIb"!ѣho( (")") '' (_WR$` MUEHgv˖,07Wtj?bCNqFGH$b7a_A ,)*nVAU'J$b!@`8!WMh^6A_Àp}s'fΞƝ>\)V-#OG+Wban}6T:gU̜1l@ UHR^({Q"TER@QY@ C(k I*34>Aj䨯F 1jJ6۶m>OKKwu!5ybRhaשc'A<|0++.® xxxD^RPPheeէw+V7nJв`쨑@m"@4cT{R!qC׽'()C\blH"+/*IeC]n%_+D\0Kћ<>P|&8˿_gv*)){Z ԎtPe/_suҵޞ㺺VVV - 񹠣^(])Ij@j(&@uPFV (Hy"`oF,--YԶĆbaaqX <|XEe89q„1f={矂})J %Iғgy·KQAsy: }.d8CR ) 2 gI6|,(WcRu/lmVbҔZ.WVVVULeM'(}}SU&@ffq@ `8"I غ8[@Fg5H)( I #0 (JFa$ $U?U(sJ@m[3oBߞcF9w%&%M?6/Tܮ]Р/7ocPPXӽ;%&&xFi@ >6+FH˅¤Բ/+re0)E?TTޔ3J+(62^z%`3g;``P0 [SSӃe0˾[N+l*@ozջR3grа# .663##33޾ %bqCm2 @|>`#dEuqdB<T L(L1~g2@_h\`2$I:::}zIa]|.c`ߦMk(.1g,cc#77#G}@ D)`uM$Mٺe˗/Hyo_1xȰ.?}?,fi|:ɩm.]VSDD#LjqrR9vk߽=P isP{. ΅ 7鐳#?{0y4 9tbJrrʴ3..SZZwh`쨑^ @4eMP#@ AhP (@upH^$zyH ɪ >AvFm? ;bEVV7˾m;=n@|B & @ Q( 0'FFOX5G'\= yd v9c@  & HmPPr H 4D$|^F@ dM@ ACP O E 1Hzd=ҡjyHZ("D`6c&NwhIQdAA."@ B*4y #x*;@a ( pJQ%@ "&X?0ByDܢ66 L|z= ꓪG ќJeHSS3.ԩ|zNjзoìmlBC.nڲѱzONN\~4xUQQQhB3gx'OoZVV6{AΞ9СxEݳƍk@ǎOQ(ܽ{g{B3vѩI}}@4K }dD k|mjVVo|ԃ@WMWZR%!eHP&~呣'332= 9sG -.(߻{'NbX^S%%%~zϙ;?:{gƌYeׯ_{e³g\\ƍϫgflO^χ|gfd>دϙ;VV+W-O DѳS'"@ ^(*]Sy܁J%!&/m۵ 8`@hgad.]7 ͽ}Â=gۣ͘'ww(=o–-`?wwo@.]_`0ƌ̌b@6m-;{tH7W7W7GDիO {{##.]=X,+~3w*ojșSgNU/*l@ %?骄eLϹHQ%!)((zȪtJ}@R@U3hBq!V{ IQYYh5L&\=w9.kk}}1 Tfa,ϣ裻vn)=oP(;o~nnO?`eeD*[ _r4}=}z~A@ ^( WJT;vi@ iHccl}p?''Ĕݾ}˻ϔ 0  JţoGy{w@aa􌏏ONNbq~ 'yz={ǫpnAGGwk-/@ DsBPH H =uK7O/Tlu& V[9Bhܽ#l)S7oXyT]NWV7O,Wսζ K #.gl@ 痢E@ >+P@| 6 wB|`BDmhF6A4PŇ ( Ssd/U3M VrZ'꾫@;UB!/7Ǖu@ nB (6}p@|ny;& لZ[tSE4 xy @61A6&B6\AC%Ztf6AnN걺{KaL&HҼBΞ=t>>>+Wr9, 45ESc~E>0{/!o޲%6]KׯC6+/BiH6!ȧZF"Z PkK;M$ufFnݦ yJEKϞ 6c S6n>{./rt~~l6\Y>ߟ  W= 8Ϙ5ِήŨc<==Ι;/عǧVP졚1)C{MIqo6hgp)rĕW^oaÆQOxK*&|ȫW[jMhʕk'^z훥KM@4P@ jthݦkeeպMkk&w-];@A~>Hdm1k᪕?>utts!Ϝ5.ݎellܥT@g oĈEEE!gxyy{s ?ZI19y}6ķPlmlBt[#66D!6E᪓h,$?| gϙۣgO-0d36ǏݻwOi&' y@ j"&&֪555}j0 #Ϟ> =ohh]ƌ˗?*))yد@`{wVKt:p͂‚5k~=__X~722:uwJJ Ru;wn^pP(IƟmMd0C<==^w/Vӹڶmd23Ahٞ^?AffO?RDH 狋9Έ#;v씚z9f@x {{w2eD"\%ŝ:w4y@ ޳{@ ???6}~߳gL&2kLrR%]~w!:)_#F|չs!ӕC pƍI&^zܹ)))@|zxxi+p]# y=ć>k [%BE > FκfgvTԩӼ>QGGgƿPDBջ_^z]:Knj~~#|ȑH۷ t鲇:$ɘuU.<˿7PtSX[[?P:}z&pYG?qc__ŋx<x cƌ,))| >X&ݽw8ikDGM>_Q^%hKy<60*Ň)ćjj6]=v|h IDAT?:>R|hM*>7o7PuxJY D_(0Z\ƴmJޤ[ y6ALϖMӦϜ1sg``8H ܺyP'L+Dnć~uU=u:>(=/BBUj lSMGY&D=B10䗖_zǙL]Wa) C *1rA'% 񕁁 tTo}9EFDDFDл7b[6oܲyR'K,S *B'<~(:%2<"2~~z tI(ѭ F~5JkA.[Mz[ +4UVY GO6]?-</-=S 9zݧku z}EMlB=Y >U@)|Jjh=ܠ zzk#E6Z9<^WUDBL*y;mXOѻ$)ޠ B*ը> ~.Ojl…Aݟ|QHvvQYYҶmlLF™LH$P$"| b\==#Ccc3;Vvvb$D 3@&r5a[2x՜}JJKDDn:sZ%OXN5>'N5[M|kW(~~e3Ъz)wlد߲otUٺ/+##cƍSS4S¼8 ,@f;}Uo2ِ( -JKX,feeevv쬬 ]\\, ԃlBzC;Z<^qB{m[Hm jQ AN[;XlXuZ~~vQћz]ZYZsǥg'jm߅AݟJTӧOܾ}/Ϸo<ر0 /h0 :v0@`nnVDžL( 򒼼+õoٲm6Z?|x8_S yt<55"<=:**/?u:eMy|RC3DJ?/=fɢZhPzѣG}*""<"">~:I۷oNLJlUӇ\+>3xB4?  ҼW&6 LlEصF%ߨ `L4b7;]^^^ ykee 9޾EvVViir=Mh Y>MhwA.=tu E"~BBlf Lۘ](6 5u1_vr;R#GVbO8}~,cwwwtM>}O{?ݹs?,,B WR^JqphΝ) 7Gwʹ4}}RpˡRvR-dMza+oz#e兯.Ă @bRRFf毿snH~A^nnRN? պM' g݅lBMPҜlc8NƧ'6tG YѻSΕϙD1ŧݣzmy1nťRىgN8S@"nڴ]1'%%eVA~V^^ʕhBՍUEku2MhZ M݄QPD] .6?/M|9|nI(L0wtY?p>ׯ_ .O6 =r) BaSN v"V9l'\Lu|UkUD6A%Qa_MmhcǎB!貲Pݝjih.1QLi*%%_|ѱE֯^w/ڴͭplJ(TF6`oooo_oƅRyj'U{j_6RV[ﷀ34t Hh~:W``}}׾EEEu }}=|mml|~z~Ni B,w. 9wPO=Ls`oߢW9\\\lB3AR&:!$bR*Xl6fc8_D CP'0a%_X'IJ KE3ޡKKGG 0"333>gu615mB#̬;tw^ oWI mdKwz?P-YY/9 uWh6S &4 GAmmuS_(TpvvԯçėX7H(ˀV,Svܵgᅪx m9"x  /^|O~6 S˗/ޝy׮,Ksr /]f2G,).}@t_VWТ ;ߺy}Fqx czor8LF͛} 8L"0aæ͘emK$soA/,[ lfV-)S/]W[} )7@"={櫯F'\L8ՉXO:'łl݆mn|9aUɓǏU/tWeC,** t1=fii9xp۰Ν;O6˗vnݺÇ֮];~޽{Ν]N(w)}Eb6u@`8f'I0L>}AEET>iKJq{؄)\A$ ? 7'G,;}ЙIԭR0~69&(ohcӲ,+Żդ݃c j6000"IYrk׮N}ۓ2+jWUR| F!>TCoި2u 6oݽ{'O(<<²*>t |嗰K׭ ܹsʍo(#t[Txc7-J(XZZܿa )**֦KNNIJN~{lo,3zmHrcƮGDjkk#cOzlȦ[޹ 6ԣk;v~?`dd;v:?vd1wjJ6lk[9xC~X|Dp{ڙ߽AC5 b%%3f*((\01 |8p:<8''wsttb1M@jBh ,,,Zicoo=ةSFFe~~~CmYXXDE =7rWPhn\*)<`6?z$ ߫wϟGG>rV" ?AzzM 0u4Htt #ѣlj'JJJ̙ɓZZXnkkSN%ĆQv2JD!6m')Hx<0mp\@&p\COO_&X,}BT*MQTNfffE P ;VE=q"-Mx6ZP9PڵWKKK_ H$+SnP;>411̢B|(3gN+;tp_z89HxYYǏKNN:ڍ&4wbRT;z*7Ug=D+0 =7owhnGt644###GǖpᒒRHI |ҡCttT éP͍C$ի׮.ߩ2˗EER;udehNUZٙ 7 ?ppݺyBh:Ç07s1m…Nj3HHH8~r⳧osO Ǐax޶Cׯ_T|'I=.||ӧM׿[v\\\7_irr*֯_3Xx1^aÆ-[\s -)$amƧ B$SSS%/ ($$a\II Gܻx罹 8AʤJ/{/\I; M㖖b1:/d L&ƦeeeEYVX &I6o׮^EdgDx5WRsLrȯF|ukoV< [[e5:\k1zKQQQs><844ٹݽ{oRHmcc 6zufoTA69QP`^6n`6w^ (++'`+VTCs{gB_|ÕO@ch` H(bxTTP’ڪ\.3N8N% goU(V!j8M:m _1zWs &Ϟ=UV6ݳ+)1G^}b`آ꯾\462?Zw7 uؿu *OxCc4]=rddɓ'kA(]0`UYYDDH$6㸾>0sn0-$bГ) WYYݻwDӋ46]V^F&uclvEE9IAڽxlfJ#MQw?ԟMtO&c; ^J~IMٹsǥs1 ά2CGo@y׮oV;vlW GCSoGU:ѵk]v}Wzy͛7t&XXX,GkD .E&d>$ s33 &V+W'S_4x4ȴS"#;f:b洴6ook~=wb\wTmvfΘqfŧݺyi:--\:HRcԘO$E*dff$پ}{zťzZ FrrܽsӐPxk jv&@??s'&:2"cCt5 ,!1ytAXj?\ǟkmeeo3i(__I& ''fĈB4<ߺysPP_V_nnn{޽iӦ{{w_QQEWW z]8* &@@aP tu% ERT*|###AOY)f^.%j"Stp]p ʤxW7VRX}{ s>}zY\RԜm۾,_'&AJ~eԌ6JA_ߨeKW ,@ z!lxMS˗.|B|kv..y8s̭7mmlmllӦMq|I5!"Zdj6ᣮ6/rssAwh/j14Ww$Y^z~cx+Am ,&/Ŝ.ݿw>:d0]>xpq'vvusةZH$իVro++*KZZZjJG7ccׯm۶(r%RWWwa/..޻wٳg`Ϟ#޽֦Mm6kѢEEEE^|ɓgϙxNN6]aKG0)Rbߓ'ڦD8NQEQAHRX$kg\D$I>}Ibb~~^Dev`7LQR\H.ل~S4TdS0@ASm;v0 慖6ܚ$ IDATkeLJڻ:>lP]|5U76==;P+>TzB|(MIqEo:VCme8l@(|&711 _{bJ_($y̙cF'$$\v̬V#vU< z~c $FkTI]dqYYف.<oμK/r\&Oѣ{Ӊ|>3gL٣Ab85yqQqFfϛ1vwzy ̝={W#e2i/^PΝڎ+P5,00b%&%qsaa|6%1d`e}>jVSod࿸U{Oםф NS ƭZxO^SdPF.QlܪPOs|{̟;~ήn5ćZrU^SiiSRR=ćnݦVH7^&Y!Cs Q}}}1 +**zyEEK;gǎ=y_7##S*] "8WE506!11A"dg+ 8IjhABX$`Q@_]=l1 ߶ &NHJN޸is׌@IظaƿkQAs ͯaEJ**Rc# -RZ'1`̂bLe|6qs={ Y^rWoա(CV#WkmD!UMUS{{!;67xDU|X$ZtRo,c222~u ~ ?~ctT*UߜiVѷI[ngke8y$=5uV}Xl A -l3.^0766_Իwocc;?~U0yԔȈFEz7fؾ7n\oݺ޲oۿo_SSҫW\٪U?tN=z\>7OJJܸDd; y/-Zx!˻]vԬ+WDj4=Z +W#\;ٌz~cCpsaʽz+٫Z 1m&4ێN  @@p J)AXXXD" ._ڷT"Mh``R%ePh~\]6E6?ImoG<=F&s~bam`2"Ɲ.&vpSC[Kf'vވL($JQʙu*0g/.M֣F,(,?M`0>L&'9aqqA+h 6؄ϧj"4Mn<[صUBvڿ3yh{7n[ǎyPYYYVVVlԯuܸ9j={̤SLMM>&7*e3EX5nN=flee| :9x\.'j%"lP%MĴAy{w:x`Ltj$oܸNRŋw4߽{4ՖMMM?zTRRԐ˗.] ̝nnnnt`Kǻw$'98ɉ3IaEܟfϙnvpI(4ɰY(@مwY6x l`52LmV -\:L&Oq*d09LZ((F( ڦ$IPx[ڻٛ/0Fё ld'\l4Hy˲s4ƒ[)P[fbQMX(~YﱱQ)o$ђ:G آ(?%%M oeCTKE6zjP{{ -@ P&|\(WPrppBByUnlٲ3GKWEE;LoD"HJJtus , ]2"zeD5U*ıUQxB/#A6-PbQ$DZ[?wbXWWB3'`JjY,Hu#Mh`AUgKQ,Xs^}7aјnbd_ecӌbDRRBAH2tNgWΞ6faG'Q3z]7O*T[byx§`Zruj3DCCLtH.HŤTL838lp',N`JOQ_а< :tt0$̧O)y$G7ψaZ4؄ϧj" yx͛7<ИyIaayuBAױ:W\l{=JKJX,VgW䤤[n&&&@gWgO>O{ 󋊊5..ͽK~%%,sg䤨[7rj 6-ދP@ >M|>v#B9 ) pdB4}g*HMMdEQVVnRǕwpb!_ܻL&+--;Қ/&9 Ç)4d0s PgD.̘1ku-lstl5y¡Æw8H-[:޺y= I$IhD8ωhj8rD,we_j>(ޔ_),+PXM8 erJzɺUӱ G%MpttnٲH$x0Fm ` iʷɗ ʥb%p) GJJK+<>fq2 0^y%'#H%M?/`b<8NdDP($ɩɤIt M@|XM lBLMM㋋5%dffv̬|{w9߾3fřYYY&7(55E"zM/ԌwPu߿w;},XTy@Bq'[ncQ%'+4ڼz ͹S0 (D|> A&vvPÑUV $F{x)eP߾g㢸>. HG+=EMoLn7ԛXMK,7,`]e̼ ,#3g9s~PWn8ۡKJKfͺ{fgށ )K^BزyHHL7|=7j?rPPh6 vp:Ș&M.*,RM@Qð;-pبTzpt0-+_cw?=(+t#_T6y3[Y-GD3}6LCF Agyek_`E}:^Bwz~AO_N0YeH4M4R'QHEQr3@1pf+D 믫 4hTY\R}҈QbBA۷m9u?FGlݲiil6[wL?!Bg>]ׯ}s/ORRRDr|?|Gd\h1 B.8tIw˽c slJU})+m8t`?t6(sq}-.{k5fh _A  ~Ud坿m77ܠ;L=.Ծ&DE%}GM E4N-34Da0Pw&q0+(Gk4jB9humY Zݱq3[QYi`99NAq') j_M!0{/5 \bZ4J5nNgXVK=N|x2xZuE5g ~E}}د&tA"hX:[ ;`& ndƊÏkbuqzŗa?~EeJ.XxWo^Q]"'^|yǏes˖jZ7m39%F/+WXigL8 3޽{lڵSM4yZm:_V/ _9Rs⢲ҧy~̻nTTXO{`X"6m:HMfsQa`Y7)d/_>Մ aPb0;n8li ـ 0 a מcJp <>_V\&kP AE" v`z3۾o ]:;Mf7pM jeXh5S `|b4=UyMjm& kfԄ# ~qcw}ߕ{ ͸k ~5&X)'ܴ `*NFQa͉18l5-6 N]bSVz}G~tO& D Ȑ! W ###V+ ??߁:̘@Nswק|\8p>~6[$v8 Bx<t *T%)ԑn8X^V:f BQ ^_ <>_ j$:qGQ4<\ZV^Wt&D4[kG7U(*kj4v͎ T7I7,kRZsQIV;ȵ N#Jw =RsB2dm9kb4r^i+wvޟ1glϙz|HM-f9 5f =# aR@g{!:o)s{k; JK]Д @P@]Ü|^@rrG]5\0lĉ9ٗp0:m̼y/]h4))PRRw:KY\1 "{dYYFd1/df;wv̻cGLwDrX5fAlv|pȐaSM6}ӋZjٔ6vi>/A_[ϖUb1iwM @0x𘀀 Ns^>Cd NZuݶmIEUUj?B}Pu:ֆ%wņ\O UlW\v=]:|{68y+E>x,VcGܳ5E/Rzg҇pm XMM&ӡ n3& G&V-BӻjBO II',juEEE3'NRz!\W@YLHJju UZv_l N .i>,RT ҏOWݷMhbW.ƹ_9N:U% IDATJ"4.}Npm;q؉uXR\G65v?kV]LY򋮬O<}꤫`Yi^|νu_K[P0n;fQiRO b!j}An Pa0TNrt:yjFfGQvWTa~Wt)&όzS`Cԡ4K͵&.y{HI*%~`[S$*WZx&_fAA,义ǝ:}fKjbb'NӋO>5*z.CGr_: Sߵm b(++g   q@`S(J(Jч ׍z_M:QMh /~ַ[s4ZЦnt@by@ q='j'oQL&ຯ!g~A@/! in -8)]'L&!*lyl ~|nR"CyJٞB#j9y*,9t:/fMjBs90L>,4L,k5:uQQ LAX0n&WZ!(tWq A $wm޽k3 pejRմ]k69m2yc駣 CBRKKKKۜu;8Bg0MIR]9N5܊PPLDny {_[=>&U ܌RлFII6^Ըg'hrZ+9#-fM] cǍ>}X,wbQqq#`֭YYۼqcyyٌw(~/L8I,񼗦;jK|ZP/UaT*^oox H$!UU* Fα@ZU󳝷]rW֭\t /޽ZyՄNW~|\MՂaXN:2 7nd! 'F )U R(IJ2,N:Fé4&H<ՄGM qy6ESԯ`X,a9l6  4UU2Rn[=g⧜ z~̅ צ?WTTEG'kj;x*aAz zp:F. (J񰗦iNno’vܝڂy;w~0yfϞ❷'Ll6[~@j Ǐ^P0-|&Z- uA(<._9FpإҘ›z(q*pSO?رO?0?@( ڽ{NWd3|>M^ ۷oڼy[ddDXXΝ33/̝J}qϭV>&ՄFn+=QM fGQ->A~ HNAUk> @ÑP7kv;)((R@ȴ Ӝ_MhXݯ& |YMl`qb1"Au!t:mEEIU<=1߱ceMl6g*UՠAVkaaF6l#> f9sü=jB\Tt+(H$!Ǐ}Cm+?!x3dbL:U5Mp>X,&G: `\ 4jMXjp+*88%egN?׮]WTTܿRD/Q*>|R[Tܹ[$+33/lڴuΜY|A5>AB3{lw{GMld>ɂhpxl6`X7BAs+*J:.\_nXp*5??0 PF I`W1;{7zsF[8N#7~/R <_' pCC(dy Q؜'5zLPP~4Lީ Hw붿 ųO/j57j[/_cygőÇ;jBO{Մ&wΧ:ᰫJZ p`!qqҊ ycj6m]wM7 3f<ȣ6}4Iڨ&F 'L8uL94=d2>;i6GgMHH`X9W 2_TT~~[ "B:h ^|Y.3liPaaGVK$)'>rT|S'C0 *J,y\.&T9+.BⰁG^v0:Xv"I5bEG;q/@vvEZ#Մ.!#xJIÍic{ϊ6 ]iGf|ۼSIO:_a7ofkm Q#&0lf3 q\ʃaXO;`n1hp @Zlxؑ&MJ aa ZJNϽPR<~,>>a¤`_P Ƨ}O&+ߵ/&:06j}tM:7yv  _m+˫ɯ&(|CM%Χ]f1l_HHDDDTP8>ճ pbM[6orr:=tzp{k-!Fs,j4tR{+(cp*=l lh`o?C=hx_~-[-?P,~{+ޝ=^IRn{2ӹm_ӦNy޳=2JCDe#]餚PQ𩸲Ade1!,, AW76;36[kNe!jB拹+c<ːBԄ} GuhF6rV?-AA6ƍKf-]QHEQr3n.#0V(3}#<`8y :y֭%[2; AjuigFF{KikBA?Ԃ~K~[`xgϹ IaaY/~g'N^vۺ_Uk/|l<Ԃ<>_.o޴!33!5m_ݽ{5駟={//]<>u‚~CΝeXO_6W7o8|1[lW~|.Sj5,) JIDppBQ&c]@ 0_thj>y[n_ٻW7ߜ1}:fϺsÆE ’j:77olZڶ :[-zv\ EBrNŢQk FO $J1b|hh9ū6#;\fKII)=!+pep'f !I-SbՄ6{^&@:]^ݗ1{lYQ+Մ.ep؝N;^LVr0[[u+|1;aEfF8$nKt8V @$ej8;iq&<Ip1T 5uF+,,pW 11 2Νu0 6uO>чdC~>4ngN>K&Mu11Z+KO1O{ꭷ}uʆ6p)uu=.?y⸬L#KOytzNO>oګ ȭ _`cG-*Иp>pY/0LH$J$ -)h{.Qf3O/b/m0Tk VE@pS&O< 0GQ_}9bpb1|^\\,:| WC p!7mn% Az^ow!^Aj  9WSs'C;:3DU.o~ɒggϾFW?{\p{5=Z n7j}O>"?{Ⱦ9ce{{5γG:[,&>_@3|w HJJRJYq-} jV `*NFQa͉18l5-6 N]bSTo?vt䩓L))) +,,3voTT?d%ҢӰ#t؏B'N<"u$ {}а$IXn?u=4x09ۡCc1/9jԮ]O][]*Ͽ{*iߘ怀/9rKP%%Ӧ:lxHH7D |UMq>~8PWUUH$aaQIҼgFk'ͽ% nm껂/@l6W_r*0by#6 z=Dª*Oq? o:;~DCð+W2NϿZ^^@6]ĜN'A>ySp&&n}tB{+d~'\VIwܽs_M4\wKW9pw;>eDwGS)jgt'6چDEEJYw=m*QOa(B0Y(RLp:p NŜfrYviН6; 5=>j^zZcsıMs{`gr?}^۾y&N6vv( BM=9E)@wi3jXS=u59ԝzEךaB~|nR:DX*+K5edd4.][\nBqu?n\..]jW 8,j=v]3okFqVSJ @D3u:X6`@jRE!~(/{o\jk7Մ/px3ok ͨ 3#|!n;֞͟|/1 (JLLrpp˩mTA}/RcF0`pEk@ZW~ B&<УV*+'#8y#>>|D*9Ϝ>If,zf]ze59~ȡwo<>N/_ʲSNW*qt:=33 ftqqQAAIٴqyfd1c+K_ɞ5k6㙙5( 1">+r򄉓rot?Ϙ+˯\ɹw,/W@w&4ZDS_Hl6kAؐ LVT[m`RShWR}h7+(d 11J`xeW|+/L5ZP|zji ʲ^t^vtڼyw&ڣ&<ݠߐM}&ӯR zWYkV]\ٵ];r8xqjYjU4sU?5kV6~sf.bZ֮Yvjv[ʿ\k}ޝWՄ.A|̎at:8t:1l2flOpF+ʫ*:-)3k J5.Ҷ㻂©}4ˉ\cWY9ֵLJrwzK.77g]wpK/.%щ{޴(0/uQ*˵ڪ !aCne ~mʱ+E5>X,xl6ET*J(`ǀ]6qtаxJ1 0t:ۭz}Xc4fc=^fL#'JH"q/.R5 :UMhf[˝4 touU5PT}ЍrKngQ(SN"r* ÌF}MZQt6YZׄ4:<|WPP*N>x -*t7=pЁk!G:jgTl.VV5VHvuB@Yl6dFxJt柞pg;Z7ՄPP(D" 2K#qt:L]AШVyK|ňT*`0(* 8a2髪 IDATUUrNݸf4B C3x6)/lnz~5zW>&t/ <A(T2,6fsY,px\./<<AjՕ2UFSUSÒ*=m}9s}Y5 =KGpỂ꭛-o|Jy/L6ztw>qFSSG$0P" DH$zN&+TDtd_z>884**.,,J"VUUTVZ,L>`j`'|_ Xg`)U|]Cj qkFt<4F:aG0A4x;vp8\.b56Ys5FWLllrB@AJJr0 kLm躗[r[7m޼-22",,tݙ`M;w Of#M:ϾGy?ZɈ+W(U?zoUOP(z/ i4}{3g͘1BA228pzҥl6!!! ._>cT*KZMaM jBCjt@wp? !3ʕ>.b UZZX]GDeeB! BBiVTUUԴZYp/p4D( JL5>C5o`7O =cszqs{wH?}TzzqqIZ "QLL &{*Oo~phHUʮHBCZg3Tk ; Gl6Fd2on3cv gBf2:]0;ͯ&m6kNNFꀬ ;wDw%)(Bܼyss<㏍/Xö7o@W^z)S&/__lJcgÆ;I:?`6/]:<<-mZYY!Xllq$idd,"WVD5a=4MTAP(UkVG 3?=WHEShݷt雮 j7UX,梢2YT# (*'A*UJU h84""&""ttjr^_<8Ǎm46xܓn nSSHB&NK`PUWgΞ[f7s:dg:4!)Mn>''q8y}}AO~:\8\n/T` rh^<ҡ6ÆJc|AN9q_c.5S֎ "HcȄ<*嶷4y =HM_llJll՚ylVsgtŎ5);;j Ţhd/h*,,JJJp:;8]o2N8s\o t~[D&+jգFMHf@Q_$0t>ptHB Oua1b&4?>Gw $7^/#ީv[q񭊊4V$ W*ˋnݺH(L" @ `6-l4VÜ0 Ü^2 2q⸵kkqީ .JHʪ۶oݶ58}./3tĨ6#6zO`P??aQH1GOvZs-py('"j,Қ*ǝYyJhWچPb.^l!M6AdxH@QLRQ 0 s52>=^ ?`jPT ҹC &S(T*S[/ǧ0,Q_Xxn8O 5qYs.e]5 yx~pϽwXh9mA|ݏ1[l_\>e04E) B FP( B(ҥqon '&''@nn/ ?A S8nH8~ZmC WYY{cƯ%Ag2A\StJá56O HMF4h$AW3ڨ&@xLs-ԩw[" IHH駵,3<< !bad6f[kNˠ⹹/D*dS'ˌFRYG.\"0bq{=b|w=5j]7@$ )(@|!jw!I(Je\^ԗOEIq߻picǧ v>&O}KW3_h,__x ?z`4xptMV _s^A" :BA.68ARA=qҤgC&_Pmi }YMpQQQZ[80544:(Hac/NV+ Âa,JSzc78Fcj5Sl;UDUe?t%]zmM22jFՒ9+**oB&7XpoaٲTjm믿 O7FSe%xҴiSӧ޽ku">~R¢**JˌnBA 0Nnz9&#xr寙L'7y|feeŧ5zXKJM1tIH50\*-.*ڴ2d萡^Wt &9#jɫK밹o6,li{U,+88"88 b0(JP Aa"uVc9vn;Nimf[,fl wR>##GKtb˗IZ;lw6ѧ "A}63xttRLL݆( ch*UbqBC#fCaB!f/^Tll ~}c"-ϝ;\x'\-r-ݻ윻ظqs#Kr/f;9d|6O>kMѼS:fnd 7Az,'&&dƢ6-tfcw})D5'@)~5O'kjBKݬ&x h@rh4Bqr+@V 1 s8QtL&ciiAmݶW-[vlٲAj[d{6[DZs}ʔI/ºuoyБmP u֬\IIIiO+Ԅڽ ~z?߬HI!D ›^O ,//P("#$i|@44Oin>?]Cll2QXxndd\_0 ;y;NL.'1l*)IT$8,<uyɒgǯ?/8!!~޼'X,A6lzZIO?0?@( ڽ{[#Gظq3;, 8XaCC̖j?} KJrA"QJYa [!f_ɊSRFjO"H,ngJ6mŋzַ\T|v'1BaތѰ$i2s9t6}hk=0'v]߻/ J+O>UUMIo?~Ex$SL[! l6٬hTZ͹Bahtt|dd|xx?X sYp8SL_,0L a٬W; FJ&GD%UU/v8Nddd6v옷zp8/ի? `W vC$L&':t9/AIׂBԄz ~(55 N/)::944*?xh߸ eFsZL'H|^8uۋѲ"T[hbUx>[y[R(`4"VAEQQ AN4`&Cz&xETGQ4v@: `d2TW+ -caβʲ~qqdryjnsPtǏo޼i0x,\* XA H bŊ|ިQ#=޸*I.8>{Z&_Pw!]BCU\7[쮭^v! (""& @T[ ]@` {߳p]|a7;kg5\{V4{l_i ֞͟B1tAppxщ4hԕ8I@~H?}$"6?'@Q+AAlVZYTtGfyyQXXT/"">""^Q*U0JKq I N ~zъy n准Jzr6$&&e](?^sa mZ@wddh!8kԉeyZV[[1AZLVl4v}` : 39qXX̙SzW_}z>]t ͫ doj L1'F_~LvV H$ҐH 2?̡($~5iͫ O"b~# ,gh H &&kumKٺ#*q)?MTTT>85ŋ>ZpRdU] aFu/4Xnݽt dt:CM:r %5LJr 6ڮQ9D4aM(3Y`P# ٵ&KCªbHX8] "/+z$aٓGג!IR i'ݽH<^ Q[[#eNal6̙ez8; &ew}5>{lh 󎏢3%- Ҩ)t_ˉ"]z=:0cu4M=ًfcNA?4:8qq2YMbghm@M(5L2-h @Bdrrzdd@ v͓&MhԯVIypf̘Ʋf :]Kx ~=ǵrYYS>0ejɂ|RzWEE_ԧdddth_= E5) b F#q&F(i6WJ*IY %ˤ22,𤡡>*jDttˆFUvkj2Μ1QQ ELҀWX,u8l~| ų_%*}W`aYQӽ.@eY$hч42YP\\IL把s2 /xft'|HwЫ 7d;sw B~` cZYyxZ"@ ˃ P(B$#Y&O"DCB4w{s6k/]zkӟGvmʱMh_P'5:B]t1#uZh`ZY 8L昛ۓ'>e+*T$&%QZzf(O.W(GR9 +Hɗz|wOES_;hfV|du IDATPh ˃bj`AFF` uuUݣ+EgM~X=$}u _DEǏEWwH VR@ <@zL8uRW"EB1`[~s 1x<>6Ph]jt$( D%.ԄCEEtxr)f/ǎewAHJJOuT!@8N,5 sk/%MXxxRtw1olr3Nnp%*UOf<#,;FJ$StptB9v$"bil;s&tXFH$r[Eq4r8lf`hg \fL&Z'WVV{V"_ PM:> -{O= ~EEEzkaaŋ_u'7vVAaO;KssSAѐMllVVUt|j5;wZ"ED*ıVd >A$Ƙ}0V<.ʞEYe䅘D^^^ "Yћ6ؑ$I MX6hpq'-**"<,,644gX, IHmZjj*B'$9dȏV=BOԄ~/ *&L1rMc} BhĈdHt/^<;aCPPHDDlhh\ BƘeiЃ466b>r &t_r"DH_O(BD"bX,Zm$ej2kkK 11 cekN:0~PFTyhñEpT@_Wq Ԓ6%Lq: ҶeAp ]eyXvҥwܞ_λkJ4uzzz^~>BhĉIA*,ժ}\{,G۩ @#.FShuy'}g9[8]v;҈e =S<Z9vhez=߯DHFhM8Bf>>m b!Z{{lna9cT2b23WFU'TW;x=z :&p~ZtBf6oa.mp&a04kn**PDjQ4MWU[,=kⓒRy<>7ɧ(gQQh4IIcd`w6W95a ;vy sPQT|>_&yU(J x0 $0n#N qdzLf3t:]%<r7E>s/sii޳"88SPh_I+NwE bP=mbյbww9+~|ЮB83goԆ?!+ɾûO<>g`_E2,J] x/Y{ʥ_ۨptFn<_õ9sf.]zk㹊 qBT2\* 16KKkj*:#R9ƸjlpH1CD2L"Q,khԙ۾ڥiS{eite[L2V}E"M8cԤzw'EPd&N5, w^VVRVV ¢cccbbc.\8S__= p1c&FDp9 1KɓYKo|$I&&! ݧ3Ƙuu%%v{ }a@wory轚0Dp/љ@;P( *loSi`& 66.UU VVgj3y/ >f'DEEf=+v}DGϹԴ0dܗ0f.r 2їnzzMz:TfC^ή_Ɓ`M;fz-8v/ʢ3y+od&<Un[V\zg.F(3 ,Ř+j>G0$2>θ?|20l7ܰ qk U^[[YSSQ__e,[( 5A x<E9*զn@Mܑ+!4ndeuKM!"(LKjwrDsCfnVɄ8p(NwAPǧDFM<̙p$ǎВ^ `̘HOZN[- E8bo<-)#Q~Y~Ckjvh>z~10W/ wz~nhmxݧ|vqJFi >U$OIJGD*Ws‰g@_, BRK9҆,>x:S'=餝v3 ډM'EjJYLfo6ifM4MSl6Z,ɝ$)Ƭ֫}&!Pd6Z]a@ $q2Z-wѴti޴)GPy<#`\.J.)#tNmu8Ž(NS<}kgA U4g.**[ /^=ΚvXb( ,y [3aB0-2 y<: @ /$[`Y[(IOݵkݧ-N}N% B%pyX5EGí W-dTZLK&>9l}`v~Yv) &5cWvz-(QX}BѨQq*U'W8$IPT!颢ڞg GO $!1` gϞ DF^cYыg趵M೚0؏+:P hȡܽ;%%eTB'NM5򷫜9B~q6OG P:PZfܿ|ʔ&d|~ K:RDE~Ԅ{1)9 c#/xw9|Drخٻf{vۤv(7t&4jT ?yTRT{ H3/{X,Yنt_gX)aX!<'"g1QvF !t)|aq,i$ ƌN,h'o[+CB&Mko^3_UU5jw?{& ԛAݚ{D:5-mZXXTAnS.$Ifd ,*qH$GGx|<: ls:c=M||@vdE)\1jt&(3.uUWC0e^Vr6\w p @,y~o;~B&3,3{\an?ޭtNjA^{mZZZpҽh4ؗ\tW9e&K_ua[KDbƸo6|Bm;J QRRɓKRϟgގ* /\qu^OMbyb'"JEB+1ʡ%466[&+MPVci7yTX{NAdRr w:/_~*t9&xɲ]e;5=gjZ74˘1##33'Nۻ?`„AAJƘSN=k->>1.nP(cLQβWlk7644̙W\z /q]5q{t"(x+@_'& RiUUB B)^zFe=+'=#}ĉ_xѢSsgTdg9[?@N6aٲexKN7 {U__{5gE -\?m[5֪^-ܔ{}?|ymɒI/vҎ ] yAO>566+,Yr+ðyA&%%de[|?i4P?z豉3͛o1_|3::򥗞O}`,el6!_m@cns! p@puq̪ V'Abu #%n0yd~t:0LљՆ!0 IDAT**:]^^s3 RK"Qf >OdmMM^eC]M :^!5=6Lvd577ymv榁A M Va thl쉔 ӧ!п CWWWz{ܦ7pB܀ y O~9} 5NߙjUUU-&C2l޽,VVV@YYgfIO-L P._xj^^/{f䩝t&d ޸q\K|>naVxo5EHƶszGjB')}{j9?On[v׮?R7|.ݸ;L;om7Xq݋[Hrt:zՊjXB1tPCxxvEIV؍$c݃&ez=g2RL{0JejOF{v,+ 溚jE@ <|(CBu>M#f̘QU@"$֥wbtb@Ml挌Sd2 t< -mB , .UXxM$&&"˲g,ϑC;v4˲o#1vlߔ)s&OjNGHȸ*(S0E9O<փ 85uJH{UN|aȇE͙3s^{흁r7tl@"StWgs  \"XdGBj >[߻B/@۾c`֭x٪ x$Ƙau4Ǚ{ry0'B: Bi&xRRYRR"]6<,,j/'$Dbg&feo'!1I"one3WR,d, u4&?>7 'O}NyI@Ǝ1E9 #**>!aPآ,S__[Xx4w}˗}Q=NjGC@`q [ BVVϖ^itp\Zq]c}o |;e}PzP3&O^},+0qά{7Ԅs=@TTNW9o bKLL˶5lfiv͛B>pX,@ 20jI$NpWT/ί D(pZB# #5BS5a$y-Vyb(/:uѣY%&%_p^(6@!W(ZcPh2X%I222,&gYt[lT ZHjBS__utǍ{x3 5*!c`YnJMQC93Gf\'("ZUYM<`C/&@G8c\;en>pt7{qz<ܾÚ6'Rb0R"I{%Yll >~ 5{cxfӚ5N4gX59}\rNC﫷ͩV׬y?o":N D"3g_/_'z}@M~OA}o ]}yyyy%NWظj,_8e͆ /0\އ%.[_.+H$!Ils .  ;8r$fzd9 0c$ifLJ| ؝Kp:NY=uuuwՋ}{pnjjڵ7`np&t $0f6"w K,u^kS(wJZ4>=$%%ab5$INp BB˜dLQOVVEot7l3/fr̜} $$g R@I>l6%ΘIDQُ?^iL4曗Kx`ennRLOO{zw2\$m$])f V@hD*8DR]a/_/V:6)7ѱPJʣ+8..>,,,&&݇\';V@% D<9U7r"DEG1Rp)韞qKU*hܰG\γNՄX:o?hVݡ&B-Rj€ve:+TLwBM ?gFAAA.M'E$@` .EN通 Ac텅B1ƬXuX*,ݝyGο6?&L٫$D#A<>o9?~y~9w&Fũ7w?v5O=rѲ9h&e^jmTvv8:XF<20SΞ-?~jb U;3fbhh`VS^n31""bƆcH00 O]/4gf套^3I|{O?bʔISNygNm0wl,Bhq}={L_ԄKA@ǰEI iP iת;aBEN.,8ȽN@BY=E3|>_ R3KϝIkQ_()jty &A,^-p 2їnzzMz:TfC^ή_Ɓ`M;fz-8v/ʢ3y+od&<Un[V\zg.F(3L(,\W;92B@M/jj*""K(X%**>1qB@TA1$$I?EG0leeYQQ^_7@x*ٳgNӮfn !-**lowZoys&&Q+AFJ瞿9SR)J~1[MNVP\ᴽy#F={v]]rsrc ;rdL&{O̞=gނ*h={1bb 5 ?YUU1WPJ.EQN\=VyWD"J.l.q7i`CYNT4Z\:Uݟvj‚ 2~W:#ƨ7 nFDŽh߽[(Z|x].&mZ»l&œ$y ՜pY4KeBG9/R5K=3v'&/gL4{ĈQG/B:̹s'`„̠ 1sBŋgCyAJ*++7…һ^PȭV[f4Fݺ^yߧLtDW᯿VCCYWzwoث  @~*o^&OۯPkԩ+''{wM:;Z,ǏdHLJd":e=_O[rl龝g{l/tF^5[PUXxz1p5 ***Ϟ-Q(䞛O}*]wMv% fT*m+٭̙6MR ;_y33Wcǎ;z4lqqZzzll\dddAA~RrjsC@ZzFZkcƎk+(ͦ_&N<%adI`ޏo7l(kIBfjCAzCM;hfVr4>0qOIIj(r{JMuuYY3%[KB誙WAٌsyoKsN'IKO_hߞ=c@љvn@cS.6oA"$I"X]lf hFY,T$A$9˰Q8v,tB'ž={}~ׯXTt/x`ĝ}qEY,Ks @GQР 555CGyy9rm~"~K,jrEi,I4v{pd˟'Im_Dg˸o?yx!d2X~;Ƶ8"ڶ(׫nXX1?۩jPhێg&g@Mp+SãXAA dde邂Fc/ƍ,@QS Z؇vPi4|YWc !VSWWjnuc >B!˵-:~tIԄKCOM+PP "--C& tGb1}TW۬ֈHذa_10$4q <-7,ݝr,b'P C75իbn tw#GČ Xە]d2EZ Hj9uҗq^Ӌaۥ /kiAAAO=MFbc颵kA^B!igg ɓ'~=KpEjPR3tuuݑ. KMKΧOArJ%f766> Jj-<]8gΜCr-]n%22JM&C~~ +6͵.[_Ynu=KN*_0c|K ((H,׶ wܽsn(**~Ҳ'\{/5aݯe aasfϚ9cFddFC{A&d_Mںڤ¼c=hO~g=@ jdyBh5JhӠKru}f|_݅ HPet3 nEu;@9 %B}@((8B.W,Ptxa"008m6>ɲ!a'?`Be.ml~eH$:5sw;?s)1h _@?lnOy \5Ų,I{܂Lj5apצ@HҦc]xMHLKep6=?@{tFD~ǟ쓦$5jj IDAT|YW-_XohZ=bDY3W޳bC}i}OWCS<y~gBKM R@yyŰSh8W|6&> _ӡCG Za&p~>^4#BSAA&S}a R4ח.p$-b\#IK0V+gUɴl@l6ڨ ÷߬?O4 ɞ> _;w.+8XItYY}r9_ph:r%3pE7,\Ն666[Gly%ɖ-~wKNNԩS~ Ju]w?Īlu^_ϠRaP[ԄA?Zw8l.S.W tG&l̘ C h(gAQ O$/_}A_CFԄxCCP5{ǟ-[Pn*t nR/wyӆz} PO鱦 95Z.WȤRXf)"C*c 3EEz}u[&)4͜90Dq ^cEP {5YPȸOOwk;necEŝTZ?][aa6o]gT*g +X}F Uj]:Ǐ?~ 2ٔ)Sয়~Y;2jǯ+tPmBoH$> 7,ni!u\ޙN!佦}:ͼ5pW<5`{v I"l6H$3FCˎ 9d3zΉiV"!I1H(vSI3 0Hj9)DxM^6ZFaW\.;nFFEDb@)2&L >rPCɵ3ut;Z]UNUPr\}MFƄм<ZGMtg]w믻axF =KSAO5u9&dT*52Yg^#0 tIXXtrr:I;&.mӦ{-: /CT@EQqVAq 2Ad2BMi+i&Hsރ$쒒N(C'?tի?tR"##׮wqc7og-td[m[~b X)Q@( {eExy{Ҧ =u+qaN\w1Ȩ vI!(b5&w 08Ŵ-J<=<1 jk򺻿4>t8`y[|gārl.s.WTԓ<INhp]/oDMpuDFF@ o맟YV\\\ٷE-w/A$$f"bhN3W^]?G܌&^(bYC!jD gwQ*SSEG':#tB b۰a#X, d -|zxgt;v9>lSGzk?%srGǖHP0 閷p{/j"ܺukٛomn՜nagUխF f͚B288ð_ZJ0,77wߟ޶f[0p^Pᆲ1OPa(`VS^^A$/-dkkPa9hvPoGuvՄ2 EK)/ G`VJoOuqqyxmɉbcΛ|@RR]lb=g̘5| jPlo3\ɁދjWP0,&f e_ +xasm?yZiGδiSW||̸Jeϊ=Kk 'cT"14)55^ޞPS]aH(=_g…...F'O1,TVVʨ ul%ZᴩSz=Vz{4q+//`-c# +Ni(Մ>]ܾU*ٛ"&߿'X dʕK$=!ȿg˺x<Je,Lw''~DD,+// v&o꼯(/F[+tmtA( ÐpxY,6BVO__p?>TccCff ՂBԘgG5!`Gy䉹d2DFF|~CK5!''g?&OVSSڲڞ~|/ m[AA-=,}Kam_NKKǟ?o|7|}}ԓӦNر/&77oT\{z5CjKjJV$7hgs~H$Rڭa5KvNu-,,˺\jqDD-*+(hQ0uYI3m FHM^afۚ9CJkOJ>#74] qtS?08:VBWfߑ |.bO>@h5!8(laǟ Jmsͦ(*88&N?a8 ) }T*y<'Xԯ__8zBc/%"b]mIj76a6FMSϯmt /]IRo{pO"qrՂP(b]*+k-p3jBoS@`/>C I:d ""Fxk61lXHDF%%7 rl E~zzJ2xGHmvdss쯼}{ckS-?~JC܄ࠀ[S~(==P!yؕpP*7/]j΂ۿhtT|x];ݪ >ҋ/[";gbf0sRMҔSUTt%F5!UOb/?7n޽&S>_uqDh6Q^bQz`\L8NL.p;#>0Pe׳T @MM=&&8@cpV]/))CO<1穧Zխj{IiՃhf 5-P(,Ⱦ (J(@ZZz]]݊!ꎟ-(lv̨ `VkV 8N$Y]]Ѷ ]wX]]b3g>tV}fKo!̊ (2r4d#z$It,$. DQb|y{z .]:o&A/'fHRnIބDp)sxkm߷'322ݻqKOx酷nU[[iiY> }߼yb@.ڲ7^_+/+ ~?I&W(W^[믿ګz>e^wyǖa0t_(DM@hhI7o `.שz׼p\5c>,Suu &O~qEÃ>ku:NQuu 5ry`aQ@yϿT^^XjNuHMػ V[QQ]*tB((O?t02&W8~w$ǰޓQSG h Ba.1dH  @E׮ewzQV MO`eƚ½&'Ӡ&mbsIcǎ{;f̙k{֭1W.ze;vn߱eInn޳=o0hP :#t$adg'-=e0Fb*݋$hggInnY,VPlX_ggIz9KPDrN9Vw^&d az[;-[H$BmڴeӧDgg7D*I~Z(.!b;lXK ^5N5<.z6<|y[osqq :lAAJ2-5u_r/4u괿ܾ}N7B/7:u`r}9sf믿65Z̳X+W~SeeO?oqsw_0IESƼ{Ƈ2m#u<!(ϟ;nB^^ι@$Gof]EEj Ip8N!>}xyc"I*+7}BP\gFw`!rONH>9{PMFjTVV>{nO}&+/|gVVVqH?Gs`/lWzVGWfњaYR^pr#GNpYOO`SS 7 v cYY;-"b'۪`&zccӊ[HA.obW_@Oπ~\-++4L\,İa< G ObggOO/WW\XZRX}ߞݻjh'/.Y*|f˖_BBBAXz*1cZC㦍$ᅥ+V~qcǎ>ѣ;ϑq';&'u/cǍf󍍲ӧOѝ;׾HQQw^WS)x7_3 vW1A. !j{@DGryV=16Lii +W/Hh?!ȿםò͚BujC+ APxl, 47jNǞ"Gyr݇pOa-.)(r%Mք 9r '5ӡ%)t)#`.53o0@1gW77I&8q vhlolv-;00߿_hOOTZe3|xxj{~ j'VԪ`_?7v pN8r1⟱Ga;}6,"""rƍBgAnyz{},+[ze8_ ı換01))122ڵ‚9? #cFgBDTۂ7\1rqߟ`;jThwY,v@9d>Dž`TVbAc ̘;7BC<XnLg?}Ti|bx _M{މIWtݗ/X[,lW15g{ P.͍QaaGOhGT ó/45iWiz@yl:w8~byu `ΜY$I;q 헜|ȑ{ڿT*?|ȉ'|W>p+W~`\իWTVVmSwRp^FNiiAhww#_&ICxydW[ _ |xkܮcM[L:=44kuFwMM6M2ma/oSU1 i)G91:}t%Vmk&3$Ņ z}[za@QȌ6lApN&00YzuNf IDAT7sO)X&8FqO9m/o%v ¾m۷9s [a3Lc3J׬2?W|~@@hh萜 C9a0<+뼩}@oQ,~啥~ -{孷k]ر w! ֭"7tt~۹hт+>nk XVNw`HF Xl^gTR)32- j\ɀANwYYi߾[ѨZSS-FP;q}p8瓓,'֨II/gm>ѣG JKKbF]v- 0(.n[oǎ32&GgժgNcIbbxӈ#2G1scRggfT .{CaW(=1NNB CJe7}||0T\|1L` /?7n޽(:0mTI|PһP=]P=-o p(.xj5``0˽&FkIKt~򲼽C]˦xC7=&@HHHqqqYM8u[$ ,hMMoZ,&$ŊV~(''EBl6'<<$:!?{`(ߺ嗯^?{ǏxՊE,w?^L2^pnZ[S~iZgNxSMwMaQAqQQ[20|A9W5A. 0b '6,qn/"" V&0~a3]U>u"Ӂ,hΜ9;/.y.3gO9SPPX]SRw>}ǎ3QϜ}|S#^^U]5v+nL^"5yβVj ,gee} ~aVWWRuV3V50"$INZE@$i_08䷋A=-AR\6y8їGaX1,hx ^^cnjG|=RU]]Vv\bҏ?lIŇaa?d333Z倴0%$9X&thF59ɤAE 4B"JqjInjB[{.7ڋ/.+--8q\IIiS*$B@СC.^LEJe?'߿o//Ѝ7xN>B(**T(|>qc r#8nh˭zyזh.NܻrtmґNi}z>M~oum`n5p< t:*CF(sj23ϵpD1J P:.#I`ZPr"ð Ɣ\B/u6֩ %%8ʪ{9DD!Zڻ5=%s\l6Bss rZbzкFن ߿R%5~ͷ̙ÇG};MM RR&Mnڳg8E]Z(憆HN+kjjhHtͲYZZnz#Xf;t @2ڵ-5  ATvEF ``]MhXBð^20t)=DP "#Gq4YI,v4h8PYY~z 3܃8|Ӳe/D"Pii٦M^FGd}k&,jD_k#rFeeRٝNCMhdddfd5Gh4k|nT7mYV ܹۨBz1g̘\ټyUSSWTtC 7;_0˻lYM8c / \0 ý/$IF'2$1TTV~{yBm2 bGC2766Xir ?n\\D"Ygg1_ߴg\s=:񜜼2{=|xԌs %K,NOpuuv헶ma,,s' dzP``d,}:3=vLbfbfThG}(ZP4TV =} =44n֬鞞oZ=6^eeoͪqvVPKG %%l\&50K1Cfsx_Tt{O}ؕaWTZC]L&Hfe% @g0 !(*ʻyˇX-(lG@d2#App`NN.m9k֌'}'7tҷT`oagy\77WWW׍scBoU`O1C[SMزg"{%: .}a˖m /㩩mݰ>Xs%$6uw|-[~^zMaaEc={ɼqڞ=VePqqLV;lX\..m{jBOƌ&GFE jue.EE׿D ij!QDeeX8sEQ]B_0 `` tp6?tЄG.볲hٗr:!p߰+77O?n(\`X,R(qqR0 {nMӵl>rT>}|׮vf͚~w `sСC22.co(~uGC>rqםjSRnW,k͚54ngGCCmRұa⼽RS$mЭXSキ288x6v[SSY[[TXI@.Yѡՙ/hh.KS蠚ЕC5ô3 NNKKjjj酇~Жn5,]ɓM0.3󒇇--- ~zcSSlܹO 6򊯾Fx1`r+W~PTT,'oĈ;wlkȘ1z=a~dX+W.(j͚/j0Qv jRR2dw@t3ݯ)&DMܪ]{<>}tɡv?fΟPRy Ê唸IjUaa;p8^ns#v'(+ ~w4 ~=' LX q0kV,56֋]Tݧ@\P(Z fk.$CaNw%Kݻw?w7aܸeee0p11#yȏ?~+Y,VSSScqCG:R]z<9A"lpRԩ cL~}*̜7tosa}7{yzzvs0YWW#S}^p(ڵӧZI؝MB(+B7(:zŋ=4c[j;/z8ܧ.MHqAAVgffED ￳^^R{yy],Fr:6vRdĂ\_ ggIDĨ+W:lÉڥdGF}:&skn ~~>55Umg` bW$je} J@fe%=6,RR5YY=?Ѱf޺BS444c+,,F0 VUΚ[C֭@7ENx11Xmj# c(Ϗ7jTZP&Jk..֭o3!tM//ϊʈa{UjFFfZZF]]nv4ZC]|xxvFz3j4PF8M|P;,^pԇt:ݯWꦦ3cF_X[Rrc '2dDiiaQQ|-1|ÇGIk|#&$?r_遳)8NQOOZʕβe`0X,A(G "\^c"h'2d$⮲0GAp§Fuvv~zϾ ?"uJ[X,u055TFZV{ӁfKL a^Q">a-&gɩ0'Lj@RWT0w%G.jɓ}W^sfb.`EQ 92ĉD}C v'_|e_5Pvvڸq}ST1&КBZK߇&{`¥ϿrG9{Qa :jwwL Y]:~oFQ DB4GQ<aaC)JrJf1t)]BС1,KLpEn@;0A̙33&f8E+Wr6ojy'[uo-K._~׍$koIc|ƌ9 )=~q}taaa[ogilWf7&Uo! Q(4j#D!R( !B[ DQBFP`p :&{߼Y{yycUSNϿ霝2YѻvaP q ٰaQ5\@ z5kn(*>_Ж-jeYYA``(/hj2 iSM (C|tڨ҄cjjer!}0@$rih\V]~EhG3\ %\ݵߥ)T9qZb~vD$r80SlJK;]QYl@ ̕M}q#D@AD"W IMZ`7 Y===|ZэrL&[.Zej5!(zI:CM@"jF@k o=z̨o?ןSYZz7y{{*?GJظmAtM''[oELLL@V^/uj( <_"_ZQh5V=RMKHNUCwМH(o߁AH$ZW_CC͛EnyZ`aa+mxgPgX` š,+(( S?(,ý;E!ODշoBTv?gX`#Uyyf` -b=_Iv:6 &ǬWTPO%Lb5=gTw:e.t-[l?ƴ `%c ==^Xrp/`E/q6uMxF=`mmf>h}@IIm;LǚqB(yzzzqZNm.VgZ>X5^LHN3"_gѨ^Mv-;0@@?>_C0 yzHQA&jJ4=pp85Fp'H(tvqqH+MEEkY00D ]4 zKZH$Ґ7TWWv)h]MG+>33v5aS M VJol~EP0E_0aRwb59eʓ8>jj[UUeJe`)8;;KZJu !8R)rń۷@ !(}ffV>Co"|J~uA;ﬨD']j#?#Wݪ7-NxN=6/ldd(mpKՖz;K\DܠU f`6KW FY`f3.^Lsf߲2R0vy@,[R0։n~g~l8`4^_It:^$ฺzP(=#Z#z`~H5 j5yy.Ann"D$XN8q3a%Ͻ/::Tfpx\.#I}իTn` ŮwA`9PUuZ Cp8\&ٕ+:{]W׀JJ:aXQQquuu@_[AnHӊ)15o8'0 ⏦7)T81jCϦb5sؤIRRZVa'zq/BˏAX,gͰ sfab8N, qef Ј% d\ !hoiA$ɪ*"N'=bDX,~zrٲwp6@w-yC3guD"qGs(x8UPWWg ãݲ7ou`3MVgffED ￳^^R{yyy؁MhCP@EEv܄_Yb̬UOH &X˼y$ݚЕ8XXe6bl6pl6p8M,/mS&0BzVUkZFhZFhTJRj4*bDރ!=׺ly5E6fݡHߵlO<6z( BwĤ*f:-"bͣ5Wm9 ݈;Irygpqqw D^R)*x{^MQ(+00:cǞŋNNםcGU@GaDg t;^׷3K&INkÐ SJKsX~#E8Eipg9l68q8\.rlpx ڡժjZTJBVJIppVc>z̚5?Ae3 ݖQb IDAT-{[P-_6$&&<`@@ ʶp$4nnn&Mb׻bVjU*RR JR)jZl+m!Cbm`]w/޽? J===?i/ݻk'|rZr9EQk|VwָIƏdJàhϞgHJJ^`^mm]Ba3gIR%=D'BC%'_(**^xQ~5>[ʢ#'N_@xٳg\ɂs}W^QYYqOvZ/00H<NwS":;;[ pXk:20X 785̮j;3-(Ptǻ 1JMcO>qhƥ-Q.CIҩ]S0c׭[> DnmU`9<x|'f놖F 4JR EB!W(J1j^:bn}r?Bu_ v}V}:&*-ce,Ceec ;va~~_|j75~۹hт+>nsCK=jsXP@ d7ng늋s*>ZPAMh+H`2m$jP۵/G@ֺ 5' w^)WTT-\At:N5b;9Zh ''yRFR( ESSLJ` 1!/l$##jjjy<ͦՁ4hjR\~#,,ΙۛͦeUpjT. {{S}}ݥGp8\(+a_PP?@NmUS 5řCТСM !(cNG\C3hˀG0L7^|aIQqG:m :}4c&]S\Ax>_$Bg@ \]Җ *RD20*CeE+3s)o B ZP :(XB$IǤ@@MRTb0R?Tד$e X,4" AnPo6C 559l G*-V]]eT!$$Ehd̍OxvL_Sm>>f R[wJm{۪`X:6b(i#KtP;ʪ~ACx1!P*RWQQ)+**|}}hȨHzK %7GK ăH^x°!_jl4Cs8N 5gk .:㱼BuB6H8NJv?i-iSxzxX((00؂%SVCne̫EMM&YBhV|H$iA*x?[iA.ob(6<]!ykW Ÿ~Pwި,..6h:nT"IfjTwؼyܹ_a b۶%3gwSR&Mnڳg_1qŋRa"9§W}ͲYZZnzzݲW.aQWdhwx<ޠApTVVXQQb20t/飺{ád)jP@hVgjNFٱ pB§:|C*;vsbbaα 17 $7v'OB[QTǏ9sFRrKY?v6&MǏ/ srrwtC diU`>kDž[dCLu\1q&HerUU,v ]\] &@ E\.klolje7 a@>h}@IIm;-dѢY0Λа./B6w^ؿ,_o+5:_vrFfFȋ$:kΝJBtއIl< ]$X_0.;;ȑA* (0P(L10tVpkiqeffmfy@&r,?/ PSX]+7|fMںhzY踱t}CD5&,xjibH?YvԆY3gׅ8p(77Ǎ?x{{z3?vɫV,E2ҥcǬ])AE-yO>]s0>_ ?ennnEm?lmapPS,^P& t  bWU$r |2?B.oe$d !HNNٸ$|ryO_CwEu3f%0㸸HzLVg{WBHVd} ݎf=6!ojiMj &&0Jc# BQ^ߝc:iq@,1z WW~FVo֫?h=B`sK.ee͟7/8p_wEQԇxťiiǏbg/Ͽ|Y,|z1޽u֢gh4[WsxƬ0 ۾m}zfՄɱhaz z/'\D"U(tvvvsvvǰfZ!764d52Y^ zVtb*]3kVvgKOf|Js>Wއv8 ݈Pbkko~? (''R5^zu10N($$O-55ڌ@!  jBT+mq}!vp}k-Kh7}Zr RRS#"sBxՌL-Lǟ7"2"ʕT8yTQQ#$__~I$ˏ>2ࠠۃ J<^ RzVGW]}T JqM#ABH,DB(rZ\mj݃pFaؤIRRdW6d:!`GJ0 ښaРl6n*yWA 4@eey &?#bxN/F֡#Mjt@5wa=DBTf܈G7mIf7!=FQS>~zw778~inn@ 75JUKk ìY,SɵP(D"!yya!!Jreyc7cNf!IR& ''X,quuwvwa$oll=NT|%`8!`Gq]diAp0_8NRTk-CBW_}.:@JݭM^S.e2' $լ& @CsWNbB؋wp VMH8s|}}_8SkHmDqIIhH|>?88(77fy9u!D;~o`K7a5ߞ10=ZRo&  bggw7WWW7hT2Y}}}LVX[v[sX~#lvL)Ol~sRMHHN+9tެݫ< ݃;UUևcCFA%ippZMIk? Cz8fw;tSbK%KmSl]UyB}}|}$,|$m?ć; d@w֓T%=?3}}0/}Ǎm{?nJIMY[[{ܹP*e2cgѕkjj?1ed_PP HBB-\fpP5 fku;v)**6SAѹ$hcZ-:;H%RT !D) JeSwnZΝa&$-y.-nji5&!I:5޲؎l" @EfjږF#I]vvJos#mk*G:0%Px zQQMP Q{}b.;(?3%PRzAEg<z"bX5P!=Kv76; KH$&O2;3dwf[;ҁL`p ة؜Lm}|ĠVDygϞ/cϵ1P(~A^U?s垒,Yo~xyn29`>2ed4ʫFiM77fǟv6B&]M60a[k/L@~hU V"K D)$IIiyl6lZnwu#$ !!~) _5BhNm7J 0.'I jSDDӁ3gۚ186Vryy_ Ù4i޽CklBZQ)l2bZVۄl>קweBѳgǎlk~fmf6^ɷ}w+K_A=m-SL6Lz]޻ޫ[?/K1{ӴMpr,dfc0 HH"*d2Lh4$뭱Zf35VC$tyiXQ&DS[?J!^xBjjoTrkΟ?UwEQrl6^hb0O Ç.]G&D]sCX`r ӷWB۷9S.iq%Wo~8lPz2CR#.@@E1{۷Ϙѣ'N7n3~P.\Dum3',C1CلvQҬ#xч 0̊bНAq8l"ʼnr\ɔZmV @x<6[\xcona.~(&򷛘LaF>} R\|/CHqEG`0J7ѣG͖GU ؄h1@l4]?UeF"jI\0po0dq^i H+,1BU'Q$iHpV^>n38xp;_t#Mh ~ 믟p=w۝Lr9\.GiE BB22>>9>><+ ^o}ZcZgC#j轕`X¸Эڱ!C^_VwT*OK ((80݁&Nk!FuM&DC>?"\*@0R@xy #)dsKQ4$h4H ϫo1ƷLͷ}w,ӄMV~Ϟ+Jo XPRr3B.Wd*Ljl6V#M;W1Oj{ƘI° ,R]~6Kؿm &BP(4܊eddR*-`[nMLLUNI{ ˘14e/\._yD _\c s7n Iyyk׮+:oɒ>;K/~8'L&|m8ZZ`PQLF" HTK$"B+ ccohH!CzNWPJ<^B.b4fd_W"!.6 ꟂԘ膨IZbJEYYL8p:nkGpΈ AI LJ !j6fhFO>z~i! 5Vj>Rht{kmKh7HƆg^;͜QK >``0 A2}NgKݺ@ : ֋>sX,"v( wWv5gll\gw4 mPhPpbhIii= hѺ6 4@EE #cL|͛¢A"ƌR G]a&q#G?v,^ ۶b;v͙sG l4`TYRq,Lv ] y`)E U*G4jnMUnxΝs\_rwf a*+uoFvhv0 !;._BqqD"Q0bİ/\wߦj ,0O VH4avb0-}f_ ZU&t3LW@.W!Vٚ}d 1n))jzH6EI@9w8NR" IDAT^-s v lݺ͛0ir߿_FFQFk׾9r8Z &qD[G ШP0ͺk &h׼ 'O>}P(|ػlgժ XzF.**nfkO_D>W+JHdJVdjLݻ@i4V55v?t_u _K S6r5B`Bԡ(_a0W NKːH p FLvjՆ#Vxv;˝8q|QQ B@Z2jjΜ7l؄*vwXqEYf=6^o>4:Vl3cM`; #àC7fKP( qge]T*xFcc/srr!TQQjt:}VV&;ٚ= Z`!n햋RTd}kj\&htmR&U1`rY ;ڄha<Ϗq8lu竫oyiIIA!rcaua+;Λwر%?CTʅ 1g[$dsb~ؖ}1>[WR5V[ctFD,0ho_{_ΝcmÇeg紤f~aEQ0r~%5[KGa0a+*+*9BQrUjj^d4+N{/L\{*`vY}6Vd*XH@(C"Ο?UwzH7(PEE٬kqϘٖncg$|9hq۶|H+oذiÆMuKN>ԫz٦q8w1$@ lvyyK?ܒ6!/\N($9$Nىr80Lgw65B=**t7SPp>U7*;;gi_1bİ/&lyWSIR{^z6ƓQSLCPNQ\V uRRtg6ʪ*kx^{ҥ`3ktv?/Y4`@@np5 BwL'L:IGLR MBBjBBMfXa[Zeo;.Ba_on_K^2\V؇k;1HR5$g^RJPܹuEC`C|ϳ۫h}-b ꄂV~ %&&TJ0{s} 4(..m > Od O KHWY/U*h|p@² ?aի?d^{Mv_)ѣ&A s]X`oL7|w57?Q0a`JjuBh4$[Ff3%C!cpgoa6w_ݿ EGrїnSK8\ήq?|Mv$)h]gx&z哇B//81ȤEI}]kN'Ky`wوBM`:BM`52ޡG nW~URS{K &L4VUY/^<#K5$*>>>9>>1+i?+E-ynv>L"2Gzg1EҕP8L*aW(Sy!UWWfZ櫯f=p  MF#R)l2jHJTt-xwvӧߒ{B`axLh UjjԞ.h4+|>o2I@dekளSff@'Ņ}?S .}v[L<Ǫo{j._{wuk6N=>6<+لG?z`0\$IZOpuC vKpP({ {t)$}mBot:ˊj-hL}X`U =z&vSSDэڄ9džT.4{}`d/x`OpBBRukPڻE+^R))Ƀ|7;#L8 Vj(Jh4R<==Gv`(3 @ ))yG$>6ӕ;B)ZͶ.DT;="fvxqA^Nq^Nqz};}vrpF۩Gk=tĤGabbbiZ({(? VVⓒ"bW^vϛ}4ə⹶ڄ=c I]溜'IaO>X]"^iX"Z(-y'[h4>s^u./S)j cDeiL.E?T:׺Cל"9#Z|@&>?cM`"@ `4V\.ONP%D"ՋkUU;ܯų+xK& ۩[6X}9N`0\ @X,*U|JJ/`SG+D=e2 BΝn66a\OTqx " Bdmqd9~QMmB?FPxd_ E:c1cK/,0J1:?vB-U]m60AKQiHKU)~;B?__i漼БlL$**+*JV'T5">q2y豙+ ߷[+\Ybwϖa5vCܕmDNKܖa rB*$%h9s[ȌEGaaTܛvBicG~:'*U;xEMJ#/3}tyڄH?߆DPj5Ǐ1kvxotO?~jZ2dFL6U-JHtjvANC`F -m?՝B#1H.-PZzaPZISqwHL*kZp$8!0]HfBL>E" 8LIQԀ(%ҕvP0I'iD$/6S :v6m&a ϡ0cL{ڄ(M=Ba {7\='b]͞X]]w߁I'W}rOx03spZj@rrҠ(S^^wȐdB Ço&YN~]:~!4j:!>!X(cm`t^Q&-uy^x1h!u<%"O#\KL~;g"2K &+J{IǎNDb0` L&}i`@ط` ~Zΐ=HPujC&Vgg[mBg9\͹ &Rc;+46vG,.]*jK .%&&dnɌ}7}?s=w߽_};+Wn駤y>#Mfs~~1c!YY5 |>_IIbS(5nlq]&8.E)`t X(`3#nX&fee~榏 N"o%KT3FtVxt%=jd,ɥR@ M&wS` Zm"A$B̙e qDM#?dF:?ψOM~ߏ~!O`za{7s]:%%9&F`!{_LrC޹so/iTv`yǍ/>|ӡϾTk4oY]]wxݖ>ر&~qCMlmNt ?Pvs,"555ߞ=y[޷oaC.}ŝ;w}gPpR0 S/>#9Hv9`@[l{n?t*@#:M J; >`[1bĨ1 yA&SKj)>=Lg O@?yJh7EQ (.A ;r#.Wgώz@>?|ܡ;NiU+Gڼ 7}sTXǎݷl֛N=gNIqm[o>=#>6[ٝs|O kgktvvFT6}ۄa51|ew Bh2Ҳ[P)mqr9}xqٲ:..R;s 71L\\?cZ_za~7hvwպoyj^~6 \{nBѭleS+A2RIH~ `]7D !xӧ3ًaQQj}exc ȿ/\6Mj /`:|> o{_Yp8R쑛J\.z |36ݻl2W cƎ+߮J{hԨA(n-/NԹ[y7\&!Ĵ apP̱_Z٧<+{HoP#zMrtO?oNwM7PUUUYSO?3<$MӧNi6oꖛ ̵mŒpL!dVSd*ALvO0L@QTf(0 BΞnUΝu]M5ҡ֠U %$~esWt@`4 |>b1In!ps6SWniq ;fy<gv'`SOf`3_⺛6[6Xf?tmȼ%Wt &@$ N8aa0q„h6bTp̙/[Ͽ/,X(2`u7Ll;b~ḧ́=Dq Zf);h;D ~X*UjRgLz}i1Lq !!TW&%h@>sH'`V`:1KiK⮦~~oM (aax OpF#6TF&49X,ر &1{Nf,?p`73ș1s0J]e|Bwz=ii7-@աѨ.'].G 0k#$yō`?"N!LR!rž{=P(79B &;ws]~/,]Z^^q;r %ExVt=0k Bf3l&>_&TZmVl 2݌_\L zH6Tf6~޿X B:Ϟ=ѩlM!bY/A\x&wch}v@$+a8/aSc >bȔgdkvHKKiԿ=C:mjnGU^VU. DV~G^ٳWm*{{={Ǎ=C˯yyeg6 X&@$ ްg޿5a>JN;:蘶>6!])g xeerV$ȤR5*J| HJꕐ .WEQ I.X, S=xO>_#? ~ b Hg,}MxPcs/,[\]7Z,ZX0]~6v׮5k ?4^!zӔڥ6saRIϞϻ{]24%%'OϚ5矯~cVؿ_o9:c ,FY|\.g;ow_na00fli4IJ6))=11n7e;`_LH553gI k ⌌L dwn?[k2e*WHьz~/i!2`Qi@ IDAT7'[FZB$ƴ3Pv{@ `rYQQ='9rRhzpmJWms &韯7h4p/Z7Ʉa l֚+**6`55 JeF()e2SחL: &EQxz}Eqq( "gfݝ%3ALp]UoԸ}^gh` R RbwDpStoU&`A䜌>3~ܹ3:_mhT-`}OoIBwϧ}wk=L7U6Qb \Pn0I$L;))d ^;tkBu cy&Hɔ CՉ^ԩc,{n"UIc xm4E B%@TC 2 @%M,^5 VT*r4MS)IVA͛0~JwaС#](W_[ӿn[Ӧ yenL$o+mBJu*BiV<"(,,ڼ[zM:t\xwD9wl۶Jԩ7XΔ)ݻgiieKxϝW(d2?*/įѠKdH Ol -{~ذ!!]-H=2쭷`l'[AM}9^z3KVh471 0삂{Р {D=C69;hBX /$yjj\[Mh|+ ׎w!Z2IWg7o  ((3fJ }tц #9rcLH߶+VرkΜ;?~4(or= LוلPv{N8 _?qv{US&&&8Nu9J;Ï;~^oWx!\WJV$lFa0EQy<.ZM'SzgSEQ] o_B2ja'x.Z`ڴ~%;xbbK/-|gΜ0::bCٶ_,++7--L c& en AXNp6&\k^4=/-uv6o¤I~}GǮ]/.p8.?^0#B(_*Ze  9)oɓO& 'O{^zԫ0{,Zi:hO78Y} V^tz@Ѩ٪w1Lg rB*UhIbL$y-6!?B IlBKg:txܸ1cǎ^BaȐ?c(JR 3O  V鳲2lA߯0LAlf,$D'11d4|L#3sP(DjjO8 `U=B…V-|~nL&4ۄΡ ^ʎ?vhD4`#*rA,Bٳy֭@$I.YX,iegoA#F {G  ,u9vf>|XvvNKjCQ#G?ZRtti;<>?FNT( iZmj4* j9(!J"@wa$b1uB[ o6@־yÇU/8ҥO>zmdÆM6l[r'x^@ S6ys@"6ʎvyyK?ܒ֞l7.c0c.կJ0KEnofKMBvv8.B #9r^;6,$Iwg7[_¢ z^OYY**BhBqgw |RS{ef(!tѠM(j ~޺6d2푚@ۄƷbЙ0 b?%<WZKniS:KUUUO?\6!B[#$p8mMhE ;v+ ~m};o2Lk/]|]sf͚ή|u:  蟟_puxs5øb;D}9RIH`(W4{5.6VnwMN0TѷoABPRӕۑ(HR]}m3vv'9jMTך/K~책}c.oB6mRa,m`0CmB(_Xdم^{] ):zId`/%X+=z%A kA0hQ(;wQ=n݆`fLqqb:Q,&SbA !IBח nJK 8uh05c]D")IGNĨfMdlR0kdeMՏ:M6 ^LJLzCDjZ &<&ǡC:޾֭o%tڜ935Ͼx4uGa0r9\.^A&S&$hfl|[` {B#A/@QTfXOPS=T bצa5Z!l?l0C7 Fp[|RA 4M٠/k>a0GlB78MsMS.]v DlzD( *VVUYMʚF>`YY8z999ro!/\ шT*@z j9s&n`Ea;}Xm'!I"D *aO>wHJJ\Yvx<%?3KiJ%&7\vQcOt@mBAw#F O>M~y'>/ V"dtгg00L#HCbiڑᗘhKI+lƕ|8}4bB&d2$푛 r:bb*UTjSDh~gi5<`Ȑ1\.!>q0ii!t^_ْ%9AUUtɿ#F |-[\%Kx~wmMJJlkvvNHx93p?P-6!]z幹ssO7-t[:}8BTuˏib $wRa~`Vl~mʶN!Px<޽OըTJ] &xee:]RQ(juZo[MJ{^TZ_Z)fg ZY\*UT g櫷5Xrftm~V(˗/9vx;w}zgNۄH w'>mB45#&R7/D4 th|a%̉9A .@mKwp >7}~/l6[4ƭa0FcLRe2LtFcӉÎ0 EQCLA{}Ze KnI LZH$CD>!=y4X,V@r#?v ۄ!lCmfiw}ͭ  Wkx1\(@M@Do;Fn &ty:jV`00b126B\: WD"ZmR>ٛr2gZ Μ9T|8nwOR-`aQQ-Hd v&pyq8MG]CMF 3eƘI#&@BfRHq6 F4Mt/ه!a"\04umM`ٺOy퇒ܯHa`! B6Z!99->>l6i-&#I@{xq<\.Gn0 I(*+GfϜ9m[l2t„ (B]CVD;mBg?z~i#OWŷߨL4حv8&@[e"UJZ'P"K"h4 ;=\ <_ M`7lݧm|OS smpKJ.VV* *FMjVѨxpzLg"* ZMg nJNf)WTw8qKp!AT0 /$C믿5w+_ڱ㷆cI` I@5 W #qNoc`T QH-ru, ~hiЄ?Г_D0̏s/G˯pC[l}Y#:L+<Z`0]ߧ eJFW(Ja7*pzL0pp\ 9}:n7</+k,Aޜ>;J:҅BpO>pSE'; p[i-,^[C>3 kv.c3N`h9nٝ3H *RbdaM`>p@vΰeFFo-?TVh߾X(`ڗ)jئ!՚6Fcb0(aFcɤjuH$n`L kX,>c.JR7:?pÔ)Jb7OaM}V&N H8X366v E  [mJ5w9ѰVui'0k: +S],**UROhRVPóS6O, Pu3'@0S@jj>tŅ|álHrd" OL\?zo?i~A]R|ӪfΤ(5k}dɓ7nLyGU=Nodjz{.Q*_O XQtwikaK !Bz$-M&Cz%>>as=wyσ###+8UJ%M+ZA"66GGi+\Us9j<}:IPโ aYN/rZw'%:]^EkNg]uui HR4q T/fTsoq bc3GYRyjo>y1_eP?RiLQ@3cBl8DW[n>O?,Zt[𭸸؜ܛr}KYJ!?rA Dw3<<<aϝ;QX:UÇ`l$%e̙9` iS^'KPeecA"!h4^*(%fyرIIEܻyd2/\u l'cbZ INΈK4O Rń 3!4uvpoDg C=8$1og1 v.םrŽx!s*U1v+& III6 m$oe/Z HG}/^r\FcFcIN5L0'9rN 0д#cbUUŗ.>DRBn:6yF5ۄQAЬVkbjbέ TB CD"$&&v69mD9k^/XD?E~Xbu.UW};0Eэ9 Hy23HͨQ #*+꽞4Gzo=@Mt MK8ҡ_~  * @HhB40 K3 ˜1C[F#A9c%l[n&e6;v=󧧮&5wؚG{gӹ篙;'X?~pԩӧdϿr.L6uK=K\ <5{JR={͏,Xxs_w!L(;IL*JEs.~6IP*as%!oM# #KJ.]  }N<,xn@'{=@ AۺגQyHFl @<4MͰ4C 0` K,wf @@}\1o[n.))9w1P~򉵷v[YyYh/J./ѣG:|fw/Yr=wzz8[a lz&$\”\ . Ϟ= _^4m)QZIօ *@+)Z̓Z D"RS(TN\Vҽ+8e6ӟS>23JIHHH^\ѯ AeƶI6Aۄ0)@])Z]]MAזPV!(Q )t"A4Cn` P& f1|ay F"AfRQۺMJ\.׌Y/`90?p6odwo&>7 m'&tsgv:p]gΜNDNNއ~BӍ =S&MX`ɪU>VǍkmR3+lY( REfۉ{}>g2 C36ЬPrDM؄X@ 003E.ӓtl4Hi&_\dmM0J,`թ& 0nERUNPi4jlno$"hܸry\YwSS3\ӧ]1M`Yc.N!i7~ Ӟ_nYZxt㚰qœ'3^xqN륗f'IrժK[L4uuիv͵0o\,BhQ[~>w& QeBaPl$H?K36.c*`$v!f" RղNƑHHh("})|lBD{Fsػw_xxW%6 l;׹ M]fsim-Tj"#*F|.uG1ӴZ` NA_PƎ! Ϟ=e!h:9OX)Pz. 4e۹E HĜ\YYg/^snj5_a[^{MҲ@ߐ x.^hjz+:疊M hXF/ 0{Ə#Gd@@34cY5 0>Y1M~PH3 e,ˬ\(˲0o5kVoY~{ݴʕ.`y+e/jQQq7ЂpqkVD\@rYq M2 cLHe鬥II4 |YYG].!hܸiJe$XQQw: C!Bץِ%hT( JeD"!IR(q]PW#v^4Ab> h7` D]iW^˗.WRݞӧt:@=[~FQTSL:yT6cb_{mR;gάŋmnخM-Ih\`eBLHr+YfX9E 10aP?DӹH-6}̘YYp5s._./l6{k8NX`I'Of6T@=u%<i[c@y&LM?K-,cO ‡^qoS@ p#GחT'Ls5ib^pn6}[ ]v1@.>06ew߾_͛{L^eee\{O:- gرYz㍷`ʔ'N Fan"/>W\\issku[)էgm„(}ZX Mh@WSSnT*jJ#+drMS{YC}P5#GN$uiiA~~CG&qsgg_yZ#222)iZ@&"G ""WanC`c0ð,˲,is|>r}>[zv*x>˟Ѕ `M?jՊ ;v&̝;1tu/ p4 &qw+sJ'mB?nkHAMOg>`r|޼9r0--IoUi:hO'Mq{6.6mz!oRo>̡yA=Xӳ6$Э9(LI"|1&4VĬQtԊ%2JT41QhFSSk"#5GOs[3g%$$ .;pujc ))'K 2&1,Xx\VkMYYegu@v:P͎hƍD{&]Jz\0Wn4|>f s***Bzd2ŋoۺ377qT㓇^޺ĉS\SM[C#B%:k:pBbY|د3gN1cڳϾ\(?s+Dfs9N>㊊ PUU=nXnxE5^ gm NVDd)Ӕdc3ަO]ܿlBUQ\eScN.bi[<}F1bH$~v5;HpN;rN%` /_.&'%HJh?,A :<:HӇևjv!Fsu;R$ɫ] e1cZDDO?Iu:ʕ˥R 9|3T*%MS2[jyn$Qj]MPi}|% +wEnv4ib9C f,&ILⓁ5;Ko lz& 71Ib9KS!@a*&ΖEp&Y6Y*U%%X^[k2*>x8Ng9r@ @a̙ARnjYrrZD" 2V('d4p/_>gՄ65soIRpd#7t3I(O 5kV3 SWgKK6mZbrN+e׮_}wII999{n^U@w޹hҤ :W7@RR~h4,W߶&nlBKΝ;cO608ETZ]miO?g3WXTTn3Nڄ~w ڬߢMh׽VTT}yy`SN/Xpc~~EQ*1yį6l~4i&6_ 3q7Jh0E!b$/-M0lM{g\R^B):ztg0z}1M*^D=zAG]fQW RtܸYR[k3jN:F.W,b 偀_O.CHd>GKֆj:tdϞ --WդX<|;$vJ11ќP8~mB<_ p%\trTTTzMA(;vB뎴<% +0/_٤w7s/)s-[>[6mjh`. s/,| COhr9!.{",f2,r4;zAjjӅP͇j"zɿ啢bXWRvF9f̨[O6]k՜ }K^IB:u͟ dBa̸e2a`3v\vR*F&㭭u:.] ]ر_k~ɖL( V\aæ˗^xO'Of6 Zz&DKt ")(.<S7(F x,<`Ƕ}?i;]'a>cwۿf/.).޹cM }G%33s^|/k<ǽ˶t0Zv˖-/_nݵ 4UYYRYY"8.&&&)&&tTWV] d*?dP%t#GOvF%hڔ ) e₪ڽ*MKA =NaPMj /6, b-[ dBWlܸ77;˗/}7ܸ]0ނ @BxݺdzS2e9 -6PW3kC]aaQ:6%%yΜ=|qG뿌8%t1&%pwwo?=S@5 $Az())$ڄCq{}f~_*P~8)j\FlU#UqSz"@˜'ia6е̿EGٺ3x`"8lj8 T3Z(pg ~@vZ6)iHDrX#č;$ݧ055#!!5 2lRSSOv6jݻý޾{8{|v_#hZ|sc/^t& ͅjU"[ ;wy~t`ZWmBBaY/<_ޱ+>r\.}/QO5]v J UJJ!v:11zpved8 IDAT  [n>:С=jݺv yx#ݳ `.6I$C]qzݴ"hI= I2"Gip7LBXӧs# N<9{Μo_x;uYOr,;z*++cbb/^[n6g]---(+1㣢IIII.l4+)ju1>#cX,ayygˋRRpf=}q~H$#bB$@, .rk_e\i4ƫ:H$F*"L" H$s4( Q?94e!^p%Tp͛0wqK6n|G>~o‡`%K ⢣. h-( Ap{6)iRE !5^74U D4"8,;aXp0?8qI'\1J?SRr㺧=2aD͛zf͞:ujYYM1^ſkAAAZZZ8؄}jX@ ؈(""99f3kkM| $)=zNg <wv1acccS*`"tÕHƌ#˸' 3(s#X`2Ş0`=zS*"!A8Vɔ6N` ,~\I@bp\'NE>>g톔֎V-\$8mo}h};bBOل~ p ̝s.]rs._閿UW8 ]v \FPX21*L*!7CW-pNlڸBZr,%%$))QP5,t&@FcLIY.u٩@)L@8@u`HX m'|GH}~¿~U Ve??+ڼ}n~ߤK.-[@h ͻb&BӴTn2D>ZUja:Tn &"!̥?3={,DI$=E6<9ǕE :622esV1fY\Rr*YDFF&$  `BdAX.Ne9$ b7^ c.iBP%`LSps1 aYa414MS@ @Q ⶦ^!tusOƝ Jҍp]0ca-zy䱵J`6n'BFd2n}H;ho1B0h9nᇗF}AGm̊$ $:h(?ЈF 4eLd:+'SwUyބg=dz(ˋˋd2^k0z}4EQ55U&S{3Ic@ԥKKK uӇ "Y-.+(N\PAͦi11X,ee} 666:zR ;p` a J cbiyvYW[[Շpソcv׮uG:M',܃-#60ա:U+ss:bnn?cWzcmp??~k<:9}{Px* \nb6ƂT(3pw&p?v.N83`eEO ̊ .;MQ5>7Kӈe%0ap[ (HHX@?HeBx\yy*`j11 11>d4˽^w[RR'' EStV{`BH4rdonnvuuW!::ZO&!;u9Wg_bbD@,e0 hfY9Nbi HHH6l\uK s瞻FƍYw.o:MSv6)mB2mHfZbI2mG 0g̅޵շ~ٮo4:2do2' ~VӒt:tz=7!t( ej-G:li?l8B\.0t 0OQ!OQn*2~1+bH( =G D #Ya6A68VZPp^Z.))-))qLUK_U4re V11C%"lxD PT#FL K r1\<;߫OLL7e24$2  % @,K㭮.,JK >>!!5|rFrOsߴa:rGd4&'&O%-~BhD)nۄJ 9g8tɜp圈4=v7 yyL))22 =1/D1RP!D$cq1BPnw]EEQMM'fhsN̜9 >lA11_p8|Up8/r_wmBxۄh ӿ翺XkBAoK.|o_tR)oֶo]z_w-BH \ / niZ @ xivw];ٱsWwvEhc\YYr&TTV ?ݰ \z[}Oxx)=d@A >*4g g*S@(@"@" "̸U]~fmfs\!4NMLLKLLK\tř1HOFr՝={*t.vĈqb!q [[[v;$NGs0LYY޳zE2zB+0fC t$aLӴj/*:Y (*p/Ӧ]7~, 7ذʴln^/F΅37䡛63$|B||\aaQwZ(,,N k~̙쌡C?t#3wͷo]bcӿzf.w/=իj,ܼӧ]<ڢ_JJJjZj.gf"ݶ Z[3 6-?t+@L}'Ν8qŋYŝN% tmp:o. 0hX܂i{ʢlBqPDBx<x>˕:d >?pV1L,[G??<꧟ZT*7miLȾO ۄ`BaYT[kBEFj Xh4&FG'P]Wg6+oHNHHHd&7,,-))6">>]$|>p !UY{KHHbq4%2e95G4i"".\8ETgo&?݈ _c ` B\SjKʺ܂NfTfx~m|P(*Ο;f,P( 3t]]ݟ[Fɭ^WWsrs z"%Sp6!#:]ZOx0lB(cbZ:RX6Zc1b1ݽX*2`!b].GQQ^yyah崴 nv;>c R E[~rqAS6!2B<%%;B!%%[IwB!8?|bsUUy*ǟO>ZϞ;=m7v?؝n8ѤW uw—ۄ#`oMclu.S*#u:FcJMLKZ0L7EdZ1Q&q1,X,yI2dNgie\A`@Ny.ǧh4 !$aGb̚UMGñI#FL2e^UUqNNgEMho`wff޽zq\ڰa IbٲnO?O;8ʱ !|#G̙ˁ]naںfy/,["_|_Xpp1!!a͛gzc~̄A{9 6IfIot? ߣ} xUx0XlBNi+, ^5FEbbcbYkkkMKTqqIICHPyΆ Z>Q 0 NӁ]:>>%"B+>o",MƘaf0E**-ȑKJ.N0 v4m-\yMGǔ~H1?R+ zⲶ\j{=^H +#{gޛߡ#FwUړk9o@t:W|yiMh4XlB(寮..CTjΨDGEj]zHcT[,Vk-˶@dbD\2M`i3ZkccSH5\s Bܥ<0Ls]qq)LEH1h˺m##5ÆOLLO,.* U62_sMgZ|,$/*J]ZZaæ++͞_L/}T)Я݂_P]m:p?pPu;A~~"HOQo>qۄAk-< ͖z&cMp@DAEX(mllj\\*˲Vk @djp(KB"0i+(X]]>| Bc~@>kZϝhc(qqQQz'&\jj۫ǤOKkKJ.UWQTW7= 捿eR36u eo߻Gݣ[69P|Wo/sr:an: M5ֱۄ&sMk|?m_4d6mB>bȨnI0thD$A A`blڲʒH]zcpo &N(,[VV\TtKN4P1L]rw?\i6W*IcL=zJmFHgf5u MZʹI!MӇ[;\~ &@ ʛ^_|lZz +55t}m$y}ө}ݣ~ElBUU+yMMyBJJJj2 n/Yc̰,10\2eiC\@}EQyyÓh4zA` ]bi7岟;w<''`I颵ZȑnZ]Sc3`D$.q)$I{WkѻO cM$`$oۄ ;4]c-BFSjN&SD, C` _n)iPRj*+ytQQHm\\Rllx,MM& ^rye B.WTj*JHLhG+0BeY1O1 'jj,6b\6w@&}  z=G?:f3g@||ϿMrnCBlҫt㚰qœ'3^xqN륗f'IrժK[L4uuիv8o\,BhQ[~>w&> \0 FÜٳvk\\^sMMyy#G?p&+k̸qC22zt9ռ6uڎCkv:6[TlBc&O_Zh ԠW&D҈2*""J&K@"c!,e1`e1g 8#nXBeLl{pNG .qqUUeEEMr"8V(@.)caKǘ,]Wg9Z,Oiw:B$RT*%"X( bX$!B!  8Bkqq1k>" mEǻ1,Ztszz*˲QQ8N(={!lmB3xtY(Ǖp)-csrr~deYxΝ@̟݆ o]{5fSKK?W \ѨjWt 'Q]m|-,ك]8XZiyJeF:8{,]gmŒcH$;oLfnw~/_.?KZ"r9rlǎ]E-ҫEEq|>k|XFЩS's?|_.h.wqMI.B.EmG?kWk[[u{x^U.[mk@w][WETPFsf1B 'Oi .Ss& p7Q%K$ L.K OH<:d%2`D0fz Ͽ[R1IQ-yMͰ@m!0eMMZOF:sCn"x<\V*CrUhh~\ܬu:]w#C ԟ~JuxjwP[hhnٲԎ:7]vs岯ڷbK?۔Cm.4A@+_怄1޹Æ%L0nm@O?#Ƹ⣏1"h4\UBBBTR[NJ{⥶(g$tu5z=HN֝4a%T BX p|;e{tc_! M4mu 7th0 UU-G2RPJ`Up Zwȅ wA>(LA~l݊gB-HJѨmۙ_h_g͚w3Ϭho#7%YY/Ρ0kּFt G) Xl|䩓'O!rs^mǶH  8)F1 U*oW;Ce_j ii窪m:t7j+i[Z퀳Fi] yW#1Buk+i@,z̥Z4BaYb-Ҭjjj:Og2L&CMM%$IT.+J,X&  eYF׵vahhnn2`|H˶!gd\9u kX BSN2/RZv]}ӄ@@W:y@jp޼_ziJ3  l|#?cΜI;r]|BD7oS7j" x +"M@]3,5t巸P% R* J E7!̲ج7 z^k0457^ݠg݃7nv7伸ݍߥ-.z&E=Jl*UȌS?hԩ3 \лwPX^^t2B[o}n6 gԨ{33ڞ&O=[}Aү/ @@4>J@73MfsUmm HT&ʠ D"H$R~<0-)Cssd6҄v7iBp ئybif`t(\L䓞~.=\wh {|0̒%-]8%l~ +(M1BV(%iPL*UH$RD.HeR67 fmssSssAἣ{Y iB ee7d2iOk4ASzAϟ-gg.\8Lp +BۙFX__c_(. R\*2LP>"X1<Fdj6FdC͝N8vVi?s:W(W8th||तÔ{ogmm]k@z=]E=M9c &i;A?… 4M&pLFh]%G$ HAArL&E"H$ m:˲\N4f`2f#tPx^s']J=4o  ǕdO>pݺMyD t:pHY7 ;˹PcM&uuw $I b8H$ $AA8H(bRT"yc-בdb2Mb1ls&}0P@5gRfjơNI/~lܸr|U4ͬ]ѡf`I@9=pKK6opaY cG{ *efSAb(H,!H, 28Xe_:Xb6VdXfl6r嶯@ w1wS}MKr&9W3HApE:pPr^oXl}I2MF蘛KS{y:#xBw0 ƘAH$BH$BP(KmbܙK!XV+M[-jX,Vb0jXVV M[ii+~A;٩wf9WL9fΙX֗}DfNo\tE5>Nk6N״y4}l6&i |@  EH(P /<@,n{ٲUӁh]Ywβ4M34mi+24ͰaXfabtK 2,˲,m0lg/s>T*PPPЮ]֮SO-8?Aii9zBhӦW_zU|aag?`O/QBx<޿;_W9Yی}@4/[ǁ']sz P޻v\tEl*7+cl-^s]$I>_R<Sk"$k'. 'Ƙhj'qsC`m"pb0 :-k{wizĤ˗f!xӦ-"hMe.]VZ<3 BH&bW|ȑ99y|>oӦ o_VlL҄51>ó&%izӰFxfNrijzT4@}˲\gήHEQk;ǣH"I ($H"$ "I([ I teJ֩mf,wKFy¥)S&/B hLK;7|0.P@DmI/ 'IG"D"QDDx@ N&[੢\}Iۻ)$:':_?8;.unuv=ؿAs {4͜ci0S@peeVKG5mʔIU xΜ5+Ν9sZaMH8iG[`2 n<8q!$tGwOPhjjj]sW!M7ἣLFt!^ 0@{:&pi܈0mVsorEr3n"Bp<Л]tb<555=@e;a/M>eÆ7cǎ/];~JK;wjWNIO.>}2˲dɢ;~GDSܬ]+&151>{>2ȯj/ӄ0(e1MC5ă3f̨w><t5鐿F\lӟPs5rc?VmڻOmL i~>&5=)eU;4!0 tȻ4aN2|VɁ lٲ'N<1+4>< @GϟRj)x&/ u=:knrǝ|W_}jժofjnn>(L>MxKar -HJѨmۙ_{nlrRRX\\c }Q`k׵.x&G[+^d~{]~;wl>CXgqԩ6aY,X,Wozp΋g[;]mliB=JBm'sE?2zwB*$Hڇ1[7Ⱦ[ @bY?(H4g9 ;ݹf!G]b\kkwG:tO;`Cd҄:9ն'}M;vؼy_|sϱ,j.;:wRO7O@,ujjjro_FiB ?ip\t!m{gY,wyg˖-w~{9>㹓we5&3sr: Oz{Ģ}$M@:Ǎ4!{[uc5Z~,mJkf֭[|?9L;=pD~G͞.ݝHT+w/ QJ$ bIKV ȃ4!cV]p{i`0lٲe۶m۶mz9/BIM3DƾA-]?6nX\z*f֮SK|W阭r/{@7N~hwtozG}f-Z4FQo۶3?g[ 2Φ };DK8pȾ<;;wÆVvO$'O }͹y7بPB{~Ԅz''${OniӦ IIc,xVr.e*Qݱcegzu!4Xu7wm_iO>wz9nRdWmV⫧[OA&O;^[WJ[n_+Vܼx"M0~7^zi˲g?d?s NgY GqJvŽFv/O &8pmOnkLѼ+zO7ن399y*RTYYYGMw7Mܟ!̡@|&H$/oߗ\ɬY< _o>{6ȑcV{v{|sΝHO??ޜ9!Rj5]vMwҥŊ?</^/߰X,#fz|\f1Ņ IDATuXZZV[[-<ЬNɣ4!pAsJB3gN͞0!̙4[}{uuO""ªnKґ#_ye]J*UH}}m;k!(MI8""V~?טȈ<|z PBCC!M$I@(BP(D<Q|H"I!DA$IIB?8=Lc7 =kMpj=}_+W.?xGБ#G"OVVV6,a!&>ozakI1Z4AS P(^͒J%7 EGGUUݞ6mrFFfc6-܌S:ޖGHcY֡ժ۷:PQ 8q̙G:t믿IbD,IL,"@"0P[ geYYnr1,bQّ{einmø !f2|iS1FAjn߮ ,\`vͭ.˾jߊ/!ϟ{EnS=}"M@(`ΡԧiBhO c|VV:mόӿӧfK.qƞ?YfePmmX,ƼuhSL-k4_~駟L e2L,d D&#>Adcb6t:b2fd2ZfiB4M[/fqޙ;I4x(-[ԤI ƍh^|F~g kr!LMrM?t gq~'%6G$}%M@(0&M(j4MO>!f̘v!j!!!*UHIIbb_|qUkrذ\;_mۧ;kQ@; ?/^e0zEnBTV)dj[˖~իY^6އ:&@Х0n^hARFmBP ~%Vkj~ndoƾ$++9Tcf͚kN״`!B!ns'O${¢[o侢N D t̍4;D;4xp쫯>xGnTVvzg>wϝ9sk-ZJKM&C9=/2f3g>|x?xO7UJJ*8X")Zo_G,6MMMMZ^0tWU[nO_c~B&(mgd\9u kX _|qի} Rw)Vv۾iB]@&W!4s3gڞ-,,d&1qB{G~_՝9v12e[oV_~Ѯ/o4^t.\ut[(n˕juxHHhHH(/#D 65iZI˲Lz(^|qEf ֭o? ɤR,_,<<c9|(A k_Acc׻; pvӕlg0>~R|p*銁ţ4!PA+Iڵm%/!mw;~zú'xpmcǎٲ]n|e…mulbVPPг>;!TRR7")4HREQ|A`XSSQ__P૑ ֽ¥ ֬yŌ߅ c![tXD48~"n߮^jy55}no/4A >ITj~h {|0̒%-]8%n x|:<,,J\TWWZ[[U__m46l jK.O4B"(>>y{K.ھ ݝ2\4Q5dH{>?fʪ=(_i@x&hrzrvv…C@/#EDD(jnj,}l6v⫹;^\| !PȵZ̷~ޯ~Gi?i(^'W}OUmmoŜ}.M@f ҄NZ7 ;vtL(7_r!1,*5i:7xz6O?Aql))sU ާ j@@GI0:zF=ors֮O@QEB$EA"D$I$B0MHz3gbi+| י42"##fͺOڵ !5mn76 p$ ˕ 򼲲"A-xbT,I$bT(B @#cA-aAp߹#2arL3Dt ~@+&4!@$(vO#gԏLE?˖r2mBQLL\LLP(dYzCCw܏KrT!d HR0Vl0-l2i2naeaYYŶ(!Q\oO ih{7M.mK| ҄;,a p4Mf Qk B2hА($Vˍ׊ M&CIR2B JRP(j=G B C͍FQo04 MFhl6M,=}xdHE=҅tO9iscvg;Z'ymb@88[4!Ь(7i#ˎL z֭bE;I ERV(B D"#Iu2kjzmSV:8?Lwr^r}={B鱳jCH Om#'iWtW#Sg<t>_п\t`P1u+ޗ|RQBCBBn|A auzN Cua :;Mr1giB};ĞnDHMp n n \h&8o:NQ'(rNUݺHV017`yU7wrߜ&?ƃ&gyo߹ei& hiS}3MEQѱ |j5e~tAH&R>g6"44Ҵ{3\w>8Mit)6?h5'xk?^ ~NAS>KOatO{$IFE 4hP(Zׯgx9Ѐk4ju$Gaʚ:Y5(L,4ys߯Sӣ$X PC^ ~S&yiЗѯ߀a"Q7o]P(Q*5$I"L&cUUiuuy]m⻶w!ṹɐ&;[hт1z۶#-{{V,{)6(iBjzTf.P}AaaqqAAeo̳X̞mM FFDFVsG&ۥ:]/-˲enWʃs'4s'=49+Ծpذ|/nS/T PMn 1Ԡo|b0ewLj@ 2ddxx4BFaNj ȰCB4a|V~iiɜ #o^ǥG͛TvھiB}`h%Om[3PΥ } 4SGČS,Y}nCDttllljrs/t.GE  uu5 !PjzɥL4!>dwƍ+W^EڵBbx{V-4A@7̲eKNsЗ)! e2J\)//r"9(H:xpbDD4A4MY:d M-Z4FQo۶3?g[ l ~ HnCr(7+WԓO>}y4Z8C@oS.z g}JV,[Uu?&T1")(Hf0賳/jn( $>/ M گwuBѴUrI8nnlBef^^pѣ!Z5k;w~x}3l-))X\ A=LNNJT*{|VVVA;&  84A"|g?}Jfz駟lhhz}ٳGZܳG曛vCz9y!$JVlFڵ;77o'~w.]i7ZSS 4 !VAU7{HaaQt55}6J8}~&y5s1L.9rF iB$w@RݺU{#n(zrِ@A Wffe]A>|c^sIۋ?Sm2AÇU(B,sNΥ%)!XPp[  dB܅.2˲/Xg<ŋE%;ZbpЬY]/W3fѣ8l[xYmRJ Ž О9sw7o IgΤs߫wVUu[*+RR>PBt_ !DQT\\lJᇿDGFFs{/ |_qq#HtgDD"kU].'K EPB* bH,(($I@܍HĘh=+!ao;&P7JZ3ܬiZOʕ!tH*7oBÆ% :d„q§񭷶x<^9NjcLi@{Ώ Q(WfI ꢣnO69##Qvnƌno#F$䱬}***Zھ}[0!aJ0+% 5 !@VGJ$ X& ("I! \{`D7l;ූ-WB,B w^:@W<v=[Ba&O6 ܾ]Yڵ[].}վ+^B͟?ܦl:mۭ}{ܻvHB3gN?}_/>j&g̘F>5k^r(7y'23/#jkb1w0据PFƺ&u}  F>/rMMe43b4*jRHd"QEQ\o.@c>,1fhLӴd2fjfhlv=G̝xcƍWifڍ]~҄&wV\I&*4|*F ϊA׮%B$M2ŋ6BƍOKm"N=[@(M(j4Ms7x3fL;xC*t11/\9lXBNN6=o>eY( ]i @/FâcYfJC$$JeV+F~y=K,GEŪՑRB(ۺam/`Vj뛴Ʒ8Զ&%?@Qyy~ۇ-)& [f-Z4FQo۶3?+3ɓ',k02ٿ/~uYZ5-X8BHP⪪I[NxGnTVvzg>wϝ9sk}TZZn2ʑ]-eٳxL %&&)!inv@$ 2ddhh?pyyqAAbFQTTȁryCeHpwiZ-fQkhl06/F.VVza7+H2$޳$'4glcFƕSNoذe1W37n|`0Κu%o Mjk׮M4A@+oӄ;1s3gڞ-,,d&1qB{G~_՝9v12e[oV_~Ѯ/o4^pv N|AMMEnn&.*S5pHj.tTJՀ!!a"QPkpPV+m25./P׃8Pik]]A ټ<@ C{Na&L`u6 JKjk븅\过 gYVR WeȐxRv+ܖ-Z*/s?MC 0!W_o7oʕ?t|iBE pWiBnrE.[/yUl&D$Kk.!2|Hjh0 N##AvjnTTw[c䫹++*+~tJ#F$644L$BKV;4M?`&Ipgip:+7nLU톆F `ܻ+ҙ jBKi@[߄:#3˗Wb P,,_|=Eݸq#A('$ eY&7JyyQP KT(B(j#Ƙ뛊KJ ׶F*۷|>Bw1JUV+- ǎsL)n!77?""|ԨC_Mc!!M+m šYJcǎ*+@'s&z&.:(1H}=#nu3@BDl차4\vŽ_K&Ee($a\XڲnC"ʿy f&$ [0 s֧l_HoڶzgRY\\wA_H'xcƍWifڍ/_;o,+[7>@&=7hSr1}С?܎R*_ziŷ8wE Ri C"8!atpa̮VR6Z*Upbiee@}Aүyjjj}wCannEE֯߄ox-5a~~onniB]\:pC#m+>&p Pw&!tz^)~?斷o7?^P(JL'ksr2h^~<$yyf$ʇTh9lMMk3EQ\*d H&|>Ey< $IPI$Ic@Aah-72(=ž=_0 dcK.NIGw'A89r P]SiW2D'*tܥP(*-(jP(6lRfk^.+@ HLLR#)l=ss3!P,X"Db>_Hcl;h]*"\`[aK1B-.Zqc _Js.P:푋Ӷ8Pʹ}=M@(αޝ)7_@ MHMQ͛.F6޾~rWtL4hؠACx<w1nn6\*kG,GD T*52\$$. a`Ƙ X1B,4XVbXhbZVlXLfj51 0 XGs  5/p ?6"n\ۖV gymKB`QQ ƲlNNfmm:A&DGDz,.(RVv˷m#G&T#6-y7oڒ˕QQJJ&x| mn1F`hidlnkZmmcc}([KacNtY8:UP۫k"9?Jm{Gmmນ8ܩRY͜Ieza bcǘ͖ MMZD"Irydʺ;*tĈ$P=dY4''ҥRCpXJQ}֑ e1M[L&V[_[[YUUug~CSR,vK0̞PziBGiB@gK4wǝ2KHTj f;>Cxo_~ah_5 >~DL`Nhb芡 bpX'!IJ,M[ f{lO<{^a0w 34\py{]Y5>Mh{P(1Ki[@ΓQ[(rxcŽKr+F83n"BG $:46d: H5e1@ މ! WǷwm4`@T*( bXXW^~vYtȑfݧvچ6o~ M[co '>啗rV0`H~3H$Q&A!̳^n(!QQ%G, EEy"8P9&C0fE$%h۶/ ϟ3~|I_}Mle G)iBHl@|&GyO-Y@FYP}6lTHHdξ0( pssӥKi^F #cbbcb1WWWf ';O҄^w_X1#ʩS7lXò+3fԘ17o~l,[8q=XOG?)& 84!-(@ߤDǏ`YY_d@X8N,44^Z-D"=zH$F!M/&J+ #66V{YSEϻt_8ݧB䬠y7eWtv_`+ cb_/0M+WϟsIۊsvBI شil֜ڲhj~YRDDA \VP* y<~Eŭ7rANI+G@' aju^ߘi'*jCllX:f$>_1bիq xIr;,[YY ]:J-;Z2Hǁzׯ_J/M[Z-$IAqSdf^^pѣ!Z5k;w~x}3l-))X\ A=LNNJT*{|VVֹشiBn3piD"~}ɕ̚O? gӏ9y|չ33eymy}M  -.B) 4, ](p[JRH ^ Yl˒[%YUy~m9sfL"i/{|V~gL B(99+44`*8ikBBFZFG5B`B[[C}};*Mra VR_ߌ##Vn݁wWȧgmn=~ZMla)zBCC[yhhh*U8iFZ 螷I[`.\t:fT_ضmM7}θY+&@ L6/Wlۼy;y =Ko^zPee;w^YXx9v1x+**O~}޴aN CaYJN v}OQTZZ^HHd(/d`BмuE&导W ˄Z,Ʋ+9"aؐra?$g7q_x):Z_jWdgg5\^SSR8fO>c _53nJ @0&xhر>onذԩ3Ÿ/oDtw(_ &&_t hNII:xMῼZmlT㏏={ "a!؄^?TSSdF: phHWSfVyjkKZ+226##a!`З5 3*?A*U*!ry\. CQ"(Bc{㱉0`  C w֮aiپpѣDž ۷okoǒ  ߅_)a ^leSԬb+ Q$B@nTGɮyީ㏏>ܯZ(Q ۄ %YVL]WWzǙȨUx gwOB1 >k$$$D F*!c 1Z废ф244$mԂ1 ==n18𲰻J;;p(Nn .CebA`J^لi v_bϟxwm+~л_>}ºuϻ"+**L&͆ Z##da&劬H\'`R1,_Yya`o}Bss7D"y^ӕy R4<<&,,J e C#D Ic0<8j6[,d2X6ZV²`7NN[WRᅲe|l})cۊc$;7o |챇Xݻ^:?S&cWTTo`*eٿ퓋/; u ^y5 >|:ff\*@ anmMW\eYaBar9U immKHjcw<8339tϮhC0Ak@X@PBBzH7&(5 47vvxyȬ50e2[R`KJNp1 Rd4}%4 :#Yftz}^~G|k7MMo~ ?c}ŋ~xMM' ֶG=ڶm[kk뺺}@lcrwޖm @~~-|aƖ7|GH=oXRVV~9U8~2UKof d=Bg}.$~_ MM͏69˫n) c_ziGef6_"wH;>S}=ee=Np{Wn/}`SO=-,wtt޽GX[us64M|w6lX󸢢x{nN 9!&&)""d2VU;އF&'gb CC^ј*&!##Om6[IY~'LLLNV*E;myZM ]B/?O wvR@ss/~+J /<{rqaṫq9i/8yUWmp8,,@Z/&LGP(P a)'^H-#"򓟛戈pϕ (DG'DEŚͣ,;)NDDL||lUUдūV]!1TT4judVZa&6kjfy9T*SSs#R0 $d0qQ3s;gP^upG9?d3<\Ͳl@2*JS[[7'bwcN,vC捙?1 'fdL0׾'FgaZ,bIMaY[UU<7+ $--bx2!ye deiM^aj몭-<gqs'u^xaΎń؄H[o922y#t99YB:LHPߟSa+&8J0%K96a BCCXݲe5Vo;V\\m#g"#c5Z]]lNJgZL&㴇YvirZZnTKNBfDdd\zzTDcOXC--~_o8پ`_Jekk/l2Gr"vMnbzsDD/7qBaII_ik+Ϟhmݮ+&@ gf ah\f2~988Mo@ , j&::e-55%V뤗Vb@&oicY]332 VhZE*Ufe (ZQ#$LGFT&9de)Mmݺc6$?﮻~O6o(QQk٩x'|b0LSS{} T/VM"`>=O_GtC3g"[ژa K8IǧEDDLENa h4ڤLWU]I5k6TyLĜX% cd[[k;Y.ymIIv{B$yW>agL8cua~th0rvuskyqqYqqS1[vah"/669)x ftժdddZ5 07T ֖LãFGEN)\^1٬.)'%eFG' 0~BOgd2x,KK?'0*J ɤ"L,D"y(pGE!D/YxWH1^x79{-ip>Kq"Ӵxg>=޵ܝ8?޳k׵6wǸ5@XN(LbrEVG mX,[zM3WUMO&ZU$#Vd8GfdJeS0f3֖ttIgTrL&g Qy$ƧFƄ}wƔ]1B15v(pEU7ݔ6P[؄g?mZ6D(M֎/w9Mz2@ Ljl< $JLL 4 UUΓG:VG%'g ޺ΩjdGE &56ٕ8`/cX\TFE T*i7;BDڽ~\v~v̙c۰ w&CQtRRX,rpA_WW&320 SeULIɊ qkk J1,--RLN H.oahh-B.(5< zȓO>MwMX$o#Ͻ{"o/O6@  EQərbpϩ SN183n熤iqAVH16EETYPE*KX-n|JJV$KcS$XFC ֥\gϞ{]˗1&,YM7 {?V&+| mf$<@ P||BҵLHHH 7 mBVꀀ`d(-=NDD0nm^wxxdfZ108[Zzc.*]1,;:jlii3. Hu]gm>inkJM &,mj/]Î$@ ,ZmJ422\8M`\\`jk 4MmEC__Ty 6˲%%M&,ۜBQc1p[]]=7?FFƥd(*4b1vuWApg9DlR_)j)r B@؄1^3+y"e̮_&8#a;9&&&188ltX1o/M 4&dʜ(qccu__kB^Q믪)i_XL%%g Y600$#cJLQa<6$ͦYb)nf&6a/ߧǤ0 @i/YQ6P &]D(,W&p“(C7aklQ(!(-=;HhmjjDbϿ |yR[["^|sԿo0Ol²[",>Qf1A2M%,kso||Jxx fcKKϸizժbTR⦎0tݺ-|'J`&; ,,WcXLMM85\|k?}:>aV6{uKϯF\!'ʌ5[Sgwۮ`u/~|o;#8ny1}h 6H CNae B@pll§gc_Gp[}}2>𡇟{ͦWT c#1F0݄`ac ӳ.i(lsn 6@*։hFk-WHQ hmsŘ8d𡅂JeY+P.22/caX s'o6Z&6a)V[/o:?޸ / <붧oؑ^XlOzƘؾjMPwN(Щ5!:P(gaIa | yn#HKKED(3ؾY<1<1cy 0V1U[ *M A jS8ol2'f[hVkmmeP(22 BCCCN&!B^&\M&Cq˰|/RTB||Zbb<788PQqlEs,c|16z%5bBAMiU U%w;Y1cf>o͑g1g2 D`F@ 82%&6avl߾NpAPBpc` Z`V@ 8 +fttSVGEEųνMP5 #뼏2,7w#EQMgYzL!s3V !!YYLx~FKK WBEߘ׏5 KʡZ9 !̃ (46xV#wkbB\UJ-^mȪCʩlB\BJKc} @0Δ`olŠbZw*J׮]Oe]uM]HDAuX$4ç[Pc ̲MmӪ}WM ¬J剉ZZ <,,2&&e,6qqjuZKJθVPBG}籇 g@l’1jB#$9V.H K'kϾu@0bF:?w}S}#&eQ"tm7'aJ C0#m?F <8&E<kw߿Zut ? @ xH$NJb1 apZM8[}}~l& T̹MP(okoE£GgZ:?,pv}JfX,pUU[lJMMӻwrgBT?T#,}!CXj1*YxuQ`׵&0LrrD"n봗&l|CCdtڋE<^TARed˭]]3Q YKQ4` :]EywW#33д!GKKϘdaqKL~>=ݵiDZ\6Ek0 cNeBۄްWlۼy;yҲ ""a||K/ܹb+ #ǎ9<`EEhu}}uFWd aZjq:?FdّmcDeaiO䱩~hȗ E'&fJ$6{y``H\\ |c 22V \r1.a*)(B$..]:mĬ5jux3,Y_WW,׸՚pQ%$e65Թg@ Lྦྷu'sG{ǎsÆN}Wx5>fr ^M  +l&)FM/ EQ6ZYv!\OrD}ﻃ:xw5QQ쿿ʹs+@s(JL̐˕TqP8׃@@@PJJԠX!;@.y"IWEŅ^0 SPM.WCb/8&X2"@&I L.bH$QCQh[. c<Dz#X) ! w$]1GmX3=자P;?M[8P <vB".NXZZT*v!'t:@llLww϶m[.]*>sW^GG:rNNvee5N坝]|$,,~=BeXxi`<1՗nШxy˷7?o:fYpLoNo s& P||Z@jxxu"R󸩩hq+,L&Ǘwʰ(sr446z 22:99GB<.rLRQ,V~*-;ԢCӴJRd2B!g 0E B,O9s!`!+_E04ݧOkg?x:Fla>K 1kA=J*!! kF. " IDATZmbX,sE%!!ꤤ,yhliT*$6WycHHxfZ@CSSykk{.IhVBB"C Mi(W Acccq[yZ-VebZMqVN{ou T*,_҆؄DFGc,G슲 ");@WlaYv+a+vGNBBBBCCZ[}/̨tІ9tϮXvl+Ƙ9 k|kc,a 2#cC\c1-y-r]::;ꯇ?k\w .\rNЉi/?vKDddZo77h߾k_ҥK~SO b9t蝜\~:;;-((x7m_~W_}/p @aF$GG UBjj1vIJV1ѡr顡繲V՛fdg d|Лt QQڤB!hXthhBCÕ@T.H A9 cs,ϲ6LfȰ^4a$>#rPEсAy{%&Yvb50@ çSeP.(XV~x ?5{3g{ȑcP۱c{EŘPp+))l8XO.S4p|4Zm{AX1WDX`Nah㨥t#dHW97>arWGQ.R --/\Xn}xDĎ; ×_+:::227kSRƾ&?~f<,灗AAAwyƍu:M׿8qb˖׭['Hz){mW_}=w.&6<ab\0bVl6 Ã}}&sb#r4#jc_  KҒnw#=D(Mpa;:uھLV, O:s1n_^ӯr76iaX…ϋ."V(sH$r >ofqY3؄%S;\}O^ĎIG{D(n&LɳϾTr}@YYt~^Ձ[oþi_.(XSO wo{{\|[E'|zŹ=;a``,cBSWec|;Xc;N4(|a +)9k8.=#^a?SN~xG._ 7<_x8qW_ՙkܹs{{ӦM%%%!;;[P8pf&ЈZ[[fube2Err&MS-- bqzBㆆ**(55WuHWR8ZRrz])y@n/ JJM hofYdjPKyʝ~zQTsniix>g?{̙99Y2|^<@le%#")LZMW|?)Oy`ϋ/}ɟ^PJf60cA(lycϜ9wL,Dلᯇ?O+*[1qO?zh_QQQ]]]ZZۏ믿f2nbÆ mm/|w}-|ĉ< ?={GQTGG< 60ǧpW__aM&ʓ3iZV?88)BHNjjJ&GFhM Jss74 sz4s:FDhSR'pQb^Q*UZmRXXL@2#< c,&ӈNSܜ:16L_}u*77G O 斀HڦwW^\4 K"#ݘa*flVXϗX"`%0˲+e2Mxun1@LbBܲd3!9BXO;vuzz^``(޺:&Jb`N%4#)=0FcGGK[[1N"0[+<|{K;Wp:&&jϞ׆ /mqscL ")&`#'n؅h٢!pKh"+*B,D7,de6a,qԬכFL6a4S7JQtxX 1pZs8=%ca,% yb4acL*ESNP 6r%iibnD"qjjD"jP4MgfÓ{HL [,ꇅE&& neҳ,ƦRR;;19226>>YC C[[C{ҍD!*UB )RH$DEi0`|`B>^cYo?`,ho Q 5ed?`8~,gyyM7M;b%Q&6@XP `6Aɰo-kys.;wʄ%6Foϰa`(why}myl%LF$K^:ÈRSs$iwwd2EZZחFCedHd<k<4/oX,pGGKggT5\!S#%tɋNkTt5ko %Hi:==O.nj*ʁZ{崴\aF~8񩁁!`XLZP|cc}NJW6d2:<MwM?Zb70+Z[+. {fo\WM &8L^'60{(NMU(T=MM瑦\"@u̧Z"N ĊzQ@8Rs(e-S&AIYVQq~N8(U E%rԔML1Kd2Y\\zhhLiZx1o1Ƽj[EȠճgϽbVt,q'?Vcr{vWߩX:w3 &?"|uħձ@;Nah"7̡M~˔/V$<_ 6d: CQtzz^@@@_cc$JLjjBu75Ռkiƾ.AhZGQ46U L*p{{KoJ2+k -lnn32"1ƻ0XSSj0}b¨x*x|l&ahA_ ,R]ۉM'لiwSgUΞeVSNM!B@لeM텵k|ؑd^Mp(Mď 鴴@\x0e&--O. b,3sEQBĞ54TM(*32beYuۤ RxC뫫g[VG21ƑʁYBVGDR`,IV`WWkOOɕ`,7uMX` 7)V= O:+cEx”Biyw磩բ9w Cz"&/Y~S"܉?&8L^&L5X|V$4M u |LT#|8TWV^vLU"㪪nScVZ'Pf3ƁyAAja?6Z4^PBBbx<<6Fz{[[nf惶Et$%BrA"qgkbiK "V&׉M f22V) T+|8s/SC1FVY\#$8ح#JxZZz{}a&Ka]MM:S6(Ha,khkng ]ϻ#o? խ\Dr PZR MP M t9myچ-c`?VyMX0 JPw54Md2y__&$DDb)/?xbݦ`h"";4kjvۘqĭSS a[[kf[,'%eG׋`cf3t66͉X!2bfmSqSn?x3?޼wp?7N;?t"w05ۄO. !b!E->L&6eez{f%RyOϘMi:;{=Èe"A JLDa76V:fg J*ܶ$7wH$ŇhiB8ki}MӉBG1`Yu:i ^h|Νi0Bb ,9Cl 2لY@ a6A;_mZ2\ɿw$I)f_ A$gfʞ*P"+ IDATef%m--u ɲ hpSS11 |eE|X*hlnujZ-eegz!4Mf#Hmmh UjjJ, FHkkCw- ^m_/aS&/N+b&+D(^AlaÏ'xOvcXxޫ+w?ѽ0tݓOp,U9qgl  xo4Mׯٚ} !tq &%krEww=LX%;:ۛ $$2))MWT\t'&fbt|*$>>0R[[.9F;8?{{]w]:^l˽J 6@C轅z$_J&$Ԁc XeY~꽗ӝt-~2wsݝ>&rm䯐.P}!ݦחL-F㗔Vkը=twF]j 0; ]W'q\VvvXXFrj¬ʅ "b[m\5b E8 _Ƿ_ @FYۘ,>JXwႪf,`%G ([ /;LSr2##G*ԻB$T>%zDG'D ؋rSSŐT疖ڮ}NATVV8Ri3 %|CCe{T.$&)ZQވfz:"ኝ|-Z3=Tj S;QMQsUM۴̬lyi`E_#_50`pQfRzo+gb(<<&|h?,Ϋg>7@M0-%#fP?l Pa7y?V5LC`%^:9gK1ħmM).*{޷Z}&{>>œ*C#drNN0՛ϻ*ٽO_a65orh5ﱏ;h>y4W }P{Մ'=}D뛛kioJ3 Nndxr<ԄeW\|%8lOHpٿ|pTU%- ""c1q5IC"$@%%R,JDz %7ua!K }K rRGK8衚kRK—V\E aw^wv~ppLJ_x֛7n=E]x+^ cWo̾6~ԻCD}٫]K֜7ݿ Wy5+> s~v$)#Z<&,Vgw6vouo L!$"&l_-}nRʍ}-Z.BAѯ1Մbb-` 7 ))!*ncYv޼e,@[[SCmwL:TUXƦh~aŋ@ll_!@ VW{蕐Ȩl6œ P|}\:!h4ՕvwwN)ryԻJ&qj/u ꂕMarj)sUMt֯7 ]80RW .tRfQmxM 7|֭[s睷;wZU 9}Zv``ॗ^inn^S!fVY4r6_+$* @hVwe 7Y]渐!w~9U_e Yh1_tJZJ&(T@CU9m~t:j_p,]Ǒò Po1!?}}lf{?2"<*[@=]\Ww_l&z©Pr|]]x@@Hbb![R/^z}iOs>"B<r<)i2 AtV4i bL0ƕe= wBh 'eIIQ=e}}oGdx&XYR:}ʆ/y}ՄĪ W\~ߞѵ-9Fx G-Çz{{CMEDAAD;SRƺ `5h]V^e0 zqmw?5kθ[{쩉5eD_' *X@ غLBo< &8`C B B{Knݯ#rV$g BZS0,vZ2-WYha{o߸~mJpOa% > M1R!رa+>`Z<1DE%먫r%͕X;nť9/v]SS:):a!j]u[Ddrj,sb__ߋ/ljjD lXf; ]ЖEju~ʓVWWm˷l)++U̚(( vjL0ˉU`yTTSO lon|B8..Zoy^K=X};- ÿ:~qU=s+SE? 9 pV <6}_6_wwwʎsRApWA>?R]5XP_xk.+WY̶g'e0dC/%_=i pJ%EElAqt:6MKJ5 GROBg(@xxdH ґNOϲ2&6tto Jhg! --ǀe٤쀀 ^]=9}}ZR-%eYjɅ@&w:n=!!DU&1Ӎ`r0R=`Q*-vlj5 3넫 efeV7 0ѽqLr ~k%y"j¥^6o|?VVV)WC!5 4{((xcXr}1- RKf"E']RIYBZ2hNzf8kV?$0ӵuo=7uxe?oBZ×?|Y0ZS_fv^~#Z?Vok;8͎ u_O˶zԬPBBzHH2X\gay$EV5555 K KJ,\$BHe屑iCC3nxP)A.W!D5A&$$2&&A"536'5J2,,6 HJ,2 "d6qs3L]YqB1!@11`mVfl&bvCl 5w½>4r# 3h '\MlyJݫ}?نLP1GrqJjZiImSR˚/_h"/ݻwsJM8n((Ì XZZ:00*(E"rK"?{xmW+HxgY߿k]9SkYf"G1KU:_k5sm/=xի#cǭ9.moJKw;'N&D"IM]Lyv&'j R=o^5z)++p Ofe-`2mCu:ͦ##<ߙz{yKt\-`&HTVvΕ#88<,,O*3 0ZuhHBTyd5z,.C>>Y>X䒋֬Y0 mDi>ڴ'mm.OE'==d 55 }||"f`k߰訨r$ߵ IX8\NLdY@પqtT.nO=!66%88aXBhuuu8Gi4TF Iq u!!`vb1w50sLYPpr[o`0 6Ͼ8?yqjɴc;vm+)[_Y0~6B_SS3Bq= ZSSVᄏJ%qo_Dr啗,[SSo͛/8㌕<#~kD5aF\'WF( 3a5<6p1xc쬀\fN!eY-Wp:P_rYg}ȑO>F75+8ƪ=lX  ""ޙR8믿٣~hjj~{l-,-w1vi0QU&͛j;۸q]vylz:. ""qdO_gMB}u A~m,^6 J 2CB"m6cy.w8.X`+րo@JJ60˨ H23PTUUẓPWW[CCd2ijk' %A6!`+݂Gocc||4b\)"jnh>Aӏ\SS7̳rs󖫜 06o1f/!r9g<y+RΣ{}PTtԽǟJNNH{_^ 15AT R@񱣗]%!1I_YQkE 5-cWsFFfffVXhX]}]\\</xߵk}Ty=m0KEAADdLDۄ‰"XͭI? 4pP_~1 JH$\ZZoh(.γ,0lbbVPPf+++LM8) ǎ E@N Iaa.uN <BZ-/7W/hDYl)ttt)5xT5DAADdtD5Ad j uCTgd,T*U]]eeGhLP 6de-o~K[[" dg/&f`aa.E C cvf"TFS(11RZ햺q. 767OL?11McYz}loonh4t_y^zsI"aVf )//X_gj8 | c:ow

ve2j-rW@T&'gpb6545^ZmFURJ.IrD0aH!E0@$!4;&͋IR"ޥV@nnޫ[+o~N\z%gw#2ATf湡&Pw~ w?D"Yb%x/g~k^pѢi s0 г7y[DAAD;Swtk #U> )dE5ay^"3bJ 5?tءA#8%wvEF&-oj;,B.j+*'Bj|BzzåW*5th4%B,JiOVKU8RBOhs1h=Sei4~ 8_f麗UYy$b8//P**Dq,Je Uct.z`Y8`L@ 84 `.F!Kqq%$ 1n?ލ"0sTy/3Mwwϥ]`~w\}c|-=#}uo&>OQPm@;7hӲSYS~k(Jt[:@~g'O$5?[K|V럑BA㤩9f vkAϮlA))ꮥ\OOO?zǫ*BY~ U\\TJudƖ|}t8hsǥj}F|m1*;;[g3KppD@@V'9HB !aLǝag ؜c@01&cAAnybۭV XAyy2̍=uІ kOʢ0Ձ>??tMW_s οLq~_{ms_MַYEAADd &&B9};a.Ǎ Y\dk? " '$CdƉK#Ki8P|22JصcJJN@@ =zd2dgP*sKK}}@r:55aLZZ[Z<:PҨU暚q]pp \__1 6a׫quXkj{{;fӄИZòreYc`ZbS e "Z̓f`蝃傀rȉd"Zn@?h2HIMT}!kNxo|MM-DAADd4&PvmZSPSワ}FqATNI²vر~GШLefZC#* C߱ct%@𼵠9*~4{TTqq GV^?lTT_ !taLf,Pq iZm ˲n"!0V{6FxxthhT*cY}w ApXyf1L='La+/ ~W1&O5ƥ;kD5aF=ƸxdhQ5a "i ]A-o鎝x%yN|Efh@iЎqgVMH<{ي|G9i1!8WB7d`\xdu79hjDP|22(C6 3CC#1LIw=:1::.::ybٰtehRGGE%ς {DgT4'vY/CJJqqR`,v65i 8N8}m6K}}mgghRGE%h4L0[}`vyjvww7Lyj򲐐^ ypjDlZ6U5Ǎ9&x/8Mw "2*QͼmHI/Sl6addђeb.K񳞝qۄk|!1@!`1!LcB0BWB !a $CdAEEƦ1 X]]]BWT>  C06#JsrVH2m^T*i=@.gd,b~<oLL qt]g\FRiti$ mm !9>{`xg`x;]uD5 ^j,N#DAAD0IQTVāzR+%I M(j<QWE5|0@FQ7jɩ:ArEZB__ZRR u1c"Fщ x[[!xUt[v,}NDzUil)!008$$e8Xr&#pyР 88<**Ia '3g-AaNl8ɭ]wSQMmƴaՄ& >{.ˢ "QMp. hr fv'1׶!Z7-^Ӌ%y4W8y|yKuA^’ ",,:11K"a v+H$젠p@XaL Ry+e2uuqq (!!ᱱ):!$!44:"B0 `++ǒ""]KAS}}dž㸤 Z뼲8=g5RR*PJD n?JI4BeMpՄ&ADDFAT@TNIAr)tמYfz'ce$:"dqZIgw}}G0>SCKwtdILqҔAA 8.QmFB\I#Cϑ#vt$ -M@BB&Q^^~\ęZ[k|bbCZOuuh1YMQ4qIprg`Lt)aa2-=Ң?",(1[. 9Ou s\MMR8֘ȹ\@W;(8&%Xnqqg"ȔG} 3Tc @sͻsxs{/N2Df').>l8xGEť0`cу}}tT*Yq2Bnaѵj9rg<YYKT* ~M&ѣ?reS}}Bpww{MMhU(T)2~7M%bll_u1#fxppk4qq>>,0u]WA0::DaʱOH3&h444D)mՄ@MmDAAD`Ln:jBr|=;UC+9Kf!te8;4F}nXQjF?0Ȱ 8ZzFdLe2c0UU ))OTR2dnAT c{$ HLL G6@*&%eT>T5467H ھIdS'T*EDJ"afA8Ʀ>4=(Bb1uvWmbKQld9_{}Q[Tf )(Մ9&8>vwQP A9*9 TI"^37Ewg:j v?}U~oߠpR*$ q!2m|}r d(.>l4:ã3r$_lG3e_VbDByð20z}I{GJȘ$@0:P(ər1AhhhooW=R[[f6&c#"bRa䘁Pi0L+|;1:Rv 콽MM3n!2" 3HCq=D5dQiQ('3ȉ 3TA6Αfj T _0 cyۅa w@sC<ܗ8n7z7,<*++w~̳-\wUVV:I1,R,!!#,, !T_.LHMz{SW)s,S}y1;HKK]UU!4a"cgIRV𼭪F˲:]VGh쫪*-HvLuuv XPGBͲC)#PS[[6#,/6.?ѝ8$ ǍC{gc$ٿDz8^P,0[w&0ı6_/獿v/L[sg>rͿnɹ89;Z嫃ߕLUHm扮f 0p5erъ{o%#GabB"eyljEB'0;""b2YL`k%$3 ` U z{;~\T* ```p?DFG'I$3dneRibcr2 PW7LEG'վQ/@Ïƪ)7#$$$,Gu z*BAc]] >Lʜ),)3ޙy˛v(LYM #6^4LS 5af " :?dm{`t[7_JunPi@ Rp, es#Č @ŘW0M=i„8r7Ygأ ~ۻC۩O?-//ի|?~u]j*F;~na/7 >l7o 7k6;袋ԔC>CoE58hv;_Qq1A.W̟RPǪf),ŕQ̛8Bc l69=D"Yq+nLp7 evЅD3 ۛ::ƏT*Rvwr<8.!!M`q" B0Ǝfdwj%ĘmGcgn&)jqAtm!Majjȿ,㢠 "2&&DJ>dw`= 3& 5Zd/m!@0!Ԋ>Qюgu_x8/o];w,OnCA֭[N $440(7ߨ;կ~kpwzj[YQCg}t7pe_ ^z5k~ǟ~uD58qČXQQdY䬈8/@(-=L7,;or׭%ZM!O"deT*T3X8v 9J ݝUUǼ:,4!!U-q%DQfmhNRӥhbBAa*B__gC^tdLYP&37j]ASV5z.c/RO]MVunQP Zn' ^Zqf_{ϻ6_[= Y&e/|j?ULrPo[s-lk ӊ`9&Py\x:hI_LHXӠh--d%9볗]ZZz>yЩ'z/>b7j;xɒu!"""44_z.Z{fn<,󃃃pòezzzXݳgG;>ڽkʝ;鎋/d111O=-Yxo|?:)qZGda٨B B(<<&))C"L#]t߼yg0zصN0~q$ ,Q4T4X8qy#ㆆa]$I4F00,=÷tJ&&&QA `[[[ָȉ{-Z3\ggnԦes E5a6p*xG_/XasO_v}/O㚯><ðݺeßa7}X St@~7 fV۟&21S0&H "2&S& 8(PV԰f<:%|elo>:|u+'ǓHQ P%K 6Opʓz6AL/ON*>>Ǝc%P|b5_ȘVo{Zu࣏/\λ~gZVz =,{{{Gƞ۳giwc`,mWyR6aPii9~ EteV,8C*7?g@hhTRR6˲x4RJ7o1_755))T\@"{(PWb:;ۼVbbRT*9H݆i IDATCSՄY%V_1{Y|ϕU%͘Lȿk`?/xżpg@wn ='n 2˿x:*:?):4i V<>:6V?rp5|#p!fj㊁0 ARSSGkd߾swG 17A83[ZZ\;hr:]B0BHMof/޳Y ;'?mZ&_/@-{5LC`%^iFg(_iy&c0ۈ(&HK!6f(5u~5A @43r~(ʭ|ݪ/`l]* O6mYZv>"609+9%*V'pIIq}m?; do{ë[UXticcK/XYY s7tW\{n1 e#\wuq0͟~h=ՄC&SǧFF P^^ zJ^A<9GR(篔 &`~.[T*1dQ(d*nU0((466eƸk`jF4Dd'dJhG*1/)+"]7.kؕ$ N Yo؜#I騋0!Wܾ8`}W?{4^WˮrBH|jO~£]x-};/b P?K g_.㢿MQʥR/Kvp{k±hTsc_Kr)LLMp}mPDDPB<D X/ B8uSрA(ʔyϼqCw8`A÷~agfUP8I# sfcsI-KxO`pߞɶ_[VU%uk‡UZ-vHɎ)om=jk;KӚ1ڟLRMmyQP!ݍ&PPW3*"j16g? =׬~.m 3 ۶~뾣V6os&rᯔ).#g SH$e -ƄZ iф;<0ql \_GyٵsO?8drFܿoYPtvvn߾r3&^MId2XUUROQYYT*@.-oiwlzȐ@0a :'HXXl55ţ>H$ΰh쩬<#::!00e@y{SSCWWdOHttVʲF=u0X,;iWoutEMA;J TI,B4O5C4h1̀A"e; 8?`7uvZ{xL,v{{ b fljw B*hdՄJ?{Egv%KAZ(G (6DEQ7lDR(] $tb =rIR\.!.ydgvfvvs| ѣX,))rs9oXHH`/hXEEII =ի)PwD8jfР E BVW&'lt@_BBK JJiiW̺Cxx/`l`{3s"gAR88E "7$iJ4g}#Gx nѢ%Chн-5`a_"Y !V}{_꡺Z]^`kflVլ\}dzbLKBr9tMOUW -M?4ߞ/SV%KXS7,ԙS:J3$H$RUy6H 6؟Mt*à j r>޸633%;;U" 2J.WGBiiQj*L6lXWW* -{xx8B&J)o.\[IOO))?? )׿MO*xI !I1K\$juUj#(B{*+Krr2[vAǧC[QqL D{رYڵi_wf #oݭc@ޮERW#<;G!mjQ/_hB ?&'';՚mh BFM>Q(nͮhvтJ{UlL-mͱ՗. {#늰xH Pv 5SzRD9SڷWT& !M @]dDlsF~dt5[BHjRrr7E,nO8/-_GQQ.08狊-yShhð`4I+c0rrҲS/82Tbh033S¢K$2%)%ars=Re4##!ݍ6Sev3 (m:y"^^9G.o>gqjBÜ\҄sfhԲFnT5LXY=k bK2˴S bUMZa,f=zD-XĢE/ WxwW\0aaZzZR9saaOOw]<<dn&CC\]])%UU*2/ 4:zP3 BXoovz}VV`kRJxJ iiWss3$44*88E`/-y(II7v $$?T, )5uVVZMMe3[C9ӊZYUB[/]lر|7]M?m޼զmc_БWu&t|@hD5ᨨ#4D̒ VǕݗj32nbIppDhhOOoq<WOAJq"!aDЪ*Օ+g\\aa='L+Y l+W*pqqϲbs’!0OD)USR.6sX, P,5x4WWWRq9znU^sϴԺ:777//̬{H _xÇ+YHOϰlG`w ӧ:^RhjB<{Zӵ}/hs2GwFG)6 ? B; 4Fh@U@硠g&nHpWQZ,i:"1RbND#EM?e|}ILLP 0D&3 #Ā02y^Q]v wDD/\Nj#E@u:JU Jypuu?qgΜc6 6mٴiUS9u˜cN;v2g]{{f&t;#pU7"dP)5o`3蠩 `݋BTE$jŨ&V!>~~@)pa!bT(f0<" c08WXFxPTT`0EF psA0BWUUed$T朔X,PŬiDQ2;ZUzUD _u8}:oq͝;gժݵՄЕ*DJq+CPP@#vtW٨{*'Wz'bC$D²0F: Bx gK(ߙMJ 4v>Mdaq*--Y kDDoOOoXbAyfe!H#hgYիI3gRuZ&`'ߡ<D*y٣ޮVHv&}\Z\yf- E"&BNj zND"r\otrOH.>Lkx!f-cq|)0 ?zX>O6H˚ccYo5 DrM[lʫKx7sNԄ\FAA31MT+8G PM@5Ÿy{x{manT͘j@xS0 P ,.F@MVR=QaXBK? *%JcoqDD@ĕa`` 9)!$8'V!dҤn8YoOKOdzoM_ty% n.3 '[㦿vmY&ys#I߽-_Y &ohw PUg=XjˋW>{ dm&<]ߞoAGB*5A!@.b N-TPMh xx(||| ?EJ@m jKBBH` فI5q4V4B jB tsD&ZxRz*##2 ]sgsgO+_viPM Ɵ ]*z+ Y.j*̰ +bՕ͟]{3Nl\uH;8|]ܤׯdDĊ_?{ qա~>*yi\Q`Ʌ _W⹬+Zv{@LwǖoP@a u1Sa/_(O5b\˞'H\Sp0/I*v jбPP@#CkV=確_='RNI6@9q.py_^ l̯n| IDATX5#T]}[?[3jaErx,N5@ZR8^gO9qFTT38 (^8RXp*7ɪ 3R $Q"1bVx`G` WSG竾`onFãM:è 9Oi~-X[Q)C<5vA aa ,ukk8 QeUacN;%dJ[HHX˓9J$i5W #q;T 1#cTS_Dnn^^..rmt`&Xh<a)Lr0[~ ^$( ̂l^ \XikɜAu:}yyaVVjMMMk8 o9kN$cIXT: _J)OyߛFDO_pתxMIRxg|NXՎ?{˿6~~Aa?!nnqPP@ju+ƒ6sUl}gUiƒVFVoF]PO䴚B() &ؤ:61#c}1 2 7eF&suwW(\\b1ð0BL\]-a˜!#cZ` ! 7L^(#4iZՔdg֚B ˽RX,6{a4bD 44.%8 C 88h[>}RƻZjBhn5:{BœœC;V߰ѽNq !ẕwص԰mzrCk˔U,d-yx,-,)(aٰ/ GlBg.v).۟J3\@ǘ<g^3I7Xb$ZRPQ[t!!oymL&,#aɃW6X0/InEA[[uAr+tF󄖫 bf`oH馠 M'ۤ4<ѤdM5]ݺ5??j ӲK;TlR&$==|zMmjX,vstwqpssɤ,"fY yJ u"=o: CP|wc$Fa1wfBL?y>BMSWH*rx׹'Nq!@B}{dV]Gp<ږ1m tgKw,Y9G$fT5.YO{1,㱥ɗrVoKbBƕ^aV0=@fj׺#>,]8$F"ӱ=iKrs5qlqE??YRw6 >n셼j;wMK8sژ@5" j#c}cvjțGya3P*Vt= D(0z+ Ĭ&Lñ=PԵQMa ֹ ]dR缏7PRTstG~,ҝ&9д`F$drU*n2!2U,BS*22WPBσs$RQ@`!-mԏZ, M9VV)|{ APd&@?n׿O#&a`EjWs*6"ơWL~ngГ#EjB~QP@KE5 M) C T;;F5H;DMQN[od\&SAD`zXL鄄L`ʧFAt:V[]]Q^^R)ѸA &t():Gw=GAAX'Ѕ&uN\ºIزjN5v%ųhݶ ͬe8 fb=c,`V"*!X#@yyqSM0';z Ϋ&x)SuӠ5yyy*1b9?w**7ޘajz{`Ѻ9@i̳S= -h!P"؇1Ԅzm0 AAAl8Ϊ&Ď3cԔ|I-<B{tx[ Uˤq )ڗTl~5Zױ,A,/st:eu jBc/]tl?g S6[7nXE>1 <Jiڵki׮ >Rx+:]&u9 w1ZX%ҡ`Ѻ& TNO%J yHoImHbpd}NƜvJ;Ɠ6;8VM=f[o]'yy}}"կWxxdg-!JU/++?w.Ɵ9RQ4ZF;/-_E5Agvqm#W Jޭj- m2iHk[k`X*i_/jrdju%t4Ǫ ^^^3fܸa}^^.a`R('7\'F!cV]KNK~޺e9IITW[6uM,4@w1K' K"AO+qηeL|RWںJlsD55X`AK僖Y+hC7oCI Ͷ8huhH 43jX,iР|mg&P!>r,L)1 yyܱyhp tIII[lpuuoJ+K^v"5{񔱮bX7tÕ C1?y( ?Y׊isм 4P[eq{[Ϝ93 r`sYW쬓>a^lc >8/NSC iLpwIݓRIJخd:&g[\Jr2}7j3m훔7z#FD_|ߧQkJMpGP *u  p*yc\e}J0 ɨ~Ru)@Ebf⭄!x;)b Մv㦣HW1cg^ j f]}"quȪ4y*<=|Z= [nUL8iN$)VW(KݫǏǝSrssϜ3|8;`OΤ&8b*]W2CAnR?Faun .gj*k !X`(|k׬ٺL01$$tÆ &t KƖVj tc2`;0kyڧw 񠠀 |jPsⓒ2e E"L7s kVnJW1C>2V"A_vB7j%j8D~gS_5ٶsR*''ڵT1lxtWS &*k 醮|zɠdjt(( H8`&&^-]nj z()%Ϋ6 MaBISh tʈ qr5~FVLSE\Y5'  獟Ǘ+@!9߮1<?-lLoԶ7W?|빙OL`E"sAքwg?ڃ/[y{-xU&>o{lШD&i~kOԏF5A:8 ~2 17 XZ(TiF; SSJL?i< ü>,bnʲ5L';:m3 Pͷ6-[tZmEBRj^5%iE 4B5+>𐱁bUACڙ0鞘 Lu 0j_ڶ+a>9eot>=(Kꟿ= P߈צJsiwG7siA>@/l_w|sQo-ܤ*U'^mg$*|^֯<؜@) _@AA Ψ&X8f$_FHFAiO!T=Ƹ&M9|!` l@-UUGg51?8b[H<NܵMjŒ¸#I/<+hқ 7t‰F,Fg{ B1Yx+a^<#!?9W S եTjt4R FT\M0'kqZD  3SzSsбS4nGHS{`Xlσ;)5=tqSBJU;£_j`I]ӯMB!_?_Aĉ+ut/Czi 1#c: 7 _ن rڢ& R:=‚!7^.C# ukk%umTi(( HSEM't1 @"b.f! aD5A RU ѾRHMOJ0 tA5A b QRM'q~xIcoƺ~׿Ƕ3ǒ-Z0e-_5[?|_gX?_Vx*Kz%wyask^";.!܁9h{ 8!Q#o?On3 h;߾kgjWs*6앭ghp}WШ& HG'hصM( >w2&3,-1t݇Tj*s潼{x+`@LPn?VC6~7ap\$)kk 4 ։ z ePP@Kl&-T¼$< %1{hg¤{bO*2qֵb Sx;o=sXt{3z)*ʪry QpuG8<V< zn⭹9OOOz;{ !bJ}[[Q)p*yc\e}JyNԨ랺k7[[SJ1 0V4SJƯ.qc,bV 4Oг3|?+'ʧKaS(O `*{uRRwm\LlQbAęRAS@5A:@ <'\?e;{Ѷ؞rԕ5%Ԣ \VPp*U[2 sҕph׹r }:ЮsM`rK\&! +8GwAAOT!أjB9ȡR% VTU<]Vr|B1X4B8'p2؉)mh'!I)eE CחV P'H8pP!%D(`V]ٮLj078LVut_A:tOGѾR(ՔC} !H; "ЬHSshD[cD($n C@@av/o#dCѷgH[z Tce˦̔K9z0&ψI+U喇cY5/`\>>A21˒Icڶ Ɛ[CA6~ xwoW߿k~.`+-bt?G^Y{U;{6϶7%2U?QRoдZM@=AZZ( HsiZMP94Q(ouBBl;  !F+m>}P]./CIf D0jB ? BYdglE擗1sǛ*),+Z?h7=_J:-nX߶THa8A9|`5a[p=zngXk'L';:m3[=[[[dPH@Qe& ҡCb$aZi+!tlOZDxxx`q_T4xHVe&(&ZPB\$u:Bӯ]\ڹ{( %nkUZ t[nխ ?*~@N2=`ƿz5oQ߱tE~0rD``ExLPM@AGڔ+yCb:.+Z?8b=pܬ;j3']k!bԨ h 1^jȯhh2 0O(w p,Abajo{ {x׹zS*dbtLO@Ia\*tZgyn  bujS L v(KRjeT  ͤޮS Ӟyn՝ %Ld,0MH0^7x*+Vʅ%& Hǃ4b5ANͤ[i}WdbWu^ڰC%щܑ!#sGh tA! C t.XF܄5aX92g=5~7yX5x{g=9%֙$[jt*(( O mPMhND.ao!sUW꯳vAAKGE"]BSkb>ŷkAUU7%bP`SN\$\j5bV H< I׍ *źAPOKoK:6Fy }\bBXUړ1 %ҥLҶ #oQE`1Ӽ9d Մ.ꔱ kKuO;&R'8z:S^m! C膱ZI& C@AAM Մ^~2|%MAn| @V6.΀A.ýt>)JTa 4Pi+x!QRPfWgW)AihA5A  Z&DyKyh煷gzZm|v&}\Z\yf- E"&BNj zND"r\oDtrOH.>Lkx/g-cq|)0 ?zX>O6H˚ccYo5 DrM[ls$KG%!*Z"AAnFv>v~5[l? W>w:<5:PP@#-T"+!Sj x:/a~CzzcFrX"d˂wV)I\HFRwm:XtZ0a'xC-kH:?V_ 'S}n3 ).nRWOڽ ENhG7yE;Ԇ^CyaD"bE/ksq䁽_|}O߸Pa ?uwq<ڴ^C c{.m(|B?+\-= &;c˷G(O0Os_SCs̰LUEZ1eNX6%~nb7V*Ъ,Ti+j& U<{X:Mq#Cr/jt<(( @3jB4R_,ʭ(2C4P451J|憿^x>螋׿zH3+O>dm@ᕕsm=3];ӗDօ?xGk43GZ3~|g<oY:NkXq嫝Ϟ=ruégpP)p"U.nU[fI@Ebf⭄!xA ,گ0쥏fE *W}܌0ãM:è 깹|$)5JFJ!\[U: r #L(5jt>(( H#DMhqdߐRw)$Qc3pSܵzfSzRT&^3eV'c-Kpo?+{u:WnF߇6=fϖ)Gz߷9se$Z5*>݁z547bݓPJk4#{.w$ OinzIP G4^ܧ~f' ~@qs5s=OTotsTAePVcs8N@A7P/?ٵM 9,] br5P yIr+ ݂ݪ %hn5:{BKœœC;V߰ѽNq !ẕw&kéa?䒇֖)X).[ZR !tzUe0lXy~Y?BI3 OKHbbQ@BSkb:x!R*ѰK *r˓.03MĂec0,9y~X_ AA3TJMBԄx|w KKmA[cD($n C@ڴ,Cwύ !^F2ý}= 0"&fLs;G( 9> .lg(K.wi!'7y7  MϘɃ,^w?m϶7%2IGO4VPO@ց "`iJ2J-Z~'M]{p1IS~t#c 3MN/kͣ=0$r/|/ TIaVl|b#Y/ؒ;YJ-BC;{B#s;Pj_+Co?Ot%slG^{cjtIQ:ҩ=1 Cȶo,xu꽋X2 ml%+lE? {?i`/e~<4RΊmILڸ_?̊0v>=1߶" HwCP l,TtZ][NTR*}@5A:2pHD"U1 Z+ m%08D؟I J~!1-iLM0g&WjA,|eaŎݑ!TX\^  S0 EXnk`;k7Cm޲є^gx նQD.\>JBOgMWL-zƼW[ۗޏcN+RfN6_M9v=wh5BAi~]5;RM/?Yv{ojUO ,F<*'-ZUvq6J4$7Vz9 &Xn&C G*~A=sN!b4M@1^j.9hI~n1@AHR=T Zm% ӊK +iB#CTRX&J"sjt(( Hsi (rPj:[  &,m"I{#Q=g,F)+bB`=ݿe$01DH.$&ܝ.,nn0 80 ܡ%/,rQD+ס?^O}:z>S4|ͥgoKzՄٹWN 0,4hMok'кs:;vʐ.oo}jZOס;Yu[;Lg:߷vUHcLm/aS?ؿж'b.ߺfMH)moi @9az|Oyع~CtNxAD?wAPH׮)0^ܵ9gj.&Ul4՚0;q4ksz;33S`MNC5!=اx nBAP;vS˽SJ.~V(nԋ>a! T~l^\ 75n{Ņ)ڶuuya obBa|6 ڞkB6SI/aׄҭ>>P*xc?va{1-2}'pWdz{ϲ;w`j?ϋ;yg ]Zwtn*޾S@ȶ0 >w]v#FHY--oz`{{ύ]`;yC7/OR+5ԄRCRJ)˲Cz5Oz cͩ0A;*(1>\P LP LP LP LP LP LP LP LP LPbKA0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A7>NP LP LP LP LP LPb-A0A0A0A0A0A0A+Mz<^9ڤ١ @ @ @&HyϿP,''\Zѽ OOMbX.K O]V^ZfٕKՑ`lP LP/^ո){ǰjI/ڔr_&3TyRLzVJTڜdZR*T> Ŋ  [ַ}\@IENDB`RaySession-0.12.2/resources/screenshots/Screenshot_20211203_162333.png000066400000000000000000002111571417052567600247070ustar00rootroot00000000000000PNG  IHDR pHYs+ IDATxw\wfқ`Јco4[5j, bi5$_ڍl`XJ,,mew\ .ޙ3gߙiCt0 0 jY`aN9aaas`aVp΁aaXm9aaas`aVp΁aaXmVPD\sq` tT]aXC9$KĒð228U?@?0݂h]񦙠UW95%YY ðXaܤ]ZZFůښwגj9* G >lmu9'g' ssXԺuH(~!4ð!=Дlapuu`mv,!GSs3` x%O$bSܸvzTdTdĩ˾Zjee52"!/% ޻Su8xV0 W8iI\St xQ`5RŎ.2Rgm )jqE! jT.}|333/hbرE ??߿47++.ꉱct !{vqw>rx90 3<>q\k,hȶ T0e{ܽ!lfj)9*DLd>7{yzT~;w ~~9 jTbb |}7lF͞;/.>b9a5 ]5G| I1椃%4Y1HȒ+6l[\V=޾IhhFSrGTvdVvYU9{ĤAV훜rB'CW, iO.Z̀e ̙=ظ,<ð!h#cG+jTTX뷛gTe_eF w,-\k'Tu/089er>[dRz1Vzr~{M:ggCǏwppxޭO3>{upՈzu1"`Hɍ[jZ$32ͱ~(S=0'}/*2//{ +JS 'x{y&&&ݻ?Fg$[|rH(~dkcc3$IhbĈ_P :tKKK="Dlүohެgggo/O.Ӧ̝[׮wtlQq2L;;wwோCՅ31Qmyj:dpӦMׯ߈jJ%vv))[e4Mի üYmڴy I2ggg(zzX+b@Bt[ .-x~pՎ5eKNLozu=*eLeĕ+_Z?r׎홳@t-W׶ זݷ…ek.**[zF)Pj*/.Z`U o'B -M򴷳ۨ ַw'mByyQ{\9\~@є;ʪrgffֹSG7Mo ^={;~rrW5,e&$(R*GN+?5++G>g={Uvb>}˕&ly`ЩS?ʊyflEI0m߱.B(88yr8exyz,]R_үOI Žn"F޻l̀\uuDɠSpuxw^7o }GK䖍돟{ dZZPX1q/..q&jٲSNFFFEEE7o֭[7k@Q3$%'G\/=MaCr?Dw"0M6]:uH$*UXxXaaBaرX,NLLyoަfjuˡ90q7ntH.WGD痽\Iݻjْ$Hezijj Ϟ]t Ɯ8Z+U_>75g'aC 5J74,⊣b|ɗ4eZՏ?KKOuNtѭv0e<(3V܀,--%IXxiw༱ȑ<};eyBˡyyyVFOH(**NN:99zz:tpaaU/= @-snFFX,=Cgظ+}z:rԙ3*@>h2,}O>ww?}_{?Htwww/O){sE]t=t_e ܭkkׯ#!1jψ\B,Շ[n a2X1#GΒfw<ζmkeL2*Z9GAϼ|ʆM[,.]=z`L&vvvg9S&'';999GfÇ/]S(#)9OJJqmެØGUcjjjmet4t~733XQwmV-]-iiiO[nu =~ U/cЦuظ8;/ݽwe٢lJ$'%SzL#~ ͍7;Yٮ\Q֭\߁G]]_PT*a/+ۇ>Ka'N9[.,tlQJ o߹o**:¢㍌0n~W@  +<٥m6b!e۲Urye2NWnDMG 1B`bP? Y)s-ƪ\nQQ>W0xǑe#hز 0D"i4!D[!$^trlQ+2q@$cf0 0 sW}\Ƌ|f͡h 钒V)8RzPE'00H'}O_x&&)j%H$%$ u-'|Fݕw WD7*/Y!}#%RItW))trz0&uVCٻo0 jH Vvx@ 8.=##.>w%ZPv-fu *)5ibO$BH.ճ)J*$)fMd2K͛vqv633K}rsrrzxj5LLL4X,TBaV+e2V-<4(>!^R7oj=W8f,XAS>U*EVVvuo.%%UvwWPPI$UbctU.(,,J%r<776;[ŲlJE$@- /0 wj5~w}v_uێwI޲m{9A:G:92iRBbBxĕz8~u$qwneeU\\r^_Ie/  ݫפO&111׮_~C5Z@R%&&3XSҮF]4P. B·俺9ӏsd`ZZիP3 Z9G||ÇefE::Wt3V0X[snnnBH.]\K`aDt޻J$bg*s.a:пqqQ*LJW7HhyfMt ;Gӗ0 ]SKg]V1?\.at5+m5o*a5P80 06֠ˡUXuaVp΁at A@'BhG3܃O>8:s1 kXp΁auh|{@#HOC t&3QOFt 2} w/^{Ϙ1Ɔٷ?^gڹS>{6T( m0dif:%$&~7C gzo8a9 ݼqî{ BΟz助br~^x |9`I,Av94ܹ֭Z;oD te?8w?bۈa՗8w-7iuC|4oqu̕0 X]fJO#XA'rGnE݊KU͕MJNNLJXJeߤ _|9T ٻeԄ͚,>v;;4бGRt'OU_V6kִHvCQ4EQᎎoy0-=yh3-3g HR΁a A&"oj5ɱQ~ĶP? '+5>}FB&a+^#G022B[d a) B|N޿w;w~׬A3t)5556sY;Š?*K+=jSaQabb"888,LM}SqٹCh=$"R.b@_H@rU+T1ԋ 4eb#H"QMn:X7L;ͿP镏Sտo4߮]CCx{ 9Q)V\U9-YrG7oJTq‰9֨]rY]Pk$W-Z% "RJ d@*$%BE"P&sh$U|0YXX=MW I$}!EQqqڹGtbիT]C~~~]&j)2gggo/7MJ-|}QQ:4s`szFzV>ll[ADr܂$@*$"EPnbl۔USYW"#~'+j;"C*,@3gHcDPh28-o%|+zjxy.k#M Đe D,IxOA TapSh4׮_wİwƐZ;U'W[g?B6bBH&98 #( )Fx>x_-[=C)}UClo0 'I*o[_o~XҪ_,]>AW_\XAAJXX OZx# xu}E|^s}:rÛ(ڶisM@Tv7o6oᜣ>:RV?y#;/x_8񓁻rٞ^g2ZV{ 7N3yH ,±mA@>oC6hJgt/+ `f(w<X:K]9*#L޴r]t?no%$&YZX4moRNI}12㏼<=SRj/hCo Vrba-PB%X-3K @I/ctB!0~w9B[f@ X0oN;׶RYZ 2J!.'L8^(vty5j-]\4oLӝ9!oVܸyysXUW"N6j>i>¯\wAr+KLe'T7q%޻ih`eiyΝZkBqqot6nƩCʲlXx3/_sMII9g :}&,ʹ W"fݽwBXs'/z .8׬]gυxz lm[tXRV޷Rţo߶2Ĥ)Jeӧ={Np$ 0w(wv oݦ([54 IDAT}g{.JepPf@ρD"wdf*u:ݕȫfZވUPPP[SApȅLO&-WrBزq.? H9c}^x D\ 0@]ɠSgBss~DP(T99`nfh$_feey6+;T,-ߠhP/Aqqݵ" [Sĕ^aӖ3͚WFڶlkX,^:vPN9*9[}ac0 .()).?GZr5E>^\.d%Yj^~~&[UbgC~ /[؅lj?ϝrbJJJkc< u:]HO[:ul۰smq0LNNn+wi<َ? w`avffMK$~}zRRSLJbYӦVhL q [$igk;/\iS/q}s!UC|\]2T*DZx7shz3V]۰iAC|n&W͚6}$a#1 zQfL6[]t9l|w?43mgRh~m;V}.otu/Vssxæ-uMm~߶7#KKKf|ZZ'rrnFjXϖe&11j5~@k:LljmѷnM2[ tw7Zo.))wʤ_~ El\ϿT* 7cL*_aӝYgX[geeaӃ1o}5~RD NC1 kD sȬB N\v]wΞPOYY߬_ZjzObU'ZcۘR4߾x9ЪOYs[VI-Co~аwfՊOܽW* 7n^{ |u:m.gL[O^t: 8`ZlF@Ϳ`oϗ.˟: Ϙ]_=#ݑ\ׁ`V ַP:]?P& [tcϚ 6#u!Jϝ:qԉ~Sg@=23B몜n]:|.OVu:#TпGmRR -ɞ'?›7kj˨{R.liªDZaX=cv:4jx|U"PoƾvMSBG^XJ5ۈiڡ#F};,[4?_D"622z )VV{x>[՚(I:iǟ >s^~JU:EA@sh& lj-~/bV s^ű,p>!"><:mʡ(jǮ=3gGF]j9ĖP=v|מIII]Ï| w܉_gcSWH vrbc 0kU.߸]ׁ![ X,T#B!o_7G:yt_\¥˹9LDF9:% AKg} gCڮ+Aصmn`陙V5Kam[Hf83aXC;uJ֦>o eg_dnr؏?l;s.8==㋥g ?grII+WjU}?_FE^zɲ/?777iẠ?>dkGSs iDQ&ڈ{,S ~=*r 책,iiݺUll\]ѹ{F,H$bgp[qqvNHL(*av]!>&[2+$iS\]~W x۷/4kꐐUңKT]$tlV"DQ@QHGT=ۍ7H:>]c#FV8A|fupyel7bwFecFWB΁{{hB#̹`e_G]{ÆWkX ihM\BFn _K,xgff+,:ǻB{' =̛dE!B4tGQmq'--^ɓ'G=zpÇ [Ȉ!}r+>{T1iUE"ќٳN8z-K\]v/ڷVCourho}7ܮ]oz{qރX#^iޢG+| ƵplQ٫ޏX8I,: Q4(Q@S@Q2nJLSF:vDN;̟grtr=f܇Fl"cw򉌌ڸaUrV׎a#11qSǍ[|Gfϝ_WkdP_BH&Keٺ'?N;]MNG:N()NGq:iW3*bo$44L) 9a#/ݹsCKJJh4pϞj;v:tȮ]{rssAݫ~DzվIş ^pΜ/'#Ix+99F%k&%9F~|b9Abu~I ArဠhDq"GhP:~4jY ɏ$MNy1D2##VTvJF)J eŰ011XT>5켼9w&LXK{wMLMu1k%ېœ"uI 1:]VX\Rp,pp\+XK3PR!g̜=>0?_9>(ҊEZ!a)i}Z۴nE3Lbb>{] {H^o߹k gnal)L+V#auf8!B !d5|F&pGH&DZE0 awM0P8|tfeN֯PF/W$: ]Vog`!>^q# }㜣ظ@>~ܘȫaK8p]+=$&$^i)b)di"2! 9@`d;RLoǰF`z$5Z6lAe/C3gWFԦ7 ·1|y/۴n$6lm:yD"z 5Mee+\*{`ckcR|Պgii>;tQaa-\qsά}zܩ-۶?yo20;kfNnBJՍ(..ݵgc?T1}@T~æwMXRz (_tb!C(XΆ0\33渇a %tX)`9euп/Dz!U%NI8|ryķtYG<9}6xOb6-[8O*[zfXEz}FU 9xΜ 4~9KC4M~}Ogυܽwa~)^m;vQhշoo###c'NT9C[4o*UrYZZaQ[ݗ*%0}*%%$$;2'(ٯQAota rÑWj1۸zΝ:@QQqJj_a޻wD8uK߸¼W]t: 2A'NdgLMi)Uѣ'eK㺻w 3kbF" Ԅ^V d{8Ç?s|Xԧ FFr2leaBݺ$y}Nx)aCya'q%]߾s7Le/ bcmrR+Kˬϗ.˗߽@>~2?}oύࡾ|pKF^u*.D|f4M?xσ0 {M &HOճ'ORRR`.=} N=CK \:};h'?0^(޽wϞ疔occ0ѽvm%ɍ/1#GxtBaߎy߸}k4_orZ~$I{{XM\rM~+V(>q2g*?ȱG/{/\70 Y+@+7h @l>kɢŚ]{NmzKW| {vu{Vt׶mzx׫@^III=9={t_{~\.d%%%e+u=ۘG=d 0]PƐxaCv,H,-,f͘}tmF,#$).\նMk bqV:zeOxiqqqjSڥ q/NJI}'izzFAAARRSLJbYӦ|yn^nJ]{}dB05 )ceىx+{W;Ǎl9y{&Eݹ{o7F}zFFs]Λ3Z]q c݌8yĭvyx捪Fߺ?&…~m׭dЩ/ڲas;!N wO)!:~CM4GW pC;Ғk0 G,@ﰈ+aW^.߶c׶/<1`\DXM.VXs5kJ)0ak%_,7j< eV7/{ ۿTh)we(*3U,aVU\\sd6UBa֩'PVjݻZķBp4 /jA|}wϲ)V^9֨$q6$B4t4 tickCh-a^D[6oq؏'>b;vL.]lBI!Awly#GsږX!4xUC "1 {7CE!B4t6~(~{ƌ66Ͼ`7orwuaa-Yү__fvޭՖTD151yOIzi9ڹn޴a ϗ%J{%#:̀طpu0qiJ 8 'e@G!F: h (J@QGWի2l%s̲̟grtr=f܇Fl"cw򉌌ڸaU+K.< ~΋p΁aXj"w16H8t:h8(]f*ʾIΝ:\RRBӴǠ{UEm/СCvړ0^ەj[n1rԟMMM`=yh3-3g HR aXQ;M+%%MֆMlj8!CT5r###SJd IDAT&9ŴKKˌL~[Rqo*J~!T*-,,ʿGiV$;~zuo gggo/O.Ӧ̝[׮wtlQqzv&vv1Z6#CguHdfjZG1%f8C B`$q>ͥ]Jd;'QfeEGߊZa6oO;w۶OdḶS ?.hΞ vsPa111߬v |ZRRjBh~<ퟏsD{DRV 1zx gnal)L+V#auf8!B !d5H ^bwFecFWh0B=$&$^i)b)di"2! 9@`d;RL5ðF0.)5.!X a& ׌9!0&@)k $u} 90 3< K[G (8j/!`2B F-æ-s`fx ktŖD% 11 0 80 06F +aa{$ +ÈaX#Cti\Æa95%YYðXaܤ]ZZF]aXz9$bIQqq aXUTX$H: 6<0 ðڀ0H IYcbf%[ !pcG0@[={ן8@ 5Bð*Bć~0L@+4 H0 kp΁aK 󋋋E"QӦTl>8|_sT92Y1y+ԋC$$Q%IR@MQ4E4Ű,7$)BD"%P4kޢX0>@)J77;vmʕ+}YlllJJJZZ͛[jxdkkU87׾\.q3AbHH((33&'rI%RP(RL$$ ,r,Dz 4P\XiHR.Ɍy/P(i( AjV39R۷3g>}\xgϞ&&&|ܹs5KKK0-J%ƜsD"H+).,ԾַL$I 0 DZ@"Vk@W bHf_#P ê94D"9~xٗr%K f͚-Zٳg) `իVfeeo޲7k5͚7  V89;Y Ӻuظ$A{˲ #BoUϲU;ߝ$I [f$A)yfp|QTTe$3gqmڴ)777""{.]t;vǎ]UߦM:udd$>t?:ʨf̘é~OճWK~H}ɧK{ 8|ȲRfRV_v}՚oNܩwMo޻eI4ZZ R%Aq1V '?Q EAQp0D]耶Mi=nx! ڀOy޻{g6}&PܳϰJǞq׎cǍ?r(~ѨmiwW\^Pׁ[eu!7AZt( Y#Fzr^ԛ!8((\Bݗ,c8Aw\7B  x(Ld \,`f1!2 3xp8Ν_# bŊo\@h۶͂yv:iOڨQWǝ7S˲7nwu2&&fҏ 1x%99I9h4N1,z 5Ѩ#Awug-q,رC޽{-I+(ԛstu9CeYeI^DJeYQP(AQ0p&gx% BөeKA$YU*U([߿_~eĈ{9pu]6z2 }`"2Bޭc$e˗G(W^~1#=2yÆ{s޷OM |GD=*|Q,O5~f͚N<.o7iZvwmr&1ݿ$%%~ڪ1_{'leWD*}1-[~Wz9$I?!VS.*Yf͛7߰aBBv;PUw7R sx"!#2Ç |cԤ#F9uCo5|#Lf͚}l9s-,*\tɏ73?Zy |;V|ݻOjZ+++Kk^w׍7@0E9:̜1}iyyvګ7O_P`25f{}A\L}gP8jHC3 ԣ 70CnϿkf̘ l6[SRRdY޽{j|,˺nI***,ʕ+ώ2t.DSBoϡP`0q/P*_~%ͱ}vArG}MFTVV}GRbbDDӓy(7mtOi٢Ek xyy<z-߮p47~۷ro\^[뺬S ˟6}曯ZW8ɓM,IW޾Ya߾}EG)JV|aaصkW6mRSS ֱcGA:uԼyիWI"oa<Ϲj]=ܳ>[ٳoիWϚ5멧{駟fYVRyl\.[,P~8Pʲl2Ţse{0Cd4~(Œ$ܮCPp;W_y=Ĭsyr'U*ke5>???Ҭn$iԘqY#/__{sX9,^YRRZ㬹:"&n0`Bh͚5 6ҥKuuN X.|`4haÆ;*s2A IҔ)S^yI&4]RRpBAl6Y׮][RR2{l'O\YYh.鬭-*.喛ֺU'g;~]J'hAx׬][W/Gzs?ܳeeG{R2yRzl/mܴy++%?,SM=o>IuiWԮSKlTJl<ʅC'HN*:WVEAOՐpRQfhOj8p>`(J'}H|^/}שR4M4)ˎ,M(PYDA C*Y*H4gl@ EQkg8:TᐠѳB4M E x  J(䯑JdAdES$ŚpH` ϱ}qO(YT4QR j7m4C<#V\|sII::vQuIN/m}nN"28+IT5!^pjMHF{c{}?oe`:R((<៪*N\wSɪ5'3B>,uv-;4kN$`6vIKѨ,(=vɭO niwm0!DiղQ;uvEuXNG{<"@ƍѦ6m࡝;W?WҴ`pzԚ.@ \"s $I..y^O8 b@2U2$d@Ps.>Q ÅZŤB;O!߸1 t{e6nH=5(KJJzǻ8ncM )99V`qE DEZJ RH1q:^PЈB*'5JCQRxAD34U'zR4aY{4T'K*jє2>Tsd4E#DX )e5Ĺ Fe7N9.L ifMߜ@;nТy#G7]EsF)=fEU͊Q4LU>eYe%Yhv60,2,K;'_өA\(  ZѨe֤4z") dݠI\|EQR*E1Y(Zu* 0JZY Fzr¿ɔ$#9k姭Ϙz47f+/l6[i-|(s|XtUfmhHQ(J5#p6`¼ 񈑴J(H~OUhUZP ;( ,J ,IB.I& 1.yID 3vZh !ILбI¿egNڪejw_]WTT.Yb] $%''^%./`τ9H H=!*n*fhZkPR U" Q4M;+}Q au,POq|] (f(JE>LQ*.@ wO{V$$cb¡2sjJd1FQ] N*X@HRi| x&#q,{.R?+F} 4MF+K,IUAȲ IO+ $ !- E62 @bBx(beUUmmm 3GqnIhlhZU+tzP~Ok\(uP@d}HfiI}~)Z떑K< 1&FD0H@D$(cbh@EHj~#@ccu풐`UT.t޽UJ#w?WO76ZJ!9 {~}dY^VhM, ,!.G 1HiaD< AJ0s$auUFW.@bԧ̡VjKKJp6g(Kq.{8]zSN7EuGz= 2M) @EtֈarU|aeIZj]C˲qAء {{!lƏѨ??ѝߤQK{h]U+}c`0 )JʲlaNZ`oI $ @@R,: ʯ@6緂n++D$IR(E ,_ FP(DQ(,˲ EdJaI4 MӢ(t:RE1( QCMӒ$%Iy.B*Jp8\RR"JVoc7t&¦?>rDĮ]޻3e6۾55X3ѿ_ߎڿ?'sqSc D_hne+]6Y#6j )9zj(AE,e(^cyKd @ TjYSMY ŸEk4Mz9DI| Eq`0$ a޶!2EQ;, ii6EQx<A`0R+ <paFxjkjTZÅ <{hn_wOGCͯiv}kJBB~[LD~߶cRTFc~ܴ@o?ny  گaYҨݺtnݪeiUnӪUIi竿/@ɲ<ǿk#ʾ8ػ׍yBzIC! ,3 z 29c" hh8ʨQY*_1 IDAT+sp\8x0>c@j,T*QV6BV]ZeYfY6SR"@e<,Q9ϮR! 8.J޽680x A߽[W2"s[,ݻuUT_ZRv5lӘQ#qʪ]}o&12[o2aoޭ(7\KEڎ-/֬޷/kİݺ/,}OvÔ cPv7#[$顙 ,oܼeێz!w}/jC\˲Z6..n˖-aAFD# :۩Q")1qkkB kHkk2񂐙$?j/M@u7)Xz!F`0TSS#˲`pݲ,+NɈ| 4N(X, ˲_]]-I`eYJ%qX!NrBE$I@~efdUT,8v|¤)-|&?4#̅ 99G>{9<ƞ7|;ܫ חlk֮ClKN͛:AaVN¿ ͱL 0Øzw8,*FS?bRdx !H}Mf3mZz/>teυ@drQF쫽?WS" ^WR``0T*ILhӧ\5kt@ t:Z-EQ@_A,RxNtJAi˗O>\2..8-IkKx3c޵ |`/Xt׆j.W;P_{s~)mΤHp8Ff˦-?uҹCvbz4B @x ܴs'ym:uŸ>ZvôKA$H|d= mf[?|ռo;δTN uםڷɲ\T\cY{$Y*߿˯^EF^eH@_||9vPERRv966.pԨTvΡ$I8e V077()iEk."_۱C=~GxY-[4p-Y#Q!$RzI*8P(<ϱ[qlcQXD ]r bwZVe)җ8qΡמ@y  99YYsuhs`k IrrrZmuuuBB0fYe߯T*q4(رc,l=GmmmBBB&MNgiih,**JII(h46" GN+//oԨ0^Kp:k_֣3lQC:c^ڵiƫ/7jРןo9Gڷk={ιcgqZ`UINK++^ s~߽l8U(UÆC _ZE(JNg6nJ5H`3Х:kko=nYƎ?|wrҪ5Ϙ1x YW~NKK;jBon_~y^EVacIz=v[jp "˅C< QEQ>tq8,$IxdÇ6^L?w?XauprJϡV(<$5-WUTTRadGs =qc4hR4zڵl ۞@Gиq~}g;n;t٣GjjD+Z0`?hiZ>!7hZM  'ڹs\IQT :tsk&''+Q*++d2 4M͚ 1O6۷/,,y>bqW;r翽n۶BUUCF9sO}{}[u_Foi+'2Iou>\| B \!)=Rf^m;vzMRY]]͇t\R|( R]Yv۶3f>2*kcYys޼;v5_VVUegݵ s׮jO #ey鑿Q')!*BTdpl6˲ 4M{<0 z6qqq Z,Y].ޅ X:|vtqݑ:eيDQm6j$Vj:\.#'N !o x 4}a+6LeRxpL0ХU{/wQyGs[eyEEN@ſU$^OYqZDE@;\.łӪa`00 T*wASRRNJjj*ޭ0L5))M:NP\\FQ錉(aJe 5jzƈLSRRl6n!Z >HxF !YEB Ggϗ@ \u"shژJެVkMM BAzeYպ\.Zݰarz}QQq* ŘfQ6)) `I$ NbYYY)˲Nx28qL"ȯMSB~ c+ #*2G(ڴiSee%EQIII8Q*V4m f3Bt^III

J=˲85CllFqjZV6؍M6͚58ׯqF+*jZt:Iw@ pq@ .@Td<ϫj9Sa3p8 pp8<`nYEQV{^Ycbb8eY< 42 Fʲl4Κ@ =$IX0PaanVU*Va;w6mT[/XPP`4].^Y, CpHp8ji.++3Jrǎ͚5~sʲ\RR²4$ɲ'p>h4؆(A~o"IN²뭩ic1 xe˲. {\.G#i-v|>Eh5@82%Q$*zYBp8P(DQil6~222l6EQ]v-,,c A֭V4Mш%IjBͦ,]v-(($W^$jժ!ſ0Rq4$9OdhhVB>Ig3r B)iVkpugiVBl64(دpH!66-eY籯,qE<111Ǐ111u`0HQd*++h.;D i0FG !AH hgQ0`E)$IfofX]l EJ Zx<!xv;󉉉f%%%It ">ܬY3߿q`0RTXz0'%!!n4ZTTT[[+jU*8=QFEegg7o<޽re8NPBB$&UdY0N'\-[l0quR$5HDYT5zu8= $#*2ρӰ BnwӦMBG9P<Oqqv(ϲ,EQ d( 0,555kԨMG5͒$b׋g ST$9m4qz" Ȳ S=ɯNȐ @555j؄ O_Ek4{BN>eId8e50 B!8x<,ˡPh۶m8yn$IPD ؈(t&$$PUQQ IRee%q:{$)oݺUe竫B>111/x{h;聐pBȤKT Yf^`q.0Z,@Rn2G=2 6`YqAeBk0E6"ḿ ucEQXہ 5`G{dd,6 G$ QQ!Ǝ5bD٩S'hXdPP(zXVX7G=*Otpۭ?xMZ:ibM&lrr&sPEQ4cHH.Lӝq! ,a "Qbbbpx\0F8<.@dP@@e& -pIF`^~UUUnn.˲ʪwkiT* l4W^vlz͗wo4 ##}گt:,I={Fb2{o׭e[윧BZO6w/fgoӅD?\$#B}A޽{i d˖gqsB3t)†χ @0Vf`!CeQB" ry:G3& aHXf;?rM;wlǎɲơ;H҉hs]wvh>'rQq;dYݻג?d¾/Z{uY2Eb<:f8l /B db4E!* !~;2 8;bZ&\R0>>oR5N/';{ӳnN>O^͛ʫx{h4?m G~WuG6ͳ]pxŊO>]'rǠۇ`M2uZƌ2 Gss{򊊤}geY#Gt99sp8fL{g[7oӧ ]]%UN7v˖TΝ<wcFg-[&sJ*.>A 0qRQQ-7qb׮_"Gw6eyС)))e6[z;u)Ǎĉɓ|G -Zs=k1o~֭W^q_~ݥsg"sDISha(^ju!njIǎ]aW!RI34 B>aIEŘC+aíTBE14C!P $8Y SWư; IDAT'e 4S(Ŏc2CEŸp8 |_=&--ki4֬zAX0M²윧tÇ[,Ї?[[ƞ=xaan]78˟6}曯ZW8ɓ\ŅE2M3$eM[cwKD*nMqu@* PKT NBxrK` k"P{+Xo ׯZ,&S,:/)>KpNzٱGf z}jj.+r3>I&Mzۭ yHIi阱G3z7߮_;gW#eWʪ3xK<|sQ(vnspN9|8=n&2 b NMmb;\b199Yy+k@ @@ jpa`URf֭[= b{+s8kko=nYƎ?|˻h?p;;xcM6㗓'M l~Feeu9jNK'sF!m~鬵k3qV~;Ws#I>NBҪ5Ϙ1x YW~NKK;jCzIvСg.@!*Szå̆ v}ٔJeuu5qoKK0Hu1gm۶ϘȨeYyع|YYU9ٹkׅסwݩP(=}4t?oyp߿@mmm޽6|}VXpxk֮ͫ;z-\C9+cb s}q|R֟nԨ;T;we{v}li߮[Ktyyŋ/\feO[V ͍TVVN|.ůyO>9+1!! o۾ |tӳ[^ }\RΈבey鑿Q'tY*uvMJ6qZi- "OR$/, ϡ=U=ȲqƯa)RɄ}eqK AT;7ΥxM|6[;x[tgݻu{oo3M7_템FfM֭nǦ#_YkVK/q@ !ZpJ@ `XI(!$ P@͞sϿK/:OE`6=*b=22>|uӧʫD `A DF_^[+\*u~SB~ c+|~AJrڴ^YOSj! ^UF@ ?!WhgyB a$IX`^y^d AZ#Mj?z:0s3j@ A Ŭ1'ӨV(tZF'Jew a^gњt#׸h)T4dA"@ D yZ*p\/Ct@ D "s(BdiJ Je7_{eq7\KH#/fF vM}m}z7+,xEEuz?Gfo7|R*SRör\ItzjNUZVV3^l67f e }O_@ Mڥ78Qpw%&$1-Z #GzѨYhnKL>+.aV,}d2͛0LZjjA1tYء=˲OVv2 ي ;!Cs4k䰦M2}>ߛo-yz} о]pp[ y<^spRf<R49tOK.?#idkޡVURmiG/n0b mZso۞ߜ-[~={_%ܺm%K%IHw5N'^Քi3f1YJrc9\tjjjyM.Y߯ߚ׭KTР; t//m2˗,>j;LHݷ ҪeMQ￳ر/ٺmMڎ98)1) lՖ?G.Vi׶-B \ p7{{ee{f׭ld6Ho|47o_wt|O>5jsll --UP4j2ucopۭ(WT ssv8L8'}`zzVC3:N|`w޿oDVaqq>U(?3yQc'h{mܸÏ1zM=Is޸yq<Ĭ{3އc'L|7opQhѮm}>2cZ 8eO>}Cnx|Y7.,*3'<ӿ_֭ZnxUpn?o/LOovkjjwMddճl_:.{}f?쁃.mjQYU|qLz7Bqn]wQT[ϝn6Ы(TQ(4Q>HoJM:B@[lپScHzx_>;3g&s- dQ#tkz}^dY^oD>uAԠj9/Xx/?Sc˗TqCw`3㒒ӹpRaw8j_֮gYj;[1SR;;u6<_P`4tLTTffX-6`يER:>t֬fYfXr\Rnwyk߁yJkt999`.+s8b訨~^r׽y/))1J<1NOԎ;FDE7zK\q='nwMl~oN㸊PU*N|qm3'D+V}A04$Φ(*~Ѐ fdfbOyrQ-_:%5N'!\OYalXd4ۡٶږ82 whٮ#Zc RY@[ يZ7_}1ZOOJ1QQ?̝'֌pL11ѕ{YPgbۆXH *uS)<Qfw7RR٪e }LtT=٧o䷊>p\vDD%[o2:4M{z^LMMhRdJ?_߰?o J/]Q#L&szFx]a1Qb$:Nח͛5E._*^T1*2YHpPECLL}nwMy}zFUBYݿo>lyvY&Sg())5\VVkDZzFAa3O|+^?؇ʹ ΍_ii7@P@($9N]V"R[6o.H ŇǝϴtR ܳ !]9 qRaa 8dgoxC&>sӶQYNl.X,<Bcem՞"J偃xoҸSOK.HQ)ʊ'bMVQ#]/>@Ӥ 2y}ldȈܚ7^o25ɓN~׽:'!Ai.ַ<&lΛlqt\ZqPomu:7o٢ J*СC&'\h>]}Rox:Ir WCVoxB^|Wrx`&~rw79L{&(]1vugxwX_xpR]GQ{BёW@ pp:0jƲf3 RTV4"\.B@oll̐Z4oR)o/kjڤɲA8C?.@t?QWB Xbs٤/%x/0LfVV]B5!`x<,^o޶-EQP(fs{@@J,0ܭEsug04<,Q;;<0LtTԩSv˪IQ8r )o׫[gd$$$`;ul" yΝݴ%?8CU99SQDMBȍ(6$$M.\`F|nvե><vg uvƏ߾}y_+xu+W_LJLY- yFF_~UPPy>>˗.yapP8rĈn]_PT׮%:L1_zEС3%0:wv7nڼl MG]xсYsc Kw8pۻqFн[ׄK˧!kגǽ! G>z؇IZ˳ 1 PV px{{cAH$eee)Sܑn8ZV(tg+,s>>ʞ˫=zT*NK223խN`ZsܴbcBEEU$@^^^(+^,07> ŭZQn]_+ݺ0ZB%-- x+((.)-n 9A5B!٧ؼ~=)<<qSŤ¡wݯֳdi\,T|}} %6m޲|ْ;vT'~kĿJdxx_{Uu *kyBD(oPH$6uB*88ɔ.i0zZa .0go2888H.{yyY˿=d;ֿi۫Wn\.Kfv{\l 88x@???cC??/DQThh/x{o{jxKȨACGӦug;t kPq@9Rv6{7qW ZiCQBH&Nw%|) mѣƿTj0wc ϝm˦¢ӧϜ['~es_dڵgKݻs͟ɄO'!C͙;o1?Z!˯&%};\~Cƍƍt:o(uQ`ӦӧMj3/13 ҥsGײ2)AC5wZ`PnaGj:N+1fYB/<\$*9YFJ=^/b}qȈ AJjZ!r[T\y@0qĆBx`u qߪ!稆& 96fI1h/X7 `Җ\u{h[\#@sQBZʖY9@  pN T"0,+B@> BjwB9>P=JRy0B; IDATD TPʹXJ灌eDs,Me]סQ#HAD\ @N^IPzi* ]G H! A t:^ b?w;,sk  *8/s^>V;$AAsAQHAADm 9AA!%a\C#9ƎYRRX^f7kђ\}mz]N'OZQDM˃lVA*C$rsftoL.3yV%PAP]9IlѼוٴek&:.6S5ZY@'rjRRcDu>>t0@`G,pX射A2u G8͆ ?T+VmN յۛo.22⮷jAZs*O2h4k&.fc66J34:7B|xA@@8yvZ D0yBj90xMVcF=}M*55-.6fȠ%˖p^^6o Njs'ҿo 6/XO?uk{&ZfDHV Pt1fb\qCoa>>@Ӥ 2y}9m~}mZ/4jV bD{G%?Oh,00 2"bVfݮɡJ9999a4|}}?N%ffesSkӺV{99;vEGG齼nw9~|xn7["j4`xЯ&uD1i͛^߹{}/\r&O>r RP(7ox*Q(2q1|Št:]k^G4;vyͺ?~su8W^OorŲ{vٵ_'1_r'vBTYJ,^OI9vXtt0 ՗wlz`߯$VfƍF{g&"Ľ:}L֭vtpN)SБ'=q¥9O_\j Dž.̙SA <̬i3g5mƬaW,Y1뾕޶}#ϙmZ/\$uÿ}c+.>v˟p\CIɥ˗O9[U?':*[);aFr<|z'jڴqrJJbg~V-[\Vf9rhPZ4n(aZ>"Wv'Rty+e RT[Ei 0_-0R!СibLbrɓJKOYbپ `K.1sq>w+""Ÿ}ٕ+Wq{:m:˲ӦNٳT(?X}ۖ۵244tӆuubZ+ݱm 1|7KCQ-5kfuWޡGs}/gx+9J&srL&ZJK ACx0Z|c,D")++Kt!@;>[S _[sj* cy*wukNVَ?T*ݼq=Wx{{<(.6!YTTzjpFR)ee{ X4 y0++vCj9J\lѣT*<{B.B C4 }OñyzS&yxx#GPjN1K@H|r籲FczFFݒ#fM~6q␡Ò`]Kڴ7qcF;p8&1pnkPj,P*7sd2_DM /6|0~k1^nP^XXTס҆MV aUԲjܨmԓ&Oz! ZS=9I|jգ5k32@Q}}m{jj&. quЇc\'N%_o.22Sh45AAԸ9^JU*f[tȈaCkڌZ :vƍvlyukEQ?a{ϨFEDko4ȩS&~X+/76s,Z0oMwby'~?lŪ6[ݻ^ޱk؞1vȋ/5kڤ}'_tΝ&|:MVcF=}M*55. A#1#oֺahLµXBe}|}FcV \V9դ旺w?x؈by'67{}?ix{3cjn^3gk.{$¥W nW_i n& hs/K go^vNNxxw3K8^l0@}6lڼ`b;[Q}E6f'O5}3s/T_TdkPaq\ f'N : &hD+*:^xt4nPTV \'ERDiZ7N\{ZO{z=;'7'77/?zJ Bۻ{HÇ7oZ"{AQR|{7B(.6tZm'u۲2KBZOO͖ [`/Z,##sP~~zQC'WRڟ^wʑ""It-3em{/l:17Y ߯_wyG|v;w}޸Pfu&. nԯ&{ti|h`78`O)***q"eB5m89%w13~a-.+9zAh(?-7fX+;>rcǏ/^I 5\|g_9 o.33g[2K1ҫgiVkRBp:rrC¯&]u:,9T4Xst ZcI$hӟڽz_~饡DXNN^ldȈ 蟫U5v|]B5"$8(5-rDŽy\1fI5zG3^d]هҴIɬV{uA YL֑fi['0_?_m LUdeR*D!3h.ǎ}>}$zzuV>􌌄qN-^$`!/ܹ68Gs]_x>$$"A܇ӧ rꕫVWN2y\eæ?p$R"UU~R @hĹ92(M!Q镗_ξ|ڝsЌiΝ??f{j-??w 1jp7睷;"%5uYly_ e\|意>Ty>+T*͆3f~ǏxKE#--m1?Οt֯PQ zzғA !^&0RP*N$uL»="IJ;6 `bZVfffn3ʇqgnwů s76&7^w8lA;vޭ+tu=dd/QY4 һsQsR!12G4*%:?\RF*A(t:Ϝ>}4*))Pi=6Miy9J\. W_}-((_>b޽6iбs;v켇'^l(` lڰ~ԨCqxxx]u9Xs`BE <^'zz ,qU :4~0ojfffnJL;~o2, '4yfPf=wQ """92*rАƴiu\7  `Rn01qҼmޠ%:9-) pNnbOF E ox6nX|\`YBJJ͙>kV ;v0cƽ7|ȤkΟ8h&ɥ2'AiX6xk=T*S9b7:vO=P~K;أ8:V FD+/\*JH$IxMF<&/ .$jrg)2c' hrR\LNIIe~:F.{Ly<AެhK/Jz5?/CELVyef $ yxerL*۰iO<޺ECoOR.0.fsdFsppbo ahCa1ӟqHAD+*6ܬT&gjcO^G_\lʽ~=%/iMK$$ G9jf-ZSOܩ)S=*vc\X2\"̖g/xV!6QZ(Tj4۬C"2ixdTO1yҧ!ƎbIW^ 9ղGkH)] IDATfdfFTo{jRRcD5T)K(h WzTL3F[^t GT~}koSm6o׮cmk[x⥚  j\=[Yacw>v{ҹcGJi/]~9X`ޚ_>5-Kyw&vNJU&ygi?/]^,B(ǹ?lݶc}UV5ݨRq9uzrøi3g_y-a7kzVjӺ۽{z,vo޺ ƎyfMo ҹӄO'ij̨ǽo65_e! Pm9GYeU#N[W:b6_mXa#Fݺ>?].I~;s3ϜᙧGpwA+.6vqM{Z ^pU׮%9eFtGۣ 4 Ē пo 6/XO?%VN<}'G 1뻱Gnڲ$D qC 4_ͩg+,((ozիfO(>vϜ=~r\@g;lڲj9]_o3G1[EEFf-Fi]|HO0M>b8]ZbUHH&b,lڲKAǭ̝g%]n,H=_mղC4CWn4<ωI C ^^^cFy(b9z}H:f7M,)bwStT(0`OOMŒyUw\;w?3eL s՜s +Vs;{tUmW3j }˗,Ze͛^߹{}/\,%.\V\s'%cX.quA,IED59?d'w{!)hyyf!ԩv‚bZ̪l2)(,տ/u&S$]Ki|"eeM4-feee@V-Jw6zc Ǘ,[ DžD :霆^8i(bYvs'Jr\.Jb៓z썚4ME7( Ȝ`s/3;>xo܏s~(XvW)z֬[挩ST*UYY-j9@5m89%w13~a-.+9zAh(?-7fX+;>rcǏ/^I 5\|w.{q9KH}|;e Quhio` vT g Y5 IADS!|buC?~#y1\-~3t֝Q:vv Ǻ!DtÆ fX,>>>iiibfgg3 #VMKK7V PF6z d3$H,%s7>%,8n.p׹I4pu!N,I$*%}#%_sՓ$ P|a0YV___ׯ_X,cCCC ÝYH쐱:*ލ**u}EDh$s96=R}#R>[J:y,1;q]0E$ HRB8rY,JP(\.R;v`===VivLOJb |L '`

:LU*i F`ťU q&)""[n[\\^?{VlgϞu\.e> |YaKAvqr[qY9|(d۪H_V#$#&vHaH1e,>\w S!a|#ɒ؉e7||חvk yh?yGUF=y5T*Mcv0eYq{TJӴbt\.?FF?Bya(jr1LRTV4Rq8,޹3Ah$ FU$ Bf9N1˲,rY<`0n{ HADMUj5q6R),[ZZP(:ڇ (sQKDa,jlljs3 p8ķ*& sRyQHADÁGvmmfhtnx⿂@ qa =$ F()Nij|Ԏ1(JV̍e!nĐGESTG1L7jT*O%@A0 ('B:ZbO10Twz֠ &- [AQ#0rȐEx{{Ĵm!J)H)W%⁅G{t$&&cAD@tJa8ѫ&eYf0RhEf)\b(wA>x[^oڮ\ͷ֜Wzpg_=I BhЀVyn@~?TAtǏ,{-?y۶bB0.]+8pf ڷoqsss=5f͚UYyӦ￝u…+W "ģW7Zj1NHHHwqE Ν;iֺ <[!f FlGv…K.]|911d2K-@mab;@ݭ㓏?oâ0]zY:GcbcDc%v[cUcƎ"H}˜(*( =93^Μ9 444'''6.SJ '"TsǶwy^h4FLrJΝўϏ/ZHDNNwyObЧF[6m8sꯝ;5hP_h9c|g\x]6: &(fuΞ;3py~r|s0_5jx}C׈"RD_ظںږ-,`F,s7RV\&p7aaaQfy{WllӦ i`l\ܮl''ǪUvޣmq^jٲ%[mo㷕YZ?rİhs¾@ 6bWݻm{ȰOCB UnHMD<b I{ek3+FITJD܇?WѫWWRfl+"ںmM:yꛯeтr~[ؕo&5o֌|$UԉNхbclj;;wW(rO3nE;9tG?5`aZG"H$57y>*+֖1T*MMM itWiJ4D""VRRRHP~[z BMڹc._)'66VxRdooz]& _7qPBCCEQGGDŽG$$&\"iELڻkRP(Ξ=+4d:%%qj"C&&%={CvVN#HvN?pc ?|ߦVWU(}{i||Ç4^';ӳ3cl]q11.9@W^sK*UjZs\.$DˆTD*Dx{i''GDbaaan;лWO333?cYR438FDP(ZjW^ݺ͚6-[ʅq 8ɑ#*attzD"q2,..Nmќ.g?tk/?xPOoo={5m:|Х˖}t?|gfff:\=4|ѣG7NQ? ?第Ot16rK. }<?P<ϲsr2#6VixJJNQ1bLxb10H&2DllldwEt]]y$8C_VJMX@jZ&1 [cqի֩!㙡=d(zx^Rӳ"_% -iYU*MzFϓgj&!"6\FFGH$y7t!PTR C/Px3w4c8/CsT>!"a-cQT^> ]^re+ E SDp"3Hݼt'4)9]{sFljڕKe˖+PÇ6mpwpusI+T(oZP8")Ovx42#CRk4wOSjnrĽW޴e׮]غMeӮ].wRiǒ7[׫ffC8ګo)Ӧ s@˽/6Or8}yZ69Sؘkya(jӦMC ٸnm [_n]֩cog{ŋc-[ظn-WQѷoڳwaĵ(z3-̍pQ[J$"X$qq)9`Q/uDT/y^={v0wάI?O| زeˈK<@1:lH/~ݻw޵aß6-K :r6|UB۷`g%Rώ to"5zR"'O:eǒ=VğǍ}~XU߂*sQffVbcl1.]6xxrvt4lUZ\ U&3rwsxӂx*]Y7/%٤&52hNmRfe+MMe)əYvV iqqrTD; 46>D.IӳFbT|❝[>NHt`y\-?jpQYg8—<ԩӻXZZmشy󖭈PϦ{3[Ljx܈OLsΆz#dγ?x{;ϓ2?y)^fff\vKumllҲOnՙ#%%eʕcF4t!c,K21vQIMGVf* ^R6&-R„ƕ4i^EM2o֨Q,晙W^]:~ٍ9r/KcB`3fgkakca|nf6iDfmy c50磂cL_vZ; 7mظOvvvs۶c008+E/';㙆N3&auUJgok`&Ɍƈ׫v-}{ cR73aoouH$8 ^ȃ!N~#چ={l޼9~PR Y{^e˗q+_ƭ\z V֯_>C(8bH$''%_5zYZ,(>9J0rD"zاbJ}>r4F:|/t t Y9@| #Ƅ́2} Cb+{.ee=HٳPkVlbbrFsYv&:s׷x9@deS.rkWCR颌}g 눃;{v6t-P¸X[ ?5t9@ {`M ̿z u(S ӊ+?xMٻ7"꧁BHMMzY/է*+T!!DxR(,{ymѨ2m+2PʞVmQ=H޻]̛-`sA2G ؼiHq#"\\\8O/\ dZSJnݺ֭SΖ1ŋ/2ZlqZ񯢢o߾g~:IMؠidik26x6sH"YƘQ*T(h/ysWRe/ O^iiOy#"#"]ڶ5Ν'"ߙ#jժUF6ݷ=Dԩӷ>^?;w^ZM׫;deᣃ}٨FQ(ƌWD*=w%Kӝz-^w֜x iS&׬YC* ?~bbR/#(栁lU8g<"ճO-[ W].!>zPG'NtC}SX,-=v/L7pQF >"խ;n옙hxɲ9fU(_^շϏk׮kڼ9s8= 5b[zyyֹd'O,]wO:sS:vmffӧNڝVڵ{;ry{#?tgmme Dhh#u-o{.>>C  [Rt:kgkk>9=_\|}DԴ7/KD111ڞ}g/~'SCy1]~… ۷ ^Οp}"vzjjZҥޱCÇ>ND۶o>vv_8:XV1c+JRUw œ5o֌""":ש7ߜpGHz$xqK/ڵkq!Ç,&3I9@խw~ E{f[[>+Uqell,)訷;>$%5])vvo;8k71,4R${5mҶm=++]uWCzzzFF%,y OD_Q}ǎz;~ܘ6 P"rqqh1 EGCЮ.Μ!J[Qbb۝B&͛۳wnk;w1o4!!Q22RxտXFͷd ffffffD|ll–޾$DD.]trʕ]4"占0莻k\|c==;3vS,|0$/N"/Ա666=V*rxEײeA"XZZ:;9 qqylߙo|MK*7nr匍*UHD:oWR%׫׍rƉ a￯Q:q2Z399bŊD$9";wG *LLL r T(_ʊ#"RSSrG %[kV8lzu6kڴl2+2GOP( DhŊ{ܾ-`EcO{gO?!=h/E}~՟V۶hޜ]dysg9ר#&<ŋt굥˖M6Ӈws-|_۶i diiyȡ=w%'%/XP¶?cS}G %cl1C{;wL6]n$3t] Lf2R@T˳99ʷwMjRw9eӕOY:5P(>b{ 9M,`gRT+V|b_6>h*U=ȷO^ <P!s!pR[;Y@א9 P)@Ʌ9X t8SN$K߃̌ 8(9@'MM˺ 1x< ۷ԩ])W7WkkB_9@'8$bT*ޣFѽGWL.<$ Ǒ /'q&slڰێT~}o\ҫWϼNNׯ^زI\zӐ"|Q8xkrV@G8D"J4^&Tb"HRLn)qyHRDZ={ֹӷ۷ж|]gϴ.^U׭[׺u2ƞxqEX˖-6[3UT۷o"1"%T*5erL.72K$R#)c+/bX,.Bd,O85...B{͚56mXǏzj*U;rZoΝfffvHm'Nx`E"цk4Ph6uDP(/Zx#{!9c|g\x]6 )(fuΞ;3py~1"3gNQûwFsΈ8T*yL& Ҁ[srro xϻϕ뷅5~ļ~*j9>^S(+/[owsseт3|Ʃ8(}'W/¢[6o:U㯾ѫ7-{Gv6ve"9b ,*"%!44t؈WٵkkO!C]ED"d R)gL"ˌr%D̉ 8_y+.DԴ7/ݛ"t_|7nS;p0УUKccc"ܹ]&e5k洩g͞RKWCDFF9sEB۷ܵ;++KGscz$xq8t#F?5TUyatE$IF#&"XLuV,Rb *V8266 ETt۝G njjzÇZ^rZ*&Onղe=:5Ǒ緱9sRm<< /=ێ;njjjjb**もn֯_wc gΜye 4]/ZjwݧW޺u+<"GƎuL'GG聛[kVo0P.=Z*7\j҈9@wR,,, uQq#q'+VN0K=ڱ}{";~'O9=#9l[>R:zxʕϙ=k_n>g,?1/_[ 16ra 3yhhت Lf2R@T˳[N2դfo4[Z֯S=:&FVC^5toBb?/>3 $Zj$Pk\[:w5lؐnݺzj'Nh79RV-" y:˔)o'}gZ&OԠ~]ycc^:735{bnsq\/4W߾SM7tE@]:[{5rēyOںm{33?~_%`L&0蘘],^ȣu[Fjխ[׺u2ƞxqEX˖-6[3UT۷o"9轊  ӶL4)o7nMNNܰi˵k *RtmXZX>_#̟mۦuҥ3K$}nJ211q#G 5$ْ˄>ǎ8~]ttG|DE+(栁lU8g<"ճO-[ W].d(z>1zSξBOyy=v?74yNRӧNy?t8hPzzƈaC#"GD999˗/]\E">Ԏ-T::lիVfڵ[޵Þ<2@I%&*nbb\ yʉD}>|#"233ke+WY[[W3gϹ}Ei"ZPgϝ/KonѢʼnDukԯ,vZcƎW*Jro?333a?&%%5C2e򽎣TܽۻWV>lJ8 ńqc̛< =fŋfC >2ߗ **Ull|ޮ{ip:eR.NY_w ~ ܭ.\pŦMɻ7,,?,!!!qqqOHptt~8stpNHH033l899<bgg/<155{=vn;::-swW׸czzvfع+>>5&X\D(N[d匱F#,3z޽ 60ڶm t>wܙ3gRDRM<|ҫg[n);w>tbx!ǎP*U!ݻuIIIÆ y 7$IvmtR| NjTjJ@QqsskeѣGUZFPЕ+W ]2@ɥȡ3999˖-#Lܹs6ll]'wl D>5z-&rpn=~ +@IPbw<}D7G*x68}HAF> {ZB8OoQBs9J\ y{PB({wlx{->YtV@0PbxOg:jq}7һSecLcL3Qfo8*:xe(FghS[\]2%HLW̱Vi>2\6vXܮ8?~"J$t2 ,bܵՍ^9K.́@WjTjccMDYYY7n: ~<^eLDN&a]%gZj$PkdKG7i9U1=zh3, GD=\%*X>?.*>;ڸ9`} ]ο 脳0i4:::55U^41fY|/Tb)K#M]۬q&.֭k:ulc_x"ce׭**[{7l(099(+q\d܅^og\NuԲ) ,U*WpvϏ/ZHDNN|#O<1wGAA7խsyaΜy:}F ޽o9J6Ga)}se,;]t^R?"sr;"rppXb=;yaP̅1˫_w=d!!M ̲+ڼagkA}zyGDdr|;gSQT6mޢTR6lآyn(< =fܠ6:dĈQO UU^PR=ZlY7ExgϞDE(,"RHߘË>-:A$HH#8se{c>+3%&&96J,]HF HH?2@IʼnDy/ҩH$K`[ @YD]O׶gpnX"H$H8Evqa_KVk*y۽|ID..ΉIIQv5.>aرc;vsuu5tiDPrq'JdFF2Y=$RzqRLD-m^V6IԶ?V,Cb%%+7?9bkbUTq5W'"BѪU˼{{d2SSSo'O}t;@ڣ{9>^ݺ͚6-[ʅq >QL+"6QOdCja,G#"FDD`=ҥ¦wVΎJݠqdFn/#uZOK< }|{٤&5{]&f[$0^2'}@N/`e- >g(|5@9@9@9@9@9@9|<*w7555t!zS^X\J3ʧqw}oCWBq.DO+W*$U{/^]o߾6\[gbbˈ#XSSS|? S38CרGll;?!s`.@a2|-ОV22|\~デ]˖,~ƶ;rͪھTӧ sp7uĪ+M6;B㕄k׮w 'N~hGow+q֬]tVaA':FFF SU3g~WaC{vΞ]yo.^݌,:}̧O~ڵI͘>erZ5!a_u[t|/ZYײD۳͟1urZ5{)[&kתT*_;޳{G ~e֭;wYxCWߚ53.-^_NAO1.݂>1m B@i2end_-HMK>--,hLHHDf?ԪUS&A o޺3{SԮYSh0Fq{~RR2ct5GG }ʃAӝ-o `Z{:ש/y޳RŊ B>vp, qq+W,6btXXL&[xQbB$=9%EacFBa|Jjyk֮ݲic]vG'o0^xQ| W̞͛;ƴ)οyN ^{`JJbW דb8xsJ-H:&&6lƍjLζ07/dE0xoAƳU+Oy҈Cg͙ADn677S{ىbw77":vWR8̨rEf߀qE7G`ࡈwUGEGSR.*Gz=n^zS'O< 9cN[("{e@_k hf0!9gd qO|ތt;[򰳵HO+uH1U(fbbbB$#3#8c$xVjeS3Sf?|ק6dx1^3VoH)8N$~e>|xlj%bç~ O- 4;@U-IENDB`RaySession-0.12.2/resources/screenshots/Screenshot_20211203_173011.png000066400000000000000000007350721417052567600247110ustar00rootroot00000000000000PNG  IHDRF pHYs+ IDATxw\%p Vp[{oժ UmRU[Vmkǯu֍ֽ%̸Hd~=7G@iDDDDDDDDDD9jVPQ23e f""""""""""MNˋ//,_V&gjAf"""""""""bJatVx766FEQEQ5L(FQEX/YUlkkS2,ZUU4(J,ZVeYh4P9j4'?U'BAlN=_QUATŢ ʲHd UUhZl  U.f$Iv,t:l6k8,ˢB|IxIҜf"""""""""/R eYVS'B`YeEȪ,eY6f d~9C˂ KdX,v$TU ɲ,(*"J$*("&nIdDDDDDDDDD% [,(J\($ɪʂ -YʲH#h)`rY$~WZ:4Z$I#""""""""",WAW9!s亐b\Xk.FQ$I,:b变beY'F$h4111$ #xyy('ˍi2rp ^/M&($IFUU݋?D""""""""""$$I2Y,sllNF\ΫFw܉9}#""Hd2 fYX,dUU/(?^jNO!Wx9n(VM&hX,L&!22RH9E6W0 111B"E(Ȳ, h4J.Q$9=l. -}F3A,((hAQH"BLL*0'^@PPb(BeA EEQe3%R rpNO%[j*p"$ c2ʵ4$ (&I4 ]m2||| %Yff$*L& ˲(b-7(qp4 rPNO#Bנ YMWʦMO HX_fe*X,,˂((FL9?l OeS3x)"*h4k+r{hLԇ9=`N2!A3%X_:}( /|Rm cccHh4 HP:mgggMU0eA:TUA((q'l6ǷE W0'XVpr,ˉn$ O#"shFDD/1KyWZ UZ%ű|(],[9Ÿ:&(8ۿۍ&+ _2 ?e鱾ll%4 dYFEdYDQtv&l]NO^27WW34 F1LjO>V0K_ 涭[}68yjNOR!h46 m t1aԨ0ҥJZ4ևbى0 C_?/Esax͞ w2n~̝!<=*/}Noժ3g`q6d7mN:_|{{{; ߪIp_X!FmZAel-?ј7*E0xHDDxо-5i?ʉi?|R%KBUUDGGܹs@ܹoz<Νpy :[(-q;wz}BC`6v6$"8q*H|3DDDB,YK}j1_+AF{y㵲e1dhDEEYo]T(_,˖aܘhԠz{_owe~wpeY:+TF#سw8t8Gݮ S\| } Uڷ3C<ʯp9-K~sf^<ʕ=a}~=?<ߨ:Bv"p)`/ +~0J(h|aggtRZw,wgglZk֭Ͽٽ~-[jÆ# ˿ %-@n㺯ym͛6Avm5۸k)EQ+W|56kӥ;{&N V-CѠKٖ|[k n/_1x(fx{];cwѻgw8:8aj4d"hP̷fs/dx{*LYPz5 2>d).]n[\qG!舁b3rpϼ`EKpѤq#x͙ p]4l͚6yx$ Kӧ?=þ(\ aÆ`OS=F! B>}c'XosK鉦Mǟ~Fƍpj˪ $ PrܛlF#aa/_tj64*:NxOTɒ˖cݸy+[l]ϖu0g lؼ& ժV c\vɊ)۬N0h@?Lh6n޼"p/S&eX,8rx7a_x?U*{b~|v=< {Yv{S0`&"""zi+7)Dsz6quqK5f|v]fmyM w~#,<?j{BeV͛61n(lC6Y.G71h@?>0b@QJe|4+\]pe< ܾs'vmZprr7/10彉V}1>dZh=BዯVK q퍊c(X~;UUѶu+ԪYQQQhҸ8z/|l @SbklQÇ{g>mGYQ0s4A`Xq3"θu>b<ٹ0&OUcܵ}{-ϕ˯cۮ'A6c㖭]+VW+q*Ǝ Fj:x V]7nb /0mdȲC5GDDDDD/yeoܰf0pq[oLvԩ3ow}Çb}inrؿ/ڵi GDD"pC7:.S q'[ڱ S6[nڨU:@$j'OETt4Lj@ddVY'Oځbiwf̜h.˖, #>z/yVz? GHh(QdI|rLϹuBrj͹YR% ><@fMš0PU`[ف/W|mӧߪUgn=|re8t(TUaCg`?EQT]isڥZh#G"hۦ?$IJ>WU#GS<^GŰnP/^– ** @EUкUK\rǍUXCE^95ozpßb :y퓿U`A,^0ߋNz`M?wp%TV@\pZjX?:Rz5d<|ڷmm@%Vf 1Bw{[3+ݺt =@ժ CUмYS 1s;Ɏ[@,]?+tSMN͚;޻Fa?6Hge\p!~(8y $£қۺuޟ=[?5{&Эg_L:߲޷Wwإ;}9&M…g;?(^FB &ږkPBh46u2~.{cԘ 8y*#p1t}·N|̙!"#"g`?$E1hHt o8Gz SݺbƬ9xk8uMj:ܼuVEbȠ`L=Φ9""""Wlb9Mr Ġ}ŊHqAƍ͚]S 7K,k?@%,Y2m͎E 7ǟl6rpp@MqtǮ۰ sn@?}3`01nHL&ts/S  4M/僫j .ALa[uQX1|@USNԿ/~WDGE \Ν;׮Ř#PF5ԬQYΝOqRvv:XGGEScOEpd~~طG:&&??EQp-XѢӈӡ= z=ܽbOP ];;4 |}0{!֩_}&ܭkܾ !** 7m9sاoܸ 'c䨱>c& pk-!**W^;ѻWo4` h_ l{zu:s!!xf 9Ԩ^ Р~=>s~Z24 Tl'N9иQCڱG`n'UUoťQMԯ6AVcڶAzBޮG?AUU?®wM ((?,#(8\{/~s@"NJUU`O?#,<7oCҥQt)(QqVȲGph԰'OV{<""#QDd ¨P@lݴsg}h%ך,x.:ag__?4noQF wKvܢEP'nɄhݰ 6uܶ;a4a4׉S(GׄKo8th_ Z_|`4m#"""||LgALwEN=^W#tfw࡯lzYX"&34fcx$,ݏ֭Z`z&.i ^FffK 7gևe՞@\gGGGw s' o?Ǐ?FŲ5 hڸvYqܹ{sXl?hJvM[_'RسqA*WRcFĬ`X K^lF#AUUL4%7[7HV ]SHZG{. qF٣uW1j,VYvk'aa20|TRk߿/*/:t..u6߸+\݃9,[9֯^#GAM.Ku/=fgFF/WąJu߆dBXx8|S3XѢxox,?N ԯ͚YƢ8tO#"ЧW;v0y }{M[,p{68;f%Œ <^썇}Smo5jW||-gS&Ibccx> IDAT''Gx͙C(J\FbBy3QJy7)g $4]IBY(T \ELL fӧOS^N*clشW~Q?RpFױd7q%ܿ ,sa̟3 歉?yE\VhD*c{q]Ae< ą  (Ȳ Yg`L߉`G? Щc{{l]~F`ޔiP?V-cْnD }iE*Q^aaa!ZlkI|K|-|Q8c/"t{ ڃRMmPZU\x)[ѹSGQHF |g-$Zػ ,K;_։eٶC7[H>|#޸1_q~:U`puu,+ڈhozbbb`40fT?)VXʗ+3pR< xl cbb7j;wB$4jXwf6yG0?:sm[%ߌM7h4b?chڤ=~Q'N9 ͚$gRbooҥJ;x tW2$I Zlcܸ1===4)Z]-.U {ؗxobc @qDcv錟l/-HFKnz0gԡf?AAܩ'OlYwm $Br~;^=ĩSPUn߁FAƍMjؠ>J,NB cu(_:vhJvv:Tz qD 珈f!,,Kv'OXѢhղ9DQDݮukoBkN(RѰA}?i<6nj}'ٹ0DQq={b*Q"v؆[7AElܜ;>}˹NOEmqQZL0 @dd$]yދ_^&OBѢn5qi\:*/s`5GpߨP> .ٌ+Wa{ cڇ0ahL?Opǟ\-;},f͝}{c$ <ĪǡÉ:|˗-sagܺ}^ |̙qGo@D<_p%jbп_ob[lk^k`!(ٌG͛6|PdXl9s/Ĥc{v8y ֬ݐl/ݻw٣+fLNϲ<oٽt:BBBj:.L2mZʯɏ_sDDDDr\r \`5^գ!""5a]`+E2FTT;%J`Ƶ~~XABaXr5ǩg8y==mXd vc f={ mZQc3{*Y`TU,˸}.f /[6wŪ7vf f͝uj| S雞LKt{x/ZǏ1cL'[n#֬ۘ_~=߲_@ϾqL!ǸSkaБn:bc'|@w)?RܶaTwǟp ;{ S. f|dEI&Iu///G 2e$FQN)$ɠ(k:hu:h:{ͭ.R\h z2g}ڹm3-_ȒQ~>@Hh8oSn ~}Qn-2R\A쏦iQMMVxm6W|]6N9x)]'N&W9~}3VW׊4)Y+'{( DȲ-bd2hVU+ LpVNO(_P~TD/U~c}kf"""""""""԰EFĀU~;OcsĀKr\.\S< !'@)рO e("(8(\]]xeɛeh|0dL 2eV0Qr**{VBresz**22@,DDDDDDDDe3v B0S 4)BDY,ŷS!((([qx>^}|)/ |||//bQ0GDD(<<0b ҧ KS0`W `Q˳ 5Hh*%+/!(;pD5b ˋ? """"""""=* s$H#Mc """"""""ʋYUUYߎ0\Nt)'E/A[Zni`#o)ADSz)WH6N_gO^o*PJx>@DDDDDDDDK`LE^+^spCTi;03xe۱)gZ vR"P"JqMS(GcUc=Dqu_P|<1x.?:NXUDDDDDDDDjeuXqfΞCGX=rnrS5!TUqMJXɐf[`(]1qxBz̥x9a8[+3t6ر.pw// 5J!sZU F4"$0db ER/ѫ&V0uwBy^k GR%..8I [*U!0 ʓ=˺{ _6C1k>|.JfՆ}*J$ \NEFj<(vm܄M`Q07V `U a nZ!s1AD0R_|`F <ӜRvICf(˓= (]ka01r0]6bC>0C՘BW )&}d un,H\s; Qng{07_11pw/%J0\Χ)&K9iO"Bw%P:H:CxGDDDDDDDDD<كƍqGiD|WUpZ5a29* C@(M1"؆>;X4.8Tb2<ك9jvʱx_r61VTUBY[:,ˑ#TԥZ' rye""""""""7dLPx+FW-T[ЯE A#~S|۔Vh,SР BT>T#|մ $""""""""z0`WBxhPpU`aS[ vlADDDDDDDD3R<%""""""""""Jf""""""""""DDDDDDDDDD) (S0Q0`&"""""""""LaLDDDDDDDDDD€23e f""""""""""DDDDDDDDDD) (S0Q0`&"""""""""LaLDDDDDDDDDD€23e FڵdZ^=0a)S!"""""""" >8sJmڼy!!9="""""""""zA ([==PU5ٸݺx5kTaoo%J`7;ǁCP<6?Dzo7oƿ@K/^{ݺc(_5+VqIf v{5Ul~O$z<(NPFoCUUh$ u뾍2K!00Ohuǁsx) =׫7WW<}/\?*T( ܅ X,kBٲSgj """"""""ŀ9իkTUh~Xju۵AxX8*T(Aǡ(Xjլ(`ڹ^?"""""""""YWbj ͛ФQTǿz޳}ºm>z>mZDAеGo9z DҥZٲhղ9Μ{a#a6S܇NCoYǾ۫/f½ѶM+xTM[kjj)ڠ۵jxW_7n_+oڌ}!p ,m۴FU͎֣7ƌٌf|À9,UZj EUjSmw""2Q6?!&&1y6 (Fc@UU\ ( Jo~: f3CBpԩa2pE]6>^ g^*@7wpuqTXǵX8o.F EUQn߾P 8ӧҥK͛ɎUUw~(8q+nn:DDDDDDDDD0K`Ƞ֥dYFDD$ =@R800 IR ?22gEX :AF>o"t۷C.1ksХ;ֱFHK`ѣ[Wth:vU){hټ5lC`_%:#, L *cbZfF<`~`@.s*zCGAnV?gʖVX EQo1z|˽zu߆?`ܤнw_e⏡$ܾ}K}"00}zFIm؄CGhެ)+~j(n퍊"xg+1[̐e DzuQT)~Vq-4jPƌµke4aȠpssZ4oX_~S 88U<=p-l/' ^+[<2KtR~DQ#ܽު>={܅B%a4-,xЦUK̙!=ҥK'~%(ϘLf|Wؿ&N?|wz}A,Yu۵߂kzluF#fyǘ#ЩcG<03ly+?y*`&"""""""""܃3eJZ(3֬ ŋٻ㯛M-(-P@ {oP|_@UQqoT(!B)#i&H6M|Gmrν瞛bs9ĝ?ϔ !B!BQ3TiܪQ!q+ڮ^ɐ\~f^IwK:=h IDATuUKFemJ&MoYY!B!B\UD˘kbQ!j^ϛ͢EH6ԯ#OLjbZyl4_;︍xWUm!B!B!.IU6iS+-[di ͛eq_;<5D{ #x_|?k.UitHԫkuMӡ}2lUxח!=u 9NRr2Iejc[nsmWYVծS[r _e|J\ymv;[lvڕM!B!B!jJ UM_&OJ$VF.ix^={0Z>`Cb]wb0֥ lħ?|;v0l`n?4 %B_lsso׎ڒi2y,_U/E\Ѫ%M}ڭWtڙO%';Uv|[ ߏ)>R]B!B!Vik0c+5ss<}}TxiFGN.j=e^;_,;y`ʽ4υW-3g9q$e1qd/>qݺ!,>+׬vpm,V+w7~ӧЪe |!6вE$k{{y4:wCL_ct܉Y3^'q n0gӭk|mn%%%dax8^jeeİ|4SWo>F_[!}B!B!&ԛ8Ϭ1k^lnu~L='ٟFQ7)zd]͛Φ[lc#׌7=6mʱp?7q٣K./Q=:OM޽zq9.[Œh:z| k /VG 5kQv-۶3|}v4ؼu`ddfҨaC K sE P׼=4G]1}Z!B!B\0d}HM5 @vd#i>ejxÚE;f4YO`2\RSIHH^ݺ{S7$"f!B!BQlk9jP?z/̌Y9p Fh]U 4SOs!]_0n5E+[0xE4e붿J\i1 FHH23M:}=n~iiDF6`0(GQ1|EQҹz z}2_ 55޽{]eϿ4k\$_B!B!5Y`Vl=/}Aѱ^oKnh(RQ`kXrG5ym5 z:l} ^cn}^p:oxY6k-#ev֮],^/=Yop9s!B!B!DTjru KRecy8u~# oc41ٻ`K#B!B!ūͥ@|U #dٗysebe7+B!B!jK,`xcx[R4bL8B[o Z=B!*ޘ㪺 ˖VuB!(wV,A\*.WsBqٶu"]ŬU^ׇŶ^u}(c/u^ 5o>ﭸg>O!BKY,B!*Ti,pB!5%0˵yw `pӹ !$\Fe!B!*ХD W5B?-t;M.+RH.gee~}N|\w8_ B!V(|.. /(BT-MЩD$H6Yذ!gp?FǶ}TUEq|9UȤ$.IL9s?fHH]L&+\MRSSX6UUeĨŝ#;;5yӟuga㟿c( aFĝ;w^_ou. !BQZ !B\fjװt[h4Z>999Ď4܄2W!aCtv^%C~nWwV v;hFW>@:!Ye!B!*B!gM) 5s9v DDD`XPU9B> h UQ@9r9WJJ2jkVG}nݹ[6#F [ffym `5J.];.W!Bdr1!BD3˄c ҅Q70F#`Ї⫋ ^AA z̪(G9}޽zh`U0F@`BBV. 5IOOGUUz=7qyeIB!D &#B!.`Wᰦ(XPlٰlfԩ=xzfK6)0h׾GDmĜ9CNNs.ddf`ϱ\d[#Gݧ/}GUUAe!B!ʗB!5SD HX_hӸ1IZiӡilVm‡Au7hE ۻ}{x_H':z׾adWGYYf֯[㪓B!BTJD{((]sLsGc*Bq+4Tf=|___qm6Ag1sXq1؜U)v t$. !BQns:} c; 6 LJ-Zp*1约:}4>>>Hί A2]J B!* En2cR>/PE !BPAAS[ώDlѣGI7ҷ/dggѣGԿs&A 1ɎeJЇ.\Y!B`URh҆B"Bnm!B5@lو/'3+ `ȑ#v4MCד~гtiY0I@6*k׌a4iUs!>[Ӽ _ɢ ? -{$&&{ayrE+B!j*Y"(BxxPUS&!-QBg!)^(`ׁ]SlЫ*)nvZ>s.=ia8o\T~qdbUdgЬy$Æt̅\^7|F4c$'vm4hpG.Be!B!ʦJ^^~4Y#u ]S\Uͱ9Q56*ܤ/UVaxxKUWƎ/A1;e^nmy,BTKˀG99\FK;PU& WY:ٌPx͛5gl68guBBoO=[6o7_Ioyt܅ďξ=ē :^m[۹OXlXCgtbpt/w`s3Ν;y:. !BR'>k#5Fu.ACcLg(k/psCgghh(*[۶mxj4 UQKVٱK;BYg!I+!EQ0(q3~II8XXW,դMv [sm8q+\ FQ@l':vfĨLy!Fݻv`AG7s.,^O;'rQg7gBPƃ=̌r߽$\B!SO 5-7l$;RheG9}TUi\z[3s#+VZҺukg;NΝhެGC4mڄ:7ٵkg]mtڅMR^]7jDYv- 3d ׬X"wc˛'U'BT®6R-z~Ԣ0T (~(F9vғұX;LSZ&YV+h(:u eI+y+xC?7|i:p/6m21.%_#ɓ}ڥ d2Uy!()u$f7r:Yϱ88r¡#i=AlF\g-7g&L_W pS[`ͷ)vOR^=k z9#_\cC1h Lyk 7;9s3DDDЧo_4{ٮih*茁T[LnAsQ)#sG?-seՁ !2xvUE޻punfUF4RRR\m'$]tfO?Wy !<*%[4M s}<}N<>b499ğguĜau7pu,_ݮr=r=g?~,ƪt܅.]Rvmg7Þ=0~عs0}s$ƌK@@IIIl߶Ue!B!Q:\V5 N9bs0\Ke[fõcU ɡC2hו'__qGw'ƞ={]W^ٚu_":z ?tׯG||[#?*OKmğ?o~:.K,B!j*Y"îj+T 7u?3v,8p,{iyK_h:\jQ|_w~y慗i/vQu7;wK/Mo䮉w2bp23߯Ç VZܹd^~ntj3995k1lP> qBqp9K¢nsi#B!%W#KVh益juc?hd͊k 5wt8o>j9di|vSSAhhʃ } =&Ͽsqq|lF FZZa2x'6u*S }l/7ŭ,""1lRSSYtYJ_l(]<B!ʗ *pY!Bҫ̠Ŭ荠jqǜ7B*y!]+qLf3o~몋vW'66'zT]R? B\4 WdB!&(>2T' IDAT{켡ۍWWKd$QVjuUwC!e$r$\B!U5c=o) ׶Α^jTB!) 'B!eSy>/V hoYe1p {mOkO!rT;qĻhMSIHH`Z!B!*Y"M-=ve5 9\p !BMu }}}y(eKɦi7nRpYc 2*e^oB!樒%24/pe87X(;G-;nW!B\A P^}9s46sÆoaFX,QQ+`'DF?3hP>&#,,$-[%ASgԪdb=cx3f,.KnߑwLDT ~}= СCG.5ĒŶm[믰X)w=Vpef]B!V @\ t.r6_j |Joؐ,sQK8BQTp BUwߦiD3s">VX| !Bqٚ>Hd=F/-fN,gҴY3ZiS]Yf3gϞZ7z܍!U7<=m*ÆK\ծ=0zs}ү 6oژTfC /лwz8z٭lذ @VNf,^.йKW~#[6obР!4N:t;DD4_t۵nxo,׋zB!Uzl>׍rp64G yujsKo\#@яL4bbcB!*3\`%,_~. 6"(((Π .Ļr9۷ϵŒEFyG_ 00^ѭT f 55u'8Sv ױx׋RzB…'. !BHǗZWZJaWEN\!Bxp $.~4Źsg[~~~$%%ƦMһO_4ڵ( 5ѫyFzQILLh4ҳgOÇjٌ9,l;xW6=zb}L|o H,B!.0(B\2d!B2p 33M] Ɓ/3v}ϽX,~B ^)uh0b٫OaGB@a o)z# =*K e…T'B!j4 BUpY!.? `AiI\H;]BT.iyiY=B,0 !LI,j ! (5QBT/gZg}&^SI}6)x! lJ!.0ǝCU!$7j\]0.˒uq5(pY!j> TpY$B\4 'ړpc+ p9B&Kd!ʮl 6Ν+t+Vqf#>>KhbԷo_xUQQwxq3dPr'Nئ$p۶W7= }cWZɻ#D K@]qyc&[߼&HDIf!Dٔ-867r -[c2iiie ?p 7?,KK.зo?TUE1l>l6{y?sa HBNo_nrEV[Bx!ᲄBJ!Kd!.^)/nNnFnFnNs-eqUС#aaDYǜO?smf-X䵍޽ŗ_|*-Y>!n]cN,ZÏ3yBr!'eOӴ߮\?\-v !dU.ZEuD]UKB}YfOLń<<׬cuh6mbзo?֮[ϓӦI,eNf!D),FV wӲU+ǒ>\_ H:w @… :UUKڵ1%zMvڅFo&K,fqLA׾G *j%6IHHݮ]L֏#GrM7E ի[}zo裏 ˌ3+=v 9!.oUW]_96\|KU!D%*CܴiSGN)vے\7gj׮>DJ2YdP‘0ol߾g!.DB[.7خqԫWq< oͳdG߷e˖RvbZqG׮ݸrIg7))Ɍz|F5k΋/pmuwGް!۷'66K{0b(ۊ<tj~;55W}+λ`6S&Mwr!'pѴ?l}هx >M7j0hĠAZ׏!Cýd d0fGE!ЦM=M{]vqף*[6o)j7OQ{I~I,+}&MѰaKFcǮ*isń@a- _vewR} ̴;rAbB^}˖3-}LfZ"G<` oI OӸ 9g?^=BVU˅|4<<ˋcz"& >G)Y,WuB\E߿AAԪU`||0 > zz`hŝgԫW3wVٔg\,\@M^ƍDj#Gq]Q4-/~|>F1x0VGEStTp؃ p,denSiٹo}n?iݞ[?|=ȝiP!j* uԝ9y5vNzDʨ !Jt7t*zCpp0+/Bic^kF٧5Ѭv}ݷ[6of䈡?|ﵭ{0m#絑[?|h֬vݷUU9O\mǮ}7oİC\feeq6YCꄸ$ք RN=t:}Z MsϚaPU[mٳdҧo V*QP#:^qp}ZHH81\p!8/&&kNH#Fؾ};C Wpi[]LK/m[8w6-7C8gZݳ 2i99rADtδ`atdM0🛽VhiFF_s O=U`-yDJ.#"I3p&_hsdm,<&cǏ׸q)(AX†Of!_siG.x3"y[]݇v's3v\UwA\B/[Z)DDE6DFFiLLXvZ**SU{`:~_-߹DwgϞ#4>u!--U޺u+bcan5U._ݞtz|}pHMHH}4Idggs?DNNGB!V0\~yLEf3nuʰIIMemt4 lђcG [)iYfZfLsLx7?PLΙh`vδ9b$˗-c0ܙAD6dȑ)8W `Lt}\RgYh18E QFZ$Cff&gϞll,INNb*} Kж; Kn-ǥwWʾzѫҹ+7n$B<-[$ 0bϴv4v˖͌*fe燽{s[ͨ-ܽ{7Ç uFG&:zkoֵ̙ srgZB,J3-c%yDE̶Sn#m_gKܖAo_}D5`OUPFHOO'66deeqqΟ#Sk==S~D*wLL 2޽{u !*˅x=_FV@8~8oO>}/HLL$\.}$\8.{'ra;&M"i׮;:#GpA\qW٤I?T/}.U2a.mlv_ u>996>`~#%%3ا,N>Fzz*z {] yM}Z$pB߇/gUQ3gTu.IU0kV3?F x}dM:\εjj{!vR%;l6owt:oӧ;:q^9DE ""I h,[4 ,Y\xt/WErE]|RJˢo;$+ߜL KvY֊_qH:tbb׮ͤ%K%].Z5k{f˿]+'%%r2N$5V###-de-)ᲄ!""RSųէ߅*"$dU0ؓHi9RjWp 7'((}$%%8` ~4n'{ǎj{pN';qSHy)/Yʫ^ŽF+D~G||}xݴmۖ3gbhJ=ٰn-?d Kݶ;+žXuTjCN-[ררgDo4 3LXMV kBWddQU,Tэh׮=##QPP5㺡[I~u=^%r0r94!wb1uZ,s]ޭw)\-X5kzbnr{+Hݺ0 !P ..DWn͈Q_X,5#3#̌ #+M|iէE|Eq$d.*]!Xڵ+M4fkQe Kc<ܳ|ו҇Қpx&Nk 'xطo_LT^ܓ'O_pQ;OLuLŎZo7lܹ.X ny)Ɏ6jԘopx╙ݚm4;HΝ … nV^VX·uyw/>_{w7OaXO?H|)40ldV11Prr}IMb27⧷^)݄Mb ӳY h`G^&z5^O+j-W %\+Ჯ{aرr T.;BZee4__B\zaƌQ-]ONx֮YUh\ ˦,72^ `00?}>̺ufz۷aa_`5yKwt؁uC4]<ژpxYx1ywо=3gL'!!_x]wG^sF1_߾\qE+2MkT= IDAT&6l@BB"Æ%$;wfvmΑGKT 8-"cuy}j妛S+0G~o-UWaZ]}k԰!znHbmhFpP'ʨU\yek4nLٳ]5"ap@pp0űifRS@AToEa?kd5w^~e}N|\ $\.E[eԺu "##JmZgI93,kb\+vգf|j^j {5g>҂-@vL!e'/1ǟ}6M8z 88vyw{5N1_֠Rj3q<ØL&{&=8V_V3v6̘/~&NL&wfq$&FXs* 7kzdBP/}?2OOO[|}8-W*ݷw`0d҃:}Zm9zrF NvN6'?\.g} П?WWWf3r;wÓ?FR3ct c#0m^y} ')(=f,gL6^OZZZ+~ 0tpF#k׮gX:&?<77w6o/>sq)0圯h$7qv;ʕ+01ksƍ#0l/+W@E~]F1v4 s|E׮]1c:ϟgnݚe˖1|pN<_|C=Đ!C ##3qt AWP޽{Y`>U:EegRXӤ IX?id2T*ja@a !x#YcB&5hFcdlnلbŅ#Gz25gJŞ=hذhdL&h$˒\[5ˇչ\tP\ĵk oo_,:JHHHsNYh#cǎ[J+EZx5r_HKpisGq3￙}HwwM`Hɓ'ן e_ڵ+O>$w}7| 7ovSJ{*w~F"QcGo<7ܨQ K,Uu̪ FC\NJhA~~>} QGHKKgӶM (x-FAVo'NYv_:v O˥k8zxϴhޜ o2(0o>-7g_sX.nXQ}_1~ܝs8x9ϒ~$Q cXP(kdg0HObyyu7/ެw5vBBB4hU0qqghѢ'G7 N&mnӆ͛sA:wBRRs eٽ{ɽ#lsرm];`',~(W\8N#^j/ʥkGN U'`̘1;vK(0\Fpp0| /_O?EL>BΜٳ-!Q@,,ɸ{T* a44e¯!M$"2Y=( 艧f̰F\*)mRE:w Qqww׷S/V(ۧ$.>MBE_۰HI\PWeƍ"iikٲD=S@`yܻw:vHNNXn*ˈőJDZBHSNHR@C??(ife:-T'00'ĕ+Wg׮ ~.q`>˛T*7zŵjACΛJK}c]7"Lx+Wnpl޳p"!!-edg[79S*9,Nػw~Cۮ!""QeٯX,_m۸D~̹" 0Ny{ÃӦڼ7:u=-oʣYӦxϤZ?%?/eիM`޳gͣȑ#y; 9~%n0ɓ'Y|kE\>bG pYڵ E\xvłL&cAl/ZuGfL# }ѼysyǥK|3D`'0;P1gĉ<7k5LA?~<*-[Y={PZ5 `d@xkGlb"gi޼9:B (75k!Ph`LEd ]z*ݺ$ G"mLfϼMvmf, ݐ)BI\vnd4j##}$qn kAiV*DQ[ug [JE,X0A>}".뉍uܶ}֮H˿DZ~g{Go"]imax"JM6&aÿ޽|ݬ_ܔGa*!ޠA̙CPPJ \s$q6νk ]T*Ü!чP(C^[-ʧV/bСc6lHF'YIѮm[:h9K@YV^Ȅ⅜**ws  e?GxxۍkeJE[2@Tt4S`Ó{xOYgJ\C*).8qԖJ5t5777"[ݧ~֮lhO m(QurQ٢lLՋO?_{.yxzK35/gϡCt$ϑwt>r] ^xK~)6oիK$Tcf*0{0j7nLMFT*2 // y.2o~ˑ [>f T|t} P(mʹT*ry{mаRKJZbA.ܔI$q2j P(\HN>{ͼLCլTvgo IX1p !!?W;%$$$3U?SRK)UvJ#-> a"-ojw( ճ`^aeys1GJEZƳw^FZG=X`wfΝܹV^$.ks^#ծt]n\./* 5731yӧy{HKKx9`u5,S/(,IbYf.s>xǟ|L{о=Μ-bRzM$& S&MHNNWϞ?2F|+MEF2eT>DFFaaa;wس{7gʔ6#]˗ {Ab]vd1{F̘}Xl,ju>a9x4%ÔU]AFkd2a2jb9噰4`h. ,3#F܎La2HNJh4rX,[1Ld{5V)'&$з_$"`-degJr%m^^Hff9j@kjFr&-LܬrM5f//_BBBhHIPCkU\2-í"-4JFZ5,>2;֙-r.;b͚5ڹ :t@PP]3d<3:}~:yGjWwب:6e SSS)(({n8LE~bKs4{~#j4.mdꔇmev!#Ú_e˖zzɄt8x%?/e)<:~7_3r<8qݻuԩSrZjskwX=6nUHݺE>m,1ǰplܴQi۶-[nem_T:sb256YYYlڼ~Tƌ?Z-k֮EpLO=!-[rId2>>>J!qcⲛ; Qj5Iۆ r[;Ǎ',3ݺw'a}I&=0]#܅ oVƾhYλӧ/} jmH3ً @zB{xx0nxziE]k,Z@8@bb"mڴX|h s=Gff&$%%7^)SO"ɸ|9W-NyGI"dtz5탃9{*z=d2DQDEr9& Ks0#(c`1"%SdT<c?[,-*6Wfc},6m@Am[7W(K3[5ۻ(VԢղXm+U\;;8gD#.Wqe-iH!%"-y 5H⻎'WӮdbkpf)iYЦREdge#Gr:Y'HyT\ lDNiܸ1*W t:\IԩSU[Y\qfk0q<3.cot`ꔇ9leZ)SG8`cǎ`0@VfIGBb"O= O>8w/fDΝ;W_`nΟ`'0|2bpT..:}KFF]hG;v~}УGwGrZ_kÍ##s"'O@K/8 ٽOJJ⣏>p8Zr+W7L[7Ăsg5;E?\ǟoLHH`) x?;h/SY+OMnݺqпA 33<|||iڴ)ݺu#,,:r  ;jIJJd29wC28⪆˧Nh48L&"7kvokM!0z~9J=i4ضXbÓ9̽JH? |UI\X,MS &̢HZM|pEB]uɄ.X$uudB0EF9;I\ReA zkȍ`!., )(0Ty \ ;,t%q՝'c68>޵k8Xݘk6jzlU]Pkz>~rdd8Pi_xdOJJb+W`2oUfѻgHBС ;X|^zmpkyIq_[ Uyd&\z#Gr%| &<<=!CРAb̊|iժ5SM̙3l޼Qwݻ8̈́ 6|8;vlu6xzz/0x?99lݺ-[6ӪU+xmǏrP3ӧOo1t؉Ær$ޙ>͚5㟿ӧo?ΝMdy qVb&¾=y4 w$ kYdlEF4mϪ;ػ$?7R#">11dL8&x%dˌabGh /f.O鰼. n"Q*U!++_$qJ뽸,Ms$re^zӬi3tD?pNV]U8/iT3i$"""=z+Ws:\tΤIz4]])SDzep%5W77u{͆`0һO&=4(~[>}sA  m;vh4qر ѭ;6n 77޽0idDGoݧ/?` jH*7\U 玢ޣf9wݫY%$j$.ܶ=|!EU`4ԉ311ld\ɫ:oI7qxGz7 %tFv-FKkR!d04i>›ӵw+Y$$[wwNNDž1>kC\^v=w|1yxt\b…*#?scs۷o'$SDFF߅;^i۷ӲevnrJ7 Vfł\~=fI5PWpM`hzwFfLVϩ Lz6~j(Ҥ|Y}QO&Fۍ 5n.xqN@HhZ6fQl#XlTd붸ҁ-BDGd2:o$QEZxyOKP< 79 W IBNFL傫 rM^>< f}#9{$+( Ыw\]]ټi#:\Nhh{\J{LV$.KD#77燧'dee9oPtܹ3kTR+ՕÆ10 $''q%^&''___`4pyz&tQʩ v_G^ͼG5|jZ}dB?峥31|̯ "Υgq[Jx0g4uZ\nٲ=!!ikr=ĩ0sj1Ra"0o]`ČH\k" hĒldp39W2ry xzzҼy s-:^Bz5"z?}$/\`mCلxeWWWE\&Jj*11ђlAӍ:\b,}EOѱ( fj J-(ТQ*($Ьw߱+9rӦڶ\+isvQn/>Lݕ+rr[{(w.}F,!!Qmj3t׉v{"$.ߒ#.XD20 ͥ\gk "^Em9jg|T*tҕM9;#tޓ͚@-x D&s~[;_;BBZjr6 www~mk e)d22Uf8y8c)ꙏ>ƝwcÿҾ}{5n̡۹6?#n'$9_տ` <ޙ;o<8i2}ECrR˖.#xxxIKJLteKٸFOA[9+p&%#N$ -rWz\tMTK+-;o{ǝq+plEsVlF]CiݺC$.WhQqYhi"KbM&$z,dT*k6d0$3t4 rsLłJvܠAC4@Nn6[lb#Gz25OJŞݻ(h4{L&k IPS,!a>c"+[]=:G@NJ%޺AQP&"UV2]͇,e):,!!Qmj77| P,Z͔jqĂU0.e?M7dxQv<~@׺5Occct >X/[:hB!?sh>Ͽ ^^^|lF#WҬYs:vĚ?~ܹ\p3e#Yr9gƒ>܈֬ @b{phR_ /Svv/((S{\z0er[,mwwm݌E B`#Vꋸ7MG% 7Q!`n¡+H-52992)pQ8ߑyWٔJ5቉rz?Πbx4+R굸,EoBd2t^hL5DCfy*_4cld2)0Yoc}3P镀@V@ "]HaMQ  :|:v;"p]ZΨT 8pX,&|رS{\nf3 h;NQبOL4(233T{0 D@ttTYeWwArr2QQW[W7WϾ}{qHw[l? ۆ۹_mZ ^k8C52Q5렓uI\dϯju1J8G0 ]AaXײdd2j=sf!3aiZʃYp:3b2f$F#ǏAH+5&덳[pbB}##E)oe HrR2-zSV瓔]e8飺pXrrm}}p(;@40zVFVW} ,Q|5))\rFиQcGs]///pw.ΤZ_Q|34@sO벸|KU嶭AjuLxp2 LZe~s4q9G9xp? `e4 '=gQ@w7_a)v`тvM(4iY eY[32mWRS:ĦMލÆ3lO}ͧ@_zZǙӨ = ~ewwkC1|sˢ]ǧ!8qwHXSd,V}p0g^%CLfrL&,= aGPbD~ X }3,Ccp<.gn[q;w{;[/\'fE,^0~ʋ˵8A5M z\\jϨzwMKTQddr)b E&%.bcE`ɄWJzrxV}SQI$Ω?ݴѝUw&RG>IKOWm[c4:́C:7ͮmƓ纕e=$c34?;waosy WU #ӧs~4'%"z.-&Ee%mH-@̂ 8pbR  BBR(XY& jxu?FtB…x.\Cw&0"j5 ___v& ]K# $IꊟɄ@Q Ē\q7P\<!7'KU]YDE0N!j=ӋV9eF $3h}GVVGٳZ-˗ߟo'00kعc;}!AAw6qBzI~dddh|2HEcI$q } 4p@]BDgX#+常"+ XK@NNdedthSpnݕ/1qx,y$g4f>5Yu٭ҡE0A -=ؼ#/.֭$.S*갸*$8=룸 `6qwp^YNJN=F(kZ)kfLRIpV\ qcHMMy]xRASXEUi<%q }HMJ] %#X,u׮ؗR恛{틯~GE3z5+W.a0jsu/?Jܹ7t!>!=R,--hґ\#k-cY?rA@JRbڀ0d2!xzYN]ns IDAT=rYJ\ I`?6?֬#.Lmŝa?yGxjat׆1cF[o2pڂ=Q$2o_fo/os9#=MO23^ n/VhiV$&sK2!Zax1[3}kȺufbaU9b}oYb5͛7#( k֬CLx? YbǟUc2Re^Y\)ے\kV\^;7 //:v쁋 ii)$$`Mok4r4*[@VKDd$ C7!Zhe](0 QX\q,qRYDZ, 4]Jtǧa}i@hhHI9ի[νC +luEd݃ɓv.]HLL@Tҭ[w~d2:{T%QfH7nĠ3Z祬_7ʕ zÍB]#Q ju^-f232kcٳ' JN9rd*qYq/DQ\; q2jelujZ~/=Q4 u ڶ C&s|.C =ĆC>q, fDQD. л3D"fu@ kBT2eDm> :p`>[/|C۶xo[2f84 B&p<ZH뼸{0a$zKÆ~r1rRs% Z;<2}E6mݻNs$>}[yF~}I\!uE\.$i7:F0 dd\!# pʍFǧiӁK.r~EUKVUet=EvVWJZCquU1t>]kjM\~As4ObV>G24 ve𠁵_6i׮nn%1,]i٢ :m}լYSt\!ȑ#\TBѭ[͚6ϯ!AAٓ[Aƍm`6mBFkZ&--@ٕyyz崫iBM߄ :w*ucZ|&.Ғwp%Ν;Ohh[)&Jr\߽Vm}MkVm1&׆|cEwV?Ě1^\'hٲMl6st YY7zP$fEWA@Zb!%fv?{Vud-Oٖgl$d !ٲGH?(B e HRv Y$!v-[C{;޶l}^Jgst{<(l!X.kMɧSRRͣ=wq 7P_uߒlj'Ÿ \yi7 Beh(=TUUGƼyǡVGc=ׯ.^#C@L.> 5z>=v/@O_$.K '.aU'QYYBee aat$%6 .C\x.e+ꝷYݲoܰ?w6p5}t@A'J I`/Ï>xoE0911Uoy\x\pyfQQ?Lq9mZ8rv;Q@㉰0SFwAH Sb% />C8:m\'`]wXdgغe'r*_ēNu"_\78BBB(.>M\<9-7u<^/xrt8xWe3PGyg͚y_Nd&N>y o*ٓHKKg477sm+Xzlܸݻ~˯{SSSc{ZAyY6 G ƛX ~ظݻˮ}/wq;Ňkp-ʫaݷ` §DP2Uu(x<jj*jj3O&X7qlZ7-' # @hhl$!>$$$KVV.9% r<sjRVG3 /="a_~|M f[ovDQh2bl:QOORENgʹv/XNy~9nz9l^/>-=zZz>\.s?eoQg"X\{͂ZA X'(gP(`N`5j=O!KxJBUpy06q=EGjfpBDPȘ2:_} 'r*'/YBYY )K gZ>?>&K~Z|-/t)̝7߿*`giFSRț6%s˘1s&/?G#gjÕW^^khPQgyz=7. W^ y5J9m̚=m#dL qFg;׋PI]]5Zm))LOB)4dqy{,p 2D fVq'{O9sW_[L㨫iM}r3wDEEnw1g22r˛ɼyPTC΂ͳۃFE>+֯#rl?O,n0rY /qOOܮ#CΝ{owlIc"D_ñsxx$09Zm>kҒVq$:?< kԇQDy "a*9!rd0䡡]^l^p"U8a8dJM> ۻzr.ogqSTX?}<~KtaA't ϻ%] dEQAoj7,@/^Ʃ̙;z+GQE48 )!/A..'2֫<ۄ롦ZsQ5L:jjk+qTVV餤I!I`㩬 DB|XF.鎝;1{=z]"##1ؿo?',^sO477sߟ?`1u67773`Aew"|(h4(aԓ?""tnvOssubEsQѡ.;vk".ݚ}ꏁ^^`6HIRD"8ddgO%11MAnZ/(1Gn ZD= ;Ӂ |W<A_p1vj=߭߭㢋͜xq/ϻ{8g7__rƙ =#ym۶T*7w?܁SR[[ˤI9(Jnң#_KKK8tO>Ax7-[6sgpm+س{˖e֭5|KΝ}{׿n2aO:O:}[lfg[Wgn^ ˏۺOBbPOBfx;p8:X&Bll*LanW&N]fz ~9]?`ݷ_s>u~ eToUHhh(^|Xݳ{M]NwםYp&ۇ؆b᡿W\UW_j믾ݭѾ r(|+Wfc7o>z'ŇA֬Yͩ;3iRNfL:?O㉿aۻm,\S SR|hK6A..f1֫<r,+[I[[3&S+:hl|TWDf3fېnHBM9Y{҉'at9\suͷou;^PPu7Xzz:ӧO%KhmmVe׎mC*7kqn'=}3g.hlzf#n Ell3Vk˷o|, N8,1arz턇G „oWbcəLQ_N+7Cx2Dq`豮{{ڿKb+~{{{Vt=+_/||]VfcK/5b1sYg=?r4=w.axyKY]?]%G2`` q]xnnńjj5p{9PॶF'$G]ghôXxTO9X9WHs?|a7^"""X,҇"bFFFr ʕh2m|U?*JrMj槟~g.47qc)c2t:nG&ɳkP# B\>ʞ*UQQ1վOxx$ryry =;GXu C/H^Þʝu%!7. Ǎihllnlnj5XL66Z@FF.Zm:^ҟfIX4(AF/}$%n |6 eLsII3qy5}oǬY3uCc6L'$${ }o`XL]\)FObdRR2HIɤ@aZ[}Ev2TjDHM@BC`%qy̐$'kys%|xeÆ*!q$EE{IHH!#c6},{ÀoiZAP/tdqS3[\_ע/4fZJa ?Z}=v<qi7 | #>eJ>ݻX cCEhnn`j$%83bm\NNcΣ"iDGt9th?fq%1h$q9 e`;>/Ob͖>۶mg;AEZZiii7MllS";;b !44h 99Ҳiii@/P9::Ӂ҆] sIx 7rspٽ{ MM:G}B||C~`w#22'}ŵ^}= t\[˽>^_͒%bŭ2|շDDD]-YFy}jfHKԩsXp)z}*UĨG/?juORjj*Hɣ3BBB5pˍAEd2/|Dv;\|$.[%F`;fy nKfnyŀJIJILL%7w:))i %QR__M}}5j.dҲIKvwa4v9zxBv؅ܓqw\5e*}"s@e" C'VI'.I}Cz}5?l̋+WR[;8c]̜5hc2ٽ{WvlXkQk]|4KEyv-÷gS`fr8vm[ًQ5޽ϩy;TED1MLQUĩ Q[4H> A\I1iv[~: X= ]v؄J"$$dvlP\\B~~n̐477 jn=7p-C:H}4`*;L,6I`ar9%v).yA$ƚ\j=g;w-$.{$>ΑY]\瓹5[t0&ˊp: nL6*+KhlHII'>>64gqlZlfVn?<,Aओ˯!bCDAmm>~@z90n1kqM5j6}51.' _+ =b! .k`Cd?. o6}}K!>>FMGkkM5xn:^$q9K"7w hN@KgTEpB_(>ˀ^w_=zEx]) <#pdGY4ãhĠQ"͝Fh Hq8}o^C\zq#9j=E!8s8sHLLo?xQyUosʒѷkcڴd2 y핗(r]9>ؑ1Ƌ7X#2NIWKlljr:ZMdHT((rr2 L w#Je2Yjݎtջ{=2mT!bAAѸ#$.=,1n8du c:%edYѰѿ_ehkkfʔY̞2 YԂ܊:&XM2Mju-ZZjz=e6<^xeT0RSSQ3gb%<<|nfz΂CrMt:zTVVa6[#77Q gΜ?@jЭ{5ؽ{3g@jjEE{x-Z=z}O@FK\\},:M?_x3{|ʩp- dgpWp:Okp-ʫa7`2IX6jr6I\nG%b"s0JUU y%6drd2xX'pJuyƦbE1_yI_<u{w^ni'|6lThCIa7d2V'az mC|n a]_FFѨTi QRRE-崵p1HN"6V+cCSbCl\ q)TrB"00"E0<~2aC aI\^W>qy?WZCJJMd@u?B+6 b;hn͂j H Z!V}cছnV/^}u%^n?,9f^} ֬s_~5;v4tBp=wqWWCRVVstg$? I`0襴 L66D`0TIxTV` ==VGn1tٔT?=oL4R\¡~El /å^_O??" p].;NREB:PILL!55 LF]]5եe,>}~n[lbE\zٕDGpǻqD᪪J*&M˯š466RTT$$$2cZAD\\xKn}rn^gOVíq_\YgL&cϞݼmr˒~ fu\/Hr. 6v!}>}^D pOh̘L`2`ljHMMudfNF':: jkGo%Y 枪Zn=K{HLL$44*ꫯ૯|7t=.W^yZ?O"vlٲŋq {].O>4_ٻw?k~yh4V՟t@U/.̚u%GO/(wkIC'.K#! \Ojj&deM%99}45 ^? ::㉉UBBDFFs|ZZ8th?Vyu5oߏDGǒMttѱ5KB&&&QilrYD_3 3h1؍&-[\8zS<_Ś-_d5.!!JAdjAE"#F㍈(&By!\.X7KbŪd7$.Kn1$$Zm&M!*J\.sw_ZJJ`ۈגC&7w:3ͭP__Ckkcq,q,tLrIKhl^O}} GC -{;Gaa_?<px;>>A~sKx79xd-f⧟v>:[.3ϼХ=Gaם~D,b~)r(*Guu9Ǡ$0oITWWP^^ݿQo5֌ZicBUU)fs[{"1%XpdgFJJ2gq*F'|?8W^yW_}9r*';S)((9r@<"K0{-D`EAYf|Esz!%$,6U\aqxPQ Ձ67mJԗ/ٰ{Y( ,!1FX,&vL|if_r4TFc ?ZNZaڴٴKBD!""3*;k u\sͽg+.wޔ0E\`*n'׋L "\"#qH`%zFf˒p !1|r9'"55 2R/^Hiiz}?%22餤dѱ Kl^OKK㸜z  (ah$%ģ_[,&L6V36Ղf9ϼysHHGNQQ?mٲ_xB^/V7x\{ =ۏ<OppwV}}]Jwn<%gC1D.ɪaE'.^^ L+p -pNۃ&"rnǃ"G$2ł)-D)lĘXKss=:]6ii9dgOE˦:Fc .40uf2IhTlQv22.$.wfSˎbpdaaᄄ(iii[HtMffrCZ#1>*>c٢nȱzS^gg#\C֐?ؤ.fA/KHRRHM$*J 롮NPIC! n$RETT4jpPBCP*CQ(BP(d!( Jll;QEE@h?_w;?ގ+Xt wu/V38K/Q./:jafQ m&;I;\9|?A܈܀|xo{ZGp:IDigɱ 5>%$$z,`$== fMYY}L(TPhd!|욄r9))9^_JFF.II:ga6(/?8l_&S&55:L6FՂD`P"E,r@jM 厍5a< 2|A(%<< AeaLͅY~O|D7FIH9Lm7u0XV*+QVVЭRJjR9&&HSS UchW.J||ju,ᄄ"py7;qjgzz}n</.ۉt&Y IDATq8\6nwǁׅם3#5k䩧lfÏO)Q*[0!^dverZ;m- CBB9r@Tv;xW*Igl3{IЄ bdHH}TUG\Lyy-6 n_!/XVjj%y #/0׺-=Lyp/ Bm ăAٜЫv>4Bѭ]޼2Ke2Zm*N?&˱ۭ?x"** Fc UU%=8/ԛ f|."D7B%$Ft#> \M[[EE{hi'..<Ґdr=55 8QC{F@xx$advAh ŝM;VuN'NلҌhf`[q:ΠxŲ`ebPGbZ~ Y&Je @.Ǒfl6 "2RMfdbbb9s! Jl6RXvf yy30(a~oc$.]\ꄄBBj_)CdG*$$$#"C nD9 ҳ'xʪ1lQL/g?Oq3uEPprqZm^mvԲ.?7цNEn1T*:zxԳNlߵPҲ+#S9!AKrrM* Bw1!>X-Evtb1cdՂi /WniϡVA`˖m9=g/qOg$qyt3r5M< ~@b2p8ZݪgwDf{%C K %$fKff^{48 TV{c(*GDD))rsb1IBsT""vMX/MGGbW(|C47Je( tR^^8MIHK;(ly87XTǁzA ...$>sviL( .UdGjXx!+V?,DRyy~){6[nK./_arʉd2rrǝ|#!1Q*L:Ĕv^z~wKe9t:JF*+חDhHOEI ,,?;rp\RFXXX{`<Llikkm[(%D䒋?.jnÊw{rsy{z_Rh@1`°W_OIlپ};V`:4_c m2:ߟp- I.2$$# 4Lz$Z)VQ]]>쁎jМ3LMMFcKz"1TAn}9m)k4íd0cQ6x#w-:XǞ#/oNx*DLȮ-(RUUFccX7Kb S!**h >1"$$]oZE1>[K\\,<ؾ=|}9w~kkX{yսtWD=Vv.\.'Npذ,l<irK"'+kJ "wԷqDIe#"Z[.RIVV>:""bOH|+O<'FՈ!::XBCUniii¹>VU>1>>Dgt|gX<̙3 .xPvoN˙Y4廹dff"]\d ȐHCC h:RSj3HJJNOug;f*tcəb`1D.by`rbبgL Dio(sDsODa׮pK&Fvd"wxٷڲ" n1-@B 9L/!$BjzSC ؆*ٲ%ۮ|Ws_3<<̱cNa]0O``i镨L&:c&ⲷtwTQԢjhZpr% 2]f[in`il:7QQ9Ĵis wʊ?;;ۣH&LBTṪ?Dq"OBxQ=#6[3uuՔ`67KTT66g3UUmq>CB i#~+b\G`N7#PiEdV8}e;NƌQ[5|G|<qFճ{F:fn7Zbl544HMMEEypsMrF!t)))FF֎ޤ7]y2>N$ڽj5m|QX qYoF9-!2:k;\oh4rZ@BP08__PSB̂ "I'HCp%# P*2^2uWRUg=oxgh$'ر8DEEIz~~HEQ$!aaaQH#>O2 !**cګΓ6d+rp}N\n߭\4gKԲi6nz^}m, r'@EE%'"iӦk^AȈ^N0"00 %>~,47'Jp ^3fA9XrsP^dDQ7n~~TTrjkK΄ S Fv'hnPQQ477!!!DG3~deab*+ˆud_-*.̓U`GfɷSdr{/Q{"CE\}ՕnRn6-o-*<5CoLqq~ȬĂ8OrE|^Ov=o+V^a1S%+ oov1OsMee[KOO@bb cNDSWWݛ= Ȃ 4"yF?Ə`j5ͦN.O'BC#>}>z|rraJUJ]@ X,V;2Emvʽލlfeg³_a|} Nj)*j+7 """hOrQUUFiiE{^e %5u;ǔ22{VHbb2c&ecl>FgҤDGh4bicr+LQ9'`B6uu5TTPQQB}}͐Kܱ>]nzSΥR`n`^;}?DQt q-*_x~>g|ƙg(޽-]p֭矇$IÏ'}۫. ś KkdLZdn 10 -w6 9{׿IsԘP=6Q"2,..`қ;nfHijϾGttqDE!,FMq.L/g|Ko7_s!!̜Y{PZ';n㏝r+ȜNۜNV}ΪUw49N^z "Uqy-Id@k NG@@v^ߩr׻fՐDk{ih.**HYbpqonw ~1_璖M7.#$$ҲNswUTF2,ST4P1(#%5e^߀,Ijl9ʓo/U;شFy8x\uBu"џVeM|{I1Iьױy<: Ou#,حqҹ,$ Å~G,8VN(,;2j ?頴8%%TUUXA+.;أx _6 Rc =nX,d=l'H ("1cE`he 樨("""i:|2_-ټy !!!|@Ess3'yZ^EeqrFj DALNLL-!Vw/oˡW'!U&'_.۝DņynRBp:\͙}ѤgڌD4w-_Ϩs!*07h:zحNJW א;Ru8yxc;<3#I泘LF"")*R,X0F;olr$RvkijjӤ7,G9ToQQ:QVVDEũ' eBH[QDLCC-YY[CRTƌȼyP^^DvN5ir.QQQ9NpQL0)ɱc;!dbҤ cjʲ,pة,Ὕ[jǏ%!a"AAa@k UT% #9n|u[dVb ]-_{H??^^j"#1Z,|[l,)apWͥ^O? sZXߴo{ IHLq`_` V+M t;UZyɓUTNGTq=6Oqy QnVn0bݘF)-Xo,4u,vLA[n(,ڕRkIF഻uZݻu&%:k/}|'Oczc?Ԯ;(O+7 =˖]GDD8$Q^~Qް~gkfCĴLF}N^KU\6C\nOLA;6 EnSW];Λɫ_7}x[fK}]]͚=} SnI^^&;hIII`Oh4'<<Aep:dR^޻ncHI9?$I&?yy1z='O'::Q rKS NIIK:$$1cFAe((8BEE**)wlͥC `̓yш52kג¤ XRΝ;裏n/2D[A?J2mlf,22Yl֯aY3>=/$q-NH'qYEFc21)vCO\Vꏹ{ KgւdWpJZ{?|wQ],dY&6!K۾,tOh%0DmU#F`9ٝObr,cXY&k?4VDAmr?iMNc߾d'<# khCoDfU\ ܚVpF^Ϧ5kDDDPSSC`` 6Lj/TgCYcZOH/_*%4go 9:̧*.wNwI`n cp{)++ccQ"Dee%AAA)߶Wq9y.42aZhDl8pɽLB {>dK\MT5x^@˜1|جʒ_EA***ԴtDQDrrPPE?ѣv F#sG!j4gwXˣE¢ٚeV.Tqyt:J}} '3wdffGz=iisZdl6;,S?~:3ZIOE``XIii!{zL("qqc7. řjh/WVV_&?LnyOoLw? s,)!mH@@?$Q\$w/tΞsSی6t ѣy?qJ8slګN$.dy\rANGii)]vfTqCY\[+/‘JkeoGsYp7@mYG;l+++gʏ Fnn_|˖]ϣDZdS?掣S(.˲(P`X Q 2|AIzJ $ D PY(a6k$ Ay_HYY)CX7y,4,pq:NGY[htTUzbVXKX|GoSO;rom /a41ٳaihaEXOPPTWW^th&ONdnQTmt:w=I.]]&kNg `jV.ر\jkzl?<㎛:u2$/r^44|-Uȗ{Hwztdp <=a۩eNY!2TTTe88p @p@6\s qq=CeU\ԀeYPS/r [U^\8q"+iܲ7ܩx659z4$Ngl;}b?1juTJK*BT ":w8_Rya@bl,qr=an3i8_;U1fxV\ՑʨQ:t::䢢m=h%44Xɥ0OM*9ʩfMpRBBBtTU\\`&@@HEX^a(}m{:IiMlutUVuQQuU\Dˉ3}k]Xcţ";ncԨQxB hj2S^~' ˊpz;vd"`XdE|D+d$>^ɲȲ26قW;C $I|@ Kh#"&5kp8 DQt'1j"ыAhëhڶ9A@ghjj ٳmVhZ&&%s,({ "4 27hhh@$4 ((Wnph:$Ifyvo1}*0@ *.{mkdPQQL|&Ӧ`̓=$ͤIYIro_c,=)S2084?`[Ky9%)i!!L}}-yy9{ӍVd2NQ♾`<illzep;20 jt=]n  /MdJ%>}B -F#On9)zpHuTqtު܆'yr=wjo^d6lȌyij2SZZbOf]{9KQQ1=bc)@v+vy{u ÛɂÁt:q:X,BBBp6HN`0j_c6LƒGD.'E8"--q8OGay̛$QSY\Wd qz7Ov=o+Vިa1S!u ;˞l1}y5ѣST7CRHO^oly-qx.ǎu3+ SN'**Ip\ ]ޟ7""bHN>Ýdcr[*!2,[vHDy -i-FmI\>xL,,. b4Ȕ(# %#(D$At!9] ɈZQ,udϏ#vb$P**ǓscDD/"o6eeeL&WĠMXJE7#z)1*.w޳g/{Tn_ئ{ʿ[ܞ+Vz,3j;1 pUWϑ{WmFq:y-.5V+|1)8A$QD,ӉTcÕ/? 6'EM`>H}YߗթRE ֮c555Yl~\ަz.{;gFD%\]-+|m Holî1zmUqٓ6FҬ/;{'慑FEEI$U Fg +kk IN>Q[X)\ѣ(.>+$'Ahhee>&5puh/[o~s-s&::z\x ᣼46*߯ ϟ(3_^١nf=O? < J fYx~M8I݈FH(=:a#0E!Lg(8z31IĒQTRWDblf FИ(ld E&1WQQ ?CHLL aY9+/ `{$ei&f; K.Q↍=hƍOeUǧ écŊ߱q{N})._u5,>w o۶pSzZʹ[{<"R/Œ:Ҳ!2 3Z\nU`(il$Wz:4u:Ta8Zh4\(6<{;o êٞϺbIs/1%5e^߀,Ijl9ʓo/U;ش&3N[rﵯ`:-kmOIfVkp=ixen}Ke%i8.[ߣsb}3{fK]1:Duf*% TUqMOBpsPg1=ՎDL9Qc ٳW^b̅t@nV"+k;v{ EK9|8kP9:Evs.n =`6e{ccO<uuh4n&׼;̚5ٳgq}aٸ./q=眅444tS8c> qLAoeSgp N rrP 䖂BQ/W [~TqYEex]rز]WWq6xn39"ezNvu_xEDDD;oSXXcǏu+LkqOs8JJ</ĉ),,n&MJ+Nqy)}^t]ŧ ܆o7***7]WzƍS=߰F:ڵkظqwꫯ%KX'Ə@@@,\K%<<:~~a-ƍa-֛\{Rܜ?q:g),>w %%f|̞3cyGyXpKDxuuߏ?k;}???^|_԰/k/3fla+ؿgɒ󉊊f/>g'B\\<_|) Y oə3f0wi`$99Q2rsQW7j쉃G$~?֛E||,>vL:_Baa1&((3?{쯨j /<ߧGU`VQQRX-n4;`Xg=֒; 3˘Nƶm[9KZz:cƌ%>>$%'c6+CѼ#~WZzi2uZsccVY1LfΜń9sL>YL7.XAaawy AX`!QQ菢HQoDrB6 o$?@hhwu+|۶ߍPP(4s@AZ--Y)S8gw ..FF!!!8v,OFa&LVwSUu׶T.[O9IpOo1.\@qq1'O"%%ٳg_{NŻIpBOb.@NGqWUCDYY;HAA:ch~#:IΨs =z0r#Yj;/+޿fc97w!7<*B``f[\kAh5?/O] IDATD}<v{>{%FY)>Vɦ8sWOxM=p:$';Z}^'#c& $'YY;赭pM`w,ۺ*ڧ_\0l졨(o@sd M2~kjNǂgqxA˾+ɉDEErˑex6y7VA;2}멬S;lTSA (A@``_hjjd=* }JKb nV*aY1X5ILW_ 66F >M;Z$#c:gZz=iiazTnS޿#GoI&SYQAuv$=c:gںRaRQq3Hjr:կ$(0AYlܴ_v] VNly_dr %IJm=DwsdA oQp739r  a۱sXGP(gwI5s~k\jck{e=yUM\8 ""ɟV'0r=Ǎ펀 c4PBE`9p ' g Ñe}*o<mpư7`8Nnv"##eL~Ȳā9;/"3ӓw̙gTTywʩ C JJ8Q>2DǐΞ}[1@`` )q{-fillT&0dfѢElڸ7NHhQ޽Z͛9֭[X,=҇}6F#=[n NQQ{PYY)uuup!v;Ǚ0ab1NrGK_,>oQ*.*/OTUUb8 a466svF=+~kwӶ,K U\X _oa.2%y?b2iVL 4^ .tݎeg܌ra\.,h#̚) J_E>+t:$aZ)//c|'XvzAm]l<{\nVWÏ<ʚիyt{0G G*Q\n"#c),<:>V,8VvBssS(gR"#Z*߆+F))ōܽO9 .` W]uO?lw;ߟ~Gm\.so/ 88Dy;k구^$uo;~<{WKNA\>*011,Z'>>*+())aæMn}F P~dnI&Ol뉋%** M AADFFPQQAiivdZOͬp%'&C9rM&̝oNĉկ~Muu5>n:^6Mnph|ч_u}CgkzV~nmKQnX ] Y;n ظaR]<ܡޝ~č:_DQ 1Iڣm_ohGua}hӟ!.NЖ4Kqd\"d `l :@#IԞrgYFg4jj 8N!2 s2uCȲIUu=WDGG sX;}{N'q$$|j **Tq PYYNJ EsIKCH2ge(*:±czeCѐ6Sj !q^ HƎM")iw N#$Kj4JKːۇ" |Ǫ‚~&V})ǎJ>`ܸD,8o\x7},ӑ3gu*ۓcy^>A(.5DEEPPPz2xrͷ+D(Ԛ5Jw|~MvFw/oӅGV1,FOv  oP5 ?y AHS_Z\VdY'Ar}=5\({fGWˀX,XCn٧SW[ˇ,Jjj:3f"~Vޕɼg4[vut:?o#G~ٍ<غe3*v>.]|)QQTWWv|Ȳ|q|CY|.~~~|*>{E߿/E|ùkill?˧2nEd O2*.w/fFVF``PϕU:Ô)Qa@sM\s JI .nt=aGF?yppS$((ơCӌF#r Ky}^sjU`% >y/%rU (,*b ~G+u7 ¨O/jkk|*2ҲRWnfSV0[ٻw/? IIɌN2! eիW#6brsshhbO4\כk4Vk׉ U\\C2TkV?%DўA`Wcu5`* ^9Z+`k7*%fexݻ2YR&O&~`9~,ɏWOuU!!u=Os7qιr//o.CY̭ɱcypyp7`6xbRw;~e_oWIqQ1~~~me/s…k{ p[B΃9qv~ߓz:kݛkRV.޺ G @cc=aah:&h4ؒdEN^*+K{eg̘dƏOq?v:]1z8DQCa׫CZ3HHС*E/{QRRֲN`>Q322=)ٹ_sҥ{l_Ə? h>Z)Cg|-2=@n RUYEdF n<{񯫫cǎءx0k|CȌ2/ƾy.~~~0(ITqsv᥍NYz1uw!o;s\+=Fhh^˭YEY{6ؐ~~4&-ф`0ashnta OŊf 2^d9nC o·{]Zy'q8igdďh4)!1dL?+gMTUUȣ?wQiϴd2=$$@ bPWQׂXWquueu~`GeE, J'j ޓ)|L2$$~Jfg3u|%wtn.SYD`l2233Kߏ$חݻvQTTԩ ܴ.l7ITT4I"zS\hv&hYdqmE>exxFYY/'0z8$ɼWӦ62zt4Jd<0 졠w`Ǝ Ki{@pP&Lϋ/CtE\:^`ᕗ_O/R;Ϛ-7̭ 씫4n]x'/ْYC&?'?b ն/skOf?f $I2/As`26!Q_ߚ,.[U@ ̲zⲽqrrjj*xktR\P vZ'7T&8j(4(0DjE& ZJG ː 3ՔVV,.{xxcSO-+->uSEړ:+&MFg5_q7P(_i¹ `4E ʾ>c'Mk{22*@Q~hpvvk]k$%e7Vwu"*j*!IOgux\\ܩ,'9ygobZ81L$33o2 0|}yW_}ˮ]{lmpΙO F/qYŀˉnח.~{(9sE=>Y((8cRFwː^J%_KxfK  ,i hjLm}Y\niS+f 暚-˭hK\r`2/u流sO*. WZb ūG]_c9T4O H6̿Ņ$D]T uuu;wwK~ zMsٜ&.2$HرSqEs玖d#׮YWgI{fe F;edHRC fxy HHQQ![+ʙĜ0,!IPRr|}JMNN&G&5yhsь9BIqqI4ޫmܸ7Y%| M:`p0w,.E,SL.#44@sxmJ]eV&5նƪ{_r{żysy̘u>55=hN 556Ԩsd"Almz!Cqwwo54k~U?lK玻橧a=l$$$ .+:JM1oޕ{())ϗvO;ֶyӟ\t%l}=&iˍ FjZ0 F ֩òq 'CYYGbȐl\YYNRND d=>}vu:"#P)6՗([ 6dq/ScR[S;?ȅ?n&.W:yt]u=Ͽ`#?n}mu:/jb||Q*TVVkq! *++pqv$(.FF%yyo;vl  G!/4J2;%.ʬP4-B%aE/G\ESS*U? ww/>r{[\+?\9om[[HTUUkRk,>~^׭m;K<,nۮ];;RKFC h_2d@uDPq22`~FS*c|ӹ5;*'1U'møqQ*Hh )iUU88h7$''X=),!!#5*RY=d ed"Vӟyv=#.gB2 w,+^TV/_ƊR__ǨQaqԩS|rV|slٶ֗i'jz#q[UWWuf͜a׀#G ,, '?ATBCBHO?ƑG:4(UJɵРxyg aĉq#E3Yl}#EE=<;̙32$`H<gg| U=KsbM|h|Yw$@vXJ[fUqBAee&:,.w .mM_tݶk4DFNٕ|](7F;y S&MkGXزyS+%mi,mͿ_y >X>EEⲝAB@4X`tQEd A@Ycǒ?mU]RI\y89(JV1|?= FK^)Id2Zնh'%e?gPfpa [bԜn]Oѯ'smQ\\z+Df3gL'dV~,u!o />OU?v\Flʵ󯶛˷|9󯹆k UUƛows-pх *wCܳd9FT*ydF_?.`6=?Ykq[KkB}Ob`򜛺Fq9t^1MV lUn{x%%W X@gɒ4-֭?lh: DttqGnx\giO\;}y}rY`dYFfhLGR#IPWWGb˵#F (hxj,2, !""HMM$+c Fxx*3gNs^ւȜŞ@#,U<1.nr阘hzѣGa\>wEEE<K%&kmVCi$00>INN!|h|9?ƿr˂yYv-A'0M̛;_+nV^ HMMcZ|<߯19rM^ԩ,JK©¶b**eq+tJet]WjyyIt<`eQ~}yGZ :^Ou:WQ8y26JNq `4P5iʞ'88 A08u#\]=BaA 즢¼HFGhh )) mƁq&3{͵ 30gyZ[A|>7F`vuu".[__L\LVVv3'eeeo݋;Q| ITTv_@A,.݅WWJK ^hOdqe+a @Ijޝ~ήDG-;@NN[nV}Y\npppdd I0/sRIttZ a4ٿz}q J%QQ4:AFQKJMdd$1q55UV/8j5%%g8xp]2|$Mιw;ன۪ XsSl79ǟZ=%|. L!s.Ĥfevꩡ*ːmѣr?ztq̖Q5&^20e>Y Jڮ 6}/u  ^DDLD$I"??t\ ɰa1-%*HJ̝V#:z.瓒aJB1L&uB^*)dq&7쪸,]̭!E\>v,l\v)7p=v]8SX7YvionV?w<<yӧ#"ߟHII >V,m?K8JFԦsMT IDATG::ddd:R$DWyFEyERRvQ]jR֙i*$Id2r^ʊ!2r*j'qAbΕx],k]vUk|joof{;h,5]^LLL~߭XB!-Ι3v';;Ç]`>|vm@6[TVVËxEOyye.B9}:jzx='.LFtƠvhRILy:Օ$%Q2$'9vPrCgh@}L6'001cbP(de'--Q|nKdGBz]ڙ;V_9̲ܧwyMD.Zt}NfΜ-[3غm;s q4K;t0/E//Ezjjw}O`ƍٳ)++5k6fkIg[`F&y$2UY\nA-1D""ps$55S7*1H4wl(f[pqqA={YY9-VVkprrFPM``(h U*h2Z<".suܔWW7.|>*=c P^^ΪV9!8y1z`fl1.M&@]dt^I\b@NqN:a=֙w<z}oC7+'aaB#9yUJc0dHFΜxdz{U@%eqd֭st:[Fz̌cJ1ulYפ]%: nny鋏O>>Au̧|D~~} /oon]p#UUL?o?>\ʥa޼+󣤸׭a:l8[fΚMZQo+O?"Ɠuw~ӝ|B0 Lhi@ Ç(`fxn\b1ԩVEiBBUU9ۭlvӹPQQFrNjk{Xfa_SE]0+gEfY\+eln~`6olF~~]N~m=!3@.qy . *s)5'cD3t&OZ3dHCPUUG;rؓ1cQ8pKxyy=["TTT/TWMTVQYYfy]]= /Q2'qDcj BITTZ'22Rxr$W77𤲲,*=AA|jYpm<޻^e>eԨ0.\]]y-mϘ95kVsu宻!+?n^x͛75͚nRӓ&pyV*<||}LF]"{6[ocXۯ:6ƌss;-玻-[6Y<5?@YY؉KJ9,z Vܞ$ɼE'#5$$.nZ%kiZ[ :j@%%$''X/(hQ(JNJ'=CƮ4^',yOOOqºu{id} ȼnⲬ;ۏ~%0_wYG|͗f1vr\;NF]򺄠,tgDkQ9|x?uu5ɓ/h۷%""IIII貸|nBLcƄ8p?D[ /`MIw9RJzABB:t$aa С} IbFDE~~6Gleg௫_/aq|QQDE0*,P4 _ ߘ9|&NjhU?z*믾bǎ:6SZZ| _~@nNoCehp0$P(p珍̚};w &&c)LoocD`^5#ۻ= 0u4FnF % 222]I '7'aK#Z\TIĩSڬDltt:yy>C%F@@Fudd:D_|?dfm% i٬qOfY\m~ yŗxWu᝜9sS믲ŗ(, ^O\ S`nĉCHHxx&O͎ӗCvSUD[a&=nBAee%})Oq7S\\ºup1Do_B$,l$ \ V??_֮]vW "b,^{5K[oCyg/`ҏgo68qEϤI3IO?dj? 3/.//}62oNxX.|= gyXl^{eKEA().Ơ׳o&M5^RboK59`' ϜʯⲀ4Нt/Z3F İa#fZi($ Zwj Ntt|;t?}V#:z:ήTTs 2}$5u9~5yDf{JgWsoe6|٧<6[2 7^/dm4J,.M^u]ĉx˯ޱIS22Dppaa=,_BB=:APp.vw;l-+=rrr=|-z:l:Y^^^>+V|7|>~,\x+>BcEFws^1b,aaYY<'Q"!))s ?$88q; ֮lFM7J}}#'PTTDt߮ /"??#Fhؕ6muuܹ-K/c_ ;;Lc %>~?jvYaoL2Zm݂ܱ)SK)..ёI&s@22n$>vze0 Qq hNTWWP섒)8::#55UV1"!Ca>)ھWc„(JҒr+˄ SQdg'55hppD&+V g 3`Mbf鲸{ |JNǟְlt~-\+y_/yLEs^)&xaDQ^SLHHǎhZ)xyb2III //Y\jԨQ:u\6mw/YgcKf5,ŔQ{NWϡccqtb2pvvújL&0: M/7zk+wsP(HIIf٧PW[\_,rݶZ6lXeԷ5);nnY^X,~sCDIq1{vﲴEExy{uLmݲ V˜yW@__O N< ~؈q=;oi)cl+%Щ뉌VTWWPVLT ֺhDGǣV;z}-IIm[-$$'0ñbԨHOnn-&#e{C P\sU<=<{{X-F" 6u6q{7kWm;زu+Ø9c3ΛƖMXZ? sSz *̻}]\yA X*=X:Ye0d1hNHȑ j^&^RorB$$6;6U*&S@3*I0L[4k VjkIII`I88h6,xQppp$55kL\+姧q,)U<^$裭>\_>\_K%Km}yL2oΥ~a%?R W_yْn[(5~a_Zno-ݻje}@\S قYF899PSӻ.ź_Çns%F`0 oԱ2]o1@RN۷U(DD^_gU{^Ь+&~e_~1 Gg)._uNߏ3fp_"((_iBrrrپc'~16Ąh;. 99}JԑM:#.wp )iF^߶7AA:ާodq!(5/AAAdgpʦF$ "ٳg555h gժ#,,K?Au$0p I1t5899Yuؗ7@FF*1""ҷ˗!CB)--&+DuA"/mo,mm-M-˵ Δ{qp"CL222m+GO̬דXDGOCsD II۵Z OpR۩ilAyy1 ٴm22]Q`vppřbA`de4+cm[ {}q_" ] ?_w߯k(kRɽ=;b ZvhxxVZ$$ <=,##(99}Jk Y\nV3**yyPTW$nĉ<̓TUUst^C{{ g曯mV^"|'RV y%SRhM$KNN.:9;moI**JQ0t.5cǎJ%MBEcoVqfdq~:L˴ Y`ele:Ogg[N\y $KJTV}-G l$%%!_~:',-HHQQC9y8: #G"sP0Z'8:BU\>Ko˽e9^#BE1βVu&2rJ@&qdz7F `^,.7OF&//ێ .\]=(++X$8]~~A1A$8y2ܓT*%%8n?J'@ee9II۩kߍLwcOܦ,` R^^nI346,GS-+&?j֬1 ^\rɅ[\p5jYYtA1c¹8r$//<<_&3 \{լZSAR]Z??tXW$NJxF݇Ct8>,.H<1L>(z?6bccHv Gxx$("IJ.07ݻ.WNl-tCG" 22wwO~b$&f %%ŤoyI`49p`e=T*5QQyRT{8= WWϐbɿLo]APoɓx%{'2֛quu4Ua/0Z>t.ٟ=HHK;Svg]ڲWNi)2wQ\kh s;wGG-ATRRrz`2TUz]hΌ (E39mtDFNAHsuFٕldNBLtfrhRs&3p2jo+">j{/+Wo~xz:̸q\rEde吖K6cccXVΡ.6r! 222}[tdk?ٳHNN-Knm6j57tQQfӧx㍷<9={5[sd3Z??6]bV+˝wއhD "|W\1%JMW$qn$I"00ٳOё-m&nҬf"@1٬K"5s]]Ǜӧu{0uL'1q;It4eߛ= \9=E΋{+ܠax{LY{V؃^rTTEza{rvq;n!CB3&0Ozd"vՔ$2j53gGf?>ׇ_ IZtuu>{ફg>KM_[KkobqYVdYFF.q@%v1}z<ӦM駟kS`Ͼ̬6μh8sƶ彉fs$yyDGGY\vX[/?ӧx䑿I懯'^I{h42|x8'N~52Ldrc̛Efk\~շu̝{)>Rw F\ &MMfQN0n'Z 4$slM]wL7/:#@纄\y^6ᓙ-.Vݹ1^ýWFf$]qt.HDee)GoYu&2r%X~~6Ve<|h4Я$ .;9ܼoiӦƓO>h;Ǜ^V$>|O>Y-zq\]]0k:Zj:iR[_[Kk9 p,n.NfxyB;y EȖE#?k?Ey_dddzͼ 9r֗ĉqV;KDQBTfw7iS=Ix%Ƹqcykor SK$IС̚df#)_r#"se 0q1m Z𗔔ownW)--d۶_ưaTVa0ppР?TTn&gSM<È,.a(W!2tq} $d4E{n@]222m TUuΠT*0a *ӧi{* 0@@%Ғl|jdghW\1cb2$jvPSSeu_22=MaR_Ô)EA]鶗/˿h~!|VL&~ۮꫯ VK~~%YwM駟efǟi[Z> _ѣp?qCD Q2L$ "" J"HRë(POD@$}C[$!3:},01".rcŊIKKo4%;%2w大`0Jyy&77isZy QFK[mzt:IȑTBBBرGlO.!''0tTUUX]cq1GLlSyˍ kw4/tr{RWWCBF"1b @ō"\\ܙ8q&EE?~j'͚ӏ5K׿Οw5oX[vu8wƎˏ*uj : V Zgƍ3Ip!JJ_ Fm >59\ĉԟY\NBNNmjisL.C;@Fi<1L>(z?<~,.=*0E_p['_J@Dɼꬵ߯捘Kh>'L&\CPl.#Ӈ)q^$$"!a3NYZ%IK?d2qr7;mVn 4ʗ$_$eԋRC9IBLh~/?s E{Q4a21}mύs}+;,ϭnJZV0 [ћ)S5=# z?h6l48;emN+~~dv'D|Gek̹!dq!b>%%g˦ Go*#cg nn5p;6 Jn{vĈD# 4Z.ve-=Ijjl)/Q89i㩧0lX(O=(O>,ttF\OvGfF lq{DhL grLry ;݅WxY,edd 6>7omǚשׁ={Y>:tGkeQ2 .8;_hP;%꒳is:BE43 hl40 L&9`c2 &#$b40LFs}YT\9c r_@#--4 Rw^^~xCҢT*P(U\m ,J+A_mtf*+1 hmm5eTVQUU!F\]=EP*? ̯ cmF$ TUsV˶J&:z:+mLtt:mOFi!I;wBNu1D+FzVe̘ "iBs%""rsܓ6T*+'IKk[\vqq'*jcns22}㦮DGO`myVO ;Seq/sMs0Ijs/~m2zp[ ⦌̠C<7WL&k^׬ *ɟgZj~84ihyJeYkEQhԣס멯j\Kmm @W.f,[1/2';F{\{լZS5u:V>}5\;vvXw̘pj5\ƍvX}qwd2QY;~ݽ1b,dȑDjk[-LpHDQȑTW^= Oœv-=<0a ԤN22}_}-wu;s^`Ͼ 䁎,.]zhQ,>"4i W76*{L;}ϻmH[Mt;KŁ(UE.;|x6'#ӗh:[RRƫf`F6=", 4/=z> /<7q啗QVfaj.Z-~F~yTjʦM[8z\~EūA^^'Od޼<5 /<x+Y>Yg =X u{%(PWWKf涀Ӧ5Y.,$@gsI Z"siPXX78N6[5-aaD4:uu5s%V}YsogVhΝ0thZ8mv*+8xiiٵi?A k<ط/ 1ߕ@ >z}!!a1S CL)z-+LffF[Ð!$'ݛ=z vmr] Lf l>sOk t,ǚXQ1`&H*C6zZ3 jEQjW`VcEQQz' Q(.b4b1b899\.nՆFv4YF%Q{AW '`6uI{WP=_)--wذQDGQp8\dfn>`P FMM%vm J%>>1c(2vmm 'EغQf5O%fHMs0p)^3-_#. QctfEFV$$mAZdE72pc [Op!ἱbe*jğ^/fA-7vIddq޼/HLL`,_0˘4iO;5~*ZMNIii?37t<7_ʕ(PTT̰aCQP3nXn@Qs^>|8SgRXX^Eaa1IxV)L4{ުz#A&&Ƅj|U -m\}a`zfܸ)`Vpʐ!iUkצ&0LI5Yvk&VKNjζ|岠t Y@;eǴ5kmu< M'0/\p. &Sf/9n{n2%ABX dMeJ1Gb0=DÐL$: mx>I QɎ˲c-#""W^yr^}w7 8vO;Weٲp:,]z?55mxpBҰ9y7ҋy"IUUU滬_~)S&q=wRYYEAAn۶3ΘSO=?o`yy<S6_!0 =HBBBXJC,4(>޽;q8:ѣ*@!/9j;>Ætk&jk9rnݻ,$jVq)݋7mbn3{,Z-6ndq91DDM;|.`QqaMK[Qe;?UipokhMrgЊvۭgW|!22hbb<.7<;sUU%v#.lks{[}~O?O?ܯLki†U8NV|+xGy<౲2~in/%`w}?`(naq'"7\_BT٩'6ք(V3`CQ\.[:t0<رӐ$_~6xqy t$7zE\)3-. 9ht,y-9PI*_0SQ{;~L< I z;^ZBQhKx~lL bϞ_3yg圳ϢGZFDx8\{=.喛okȑb%,sһIH0qÍ7};>>(7p=k<2fϞ9_*K;%%%,ZXֿy1_$I7WV̂.;vg(mOV#q\TT11!""8⑤Bgmmv VdAhTVVuk7=33EFirމ\rNCjweq]vjNApBRVVi#FE7 VÇ5jaaLM}vw0ƎZ!;{qq 5 [Ⲡܿ^0k6g܀"O 3ˊ"5JBBq9Jm/'~?ys-# ߯QFw>v<fK/⽁L8̽{ٖ=zS?%XV| gJll,{~{vA 0k,MޗYjΣ{޸,,ԥWAKTQSSEII7MVUoqa2d(+8QYiWt%I3m^~J[Ǿs '7Fc"PVV)=6111FF,+޽Q˂>C{p==t7]ѠӅqMQW8f_"QqY|G`= ,J {eEkg<Ĥq_ժy*qldYsomJbժcWzUW-#*(,GEFTUUCʤʪz6l7PvHCRo\7!QtfSJ\ p nn7V~ozXXbb≊%22$ @$n6[VR**,յ!țI.bnիt"e7FRO]#袪Z˜1$5pدX,:]#G$EڊJb̘)!'`|QQ; Pسg'S4۫_ϛ`Y 4ڦ9B\>r"s_RQ- |~oS:p唕.m,;֬Y_Drrl߱BJBeRRQͶu,'Æhp\z J%;{? 6̛q̼|Eu2xP뿴@Ѕtܿ=YpR[[CmmY$"""'::bb∎#5Lj-܌ZVaߐ_._zE$&xȲƗ'鹬pDqyF# fvszvw5 Ett<**tp.e3鋍52h嬬tE$IO ** hƎ\^npAOyڬYik7dq㞬t}?I"9)ZEެRI$zd #%'m)]nJ+?K.# ʫ?/V斛oLN3ź}228eLz=o.eee~=gyUXVp"oY̺ur99|0 6KwW-q71pNYwGQ (ޥȘz9X$L$oJVr3f+kX<ҋHH0s/v,,h^\n#2gHkˎ^ x'U`%5u8Dnwp8 !!"v;ChGE}v#?~j}]dz6FFH={2h(7k79،O&qsr`:('އ-FfEV+Ր5l\>ngLrrrػwiY{|9;Gxx8 =c TXGmϿ@pe^±~R~^x1o.n[7o.r},{R7v)!. /z}fJYNks]PJ \\.'K K7M[/8c0DIrr*G-奘͞r55UM7PEQ+(?T*板6F`„h4ZvRRRΜ9O*6vq9p qN`V`$.7[iw˟\~ş|2d0[mx^fK/go0?ᣏ? xtr=ǣs̛7R?:}y}y׬e>iw?'"A2`Iie6E l'%55TST$0#&DLL< IHuu5X,fʊ)//;H'Draa1L[zܚ߱7_AO#>>EQf;p0EjGV3rdZ-`6kP31xH:ٌ\>,L3jCؿO˜2ewXa:*.)or rܼRܲ̈IT8q>NBlLNYY%q5wuu>j;uu҆'3y 'ЂFfڤ %n7&c40E+eĈ̜1ٳfʕouΖx쑇QkAEw-6;vvzAGП]haȲO<+fA@QdlrlroHbcMz$&U7Υ|3%.7v3rY)%ў =dY J@ǠGEcNGZDуX,E~Kx(_~J]pPƏIHH(fRPp4h =3fLС#em~q@,kfIZ.[+*q9$%bX+ARH4E}9/rƬ1Urp!N ѩ:VBEE%nEaTU jrK%*Fk&jV+ 2oZMaF]p>Ǝvs_yTT7@pR!ngא$O%G}$J6rr"Iř-o#8Wcz@L0'';3;&.#yҿd{W'AO$<<0**̸ݮ5rDZ{2 nTQZmcLAVJwqfƑ#=ʉf>uk+OEuk֨p9ܠRKhj܀$+jQ#rE"$DZBFChZ $p)2KAe)^z>|q)t+-˂׳xeDGGcm@p hʱc"I9&Hp(x,b,K|{3™yA+C\nMƓ`sK@QlnZBZxj+|1R$k`ѣ_)))ˣR3f*r؁/dNtQCOLo_~)3gN'!ҥ @ll,KITT$䥗^npE8ԙT*˯rcʔIE>_ ;v$&& cOt{4Ee!5w&]"AdN6EeС(ׅ…3PP@tlՄh$c#Y95 3 "a(ؑPАdsQ@f 6ӚsӅGnn>y{nٱ z`[ QIJJEQV fs!fs~(rGM/]LMm4%7%).7&>EizyKj\}'N @ $IELˁ޾:]8CހC!2Ҁ$y23_Ç`0p,I#GN"** zJpYum۶^ɲeRQaEVsW?W_}iӦ0}4c)uuup5{|osf)IcǎaŊ3gV>u:B\\`X0( .YVSdi8_|\/D!&J}< =0sҭA\, aɒ+Cey$! z?G=M\\" DEb)l.b)nC@ |bPԔ+ET 2YYp~FVZo)]BnDRRa2PYic >D**de=FsubU7|\.'V՛RPA۹sϪU9>>'f޼}6l998utI4OۗM\\ 111,_ yyA@eq+ ]*#zA\Q|eYR/*7ˊ,{l$.{,}ePĈY &7x_ n9|,XpK[Us=`o|cRWLL O>\G$U'z'v `sH۶O?e߾ JJPU$% di̚u'C#ۭG@ eSHMqrO\ 1vtPtkdt:23!n7RSׯ?V~eg/i<5Rxᅧy7HJCG;ֳAV3s Fc}_%n:Vx }ܴiSض-#`{IIXj5O< _EosEJZ0Y)":R\\VaW\V]ZFȬr+ekEV[uW~U@nqu+*7;=>CӰ%#c;ᆬ8232z(?)R\0+'+DvÂܹᇟ:tp\;L&#w\.)S&/mFsϽ$I3SXXN#!đ#GTApQXxcH(us\\B}@ÆNII>%%TWWviGºdI,oO ƚP(//mU~ZMz$4"Q\CQ4<\Ϙ2=}":cRRR':: Ȳݻ7w V'LMUP<11:***j̞}G,a2)..d2hY-z9oV|뮻n![fxho/|RZlOK ' 6mSgr)3'Nʕo{߬6y"$$۱3W|(,,b„^m)Qk@P2**8xp/:GLL`РTWWRZZHII_Fa0(B\nOԋ f+k'z-OE/_zxZϋĦŰal. ؎^SP_~FU"ҷŋSfŝwކohkQ{x7e]wAdg"##uԩy{ ߎ"h@ ZP\n~d߾}큗4ǔ)r' Vo:Jw/*uu5%?(L$bc 8R[[Kii%%2{yH|(+.C-?O2O #:t$( 졦חZBz8juqBfsa`y!)9SAY rBSzF{e{6< yA'.pAN'QQX6N{ǧ}S 6[CodrR\GqqjX&Sqq&RR2ÁlZ-AEןǯݶ|.?j.3(6,Df!.P>DŽ@ЩHDLL.ټ /!ABQ\dfG2xpZ eZx󦍁bByߚ@ml`u3RNؙ4uF;j$IkqmvjCwbZ_qIȸ ϥћDbB"O`玞g)I8z5aۅw%.k_0O?/G/ѯ_"){ŋxS/8a۳?zH|,ק@pRv)--JEL^lN )i II\bJJ(`䍟]mk+_{("5.!.OB  hj-fsQ$$x,:^G~$P7ەSeA@BCCQ**\VO'B` >g6N=dxJK$ IDAT|Ï>KZ!"׊EE OK xlgƖʫBBBHJdB: OII 87 G\nK\0{~q7͘1_rٱcw{'%l q?* /j gu&_{A@ Geʊ)++F$DRHHHrbP\Gy> `g EeV<5;7/L&K_!h~_um糕Xazn'χu{ߠѪYU(׭de39}x\N7pu+/zk䔇v4YSJ%`B\.".΄$Ayy1ITT 55dg8pq8deuN0ܮB\1(+|uաӅS/"!0 _NǟGsJf <ٳgqUKmW0y_Ό-5fgK/Md$)܀Zd2pXN}kytjӦlڴ9hy'tr"|%%cܸ1(m++:()/7#Iјјɔɔ堤\lY7`~KN|B$|p#W|M䧯OO2{vo96Do^C֮<@R{xÛLV<5,9ENKN㏧>&4L-7i]-+X#9J V_Y~]@Eh4 jkk'=}"aa:@b)ر~yYIiZ8zsB\Nԅ( ŵB\n*\^|231b0nzjjj{=!.wB`n#g.Ͽ`./ONn.9O+.w^-˹*2 \PXIDx8UU6%a2cHNkϙZbx㍷o@QqnBQV V3&!!IIIJ@MM5%% 5?z~lX9\N7g 饟 a̔A*.yR{m?JxD(!u.򏘹Ky?[\ܺgfko!.uψZYqA&&Xo\wLV3fT*iB\^x˸[nU*y'HLL? -2y- HJKJP]K뭗*5qqB`}r1 .,8]_X`PɂVV{1П8# eTV()ɧ$Χ~V(8VƝW2 8\l!jP$IkWuWvǷeFi8ve>~ IJ[aЈD.v_W[Z/ qٷk`M'vz6;vppYgQZ/ ]All<5cԨɦ'Oxx8Æ79|8 aL4%r:{#66'eAϧA`./gT9Fj@"""())i0m[0#r8_][sfseq咫";{?W.7xbaSdnb';_ך@ﻴn-VÀ7n ˖=rf@m(RRZ&..DG2hP\fJU?/ޕCҀ8 N?]9|vnw8.x꿨$c\v\|E߀8+kZ+>*bQn !"JG֎d8ʠ<"o>`'>e\8V.eaM^\=z4}~-~:$c \_EFF2t=T5H(LvNҕ>/4P=.}#.CⲠPh*떠Re__IUU7O_G'/B`n&{ōC~KJJwؗ}Rd$KzCp!|ZXhܙ9ܿ+h[ﴴL<Ds;yJ vSRR@IIZm&S&S2QQ1DE2t W\aVòbgs՝V9zG.v Ѡc_Qw|5w-5E$lU <ֵ8NEBPåo'"5`n9brˀWdhd\{:o6//3n,)t~ee0`(fϞ-~n\BLL}2r:Q\k"=&&Y˨HUf5IRylΖ-ۛ<ޗ qY!0O>+;{?~7\w Xpz9,\Yʬ9S]ݳ7߭o" 粹Lb"CT"eU.7 TyTz?|q"MyU7Y˭ 2ʕ+ꫯ?~X*A$#j- %e IՒ?-m| jq㦡ׇ(%%N\Ġ(bP#;(.'*-CCՒ=IcOW˞C agǟ7i3cK'LVUUO?o`YA 7t^c|^n z1 H3zdBCBii991b\}?8r$S/tV3?i CÑ]N N!:f#eAd-gj% gg 8|gAǟ~EM`6L|޻ހ+Vɢ .H'z>W^qg1Ih\{dfesq\h4Kpp_or>ys-7ŪAwk $w%PPPxεZ9 .W]m"sJ{..&mDQj41(nuBbdWms՝TqٟqT S`ۖM%ȲO?w_V jXjkk1b,jgs| $Eaޝ8]z/44qm.Q E "VV1X$m8[[ۇ#yһr7)eEز9Jj.OE-_+ɋ[>z>Brrra׮ݤ[oϿ`\r\qe|xgXz5);͙gvY\_;,ӕxdg甙3G3q>ǎ`)+'.>Nx|.˰Wڅ|9XyDHs/0`@tw(ʫ <{y k>:~3>lXO:+/SO#22\y-6mo)! ~UUU<ӌ;믽?"2mYysYh5bp&O7߬w= 6`Gqq1|o_qӍ7p݁`絛#[\ngcjhmmUy둚i1`w8eR$dmv+չqAt(P5jĢAoe˖COsmuw!C Gf:- g5l Aߢ `%zkV$IēBTTNJDp[AϦxGy#<]pF^$)T/[}t9Q֑#XJz}Cv Y)vS¯>Шo2 D-8u('Dft iBrGSU$h4cbᬛF:l3Oog^{x1ey7lXYg_o;hږ-/I+{7nPRFمKP蠥@[V -Z(+$K8lي-a"=_[>zs {n9|TUe6ɓ2‹xdff~}MxHHppuWaZijjg_Q׳lt:ǎ :! E2"`ç[r?be`BH֮Y3=.ٳf捻n#apy˶q9-(B{e\Cj1F4'Fbb TVP#{nG+I&.Δ)YQS1Rv֬DDDi8xphu lPeSL $YgPڌEeTًq|#IfT虅l|x ?/YҥHOK豣̘1׮~{dff3wm۾dѢŁcǎ` .N^^.'O`^P8Yu֕W~[㏷z 7gѢ,Zt x<^r82M ..0O?>O>.qf|L>F|^/CѼ>TMũtji耹UIng: @֍_eUUyyl|*pVy)}n{kpU4o"\cb<9h_l{61r1Z[ݻ_o5a8ĐYˣNg__Ï>Cjk̙\p޹\C;A?D<:OͽM\\\`-ᇟ cATU """IHHfK$55,j( B> yC$A̙ v`ʌIrh42}4 rr_KI z>pY0Z*Nσ救dOFiȚF1*iZGc虂pkhhhV[Q뉋8%DFZhiiaٲl\$9ou?da,e _w?<;Վ~ǽOu t&yU_yq 7 g--MPTt -bcmp[(Uڣp"!eW`2$( O=5k!&^}zI6m>fc46Zc̜ޱiZTFdjw ^ׇ*HJ$+4 M!G25O2R!3"\NvRېݻ]wݎСf͚ 0#T IDATӧ[?#))^?d9cxl0RNNC ޞ6!B`jZ+(Bee %DEEFliMb<hwU>s6o7ॗ^ '3ًyy.@kCUUx۷^jd㨯x:6/T16:=j|4{ܔ{+ea‘ph6MO:"p"iD#tLB\HL:B`uuuDc4e^Gll uuH;fJNd, xoSV^?? ^w>^p| C ѫk -\@^^:u}!;ɌݞLBB $$POEE(! 5k=|\q"d$))t 4Me6ّ$] |&/ht5HLIxnG3kI1cBL X=z-45pEه*i[^i:R%3*`ABb&z?=eۇo\8鴇čN Yv+SRRJ}}:-lx=l׿w 'ZzM*WrJ+ed$Ijw]֫~_˿ʕIHpp=C{h+Gj xzJt:gGoaOXd^7e=Ʋp~ۇ.<0AEE%﯇]UUٳkWHXXXqm3JDU \RR:Ӑ$ UUٷ﫠zˠg%Lငd2QS3٫%22|rs@ fX^Сݸ(#. ʀĦ9X >3V28|8'0lϞl.B6o6[N;Tp80]yܹw{ CUUyGXl1_3hω}ֽ nsW^y5ҥ_^^_ A8yJJ(/?͖DBB2 %rSQQ%4 08s/iw>Sn^MzkK򩧮~8kLf̘K/yI~{1 455t=Nj4x(.Oȡ#fAF0\޻wןb'[2eR^t8vȲtEvɒO{IxGÏ)/ <<P PYYBUU)11mucn' LxSHNB[Td gz@ƱvE2ZxE9UU8zt`XX8ӧCU5>lF/D0fem 9KOMiZ@bbnF#֭a _MFG iFs7p;owzo:\Ô A۶mgꕬZe),_\Ymdj@޽;gM+XpAd@њz%04M,(S9L˨@QaZ`Mf(v{2';ǎ[nljTo@*I:MN'7Ok`Ncƌg>rڋm]uYjuȲ5܈n&<<MS9x0?YaÝXQȲ?;tb.vkEcA#.O_s!\fɒܹ{uZۨ7T=Ja47;ÑB|LӨ4p'tAh/^Ayy9ALv qqxٻw;^7h8jkpa6(jk˩)Z7yl"""*RG"\04%\Ȓ%mg,rrt3eBqV)aA& E;iBttq4SYYBccx_ hDDXhmma/\#&&"Is˻Zinvu G`dڴhѣQn!+k:,ݯ͜j8{<1lDB:=z,hyPXXDq??_=5py4y(_ʊF+ ]w>^x x)lŊ]%wAgw <pW;Bԫz."/_jm6 #_j"#8)XqdfNP]]FmmeP #dX?:AEE1yy̜NRR:oA7;QTT aXޛ)Sfc0(* >}>'/oD~.,ez lt\i+#Bv"\]'El c݁"Q:,ЍT*۶mg۶!kiS_|. gn>Ja4591q8Abb:55Ԕ^PSFҦ fp:;Ba^ς0H8v8놧}HLL#&&bee ,Bee Q#~n|,eA^"\}'E|^R*qV|*GK eq;p ӹ{im}ANvO+yb%`%c'`%XGuu--=Xpj,H{AL~ !IPROaanONg};އH22 >;HTZZ8~Ȁ١EB֯ÿwVBI~yۺ:Νxnۨfsb -\Qsy#|8-d&0>͑Q>,!2W`Ѣx>oz(0rdYrbcq8R#::e6*QXN'%mAl3hh޽innW:%n1t:SAt鳱Δ)PUG:U{x)**G@ECC#<3XQ\rE̙3YVhmm>b/g[???=̒$ݻ+r`]ׇ֯X4f 8'1 Ug@C1qo)BLpN9e%F Mpٳ'$FJ$234??e>Vtt$X!kHcAӧav]^ؿ,xҥ|o7[ow{ ~7K/=?$%%yܹ{Яc,\YaN˂$_{ ^{ngg';{w"\ll@LGF3Ped+:l:#EqFG`"X3p}?d.f62WfMv>.'|Fbbv~/0uOHH_e)B'SȘ?1(*ʡ(z.\,{عKep74GndfҤJn11$'񴒟xH91Lִ33Ь헗Wyqرc`^˜9@P,e9O%#.7fuqqd-hm2 d2|C{1YN.Cۉy`;}W^kb~MAe%TUkH"6Fl&'UUe\bv &^)#,, MEkVގjatQ]]ڥ@EEE҂,Ԭ)Sfc08~XP ̔)QU#Gil{Ggh3GD, e<͜r$ewdӳ6A) ",) 5H1X7_0T!.!swT]]ݣWa֮]cavOf}"\U!ˮu+-^9KzhЏŽ,J|򿻌c.`3XO)bh e4rhw\ Uܾ?d._'\ahmm0"ldHLLrnQYB-&&9sJwUsAۤc+(ȡ d}e装"I:Nt+**IxrsVe$ ~~Ess :]eYK/GDxXnMt: MkםVpY$fǎ10+AI0)h >,&jاqht /,w˜p>q7%(TB9JA-=$lD*+KEfAs4TUe44T֛L&.\IȲݻm i?""BR/))YEP]]FCCm``l ر!9ѹ4ڭ6r]J9MٓFii>9%І}Bdd4ix 2e6&_Bc"\eE!igŴ]rF﹫K:Bf.Yc*`>+Fa0vɊTFۿ3>%UE^>Cҏk~p5[`?>6A8=eu IDAT0˽r+. 4ZkXp8R'3s*))ԔS]]>nnZ%mUX3O#GP^^XɌcϞC>jH~n0t:='$HJJ'&&!?nŴ].'%w˶TEO7X0fYnJ[eY.|a?pdpM06}nfj֟}Om܈ntcɧ[3Wp[h.on-)))GvF_ݵTTTfh@Υ^_~{z< Ԇ9\>M;$ ,. r0)l $%eN]]%x< ,11i.v"(hȘBF4s~ z뇷 7xv{^p&&&rk֨(dYkASRRxfS$%%"2k~p5^w|afq/r{n)f6x4T, +A^TTb'p`'a%rQQQ DכXxiʡCl>jlZe/_:l-hDKK#::=JJz=S /^'ǮeWۂu e xק|}3HKE,sK.%Kax8z4^Ǐ~t3X,\}Qe[!E2cZK$6Ia +(LMܦFZ|^<^T_2Ѭ)R2_g&ѧS>`t:w.{ŗLuu ^xA6)s{_M7@µkyjA?$!7̊UkO7M7^~xLA8}:py˶T$ uKAEQ(a?Lk 5S1k)9taB4i&Wkjӷ匌),_~fs QVvm3"2lFqKIf*yyaTTo8pD, j]S^^\U}.MP+tF}Q'62L&*2 -4y=EQUbUdMQ@˨IVF=}ʪ+ILLXn.eTUUp23)8~ YdpЅi:D%aAA4k!2Jbbde 552QQY#YhYٳ mL&h kcϞF,Xng6iXFddLh4QROKKS`͖D||.͜jؚ06ao?=z,hy:Mؿ ]l"\~{{Hf;py"|èk,QD$&E2%NTC4EEV$|>cºh*h%U)^ /<ߧիu.|- .W֠`V+GO577mz};S.#`zbD2`0x;|AȚl'113IJJR 9sc'Ź](O:;v`$`2 K@\&'ŁfsYYP:PU]UOABg :q]{#}{{:*bK[p,OpՀ9RcYcfUCQ|Ժ[p h USVt@WU$sJ|y? Z-oƧ ,߱~##c`DA8pydgڔ̭$|&++* y<RRr#===GfJ x;s,Cnw vmgܥtz$ ^{|AkkS 3$>d&#c*w8IĔ)tۡ6QGnٖʹE,! +DF5`>b% 4E)2Ǜd> TYEAIk+!SD: hT2mIJT {?\t:oOzlO8ӻ斛ȓ?Ʃֿks{ivɪ+WCYb9W]y---\y,/=*\~{{ڄ=q|XXv5/(!s.LHnf/1DGǠ7nB҅ߖoyp"^…E44MȑJ,<ݑ>HQB;8+kFǏtIIDFFPCUj y=Q߲-sW"\N\\ܳ*$HM$q{1ΥZ~ۭ\twb޼|44vz w.}; UW^>wTƞѫkOdd߾"`۾ <:ǩVƤlum"uW̩wOuZgLaDYDFZq<\45X{o=\|e/{ Bh̘:v5𼩩={ *C8#%T5tIHH!::ZJ-(RSҹ%\Ȓ%mf̊iz hHjHhTTӵf@pSstUk:F%+ƧaxFJKK-?>t)'3. ~z=N$.` '5u>L4 ;,Br\Vm׮|'?BU~\oTYӬ..]j[oDn.~󻈏Gc'77zf'.Q 3 f|4y=(>FE!B&EQP$G4h*$Y' 33%^!0L!aa5aaa,Yw_Dܙ*7TXCDh;G">kp D,5 b0 UU=@IIA`^ς+3JK=8J]uwIC %IbҤ>_G])GPUUJccݐ3P=z,h@Hq^w! >o?{7x7]<ݹrrs/9|!+..{h+GrҋYz%:Ç3#rP6%Kqᅗ-kٽ{,\kCMˣof 85܂YjmƥACۍAUYA*4\(T"PhT!uFb3O1MaQO,~ OD9pXjjjZ`ˉaT4<-CI.w^i͍477b6cψO"66zj3D,4…kX"ʊ]zT&OLݟrQUM04""UQWq8|-D6N霷#d&ڱc>m]&Ap5\v%< ,[˗qxk9o[[vک8.ǔ$yi˜znjC yLNQ L^iѤ3a xMUq.Y4b؃LIWY0A<"tͱn*>#1e<E$ O\RUUDmxbblXXM46 wwa̟-uٽ82ʂ0HȲ̾};ih1CTt:EDDɓgyyBZYC.7q'M9r$ hX4㬬 qgO6_|!7f-3<cN:b^Oz0s ~+9t(XbccٸYJJ:B#kDf=Ȳ1BE)7G@$<xh0h~k AVHdXEŠi|H,u{y72LX4 /<*\wQUJN;TnF^x%ly{;wc=~+j9Ɩ-H[s]qOy((8>W}M}@a#ԨNq$!d5ruPEcc5Vbb $,1UUhlE"ŤI3̜FofϞ/ijrM,\74EB6݃k__y&$qxFT"#HHH%,̈ϧvفOǻJ ?Ww@xZ T{װKl . '\Z++Ess +WnU⦛gӦ?u lv񒓓oup?>6pY!3s^ϗf>镠بب4cQ5ba4F@G*Lc!4-o ̟?={o#//A/ }j {>m `%رӶ] 5@!#2YH5G OJ㉼C8 Vhind#:Fdd qq47tVт ݞKۂP UUIEEWQ]>r2imufs8.WcaaadehnnL'&v x᯦1HRoj'$EzbۗiZݿ)H4Iq3. O1*UU[n_Yg믿ΝHIIˁ3g6g_pQ֨.m.Zt 7PSSxopYm ΈeL0M:!NU!:cK=Lͱ'vکdgp`6)..Ly}cw{ CUUyGXl1_3hω}ֽ nsW^y5ҥ_^^_ 8a8T(Xv Uee%ͮ^Z..Xx",DX7t6tբ) 3gRL@8ZTѣekOGJJ&m>{.ILL u Iht:#GwPU IRouzc*(>dYnvS_@SS3nwÐ^5UaXVnFdY1. ]vVL5|>)7p &o%PsSQRRY31c:˗/ ||'`0Ԅ̲7 4-$ 1\fk0 -gaX8u|VL]t>;),]]d1:`ǞD$xQ>c+'!cI*QB2R^'q~d,h>O&Ι4L9\MSq9kq9k1E`ډ%.>$}"d'&&yc2uH/,OeҤAQedXa0m""05im*5Xk7>Uiii`0Jl$3Ob Es^{^{՟v…>tF 晽3p=444`4Yn m$;U8v.6m3:tK,׍Ny j>˖-uEO hOap٬L2Tه&L16"&>p9h44TPEx̬ihZYY3ȘJmm%\Cn/DY`$$I/e5;F6kppՇCXXӦ-fs8qsPCm ^{=bcYt6.X |ٖ~b"!!N˭$'gz(,<:З;,B0wT_%>[]^_ ?7@ZZPWWσ+.ii)w/dgkna0O_o 33Ç "\x4%\Ȓ%m6s9ܙ̽y~O;[ҶD"twwL&&&v?q1 (Sݱ @ 63GGs?ٳ7ejSv>p EO("7JWW7 /1eW}4-ӦMK_2qS;wDg$2e,%`%B )5L8Ig惐p?>cA.K|r,6lxCvH(8( yNF#IMv6o@$& dʎuuua L2dYAIBVϟTiex<:Σtca4{^PY9PO h2e TU&s0 wZRؽz^{L:oNd[nl6s'ӟʎw~Q%~kk+_8`P`YN|o޼7|n YVu"+ȧ?}&Fk)tuuqͷ~3'NJ`D\`{Ri˓/KYP[[#6H&$~Rw=\&v yՑ8y\p_y5ÌC ߌ\8UNLVD*՟c%*9=Hcժ)+/h4o~[L%[p/&ci$I.ɒp@޽ێ:y(42s f55F)`xy^ ;(I=DZRImOs /歭mx8ᄹ̟\r7|[cw}O7;&ȱ HR8]]NN #d9)wxt1lrq$ łfl6룭 #>3@rظ=6n|/c 'SC$rAٴikJnh@01 \d4NZP?{wywk ?-.=oo/yy\ox|>PoNV ¢r^A vRÚUNnn>Vk,ښhj[, 8j̙8jB]讹;6esO.K˶m\XXs4 !Occu5L:~#1M6$RcTV@QWwpL9_OaxO樀W(--/@x܌$Iճjսqկ+.㡇$<V=Lww)F!p5,n&mkO_V7 /nw--ZM0rp a{E |%eIL6^xزe=o,,,r6.Ae%_o={>h᢮ S΢bjZl6r Mưۋͧڑ~W\”)j~䚚Zyyۇ/z0)^}㿿iS_򾔲U}\yQ{8rY?,IRN7ǟ+DP.Π\H!Q|;V\S[KMm-yg-|KxgY; XtttpgT2[,\nhlbtS\TᠽnOfM\;h4sx_cNf̘ 7\ío`1 rYεPi0#´ЄxBz#*-YY +̖t, 8tArTdIM6lr.`%^.)[._ne-|_Fe6n@CCŬ\?I(i12Oml\ةNetzzqq,*c̓RH={>N 0ylLz6l@$2kh41s H]-EoVKQGpkx \UF~x$IL4IOa0dQZ:YPU`4lXb01h:4-Z6*5Em!E$a|R iXK7c%o\_ĪUfI,H&yҋ.ENjrG9%L:B:k9[|sa=*dZ.WwrA?|\rs 7kAz<}r9y񥗇yLKf\X(є(-أZ[M`(ruwz W6LiUR\|.$IbaJKKؿ0e|r(Ap9DB4H3 Rt|D#D1+SNYERVVξ}{9sV 7xIqzN>f=(>3XiFmm >{op8\pJ{=ԩS;(ttъNfst[@NIfَ]G[[<h[J9mFSPg:I*}Rf2G3B& QUcD)܅YƼyb1a0hQr%*Q+QTTqTRS9ڇH<>}Z$zޱc+W8ٚbfg_Yq{^̋/O[o孷,& \Ry|\z\vŕCJu{.Jy455H 9@Nv6Fuf0L}OlbG/P̵QH2Evɓ+AaZ4|b SE($ CȊL"тڤNtT^ q?Le5W_@YW<أz_}Ms߾}\~㬳Ji7ahn`0tpPPPHAA!Hv7utt ah1LH=( n>xcz!yN%?0)UOʌdf8< Z ! hkƣvޖ\QQ$4MT|(IQJ<ڶwJc0!YǢϓi,VeFpYx'9892D,h  룩 <8lNZSNt:KɱN[[Ӑ1$3~_tD|re^2ԩS>}:fmcx|*+*ػw;wee;aZ-[PWI (+-f+ EKK+.>u&o/Z[[360s= nE)u\v7xFi1֬bik6B0 cfrV)|z:p0.BI}DP! F",D.%L@JtO#ݍVfsrgc$+&HKK#==]=QdaΜ)(phNô4}f"D2⸄5ZyϞ73y,fJZzgE…v>CSg%̙,3cEikk,bxI"D$v]]#%̛7Bt:"*A$r+B8#.qJ2r˧rIKp#Iw ?3Dck 1-.+X:ڣRd \g#PVVUoxY:,jy8d2bZ:u ,~7אǂ' EM{2Ȕ\H۾RrY L\[.b(2AXxD"|;G16JJJ&imm֤Tc|ӧ'/0iQ=wSS?Veg~z{ρFM? }$u)/Q^Cx5JZ$)lEQ_V =I$ITW# ֭83˳T?pGcL qpgHX"`dx̊R]\k_A 5<0D#z{{{g۶3fL甓O?7xnUhnnFe\k[X,#u8 ps_Q""zY $#M efښ$<Ng .\ ´qp8<äI3)/l/`UDSyp84#LbL_'h ^yuc.MB.-`wK Bjjk3گpX"c+?y3yKȎg~:,[hoo?^Nﳽ7oٵ{77A0q.<++et@ <~HUS& eUj4^m./BA^(\j$4A$dYF$"0TUXFьUN(6b2e֭?4JK+),tmFZ[Fq>͛6/Gn o;@;8bːfQ] jy~|.<_^Uo6qcXr- IDAT5O?GOI_,[.HFcI̓'O>ӥtz_7n^/Ow446Cs%~.zM7[nᖛn$?E?1 &&%_X* a<c !o!3(tu޽۱X]lNrs -`ʔ9~ۛimmH$2,jL:".K!Z[ٻ> iZOOYY%:>BQTq Ѩ`@ Ȯ];;3z eeٜH $OQdƴ|!Ijj`2etV Q7o~JYȩEc!vچ7B. F7o7nBx]ww ]]h.xFkأBL2&]Ʊe !` ,_6._XnSRc'\~ŕ}}S{ꔲrΝg:NV&cc,[?|HrjG":'ˆ4 s<~ Aa'œ(.,GjMν=ǴITVNbC4]J>g}v~~>s.l6hJDr`Ї,+AvКِee-sVP[r|LBg{Bt8Řf:;[jT,|syyu\Ky3ߺw־KSSsFN?_a&B.;SDӲ@`,)Jcde\QPPHIJK 2-fV˔)\dePVp$"tN2v̜y2YY:ZIJ,pH$Hkm6 JK'QPWG%A͡s&wv6 $Q^> E9O'h6tǜ66lx)SfSV纺ڨGSS-Pp$_ĬcgÞ[x!G,z\~|sg񷿽:]2.Py7={ebP&BӲDG` 1ih8DC!$IC^^EE8lNl6'3f$Z-$Ih4 P6jkPM^if1u\fΜH:4=Z&%HL881ˤI+؈)鱚9,55 BWW+]]jTFƐ8thoJj#v7v7ˤI3))7445XC CJ8 w/ӷB. pA.nF.bV~m86ry  hii?9K.Jnq8/g?%ãSI.߸!CX B.B.MrrTVNЅlI, AeE&N#˪DaƌIZN.'EK/ PŞ=ۉD:itl6CQeR"%IPeIô5 | de(*HD)U`0imm9{zؾ}vڌYJII%v{vNXC{{ʹGdqjZ+Ȓ%j TW򷿭pF7_o壏>fz>7yoKB. ?,IRFs鋩Hz|#b6B0w־KQg-߻d5s&(ҳ"rVf ?ߎٜ`Dpf!;UE"T1^&_'Do~-p8LGG+})(pWHii%ziowtS@n5) zwh47 թQl Vk>X,f<RTc'j 9z%^ RZZZ:%Ϧfzf3/3^h;ee%ya&X0|rY?2{צM?'?aNxz_tfk.*O>N;[o@ ~sW'<3OI7~9ں 0}tG[*"rye ˃7HF.o`#'/Z]O@ot易\,rs 01tFtX.cUq,rѪcɒ&B8BGVVsMr'DXKU9;ijeҤlZfs6f(P(ôwkv`gpSQ1F*Ka@Oc,x<]x<]ק_b2ec2ee`BWee tbZ4Dt~_ɕhPZZ̍7~^϶myEv6m ,SPOYYi\0'J.GeJ&]ٳ'^꬇xFNT] [?byU08pO*eӦM`0/$5k&عs76[><دqU.@SS3/e^Wenޜ>rhA0\^t ^x>N{y)))ᡇٍ$AWw8p,]v  zzz_ի O=$?/:w# ߯~|>~rUWg>^}C?cdS1%cL.ؼi#'/<GT2peVKv5i0lhFףeESJ28CiU29m$)u $X6VѲ,(2@E ȘLfzc҂~ B!0_J C> sdB. ֵFfqP5?/8p.Ղ˒%G*%I߽~6~}̩.dӦ{6/?+gժ8C.Af@0dN.Ƶ^A}}3|>Wprͷ{u]Ceeݷ^|Ocu%%tw{xzR-I@ \.hXM9)d\>KRRTvO)ZvAKb'~OD '_x/y{E2PKw`Z2$ ck2k#?FnnVk>99V+$UvwwNgg+4`80\D"xj IzgڿHKK+6mko~tttnaʔIHVyG>$ }&I'6es>rY/M4*en^W_x6/>p3%%Ew ٱΝg:ًj'+O/}ǐI<>rF!(3>r C/RwޝryV񍯥s<#<9)o6xN=>>ۭ\y>eea,KW|Px:IEM+?\2J.G XOhUK`% C d9B-8I  EÄB=x<^ۛ{՚fj- 77,5l^^St0 $d9Te0dQ^>IIӱIqx:HCácOG ??99Vrs +$/|;yyv*+gDQέtvo>iQ^>FCMM"5ŒGAƚQVw{"?mt:^Yh4'4z45OFb۶y}loknHDСhڎlw>k˂#qg̈́B;\s͕_Xx3\N]]gbvڢO<wޅN7ߒ Tof(r[,F>‡*v?;ؽ{ᄏ$O_Buu QVV6^~u6߿…j#i,..?p8u]Ͳe B  'B.FR.LjIfAeW^y.h V՚Gvv.)̚5VMo%I1 r4$,Qk"ALƢc\Q#c׼,xOkkfrECQx^XĬNj- /VG1Gq\{=t݁ӉӉqNv;PjjuTTLCQ(c+5F&I>gDdW__M](O[jc]uK{Hn͚ҙ[\ |Huw:;;,_~UUIf7+O??jz@yn6ґ;TQBCf@0$exOE{EQٳgqi8/s-`2xGPzz/>r1 mo[SS њz%?B.38!-N#y0rclA`40  :t:z΄NCՠjhb ibHF#J&iO˩)8=Srh4r,XbRZ$a}(䣣Cv31zaݴ''Llrs /jbl.,FGQesw++!+)5xyi$t:MM1-3,EeȤ`>[/erk +0('7yMVV p>0]tsѢSxG] ]L+c˩iGf@0l=9r'XM466ͪUq sq5ljjj߅ O[ v#4F{@ pp$r8V.XqIwtpʇH1=VE:%~PrJľ%@<Ä~zzh@|Ԕ8/1X,X,擓K^^yyx EQSlĄsgooOMyT4 %?Q#xw$ψWg“ /e}8y|[WO?O?ۧ|p-iD"n@nn.&)e믿믿 ]:ĭ`} ˂Ef@0dk "o߁(8invq:uEE.*6lx&wvX^x) pp$r4a=\uX]VeO3$mCv2=_^zziiim便1^hb#77%%8+f׃?,,TScx<]qNGYٔ|J;B. YN|l޼7|n YVR-[q|xh7:j\RCf@0j _EjB0H^xSRRr>N1ejkc1kzGq#CSRIp0 tM2 \Bl|wヤ:O}j=8˖-M{}7\,F;wߓ/uF)휓c%'ǂdbB,߳|…jHKhހUc :ƚ :S COdV,̚v!H kfΜSYx٪U?ֶjYoˣ`Z G+%I39M6 ,\7m wk/:`2Y0#X"X:`ڂf'&&۶iۅtv֊qy(+#22 EZZ:³v¡}/~}=D[Ȭ=>=%2K,:S5pX^Zݖv,x$`B`N!s1K_ oy7z. !bi:uEh4Bhтlh`21 &L&~FRR6}>/xbqOBI ;yxϋsz=_^^z9|hZ۞khonK~{^~yx[o 2Qmƍj>C燴9s7֭;ز忉qm7^CHd~R.w<:ñ-h\g< 0 !BL܂齄ן!T~Am+B1R6Zijjὸ\2YYp=2 /^^oho`0O}던͑.p>Kyh~8|5vG۩2Zsr-pu?Dֺ)06~'y0w,Gkk+24MGl6SR\\_|ؗi\={g?{ ONiw6l¡Cy z}_9zGz9\5@!cAy%AH1rV aae[Ky{;6I !Buiik,$(]e׋JzTUNCytUUQ:PNAUuNjྡྷ( Jy}(,, s\r|Gm؜k4VmN fIxᅗ0LsN6rK5<^ 4\kT\?wl붼ǟ^V $\U3e GCgW @I,v ;C6m70 !b,bhnnDrr&^FqqhM /n+v=gm\r|*٢%kty^z\.wՅ9=ȐpY@pb$`B PlKC%CB!&z |>NQU#:NCݻr-7dmrYx!Gl61v ڜ9r}__> ::FpWnݟ4Z[hll'< .=wˢG|cA{1Jd"\9h$`B C ;lٖ0O;Xˎbg;]_X[!bdIO(Q(wBdd4 ՝ sGC{vE.mڴ˿ŪUm;طo]UTU᭷~-ĢE ||6/~+nzVwE_W477 SpYi{gnQ9 Ji|HeɗGf!D)\I^('B!bb≉ɓeLfz=}8}r.mN_=nw]7ov[h7~uc柳GeqFoh2y{߸0.0 !+yUC8zY!g@zz>22& 3eluӼ)_H,%hM7oOKI,ˣqXP-WԡWB!g,t:eeDDXq8ꨯsG nn˒9> ܿ5k W7GyCǕA I,~! Ӈ֯QNf!B1E( Qx(UUDGGkݵ!xD΃%"d#\޲#}L  mXB!HȘ(*̜*=?Y0'o/W– .~kb͎6MӨAQOWɤHƾ}7uVp9,$`B )B!>4i UU̜gCCS]k~Э\~>-̼ysHJJǞ"77X{lho 7,cyJna|m<}af͚ue]w}/؃n /`ժ|%@'Q!`Bտfm#B1Ҥga0, L& 5546ևgI}>ݻ_| *@eѳ`'vO<R\%D_.\,+rywToòB!Fh;6QQ/Err*.҂v,ӹDP'kH窹lٞ &񜾫Çw|xY'"l#\׿ۿ,⊯rmPWWh[a&nw`.ի;暫YJV+n /Bnn #;{2}7^|9/=fh4|CoòB!FNOfG:FӠ>BgÖ\5-Kˣ[k+D\\/p nm9Q470o\;}s/Νz<^jj V /aٲXա? G a1p9п^#̟?w *۷U^ ))ヒ3y5/|1/c~&֯C=_>tT>˲pB!m1TT @jxL&3UU455aBeG9w>A w޹ ֭]v3n\ O>.s.PÇ󉎎3.bgz<^qq 5W^yПDe1t0 !P厶f/rW1g,>l[;nO<+o))ITTTbZ>={}5k^"...?}?:ɓ'fͫ$wi_IFF:)|zvOf$`B!hQV )8m!*F˂hB7`0錁zހ˦).04^Qsy(%؞?#({P۹n>u ֭ 6a$ƢE ))6m*39sfOijjt$cPI>^xvf)s!BAӵƀ' OFQ0sX,X,DDXEDD$Fh4MkA P\BQ4௧x {< %ˢKޗw|$''椾…pDa{f*+Oe;io;k|Ӳ;p.Brb9L2^䓿i~㩮cS}Eo䓿s+`={&0={P]]b`0X*5J!"1ˋ1&`0,+FBT/Qf:K;blՆيF[[+nǃjubM2shH,: f|sl<ȃx<VXIBB<X,hs,_YȮ]=]u={&?kݖo{Zֽ#H "drBeNǥ.hѥz.l!}6RTT̄ HWvj3mTpuӇta =J!"cObbKl0=NUUV11q DG`hOVjZZhnn&ZZikk ٝG{_-}yN(h4?pko;mmmnOٷonC %j} :f͚ABB80/Qnn?ѓ' xGx3bܭAbYv K!̙3(+OlҤn݆݇䤤$rضm'Y۬__kx"<0(..c{Jp?B!~:㧠i'N|X?aB6QP`ڰ㈉I &&(|mmMV蠱FMM x3$z\~WiO> NmN( $\|Sݻ?Ӻ}w v{pr88Up{_#sOdϞ OrwF\\,+VNrr2|Q_/_+ZAh,NiG,hΞ˪~.Y6_q=u m趬oveW3g|˖emyUo"""[81 b}}jkB=!B>EED[[ 6[,ˊ/6RILLnC3_JUU'.WUD'~{_'.]yŗ(72%~ϒ#˂CᎶqR<ʕ+L#eeICf!DX2\p : 4ؾ}'K^/7M/5k^ !BLUu^Ç^'#cRrO&))fKb+=tlꉡb/vk7dgOrFCéI/ ^x'x#*~pY Ncʔl~㟐~u1޻ݵA尓Y1.š?C՟׬?x|@.˖M[!a6ԥ Fzr! uRRINnpݔQYYBUUNnzӦ-3<ɓOG>O'..''褯4m55TUUq1EavM&?,W)f A-A?H,VC ƿhH( _"v-B!jB[[ee211q 6SQQcEDXINN'55-6RN,F|n=J`M(3<OC掉gɒ~&lh4 >|7w'?~wXH,N[(Jdž ٳ7x7^|% v0H,:SS7~ٳg}zxpCke۱ T: 5pYs"HmF~7Ț5iAM\!ƍ`PYYBsofdz j:tҲKBQjUU9eeE^ώ`LU^^ԶB!>Bee)MM dff()9z}Lf22&1Ʉ磢'SWW/z5FTT QQQDDDc6GztJut:iiirtt:qZxeexȪGddv*[/QUUASFMMuuv(~8ɟ%p՜b6mLeq&.w߁$`BQp历 KFߐ` +!BP?>HY@m㧠).>e}Hfd'a24'((ȣvx` F⒈Mfm//c^ u8up Ks<ɟߒA 5Upbdۼ-!p0u1(0 !¤pg:ҀVOV/' g:E?neHi3w5B!%66(// 119y,^g)^ovSPp|Z[C[C7Dbb*IDFFa*jkOPKSSYUcbh98$\g=FP37{ѻt^ %Hj4VEܼ=%JJ ˣ.0 !Yk.xB!s0  0a RXxMF$a2q>#!)5HHH!%%T Zʩ*My;ndnˢ_;at&d^qאYEf!DX"\Âj鼒B!qlq85=o%b'p2KYGf!D؄"\޼=M>yTO!cd!== 2Vƍ^'99H|>/? F'&&>p@ee144xg`^Lt؜[e1>ߩ_ǟi{s}{سg_mǂ/{( BM>~f0 !b$Q:Nv*S^N4qXntPtzƑ6dEAQb*+Khii ʱ6ٱ}[ jn{^󜜱I:R0hQiG,=\\\,SL>.ڲ#v%\/ No}ᅴ jjjRPPʮ !b JIIjJL& ^hee;vfe)$'g놆zJKOP^^D[[KP3IܵAe }]SۂsٵkMM=m 3eGW- ̃ w,x$`B韠J>>{K/w{;>T(&B1&"JZnEEG?>IrPUݟp 4N#5u<(--͔PZZ@ssc葬5gM[%\!( . F@ 0 !B B.oّ>&CKdTUU=B! EQ8\@Yyinn`C~##̸̜q0 |>*+K((ȧ!Cɷ/ax E5mӦ@^^~P'<[Iիț0!BMZZVTN:4MؠeEQIJJ%33@tRPOqQڂSy yXͿ6oO%l,[P1j]-ckۍyH᲼  a'o( ]v)7t=/r$BQ :Nf$f3pRQQLb8(//>f HKd2i USYYy(_p/,aWӹzAq9(}IG-U=Mo2{Lユx<^x, ]t>}e1MCf!DX3Oϸp8B+!Bv{>GEE%?(B!8y""" K}} {lC|f`FS[[MUUͤI璔(455pN,"kreG:8=dpY wu/Ǎ,SUMߟ0!<6˲eױq?`+?/rɓ'RTT ,W:osPqqvv; JJJ.wjWC#b gɯ X~_n@SS3[ngÆMz]t?(Wwp5WdɕXVn7N_~<,Gvd>os,_~{gUcc3=Am+BAQ23'5 Pq:p[݃bܸ xn /5@c?X*`9zMzKbaˎ 2K,: {-UUy啗E;m-'::͛KBBB{_;yopųعsWKMMaժTWװp%,[vkּ:pY BaYwu ?o~韠¾}Y%?>^ZA.2o'obM<OttT}Θq7>K ܿ+$\9$`B߀_Yx￿9sfgۺlq{I^y?xHII9{YqqvitL<5k^%%%KuO22IMM׳c{2C$B!BmܸL|J&XOYY0",hsHHHуTWW s,+6Vk&S$f ьNGӣj>]ATqk(H[>|28.w`ٞ?#({P۹n>u ֭ 6j./ZM9LaΜفor>p=q³0K !Bhb Ku%5pA@f#1qȤI璖(44ԍ`h4B||"V 9 ɈNkrNQB#(8b5ſ߿O=DVeI,NR?7T{rrmmN1 ,\x 'NaVHLL$ ,[v-/ !::mf)+pη=-뫿{]n8ˡ%"dx>pW/4?w{TWWh\v"}|߹{0Ϟ=?}Ӟ={b`0z_lz%B->>S/`0R__áCpFUU=D70qTDZc+BZZ'^olcXIKOdd f Nϩ.?4= ^xyqXb)**f„dds+;ۙ6m*_Ew: t0{B!FEQ4i4=@qq4Mc„sX"9y:YYS  =S/jc;[X,&jd2tMNvp[ijjᨦ!Puڵv7h4?}.]_f !!_M~K\ɂs|S\\y=yn?~`x^_Fl6@G}(77@ۉ<Уg6$'%%+Ƕm;8ɊfM\ŋqੀLEqq)mm;8Tdu!Bh&'g6[M89 $%|Shll9)Shr~\.gt:&:XzS%*N4p]844Q__EEEM| ]ũ}DZrx(--CUUL&Xg.m>ߩiwߏϧ22W#OW|n^x9\p %\1$`BPhaE|.=zKN4@ 曯b4p8mlذ ^%'~e~whmm?_<;w?}= B 11q`0RUUJn^-ĉ4G`23'8q"9UpT0??>$NJJK ["s]xԴ𑗗ԩ|C򈋳cy_PRR̓GDD={F .[vi(sϭb„,_~#M}Me}Z~.;)4Hmmmxc=$`B P_q=u m趬oveW3g|˖emyU|k_[ZƪU/^ !l1pwjU4\z4(*'砪:jk5k!F#GP^^'O:$'gbFj 4O |477RQQ̉y\pv{HB51'8t(7xwO?JSVZMuu ^²eױfͫjK*LPCH,:,MG3EQؾ\wۮȘ 폆.kXH,+ ,{QZZ>B!X4TJJsXn[v:r<7VϟNg󑟿az%3yr6[,:S MHaa>EEG0y_]%$ē4Dv;'1 ]|kZ)+`29s}:ssIII OИ2%ÇGN7 z E UUp_j̙RRRm۱mc60 !N###?gB!EQ8qiix|:'O\b`„L&JKhh#-m'OGUݻ'H~YL*]Cuu yyimm _'G^Xu_W_uNn^~-GesN[Gz;v:[oo{9:Jaa1?A|NC$8x7={&wJ</<{~Y~tv,py䒀YV 7nElّ^NsIL?}={n-;vB!FNϴi3Kvs蚐B||2--TWrEI%1bv4qqLvV\Hrs'))9~݌)WGDDp0qbEEżtUU=Ƕ<~'O(ࡇ֭۲ <~ᅧy?{_ !f2əMdd:f hhcŨMss}>̽Z9W. IDATq/(Q]}wW)t:"#ZDEY1X ft:ހQU4 EvPy{ɝ5 oM7}od͚׆ b.钹%.p0 !BC ;$dRo+BGG0k2(ȑKPɓCyʚ릵M8|xt(FrrfNy$M]]ͰgxDl,(f & Uգߓf woӴss%+ Om:M4eٲ)*!x?yΰ0_$\>H,v;lښ !s? f?;mBqMdԋT=cوIDEb4PJ<7QQ1~X5)F?`mnnȑTTK?b2=hf j@w|iW[^Njrrx\/ ׇuzoŵ=Š,bˢAy%AH1 Batpcɩ9m= ąB!z6i|>CuuylqL0Ui=%^44QVVFOG\\+r4Ny?GtqDEEP"sW{4xx>sϝ46:سg+1}= z_##c:i\nrsw{ Jff6IIX,6S z<.ZZihrJGLܗ7@RR"^w,H5 %s.K*6$7rpbd۴5Q[>!g&"yy[B/kvL/Ik{Coo] |b=c\`cB!Hf4əMddU:2q4&iS4M#;wގ[#c Enaټ=Bf G apy4 J:J!?:Sd{ٔ²(.K[T \@{UD VRT+ Qm)^7fM/L?d&dM|>̜3J~4 47`k%dptzDRJMMMYk7O$005k -رRCV4 cFʲA먯Xh k 7pY}ZV܄$AEE!6 =("dyrzu笱( F|:jxɒ$$`hkk8VgwD,D\O|!A6lXKdd}oۇF0R A5"\^XF^zu6O=Sf7  ̦4le`mSIK$im=ŲejU`4RYJ i`RPլYp2> 33INE$p8l9sZSy[7G^/e/"..FYYyy9ݭy'Ĉ oJZdKd((! 碴%ť`))9-j?5|]w݆{DVs=wdno;wN<޳si sN|??&mv{{v}e}J%Jf ‚%e4*N@RJMUU1&TeeEX,K[jV:TgYAQ:;(*:8JO#==Z^p8hi=![#'bݺ5DEE{TUc=oLrwpY|:xxƬe|{7믿͛7#9gb|.PyfD,œU/J8==,gj2& ǎ?RICCG}* GiV䍜ر"}=xndYҤтp^&ea$~lȑcoGZ\o{==j]\syٰa7nbpm|7x$|2^xl~>/G. 'fA<&sT@{ EoĥW IDFF=a撘JjjP8..x^ꜣے3 SǴXfZ O[u'2--TTshUkUU˧zEYh G7UYY^ Q{{{˜W:oP^^b7t̑\z%#WA#IΑ1p %I"--dV3%%w7IOnR^^ȄGl ,Mi̊ ugY))9F{̂az& ^2M7.oJ-?J˂Rxɓ <sn ټyQQQC}7 /sˆ 8rNj?|N.pW_}O?D A'fp[f˖ͼF J?111~IMM?~ڽĉR."={g^JKطmذwywMą  R""wJbɒGc2))9jvhFTTTa^,˔z `ŊTj0?aFbZ(2Ť}M(ʲ̝wދVk_e]ʫѣHH}JII)K΁Z"88hLk֬755}ӟt!Ĉ 1ߌ\lVcv^~3lܸ>:౿g[[<3{zK7LDD8]]]^1?j ~Yb=ֿӟLrrq:{"\VI;Mk?{׿W_}7x]sy 9u9/O^^.99KظqWch4F#}}^g{(T=pYAu㝇Nd$Bq @.x;`Nim=Ånرzzz9p]t笏lR*eӧ[x=DFF|ofQBAewSQQ, A1%iEIcc-Kiii4,Y d^ L&r|| KDV!I΀Ӟ|N\\ Ah4:Z3qNo((pxz~EAɮ/\Ap윤q1ǒ$i'&eSzf_lV˅na5A"::3gڈ? /Eqt ׾vW^y9u?ȟޖMߩ"9%fAfY1w]^17;{( [o&22 ~.K/{cRk9|x˜ Dףj֯JAsMEϸr@@ kjhn>ɓՌNjjVB@!>>zԬ]!E]Swhh˗oBK8qb!FHdd<Cz4ЗP9gvMʈ#_Eq8+:Vf A#&չjbZ-f&c<'/~Z۰sσ3z^~]), Gte&BBBx{uQQ|7(2Cs9G?a_Qoׯ?Οޖt(\)ψY95WZ bپ4 ]t!}ÉTF#//qW$VXK/amF_V$`KAA.D}ᮚ`֠h8yӧl'7w5"Q^~FppX,V** !? *3htjzիӹj,+tvvPT`%--8z=j=*Os;Ds!c۰Z匿F5#z{x]?U?nO?G? u<ȃλ=zjzk{;M  QUUMKK:D,) otx饗`\sh5߾l~ii9EooX|[[[Ҩߋ/^e1 /F__?--g&n>pYMu:oEQmӟ>o&k6lXˑ#GOu{Ĉ pII"**HEE!aade-G.[& ZZ8}I] ,[J@'OZͲe5Rl6q~Lso>@vj""j]x/ 6.Nmz 5%Icx޶uݗ$k*={>bӦ dffq-W]Y?S^^cS )y9h4rQrz bRijrNo*m-J3 G5%) skb{^q݀ :pî1:;;==O<]~ss3]wW_uu٨jϳq:dY,NA3IdkX23P(k[لGImm`6HJJR#ǓTl6/ Qz21 TjȲ|j5e{:f{bGO刈q>Νɓ |;`'vsx!~%୷QPP4{+"\^’$q%9rAGG{љfq-gD̂ ̫mqY8\^W_ALL4ַ1DOz_AA< IDAT|#!!$A** HjNyy=^ۊI ))y(BttIYaa{5&Vk;\92B{ 0uL }-7RRRO? OΚrrud,(hhYT'×95mƻ=8G766(OZZ{Ad"iAPI~hy8pWHNNK.C $Ĥ ̹\q_O=&zTz>|twO~yAA.**tv+XcGѦfj{0V_VG}}j6wTTLK䈈(֡8[ 207!@~*""bj(;%IAQ {(<' R[[Mx=ѿmqײcDžf[ns^%%;0JK/ @__?>}, Ku7h4ן_qXpy sF>从-EQ8p$qd$''㽮  3IJJ&"qjbb0(:I"'g%CM47$.. ee Zj?֬B@B}}i̦8rsW sg@*ail|~;zqM 7_OFs&^zeeq_k_}LJ'~gl쳿p.))8yl0kb͖3tm/,A5zF(vy&{ z;w~ Ƌ/LwwJA<4Xd}iiDEŻG.O.GGǓd v Mlzl|vZ IFQÈ%7w :]3GW^DUU͍ҷ $$$E@@0z} PRICa3vĮI3@v- a!$;kKdF>n^2bbˀ||"`a \v-zK̓6˧zx־  L^Hff>$QWWNrTKd2R^^np9s$+WnVe52R(46VSWW5CPY?b3Dl0Dhht:Pc=|Lf(*YvBVYVeYa6[m8ŎnGl66Ebp8XV ݹ-y%IKs1M|OB0 0?|. ̉yJA_OVRj 'OV9j g;Tcp_G~zT*===$&fHFEIq/VڄZ퇢jZ-kի>oqf6Y&CѐALL C~~ ι<<*ᐱZ-LFwױ }\wݗq8d7]9L+\y~G>>|<&\=ӣ*nͨaDu&\K̂ =.obS= BYA֏eh4Z<^$rapHee{7*uh~X, ACL:nw%}.g$e.D,,sH+] -%AKAAFKv2Z---5{$尰,?\Y^fAr@X1Bhiiz+WnAQ݂dԲªU C8 'OVPWW>}OHH8YY @ 86~ښijYk^{허g~QMi&. B'90.0 0ƾBVZwԘ-}i'ysT/NXq3, 7j|uYC.GuuY唔lcp8AWWtwSSSu|bcg}r_E\\* 2u).>8` 3s*CFdV+=477\7}+ҋ㩧vϣ~>w0)"\P\>wYokbAAJEFFz} ]]:56LK[BXXԈp1a$&c[Ass# SVv|̄ljknC,3ǎᘽQ:kx,TUiP䌡ZI%ix:UMc$ᦛnwpv"\ΦDL5/d{% ߖY[:|-+1zYAB$RSs #ҖqRrPP86L&#MM,]BIɑ1cb\:tlѱ**Fq JJzz&))9C8m`4rt sү̷v,fS./|$Z7]XP ,gD,¼u,&ͧ8X'mZ΂ 05))Yb4rdQ))Ypr@sm{iZ[Xr3PZzϊ #c2ƴ 鹤dRJK(8v**hmm<{3BVV.CA3ve`hiiĢeXk0_Y?넲tnS1py [Eqq0+mWw9^qu xNhh֖( "#c1&Us`%?}VފFXIrZ꠼|v,^r##8ܢC!!&88 sAꩭ->o|9͋sn. S!igF:1x,!fAfDa天voQ0<=Qqo&]Zy&OS~§mx%nظyaM"**Hmm929!!xfgMGFF~IǘL&V؄'ho?^C|| v!h4:֬J`` !,IIqY!LvrGtvz)l1ByZWpA+'d7'mq{eߵ;Ldٷs7m#,27f]Tl.Oa.l3-@Q{WAAjw>w6.~Ĵ(|k:\@}M n#]F2 ߓY9'!OWwΝ"--id  ""MnQ[[fXD\\blK8ϏYII&:: /o-çNPcsrlO+k4.]Kdd*jg D}}٬NRjd(eQ"H;#?]8{].l9῰\lFHSm\IXT}92o~ /[Ng[%vGo7҅Y~Yƺv*On{.z`N{BgT,y'fA支%˓4\O0m"\K˂p~ '11 Nmm)V@ %c>1&|9y*WZXYI -- i#ȲLZZqqɀ,;(*:dq z$IpPYYHkkO`&KEh짢6=0/'^o_3d0 Grga'nsOc _vdEa6Wƣ?yxl7ZT\(]u]DŅ5B;24\g%fAd<7Րxɒ,Y9."\BrrL]]9fc}LLqqXVN G $7w{:FmFG٬X@Ed2RX8N)r~~`5bgrjsh\O%@AtwwRZz7Apv<[A:Mx8$ea&v;W~զL[媛Nqs,"`ax9cm|~. 3'e@˂p 0 (vw}YV&5ik,ea#U24yY?$q*rV&[<Ӈ<*{n7!w8f򹰰(p8lԔa6ֲe!I j@NтZaŊ cTsC#BGv/ wז5sߗ~JoǾ?;z+OqvL=\v-2pD,œp9005ǿow/Op ݍq{lV^ɷO>?3WufxnF}K&?9}a*D$$ l62Lj/߀JFet: :]477RXlCIpXCKK㴏!88e֡Rg9JKOͨX֠Vk$eg->`6_DX& ^Y[}(ٻt e-./* yBQnvk)!̈AS37&&|[f˖ͼF' @LL4uRSSv;8q/?`Ϟٳᅦ2{gģJlذwyc|.BtEX|T*5yJkk0RR2Quuz/tZ-:jk$ՄFM``(଑{đq=FڵV4qG&_CTTrZeNla>0mK 2򨯭`+a:D,¬0לf2٬tǎ+\qgظq}tc϶6yg<ω ˗oOp<*n#2xgXO3I{8thBB0Z/ _=;(?K1/!k֮W˂p~ST`zd( uu JV2wcIRDsIZJTTZӫHJYVp8bgP}!%ΰb1SRrdL=jatCuhCuըTjd^$IC,$T*D$T*:Ov /pYplWvLd2kޤLȢjD,¬9 III&$$ \|wMWW$%%z /ʱcr!.^{mYwٲU ˲O{?̢܅0eZdK˂p^$%McAC))Ke Grr p8KHDpL'HI&>>PO uuӫ@f2 ** ԍ  dwل\V %(( uh4h4~TjTCO] WQϫ.xӐe6 PBgihȮz*D ="m>%''oX#irZޓokow=w˲lcl1x7DD,p{}EzDFF1^o_]^=>w}Ǥrqщ^Gz}- ̶.w|#Gw#}םdffq}"&&#?_sk0opL+Gan%h IDAT[LSS8p`?;v\-nER7ӟ`Ŋt-a6ؿ?=kL&q\uٻw/9$$${`E˂0+RR hJzC0iiK8y>m$'jF4DFJyyNrr&@B)YӱbfZg4PSS>ã[V:@~^RDECPP8hXb28G;GP9@AeEFVdYf`ٰZX,V,AVFf uhr9ω _`6vട/D%''@sį"\d1˼l8$A{s.j.`+v/q^tхk^ '""&RINNo>\@&I+V,㥗06vpmCEq?5>igS1#, !\~^/O~RJ9E;.F$j|1bccyi#&&Ȩ(^zjjs>ǎq 7Gwx^ze˖y|@Ki~INIoAV󓧞r?ڵkyy+8\QX$&W*$IWb4zm##c)!( VGWWGP30M8G:8q0Vu}^t=!!a349~ SLFƲr }.QťNPiihkt'ay(Tevviy^V <F^++~T*=jBB'xjK E v.zݦy A[>lX]ӧ[yﺗeffp}wꫯw۾ʁhmmc׮ٳg//{+;SZ:0n'##ffݟ-S[fnOL7xcf 3;1BN#߰v\|1F7 9֮[GffG&cجΐ{~rͷq&Pռko[~zIII廏>~u{<믿OBB<$$ĻO>ȑ7M\\X,֖ A`@tg|d=^Y^(tv@ll"}}]|,&M~JKOɤK#ȲLiaOzz.IIijȸ!J7Ldd4C(~~0,ʍ8ZtwwފB۲ζdYa׮o]-"\\ Y9:^ر>]MM K+_=>>oFͶm[wc?O L&۰a-G?e0 ߎy.tMm/3k׭;Ijjo+Vŝ$Xm!=pyEuRu222䥟poץ}ħ>i[^,nPS]M%6_Ķذa#MMMJ~Re~~:8}l>&^|?`2X|;`޿Coo/j466Wz %%e?^01)"\lNOcc,%fAeQa&ɲ?GOO/v]{wu>>uUUU{/-ԤfOdd F>̕>sVZWL!r &Ξb;%(n(^֕a:nf>{pݬt\>;ЄeI΂WԹ!"!@ XbP.f.XUUOxZ-?EQ^C 8%K(O9K`o|qDF?qENi.ssjv=Ï<|c)*I~~) P5YlRPH{{#3S($'grKUA דoyYFs bEuܣ-#""(-*E>ͭ˺u[`o'z=iidffR]NHM*^!:;i24YȠp]+}.2jw\>ejQ0>>}8̹瞃`bbe f!.YrrY ,B.:!}j-\_iv=󞼈vzz*ȇ$^yoӑw#`-"@ XNW.^皝<'cQƶVˣB餤$SUU$IIOOa F)XP<׋ ^e`Q0h4RPhdfz{;f,_XE+*622HKKHOc||7ZqNs8b))ـSQG͛-%Çwqq*DUUdYftI{{#M4ʳ`ahG?z+yy#18xf9[[fvoǴwio6\PNDe@Y ,3A4sd+sCC#6rsijj!;;z{D]#rع\VfMӢF0tu3S.nh4Aww[H.OLqDGǓ HHJwwsb++ۆHFkk-*@||2TVWd2WNBBf^FFhig``f*^jla0,X6 3&ltzdTt: -J]+tՀޫH. ڹoCUvǃY{ h+!r9C89.#|Eӡ( ø\csZ^ arY X9Lf6b2h-4h4QXBWW+]]mӖn phn짤dYq뤧t:Z[<-"9rdϜYdddQNL)||R{1HN ;;=mi@Uehkk}mE(L&"#cq8#ZX,F &I2$i ` ^0xcy K)4Jt*3dʑ~'966o-WYY+(=!ZDf@,\\-$^L{ws]V !,\Uhx#&`h=fi@\T.PhLqJKI~~9fEQ145?3lp.&%пJGG ͧ\nbmnEc<23XڑL 00C]]^`2M&..=*$z-XU4C O bM (t~Cx>~>Ui>dYAQ|(zʀ,W~mx),I]vx!rY `K93osm<;ƶ).˅ˋtS.#`b0rJggӦlIGh> ~֯?dFF9vl?%%U,ꎞR.'%eVz'8|9mƍ`YCR Inn ii@Ȍ\7-R| 99XlHf3z!^B5p#ɉw߃(:sJsxxe+V"B0 ecrdgGS$, B.~Y6p#II?Cy,lWrY m`@ -M0lRdBkџD,LCuy ٦j߅k߶my@w:"-@0z}@.GMSSi뉈``if&͛/ ""6GILL@3ûuLśBcqO-6jD P]]1q:$$[f j^c6ziiY$&pDc2taD&eYAx< 38MooDznr,윚»u)N8|[u\! WwY ,9%gkry@pf|NGe`tz c;衩8Oc=v{$47L[l3f P `EьDF`6TTphWA~:@~#GN/9==ltz{QaJK7aG< (PSsY^z!kZ*&11 َ^Є$ii:TUu366LOOݭgD>]]=|#w:]pj\^[dff1—j 95Ia/nmm澛O['*0'g6}a&۵U/`KR.8uԏL˂Aw:B. G"##裱:t MSS͔iz˷kMmmuaEyX,6ZZXtzTU+ 8xuFGGŽ'?#6Nޓl -ܰh0z=%%OFUuSĭ55G[ڢtYepLIq 7|>&&s~^,lݎ7Gƕ;څ\^C.Kgs]ǩm>,|s#'f6i<׶S9&%$XYf@,\f]eAGw:"O~jAST(hh ] dt:P&**Mv`0ij!"XFAU'3AII9]^;?6mnE9N_㄄4 1hVBUXHvم$$$a4Z2Y*^!Zi_V );O峇GO1KɣO6uL.?并=zy/zm)sl:g$$Y͒Yf@|,\~nwIDnn@p:|Ng& s$(4(zOF7bkA; S;v Xn+H$IЍKrQQ&v$ZAg7-b7ͭ*2TV]tz DG'*'ZKGGӂ/v2bc1ShQʊ(* R\, L܋*ŵΊmiX],LD ka ,YeylCfJA;!()DDsj\.)r__W؟6-!!@^#G"2yGQdDUOH\\N07]z JK˲LM͡Jb% Z~fE&z{6)))" s LU<<x6>B0 EC啅*=YFۯKK%9-+<_rY.]eJ`ɜFMX6:s Ce^$IpYYx۽0aJJchr\ Yt `G|LQ{^P^!$5;{g^ry 3ۃB.ώ˳}'[f@,\~~OƪӷT@X$XoW?rY0mfhM&3%%XlLe^Oyv b0ٸA-BybB/],da賵;a Stn7r90k[.Os |ȅ`K̅Ŷ@w+x3OJ慒7,X)&JKbEFccuhlt&6ZZZoHJSS-}}]X,V6oH;0 t`ic(.ވd e:YǜIFF&'Opg/4$"I=Jma\.#pGlHbk(NZ[n[u \^+,VB. kO?WCPۯzcUv̹z;~C]}+~^}Yˮy?<7#;Œo:~N:{nΖ睿rb08 B. V;Ztl6;ݭ[vJJ6a4h dݪ\.bٴ|F3==m F~? ɨJUՁiѿG,م&n7X`0E4534}DIf"""Ѣ偁nꪐepP\{"jdaָQ9 m!,Zac-e HII9BG{;GgYRCr#Nf@Ȝh9,8}%XUjE:au! aG^WuV7na!cYejbQ^Bgg˴v{$%%0ևNdf؃,ˤfSZe Krr>#Gbh?ul&{foff>qqIe Շf. aڴc Zzzh_ttlt:m㴴4մ ,/S Cpul۶x~GJgB.jNzڵrtL W^>֭8:m9t-p0w(*Fm<,2NrY/'swڳy|斦S %I"/?.oOdz'! :!qrYpzhF`K DY Z a1ꡪkbz M>N@UU:p<*vS)Qϑ9bνO_<߼V@4JNQ w!{n'O䇏}O\?Ogӎ|>u}|2_P?[s |ylZ_7>'^E_ 'Uor͇ikʟRX8J[EUӗ06ﻏ(.fw"JYQUTU7x.z37boO1eO -6IZ(#1tbM\AL81nFX=-ott$b`^ƍ;뵔a0ٰa;qqI9xHIRHLL-^99DE*:Wg99i7TNFRR: 8UUa||3.gFPPiRYU\47c`!XLMQ[[7}3D|{2I|FrYӕW*.Ry7>thLF}CE;Q_W֭[o%&6W^~IeNW.`Y8y׿9"O+J %\ĝw=73*p*^:1%%W?yHnY/X8,zrb$EJrԔOxq_oh,<{C7y-R>??vgТp_~QVT^?-J7eR5^&_c܋KHɈ廿(Ef#-uTnr7RTx]niaݸ#|獗OO85z}vV?A#_, mB#O~W%QPPfxxNY9y18؍cEߍNC$TUlIoo7GE@Fz*!~*+ϚnwWND*vv璚NWU1zO& ˉK uYV_8D~/MdrHB.IV\> K~@{{۴eJו wu78OY ,9 #vxaÆTT/18tu͞Gq6k߸wO~[g!)2%ڪ'7LNhk p ݣ^]2.#n_'xe%,ɊN~,ILoCB$tW,-r7N_-'Jh D$ 5RPuz_:?zi>C~UUt'l6xȾ&F&BEc`}~ i|>s7O_ctLn$I}}p2M wⲧbwuj1f I3\t+GUe*Ϥ4rrJQ+p:HHH!7PUG211All"6h4׉^]|>bb1MS[{UU'>>)&^f0@Q, ݴ^bR+ x ^ =餪*n8͵-qA5jѼÿ I c­^rn_,gǟ=7|3wfCSb?!@ Xtp_g<׃﫯%\ġCILLl6ֆ]w~NSS37x񧈎"??n]w5?ǹ y/G1::Ci댉 "Iop&>> |Y0$ rblHc#=>iCӇ;Bz>ڂ$Po=x|0 /: ڏ߽츤$ vyh]mDAY@U{y\vP?^=?vMO*g#x{*\֙`{gK?j2mjvsޥ4`гug!Z5c;5uZpaƗceS+ ,XeSw<::EVV!~cr9-&1Q{r[ȲLVV>EEQU=b~v?^A[[#-*S]]1krLL<ys-7sMYgCד_JTT,8-qcئOIx<ZhmEܖHLL"G,vŎdh4uHuT5("ɧBimZ!F-_bۓ3E@U\W\}WSSs<^~߈-5sݥn(~n\4{+ݳsm+dSON_!1Gb۹ y{ve]sϽ~.))f׾c|Sδe ]H* ,E $ȋ3>ՆìGuK〇a/YR^_imw{Cm^xc&q26E"Ǩ=Oq_uىW/bd`}?N,|nzTlhң$7ȏ^gP1c~ɷ$';;ef_Ԉ' kiгrYfҐUHFF.^}s Kde沈r?.֭ێͦSUuINdbb[˷NС NRRVH9uee!JoM&CcWUElu dua*짿3> ⸸D""""PH-z~깱vܜlOUU lQ2X2M ;}P#8@2SǦ~v,IҼҧ@U}V\6[|`r%TTpI|3UUi__}+rrndMzal6? |{V\fY J!Ҳr*ػw w|sN9۶m!))h$ 6ǥ܂}= %+9v&M{89sA7Ƈ._imphw=}{{>Ϟ_Ǯ;$qׯpkhkVڳ\dz{s:O?BZZ=Њfgc0DPpF;+cg36"X,H>lH8 L‰{A;S*UU Ee~E(*>Yy}LLzq\|q|>ۯ^sي=I9#T˫I.߰q[&S8mۿ_wf,ǿYJ$ޮ4NkGQKJ9VUyZET;m۶a0O~gltlUY ,+)k|;رcN`(Io{':: GKioBv˂#X~FfɊ65vG S1[o8m$_ݼf"0 4Tucm]+>˂U`d3QQq\TVm"**s l6nJU]hNM͢d cp7PO"66LWW UUMl s g_Q& x ;dRPPb Oss5N&pN>f::N/j'11lbbb0,YlcQ„d~BBQE{pur t0:: wO<O<=袝t:~?{ǟwps뭷|c^]}=1̉3gYJf&RRRioo+ʖp'_ s0PLnmzEt*g.u_WIINd6t:ٻg7O?TU}ֶ| @~{}FV.E`ƙS@222hll&>>4kZ׾}?+JOO/z@Iihh/ΝJǀU qfɌf#<:\SױZI.\Gba6[YnVkCC}TWW 4 ee[Z RSs8[ hQ塞l+9x<\.'@x9Bzz6:ôQZ hߛMMճ⌌|Cr.,ZcFJ0SR( P7pVIM 99HM k9͆s kGj(qp/ypW&Yش?ILL4_qb6y{߅jrf;mX!W-'ZrŨS1o:)Sߛ&sc\uk/3OƠ0:$""rSÇy|\tEW޽{Brl OX.%`ā+ ᥗ^۾k~۷1<_ҿ$^ 3|_k?c^`u;s"Ȏ1W`o5=E _K,\"EiVF]]-44 }푔mh4Jcq˷$LLLPQ6[۶]JDD2:UU%33oغS n~;, ֡׃vvPW7w)l2Y/b1X<99$&C~ZN/J%55\L&)+$TU emh+?EH,`Ubb"\pԝ8N$ ^ӟ1Wq_ ,ork{)?Vx-[6i$I?;$-񳟽d!ۉrߍfh4RQqGݴqJd>peezkߏ$I|;chh~O 3wm̛\)_g?4y-p,L͹<94m)Xtpͷ[YYYٻ'0_=_.<~zgfܽm xqyft\!wgD寇С#u秵?yr{W>%@+#8u\ ng?Gq-`:9x{g:muƋ0fp t-1qp^}XeJ&>>tzGI&t:=5u}Ł|˄"Yn+za-h&551'oPP)x'DOObzyy8qij:>r)fz46V311?l2Y)..j @UUuRWW;1V6Rbc1-tYo|((~<7N0mm Q bͦB/ǟl6w\pOh1{پ}_+wd IDATx5uuر~N߾@q_`M<8=_5\{>A {/\}~~L&ӌt{GΉ웙x%F.gr:GHNN@C_[o3e_A$o2ZcBeϿ.{;8x?lڼ{?MC8眳UPe9_x{K` - yzBeLEXK#x2ʲI;{I4rI:\Tu/]dۖsv,ٺE$ ד}RNdd䒕U狀bceo`2Y9ˉ_]1RS3e$&]$7bHwZmX6z45X֓WDllB(TU㙠y<&SJT#yLV7 TUEAkkê*YЍM$&&̴Crw_ί~4(J(z8(wr7>d ;c=GfL׾EQQ!|{Cg;5g W:{XrY*ƛn&ښ,cjsIiPWW;~)/_ǺuIINܼЌ)Z4ubb"^w~>NɁ#϶`Kg'F.wQFsy%V/-DG16椲r^),\OBB^ JK7b4j:CTV#+H@FIҡ( #%%kVҲCvTU7,bb;vĔV+YYEրXVz47gbb7V;Xv`RŽ S_ Y^ES*nc0QűP.U i"EGG+g!v˛o殻'?X,fw+2::Ͽp7ccc;v|F_SSU!##|jk9satԥ=ٍl6ux}kkqvnsq;NVVW0\FϜ>"@.&oUTpŗs^zGg*i_ҽL{Hv8U-g}m|`˃g7pQ xISD AyVl6;TWDef ee[Ɔ C> c Mtb2iz^0 tv6c6ۈO$TU8o_n[ /zz:O-V"L&K(/禹f^b911l =* ==-tt̹ሥX\گTzYؠ}ϸA孷v311?~{_|yƲaSTo.m|woYdY1U~N'裿_<TB{{ofq !0D.ymlg{C;w4~fYd5rM7Ʈ]/`0ۼڣAf@z<Ão%py<'LxV+K$xqTe@HLLp&Cbሡt3vt:2@x=tMbb9wc4d2MnQVlzGF8~p1fz񸩬|1S,롥e~b9;0$ABQvT3-]rWBrr& -#ZOUen747Nr2l| @kk<Cݷ,<}K S[)↓2 0:o!j%qv\.ݳ{v>B0 ednB2!FE7Hմi1THD^^)*ǎw|JJ&Lnk'%% ^lرm%99YVhoo **.W >>ˉfP]cX"(-݈NTilfpZdguH롱8^IJ^'?(m;22@KP4r`(*Hddl@&O-ՅD0_3N{{#5UITTGv{&Ŏd`0Itzt::$$ ^R(CSQU]zjkiJ'6y{>|Ȳ- w?nz.R~T@s"Z`͹ r&66Oivz= m`/@Qz @d /gGZ @ZLY ,9 uyL^4 2:IbgN$V}.O._m݂Տ61,oabѣo3> ߠxNMMFFA`I㌏wc6[q8PUe `0$28M]]U1nfsF9~`)d2񸩯XZb6[- ۱li0Fq8YCre,>=rV0$ODDVɂѨG )/rM4xyGB.ZԓZ°/O>l-K,K rÍ7y^}o|(/~sxq˸KHKKr$c;2,;&;+w<kmvl<.ϞoM{/&< {rOaOW ;NVj$**mF8~3Ml!::IJJGUprr)/߆6Ţ11q{0̀,9rdOhLRSsѹ*>Lu!ΠIܢPx&XN ++hM40<7yF7!$%I LV$kZt|KEbbqq DE`D`41LH:&q*&)KӊhR8i(<֢%Tx(kEQe?,#2*|></A@1J ߇Gd|>=߬7n6$.}ы˫5t.z>qWrۇ>/S^^ëuPZkU.Ͼ=/@ X&\.MJDX'ɍ31͵Ù˳#ɿ \rsKQU8_[[chIy6, cc#lVFFپf+.abb4h`0222:;[hi1%-źZl;vM,"&&&hlXNK"11Ї911Ӽ4kHAA9QQ  @&55av\46ghwIƵFILL""^od2PQ N*TgF+(/#^< 'p:q:ZMȲ³ϾCYsWZ eVϹŮ?we3[nn\\z'! Bt""*? "DD{-.{l1[ojrw͋>3fyg>/!33TUJKKP=궃Δُ`\vI:^LH9q3vO*p*3k",r8Y(Ұm߿,[N'344٬p:<܅/T("118@Zgh>dYvʰ{N.]l4A80Á;l63w2z'rjt|bYӑO||ϯl07o )>BB-M!jjJiiilҲhp%]~;[k9Z̊fa Oww-- tO^Nnj^z!ii)տ| |k&,5K!{gkB. HDV\ 2唗x"f5|4fN:vK(*eedg瑞ip7ii̙af륿x8G"{JӉ>Hww͍>\Ls8nc:7r9ca,zrx `SHTCB.G.Q#!JςHlN6LwwFFe?Ā^pddɒKnRP&_րz iCy"b(-;.Bjjg_l6eHK$##^œ~CZZ ?=%5I?zoJ>\ v]г Ѝ\ywG\.!ÓE拱lN=v@a0Y V\rY:d eQQ ˻Ae?Ā~gΜl_^=ZJ ^…+INND2˲WKrrCCC!33\1""Uk\Vv~f7w*lHMFF,{ SR2匌$& 觺h\ˈWK{20OyyѴ "'g )FO,J5-(hoo}?,=B3tlr8kCG,b,vc)#rB!eALiY\C \G #&99͕x ՞11,[)/gn_;rTU>[ZSE7`=r0LXΠBcc%0rs旎1't-lxr?JWWUU:nIzz:7oEqG)l!'gsd,A"]XCttPJw5il#H|B.+"Ƣa7{lWa2Y L)') N3&Xg&(ǡr{!ڈP4,J11P8jlA ˃z'11K`0&А75++sU$I`9s$JJp*R=7,c IZصcj+VlxdV}Y_L\W(B{{3EcgdEDDon)4͟DsϡA00p"|-]Hll$R#x5މvS__FKHi1 GS)ojjjl̉Xtr8!@ 2$.ryaixuA)n23X>' I00sScA) wc6G|zTU&q Eqzz:1 S+roYȂ+0cpG+JSS  '..hNuu]]8r^ (`6\}\VumAGG55c3 򖒒_ɓ=ӾACC6S]]̬Ifq;myޟI1ޜ [LZ0m X, ,]ƕWEU%Z[(.ZG~ F#R986 jut:99cg$% :qF*RUU>uTtI 5Nu,ݟmttQYY8}Lq݋% |P=pc~M\,;y m'yWn">)V%sS76j<+q:o7c 6RO}Ɏd&婊d,pUB.IX Iy/`Can)+22rY`%vL()(I\\"YE\bS6"~`4Fx˞=Ivz' %%{=lZ~檪 /@v<$GjJmmلg7oIR1 I>i`kɚaN^,3$m6>7}0R.uIqKRd:JKwTʕXhk-[ƭ~v ^gŊDEE"ܓ9Oh$tJYQtF[iWUa`ʯz@ OUqS.y⨨(rrd|VUq8ltuRSS*R]&D(|vckg[˛[p1,|Bi _"(o$sHrqY L/q]{Wq.׏\?|Gyq]{nzsWTuqI?bڹϗ*N8;<˚;H+(EȲuvE/vCIA1+ i3":ZZb[TNk^˼׿#z.~} UW]͆ @޻/o7TXnr{v:mK|e ,^}ƺVi xgGX- $˂#pm: Z9e ь:@a6jk+gӑeɓu? ˠg 1#Ex?ŋW\uUv'%..\-؍tt4QQQ ]V<eْre!7w>1-zBmzs}_e5$''q]RR2U]“7fqֆZښL7U߂ӡp)Eqj N9o 7y>&>)7y/aQ@[^{":/hzFY' N/oا\ӸN̒չӺ /!:9trYcG/`:\(}8 \½5l>kU@604ɖ^qە !Q$ę4u=ntx駴I$شx`x8zZǫjmvU j~ggiˊ&r95VOO*x":u:Ñ#X,YC\\If!ÇE]}ܐΏK8ՔԣM:zGHȨol 9So{>,]Y4d7d8oNd\B.`JL9TΛOuev[K1YPa,Iݿ;NO=Sgx5u3'3&F75=5A aQ UU)n]c2XvEEE9[ojuu466?/}8N-^|7{.sQ϶~@NSO9VX/[ߺ e޽|2} i1f[JZZ6ujt-fMIdY`0b(*Cuu 11qlxz6/T,\%S( MƓ%vU{5 +6Ha>JJc z<, 0L2EfS__Jggw xzDl}mW  ߇%%~M!o~ř.|r9l N9w ?*!-3fxo>/>,"wOd[zj里cz;lp,Z{9R$h~q?Y~.Wx:LweXy}m-IV=_(߼Kl:m9=]GFl,gCW"s3\N5%TW{Nn'IFC@볻Y}2λr3TEeIGo嬋pW5yI,\ɽ?y&h]`$ͽgQ"'7TWWp:_s~u]ݻ)+-e…QyAٸi9Z(-"^~{|kKxPSbsW^u],/ ,7/&33롨hڍ`dd4GH?ɪp:픖!Od&!TRbLgbժc֮Z&9#v+UUcNLF^Bt:#"IROeeȾdg#))IQU/$A퇞O`0959(700@CC==Gi f4cgݮrUU_o{nysq_{"w **y uN\b47t_)og]_Jmhǜ6snwěRr&ijȈ5kayrc8=Y L9~'e~J`v5:H# K+Y]O$v~\¢Uiow% 祿 w `UD0 Bd%,ëVzج6(=:t I +Tz >h˘G\,p@˩~HZyx&Ѷ?3^.{Ȳ hhFUUYb#fO ;(+;HKK=aDEE e5l;99ŋre$t:-j32r̜^ 1 XCTT죮EQHK`£𽎪tzZ[)/?@gg T* vvv>yy]Z]f2हyf VYWQ JMM MM ~b_Hd9$-Һp ~yUՁhr8촴zH$oJCmK!G6%hn?GOjF22{qK*jDqlo!rtl,+[C7?ftjʚt~"}ʹ;'3_`985mFNOJΩ˳!2\v$6 ,LY>DdztC,˾rCӓܹK0"ۭ略ū,XKY{^$o=)줱10wŊuǧ"{*ܭ:e$%"I2ԭ-IIIGFJkv19ERR gWUp:5\H7 ⯱nX,n8NnػarY\/gãsѼ?_РqgޮgG/s<7{!>~g%v>{>Zio"C@{K1u>}و;ge0lCf@0mdٶd\sΧtzjuP fO+;ܓ 䲐# r艌4\zTW`4XD,xHdEQYի7b6[о SfotvmbI`ٲTeMS^^Lk5'gUuiiTFWꗲCUz(){HQ̙3J? YƕGIww+55ގ@0}3/3/|6 / Í3opW@o}S~{~Z,6᷼hO?_=eU%?A@{?+ago|?Hw ˣoR6r9L`ӂ TW=_ t.<$O&-bPŒk һwsMMM^$a12C{u{rY8R_!*R]Hr$Ij931llt+ћBU%[((@-'33 +xIUUţ?99DDNp8in,`4WwUcɷE $+u%[H) b@l !\!CN#==DG[PUvJimm`ؼ\0F*uSX(,XΒ%GM/Q[[NYYadbMLQvel6;MMTT*_LdYNNښn!#c>9e UFYIG)[,2{&iZs6 3P M=< PXX_.".]NGsqp?{wSϰN</!2}>|L& +P?UU~ GS^x .*CCC|-|q9g⋯;7J22҉/^ĦMq뭷c9\{5wO~r 6w 588ȭNJJ w}EEtuuM~aAqKL-ep^!adOZAx1:,&1Fv+p\^[aeqL^"RS]i0` cѢ|ݓyQ$""$:Vm6ɒ%뉏jmKRWW6j3˛OddڡM~]T1BYJa(''1gNFm z{;& 8f)m/]IXTh4RYY|ĉ'@EE%'?܂]~x4**2o-ZoC9s[w*;mXt8a1= r9Y L1ک===j.gJf#+.B.-MffyDEE`tZGZZ&K=u%IuE*k8$11AWUhdm623ظThzSmBQ>*GwffL~3o[%kAjv"32rHI`0xR^RUU@##[Kք v-$Sϰwタz~[W:C4/2B*> :9zmN:ݝ)De1}_t #9df%66p:46a6GcXX+iErEkQƒ$!!V*vwp8ʚqǝ{{ y$餠`;#922%$%~v:I-DGG#}B. SLTGTQ߿`Jdc6#ƘZDDlˡC2c( 4t rYe!}0͜9'yv ΀,KX"TUAQTdٝKXBzPwEuՑxoQwPCAcDEY|&woIJuIi>zzz&||,rr$}t *6fJp= S{bϨ(rPSS?EG\pOO''G|G?҈|&)d{ IDATrHX`}%MGjL.0p`", d7B.H=zͽva9ZrYe!%I"66t]/4lwD,@v ghXU5Xw?m)F wpxS#== )IF@ŮڱCEE!->6ǧ`0B۞&.GL'E񾅰uvzQN'\5.bxia8 rLgm)˳=z`SI5*ucON3rYF-""tRRIJJsSpG&}=v c$Ӊ61z S$ab瓔4?ݕyy~YQ!>)AsC Ca*Og]Y' Ybpx׳llD#PvVWHFnb߲lmW4{stߣW*}1/ѨGyo[=l|}/~oQQH|R4)q'`%!yuP\*;?-%>)psyk8cu2=]/TޓeɊ3BW?-"_rxD/`9'SY (4w˓i!Y#..$0"F$"8AO{(p`$%]\4Z* Luu }}c XN t RKUUB Lߠ IKKBQ N =;3O\3G0j`^fEU))cJ]|zJ*ϗc9HIgGl}0xT ?b| WF["-W^R-;7߾@.X˖oOHɁ:$Yidۖ"οj?QlV-MGYa?aNhK$~{lRG累>a%,\cqu'pi63QQ7}3H1P &+?ƚv~ _"3[_l-2+￾6 }qE Jmy+s^cy䲿Rs.;[x9n3'+~1 \eY L#剴H"z͑&BHh#I.KNNyNTƞ^ry2m32m[YnI#T&oˇNZeL(,8RS3O"""^Ft~Wh*S?Ū~Cג}ޜɞuB+˲ár5˞킖syhhK;)dffc$`0D`0<{UUq:.a_@ ' MOiLOOw==vٽYP;NśpMmD$z=kiiw?d}XKڳ[|a!Xɋ8p'>>m~zhoA'4To-h?_Vnå5uXA]E+$vj}>7By~;3z_w9YDD% iX]UceNY*MkCMA$uL&'ZY'ذwVڮhi3BO^O7Ԑzʦa\_BGkzuOۙs+o[cK\-Ȓs\RzDzڔ$eyzi6r9xw>nӗa27?f666?(.?o^Gޢ9qAدA<ryvu , }݅$mxn-rG1H=xv\L6''!>2 Ѵ߽i2ߔZO;* (nRPYE?BWo=K}Sb8lA'D7`0Jbb f8c펲۝8CtwwS[[FGGKai0F' 7 uB.F>[o )k?{;q8<(;PiW\D%ԟ]Yx#2w?~ \(w\ӹg*i77gi | \*-'Ӷ?S!Ď^8il `IGIۜa'Kh۟p˨]$qe^{rLNGDD$ $&!!Ah4`4ʀEai,nNk'?m׆WkȲ;\[Tl66]4TԳaΐuu!kk61rY0)x`ǿMog?tR:4%r9hau,"\!FHׇTtwejKh۟prd\`0Itt F !H#Gӣɀ,+(/E`KbE JeG<> 8۝C I{{ --A/q\=!AS8ֻ%t}A^] ˑ<y{(n9|r9\`ӱ##px j1oi\mnr]0Q|ٗ,<)#e[J*#Z\!{Ha-%0Ż ٧L ]OĪ*( ݆1ࠕ.::lQ`F#re \&"cItp"@ RE/ <2B9hQG{s#%U.Ow&&&d$IWDw+˵"! I݁((nn288OOOtwwx| \r9ȲaB.dgg{~[]۷'Ƣ,z8r8 ,Sr8e+3'K69UOO7uuؿc(U1@:\@h  ?b@ϫNMf@ !g\$;;d:Xt oYۂ` )2Vr9.>:+V288@]]==gv:.voIooO@b2<{Ʋ1J`! @p8yO()=&_!g%^굁 G"B0 )daS _@II1? UՕ׳%I"N>'{dЁRVZG/'>!bLv =sb H4y| 쏐ˣ#@'Cf~ ZaFRNӾUi-42)Hކ!jyhʼS[O,1,fE.{FN:d飼0g㣪>3@ @wPTTĥZ.hh}\h[[#uXwmqWV`ald{G2CIH& Ʉ̹{`/uH$^?~erÞ&'5'\v ȓo7wzjW0kaZ2o$̭ѽW);zN숶)gnI+)ٯs.;^I ָsEzpz@/71Q RFFݥ1jjnܼ,ќ ڦ/ض@n*/K3Ib"~_~>#*tiu5ƪL]~ŕziJE.g#Tz Zb^}*,(PΝuۭ$nO]u;QR@;T}b$}bv(-Z}+)ٯkv8טm}g+NyHŒg1[Sj᜕z_jJ^)sFG{nf\ߜpN;Hܺ[1ȚIJpY"`TH$>rJqӆhۧ ]]e@k4YeAKE%U+W<|ȡZ]\|V\-[1#ߟxBPH|𾊋:\Hө]$I m<jTiu'sZN7J3J_&:FچO;+wgQ]ՇoSdٖqfX[7lGlʐp9qu h ZYe˒Էo?mٲ%#E䣃:#Yc_yϒ5iovyoۦ(3V}uۧIIڵk.7x]=VtЀ~uև3>w"ˉZw,J<䪠/:͝ƞ=R'unY5q[4w$xF 0G4?\N0@iz9eIҵv$?A5|~`e1!7ܱwOg^.c]JMq]믿ӧ+ iر:󬳵yf-\ .H>Zd"D֯_-mG~ $"۪9 eiKkET\X&˪\[Ԯ ۖm[|OW.od]Շ%Kn؋eԹ_"\Tvd e 3V;F>-:z htq3%>jg$Uz R\:,T Q.ɥJKK$ 1ͩڶuk"מp:ӵ曯ȣF .?P~y:њ={FuKCE IDAT*[^:mR@;VJتJ1ǫW+WzwןG\'(XҼߪ4ي˪We\~`C^2@ҎeIںe>Y%ceۚArKj˒TZnӓͶmkdV#˞$IGqD׿#G*;;[:\1qHY6WPdۻ_qu$;_~ىi_״wvBX`fG;-I}.?@Y*%X9t<Ӛ5 ?7O#F;\}M5t}VVSK.@˪<|Ԅ.Iu'i~UUpUњre f \*eKSN076\4-YX[_lTQQ=h=ln%fߩi38IRvvvBuǞX3U˛5@[HuۓUل-^?]:Zh{SNgzKLO[?T_͛7kڴi/Ϝ(5% $5z p@cr˒TTK.?^Zfu#Ӹqh*//opY.X &~rHu4>ic^Pڻ!Ǟ~n\@O?8yN<mӟ<M e.w \zYT .p9!T0h50ۆOe/3?Hy#Gi֬OzJuՄ LyMG )hɄ uKv$Ґأ _ToG=Ofgf{) wK !`upY.YH+V,gD_qaW#FWs;O#;Liɒz橧ZmY.<{}PdYVP^m=ė]l/p>@+;[̷1p9򦴤D3Uo>Mr 4cTTKYYYZf<׫ymc4;r֭)>啻+ p}#d)D9*%..Wyg~꽈p9{}`d[Z. x{ܥ1gZRrG# 6.Jr{]kީ>-z$z;§Im;Qzue'󤉏?њhf=ɭۛO>EW[>WZTޟYُ~~8hyt'ʛϊy]c^~:|{tҏW0 (.kOήK;u?F eIsZS'Ne[z~͚h]RavTek0hU&VX2rc:߾\YYY iJKrԯ_er^gVc:\s/krV#~̲w$5f}"cTZ\Y-ӑcWr 5蹅%x 륻\o\ۢ$I3ڼ.G}uou!\0h5{^ppirD{ %ɲ,K+vP mYї,ɖo.7kvLeɲ*ϵ{j&X>]ճwmZ#gjtvc(rO}jc}XZtOvyN-Yr^1F~S kR+J !` .2\NӀ.~8m~YUoکW)OΊGyV% C>r}}lK7|0JNɶOkurlKiI:#( jMvY+u 4pH:c߁j=0i [fAhY ..7=\nor%~dI@Dx# SqzpߣN8@/~rI>hzpD"/VWM^VCvꝗ>mOҵ8WOMI4ݥZ*ٖ]suƅ7<|szq^tK?_Nz[w?sͿqu+ƳU>X*tx?xaҤIVffcYCrrr@ ؞;wBIɶmcҌ1{'HR \6E@~;63h }{y-_ܖ cDb>5 E[ C2@޻LjatvBlQǎm17?8ϲ|˲<+T!۶C)))^0t322כ4an&MTϻ`ЦZ:\>Wr=GVeuvg^hT~kr[%\@ipdyL N>[|_h6|Ve.ط0hu&da=źJzF kj?9Hku-.$/F+4ᴇ幕'6nnB=z'ЇSjќuS8^wIJ zvl-$gkzr$Iݬ'WW岧Уkwd>ieV CrZ 5v Ri76un=g7'f2@]T@9f[-I:6sy^c$ >zWϒ4|~b;v4oIFQGӍY[+KWn z>F2\ff="`3 jf<[@6j7Gi3 ]I~m\*x~qY`B-RRt}j fRAnߜ'H'g鹇>;U>#[֍;5z:c^$~P]rݩ$IW#taUP%t<i~ 둤rW;z8-f×3ճ9k0dq5sZ32@ipr~yhkaH%)6lSH?_8AӒuڸQW:pDSK?UEǕֵh\yXjh_Վc4~zOow/?A\{8EFFC__wUԭG&>3MZ3.PT:#> J01@sPB[]  1;uJxho5:5gz=b?_J KǙ;km%wPşVEyHtȁZr?~s[]:5ه(X>~sIqlK' IUr%*(wzH-3: #Y=TL `A3-)J悠lKPJ6 Nȶ}UM;35Y1e[ҲkumIO:0z̪_W}U}[uWC-ےθpPYQߜC38lK=ર[u:Õ/DZtڸQ5Y앬=W%m=Vy_/}v^6ɲm7J|wιy4zo9'.uKo^uz㎮qkI $bKאI ɗGT0h7.G[R~tOҐIO1rÕwWN}j~{?GeAmYդ fլ.%ը./գNG. XTٖrWQݱ++u葃ܨ]Z&N1Ǿ?o$= EeAO6Q:sb3LK歖$zQZU^dIo?J/u$u˷E= $Wkp# ꞑ/<:+UYYP̻vp@GA ]hjyoJyŕ?V'/Ikwm+*ͯǶw^vq|岍mWoS-M{fv~ZKX]ޒ'>9.IlG,K<:K8tTFs,"V}c#7Gi3 ]I~m\C&rfO_Ǐ֋},tE~~tҏW0 (.kOΎ9^ZpJz?>|`o د>=GRRA͐p@GB p9"Jպ: cG/Q|ZU{>U-_N'}vm=$VWTnL}'sZN7J3JN6wiշ[tĘa ]m\C%O+e iIڼ1G==[}7hߵ#ʐy2Q3@jp9"J՚bk :maD6k@'I4g]rK 3Fsg|gg?Gs7GP0Z靣*=h*IRB&)S"1g:"f{APKVVe7vP@Ltґ:5Ҝ]? gI,|s}Z}h dYVt?ʽE,-V7Ʈ5-iۦz剙Z,Kv1r,23'۱eS]x<9qDb[bK tlZYPk-.K#\RNrKšn}R&;:aTeto(ֺ܊@"InMN92}3ɢ{uX3IyZU0Kb$ժlefQfz&ctIvtD=I/7hSAnOkkfC'ɫU|H鍥VII;ޫ_v(Ig=Ed|>[+f鑉kȽ2CB!W>o?~[`X^wtZr~񷟫 XOMynU^|)z6S9B+ެYqWizZl<=zwuQg>j?uE>9KKپ%kk3EF''۱D-}%_ǜ|P^'Ne[z~͚h%taڞ?|W;ks_%iCt#>P0ѧ=NOx>sWGPvlnU[V?l+\(PvqX*P)CHx!32}3rcgW `gto{cks׮ʐ^Ѻ۔]$M{nn.}R'y:_;w$z uH^=/ Wnڼ>GN7Jコ@g?V勒e 7w~%c޳sj~}y3BҺuր!=bYVQcד'cJ+4e:rZ0kETU hԽN9q&{tOkǝr I,K)iɍzgT2 ]]ktrK- +2hh2&X* tTZY)Q yJ +-TO)%ۢKd!WꖞҪMRteY**(Vn\}b=5w:4o*h$۲k{HOIDAT7'ߡ_ngKmkۦ\zu.-KkϵBmӖ9-KH]#F-_}.2Vk-疤,˫E3:a=B m=V.)U -ipz@)%48rCѹc[-ӿ:~~G.ޚ'j[}Fp`f"\} \Vw%۲C/J`H^Ot?RyiPWlcK>Y?l'g?$IR-lUgrzu룗w+TZv2uzyZuݫ\Q/=:Cwr9>[ewҺ̭>7HsFtYYh:Am^|Ϫ,{ovhpz@/NY.p@SUVӤIL+''***j؁@)))=w mN1ƤcҿߙN @ Iym>Gw'm8gРA#W7=՛{Gwz9m=vm e(kath{w.9w+uũSSl/)N iRj.7xMݖ}~,ʷ,I~?XZZm;A7##[~IKK3ffҤIuUE3V₦RU%b8;^w힢^K4R v!R:s]A?ESW4e**,OMG׳{ Gw.p@B!`jRp9rzhnf߱XѿhъX]kDV-Ɖ jw?5{L=FE_/fees'4G'z~{dQգWeoSannB}/H)i VrY ',>AZ,+oWjii寗i_jǖ||WkRgڋMs4Z0}GIcږ .Wo80 BfV-K7Gg^^UlwҺ̭1Xzڶ,jα*҆&˒ݝ W@[#`Wu̘:ʠv;/=׿TOZOZ\ؚ6+ӾrFv7ޮ/gj{Kcޫ=6n5λt̟뽮-p9vL =#`vO\-=U&59qy/k=rJUsضmLƶY1&VloVo[-_Ve7?\1c+7v@+*oB}./̼)ArCXi7rb!thyz $9c_P ]"`bW To[_}m+#vr5o_ ;}}fe<@ rZp~@׷v<gW/ km~;_4yleU;Y@Gp֦U764nJ{yKc4Vӗhl[Shl[kT97~XZr=Ǫ547\n ZMe8܊D%H2@8f 0hU@b޻m=@b @\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\q!`ąf@\qiٲ,cYi f@\q!`ą!-3 .M sss$9cʌm-r>۶MYYq' f@\q!`ĥQթS'[,_cQ 洴4*`ѩS'|FeT03`4i>|ȠzQffҤI1b*q!`ąkgXm5@BfT0B 3 .0B 3 .0B 3 .̲,ӒёǞCZH 亮گp`ĥk0۶m1FpGheu1F>T0w8*+-ˊZnhY²,c۶vg&7$c۶)//W L3  q ZZq6Da˕{CPhG@ Ё9[zF&55$%%@ @EEEt`o-r]V⺮6mf丶m۶MEEE45h\Kk6ُG,R59--,_<q)eY&u r]ׄU̎gIJJ2jm=j̶mWöm/R0YYw`ҤIf&##H0w暢"SZZbvs<),c庮 ~jʞ@ mGdI B| M$`^ pU(B8!5.\c5k>|ZYСC͖-[$24<ϳm;,ɱmےdB!<+Xvy{ke5WJ1.۶#۶Myy|>Wuy纮8NqT.QSSK\*#33Ӫ^ɜ$'';~q v ]׵\׵<ϳ!r@"̱>۶m***L}  sΖ뺑vԉ@Z@YYq8 +**$󙲲2/V<|pMj7mGVII-I:upD>Gfv% m^v һ-ـDeT$4yL:g?],WWWqF$} . 'ywK.I?|oxۈ|uI$4a^/թAy^wݮ]<>> 5<4Mob(I}YVeǴZ.WMs>2!I$$j*I2ceZ.W%sl.IC$58p8&IeIaJ\.WMs52'I U G }Iu}]2'I <8V f)Ir\%0W543!ynZNSw=GB\\ ggcruqf|Kc;NпIENDB`RaySession-0.12.2/resources/screenshots/Screenshot_add_application.png000066400000000000000000002374061417052567600263140ustar00rootroot00000000000000PNG  IHDRdMu pHYs+ IDATxw|env7DAOx**Sc9z*v(Qz" RH!}wYXH!a_<<jRC !BQY5QZ !B!j? B!$B!`@!B:&Vɓ'Dc!BQM<u"qM4KyF֭[%B!u^' ju0@ !B:/666_Z nݪ͕`@!Bye6K[*SV P/**RڵkWMB!̷m6Ng@#$Hj &OXB^^PXX(=B!Br,mp:ֱA~jsJP+VJf͔HOOW=zc%AFB!Gv %222,aXfI@P]=Um#fggU|>xaH B!Zhl M(zc!8`á>|Xs\aVhc'r$8B!g2%AiVAAiUDFFfƍ!lcUbcc}i!!!`x jAEla-˲6UU50Tݮl6Ų,Psw~J'B!Dm(Jq^$PuRRU2M0MtEQ|2T*(G94M 1 p8l>Ϧ P-RJc/iI#B!8(0 *gټ>k۽T< 8`R=85Msiò,(aiieYijIfƾ4B!]KW2M<+`Z0McYDz"1MC5T(hi})T !B!N"!>-t:E' *:@=rܗG(`Pǣj)b3 ázH߱B!pMӴax*Jv8A@)(**R .Ku]5 Cu]SE;śB!BMUUfÿvze08W]v4]P4MS5MS Ð`@!Bjjjb wVJ+e)^W˲0TUU+5A!BQqahjYi+GVbbb#14%B!ep80 dqeʫRLTTU- $B!X٘W1MӿDhUU((**RJ" CBBd`!B!ji(aJIP'dx&_!B!jfCӴjksWjUTUUJ,Y]Hl0*[vW&B*/(`_r^E3<=B:yH}v(T<ϑ!Bv082TNyhղ%Sr(P0!uBll,[bǎ'=?gnj&uSlj1Op˲U&T2k4M %B$==Њڝ!i(*=r+ U#B!DU-KtWlAu$B!Yd΀(TҢ3 B!DU-v;U3 B!d(LzB!u]PUvm!꠼BQuЁP֭[We%\Ioj/ɌjԶm[R vUuP k׎[*BQ=U#@D(">#&T$BM=tڵƍӣGzEݻӬY2_|%e>f͚1`S'rˈT5oтziӦW!k; BTIK}aӥ-Qw"k{Û5",1Zy 8޻Os2VƏ3>be\|%4mڴT7[nTh"#N !DRѣF3m4yg#G* BQi8>[L%aF, mpo"/Ƹj^zJ׌kn|ۏO>8 }M= (5lp|-n>M6UVjժR].eq:]. N.] dV˲ի e~~f͚^3 ݉9EPPTPп@̅=*EW^Bd8z֖xYys1()皦Ɍt1rde_7`_{5kcEY\˟Ȍ~oSO=]>|Æ !j†֭˗/gذ<yaҥKG6nڞ~ !ӎザd,_OAa;Y {$6ļsX[iݺuy}=:t,3 ]~>}(=3ԉDFbq!!vrw%84p;x}&aVIIIDFFȸ'azOIb"iiiVXXOڴiî_ŧNcc%//̼7ng䐜 &M:d:t(ȵ  BT34O!4M]OhƘ/s>G` i.kG9{xW|XXz]F17yU,^|6IYreHz_ ˲hժ{ ;+а0NW>p:3>Ɵ7/uoU-HKK硇!C,ӧFIII vVm۶!:::؞{;׾ xiL*%B:˾ذ8?BQ2cvA^?ZYǎ;ϝ3R@TT-[b;֛!N'neYhai޽{;v,/bbꓑQV1%%;ws/q>|R+-ZO>[Cnt1q$:vYvm:?v,MHI=ݜ9sɥs` >.bգSN,[UP,g5UҸJ9=Rsa$$$/g|>8_3~8rrr͘8w-7|L{]. Mxw=ReYu{ a|r~血2fϞEnx=zI4er#Y}2Cn}ШQk\6z|!~9?Q++vڕ n^/7,,Raaa?B7 .{pJJ ofo[;y?Đ XhΝ ?јIew߽GqkYŢ P\Mo>륎w9k{]ÒE ޻HHH`zR.dGy)/%暀2UUeْE~ۭ5~_B!~l}rr,CtrrVV Bj04^%Kiٲ%QQQirǏ]yh^Q!gluVeL<9`lzV},TUOAAA5L!B3[sss;PC޽?n,Z|aaaԯ_e6-[T{]B! ڵ#77ܑ>gjB'd20yLz~8vm۲,^8/͡e*OUUFK.&-B!iWaBڵ#M__??ݷ?111%˭pvه1M'?q:uB!DTfAZ?g222J܃SB!Y7LH!BQ1 !BQGUjPLLaV|>ҐBk9.a׼j\!哞!B!( B!8Y0JGJڑ`@!B:JjG j@nn~!^袋]Zg nFvhӮ}"rغmK!ިѣq:][.U j ,RTYŶ[] !n޲BAQG>+G/>~䘢ϯD4h 7nܘs=^*_¦MWՋ}r]wVBZyԋOiӦ ;vv*E44j)OzBTeC3i`^vgٰ'Zv Tp\s #l^i6 Ə~w*No[n,_aÆأb3t.]ʥ=zq `@!Dm:ciʢU露 gCU`V0vMHӮ[ VW 4hPaŊoILLuYtб4Uo~̟?K/}zӻO_\UU 8flvbccy4.b&M7OB^ɻqǨQ RCeرvvB!*g*3ۨqoږz!d$j ha ,K+F"ΠuAX|2:w&,,kzYxQYYYU{o %%yr=+Vc\veڵ5k{XdqBT۷3z(ƏP*{H\]d΀B L9hv9tj {ci0C1n6YIR/R^OeYd M}D(: ϊJJJ"22V0 ^xy^ 5IL$--BFN+W9fyxRSRJY5#'']4i]9x wСCA]H0 Э[7֯__J,,lxB~߭ԟh =`)122]P f73;9tbfZn6RXhQl6j ]~Ղ%4*`fǮ4A AQsZhAZZ:=07eYL>47oNqA|]!ÄBTÞ]#g1UcWN[F}!l6M7nv$_~?džZ ǎ;ٿk9$1T(**.]cwy7CNnȚ$$$pe+ xб8n @ukpyW\ӫOYQSZhI>}h٪CFn*5o !0UPGwSG?kc6+i+hncVĠ$f.ܹs7~< پc'>|׌7|3f|y-7q 6G}-\/,ul^}{}RSSu ,MgڴweƀDBϴLc$ 7r ӇFX`@p8 W19gN^bxl@o-ؘ=f = apSRR8};6~ܲء_0=zQQQxsa9o:3 ÇK7wb#33 wItttBԜ_{1˲XpajS{H0 D%ďy+?祕zԋ:u< yRƚg?;:m׎۶q!bbbӧof !D0I0 D%ZW PR0CœO>9degS ]-!(E!*UYl``+]۶mJ #س{ZEP5|o\GQkW2ѹS's80l&33_Ftt4֭4̀r<?={*TwQ{,]ի+g"' tFff&aT[BQ$4?v,MHIM3gnzԹ˖}UgoN2dM޽=iժ<n7Ӧf_w > c֭+{׬ (p ƎG3?楗-RPP@AAAYTTHQQa)M!jO?(3MQBBB(***3tӯrڵkWf0rxrVW{P4&f<7n~? !L!j9Ɣ^MNnnOqs,]Ƶ}_^h\uM/_7ue!@M4f! x=4 rk5lؐ\p>K-;ݏZ&'>>T+Vbo]t.~كd IDATGz]{tgޗQU.B E&Ǻk;vt:9'1tCDZlɫzK/=ޒǟ̢O;v}9e˾"Q#ڴ.^~z:TcϠ&i6+VЃJ3͵za&xyu-2e 9V摇Eoߞ ~ '_!n!jKnn4Mk~ǰnaCg&44?yd2 8G1rWӦukİj\-raE罸ݮ2|L{]t]ٹMt]gߏkB!D `@Z%Ȱ0O?طo?#wz%Q#+WqҵkY70_|~c}}ם,^WmLK.em 6M6pe=l${/hذ!o8-uB! {xчI4USdl'eqĉ'I7LdUL~),] <֮Y˳=LG,BCYpf.ϙ)SkvOg?>wt!Ǎŧ`Ydffr*=cΝ8pk֜pֳ(} ['b״ys%7qd W,,ħlu/O&̫BC!(` RLq&Y/gʕDEEiK}ڕ Ceɿwpa_~ $::raeٵ+;wVt<Դ4z\vf'w2 ɧt$i.#,W8`iv/Ǫ*L"=`؀ C5}7dN!$RZ ~ZR|]ݻ-=z+dggy؉Pܛpt:5j$ 穪`=cAFf)s6OSU# ?< EX%o:6PWX| }2\! W?UPyNkPϰ'_2ow߯ jzui.hV "ħx*q}г!EP#e\,k,< Q %uTL 4l>ȣUjLMkLV4BP;GXGVgB:t@hh(֭ vUN!*IQ&}5v~]zgWP<@J>xE9;O$. _A5R!7jhNH0 |-7eOV56w?m>cW:, 4hG3?暫0`WGq-ZP/>]M6ر#U * BTT{q#@۝ېW&MG(/t0`Y=R@IqOn]Yh}>(5iӦ:#G}jB!*8.0uTYF#: :Rfe8N^ v ?6tbYODgEQ '?/Dꫯ4 NQQQ#ÆK[2+V|eYՋ?˲ؿ??f rO/ BTY2ܥM,  /^N> ^zIBhX<^|zC\yeObbb<$\z)aa,]I& 1cxwaƍ6aÇs ٳg:tOfży,X0֭[#7,48zYTUeWy<1yrʒwoNSG3f:1cr[y7׬-d!RVs`Xea:i3(0bwvon9){~E1*OAdeeWV>++ ӿR3HKKd7nݻcǑ@QQ阦ɧgAIp0gk,_5{`dggӤI?l ֮YMsV~k='J{og@!DZ.;epl@QQ݊'xryggrz>T ]lK+;ﺋoddfġ;tN~~>>L7 4͆i 6c0w<֭_O=EZZnj!&>;w"%%-[HOOhz}lN}l!D䐜 &M:d:tg/ BTH]E4 ZERhޘt洣(C-Eݻ3lp*rrrʞXe[*[ff&_Lye}1[9tVo>t҅sT%*;9YQsZhAZZ:=07eYL>47oNJJJ2LH!DT\v]aSPفXU\!6œ6!6Zv Mh0 Ӂˡb+Phh(ǿO=l69YzQٳfӻOw/иq$8=ZhI>}h٪CFn*5o !jf6U6ͮU450 ,1;PEQMY?o|~GVXQ{yP<./w߭ɓٰa6p W_/gʕ޻U昖wdUcCn}P`@Jp84lP|>HO$~+ZW*gN^bxkb(;g@fE:n(^zTpߕ0ƒRX>[GBTTIlB. 6W\ATTpeY0qk\?8p+득mO?O?-~5^+u̲,-\ Q #n7|M[P GtؑF;W|uMW8S ^Zԋ:u<Z> tP)jj*&䣟o4f(} XYIp8XU*.OBBd΀РaJ6mQ2W_GZW:(i)&mְ_JvO[Q"ͭҚg9s_ܝ/Ģŋ;mû\. O0t ~b[JTs(5b⁢B c#v8<&H, EgAޜ J\!I! ^l6lڴwm曆硇a篿0wg?;FҪU+Uqc8`^#{,7n?FXh1O=k|1>gj,b V)#Vp ~Bu q7f !sCQYGK4 СC 6g}nG'|K#==ݻynq+Y4lؐys>cy|9:h2a+6mZӧOc/^k޻=ƍ5f,ey\^ͫSz͚!8;I0 ݻ8pɿƦMT{]s o *2Hn}MBF?pg|ToN"=-q-ޛ 55UU%44l~>{̙t؁pVZ}hp,<,{Ehh(R>|.͜Ikeɒ%x^Nyw?/ǟ`E&tϡ<#jي~ ](ԏ!//2!i߰^B:K!jS~JhF||2O>II+\j23ٶmS1222H7^M~)etڅ0zrr'eWZŤӦM*&U/Y\* ϻԫW\^o@v%sÐaDEEa&srx|e>#'KpnKt_7*B!!ÄұcJ ؿ?hZ:N:t1apСnbUyӵڵ/޽+|O';a8zy>²,222%;;)ZG9>α 8!( Q r R?U)Z8*ձď}z7>T=ߏ\Ǝ_M iKaLcG%$$L0 ,ƧbZiTbxI:V=;ٟ~Zm=g.ѱ%#ickA^&:u 5k' $E9}d0^Զ[TTT"\wNsqO4rUD, «BQ4Mcذ\BBm*4SB+"4χaA78vDvZK}EbbbGqiN66Ҿ g9 ֯_*\ pN8yAKkK y RluB54MpvF|9'un7vUbQ!)טs]8t |><^,0ä椓zsJ׉kn|ۏO>),,DuBBB,+7:JRq5fc']ѨN9iU[xB!$!EXi!"y1=G|>tFU[S΄vZ^//*;v,|eϞ|A~}wo7{,t]{BN6yz>R*-;رشԆ2:gJf5N%?읭ln Q|>ܺA ׇib7-St *J_+))HVZ@H0x{_>)?gd XB0>>Ԕ<)ԏ)J{YM!D핟i#:Z!ȸEG!uxP;uV4k,B:!?;wVKYmt"NGNa!>#%gRQLLLhT|AXXz]иXhQ233shh(dzgᅥaǜ[: !js$- *$&ž=ap5,~1 !8=ژ4-,pQ^WwN ZnaC H_`>#nuz0p O?o>.v~΍7B"A\7D.Q =ƍkf3ABQ%"i# ؟C^Q˫cxuLӲ2uRt/֑`4:bU_?3RΝCnPf^|0V^˿vӧN¡C^|d„9/nv.E `HB4 ƸqsذØ1N3 BKCzq#'<,]|:ϋRp^"˲c:|bbSgfbbG08)))׾NT*=##np àSӋ8\.6ܜV⒋Mff&e;˺v2 3KXȇͦc#B QFLR (z}^}>r|^(,PT PQ(P,а P9-J=izaa! 8idddDk{ K!R5. & ? [n ÇG?T"Qh`)$X*M- B*v[6v)^K IDAT]T!D`@!D$:,Ha'ϱc珛wgXd+֑7:n"Q7pEaY4Beo !  !EU[ERAB?{&Uu>p{ HW5P@#{Ԡb]bL&?M1j-klXb DXe~u 8S{fǙߞlZAAe#z {D2ɪUEyLAS#ֶ #GrQA4!'AݤAkAAa%AAAC`@AAP"AV^?bm B_ Ak5u^3! =nbڂi($KiXiXm[V$KH,˨TVU!IMM~JKˈ=Az`Wf٫~={Q73$Ixn\l&aN4& c6Ei(,HeؖmۘeY475d0 T2EU/UUzV'Ɉ̀A$éqQ9r_AOQ\TXI嶌 P:]n00-+e߇aZt#d] BO9EA7Xh_Z1; B/~Y`AOw`@e>Hp4ߒ$IFh=ζj隷~ʲLaQ~sAP e q98Mx"$N% ;eYvxv׶mua8+IM$mϑuj6TP{;%_ V*/k,6r8cq:]ͥ\L]]7zˡcRVVƚիO 6t`ԨQ\g3jBaƜ-oa[}n#PUv4 EQogrzHD, =(ӯAno.г`2R0#OJ;cĉw96tGF'—#I/Σ>ʌr饗tz\o~.۶ kmS$^3QF>r4y=L&innrL[/}YБ]# T `/oͰA!cgغN[pC3xf_J IRΠƶ/\%2^D"}ʟ^s5.'k9p!RYQ2{ض͔)Sxm>#פS:LsV^{5\C:;lfTVV4H$eY455Q^^γ>FY |\GTT1 @4ؐ,)Spu?G$> }7v;| SLaq|M~]~qAfyd>F</ww,VYl|]hy&,..ŋE r?3x^/`~D{TO5M0 >#-Zin7~]YnH&yVZ5k< ˖-cTVV2ydVZ]"8?{,v6^L,dx ђ!_a鿟~QG}SO9 /TkyW9`1'W0a<'G4|wE+V> |}夓NOd̙ 8K.x fϞM  J1b O>!޹XCC._n@ O&{w{9jōɤ3d2쬎g27]goUPT ص&::: AU~^uO<'xIzǻw‰'c3HRa}ee|Ө]V˵w-W/?ߥ,gŊL~9W^^k؅Ľ?Mkf6V0#Nr-VUn<6mbÆ Nՠٳg5 }It͉(T I&HY[pY6J&oI_~&W]'gkj' w) iӦnǗbgu&]x!cǎe3CnVd 9KPdI=adt]u,Ʋll²rAV P4-,0Ll0 l4.YXmRd)׮ҹ׀oߦ w" n$4MEUmpP}Չ(z&͢d ,u,ۦ6mFF,:1,Mꤝۗx~zy]}1͞s}=y.TW^yfc>nW?wxT2ɏ~tww8Yyg9{ŋ/H*Be~zl =˲-.Rޟ3y3㏧uug`@F\IA3 v҃z4`6%!DIȚI24d ˰H'uΪ="jJ $Iѳ&6dl HaxU0tLZ'ѳak<.TUBUB&eM(Q)*M,[wOA۽#P8a0-8a`ftҳl 6 rdg6`Ipˠ^ؙp pϧ0byϷzO{{?< iL&}9iZ^/El 9s0(..& a6$ ׿>s=KAAPh'> ˃\ƥx5U4LR4&KR4@FQs#fUȤ |A YrmA" zȦM$ @dDM,m0 Օ,S$6мYm'-؈[q{; 4'"0xR,XPBam4dt6gI:Q= dCIɦ? . }QYbp8Ŷz*ـ-YE{{>a"3@^&c6V[e0HDG<$SX8{sfsC<Dh<Ͳw[o)(S/[Dܹ-R*̊9pC)@~`ca)IgG2dRFX@CV$:Sl$Uđʦ$ /*Ƴ\zH<0M [;paYc)++9c}2l zvSm&ֹ M %2mj1(@" l5R1!gs$IX͆5 D#1ю$%~$lZ,Y$aY/ P"ʰni `mw= H iA}`TU>{C݆T$](i47M4ˆRPᅕௐp{!| .U"Ȋes a>XP5np *E)-`p1W`Z[ `&҉]~o$6MN ;s BAD0`666m#+HP1(C+Pǯj*Hmϸ}ʪ @@KbоeD;.++T€eT (Fe4 Rnc2PK ե I6%< ,P nO?$퇤-IgG~A9$Q]QYiQQ&UUY?#\/3wn)M.Q&`YCAD0gL-IJbLY1-WD:PUlFǰt$vah=k*x.TU@<20,lq̀mYHD-5,`EpL$2H&dYTU-\n_=(c^,IXn7U$zFd ž&t14g^O,6Y](plƌ 1p`͛ݸ=Zz?!ł B'˶$u{/p#d4wn_EQm#I2.EE tVReLVOiMH҆E6ebdYϕUd$$dYq2*#+ ɸexnUc`XI#av45zdH$" WH!XG:BMIL2W[=G$Ϗ().c[xt,dC1k/x\x!A]IBd,VvмEng눻D.H۶l˹?|]ҞƶtיΔ\moX#k.mW ϊD ~{gm/<֭Y$n-0vcOA5>e/@2#LAbm#2. ]ױ,[pЛl\_ǃ@5%p7+BsuT ~/isqoho `@e>?naTVVbYx^{!mYLrdYo(,+H | QR ڱ$eMAh!mm"A HKöm< I0Mt*=` x\.xj<3NoO0SUE^}(66/ǏϑGK/<( ^X,WAر^ (L&#eY\.dY0 4MsRA:G`zm,JnTUŲ,|>PT*4M$.+N( e9, ]ם~rve9&@qI)"c;}1GsۭD4K_,Ӣ 0LQ[[ :?]z g9 G|d2mm?CC}Ҟ uא4V?gRI;94#w#V =mǝ|mۘd9W~4ÒJ @Uխ.J?6u]Grkb.+A(Dii)iF)((,R9W~ടrd2#Q4N}jjj7i=OiaÆat@~#FɤYbsLqq1 "nz 7r+A/,(#&0fHg2l޼&**:d~uYfvII1bӦMS)ƎKu…x/hh,Bmr_YQAj `ٲe;wil㟔2nd|K[̷(fܸ ``[@8&Hr0`N0/3ϐd(..& vkAknwi/_xϏ{^gZdmMd2Ȳ&|ms}0{xd29Ӝ;lVޟ;~r5eee#q.2z/x<|~x)|a.;l\ߟ?e1ax~y0piK.㱿<΃=L8f 㺵3z<+klذۼAn& 8%KO~#OzT@pՄ,rnL0y{#I&LwW7d̘1x^:(,Yرcimm֖ v\re=ݍ^ | A,sFӒ$J(((Uя~Gꫯ&3sLdP(GeɤǟJD"iȲL4uҁ8@ۍ(z~~ijb>,eeedYx66?R܂J6l<7iQxݎ׿v_t!xۚk).UUK/a6uyEQK'm78ƍ嗷I'@"ƛo ?_A5\C,cĉ :[oAoR]]M6V`gq$e3>lvԵ]GkK+?;>bϚo~kb G-by<9ʉD,^p8̀(((dnaG1c~x>q9EQ8裏 kFIq a0j(Vk=A >g۶$Ivx<?d2IKK DA]]())A4jjj_3zOI&!2pJdYJEC% B0 6mڴչ***|GdY$N0OSտt_7h@}ݎ?R;R^QÇSTTDEe~qK.n 83yO:MHAr߽xz)op2uTxB[ IDATs%䓟]wu<|p{;<$I\py糼 Nm2/b2Mhlld˷w}孿b򤣺=1~x8qG;nz֭_GUe^sss>r<̜9snׇ~s--vȣ38z$Z?z+!}$IL|:>(ip饗ӟ^Q}.Z-(oYGf̘1̜9UV NX,eY*Ceɬ[+W:,;k t]Gei2rHw_fΜիD"z-ϕ~)>nimme 4ȹ~ͷX4Ca6ʝc=;nbֆKump$Sm.[F @2dy7A~`@UUN;nwuVj?۱r ߸v*8:L;n.WC6l␡Cyǝ)--бc?>'p"=yѣ{yLڪhiC?{7PPP2w\^qF.B}n@~ɲ̝;wx9;|-ޟ;SOڴsas9%~1? Σ3~oa;žm ;v,6ln&'X8x뭷0q"K,~}nf4Mb^M&7K.*,H$@h~>8 he˖9;a~ H8s?~seɒ%Ah:9)FyZE,cҥ~ u]':vŋr Ǝ~[WTSZRB{(fʱle9Y- xf4o5]t{L˦?;&O)'˯ .躾;O?~K.vʑGx0B?y+**x~A{{;ռֿxwuL̗^䭝෿5 ,ogȑZ 1cﰍob.2#2dص |t>L6m>橧f5^믿7n imm嗷̍7ݼ|A_v.Bx)ҙ4_~g+'smNnað,Z~?TUU*)H$p~$9kdYfڵ1™"f*N(bӦM~zjjjev#0R) 4UUٴiX EQvyk5Wsδi~il#P\\ԭiKk+[!Cxjj FyYVf>pnk֮eٲZ=._ξGSY: _"2w?K.nO5,Zۏ _>$NںQu˲V8>avZ?7  &dY@ +ot͛i~;r} /QWWGYYlCKt("w=>yش)'嵼;p‰,_~'6m+~x bѱ +V`y .=v!qKr\v$a躎i~g~eYAwgC]u]w'Ikk+K.%:̻߈,L]_nX9۽m3>Ǐ /v3rƌُB~D"alnd1z}ώu;ijjbСuԷQRUUIPUoi>ÍJ>\^|>?O|>WԮ _iӦqgpso3U#`ƍ\<[nA4,r6/ܞP{;U}1?*۹ 38Bޛ3q 'rɧ8kB `U|SL]=WkUUln&Jʰ,sM$a̗Sљ'-{h4ڵkܦ:ݰammm=ٵf iI'{G~hnnFQ*++HDqq1xYQt:팜w 7n+W$ !2 ࠃrji:7羌I&H(NJR@!@~Qa|[bݺuKg~|>`>RVV잜"eh͚{҂i7^.ϓO<[7?ge]?jSYYʪ*P_q{/7t3ݝ\x|>A_1|0ZZZ8󬳰mzJsssOwG>mmm444F|kMӈFPTTD"  zIRx<n7T ׋!Hd L:AD<P(D8vzD"y !C2t/ғ$pkI0 ټyV@WDj\H{{a6o,q eq]wJ88կ~ʕ+Ϝܗ,YiƑGɔ)SXfSel:ΊBTKYY~L&ÜtIΚNdʕ,c 6|87K眊пڋ\sO|xܯ^}N>ٙ:l&M7DUUgOD"PT\ @4Y&{aÆs3|>L.BƎG3dО^s3$q1駟*pr\.LMPUTUvs駟:555N:];@immEeFI( 6^{!2PBdYFUUEvsqDZdR rQ+w $FjjjhhhʩB ߴ-..;ynt-Oٕz KG?17rSHWʬY~zy]}1͞~Uwf'?JOCCw.7x >\H8/s7le˖qw滧d|gSO=̙/Fswx^ $I&z~,[e˖MC}=g9K[2˶Ky繳Μw?=سOaa!x]x`0˶m~?pillDQ ׯ'x4R4P]]c6miӟ|)=۶ DQ'xW7AͶ 㗿dDI #i`YӒm3lhogѦMYaWګګ ݄a?" ت/~n{)|wO<}GJb}0-GNeX}L:R).{Ef\WEĶ|86>&Nq}{{/] tEd'7a炁>.iTg4Ib;;=+WqF6mի4hz(k׮%Hpz7n,Z8$GuKNX,FEE,;eOmJJJ0 H$i Л僁5kP/'Oiq9@.ksW^oKMϸYhQOwGas 2ĩVd|>c,SWW$I@&AQ֮]KMM cƌ>c9s rH$hhh`~jkkmd2IEE\tR àz2 ---1d0Mrg v 麎$I쳼=e F~<彺:TTP%ú,}xf\I{7Xr[c\=[ dY4M'?_TT,@nA*r àBf̘A}}= *6nܹs߿?P]I&… ),,$fQH$$I~$sEEEaYS(~ 5 z˗/1J4 '۬Fkߟ?W͛Nj}R^>8܊B8mPYcAas466vbf^2^)oʕ+"|r@$AeܝR{ήƊH$Nh>E*#F0 ֬YCaa!m܌rpJAW_e㻃;?%9x]**gew:O|HAzN y555I<Mӈrhmm堃" Q__Ϸ-*++OzdY3)++~z4MC$(%%%tttDzNQ^^(a";~1w\gT*E~5 fnHsǝ96ڵyZqił BsWmcYDLut]wJqFl-=ydLӤI&Q__O}}=&LFFI<T*\.:::t|.‰Dd2>L&C]]'|2466 hkkc"F2%AAMӜ} @u^/f:nL&C&q u٣ v1M4zb1lvj3,VΟw[49Wo]ϕ4GӴ  {>&dYsA_TTD:FUUTU%qݬ[JTUe޼y9˲={64MϟY"0`x'_edYMPUvb;cYpUU4X,F{{;H$#*hX,G4S4;w"Vũd۶s|P<GQ(iTAAC۶$ Id2\.LDQJKKI$dY FCC,sᇳn:lfܸqY0?~<}:L&)**r*gJ NhMM ι֬YeYL4իWcYMMMῬ  s3. M0 Y+FeIIȲL:vHR6T ])))qfӞiN~&:($1x`,"J(VJRض휫4 B[vSsp~pfgojCA9}nf:EEEDQu~hhh˲XlD$-[ƨQH$ۤR)$IJ,R:PUU(Y~=Iee%n&kРAȲ̢Eg}H&,Xp89 !IUUU.6OmUe6E*a(; r9)Cb68 BQVXAii)eDذaX'@4u1}ATEqN $1= ۅ`(.$d5GmxTF< Q?8kق||˕_gymϼL& $)AzI(P,ԤM}0m jh,SPP̀N:3V ApdĤ$eEieAv ܹJ$X,.e2gӱ&b$HӘ&H8lֹ@d2(w+ YEaa!LY NcYǁeY|>\9W~|߲,$zIH'Jd:I)C Ndc&5M<)lsD$I2R4l0-`(´i1n?_K`@LĜԠ|ȥeY~2t/(mۘ+ sFߖ#Z]յDIuuy>N;ał:Az1$a~ĢQ|E),,tv_f9rZFNp>w.M$$וq$e3>wΪo<˱?{E?p{5WPDB IDzQD&E#T@ѯ`Ă ti,BHR/rm\r$]$#3;;w;UMf(DLyu ,˨Zt.r,u1/ DJ $ Y% F\0=K<]2+A7eڞ \Yj5={i:DEN7$ IDATs㍾8yRf~V׃Z`RV 2{ߒZNѩ\V=O3:}qA V vfc՞=) .KEߨ.p HH^$!Cye82..'zY0L,^9o ̙/w^hӶ-Ӧ=.QUzA\'a4霞@EÆ""*+(p?!8!*|q \E󊤒 !\p%pH$p,,Un }-jq$݄BCC c׮?@222` ,]d5S|_z#GPn] pe1zt |\[NF oy]A.B.E!#+L239pʲUrA fiPTXw0\ @fffǤ9CVVL& ߹sW \3zt yp=AjY) kq\X,L&Z-NJ‰'`xH p;r@fFadeeUx̸ѣ'Gd2>KJJեgT ӹ{cI=&3?.Ak5\@` %'.H@@ZNǡCURUH$s&tqVVGڥ+  x{v^_ӿM/•k@vdddى$hN%<0HA1I^+ l&($Lz=`Z&;;"f |ṟ`@ ޻pB:1E#K֋޽;~~~^o peP'w2jTcԫw> OAI{`2h(zz=Ǔqqi3"=(GS X~=1mt, >>> Y[`Zٽ{?mu;oWAT*vÎwoisZa  +~*v~:|p:tԢE;Nb &_f3NR(t׃^իWaEӑZtGpY.שSh YezA|NEʯ`Y֎Z* P EǜQz=)z0 `R^B./K\\,lξ/NzAj(M WEbW pm=-poE@!d M, \f"Av:G&#KI#֫质u:.Sdw5t8 pP',:u+/ \D0  xPXGG9]ѬFk46p:!L&";P|| Xdr8@]+Ұٜ^O/* \"A&INDR P!JPP*!Cj.[^ =݂$I B-pŬ3Ch߮ul0A.9۷kǫ_$y_-&Nqd$;yz{v*?Yg,y(:thT[3F!] W(5zU p'F_AzuH"auРA}zAX~%9wV7~}営n}o1 >z^={\iZmt֕?mbqϋҨѵ\w]%)  BEj}00ltZ-|s'IV{zdriZ-j|Xh4V:w,X/_[eJUei;)(([Y9J7 ^VfU[6Z$I9g4* Ni4dYȳ`0k9x ̵tԙ">_ETU}z Kdjzf]Le*TTס!7kz&MR.O@aaaRA2>nޜ(H$6t 4`hٲ%ƌر d5ٳF5#Gqj57n୷a!ĄHKKGЬiS 88/Zt #<<ƍ#gAA1 xǧ̾-Zpx?йK7zzI˖-O_wnwжm[6mdߟn=zqofM_P@RRZe׮ة ];n֭˕$_VK=֣M7fر?;qfOy^w!!:sèQ#G^i׾#gΜcq ֜7;o:ӹkwZ+ϓ'5qv!ֵN->:ueg8z(]VԯW\7oO۷өKWzׇ6mn &&Ti&\ ޽o,a}tҕMy瓚Vm}hт޽zmvn2@ifz.zе{O6m311= J#3Uof],Z5te'e-#P]:wbС<:ufL?pyo5^}]0i2}x  ">x'ߏkV́fll ˾}`'//7ޜp`<+Lƒx(|`ٻwAAAG|>߇Vľ}iIHp099}ˑ#,K$74"dgУGwrrsXŗ(b?Ӡ~sLLd p\\.rsrq1|;v,Agjj*yyVիGD)((%5-o,V ͹:ٽ{)))$%%\\1>X{pAO+ulu >m*F@Dxm۶II.6ܜcs'$( u#]vK<ӧϐ[\˞,LJjK,@u|8~z+껤k~ >>RfpLt4~qk)iQN߹hF$Y?DHH cF=52QW[q;rH{EEaѢ|2>4=; ߙ͛pᗞ7 GypÆͣ7^<+7mӞo,)g]1|:q&zяLJ_âE]o~udffΉ'>>2T¿զM~coDŽ#/]$"EH$UL"p?ERy;X#qhk2רTq:/As]wF_~;~\7g{:Al˕t:%I*tEvsl6gHHرclVBBB`ƌ*ybcbun8ޔ%#3󢗥$px,)Re[$ݜ7缅$ofqY9W]];j?E"I N ؜NZ-$g5P({,Q'cmi`J3qM$ py5 W/qy35s`=z"N&I8L;UWlڴ. /By$1j(ϟ`L.5 E,$\2b puKǏcظ"C))NN'@rj vW(FajߐW lҷo?>0k42zl6[cfs]K_f1a{|ϗ_}ţÇ֜9c$IBSXx|,3q$~rZǧ Ap8݄QYU+* \M<[LP&uE!..ŋFQN:Ş=o.s[W]0  \8I;`jj{!>Y9p@n7v;~Յp8 1$1d0ޟ7L `w'zY0L,^9o ̙/w^hӶ-Ӧ={ɧ)((`]D6܍?h\Əj"BCCY2N'%;;3ӥKWN'tpz7M|||ضmS|.($ޜ7F˒KxATRG/Xns}-[6gyu݂p3f, > >.g`Рz1>x~EYvUA.C$@H+ga!|K d }@ChZe7PصkgO>Ї{^={0dPիZfʓOj*Z^߂+OzWUT*Zܚ#Us|o=a8N=ﺓ&N54;Z2葁;Zbݺuqm{в%x򉈈UV]ƫk+Ib ˆ#y<6z4C×AI]\BFViefr6;;eϫ 52RI+"b Hw?A&{!*fK9s,BCC1LdeeٿsV^uϧjy饗lܸ ' xDӰaCRSS̫s|ᇞJJ)~ѽVMnn.{5 =ٺu gϞeŊcڵԭWt֝;v. ?%$$0jHƌ[nĉxtP:tJvnB d .@$ rb`2j8NT*B 'Fz)#4 !W:ѣ'Gd2!T9*K=)Z,nipOo> Ge/5mڔ3_BQs BBBP|- RR*˖V(ٳ|sjQXXʕ+y)>=;VYGp% ^q89sǏ_)ɯ"A&^#4fСXrrzR jtJ<*[*UKB;= hMgeex]_n[naء={o;-+tҥ7m ~1c!$$».W yiTWo>_Ȳea˖UKtM7&--S_(… IOO#22]BtA&kIGQV+dggSX@LO?T:Wf_~bɣ:3`CȎ9_9,9c׊4l6Ӌ W "A&INDR P!JPP*!Cj.PTjO IRD P `@A/Ͽ+ P;EAA*%AAAJ`@AAR"AAT@ܼye8~SO_yo={/6e-UY 6$6&k^AAѣiР>)m}e iuS+6lѫl8pEEFDpM7`@@$"fӃN'fAju0e, Jk2Zz {&::Nnrl/yCAAAte@^^We"Fre<(]Bv]jTA.?EQPaEՉJ%a4Йh&$lyL|qlXfaPs:W!Aܮ1v?]?˼qz7[oa|6[KΝgSVsE R DE5KΞ? ;vd]x>3,F( ~~5*UskZdIuiҤ 8%`dff{1s] |d0Ns9p@nNwq;pY0YGTY7./`Ν/d7wFwy N,Kh2ǫU*4s_F,..j5Ǐ^g VP)BsGSf?\p[.H>8 UN8š8OdaӨ'.% \j}0p"K'++7ޜ⯾9oRXɧy9BnN.##HII妛nb4m҄GpueKMMEeBBB0dggS'mvϿO||>u֥i& {t|^)OLˮPuu/ú$ _ uBL"p?EUꦊaD{X쐹Fls$; h4/\\v>u(((`<ԓL4G=$$ |{JJ yyyje(ṯh,deg9lF !$$p϶~ۍ$_G!!!X,y{U=+PMVWNUTy PHp6V$Ilh j5 rpX[Z-L\S>.To iQ>$PEHxY냁3l, 믿QTTDff&Ϝf˥lш^/7pr"j|  |skx={&7]wYE  b++3x~/defb2jfg*s7 88Ty PH$ ߟQÆaK V^'HOAjY.#4 %[¢Vf#??L222ٜ#P}p7OÕ$1aD6#wO?Ì^PTD;VE2t0ƎǢ_,=P*m p$IbQ̟??#.97sX_@20vs.%'7\3Sf7ٱs'۶mgʓO3xr{APTTĔ/p\6f8Eonjl6~su7>Z;v[osI֬^I{}Gف{ヘN׏WfɓIq֟kXVF#cMndYfԨh4jI8Og+/ӯHĶm'''>GZz:us5 *B*׻S.?aFl6;q:  ɩ)]݆w8CzfH߾lh4elJ*z.} Ɛj5}9Ç`Yc$IBSXXzJ pq x!Z:$Md-(B\\(:u={v7\W3f̐<(KEjԨ.kZj].`0hv˲lTŬ(JޞՍ7믿^$Ji(.9eaZ=DNNgq$@Vvv?.*VW+RNN}KeKzj gFSN*SӺkӦ c^ȑח.IE[Y +n'm`'@| ?eBRC#'baY $[ɂ| ɧF$&/bΛo0sKݻ8ڴm˴i=lؘܴhNgw-ϸ񆖞m&MQF8j?h\ƏѣGhР+\ע+Wc-A8J݈p*u_>Y(  KxM(440v?} ""u7tQkLyI^~%Ftw [%Kp07IHGQfÇ駟?~gA(YcDdd$=;Up$&a!|B ˲A=`@(Wѝ,|}8|0. WKQ*3h@@R16ruYʦ"@$Lf3UXI9sY d2EXx1sV^uϧXz5jP>d_~g|A|||Sipk{ZYg^fǎ^Տ KHH`Ԩ̛~``I :$R`*ob7A%pݿ&8EłdBt:QTX -} V4n' / d7+}:nxzD2230LŒʏ&}gѢŀ{[ڶc&M^{;5mڔ3_BQs BBBPp  !b!//r<1e F3))U ^%1pp?^`*p8uA .qp0ŒKb $ VNP!T*T*^ڹrj:8++#tҕrr >>c4)**ӽ{wλN_/n=渃 L^<=HRRGl :eJJ K,a?5{vr7K.4iڔc!iӆv(2rOAI{`2h(zz=Ǔqqi3"=(GS X~=1mt, >>> Y[`Zٽ{?mu;oWN'/4?իy|eR_ЩS'Da͛xv2yN6e}ϰG. s).FmemUЂ A(ŮB 7{Z<^*,a㙅.8& \Z"Av:G&#KI#֫质u:.Sdw5t8 pP',:u+s. \z"Afw(,ܣ#.܉AhV5PL8}&Gs?> r,X2rp9 EǮilN1[ e&Ak$tJ$eR)ů2Հ-H "Ajt? /  zѱͣqO̧_9'NWnztƽCzN{]pV_߾\<AA``Ѵo%ꄆzV)|}}/(mmׯo_6[˨#hӦ }}ITTW飣iҤ}n]1LLҖP   \W|7! mw).$IBy?`fp8.u1/Ʉj{]H&Lٮjl^Ïέ)2co.@OuR0 X,OչAAV?ʘGqz-{ou㍬]WE4mijnݺ,V|3q+r ,lXCW{eL k2`eoi=QT|cBBBYv uBCQ}6nXNJoچo>[Z YY0#6s|ٳ^y  ^b~XGnҭ'M(V}۾#?[Ϭ,/w+mיzs\˾\.m۷Wy\pp0c]UhPʮ j%wjj5N#GAtҕԴ4ΝGܕ2d`$ ׯǀӳWow r̙ |!5mJo}v̚T  +cPDDcɳPN2XբŌ~l ^ *5Ƒ_r-n~֧}^1f_z~fLm W_-^:tBCBHKK禛nh4̚*9=y2}/d2‹/uQ%ť븭-D7T%)H:vpJX0rs)G^n^59 +20LM4ѣ8r|=lX,q8\.ƍS}'e23 :uB9v}o. >'&Oh4V&ݧ7n̴禢V9y2`ʎeH>uЇ3gp ?NbQ<>5Lu<4`@>+y<2aIh4cN:MV7zZ8;gjf2A`ī`QQDX.^۵" AQBр^&sG@ eY+nw\96xaB[49N*j%&&rk,;ub!<yz݃ 8<EvcC!C! Ҽis^9$ JCS 4(V-BF刟q 8W_̴i ٧3PU.^7ZF7 ΝOgksτ4 ;ȒE fq}S\\|gѣX[._;njS^Hhb^x9~>`(_.+#0wgqogor嗣T>히}ay9ߏpX4 eFJ^QXObՇqE!55Bʪ IDAT׻s- ݄rX̔{uo)))x<BB.W"J},JJJtBBBVT8Liio*nݺkXɣ mLUEl]Y.RRIp8: ^! ҾE:MRIINlY{ TU !/ݞPHxi:u5g] 4JQf VUUu]$%%iPHзlb\.###ܹ0qĽ7tZ0())9Ypx^JKee藺hT1"6 "뿩b߬zd觴KDӰZPQٙ-[ܞ4ovRQ e&lXN&:2 3ġ%>cxAӇI9ZC #!ġhMjJ*;ƻ;qw/BqdU~iŝILH0Y0'C[7&NNGQXTFΖ (;IحVR/ 2NfѴi8N3mYC̛7{{&(~4'O&EQvxw+$BWSB',=b Sæa2EHOn(дiG$+3|_+.Z! 9p8|ɄĻL;6*/?nc`^˘ogϞL>?ݞ~F׮ @/^aӇ>0e͚o:uj{|xI0 "&F"D,T(bnc"miiNN8.r233/^äƾRC<ӤD1}f͚kyꩧx?~˷k坷\\=*6m?BQqۓ4, ޽pF$&:7ww}W(#>f'/? h-J6G1[y9 oVر7)Zy{/#F\n`ʔb\m !8|~%,6 Vg4Mf( IExWP6lͬ3`uta<$j!8}zӥEU\uU> T"a6f!fA3z~o/EoXOgЧwozw'|r>{}4i҄{Yͤw E/f{R~w@B^3Q_ϰ2ƌa#شiSz_ !IU* 4P-f V(6TBQUڵk ]7HMM!-Z$;;) |X,zZbW_ʕ+(,,dsNNN4M禛nSΌFB6mb˖Stjf!Dmذѣg؛7^{ 7nCO!* Ml^ʍMj XlXEpF*##׋狦)cǎӋK/i|>{"iم>+R~4}gg|*𨨨 '7ZlIӦMغu$BzRp%b%HN:XRR''`JbZPUUh٢)@5kADl6[4N:h=MQM{>N'v{B2YPZRBѶm[Fs>ٳ8h֬}e{ggSXXĄ 2{|1woBڵkōB!bfZüCc61 KöJrR&lbpHD9+v;~@8h;wҵYQCiY)w+7I'Tϲxb&{۶m~(8rdg_~Ё!qȑt֍={V! tÆTWEل9HʖT}0aIc~7ؙd21MӸ;4h0 Zs|{h޼9, dsNΡ/7nI'̈:CN0zҥn/R #BU^z:ia9q͑C!1zDfM0[ ՗}u˼PD!G AJJ,u{.YY$$$PUUuH}(--wCz/!h $B˅dbX,6nHMYmdecӡ[{ ]~|k˪{!o oWnEQ^!D: sLG9cf͚Ҿ}vzx 8kM6\xAkOs\ٌܹfs|8c/kW!޲J~<Y'6n-[byyyiB4jG1c8唓O7i,[VvG~s9xgHr1*UU?syA˶m{}>gٳ8 ̚ @ǎYСCxǢ?1]N}ۧ7s?mogk̚ɧ3qLKsϰ`\j8/>=yf,?oKĄGUUXkUUQ EQ0X,halQ! #~nKVV>|\]x.ϓO=}@Z,s\|՛|^}Ezj9'mEo}=.}ϧy}t2uS^ge-#try_1}zc9SWUnf eđbAUM|1wOy,?3W/ACqa4o֬-q_ӻ31T,oX+PU'}Ć $B!Lf+W~͒Kp,yt]Yx+uOg~F(Bu| _`ZIOKO,]V-[nZNi 7z~;%:͛7C[{tR^^NV=^/o'=:3Oc2x7B!#~nO>=>o>hڞN=pw`D":Υ%{4rk:х׫gM1.x.,,:`Nݏa4?-o Ӊ5ssw>{Oa ;*?]B#{7w&x<<$}<N(>+Ir'qW`ٜw^Zuc\ PV^kOmn-+-%1щj% r%FuMsGzzZzjW / guf̵׌䣏q7z7z!B!_&/׋aW7o>^;TwoѢşj4lЃ޹cNA1]z|f3iiikmx~>( T?;o7]?p|`!?r6oU_!Bff`1M330mt| T;[z񥗹w=|1g6\.~5쪪2z(, {A( K.g</_ D"̝;֭[3pSV,_gc̙U>߯]˲+be]J֭g}'x,_B#FJc:V ` gRd®)۱]!D]JO-'NT~HzJ۶m"j|>pX4 eFJ^QXOb~Bjj*^7 ϲl\.<pA+xb^cO䮻D, <1!D$ Bâ[n|iN}mV{TU% D"XVv{yPp8g2P0I'\B43u߻<+R\uiUm6[*z$))I BZFFerFΝ '~ a4h`of,raXK駟k xokcOQEPٌld2aM6cǎ|\z(Byy9PTTĚ5kID"UT !D#? \"pشiyxwK7rx^z5x^t]MEQئBSOO'))AS !SHkb`ZP _|&l.fG>S6UM TYXf6 ޲}BXl e?Ļ+q'@#D|9qحhz~Y>;ey]6!Ka/%#`&!( /@ cy" MW̜qqfbA5ܽhQ!e`PQ  QRZѱT*JB-*%e|a,v, PTT! z\e;hץ'7g\DJӣb}jZvj+i)k[%Ҭ]̖G9ݝ!1fͲ;. O+bZذz*t]gê<0TrQ  ٹ)˰XM?+s97r]PWJwmNcN;'?gA7k"v_񽆲}/mOI5xK !_OWMrB_+-['`knLzňA_#B a-)C2j96sө{^ ]z2Is+ۨ"9&fOˣfH(S(*\[X\7P,V;᠟}QMfv'BU+zd?Y*i!u(fEdHI<-عUo<{+eBXl7Sqk)lMN_+Kd[0]zdK`G8$6 kPbX,c],{ZP+pzɘZṂ:p-s氻QMf4WZSy~1wz3T!`9y}-_]MzˣHlWWӾ[_.`̔hsBUO~A!wD߻ OrB4UZtuko4uڴ]Ϊrge @fBĨ8hek^ٞ tEQD"at]l6c߼[,*ha4MCQc n+y&4=5_lE5X3[(ZoA5[еwׅ=7n>]z?ag9}8>{j4Ҭ-^|/^s"~o/& E5a5-sq$qLyB4(6/o?f#HA&B›Yݙ$BoEd2q1xBx^222زe (ˇ>hv؁lFuٲeKmݙ@^/]`'/gd9Қ-EόVxh GW9X< /!ğ\{&K B!IUUZh_3`D$33r4io0 4M#//VZQ\CS}+9X惬)z_8Vkey٦3<&]ILÑG[yǙoBʄ 5H<&[F ! rrrZ8N\.. EQz8Nn7A. ۍ館=8E)[~سUPk /c͚Ŗ49gMg2㱑lX63溻1h<%9N=ff";r)(:IMwB!MQ l6p8HMM%11B\.UUU4m] dee*n,auu?Eo=ȀW^ڹToVLfKLy6Zߝ=az m/ HnrTtπ5EzVts|!id]2)7I+a}VP{m!:L3Ii?,wbɢp`+qgiW J0 "faPVVb!!!H$Byy9m۶gɒ%tؑ4֮]Krr2>k IOO' Ϝo#WrΈ}TUbMH$PYΦsӗ4nywP-fY>ªeC-p AQM|٫㒘g;),rx w)}[t-R ! ̼~uAͩ.LN(*vE!4ݛCx^֭[W}ڐbZ1LCMд_@ aa0v@ PkYPqq1Pa!!Bz1 `0rD|V#oV)--%!!=~c2굁X!_C!1MTVVD"}躎i躎BP0;5/G B$QpVs9%>LdQͬu?v3 F $E+$;D^!DH0 "&es=uBqĐB!h$B!eBB!x&B@fB!h$B!eBB!EQa 1!? B0 &hnd4L&g [3b_i%D\in"2B3*̄#F ! K!13iv͂n1Y*sp8 0 n(G#2; $B"GB+  񂎁Ff4D u[9\a6i[0CBFM!1QI\ea*n-5BshX7YP#*M&zSHmjFQBw@qwq8NVZĝB!b(!Mn( VٌaT#~nߊDnQP9N׏ݞ  !Z%'3kVTARRV֣TT W:_ EAQM7 IDATy8!!.]Aee%6mdݞM}چ (..w?_IMI%бcG6n.ŕB!b5{VLTdB!f i|0+Z5u9``ذ:n[lamr'q_~uYuYtp4^] ш(G3yd"ZmwJ!VߺǂC!6sڙgi΂|z&g)BQeM0P; .np~M4f xOק+1=nٌjj.p\~"H[qF׮ @/^aӇ>0e͚o:uj{|xɂM!1STS B!fY2_~`ʕTUH* iSz; :˄tz3F^|Z X|] T?={dxnyy9}ިYV3{6m:*~p7r} ÈntB B0 a6yVal#T_R@%Pi@)H0 "f<*%]]8"x4nbbT G6*"IvM4ϊ=!h$Bp56R5Hp8]fNfG"yDa\$=^%HfX9PHxQ! BLQ4MaG 0T(M `fZ3`. RC!8H0 ^^keB1!B!) B!h$B!`@!BFJ!B!)9MH!DL:ܟ=a>Ы Au9v @oV-g7(!h$Bp~躁nZýfz:n膁G tM70L !DI0 "&;n)-a:t(+$ Whzl@a2HH{XBѨI0 "652ڀ(D:W :3u/̤[U]P+( a`:unÀarBēB!bbP4OhuaJ_].!8ܮ==AhQ!12vo CR1X}{;ω|n e{:1wΝi޼yO݊+WP!DLGez}n<p$( i[Cw_Fpl6  3_Qn7@EUU|t:Ձ>8BHd h> !Æѵdef9ŋa}>0 rssY[Nz2!!11 [ە@idf&a6L*PT조_UR2,á駳hL&S4NcX,n7/2˖-gW[Ѳ_̝)]0w<,]F&Mxzj,fcif`W|h1CeW-[dԏ7KV; EQ pQ,K03ݻA(pD۱Z<ȣ4v,+F6GqYg8p/*E 'bE<3iNW_f9gY`2IIIL>gYT^x|3|3n3?O߾|>gN=*Bk[oC w߭?xn3G\ŦM!1 t]_W:hn OʁgFz6nWBtq} o߁zq@^?.^ty1c:[o]oi7ވ\x!>GM%-[rtǎ+|>{oFVԩ˗/}dffk޽{Ν;?ZjC 60z{SqkaƍqỲBT8\-8NivY ӬI ߵV`(߃R3PeB3?il>}ott9|~gˋ-))Fj߃cZ(ϯVPOZz^/UUUѼ‚Ym^V^$eBB*** ^Dc֭ǹw#B@XU~;/XK8KTضNG4b.]K׮|2cOPZZJZZ:PtZ2ˣDl6[tSUU1 B^),,b„{4x0a;PTTHvCXH0 "&a되hYTE!It&k&BN7Ko·_Z݂a?coKvv{`4}ҥ r8WW-2tAۚ={#UV KPM&; ۶mcذf0 Zw˖-믌?{ Mp\:3B#;=cժU <=?իWbŊxw1.$B˄.s gmI CǞ`c5kԼ`,ßr 5q"| %%{4IQ碴;悔@Ѱ^z:ia4$Bu-[UP1횱d *S7l-mG1HqLf,^v|Ls6GN|`ZYh>^oP3:yfJKKX, 4uQ B!$ !eAIaN-aZp$Xi&HNJ$kE$lBFłm'0tuλvq79)p(--%99#+ I!3&=Յfr|F̙#JѦe:z Ct?6Lth0д3lR֯$B!`@!BFJ!B!) B!h$B!`@!BFJ!B!) B!hb!4ktKa S8 _n !DL;8N'VwWNfB[tYxWĻKBG׍w723 2laV'SQq2Co:`Bf~6{p8\;ϣV9ˏ?NEQ8iպ5@7}6N? ~q'|2eeeCZZ:'|D nBPOm۶g槟ƻ+BUlRSR G"tؑ7ƻKq%3B!(h$1I>9hݞo7aN?ZiG}4/2W^uU5{O>4s.^v9ӦOE+i&Z~A<zuR[Ǎc_2уヌ>XqN\r).+Et-="Eao}v\|>t]wjEUM:yrz?U8K.eҥu&$$ ?2XVl6TU'!C kS gs/0 |afͷL:5=>$BQoSV.ϰaCyótу% PM&@N䡇fԨؾ}{|EQy͵K۳g={>STTĄ{>Ly嗘k1 <ÜuYΏqwxdԨ1L( xGi4rjn\zezݺu_vcx'4f͚[o'2lp, vbc%##Iu6``A oVر7)Zy{/#F\n`ʔb\2!!EzF<3?:l۶99̜)W\~E4# mʫrםwa}̤I&\b36mu?^~U3C cq٣;#[n̚o)-7v q:Pnzqrӛ͛73fԀ+.$??jj }'xgyzrgD\)BVIIMG38uT 2|ѝg5#@@rr~kF26|xCpØ1z6x" BmҥذqAfLo9wQ?n%@؄P @+h*bU+VzԦVy5Nj/Ήvy, zjt˗aϞm۶=zS1aŊիM7aaѣG?y~- ;;JZalJ~~>y b{iKPJml5z]8S1zh躎sӎ;0u ?T*66\w5mv 1 Q[п_dr[켑 o@_Eܹ/"/7t83f@VV^ _f)ܥ ?RR:lΊ,FN-Bχ)Snwޅgy .w=ZRaa!vУGXcUj+ Q\tE-%->#G8LL8s羈7ࡇAm@nNvdfǣ{х2ع;7j!---{AZj}^YU-((כZ㱫Դmi;1je˰|2 2<3 w^!++ӧC)y!;; }Ł r[nBDDԬ gvyH4.t]7c߾}oT <˖-Þݻ3г[ ٳcګغ <BT*qEٌBiөS.,䫮ǿhXhd ŋ7]MaD'˗ᢱcS&$$Dg ^+Ry|})e]<&M%KԩN={Φe8x;o@9Q]cƌAƄ㚫СC1rYӷo7 A{=<qZX)6 JJ_.aɒ¶m\s:x,M/s9rP~0*-]̘koo0bi>rs5X \nn6|q۷+?]埬u1fy{V~ +W~]B)^|?3g>-G/æMګ֩Ngy֮[E|~;vDVRILr=)u IDATj2233ee* "Q!o.EQQӧ֜N^RRI) P(4-Q)QJu؟_i"N:q06lДj0tP|4!)lA]v)ǣ^JOOWQ""jP(}8% 8u_`0M6׻m#++먨(|@3., B!GTSB)ܲA Q|5 9HvX8[6VV+.q.r]""jfY5vbNYID| """"j Q (DDDDDm""""6Q`b0@DDDDFq1""3M pB4XB~vm7Q툈 QE}ѯOozÓJ*Gs`UՙiOط'XhzwiQ}1 ":SRw! Ɣw!GǑRBAA45""jd/\.{ ;# %8jQ{HLL]c0@DD _ö%Dn@J_Uۈ冩Sr SQ=ii|}_0pL8]&xE}m md O@ZZZoOuݻcرcGOtRSSU7"j9}Cp80`xW' Q ÁRоc wLe+0 ;>u/0}t7רwuckR ' 9spϽF >с  !0gƜ9qS]c7!""0pm eB p`lDD7&B4]}U{<|zq]nK.֯GNױ WcMDM4 '<ieʕ+¨QoB)}aM?~kܲ "z1 n;MLWt;MwtСNT\\]ס efyY}>X}Fˇ >^OW[رW:Avڹ{am.#: ˖/.СC:^}5xMѲ{O<G?-,cYwuWt6w ^x_X9]"lㆍ:t(/_'{R1L̘ cҥ6|8nڶnΝk˯̃?kS>~xMjoTafE5p4_8]b0 tÀaZ˅޽{ܥ ]db(PZZRS0{G;fΜ3#//={ Agѿb/0lذk׬ |ׄcLznʦM ]{ 8, "z4l̀ DQ!8>@ it] uGo{{zNwv}@źup`ժOѳg/3WK OiR-[?㏵։;w~ mϲ,߿wFNNNk? ^t]B`i VE5MSO*+c6K>])5 p9V{˅'x.Cxw}SވN)xbWgʔ{h߾ƍ grsi~PZZZwKDM~3pPJa޼yB߾}q7 D ^\AJJ1+J B ?11=.;>_z*}1bZ ]v8p7>#ALUVXt.Zvɓqɸܾ=^zel޼ v·~i݆zmr!;;Aׁ_3f ֯_ /]wߍ;6l5k]Ÿ`0@DDڵk1؟]|so:^}8s}]xƒ3gw߉9_ y^w̞]9-¢E_ wﮱ~nx1G?+/QL8x`(.*r?Q Jbʔzժ_cƠ[׮qY|G }v-D>}Dvvt:MJHHHpB!'iJ)RzN 64!" :o}:\n:pY!HTRg%%*Vg%%k.8#OWӱzjE;t\H)+F4t%%%^ ^

`;]",-QdB5a0@DD Ҿ}{;:un5:#(L8U Ѐs{s>rģDDTDDTo۷W\PJؖ1.ÒƱڛ Fa*ϱD_>U;DDT/cر@믿ơC!_Ü^ n:8p /,w:q Sr3g""z:餓]|>6oT0 S99!7k[/9ѭ[WL~бCG8 0 Չ;DDTgaȐ!]v۶k}]4!um5ՙ(B7Lٳ1gl\xW)M{A@aaaL<]v^uD)qrZk;[p8:~Q4q$|v~+WR Fo ۇ͛7aqqb0@DL )Un7C UPx];prؖS7w 㭬T츀u]pv'zC JNjsSF]9y2>n]v˯oꫯƖ-[pםw ??Dmܰ78g^|qNL=3f&O Sos̎GQ39`v6}G/5Ջ իVBӚĮqa +c Ҿ)'d ?wN{Qm4M4lEB)))Ӊ3czˉ۹;\{xyxWcOo WM|Mj?3@DL<<Z䑕dT3  ̭quS͛\yMZNDێ;0u ?T*66\w5Pc0@D\Nя)}s ~,rض fD;P7KUm EDDtb0@DlTSڏ`݄(fKoҟq?'M lƻ DDF1 "j&uIʼ0I9j`˴`K~UVE]v٥8[l[o-1FG,YۿnZQM ~Ak6bLmZyII rrscs9'M1I'p3ۊ "8DDD- 5wi# QrSNw5Zv""j.IQn:.ׯwU⎙""j1|p^Ӯ:YoDgH"_~бCG8 0 Չ;DD̈́s °+M?Ͽ/\zerΝ;tDԲzT̞=sOw݄Ցl޼ Ϗs[3DDͤNp<o'/j>ZF趓N: %سwO̾n YK5kq9ew)~+lr|2,^!N:$ƛKi0aBN>y>d>Yソ(kQbvmt!6n؈Cb8q^(Qsό0a<.]aÇc֭qmcf[r*"+,@3Āݷ"dY"6[ٶlD[13E(,,;w⏷܂ /܉ܼ\$%%AGfvpVXX;eaؽ{7rrr\a0@DD "@JJG`Np7%$$$ਣz#TjחeYEx8wxg+s͵"99>h=:ffk:vLt:Ѯ];dSOĉpgE3ـwFDͭ~3pPJa޼yB߾}5\^={?oヒW^b]Rybb 0qb9qXd1 &N}vW^ . f3ǘ1c~zL9\.7nwqذa֬Y*""jÁA1#ۼ8z;SN8` v$ݑ}aUNc:}1fRb!mm|z5~|bJJJiJSQ Ĕ)cUm/ njAMp`Z믻6c/y~=3?8HIIAaa!`t!y1;E̝bm8 wy睅x<+7~ W}, ōxDԜ56,^ڴqVZZ7ՋZSڝra Ԩ(`0d B1@y &ǵq |ͷ8ѧoxVM())uCvHo1?ɻU5N>ƪ{u=ёG8zl " (DDD-_=?޵ "$݄JrQq5""""6Q`b0@DDDDt8f0ze0@DDDDF+U|J4 DDDDDt:DDDDA~5$%%Ż*l_f]2 'z<<-U#Jaa֭_[vfb0@DDDG_ <?ۇ]RZZg>[mwCp0+ ۶g`^rʩXvM׹>rssSc舓@<Ϊ{{⥹s0ѣm!fL4/2o؈|a?cǎ1w@Q'%%b?xgu& 8笑 {C:RTx@M}z?W_@ ٳ'̞{b^ӭ[7<_-M458|~nXU}ʼn'/ ޽{+`񕂁c3ʕ+m4ѣ_[|ͨ: \1n]boNuS @)m_wUs9Cp:xYXz i // =;vDbBxͷi?g~lFNN.&_;J)L.d,+R|~Ws\f` O>e۵f}*}W;RƬgaB}To|غ|͘g>|wջW8h`׮˖y`03O? 7p=V `:^x>~ii>sјeuLFn]q+PXX(%qС1ߎ3rU.1DDDtjM7ބ޽{l3MϧPXXX@ 8tPe mW]uLc4\CP>ŗp@0;5+!1j{`ii(*.덩gkǟA)믿Eaa!t Ox B) ''Jg~6b^7L~|y~ u  /7UBJf[o_| L2?|OKڽ{7r7DmZ3? l=xz-OHHOC߾G˪4 ///euСCdeeW:nJJGtJIAi/Bh><1 """^%n6 Ӧ݊ls `_ )) y昲#Gb˖-1rsQRR; /6m|뢞m%]] 7L|4K>yW۶vc_c͕_[kW_6"5Կ))}nH79s+sZZmsnBDDDtiwg+;o&r}HOO^x!]|1}*_cz: !7iU5kaei;>Y^={D٣G803@DDDGf}]ٳ[~Ѩ{1Yp8`&vڅo[>z7_+n1{R1wGvB*G&M2w`CӢa<JKK׿ A)n{=^ M0(.4kvp>KJ0i5l:<JKK;p{y5ʮI^t*}!o.EvvֳgO\.]aH)N)t뺞H);Q'իVǻ"@ [G ǚa;9r$oXc !pQsY=`bKz"!9tPBtEEB'$$a.KuONFIiik攡C5^:wj1|!D4@iiiHӴ=Ζ^Wz^222""":vk(jR ,oxZߞ׸kZZCiv۶[aI !akz_CՔmn &""""j$BmI"""cp yPJӴ& Q@iReC/ADDDDG6&װ\vQfFj 躮pf@JJ!"""jS'MӔS03@DDDGŻii(*):mEEv-a>vP׹^өG-h~?NgdCC"""e~_ wUKE%LQs3uæMѧQ-T#Kaa!6lr+ T(뺮zDzW &""#&m(; !k5w"o@p˳,Iu \.JJJSNSA@ qRbDDDD 'kz+:H PZi*]6ycDDDDDG4Y~.>V`s0 !eYʶmDDDDD(~x8NIIIr)HOO}̀iʲHt"{<"""""Rڶ-0  Ѡ*==]y^ nTiii4;u]J) 5]HH ***6ȨAH * ))ݐQ2r#즼*--U[@` fFQDRREu]|>eFUwDDDDDDu"eY22^0 t:Vx<@2iDYvBi۶ r8eY-"""""M$,K!m۶MӔe k0P}0D TQ( ف@@:N)CPHӴ`c Ur,)NSYSV@U=3P~ ^WA;11Q&&&,!D0R* 82B,4err m+VAKyFFXrVTT$RSS4MUP(B HRJ9RimۺiRJH)5]ׅR*Vuל"(4!&J)'S)?;x՟=BR*iZmKuKJ)RR! xk do+G6D~m+MӤRj&Rm_Rl`{]Q~,sU` #5өH aN)edn۶z4bx+S*u*(|^BB SsVq:q]S;D)BXJ)[)eGV*[Pu1b0o3bvd[Ӵ8aH  loYYY@hd0PiK/T5eLt0nf۶fPJ ۶H#pkX/d }.G3L)Saj 笼geف`_mRӴhYAY 4MeIi#iݻ7ҝ_-X_5~t}v@VVӧ駟`&p,a5MD(ҤtHcb5cqp8B0 C!eYiZ$+pV*Hu""")eP4R* !.&hT*F!&ZHR(qm ]h| ++Kw\u]׃t:5۶mBJ)L=t:9,+DZik0lvjfp !E#~ DDu;'yiR%Rʀ"iZHJiK)m0d0TaȊ 8ir:2 J˲l4eM@}E;3g@$Cw^ճgO@PB(--:BP$# vOCQ>,K3 C iB˲aśeYeF(ҿ[ iхN4MB! {KD2Em|1]]4Mi,@7DTdVVHMMEVVHIIQe4[,'ݦ,`*gn[ضI?])eaٶ]Q|'EfAKGHaA0 )u]>O9wWXZZ` 0  t:e )2 DT!|@WoTeY  !DR*2u]"AhfaH)miv1""j4M#3 Qu`P*<-fV!R28E2@(v8*99Y@nnr8}24u5f#n|`0(,H ""4Z%<,K4M8Nme"/+KY^YRlvL0¶m4M)ACY4m͍ RSSURRڵkWd!Fg"!صk~? X@$8MqZ:BDň`0("c0PH$&& ۶5!4 #Kb.IDDqe۶,,BH˲RJnh|>vTB6gmRR̄R@}YH0hР&:I*@@x<-DfBx&!eYN!KIJ%w"lBDD&.@QdvRoF0Rmv(ennxp:tC)MTBB, BiDD*ueUJT"]vhPMhnBw/DDDȼ*J"wiv٠z+oUNRgU(PGfr:2B4 R"AJ)[J)u]Iϧ"aTUTTjE13@*{HOOW^Wy<ʯBt:m6pX՜"N BtJ0T5"3 U 0C@q`ECdYfB!)%DDWm%].d(N2MSeffƻD1 PkD@`NLL6K2 #b0@DDw8!Dȶm4Mp8TQQzxraVSPk|fdd+WjEEE"55U+((LbضBt]O,uݩr!t۶u-<כiFxLy_""j["E,+lTJEoJYr8~۶Km8 W@ `o^feeIǣN?t.BZC}ٚԃ !nYf۶a)Vz0( "j[޶mU~ömim[a/ TݻWy^zՂ "1cc饗^egg2J)ai.@@)%"#}QI  P(Z^~Ea!DdQ1)-˒RV=l sZ[@uz0 CRrDDDE~?4MSGY ÐRha a)ٮ] iJ4`0n 5)0Mƿ3( ""6|do PJ)e*[SZe)QM ,Xol$f@EP CtۭYν(CQ>,;`JvQ"5hYRUբ 7@bHp?>L&IɩY}ߛ5r?TUդ k?_^>IZ;,oEALn.4.ܪm[u `z^ nfYWU5Hp~P$~Bb턠i[IR۶Fcv$ys3@lGїdʲ4UUIjHKxd$I%Z4YbC(B'u],I*rCIIOKRe9 6"lqB IEQIzPxDeu8]9?'1@l(x7I `.B\8bD(+HR(sK%?w\$1@Ex%wKXK(aG=wBA(+b_謞<D(q@VIENDB`RaySession-0.12.2/resources/screenshots/Screenshot_add_application_little.png000066400000000000000000001544311417052567600276650ustar00rootroot00000000000000PNG  IHDR\>L pHYs+%tEXtdate:create2021-02-04T11:14:26+01:00Z/%tEXtdate:modify2021-02-04T11:14:26+01:00 IDATx{TW9 $ b_%mgrf:;gzzf*3mg&` v $~3?"@`V!|'EܸyyM0 CX%t]װmۣk ! )t]WRd@)%ݗR*4FyDQB\>!B.*#B)\c"mF8}^U^Z~a۶LR8G)U`I) BRUJB +A5FyBW)8!B @HUJBG)eWJJi !4]u-[dw(i^xANM庮q܂D25Y`*RR "h4D\7VBR.B8( r]yViF$-uDz,'J;vh$bڵx^#D"a !JX<5=3JvQFhCrF_a+oy$^-p\U۷oWȼHTWWvxD"0R`H)=BR(^k1h4*J! xRi!Dڶm4MH$ܲ2Q^^PZk3FEPJIqRJRXBKh6Fh w0 d2I*BTWWl m,RJLCCmk4FsLHTJt:-\u]L$ hgcų!ˤ"h4>RdqGض-~ w2H$0 )%RJ\ͭUahFgv7 Mǯ=a4R8e2uEָv|m[!0L+RX WhJA_?XlR÷*T~`<((ľxı-7ugĎ|Rjv7:aPXO{{;tOB[|>ƍ.JaTB~)7-̓@)**^ R&#C$R8cj䱞LBگK׍k4ölϢ8xaA`vp34u5j]JyKF-;e%v4`!3<0g03=hP+r#nYЅ9x&h4ͣ]6H;t1/B/xЧWm[6Ybh8Ҹv[Fˍ<~5A)EEE9s])5-$vf?+2*M)x=.5hIʸr- Mw6Hbv쳠H!EEEN'HsuT)ń |477i47"QxgXd 7@/w2%kI=s?rot&޻F)E,#)sk~~<%:{p_/?Pwy!*ux<lxv Ö-PRR:r1Lc8X2u3gƍŋiwסh )/ӧObs44# n* 2N@H zlk:RȒB|/%ك, 'aXЊ,G< M,UUULsEd2IAA!R\EYtyn'PZZO0 GWwטɺU+=g6Xv H!Y|淔ٙs fu|vtG@sD(ׅR- H :7)3&3򨚔y{.v܉,X! ֽ˖쳍\tzU/Ȕ -.p8LqqϮXA /@<g޽|{ߣSqgϲ~Ĺsg|ܹޞ^֬YC^ rLgA5i߄TWWtc6%$Iz̙3];9Z_O^^3fDiBJJKQ" 0 6oL}}=RJ&L@H x<>۸h4J,?tD0 0?ܦAJɅ.\ _\i1k,emۤR)lfy$q._(*,dqSZZʺW_JRҋ8v˗?cF/^ʕ{~&b`0. ÄB!RL6kpqlŋ%ʕ+ttt k [WR԰EIkgWWWDĽ(XVZٳ9q$"9*E[eΝ;ώ;6m*3f`ƍeD%._X?,tgpgdqgZi`0ȿWtvv8t~#C{~cT*%fΜ---AB0m4q%r[$SI6|1;wuej!$mϾ}a]qh4['Dxj4cAF;wPJ=b}Tf¶\,0P(DkkSkR1"wTRk0g-#vrhnR"e])zw[r޽p\D"A8߯2xw5{Bb8 9={]f9j4F3|"##12{. y_IX RrNC&CT8stn7RU'OFss-⢟;f4ɦ;n>(nZ!9 ee:T;aaݶ8+bGQʦh73o(B|>HR!tVB)OQ9B^Mh.vO[(r3>}5 L a޶ <&dK> rAF|<1]O F#PS HRUj8~S)E^^O? eeeJ wd2%?8&׳ L "iHKJJ2e }!~mmcՌ}A{]jkSXXe%ؿ>S)zR|>lzˣN$i a3IRQʫX8孭8AA[pME `9'Oq) .]ʤIp]7c+'RQ^A+L8'&=Mȫɦ2̑\E zIA~>j[5x|іX˴rۗ-!eFR)]AJ)Lh%&J8(%o!QD8c# #5RJ,Yʞ={X? 0$˖-cyXjӦ2i$< Xl9O=g℉w0q"MMM D~tڦ^Z.]7ޠ50]Ç vy_g\EŘ7?0Q)q ,^n=!~mM'{.tv'S7c@\Fs'!t\'OO+т!~j/NF\5!?u I-^CKu\̲ !Ê0%n]>Ҳm)o;S\nLg(a ˴evK.#w^%ij0~;mW^ϛG~8: ɔȽ6bc-蚫qz/SҏL C z"76?p4MjU o2}ߌe04YK& ̞= gΜfe.X@iY)`G>ϱc 8eY,?h4ʙgGzGkt$Ra˛ C9 i(WqE|ë\yX~OZ5![\daK)Yr%|21 e$OB~?aH&Yx1pQaxqr~?i&9!<3 \R& ;8>R~%jk_eKpWQe̙=7KKK 'gtrL&ʽyGN n=\AGe._n}ֹqE fDr3NaCc @*b}wÐLo||Oifϟ^"Jq5WD;exnųX/xn jk]wS_W z{{ٳw]kTA p(L0kx7 HAA==l۾xruu4?>ul]M mgA!D 枑S44P>KMR~<M$Id;GJ+BB.Ǐ'< SO100@[[mI!l9~h¬3I0D M̟?W$ 2bT+:ݪkh$cTЌ)403_^ zw..]h3!hh,… )//'??q(('NL1ɓ'Q\\DgW`1 ]]ڰkV3w~k5s&~)V'4553qDB.NfOp;FIsl墆̡ !;,455ׇ|& 2">˗8"+[n &`o\*tRbT:jJ5d(}Rcg_ptnk4tU‰LAď~>j8a\esaJJ)Kvڅ8RΝ)`*PŅ M(pi!۶oυ02nGUZ'҇g 'w8bܶ=gdۿt!wȝByẊao CXk^JD1Xdk2ҵh\ì A_@ f72vLQ.W_|wx h;~skTI^)E4qVy=6i!rP"[tSl!4MFWp.K,e…?öTٍk9@M^!Z8iH'Z|Ɣ*~/|!+t9 #0Rjز}}?t_n-++4M?hσ|uΟ?OEy.\… ,^x,7V.ybT3vwSXXٳgپ};t[SIRcRAk4/vKgi9D,8ģ;NN.;j;\EpaNS`y<_ .??äI0LP(Ğݻ'd'1cn0X6>ӦMǏGF(wKZ? IDAT*z6BZy睷7>%KrX=[nӿ+mk4+ )ȳ 7+b\i9)dXK RR̚5u^XiKOo(E,v*cA +V୷O>#XB oۆ88iiW*}BdH4w8o}^/={ߖ5q3'NI53#\)  |>k0Q%d7M2***()'gPRZiBDEJqU0MTVVri򨬬Tv: RDi,Zҫ kÍfl*Rv.2aǴ5אy#u A,b?F!/ZN%IfW |kZ>wr}ws=Un SahB)<bϵvۃeJTWJB`Æ OJgRJN>{А&*,,b͚ N  qA رz0 ph{NBC0DJ``w0-B_&RT*ŤIm;qDbH)0a$8[(,#~|;O2ox.w);/޺e97d2 78|!0aP?H˲d2um-b;wλv! bK1Ei BePPu1LeS`J~{GOVLdkZ#i*O|kO֒/WOW'˧# #|Iud>=4Rܻlq\|qkHkhA3^0Ka+V< HR|F~/Za=llWA.|86j_S}ZEWv_ɴ5R)֮YMqq1 룤/鵵̚5Ϸlm>χ'PUU5)**XC;vd޼L-T*ŗ۶. xrrwYv@vm^J}Q{`e\.P.1ɠ}V  qy|okk3MN$־r Μ9˳~`K.˶;x"mvZ[8~]]sכ[;5 ]U |6; .fiN^'?߲%gm{NojM }}}vMtH$qܴvJr;9|RJ(Οu]Z[[?v g|w}4x}4 ޿tg 'h'J=@2Xñt:M8 ZCn پcMƓ?EB/@p *~(s\hjayXP@4yj -?Iˊ2ZQnIՌv|١hnׅy$3g ~;A:=Gƾ;枓No(6_Ue,y61 U,is 7ѶR̳,.) ,&`;RcyoTͲeYp5YTsvz煕+ygrJ[ʼwi4RӬ[eוw^4h 1C !G5 (<7JiS3fV;I&~Źsbx^L$G^^^.=ph0}藺x,F8Ʋ, #SY4ML$JaY,8Fs=3Mz*I֭rɾ}.iAh4@FdAF2qa?gbq͛ǥK0 iӦq)GIi)]?+W9s&6}ƸqwK !`zJKK6̙âEeY\p>ۨ;n{Ffeժ8O?0!fӟX h0(emY%%.c1d"1(\xsR;b崶PXT%K8{,Uh|3\ϝkB+i::F67;33i/w1R.Zq:)|!(WqJR||j k+協hg2~2g;օ<}t&ßk\eYLeƍŨYJbR^tC{Btt:hU 0, ˲-}Oegnx*#Zre{]_`nF3Q(o:vy>P~3H[:ultƍgWaGw4JYf9q8Z5w뺸eY,YYgs!چcQD"A* jd1lhu3s>d2SqC{<[3O?<95cS2c 4?W_]G[[+?~|Y5Aw]'vN)5g-`޼yTWWS]]́?&xpH$>Ƶٞ0ь KZQVƍQ84 Mt˲x񥗘3{߼Ô)S7o޵uL49a7 ^XɲːBkNx߽ԓO2id ӠB6l>u+R+uVvN4%ܹ444<Ӽ!7vppJ)JKKcʔ)̜9rCdǏٙk;4G /WQ) X 'G3| Wq<Ȼ9sdZm-iPSS/~sNyiƏd괩)Ӧb&ӧSPP. *USOEιBx$ׯgDQbUU~1k [){U.Meojju]bPKCC^"~tx<ӧIRضh48PD$o`+$J$w]aesF8#Zyo}ۄay8Ccc#Wth"Azzz8s4/"q|2v*EII1\9=s>+Vlr;x$k&rq.\ȲeBP]]M}QᰞC"$X^0ϖϙ9tPR NrI4MIa(<Ca4F A)B a_+@J&Uwbq0X7 JSx:%XLZC͝;@^{59LqdƏό3y} 0L)S`&Ґtvu!dJ~9qWx"(..X,\s((++gƌǙ1c}}cZa'Ye 0 @)2w2N"'mI]P 40M3gH)1 2q"Haضة`i˔Ccb{wF6h4PZjHD=v3%'" d"T*A@ ,4bd"4662sq._n/`k.>6kF0XmBO0SNSSSÏ oMd*{9J<c9k#+<K*x-(L\!wIbVM43&xM^Ags$'kh>M_׌]<'i<)ٳO"ĽkPP,P!T (PGH#d2i.a0+]A{{;M;B8{|v{ϮUo'WJ7`G@Q$ T %@R2SUq+]1JAh(_db ==Qt%@HrdT:rtiܚpGR08cNffZ7ćJ;SR8΃P/0lҶ5@[%DA9Epu6h&5/E:5B /͖NmEځ{q<>>!=¾BHASԠu"f0p.L[T@Ҫs"PHW_f02g4!B/ \_0 _EN3Ҫ$ifz\"[DKa.IV&(/w<)ɓOQ^avg{ӫf%P*H Y-`L qp89ɓ<971qE uHiz/{Oٽcښ`AZffvY{8~svVu kȠaۛL>B px6 ( 'g@p8YQ!DAh8M2+F)ZOF2h]H",r6G& 5b ivѵxV# ̡d*ea^#o- ̜C[[ w?K~L-&͠ d5BՈW躞յ?OgU*kRp-Z.AA`LUBkIPpܓ6|(Me+pQ |{E݂|rt6f-+,L#N)cWFGHiIDޭ؝V$ˇ__,W-1;I]" 3a~E"LZj۶ۮ17^.L]&͠ EDud9j˗IjϥU4ݎ Jl6TM'?0NCVΒL>0fQQQ L, AL6kv;D䜀,h(Ȳ@.gDf.ϭz;(--Eu({!!1y-$X'5ȤSIX .tp;OӴ+~.>q#?H&jRTTD:,tzzz)//G(/+C$jG\.|Ņ&]3m"''sj7lIX,9x TG>73i=͢(B_rUUZ^ DQ,ZEQ jRFgn͆ UU' yfCQ2 V}׬*su /3"9!?9p:LBqqʾޣ+Wσ_|*oF'/CC!$QQ^;v0w$Q" p+rN/ywx_\͏SDt{DBC5R\ܘjc=ƃ>HSSO?4 p뭷hhh#M"/灺y}qN]r|Kq7%bM> MӨC~&Q':q#CFlX,)))axxM{{;LL&S0>f!Iqn7Ìi\01/{ͺNMm NaZY6f=v"24dǃngZm-=׈$Yy 9;^gYaíosǺu"gݻwBuFFV 'f OX&,XZ[[aڵ?uVO A*: jFMM 55;v ֯@kk GE"t:)//gZpEQ!(--%F"J>d3&>FB(IZKxCc=rI›5.**bժUHoNzzz3ghѢŏaϟϼy$>ioo'Xt)U,cV@4bz~Up@mM-kg>1?2:J("Jq)FG#~VZC}R|>(fض};lFgg'| GO1glnF~3825 \>FI~ k}}=O '?/2>|+,_{@ պ(uFbɒŬ]{ obM˱X,l9MMMhEQXd ]ױe%lv ذ.niE!_"3g,}qrOQuíɽ&S2-[Ɔ٬ݻM6qM+9s|Ƥ_(3sKKKKap$x<q={6mmmA`@ss3( DтfQVV B!XLU PE9zAr`Xlٳ˿s=[o?/A K @ D?^,--%JhooV0rhiӦ1c ֯_֭[ZUUwɏzsOتUXr ٳ[hctǃ(Jvpt Z[[Yp!s{]v47cUl}c+CC8t9ql6AaXp|n9s&[c \n;Jyy> ռ+$Is2}:׾ƞ={رc,_zlf X, Å֨+ψu' Ξ=Kee%^T*5mD"tuud 1 w|>|>t:=犥F'Ocaho`֬Hl6h$¢E YNx#CG JyYf %^;2EE"oz1Kb Fyk_c}(JW줩yJL>Fi:&o}[ dYVXEbpAL}Zee%dfb!\[nV۷^z﹇`0H]}=:MtR~_|9q+)%ØOUUnZ3fK/yzvN^B<GQپ}e_ɵ >}۷QYU`!\4-LA7J^^/hh4$I8B1{40BW&Ӊ ( 6mBlҤl6K"v#raAךH$塇dL3g L^7 L2D ( ի]zmh /0:: $bzIlذd*SOEU-6n@{GDŽhbˠ:`%Kp/_i\p8֭ LeZ[[immL>&Mhv֬Ӫ*DL&C2,'OYr%s,ȯ̍DK4cǎ`BP:T UUHa ,d aw__,g 1d2oc+i|_g``={'‰'8{, wuD-[JW~N+VpADQdΜ9,[|;}m X7o?bʕ,&87a֬ٴa#^~%6n|<["ƱG6nDEFGGtRYYE<gyu͛پmv0\N0ǿUTUѩ/Ћ ǹNga&$2MӸ\.l6\H$RMݎfH$B2,i$Ivk1z<022Rx b<@4+lgd_8 OdQ3sML> RYYmp4n@ @Oo/-MM77導i?K  k#nK<ˏ|Fc92 ###0LAӨǏJ&IRD8_^by\e˹sRWt;ΡChhhf㴵rH&r'&EEE]{ 6ӧٳ{7022“O>I.㭷b߾}8N4d.r+و믽V<3j^|?T*E:֖TU%if'NGEZ[[i믽6!'k2]UU fJD*n JOO6lɓd.\@{{;UUU,]T*ECC@:g7f#N.kMd664b̙r͒ ">QѹsY ?w":rR tt:=aÈvIyz:'x uApKϑlvB, O>J6=c m?q,+}j.w!( lzxB,w^(x^z{{ioo'z{{d2B\yy9DwWti\y*}}}ȍ(/L{;O_@W%*CpX,<1>vy9ut|j]Ư?j"JZ2`(RTAUeN:E(*hZȌw:ض6v;H$r躎8ex> -0&ZoržDgx$dfy Qd|ݎjپSdT*U(A-   5$]lomOӉslEYHX"|`ɵn>~' : hO4xi\OMLLϤVUUl6[AXiKg!7+d ^r7cx$ ?KjLEӘpQe<5T]<11LA7unX Ql6###XVd! 3$L&j%t:bH$$Bt뙘\+|*7 /N V&sCP2 {^%/Nc ZbBܐrr8iML311|*YƊZ8UhjԉP(D</HQ  AcL& è(8mbbrT;T&b8lѼm'OȄsV961jLA7Tطi zHD0$(;1!h eorBS\75yML& 8Kbjг 9Kd2&,tŶL֜ \gGk >FSiiE!#2CCCZHt32ڍU0g 1 EQH&(B8ehK=\_RQ-9i[N$ͫJ! RqJ L=3&Qwn浘Lt%JJ$τ7w \ӴB67~㊢y(A/c?c?3͒)zLL" #0vFC!RNg^UrK ”c钄CW+^]|N B`Bp4&*ΘXV㦛-D*0Wf-VCY4 }xW1V$ ͎j51# ^/,ٳ* T6%r3R3}5Ek}z%V\Ɇ"۶CccjcZׯu fXdzE|>2͛̚%sxC$R)hTGUr}WvՎk EE$IEE\U*}>Gds0 '@(yT:Mqe%B2I:EL>cè^5:eeeUN8^ИXx1K,!ΰ{.$I.ߧ q,URRºuz9u$ n\̛'o1#M}}EoVky9EQJ}RAb:ŊhH;ׄ' :ٜA̚5 ]zGFB\`(^G8&W;^Y>yD!IU8gϞe͚5rtwuW7ޠ}( mTTTp}f+54t]Q!ŋ2PanLF><(jWBހLLLrBQ,6[i0x*A𸏜Fy:d2Yz{`d¶̝;N rH$;`b /YIy Ȉͅ Ρ6-uT}|5\.XDNX̊ S}-)MLL &H`DcГQb˻EQd``;wa(N;濫fTUЃId$hЗd2q8DwoQ T(>miMLw\Dc `łU[+XLYAJ>wMxw8u`T>zz|D"$B.g?)LsgRYYI:&HsIGC߇t:?vuJs0 u (6*E MedEQtijBF'CVQ]%dW.!4-o{{}p` %iLw$)<4a;F5t]Uuɩ>I7T\Z]53O^I~=9_XI!*N$ˠ -"LcuYZ-e?ppTr*p>LL> .~f5Mb^UqnEQe*\cZXd2$I( D\N.%Q>e5Z^ !kQM>T80dnaX5 AtIǒ ݁e4mjMLG&ŠNMM 7^]h{ܼ`(7_1˴Z|lΞ; Sg㻵}Z\},9r+~rVSNQ]]#Ysj.\H_?CCC9rt\fF5^,Yt:Mc \una>sŗ^ x̜9`0G&gej;e s~`&&&Snu]p/ιsZ:eenA`dtbrLo_?^zzzq8T\.UFoooa*%%%m6\.p?$IdqTT:==}KKJlnl6*+ZH& fQ^^f#xn\nCC8N\.}}}i|}b04h (`(DUU57nd˫E QR\LII hP(py II"(ǃax롿D"AII1h UU ]ON&jRSSf'f!Kg^EQ)+-% 0::J8L jR^^h<Yα;(..BH<455` 222œ9sD0̙̝;Kgg'd!Hr}qTUUw9p ?cΞ=̙3u6͛;۶qtmV 9©ӧo~3g_z6l K8ϿP( \qӦy:H`Q 1cgϞc׮]~24? 44;ʼ..T2E& v)?ظ.JKKa$ M/|x"A4[vr#_Fe\.'44|-<3d2!mr>c֒L&ٶ]֮YCkKܲv l eTM)VX7ǼysxٟpLɯU{ @4`U|~122B}}=mmmBWW?~0:.45s?СC1m4C,^nϙ3gޭh_z?̙3x=VZ(|?ww0{lf̘0/"lۆ`…TUU /PUUFZZx><7/ T*/^ن IDAT¾}z<ꫯO~JqQ1UUX,LPh,]ض};@T*=wo"Y8u4 8p?%%q1&ł7y7fl*;vtRUU$)>_+v^9ZZZzI:::x' ΤٰNݱדiMez}g3K@7t= Ibǩ v)̤25M緿CII1 .$?0HeEN'^l9{ۍs=Wq9TUPښzz{;g.PG[[nښZΟ?,˔r)d9GYY}̞=.(*jΝ;G*jk+H4'NL&uӧs/P__>(4QV^F(&S\\L*FXUQDHdzq8~b5 عkl̘n1Oζm}V*+*D"8===TUUre RTTh$B*&ٕVԺ+0Ŵ"2U2 T䪻- ˖.|,;&JnC!<7^o>ad2i144妸;w HRڲTsAl6%;~`0㡯x<΂of1~{={bZBS Yd "J#sUn4{ZTWWsI$IsYxUUUZ+o#0<<ϟ/Jqq}^Fo_DT*̚=ad9U:N9sfJjR;>jjjȲL]}=mml68r(@ /[Ɔ;yJd2TVV9p +W  M#<4D4fz*+!d2$I !31n`ur&YVHgA@j#L"vi%C{'iM}>K%F. l2!H, VUPUUTUU$ɢMGNQ2Y~DQF'<6sLf͚(ܵbD"ⴷcZrQSSC.;w fEII U) qJN Y)9Z[Hnz{vo{SU蠫k,y 9qd1Ll457sYEL:MNQhok'ɠi],_>^//pQDId2Ioo/##R):::p8L{{;CCCL' 2$LpZ̝;:{N:x<( dPT\hj̙33zzzh'cZGG#x^dYfxdNzzzIR̘1vޅ,G%b(Wkm"">x<>QD(&u %iZs^Np-zTmN:mN(—(kt;$uJ/V|+E>a3c&&)++>H;㨝z6mύtAW_z-B鰽iQeUUŢYV-6M///' ܜߏq'x<.\.QeK6ZVinQLH,m]wEHDeE9nF(l/1~Eq>qsn~iR-5;u}H=+U gk4mlwsJwv/4Ksq/W~wq|9_&W޾a8{%C[AЁjp]WG,r:62lNetCcf?`X]]C,%]Ѱ 0J Y/Ǖ [/v=+e\cMXl9oJ:ȓ>]Sy{|]1O([d -CXGvI,gv{t*dRx<ڢE7'%rHAbMkkq߯t΋O<ǥ{9>Lcʻ;v'x.cĥ6i6Z/u?hqv1b  K֯ӄeOZN#) G4T+4g@8g6}( 9~-.\(lc|'w7oС>|(&>'ƞ8pDU$R$l6մΌ3yw[Xh#Ϋiڄ㎟3FEEETWW3<27qIE!Nل).".4]Sh4ʡCcrm ` Db1r29YB,C9xSu]' k>Ç9r0B"g̙̞=t:éS*+ b>.]:;; 粏Uv}2^ZZZ;̝3p |KkraMcs#"'Of4M̙3\iӘ;w.JNA2,}}iok/,^;FwWwuq;==FBSq`*i 1@ i"%Jub?&x"w* BDV^!ǿѣGțvJY#ǿ;D8"2٬Wn IXb~h4B D@`y{\pN6+SSS*{=(--CH̿~t8$ PT\D2vZ-?;ikmdRhii!1<2‰Qǎ1} N`SD=o4uQDX@MkdXA/AVe`̍0(hJUuB(xB$IRiӦq}ZGX~=;}±´i蠣;w0k,:::ƞ={T!ٲvIqI (o:[^yKuu5sMɓ1g\jkki8}ڌ_c0/<<3fp8Xlѣ%~ nbbruثA@J|>ܰ&'#g]aTºWD+B~ZZ$3gͭ$B =\LaC188H8B@@tdO,_X,ƌ3ٽ;p8숢Xh#7t]';B:Y$dݛr ( `6}}SvenpU QiLLLN@ETEAv{G6P?z 9P3Q|_5_׋azTǓO2[h"' H$ k^尊`QT2I"nhkmo?&5~e[ZD"q9]TUVRT\(B|s?yl6k&],'144Ħ捻6FIT&111ab/wQnߎF) 6BLY+r/2s̡X,F8EEEKcbH2}}=DQ[={6x={FZD"QzB PRZɓ'I&D"z)?.\ 2p8LwW7AA-)*.aD$g'Nb}9sf&/D"t]ܹs\O>r'diLL{>QtP$8tPGG1759M'NsPOA pc(rܹD"nWWW@a+\NecryFCPcB|yyxAH$27C /^¦7q aӠ_wAHӿTŤЧ`br"DwXmvDYՐN4tĊ3ܞJ>H.p9.Ǯ1^GrTD*whnn drA"S)_fbbru`ǰ ˎ*bsZ6\vrMFC і%ӯ MWg' datd 'GS˜"ח17j7˜~=ZkkI0t73,.wp Ws?I1,[e˖2{,O10xt]nQL8Nv``R QVV\˥~fϚeL& ]ϫ/LAƻq 7P_WbX.B&,[ve';.A/[JEEńFcɒJng%xBs^:e5^u<^/nW^beja :tJ4Moφi8Ӏu!"{Gz-,[9ʬ3ؽg(az;˿(qm"I;w"G(~::V:sojw>N74L0rM˩୷yp˸e"Xk^m۷iv+ǎqr:Yt -#Gp뭷P]]Moo/[|7DyEnxyM˗;۸i2R G5W&Qg'êL6#EDɁjsK%A"$ei 8cʘ\N,0)sm-kk|UV qcRZZJ: .45s=w`]{3l›oE7o7Dihgǎw?0-x{ƍhុ念sټ --[|>>q#;vٳZ˂7bYX,̛;z ]8u}O$8xoERYY… b7uy2<<_K;u$u4٨VKsCsEːNFSB/2?Z0/U~\O288N>L ]UU9v8X.\h/?̿ۿ#I"̛7EQa`MȤ3Dc1TUeUTTTxX,X-FUU֫w, n4U#I`ZǩHOoon`}8؈륯7ƎNt^STE!L}HRx^N'T6צkR)9_+gG|M9tXRB6aw8Pm_h%R#?)Rdl+&:}@L&󡪒FtY/6vV+n%:&&iܴb/濟|Y?GWeҺ BY39v8K,f pQ[Zui,\bRp8p9TTTz5m,lիV r F<@$,PǏq9$eB㺋p8 Np$ $I A @ʈ@ Orƌnq-kD"?pE LX\?/- "v%sI¦'2P tff4YmA(:hWRYY|3iݾkEQѣ;vW"puC=DQr:|3 ^ȇ1iF}}=6SOT*y1&&wYfaۙ7o G"֓h$ٞ&araWݠN<gwr :::;wq/P,wwnݭrZΞ;{϶m%JI" ׳{n{xrfioMp\>|P(D8&s.vV7z{µkƬY^Apa}2,Vd*'C_$Ӄ%+ٴim^`0Hoo/x¤"wqg9}:9 `I+Sʖ-Y=ޙީڪ[wnݲޱ-`ٲ%QD D AOxC-0A"4ޟ r`yΛ'bhh9sfr/^d ,[;w]6eƒIextEL0Y{ x;&.UJI0o>#\UUU֑ɤEu&&1 7>yv{8~˖-W_~GRW_5!NS\\ܹssMEQ!5i&&bϫ\GZ{mmؾM]wM__[C:B!ȷЮЅ;[]Ҷm_Hlۡ0H&ɯ~&EEEؖE2o#b6mGo~ҙ ǎN, )%?z=L&Rq9ynT*uɕ;vǏ_էHgvލd&0m;@?iT#H)d28un,?R/SD6ˑVtM#N:P[*8B>#'?a||<}ڵ,Ysw"O? ϟg߾#)))aʕTUV򓟐JΤ:C,[nAtYlg8po۸ݞ\ֳ8 λbQJW.khh?@[[{Ʋ,oƷ8qB&]1t2SbܟL&/x|\LLVoL29UEJ4n"[nE u"!$H\r SM\R^T7TIE2Y.j8Xv%ӓFocJ~A$d״|###7MArH$wމ }lok'<:?@m]eXee|Rxx{ŶmU"V~ ~X^.Pt6{T [+<Bߏ}Y92\&BHӹ#27yǟ@u]:~ d'_gFeU<-p0k4MLnq$IJ&'*ʕ!OL>} ʞ _mۗ*(FPUUEt|~5܇FaMD10&({y=B&Ų,EA(nD"[&p *8ۃ e#~n}o}Yl&{BJ޳g1\O<8H_S R'f#j9wlDYљBfE6a۶5۶u]]RJkZvU:}\3MFPeMvD+*Eדl?y[,2e5>9{Qtfs,C9K)JT( /X.4M:N0#nG $ IDATDi;# #$MOw55L|r8Yal,L?ccc&b?Uմjdk+}q| qt?O{{CCXصQ+mt04>%C2QkX-]&]>"Lkmr\aivjT ]Qf<[)Il6W5`˺`]8L&M(v*9_ahhm [ǎCӴɓN'9tP~bO?EAww4N>'[Ǥ(#`,&<-p?7*+ &1VaPz.B)|&ʒu$C|q*E㣏<̍7܀mW0 {]6p )%~{s~6݃ئRX]\Y6׳,iVWeTE\3V\K줣3?V[[C`4fdd`0HMM K/fl|QfS\R0xP(ps-BZ>T4|~ٱsW.3iDb1ci6nXOCC~# Q\\aH& ~^oZq1&DJEQ3צ8#aZ j**++)))^x7D}}7{|>~op0jp P_W[osA@X%]eee|뙧կddd|yկ9¢E7x tw'Xv eee^yU6?t9sa}<üq9zLDW !+f9˕(R)cǎQ]UEqǶ9|`UlܰӴhm=|3>vw\݇^ҍ˅6l==^m'|;f<ɉ-P^^A -[^!9cd2ɱcT0WTj ܲ&+(**b,m\LySZQfkiEY6l1d2eۤR)|>~]|ٳ޳@yd2Krʧ&!~g+.݅? dv4* )o0r%VùFH$*Rr\w+}.ŒEি c~MQfi5r7+W@tb1f5J.Hvj*2, ,w!V,_N,ò,Dn.q,YByyijn躎&H`7|3L2t4>k,x#uuu8ad tm@ںZv~Xv ˖-ĉ|)$ \n1xm7+V:SK 0<@\?6E W\ԯi mǎ &w5=JOo/ccƨ'Z8Mט7o.&8wh$T4)%%%A%%0gB -'i=yAjHS9r޳b1vcn;Fii)q0?ޟ8Gɤ3 (B 1_ Dm&\!ot0#f/v/"P4!5M0VZc~ ˙z\}7/qVYwIkk˗RS69ᦦE4:|5l}Oeڽ{OZ4G",kittv_{:!lr ӧ;.ωi }}Nv5)3Ϟ;uv(_@ j!:'/C g3>6j+x ̖ W8 \t]*GJɒ%Kp:CCCn:̽׾v޽t:]I(ʵQ/jJq 7X=!5=^MMMH%Td2,Y®ضc,to/bY/SL:'i!p )3) S^Kz.;.dTTT?clvSYYɻnߣ(CJ~e/?18Rp8̂q 7.ij:ŋfetuu1<ϟ(GJIeE%ϧal>˖-aZ2 !Ѓׅlu)IC?B/r#Ƴ H>xoo/۶}̆ >"w|W޽{xhf6lHSSmNa68RJN>uǏ166&1ZNeɡC!:8y!O?U?1~siLdΝLr_ߕ?/p資nB wcvC bH8EJ&IK~ Lsז۶]ػgk?|UwkƉ'Rr8t`;0wo˖/je׮ߒR ޞc2&"  bu}狐RRSSC6ell@JJ(+B:LC-RZZ)Mn۸*60MpAzzD"D8w*NWZ9+~ۗ.OJ3t|z@RأP]] Gط(M.8ivA=kRKӓ:55q\\u`0HCC[1rh$}8ɢE󩫭f|a6o~R6n؀vsӺuBx'd2>MSs3_۸6իVq 5H$,X'ox"/LN<#4mGX$7\LEGԟBqM5]|y&&&xgT:TTnZ@RQQ0H%;~vikoslnC!.YkY{S~4Μ9sI.w)%]n8@0dÆMLvOmiZRiFGGukHI0ZӜjk4`)%h}{9sKMQdA/˂(hj|c~Ƴ<5F !8p K.a5{Dr7M2-4M˵̕d4<ʉ'8֎iAJIQQaD.x,J`O <\~jIee%LvQwwݙ/jJ4f̥1Mł줮5_GGI nP}V4RDQj2+/|Mz2͖M&y?>Yd``kVSR\B'NL湶.yOӗWβJ&_f?&U/ʖDVbk 6(QRZJ2$N`bi-ptUE3 А2ͯwq+n''H+tTaz#(룤MMQ_@2"H\׼En<~J$b%R eU~1&.0lJC:(IVZH snvqieM ̦AJФUnım}_W H YpCCi4!sJ/Hsz oq~+?%r!8RbfsC@ݑ[ch¹d6roPӸc膛9D{&[9"rݙRҸ.R0GA:!4l)ȭ= IHA: VR$/UuJj7VZL.L%1IrӾ+&=Gw1V-(I/X_w>ƛ2YRc0.Hd%W$L @) At)g\) :2T[Ȇo,QTAttCY| 8Mz&[8s#ފ/XJݢD{9 V1Jr? t`|!BxO}Y"?Iđc۠mG x+ʌ+0y,T*mY!xx=,$ɐd4 ͕$IƘv RN͐eQH8E:ƵPh n_!t2 Ν<}, n4g9IyV?QζL'p=ew>Ŭ=y">>Ĺgceѡ^ۦa}>iKxy >)_+#d#lhzn2gR]Q$`~)%݌:EEEnʰ,Xls: u%tc?~dd@nCV.?@ӡy*`I~Ws>G )C &?_AtELh؎C"$'L0M]qX,F2ϕ'DnV6}#2/DZmLs5E zz>QT@WL q h$&bX\!t:aH+Kb$˶Ș6НLVeQ]Qf0, DALD@L&NYRq Y3MQ0䖑K 4`]ױd!nj&!N<\]^S\&%6rޘ|A0oرctM_t:O6eݺ;wѤϚ_ɮ]ؾ}Yǟxޞ^|cQ]Qf:&h$.! ф@" r 8B`kWnבJ&ikkc֬YXpshhhrNY ԰}6jjjYp!lذQW[]w7?Occ#?v^ȑf̕?Ǐ2a###it]gddzl6[pE6XPU\0JK񇂌=8HZ `:ЮxB-}ւG%JqA>Xc[uqIzztYfUTWH$0 ====zR왦ɾpn- IDAT-ZĒKȡC*`(@MY}ǎ1R\RB2LLpnBw͆ ٻw{쥦+VOtRb!E3 `9|@tj\4cccعёQlY mɔ?_RJJKJ;o.=K,qcz[[7r r%0<*4wY:SO=E6e  2:2ڕ/blذl6YT@WNJliA4x[^g%)cCF:KzS6x,.VR4M:;:=Ct0eK93&Ƈ:S{m(!9~e;B4tMr3\iW)R"33}`5(Haސ0-oiXL"^7x$)JQ]Qf8ہafE5ĄıH)G$E:ndٯE E d`ZgU\Q 芢.SQBpcsɻDž.R(3 2麛yCATpoLޒ۱hYG%sQBPP^Y?ʊ勰LG:؎HGN}RJ7~GԺoE)*+ʌ%z=̝SO3G;sHP[ĕrf]|CNSOJIuu5Up4zsRRVVS%%%ضMCCO<$n;:sz۶1M[ׯgS..ll{ZYiMvڧ!Bgfڵ9~8wy'5RYY_!^j+ hcAܹq)}R,e}RJ\.UU륲VD9yٳ0k,Nq=r̛;>VXIIi >kגH$رc;punbʕ  'سg7cƍd&;vl'Nzj*++ 9t ݺRzRJ/^s=OSa v;8w/ ,*ϒj+ 6>utJnE>6uoӗ}o+uuY+'䮻r t&^/~fsP^^AGiq[n|֖+xik;O<ܹsÜj;EEE>(bo222GM(l~au1|u8qÇ#FWWghX,G}H&)`*+6q$A۹ﮕtK7y]1M+ؖElbh4D<@kk >ŋ3{?>Nm-OʡC ~vIUu5+Wd||ݻvq"U,ZB粒}~Е+HQV^NMM U,^UR]29RinÅa*lKIx . zqt"B#vE__+WG#rIx ' pA ORhF&v BؖE$aEx<aɤD"4551:4B!\M@JUNQYYߢi~ё ʩ"e˅eu .!yhUڕDb tT3%!]OR!p\H JÇ_g$Iǽҥ˨$Lf0M]ikkcʕ|ࡃ477| ~288ȧ~Cm&p1HS xTJMS`>ϳwt&<t/ 2Iǡ`Xp5ē$q@cipXr8i@<GuxIRTTVCˉ'|ٳg1 M'ql4M#eIg  !-[,XUVaY͛b###$ ^ŋi,/"D[XWO4:;;$_]T@WLMSdCC>zώP[SF$/ xABE>t]\vmD"|4fZ͛7sAFFF8?t:- O0U*(林Rޝ_ӓOb# mDтȤ4CQMM<2efUaZUH)P,Ʊ$qw$ ]lm'=!]]m{ݗJ&PTTD2b,`+OJ}BPB1vKolqqs47=t$]gΐfRXKi%;C8&<ȯ\+*+ % >1ί^eǶm?f|UWS]Qf4meQU|*(ʟEQπ 芢(g@tEQ*K(VdSEAZ_@`8yiK!YS]}SxmW2JǤRRRRB(*+ 'E7H`q`;.guDS]1i!N룻nە2 vIRL4Iab&h\Fk*a*íʚkH2,:EɏRC4B %z,YoIbjoڴw}h4š57~~ebb"6?0sl8 x㗿dYwyl6W-mܹ<ȣ ۲ٱc;Ǐ[4 m2ԉ@uS !pqBiZ>EvŔECC{.lοԾlοrvvv)//֭[ѣG,+ZT@WNYA'!_uIw>555D"_Kc|n7榛of…̝7ǏsϦM4kt:eY1q>YG̷Ev܁iR)Wӧd֬YTVVQS[C" G]]=55H)innfllsd(Mʕ+3w.]]̙37߼`޼y,^d2Ass3t˗(++ԩSh ,Xt:'B)LRJV\O>AwW7ʹsش^.Ν;ǫB:.ȋ4EjB,e I_$:3gxg;^3,q1즷qjjjgsɲoߖB裏1agϞ|^z[nukױcn\q駟ᣏ>d~c#UUUl۶?==,Y`0'Cu7@۶ih5kgԩS,Z>C?|Ø,__OrL'LZUxttf``xU~7r2LAsP]Qr-qKӁx<>PZ~uuu&b[={v#4T2>HIUuY3Kyyxmdh+xWimm%KlrQ__Ϲsݭ[Yb} ,`t,Xں:ivfСzp 72_ |L&y0Mۿv3v:!Wo6%%%$ V^͡inn. 4EAJASSC;rf7pcc xx477aYV~̹_g}|+=c ̟ѣG4 0\܅阦8$&k]huI"v(lڄkr}j\=7153qt]?65n&T dD"+[|r|I,ɓ۪S.:^v2  PtEQf3A|>_~B a3çۤlsVJBdEĢ1^{U4#lظ;vqڈƢ؎Moo/mL?###gnͧYnTɡl0k׮VoX/#LewIngʕD#QZ[[hnj'N(p8LUU?D)%N䦛o/]*9~8dG~v8P%Kys%gœ@\Yqq1ÇBtEQ ?GyM&sdHP!.;^SS墵Ç?Ŷm àaɏLcc#.a۶hjjbtt4q~줦T*E4eΝ }6ػw/k.]'u RJzկ~ ly "rTZ9w/".>{wqQ::NcY?4L_{-q())3g >(B͏~C"mm_=EA/ nG0lwC#HYokysٻw/===oᆪۺ;+h؋:Lɢdre{,ϸݙd9'k7'k$9L6e2%}:w.i==twwMX%wLmmm!8]_ {ʕb1w-HmT+dNdeaY5&tQ[#L^:`n!6>' 'ɞ)ֲ^._6~7^w1*A]QJ {,x<>kN~rQ(uhD0Wn((m@(T(cU7^].ފ 2Ǚ. /׶mMh?ogRHeR-f vc/Ʉv?aA84:TQnW f2ia|}Dfj SQQA4eX4}}x"LӜ}_d9se$NRJ|>^p8<+jT8E#R:TTSQQima;IZ[ضsmegC5 2qĺK˄|>5rKI)ټe kv{Ek:ee}^@D57o!L0<<̲e9?O<p*~[<#,^ tuuFd.b[6}:Rw(`:n׋H;V.w~InKR1+nS40Ν+WR[vD?>tk---ҥX_@:\.)㏨'x{>vZ~?M\.֬t9svdpp0oOBɛ;ߤvm->!7o۷/oۨy0h5+@xpsH$(///k:$UYRJ+x'iЄa躎"L`YV!:bb A"yN8U'+L6M&Sx.i>*0ۚ\X Ǒ`N&%}!%| I[2M6JߠF.G@`*+Q(4mEeT+r)%$ wE{*E ӝCqB%@Wyaa!5Vra9/g m2;EtUZW)i]Q-ZĶmX`!Z:Jz#u E)pL|+Lr͚)wU+LGyJz{{P|QR\_3Ÿ+eDԕۛ8Q[ò>qEt]gÆ TUUASSÌzR>oEx*|ft0R((( <3~Lu*RJ󱦶Q]]myT%tE!BnMߟmT*V@a!˖VFIJlE+Y@ws SsC_\HNJI ࡇ"HM lۢt:n~?X!L;6eY  i>׋i ̊2;I)]=܃e8r0>m}>'H}u2,X+p*۶h 2222哌Ԕخ`1d n!IDATZ\J_KGϹX 5.mzF5v7c.~~]Ͽ@})/Y  CvIyYϿmmmTVTOORQQѣGٳü/))W</O> TT*oA8"Ne tEaPVVNggmH EETVV1<<<DPcv`4}˕  )2l2jǃ-4⎎I5: 1 c\Ώ_xyGna&o&|žYHI]47_d7駟NYnΝc8s 2n myf7Bad+[;CbB4gTDv>{ P#HL $~RP; DA>B!r0 P-&JSOrqRT^OG(- 86F 6Y #%-7ѷd Bhu,4lF"֭[ƍ)--%PWWǺ;j26n]wqW]/^)Yj5ׯ{-؊eY,Z-[p}g?v?$eNRR^Q+`>nfM-K,0UBWs*x!ĴTIk$4åۘV5ljK+]A$t=k8dl߾5|tvvR([nŋ|>nJ$n=d{d.Q/_?yd20OA(Gw455aY}Nߏ"o@W<2M`?XYCCttvN7?H nrgk%'|h!EhH^҅$?/7h4IO4455+4MN<]RJtà5Ot=s P;wFRaJBz}r32c&8TUUkSM`YtJԔ)<+Z(/_]IH :z6mq1ݳa00tcҪ"[BӐ΅!=/gjAS)J^&{rۓ~eBh|瑇Y<+/_ɋ7ALpЄ]QfUBW$ф61\fYAשFjT+ < PXO~P&_ 磏oRx,\d2o-gϞexlT{?" an bs3GU(JQ(yBG'~N25u &ev)%Ķ144ɯOR5oh4ʁ枭wx^}OՓD2ר@Wse !hni_874nrS$KwvL;YM\.\.W.uv6ܘɵ{+iNgPnj(yhxxxJMV\ѼqsxOxT 2a<y?{8JEcbϧWmp\mL)إ^|%@^>Xa߰7QUUE:SĄlORRXXyg4 qؾ};?vr]q\~4MvSPP;Wz}u=7莢LW3K/L$ٵ{O==[nr!^(3q%c-ſi22<øFkk+KTSZZJ"zRz{pJ}+*hii?}_MqI ##$I͛ϱG8x %%+=N~}>ux=^>38%բJRzxt>7۷Qb*Ο3}WeضM[t*!o# !.7QTWWJ&Fuص{7{aӦM~.… Ɲwɑ#Gxk}=n4M7'wTTTp_6Ms=9}]444;f*8xŋ?}7ȩ̐d2fMG!a t H14M[܃c;:u 7hBΟodhBel޲! cSFh FimiX,dZڇB!#J1o|֮PXXͲ,ՀNiRJΝ=˦MƢ8uh4ȩ@WO'4yBP[?W_& 3Ӛ^.@7tV/_|ukq{t]Ce'&}6c;C,öi5KmcƔ[)(^Qa!~wl>0 5"X4*xniD"#tvvLuZ*M30i۶=W(*, A,QZVHtضMww-pѢtww7>%k:ٱ'"Ѕ$*Uͮ(ǹmҙ*@:#QoTf(.K|+J~ LӜu(mvf.`0()(yNܜ޹ %`0H C( onW-2Snn<}lnn-p}?EQej-ݓ<n7e,4MU:2W87jU5 G'~ueSAAT˺u /cp(8_Nh=/۷S^VFڲ8~8,\e˗s!JJKD")7bZl_廏`:vA/Zc;ᣜwoDYY)dO?8eCTT_#q9zzzw#r{p3^yQQeN桰yfV\f/+^5dG]RJTh4adʂP@uk²󫼧٪?.x"AgW?ֲeF)Lzۍa "e~('Os4˖Vrpݜ={ ,\8{B}?#lټ q8yR &?[A(36W> w/ m {4 v())k WUUE()9{,?پ};/uAg4:;;Yd a?dݺ<6@.ON[TVV8mi:o}n4A2$#$Lᑑܺ\IIq1G1*wEQYJe b!ф駟#|\\Ϝ^СCTTTPYQ|@EEeQҒR~gOJ4iSXmϱ'#|w_r ӄȄؾ\IltH4ho ZgK} !hnnfXPxϱGJDu.Geee,[L @RjB]ahBxҖUH*(sorT= 0Ut$xVX&4K{[;H`0aaFGG͉;ˍHd@AAE,6:B*kزi#bɒE44O>%LNXOAWW7xe˖RQ^F__-,Zd2ٳh L76;E__?盚((Q]]M4TiL`exuscUEG~\mdVv%?)!e纁.sTE_t pCgO2V:,)(l"aXV\ F^8#oZ.MӔBi,K.aju(ʭ108HYi ™>iL .b642nUĎсW/AcespWz+a1~S @TElۡo S> 2ۨMpś0?@_ڭzJiY Ð)i'2!гuN咺g I;IQE v_[:oy7H!sgq;RXgA<Ƕmn7D˲ruI)霱^QEQH) 8ْ4Ma\.Ąu&z{{;PHX,&-˒lT)]QEQn)8;x%b!pdI)%\((7'SdN´8RJŤbp8G&IxBXrs(z#eDJJi햖eI-L&j;@-IENDB`RaySession-0.12.2/resources/screenshots/Screenshot_main_little.png000066400000000000000000001501131417052567600254670ustar00rootroot00000000000000PNG  IHDRT?ϦgAMA a cHRMz&u0`:pQ<bKGD pHYs+tIME $CIDATx]wxTڟSlzB!Q( "* 6T, Ŏ^ޫ⽢RD.޳21ɲ$D`99s{P=B%P"P""#EE(E(BG(B?BPPq_!!BHd#KtVBH#ϑ5?Py(< FVU|]IK<_aP82CA@8$IF3gW\\.BM*bzzRee ixF+Iy}z7dPA[r%vM+uZm{w#:,DQЯ(.)9 ާOںB(KeYWX Dzج^_XXK >_UUDAAY (GL"**jԈr)2 @ !h4g#( -,Ghbnۙ/V?onB||eUuJ-[}?x$  bZM RaN>,Kt%Y: fd~|VCCF}zUXQ Dz(ʲ c^8r;kX|78(I`PBj4ҧ!(==gb}qqͽdk~es **+ySU~(Vy֬Gmꚨ(_.۲ur!DWb,,jZߟ=t:YB~_Ѱ,Rx̘;wٳWӝӒ`slL PRZ6wނ]wkDrD4h]߆pBZVV*à?O#j9***UUMMxN355!7\w={y8 cܻWظ aJ.Eŵ]vMrenG1,;ly t:V$'ݞܼ/VeY/xلݻUL0v}II$M/}=6ɚڥK۽g?8{=wsT!۷b)**6Ͳ,_yŤ'^VWW{,v9]xp|2ee3g<ޒsrsgx$.66_|YQg<#rCCc>Vvt+Unhǟ6nڬh<%V t;os󛚚ZÇ\j%cjK/,(/+d[͛Ӧ?p0Z{{>qgJJJEEebB?鹲PcMM M&$IWL~f?X4{;O1 SXTןyz?k4m4|睂E\]]tzTVXχMgɲ%W<4tAgnۻgラsa4S~I"ʅ/PT\G\01 K>ha߼wԩ̘u6@ fBeYaNfcɴ@֭n@V^z?t/> ֧w̬YY%e6NۯoߝvMq7˿+/x{VIO_7GzMqqq^nڸisԮIɉ/ƛl޼aXYQRpȐY=wMͻmO+uw;oP,r繾Z@v=wO}xl',]&mW(+DJErQ0Lͽ{䫮4 _{aoڃWGwO&I4};)!1-(ebEN^{5޳f`0\5~N>x5WuA|oOa1x},j4?d{; w42ϧj]5sZ[[[[[۽{ ۴yKaaMЈb~~~|p:omE=9(l6M4ʬ;?}t{ߎݵ{W˾O>xlRUA`=ۡC9MIIٽ{ob|2uIz^یu1Qo{}Bχ ²,&y,` ;PVVfUUu}}CVf^oHצu{MM-2,1eI#.޽zW?-&+ 0rj79>_~'{ࡕV;ֿ_M7>eJQIICc#`Q8ΕּUrrË[X^Q'~5rv!DVd@ccSJJ]^^ҥeaEUH '@1!m.QƦʪ'NhllXv%cmlj EEZ6*Z^Q ٻwǟ1Y.))e9&ƪ >˓ZI,f3˲(صkypÆM{q4hlL_q𑙏N//()-#G ߼eKmm(YoF`w8ߟ}םwt%&:zn;n+++7^G/ؗ˾Qd#,˦vآ~ ++f*-+`p>֭ᇟvr\MmmQQ1 UTTW{O%YNLH8p˗/Q8I=8?2Nl*--<ћ7o!Beeݻ bUTTdw8464j6MԔ"t@6[j*0y 11с@e_\iiq,x<#]t1LVٲu(jk UX,--1 p8]2vx$ɋ^yiLI_y$'z |S1 sX~~AAJ.f۷e˯\.%%ecEڳ7:::1!a˶mE#:v1{r] JV f99)fWهrZ%y^A8%BN^Ae (lbYr,C f˥hDA- .Kd*aBpTEu,ø\.eQUUŶJ`0x EQ|>$I`Pv z<ޡC?:[쩆Í#mx<цƏ?\jK+Kaq(aj*tC,¯R N Zra["Izr\ӌ%.KtRDM]>5g-**PFDaX+JiI66wbd\E(Bc@ He<'6P"?/?*йx#"-"D"ta90!܉*>ڨjNYN%q,#EtB!& @ۇ=@ꅄPmkB O#@`4:FpЉz։A"ዶ=|{wbD|^ۏ B8 )PI2UѶ؂LeE>Bri=H2Yy3[B@W]%Ij r!~Co¥orK/z^osM*ק(V晼~m{r2z<ӆA~,?1 zKUI 1cy]N6.5y [LɢFY1UTV]_]2 ky~***?^/iFGpC\6ҧm0JJJ3/77WDYD,Ç_u붪Y߿_ccˌV'*ҳGϑ#. ݻr Lhkv 't #?+ܣ|pdADˀL j-@CmfJPUFm߉OJ{ttdTU@(h5zW\q)DG<'BII錙UUU~ꊅ'0LZqMޱo>N 3pi`P6Ə bR$rJqU~ W:ΐڏr=.lKjyyecW]~cA"Y'rr-̭~9bDQIV .h{yCogͧ]9y^;o駕e倐q}n;w^]Ȍ <Ĭ=;?[f?+ _߯ߦ[zKnd< :K$!6p Acނ@2U`AB 5{r\oe,f~~ݓh5 =X@m+ǞhF{@ xOyK  1~⊉O?9Of<ǷoKAJMF,)-yC9tp=lvUW\oY~ՓmѶK.[RRyVN bcbo뮽&^6!رqg'Z+WЫgϥ}owԧygCle~aRhQ!Hu%ᅧԳy;cʹXnݶm/Z:Mrƌh苶ln:dpRRriiهK?y>" 3 ~۾믻q@p]SnYMw%_޽;~?qtҏ>iI_~}! VKccSyyEBB<q\\!(11,yg]j!€P~w_߂!#A7L ;_YYuلoiD]ڽg%%e۶VT\ڵkll 0`NWT\yhzf􁍒Od@kq~?BMZ !`05%c/y?e@BYG05?80-+~Q[n:tȇKޛn>tdߺm[qq o>#lڴѣ]SRaƆAlظI fkyxyy"۳h 2 @{1 N_Gglw]=V0S: /ud3 xjY>9 QAÄ6bϿk{{H HbjL2UVEżPX^{b`! |s|@Pg2l/ҭ@SD"/O PuTT[oog>QCBqh2=fWI B,8{عG8#`'~9S0`[z;ĎQe_*32#?`d@YiB!0(RIX *9ޗ `O(/B- q,WB4 @UUVCH$ku!pc6NNu" ÙFNo(a~ωuz3B:w P"P""# ]\~PY5$?~dSdĜݐѽ٢ε x< b!Ӎù3 !@_w !VO Oyfz/5_F A!@& _!Z_bJo6Kʱ 0&6[sӻ(uu  S[>>ϱA2:>:>m[0Ȭ~_ >a_Hle*ъ<2Q$%IEE$DU,XVbYŒ  !#iE`N},I.ôwzs[vsaaEQڛ5޷(z ,IO\I~''oG3d'xl;)**ynyknKeEZ֕{V_ژ㓓/1AK/II !t:^6%`BB'0& \y ^1| \Na?Q# c3u!!djH)q5y:"L!@H$t0BJXIkDtZy1[ H`0tL93!$>>PUUM M@CMJ~[jyCZs-Zf<$bDuRU`0o걣;|­~[UtrVfw:E%'&&zo%+mzZd/kh[Eeno,nBwEo B~ *uIN1|غ˲cEQ'_uEuuͮ{DQ )m<~ Ï?t:EQ\.טѣnls?ty,(ʬ/M&3( s8! Gt⒒c}p'|]yyb0q ~N䇏΀ {\!`) 1@Ly``4; N؂zaYB3tgb";vu.-XUA0;i D ).}x/ rPTE$a` 1AUU4_jEͦ}N`0iQWVV+%-B^s\Pƒ$)qNmmrzۭшG$$3 z5}}~wL @@#j˶Gz~ZT Iucۃ1EvQ`L48IDQDIb HIbnMBAYޠt:Bp^=cEj4 S&^z{۳p0̍7\?wSs>sN`P$aXUUUQHAWUUu@F pw3q:]/9,cu:]m]Ƙc9a:PjgC"x}^ =FeuvGw.̩WUt!` E>?P7BWwQü7T 8SU58wNNI>4igH>IaeYaCHQz着fw׈"D_>Z,z.+3nǎBzdeiDa݅EE$AJi%'%ݷ?kJ޽y?r4'77o ;vm޺rnI2һ?cg}}}bb IIwBu5&VV~c'WK~\^QaٳEF>SWWz!>|m:_W__ZZm2x,^12ź@vAa!h4\6a`ܟ]SSPTTt:]cc=w݁c49ׯo^srggC.F_8z޽IUYl\o;oO۴eȘzcǎ9NUU`g/rZZĉc/_U|Í7|&oI5֭W_}Mzzzrrrޱok)((8|4J+8 !Ī1&0&EQYKjA(,,ɽ֬9(I! ޽_a6۳5$^#M, !1,B,B1*   2W r*Am'ճm~ZܣDciHKb:kj?WT$`0bea|z'|x+or˟xlLtzzeUUE)|٥\{UMM:qQQ`BB|.QVˬ zmXv@s$23?jճe#+`=!CˀCx~}L?n|^/]sktM7 :kAr 3 Ԕ.}{ճB/)p:X>X=:a ٬V9=-;ouvco&`LL^&ulg=prb떚:h@p7L8,8nڽS{m{$'_Q͚9C%']&LDuSzo{7t^Sdo:u*q 8y~)^a?C_>b̛ 11v=?c?(,rXVFjO+1t5a4A*t[خWT 9-MS @Hc }Ҭ0!!a! ݠ|W@q5 !$, ?GPl7Ғ=LA hq$AEZ-&` js{"xx<]zUEy/_|e]:k#qq^⍷!|ч7.b t8iݺ oO=k6ZͶ;n!п_rb?>ߟ}mS\.7!`q{xWo1rpzٿoӦ-7qſy&!*j۾cæ͙ݫgvt:KKK\OTT] cs.ꑕŲg}3O.Z,+s[>qW^za[,A1/rca  '''ص;KMZUU YV˝:+W?99i᫯-~Q#G~(-!~롪=zd]z鸀?( a.Id?}՛@V\=)))[lfYv„>XdOLL /-~睔Eٳ.;; Pv:]BHaleۜ>UL ƀ0H~ uQS7 Í ^hqԨF451&@Zbj- ~cthԐ!qall(PccShdh+ QV33S$7474؝ԮpDGH\X\#IRaQQ-21 qU>?k(gG^!66bB X;w钜 <ZVZZ0(.6.af'ڿ(EE3?}kBò>?~O$332 Z^Ltth 7$iuvh4~`׍«p: &^s] !,-+OJL,--SU=[euuh"01 h4Dzw޻WC F1`[jF,l6F3喛^Lф@\Zju]m݌w! -hjl5QUU@Hd2t:QQQ{[{޽zc98. 贺?o>cƁ~O{)IR2 2,˒)q21*&1Q>Ř'ǭ}f0Ƙ!P==~?iSޠnۮvWT"b޳gǓ_PeY >Xc. p=w_8j,Z,E%}􎊊шb||\mmBGV QUU T]Sш99yZ撱4pu71,3x@aT[_do-UvGf7jXr ʛU{rǨOG}i6'ݞ0Eբ>/$ɥe9y^^᧱޼ukqI w,Np鸔!EE!BVu؝3K2&X %7^yCO&ࠁx ]5MQq G h"].+^VVL&#׾m֭EE{\r{%wNW}acll,o656;'+2 )]z=+Vz챮]~‚ ~6~ h ~UU/;&>>8 $yN"*.K$z*&J`f!1hvG;@* !ڮ*4!.~7e*NoVt<צ;l( !EQBq:c/# {]n7~|m'MgAl޲BbcѻgOADb?p',/< ~gdY6 Ɋc~/ B&O+g JfIQTFT1vUc.+Wq&j.󋊋&oKtuu-x$+38Ni󖜜trcj׬Yk.V{>k}#G\TWW32X PWWWh4軧We6w l67dF;vhNRRb~nwmm?x!CXٺm{JJ=**NevZV^~aa.~`0 8l6;]=P:VMr`Рq$Sc .IIIUEBǣhIb>^p:Trt:Qv; wމ;gukzCġw8]t-B}4Z;o^sMQZr\yy[/I49|yLtt߈13 \_p8].ń`Ҍ|0 XC'!f7B^Bt:02Ist9FZ w߾iiVpzN4i*Q jll"(7lĄ j9p a=naQ1s,׋|QQqnn@ՊP[[eeT9e/MJ |-7]owد|Ei+Wzͷ?!xZ샻wQfF={ C H˵ǟiUEEŴBHEVBjrs_n[ozם/wu: t:NwN2n0ȠSh = }|mŖnBTB4tL`Y&] ͏3 c25]> F 16mVf|WBHaaBA<6rY1+;M<߆8 Dm@0Q !*&Nwh?rrRճwkX:ǭ I('~N j5 $*0W XwV{?N>T@,efggۃBBW_˶D\xvkD'4T,䃟Vhnk+[\)l ֡[Kl;"@B? }~"R i*!ӱg֢ FQ3˹8Y5 )oG9͋jcF-ANNJW<$X2uYڬlxc9a0<0l @>`0 tCH0 9H!`B f ;3WNDwv6>$  i64`=r `w!|>d@'ZA< ce^e)(}"CŰ=~%mm;/" 6TcV0nÓ AK;0"T:'bU"Zsà?0 98NܧߠNjا,\SSg掻 šUUm/ɏ:4GvѽXcNGnnB5]{Q(gؔeyA8 ,[]UGέǯ;|XfTEz:RxTk8Bx}XeQ  3--//7@Υ)neYԈ^i/|C[g5CuQ ghpHz^r;O[d(woڨ|=ďǏ;?ðroxzꔝ"P"h?,Zl<:y%cyƗo/q"m,_;gY,N;-䋢--->>.NBEd:G,UJt*;L !,Y4h6y P$[Lll\_躦I%ER0PЄ::O0dxf+JJNmjj ~)LMkkjK1E#oi'N-V$"BH% Ɲdt![n_|q=0 _iVzEE'$:MU?06{F\ZXPkyzcFSRR/766jڎzfx=^g,556w3װS r,N z,'%ۢ=nae5m׮]U++v)B'##֭ۖ-[~Ǧ&attt޽x}}gUUUޞFYE{=c U[F  ˲}:u*Bs̙7|sll,v֬YSNl۶-''gѢE3gt:cS~<$6.XnnBb5ʦ(NcYVQ6k؎T]`HKG8ϥߨ vt#j#?Kt>t銢=r8l24ETYYevKUVC:KMbŊKcC׮]No꫻w?-y^=u~7hzC,zmhh444ёN^3ͯOF ,o9s @PճE<2 j5-D[jZVK=!H |xѢE&)48MbzTWWjӺwWU8%J{ I~XxЮ ]3只 ׿,w43\Р}?p[6:mKE(M eeζSP圣G{[Ncw>mڴz6MQw8::zݺu _Mu*gCC8V VA;N**t5dKDl{gj q>4BrXm%|Y ƕ!ƵrVS'$Ie NL{ŊȗeX `0Bl6ۺu r]w-\d2V:9tbʭY$Np\H ^x^ƶiMBUU $%%ɲ\|a7.z48|xMTI =];vaM)u:] ].qtÏt|-hK K۝֍ښjOgjL*;WK E [_WOc+ԙVס1jrwRDl5U0 㡫ޥDP_? Χ=&"f7.=0۷o|t\Dze^XyL_mRUS0,a$Iz񥗎[`~LLkK7`[o5** 8zheYq ֞yEE c@ p!I~=MF_BvwFٿUUUff-[4Zm8k{˯ 6t:ji4%yv_4iݗ~_^綾Nxbdϰh#lڸQUՀϰ(݋$ 󼪪  ÈHTQ:SmP5`|^Oy͑#GzcQ@Gzkʲ &&tz^z_ytR0t 3m|uuG_ݽ{F),,tC].am%G6CfK[낲$q $jeddVTTCYY c!~x<`[n^t?˿s݁@w:jEv,//W%##c+#Ԯ]SUo~ VYY~z7`y^ջ׎ۗգGcCC7!nǏw\V ,cȑg{y}UeE@\~(mMGFw9]kx:݄ vE6'{c,UU@HrR32bbJK*Bvƞs֮]*=C9,vf`z}^aSJzW\qŌ3TL>hitt5\[SS=gyKLLܳgϳsddf>311R.ŋ]~ݶm^]~XzV;Jp=ϬYZ qrM{6CR\lNo0 9smڸAQ!Rrrҏ>&Oꢋ.Z늢 EpNc͚!uWtӧ<aEQn jLqnuJSS!g݁`p֭O?ݣG%K8].4iҤ):iҤ 9O߾<=Ë^}e߹k/ѳgcc<0{v\kr=K/4`Ɔ믿ᙧڼyi@E@U,l+ϗ` e;1וP6nh?YZug6s04hzr#G6 r-s}>g>.j=;7ߴ홙G),,1rԿ/30C9|IIIjt657v?:몫xk2!$ ؾWvĆ!`Y{ﭫk=zr˭8?ʫU5s\?99n֚f| iӦv};bĈU\thUU]\~ KΜgzGO7nv0O=9g^/kk׎ѣG5jܸ??|cǴ/k{f~իy矿mͣf>\WڣtDGOAeE./+߷oe'B'L`0jkjN(rzݟTe_}5}ƣ.$77};pOP~ D%!@>%$If=vw̝;4W8Dg>`裏&$$ n?5L. cܯo~}}1ڄ@$IF[wyGGvK& BueU#: !ܱc;tI1L^{]#j32bb?s$I^:A`$aښZI[,þ~**+`_? ^~E !ǜ 4" IA$Y RaXWWgZ`{T__0i4$D Ԉ1^W>oOƛ.a6orFԬ]vǞ=>3j6dk1fnr!T!Y^a%xHF뮛3U[~ &eY ,ϙ;7Kۦ:qS' |EQ/c83޽d2p ]7f̘Q$|ؘX1(>>IQy*S4 QeEQ{Y:.;~8jc!z<VCzxMHHp8@04 AbLY[lk_pؿQQQgW?B |ި(Q#Rih3Ֆ;:q>b2o:8;;O>WwPRkh(--mӦMژmaaXVUF3w+=J!1P1a„k<3;.>nO?R瞛/~{:N^'_5HJJz7^љ3ZA>m[hhm0u:Bbm\5 cW_۷~GeeeZZҥ~C>He99_|… ׯ_rh曯yd//y𡇖,y666D ڭ]w]ZRRYr!RÇɲNFEUңq7& Þ={ *OVU5ߣ!u!t|M 55uuugUWup[orWZo߾3vP_6ȲJ^~Wmuu\%ݬ꟨wI6\r/hژ OFwx. x5-uoժMM TUVYcjJvUyLȈ# !@/1zݻw_СC<{??縵kVT<_S]yӦK/ ҢEVZe2~6?:))1*gON$)))YQdѪJa~giՑ1`0#ך!eWk0222 \māŋm6[{CO6m}[/wMMM3OՓMUB[SR0Ƹs9*$)+) ن>`.]hn0VaU[_f5n7ݔ"a~NkXdg;fx**,$(2\UF9hMmZvJu*7V+ Tc-ׇlpWެ"'p`lk\ktջ|j]w6w $AO&~fV'&q~q۞?rq:e|a!&.LckX&-Piguwg+)a3CGx``pEG(~#ȇyR423BoD""#EE(E(BG(BNgC%kE"Z;; C;$ vY?BS( :ٰ|! Dl6[4q~r}3zd= ő [/E[ߴ*?W!fVܝDr'[ZZ||]"*+*:( :m#n0 g a0z\"D!J AuQɲL{AѴ7B(KRTttLl_PZVR,IRyMMM`ⓛF,Z,*NJNmB@@ SS3 cd͊$I,#l6,B,It]:|I0)))cǎѣ][__СWWW\EQl . HEMy.#?h~pYCUA,˄V[ZZ+8SNyj_b.ktf%.. s?Я(},Q#cM 88da4s5LD?w|Ut: &eXF-MU2yAtf׮]No_ !dzx;w~uuu',ۢcO^A"! 5Z,AȰ,;dȐiӦ=z>}m 1cwرcǖ-[^}Yfy<e/k⫪ 1:cـY5t(kvL\RWDŽ`*7Z n?!L$b^wO= C; MVTۢmikkj*;cƌy׬Y+P_ ʕ+F=ܳx_~a'L!A*"N۴Ϯ]Xz,WTTdggӎ*K/+O߂ >Ҕ*$%/\,u:^j<ϳ,KE/\`ѢE:Nko|^P^[[j+Pr)~II]XAC%U52hYD ?u!# wOw%9[k,+IRNQf]_v~jjC=4wݻwl6:DѫVZx3<'B g;Q>QGd0.\pBL=mr^0>c5mOH0MJ=iO€2XYN%@VdIGl'c5 ӫzO,Y﷐)˲r8Sȗe966PQQ64>UXeq܉zwZjdUn;nQN6m;|>ߙ'Aն;KP__/IVE^5gf„ }eeEyy9/4V$R0¨. e(@"3ҍ凲a'?}ӣGbI@DB}0|dG^Zն8pkR>2N'ݭ[7Q9B{E{v~-VS]CsFykn~|!'LƆp)/L&|2rp5a{RG(_~E}>}t'(B UU > J7|+ر_|>::q>}Fm#F,KMβ,էQ57XƆVGzLEL$Ȳ*фIG@mA )0v}ʔ)O~3~@  (Gn}ŊWX<E^ZGAQUa@ 6삹KHGyt7v<-B+9E1Lz<AV<ۯVQVyB f1C?zm۶A:\tE|M6lcϲl}}#GF_[N޹eYd2:14baVبjipV $jDUQ),UUeYxYjդIB|ѢEZ6//6tM ,9 ?)Z0kt"e e @$CYT ׎۟"\^0~\.W8'?VU`h4fW^VTYp1'={_TUyBB$Yv;M233@gL)MC|t5z7TVV{v.˲sc,H'OZIoaÆ[UV]s-pQu=Ps3脒֊L'L g ^cBXϳ"&DQBߌ|^%Fvps.k1o}`W_xE,˺ݮyF$arr,<ϽÇoḩ|rӦ.z^8Q^x)ңG3dKzgY|$nEEEY,‚I x+I˞ࢇclٚZQ y+v{vn>:}dYy'=yogytƌ/(ۜ9s~/<*ʶp˯noѣǘ1c\>O>V+%IЁPA*qY0{锟Rmf07nhBƛnFI3223>`+V W_wĈee%99NJlo9aQU8CzO9%dNkk{ݎD0(@EU'bQH[bw /ObG9ztڵ:.>>~ʕ,ٳp(55!77G-7_uՕFQ$B#br:_/[0(fڱcҥ=W:SHB2'X0(w,˅ϽAecuuu6 BԿ`2X|!Di4ӡ_/MMwyg|_wM_|#D?Ϝ5sO~٧uuuf BibMx E lb_"8`I|?@&dBƀ le6ԿظK?ߵswޕzq^QF#B&DeY !UEQf3 Z9q9򬬬:1 z(FrmP__\Rlojp$SUd2Vy{^fM8G@tJN֭֭[5M'C4`0x_jرc̙[L0ᥗ^NMx}w{ǟVsÆ_N̙ ΜcҥK?ƘW_}u}AWrsg)$?KL^RsY(2!^ `H9P:9l4~m/+lF]t)S FnyRR&'%L~nѢ~mO+++nVѝwe0BϛL&P\oGo믿/bϢ0F K`0xP,TmB***%?̽qƷ~`0~^߻wy!:{/N UU5,Yq bpL2%)1r]=niir]w#G\f{ eu6lC=Ԧ9PUU/wӦMVuyZm,wj Ue9M[ZRe(L bEUj! `1HlQ{&*a?UUf?z2@||BCC?>WUU1 qܒ%KDQtc>ǎ=cw\~ݺx<7oÏN˗{ Bg):!!)=BVpB$IA*\Ng.F!QYYk׮{wфرV/x${Yf2 | 466R0۾};@xa=yJY322n6/QB~ǎfIr555;vL*QH@qb Cn ۮq[2?p`$+@i5ڀ @"D-02zuKz ?G-@OQ1( 6mM] FeaYNQUU Caa?`6[ ߿gXFQTN'^{֨];v,:BE6 E'>ŋO8~VUUѴSFEE-[tҲ-4&:6hڊo\3ET qg5Z R:T LN[[ݸZ D=]ɏ7 қ4仚xLTbQA)G CݐTa0'1AUhkT'nF.%գ %m=Nƥ O>9|=N;b&I|-?mCJ]U88Qno˰(@-Gp! #ר^ Z*L{N2ah-~2!&hh4YB.@Qښ*!'d߿ӱ}YN.URHV5<{,mߣ*BBpi!  L:a[KSϬ/-nVۓԓ<[{6m1)!vk9c$\h%A"Ł^gAͳ$;dKI痋މbLY9QUBkYJi]n7}t(t`pTTvA@6Z Rx<0S"z~(TEFe$EQntko-^*tFh/|;w(~PjJMVXoY Y!e9رcyy^'hOR9[ZjGePhdDz"e 򻥥efHJVϏ%98qx fcSQXIVC`۩^<1e`@@EuȢ,IY=zq#P ;wݻx D=UפӧO0a̘1t"GvMM-(ȷKLTuOOoom{vQmhH%]Aj߾}B/o?PO,ڜ @$;lsoQ18aX5әY֨8IlIJ\׮~]8or`.+VnDe(h42 dYZ?u]7xׇ :I,KaqlƄvk"TTgYYYU܁mBDyDBBԝA*Bzt&C?pP_F#$f9pG UU  Ð ~@V߯-[R]E~/!joN}urX%0([9ҌF#e MMM^ /)//yl(1 jFFFUUU)Еeb0h$IIrrrDQK8r`ff#Gj'8p;|(-Htwygʕ>*! _~eذa7nl5;**aSK.aÂ`H̰,e&Keq[Q5t@b4ꟙ3uM7&&&n zFCFvDSS`8Nvi25&|^Xg܁`1>!e%9??eXC^3t LZw\Mqaz/Lac譄 ǣr233z}YY,z>t:jKCaYt1.))KLJ0=1P]]M # ld56tEU .//++-23zg zݻڜIש~*~ ;W]u|e:`#gggO01  %I JS][ "33kO&''7@`Qlym"Q<Äw/ޱcO<1|YWXKxyӦ>@_xaÎ9k4 bc-[=FС-j`PH~[0lƏt,/8cQUjfƱp8\]]R2Vq|hvv615eߌQ>f͒$/:8hojOƎwYo '? BtǶm>l^bի-[O->k֬ٱc(6׍3 票yPuUUrrr ;ΈA%<3$<.$P#A͟kd2M~r78sH\4i~^?h4&I:5-\pҥ/>[__ŰAiɔrUW͟?W^;o kj>o8qq\^^>UUUx|&p4k"Mד%wo$< i.24 CYTUUE%MUE%Nn8~vbʔe$c|y K.袋/^yСEQfsvv)Sニ2b3WVT_ 񘢨"6-Ι(IL4IZFQji6[223`Qv;2(ip:='.ǔN`<-k$8VUX,*6 02 &v܍eٙ3gN:533`0аy憆2/,v,6+ðK G=EN-!UQ)Q4T5yY47QT衚RUD "u I Od[ƕaHK=M [Y]x_38 8ML .FOeV+ < uC'B,8nwک D UU:UU1$i ~{0 {1CHWago >e3Dr]ǡ^Y,/uq mߒ^OA"P`0Gw"XKmrvclU$Yqt;{S c6֞C?O4ERT͐iZ7AC-'_cZZԫrM ~@r zᨯZ"a o*86ѴqZc23?aǧIFᣵ$AW;3ӱu]?pq̯n?sB[nƿ:묳ONd 8p@GGQ;["P Eh=nW!\>_\\|5הS7oѾ&颋.={6Iw.//x<A(2iҤo0444A8K'rj3pVd8#"ۗ8,y=QcͅBuܒSyH]U/3^ u}R>A*ۉ,3vX:;;qv4ޢIM5 ^$bv䣌FhWg䓹6]I5mTl,nxDϞ9,IcKJ'L>cYaa;-533;##Cm۶,3òХ)KB!\fskkn7!˲ϟYg}et]M&V^~i,G(&Hlkk-)ގl!lWg' FiؓM$IRPg\w8%~W|g|^?f2F ,KzF&˱x#c-0ޛDOUDeʊ1UU4UaҤIxF-期 /<֭ >5k֖-[n; #Eq3fExMo۲Y$IF].d١l"PUfrh4JQN蚪qFVk"%)%%%H2 l6 f øb}<WUjFёw6$%I \}HSՆzHr:Dyo ? =L㲳eYB7jɲ|љ ~? :;3f4745uZkkKSS_VwnA-.1[-1ҷTTAAA<0ďexWn/@/xWEY9>֌|o Kn^H8s4adX~?75554Mźrrr8kooVe } Ü5uzsS_3D"9vlqfV͛Μl?IIiAQUUp8338Ѕ^ves|IߏEy^o}v) xUCjQچ(ʵ^[VVvGK/W_%I{wiy衇og[lҥU̞(k^n䥗]裏.^%T~qqc+W.{/w>D꽪:Nd4'##C匌h4 0$IB}ݻfʲH$vItQQQEEÇ GvTU|{ݷo_ff"n744ԛfY==6533aYՊuFX$O#bjW_p8tccӛoV\ĪUD|ҤI~zx}g͚Yu9sHYʜ6m믿677an>t8A[qKKKq:^n A8ѨS%OD"NgKKdՄG?)ytQndZ&LXaH$ Sկ.^ۋvڗ^zi׮]x4KYEQzzzWD_v =⟿YH(qܾ}/C//wiZRRR",--yty<eGzzzZzzO0p8\.&¡b655Mtc,#GElh 881U/xR 0f]{zzNg"X,%%%@ kHnxdL:$I666F$LGx'Np,8qbzz:+FͲf>}QW5?uvvΚ5heh4j6inn&}${\Wzzzcc#˲nl6s80ʲTR2hm[7H BSU׋O%T-o &444Zy<믿ns/UU .7C$Iq,ph۶M{DI~ ¾~VqG}4u4;wp\}v {.Κ5횦tƍ4⚫...9‘7--jDŽ8؞b{NE^I>}zvvvMMM<5k.,,4M3f̨Q?q( G"AU՞ӧA׋hoj7G8Ƒ$V{<|s9'x++d⛚>6xZ[[|mmCcİ322}JOQKAXX8SQѣG;Ρ ^  oI$I6L Aa[y%3-v;~=z-egf2XȴtM8~L&l>=I"zuHnzˆlkbViXw3Wz'I25p*(@&۷Fc<'>r?~ɒ% RXmH4իW]v֭6m$Ɔ"ۍ~"rVVvvNN]mmQwo0c}ޟ_GcHZo"DP(xg<@kk~?͝>}YhQuu0 SB(:TY7lB8c`bl600ER()XWkE:si.M&SjjD(!Vh>7ŞzS'/ߩA; K M}ݏ>h֬YӦM«t#b94HR{{Vv'DjZNquIJm--BCI?B˷#~9W^^DZw och}}(f_:tHUU o4MiZMX,fh oR{8mUΐXx}?~@^p~8SъJt[7)t;HRLďTA#+HrA~"rSc>Wtp(~莧|-<]Ƚ3q&,E T pZ4|MUUyLFz=ܼƆaCxD} i>W%u B0GM<[V\ayKJq8SSObv%y.o:IvG2RENnnNNN\xē,X ~w²&UUUA}3 4"A:lOGTU%)v88#)Rx,b1a$PC*BFFƥ^ZZZv5M|ܴiSOON/*+ohQLhNj]8NSUYjU^^.'j<7$q sωȲ2|)ŒId `Q|V=3++"1BgyKF^3%ʘxTOD )K E4p,㠄jxgfffee'h4*]i8XŖfA܅$X,v瞩S744|!9u뮻nÆ of,Gэ%9=33&,jG}NNAlҥرco;55!zo믿 x<~xɒ%$U4M쬭qTEQlV+C3 1108֔37L+i!Bq6c1:c18)]z@]8aX,fw6r臘=+ʔ)K,ٳgϽq aL&SFF7 /lllLҿj*&THL㪪(}ڵ4Mb3`ժUDn{} |DrOa\.t:y קye˖+VTG.1\Ũe⒒D"h Boů]pjXNR4I$M#Noo._|۞}#>ج%D8nٲeX졇y~Rubvkp8ʲ͒$uuv#?ASI뚪$U:;=dziؼ <,E)wj*CD-ѣLG["}UUPK(DUyw:,_~ytMFK,ټylø^!<{4IqI8;I"~xlΜ9O<ԢE wa6qyoQ[pEӊ,HE?į("20(W:::oߞp\??OmڴjQQݮij$1nq˚>FN#~#a!K$;]v ,fϞ⑅>sL\(SSSsy}cX,$IJ,ii*qPjJH$Zmn_< 0rѢEĖH$[,r1 h}>7y:!k먷:"UMMⶖC,$Gv4;9~rᅗ^zw/xK~()))??رxO~0ݻ}>n8q0aB4ݱsr`ϞݚM4dffxBngiX q8d2%)gٵk()"+%%Ňy>/+;|PZZZAaaKs˔)|>߾}t8eYy 7,XpOb/:oܛo'?z//;o͖\UT<"'ownjzZ[Qʡ O8r&NiӦE^B!|MӒ{RF~أ~yzf啗_X]w]SS#+1%K7~<`ݣG*)){wعoWXl͛6m2Ll C+ߘǹ\.0VR#{SNLZ5t(BS4])-i[G ,R4ظiӦ>l6O:mRSBwydzɧ&NiZgG%W>8EfM׭{'OȊl6GXvo[o%˲޷$\d!jX_{'X5o޼sΝ;n馉'.Xl6iyOe?566֛[n+[ 4M[hnk4M{s;'|rW\1mii~|*k۶mmN芢$(:gee\n$ID=*64|Λ+͹[L2/.>}ƯwjꭷަiZvVVWg/g̘q͵ffdtm6G}H$>֩Sj G}uWgק|7嬳(:sҤ7xawj*EQu\{PuugWWgJJJGGIVK.SXXҌck׾3rD~tiw,Jܯ#EQ>vs*跄@W4jXVQb~|챕v3_+&pdʔRRRtM3qJJʒ/ٱ}{WWoiii '!3YUUcGj."ԻXcwG.H5'MvJPTU:EA;򛫪>so3;:X,0 q^WQ䴴tQg<O"0&%m6+˲B4J"СC=,I"swuuua!"i t]c`) 4m6AN'MhT'p7l Q׭_nuvv,H$ c[& Bo|׮]PhڴEEE\ۊe`08DDd<s:<'oA=MMMnM>/XlNt/4c`걹b5믿l1]n?裋.{ B/{ッ$_W?̤ɓf̘sNϻt OrQF%/UUU'[C.? 's&B!] %x"ka)u@ (fnJ)4";Z_}XWpg&}Wf޴gϞ;}_5嬳Vzb}mww_y<ϟ??j}x;=z[\\u00椐yusPo߾۶-Z8%%媫nmifΚkmhh6mzvv¢"elڴf֭_~a{vNMMy&vOߨڵ M/\;!hB׋+9yЪE|۰+24Msvvt&o%4M3L_|ŪU^~eϷ/S_,qƭ^fi:9f<GIY223u]=mnnW^JD(ڲeK?[>GQ(կnl6HbヰGi׻u0L l߾}˖-$IrDzleeeyy,Ǘ-~MSX ~<>0L$ P~iȪ"iJ:A:3 77N.򋱊g-C{ *:؄Q?aZA d22Y/kJQT"g9.n4W_cQ]Eѱ`2, Bʊsg6>8$fisfYeYڢ:qW]iZ%IRg2NQ۷arx<.;??Á;<577ɲoiZ0~-,Y$-;Tt2GYܒ'uOqΠUUԬBe)p`,*R3 **#=s s&<~u]:G+bZs 7x<e2y8 𪪪ƌ)0!kI !99]]pZ,m۶ix3fhԈxӃ\hQYYߏCx`Ih +\׏>$ kFR*;cr<}Cð{5u7{n)nǸ-zC߆pZL/5d6ifSN5>GMӜNk8.w3?~@? ~@? ~@?? ~@? ~@? ~C? ~@? ~@? ~@? ~@? ~@? ~@ ~@? ~@? ~@?? ~@? ~@? ~? ~@? ~@? ~@G8@&B' 4U5%|4Uu WG麆J́ :AѴi$~U$Yfxh%a_Ue!Ͳ I5U#)~hje/ 47?l ~@ag7Ք%tEXtdate:create2021-02-04T10:36:28+01:00{ %tEXtdate:modify2021-02-04T10:36:28+01:00 )IENDB`RaySession-0.12.2/resources/screenshots/patchbay_raysession.png000066400000000000000000006104571417052567600250570ustar00rootroot00000000000000PNG  IHDRE pHYs+ IDATxw|'ݵ׽2d{FE(SApY""De)KAu#ңyRxޯW_pM.^'|"r>jN/Pˉ2م2م2E+ oggZfzq`` e""""""""",(W\r:As9 @98$$2Q 9*?Bf``LDDDDDDDDD/szUٕSu9B09)8NHHlٲ9Z"""""""""Wӕ+W*ZCP9El9(9e#@||<+A׫sRܠA%'[_d7صL޿h0bŊ 111Bh4 `2\7f"""""""""d u: 6z޺uKuuuUS@6 S!!!hL&<$N f3c"""""""""lj*$XN*J:sӬL###EWWWd2 fYX,ϔdYfLDDDDDDDDD$IiFMw&Y1 Tr*u:%zb, NNN$0Ngzz=f"""""""""zg&ɃfIԸ8U$UѨ^WF\`A9*T& !!!x}A1h2D^/Ȳ,Ȳ,("888ص^{#"""""""""zYhW+j4UQUITIxU)FQqppPX2 ,O(Wl24$I V-EQl~1c"""""""""%I&$$@(((&IEQh4(2KONU*U @#˲VUU-(,ˢVdY55DN{ҟZ6A$GDDDDDDDDD!`l6LOSEUb ,+$YdUU-ZBe`9KrffY'I,:N11$˲*'$_$I2 eYVӚO YeEȪ,eY6f!TvdA%IrX,$TU ɲ,(*"J$*("&&q)cDDDDDDDDDI,'=X,I?(ѫH$* `X,fV r\Ce `ٮ@dI? MDDDDDDDDDDD9`~O*() )~` $(J$ eYgXrSX,,AH$F1>>^tuuCBBĄT9qMVV^lYܿ_ zh2DQ%I4('H$dX b4e֭[Iq=SV(H7`0111df`X$Jd6/jU9>yܦ$NEIՊ&IX,lL&#S&+x[,˂`4EUUEUU2KEPzMPh?nEDy bEEz'("x{{ LNn:lٲ X,AEȲ,t:b(,3P&""""""N5KWr{(ϔ/|6=IdCH$ (L&Iz(yۋ@ ld"= ˲( ˲(S-E$?pwsTݪ#Us2轁^2qޕQuzrժVIs^{"""""uR*VWF,H~S>YQ|Z"+S4ڵ63[ jT'''K09:uB / F2hpp\$IV ˇ(\_#zv5CU_ -YjUX9{FB 쌐?&7j&a䩹="""\jၐ !GAA0iaձ(^ Z4+^mw߃$Iy޵< $IB&Qbyt:,^ """s5䦢E}6Ge/xS(y/\={r'Nz..UO{Æ L&<| 𬆙e(ba8x_(YZj /OO?m= D={fj@-`XϿ|.hZz{ߕ.U ˗ϿMz}} \'OLX<ܺy Gþr2ܽ{W^Òe5e彰L&3Cp,g:ڶN>G3b*H$$/n ogwŤ1d؈L8]\\j={ѣ1kw)wQ䄘Tt$1*i='0Mz#d+ތϞ}NXr4$I!s2{6[۶m;k(Xs zts>FAŊ0p@QQQ>ñmvܹ{hۦܽ.H"aN,]7nј`6qaTPӦⳅ_9z폐 eUvMѨag(j'>3¢K3}nmO?cͺ}zرdg6^{EDDb'OBB&WժQ?i3tAXbeиjiMe;ݫˇ{[ߎtVcx13z~q3ݿh߮-oth&[mG]O[ެU MFX,rŊ ;~Vm+WFgΜ+p z>|aԈል>F\\*Uy7+EDD/oܾ}ժV/?|a'sfzliS R~u:- | YznzpRg^>sÆ #عEfUZhe{XF :;uO0aXh4-Ʈ{ccHl'\){@ʕ1v)*@NP{bFlL Lo̙5  ATT&h4fpvv5kv݆TcR`{'OX]twށd;VAʕ1eh4@|0#Ϗ6z CQcʤ(U$:Ξ=Y""2c/㏝޵ 4 = ϓ ӫ'V}&L` 3-ӧ-1k?GF Z51rP|׸r*|-Yӧ"<"]=GDDD")V(dYߦ&Wo b{W\EQ`A;~W]C??Μ;ӧHSd^^Xn޺={999eƩӧ3w?!2~m+֬^իapppuh"6`0JhݲTEEXX5@PrŊߛCmoG&S=Qv:6 ]:Ա={2hӺ[.iQJe.U;2:}'Oܹs#G âK??ʗ/]Xm׶ ?`ꊞݻ𑣨YTٽm߁ti0߶ٌ]6$@N(\<ݑ2Kb1P~=(]|p e+V /%-7ChX'|}・{UϿfM`q(T fζN3zjY oWh0f(oѪesp޼5S8q._DfMQJeL N;E˯oy2`>Zn=b!UmkqO[nᏝ? n@J(X~߾#ӱh^099??,jk<==Ѥq#5%K͛r,OH.SWߜj֮k0H<ɧ1r0j̚sк]G|8L4~~~8"W Q\|Ω0|}鉋Ra4Qt"N͛K^hڢ5vً3gX{Z͝5A6бKw4lP͚6vSU6} 2i28pdEƲ_zj6;j0xp[m 6}.hܬ%> qVfϜk׮Y6hܴ 2yuB -ZCC';"/j f͚Gh٦6lI˯pu,Kn1CA@У{7t]=GDDD"}\ѪeT\ѺUKb`oܩr!E_}>_?__DDD`٨Xfd,].ѳG7|ч֧jx??ݿ ƢeJI*re@p},Q ?pss$IHHH^׼YSL8ÊKfK>.ݻuA^t,jDƍ̔DQDUqe@"g6 .d4".>CU ѣ0cTxzx ,,ĞǟӖ_AQdU+xVM-PUiUTB4N~Qet _ j 2],KtӦLѧ/G[^d I?acm.uѣ DGGxb0M FjUqI{mY 꽍ÇzZ2Ξ;ʕ*a_Z畫Wѧ;x___gϝO!((͚6ɓw7w^^ǝwѡ};4i(nٳ;2:o{p(y :wh=ClK/`9+Jg''߶mCBBb6 l2tR(^˨f-.A{\zQQQ(PTƢЫgw̞1QQј=w>cm;=`oCk_w}6y.]fE?ʗ+GeV~|oUU*8F ?նm..ȴovHjo˯[O9RINb/0爈^p8L?7nw@Qbbl*5j%sa+T@Hh(]H"Z#<<,>r[قeW،I Ţ%ˬc޻gЫgh4T\ݾmsՖ "<|}[aCczYMuq||hm5r؉[ g""#0s-nϴ_ܠh I`yMg>,?Rp@\ `лav-̙ 777^O9Bqk VڈKV|>M *6Sh;GЖ^'sgaӏ[pq{?~۴nÆ`c}ؼGqqȞSΜ=+V`#_,Zg3L~#5/b{|u ƦӼo^8| ֿb 3 qcϛ/a柬Bn߃FS|ꋅfzz|Pkۧ7֮]jy[k|w2%ɪ1c8?jԨ~ǐA8u j_NNN~Ѵ=Ͽ7}M@񁷷>iGjhP>>F#ޮ[& 6w>f,Ť [F9 IDAT` |}|yO> Q_#>>߮¶;p} 6 m֭c7SMu846X,6wK듪(BXē1?*fM}6ǒ$af4,Zھ!'L<'O^n]`ْEo@i>͑dtL?x2hpuӷ7 !OC5Lٳ1knb Pl2a߻vUQzݻG@y&ptpcaْEؾ~m囒qМk,龗0qT(F O̲ s=~m6i3|ŷmQT)̜5zRi2Puh3o %)_vLdxx4nww7\x qtlDEE؉722 V5 "#"pU<Z*?ܽw/\?'?~S=m??_=yU,Dddn޺ oLv]f;z{?9kaPbÙfZ{@"E2=""#lJ!OGCe|q~ش]:uĢ@l֛9AUUx9(ܺ5m7nHa{E*N:Sc0=`&fϜ.b 2֮+j_%(\]wFjYQP! ˾Y˖.¤)pI8ww7-PC@hhoQ۷&^zoEš(*~@e츉ؾnχPE_Ç*>zr*<~^Ӳ݁v+.>7Æ |PU ..S01988`?pCxx}C&qpth,˨[6^iW v$>>(S֭WWWh-_mFFCUU|:/[CyJٌh*Y._*WCɮRH;"#=+9^q.E?lш;$Ihݲ5P-Ϲ6(-̷߫ƞczj0LpQ2o}5vn{z(gcI_vJL#(^MY?yƁ( ߸F&iJ3$IFv:E߻vm6(Ru>˅ q /!88/{!\G=A;é3aW_]X+ϗ/Grjt;Vʑcȴwޫ#"" ǥK<((TN>.bŊ>zU IFămێ= |FLΓ^.;… Fc TԷmfLH+, N_0߭ZOq; k矰b|,Yv憾{kNqHk+nA@%m,Gdm){2;EQĈaCd7g΢hѢXd!SXpsBCCPo$3gpxV}VDxx8\\]eZA((6mƸ?Qcp1O Sm6mނf`G<̚1 ~111p;aАa6NNN1}*>;GOwIW%0HHHM?93 'fΞj>Ħ[ӦCHh(|xϟޅzo@b߾`ӲcؐApqel\Oz({ᣏ'bߛ7q1lټ !!!xaO3b>MψaCq̙t;}tٷl^UU|bzB^<Z#*:y(Fv\G.>fOݭn9pqvNƆ..hv$&ګ75wwwR'NNvh_n9w:wP]]\耨hk@G4 /{(#(Z;1߯KYnnn KROJXYo $^hؒ.m.GGG8::d,:Cb6ٚ/iKU݋H UUI+}$$$dqvWuo֪ Sȩmjneu:]EQ  r(&$YUUKBB'߽{WU|}}rʩ!=OV('K (3F_9d2eBɲtٜTEQ2ӯ%H+MN ? ę Y3Wퟴ>Drnx2 7O8s\V('gIweg{>MU}Qޣ(J[:г!vVF2kʬ('d Fm^ۋ?'dJi2qJc6lNUE (Yd5]s~I?r̘9;DDDDDXLLlEDDDw0 e 2ٸtQPFNfDDDD_s{D9U*}^+e (=/=""""""""}Ųq3 g0""""""""깥^OSqlŊa޼TTbŊbgn]V:L F~I1N".fcG`veSζgr֝ZW< ZhO49c-%{(/V }˾؏]Ӣl\=km\)a@_E`gm*B;1hsNwqy ZhTN&'I*x. OPNL^lBX"hxܼu)FKyEyb#U*6'`}[ [J^|yBXX`6&@zopB _Gm {*d C_"""""""",ʓ=+>w Lj0~$ɯ*dd{%eZ^)r^ 9igdr4m zj֬0('jpG6Q/jC>hI@8I/R, }iDDDDDDDDD/1Btt4W]قX uP̗r6Qޖ'e䒇]B i\ jkQU.S,QI-6, g]9u 饐2e }CT .lWܕ-X *FMDDDDDDDD0P C_""""""""gGQ@@@@@@@@@@@@@@@@@9U\ m۶$IO5=j="""""""""π'D1MۼYS`t:SMK6?oEs{(DDDDDDDDD(簒%K`MϟCy S^D;wĝ;w7ʔ '"$n[-(Q( 8~$<ѫGw@mo[!** %K@;wb})Sjք,8q$.^d3 ʣFjAPRETX.](W,*W={''=v{cou 7߬*+A$ܾ}FdTA@RŊOǮ{p5k#** ϜťKФq#(Q#\'N">>NdnPJeOę3g...ܩ#9U+kcN>=NDDDDDDDDD`.:Aw+"##N:`aD~}ЫgDEEA$t ?^^^xZ&CU޳jqc |9к?Ett4z=z3qOFdT\]\гGwL<ΝGjU1ӹHHH@l\:uʕ+a-߯<<׋o׭X'ӻDP;؉1GMV^GΝ0~dmX 75k^a왨R2抮];PDq7nˎ(ܹ#6|V..߯:ul^OOO4mC( """"""""4E:\]]1|(t ^^ֵ3`1lع샸xԭo0|Щ+1bPG>hݶ;u]߮Zw!24il3˖骪⽁gΜ)кmt_@j7ШaC4nٌ,SnxoP޳%K@֭㏝ܵ3Cҥ+WW~hס3&L V*U*cٻ/ڴa#޷VI')Q8Zj]h߱ Μ=޽z:_|Bu]{`;Qx1)za"""""""""*x!߸ص{F#J, CR0yxH774S={!$$p]yv  Fdd$l?p:.D @b0  #t:~߾.xnxyyJ8|( e;~XfztFTTPX1̙=cFEQPXQϿ ǰ1#`J,۷h4ܹVm,]55l7o&e1u IDATA}Pf;vG|Nv:;]GDDDDDDDDDtMFUUl\\\|?r8 * [0tIXUUlb|2xhZt:L:ӧb e&:}͛aEwu=fΚ( .֭]bŊBO 鴸~ ""ÆmoG &MoW'M}GUmiIf !$"]Ql@ ,ذ("a/XU츂],kA頢 HB :eydȐBP99y \s}^t:|/+-q]RZkQk4PGdl6^"##پcmxy«L96,xiP8++ TUiiZ'xv8O0'IMmz5O1Ljmscyѝ'{w- 7ͷSkËo5s>b|G|'\u l(}s[nC\*ṱy}Kr=N'w`ڴTVz~Is} k/ Xl9-[ҵLF[GK~x[>S***z~x[s6ΉwBq_} iiiYk'uֱqcAnn|n$%%G۶%`~Y+%%%DGG̘9`? Q\\]:ӻi˂_1 ロYgA'nzf͚ Og̜YgXl9<͐ 0 n7'ߨu^OF1kl;i2 ;f4>dJƁo =}-;w9vv6XVLdy)--宻e̘[ˀ@w'O&7'vGēOSXX:>c~]:3xβ2>s,#n!p|{JHs1B7Xbm:t0-ZRRbvix< bLӌ2M3濌{(((ƛFUNxx8n9x<EDD]`DGGS^^'fU.{3fMaQָpPPzHkypΨ(`R\RBe- 90 (%@n,--X,WVVׯ7̤$裏6ǍW*`&uŻ+ -++w^5rQ]t"##OWxIIIȍ} 6P EDDDDDDDDt B:u;oO[zI"""""""""rP\[n߷g-)'se(.."CDDDDDDDDDR\윖^^۵ ޲DDDDDDDDDD@YDDDDDDDDDDE4ei""""""""""( EDDDDDDDDDQ(H(PFQ,""""""""""@YDDDDDDDDDDE4'V+Gw;HWK/EP\T̒100 ױχȁ uƶZK:jqǝſaKPy|(HYYـ+++(le"""""""""*PF1ѡ:J*""""""""*PV6SPV9P""""""""""(^Ⱦ+/Һ5۶o#[xE""""""""" ;v`ʕoF]EDDDDDDDb-/,+={ݱZ- 9XV|:thUb"#G Fvow8O<~4RU(UVb6mRhĒ4Zh{aydM٤ry|rsstޠ.P}CYx,[l0 !j^}}׬HSh ełn'""=zG\l{ ""݆Rl__>jycbud?ؽ/..~ ILLثy /233i:|>iҾ][233z_"""""""""MY*m6'ԝm#..ER$v;'x"iii-[ExXKt:s:;]_.rQQQQ sPY4wFN;#tfym?/rQZZ2(&65$L~q4Umc42EDDDDDDDDH({^233??6  v;qЪU+~[g9~gμy\ϋC1GéLbBV3fnxMg g;ŷXl6>o>{__a1p9|7; ߗjI'1g<^y } {` C/44Mxk"O\o^^'N||<.I~W^s펐'܃OxOTVf̚Ë=M޽a^z(gfnɓv儇ZmlڴBvk9L^,eQtЎ7`Yry9m۷s㏲Ulݺm5YLx{y=wUOn9 Mrr+&M|oYо=11< v;V0~҉\v?ihmNNx٧٘kҫ{.72-[8.L> z07}sJ֜s***j928LxY8!|{dM"""""""""f)_FF~ 2VQQ￿4qa ִqN{L7N' gΜy :,^z1_ZZKY&'[j8PU-{`̜=Ҳvdec 8#<5V=}6c&[]߾:Lql֭ɩ/Pn\}9ìzC\{ fM EDDDDDDDѬ2@eҒ""±zQ@h(=}jB :,xx<!|őSDۍlƆ5%%%fڐmYٴJJ > z}XFܶnw_ͷaŊ!cǼah |~s.UDDDDDDDDrBbBIq1X,ڱ[trz^۟$N;s75NNNf?w7^"kmgr)*.SNn5$%$lKJJ$+{qn FdK8k@_ضxA*PHJYP\\11lڴ&O>d-W;4%nzX;v~?Ag=';E=^ ҹSGz8 118TVVR^3x~DEE+..&%uΜ53r)'3g{̄j<)quAyLBjyYz5^֭H W v oj`nt2Z''fͳ;{˶mygsm@K/ʬ9sٴ9/eer~Yk𸙳p,u!/Jȼ?O?oyWIOmq 946n܌aXV|>_}k2ce#7rEDDDDDDDD((|~c0HxXx16m nyT۳sx;vdu= ?9MwӦϚ=sKiiv]DGGz)ݥYsQXX%î Ï>){5Sy_D|{d۷c 1s6,_/Gar"""""""""RfoykرEuu~~~b&yy0Zaaa0>ﻆ*]ƍyFXXKy &׬Xښ|{g^Zr Tڛ}zppPy߆5+"""""""",Pq>?DŽߨgoce߸a:/.vU75X~^YPPW/P#w(]"^G(DvvvK/EꐔDIQn;T^>"""""""""*P^|ݍڵR2 ~CDDDDDDDD@q@KWa1Z sy>DDDDDDDDDVlج6P>w@(""""""""r`DDDDDDDDDD@YDDDDDDDDDDE4ei""""""""""(>aQ00 KÂan hٜ^raTUq6 {IqFm[nsX,heeelޜi--(U4gH=vvg~}}{IM(5 7eǶm-}uJ*m۷gZcsgMksL$&KDDDDDDDDDZ$P6jT4AIY+7l^]ɼ{}zEMta2m[8?͝5c5]p?x*4)aAHq}/Bmd,c޽[z9"""""""""fP6 GbfMO\^CuJe-/ ׃SwkO=}p[aAHjF{ξ:Ľ[DDDDDDDDd"-/Xա}dUʻ"""""""""iyQy&֖2sU&`bFg8Əi}`N; /˪[FO`<ȣ ПҖ^^q l*U,""""""""fo:^[f`HW`b48SWf BꐹjJLL[nGswܪVht;kZ{O+0 M:\WOȁ̦Yc_hHjrv٥X,F5Iǎq:^Mrr2mڵA׮GbUhݺ5m۶%<<TRnݚ-[PQQAxx8mڴam55g6yS_{  =PME5VUaY&SڸE0ZQU\c*T6pw{4=g.6[e0 3v,V2ni?ϟE Ͱˆn:n1#o iA~c_1sy{zf EDDDDDDDD5}n` sa oTWTl >WE6XUfɦ4O30nhl6l67޽Ncٌ;W'LG,_c ܳjpEѡCny$&MO^31PmfnJ޽ѣ'ׯgǎZDDDDDDDDDd>%̅*@\*F{FJfiܗАo/WCϞ'cZ` L\\6<.VIID8cX,w&###87_%^Jxx8=z`o[DDDDuyd_^`=P=b"P]-/jSγ\aƌX{モvDnhoTzz7d7`2!Aa+ w 2!U9ìq滾m۶1j]6ˇ ^CcMawhBܹ ?ΈJJK0 6lի)7JJJ0a=,8M̘1ï!##ŋ4%-Mofwib"vu wޔϨU\{s|I{]$'jXSP4i2i /1⦛Op[yG4i2YYYJoO3?o57dV }z3x%"""""""""e`SQUl Օf -0o֚:n ˗ŭܣjt=m3OgQ^^NYY}7>QQQn*͛G륨6oߞ>R>&[sci8WCƸ""""0p3^J1.""""{*Jٿ35M~{=;+BdΪdjJ~oGOXSϯ: |)㏓Øn#77ws[[z """"6mR8,-3ʦ lٶLJ p"r *05XfUњb ;v3|>3,,VZy=>bZ7f:vd h&BJJJ#** AԜsEnVn_q BnWZϦP^u>bIIIGvĞlmӆ-[v4D@k\l&&Nh/JOBX[Xp(+,Gh'V*Tک"iA>IKMH9k^E@O^GV\~٥ cwv;GOgӦMx~>,M ~r(oߎSO9ׇp/ XaCȼO:dɮk}g?\Wl lmܷr٤`|ƽ& S,""""MbbTVr*oҲca5.ia4A 9@J. j%~.+a H|8/w.( X r7Ex ?4 2#>vLĎ$L .|S|hK%|(E`]n%efU11ƻ&6l]9NXV'/`AKnn.+Vrtٔ⌈￟Vo':*Xn7Gq^M݁@;a. Vky7B9餓Z t&Sr*222jcaժU0j7wWIx<bcb0`\.֯_EZjqqDGǰxb/_Q<OχiyAu\g3 6 +>L,T%-0DDDDDd?g@tl4)mRX,x<l6>͛oז(rٴ)ߏ49-|"2 ClxȫI\0n$Wf&=$ٰ [Aysf0\Z\ϋYjJg$%&+++cgp8۳nz5qD~}1['߂rc-\;oQ} wo߾p!7obp!lHvv[l~$22"/_k"-/LyP:H*@ 7k*yyDDDDDd?gBƆ (..T%`ۂ-, -(((4JaA![2бS[,BW^NFAAp,""ؐ=[.B^wִFm۝r4?jDz:s aa;, Նb VqbXcӦʹоsl6:LJJK3g_^s׮]о=K.a˖y:4bbb9ke"Ҕ 9ADt~EEafDz(o]'@tt4&~lW{n^.QY|iwͷS|\8dV%8]#IIi͌3)//gϞX-da !\YY;ٳ_|1O&Aݥyyy$%%nݺ=1##zoظj&&EH3k@8+!ҸZ `ݢ[hۮGutK/e(--cs=w=ͼiIQ^6:uonF~? {\7</aaaxB ՎbpG혣Z\[bi}a233*P>w ^z)@#o.]E Ea׀JasWqq6嗸\.""" nc&Eo f_Y0wMAA!33ݻg )֭ۈb|ĐШ눌"77rV+mvVŋmv󉊊 n|>(**m띣CXXv=?1lܘQ|x<Izz:DCsc&"ME$ogVK4!3ouű@35dX 3MUDDDDb`X1l&6 Îcw8였#́[(퀅͛7SQY&deeal`^]JJJ⪫Y-hZcZj)>>FVVVWaX,@ы_ajՊ;vr <"`@αZΓHII ee;? XXABB[6m-_54 |xd\mg\.r~~>i#)LxThwABٰSìsݫ.¢""#]l߾M3Yb#77B^~>P5Qkl[Ahժaa B fs5y̢~gȐ (p2Vs-K/گa9߇p0k_cg͙À8\.~nS}>޵|"Nʎas>l#"""Mo%AbZb v`jT`Vs Yr5OSRlXw&y ᨣb[op87ͷ`@>v,ɭuBn׍!s&&&&%︓y?2>`@?+)))va,[>{ O?gQɣv, ɬYyp8JJKsh^z)_}5grYzyO钜J

͇}Dxx8%%% U\Yj|| ֤cZ)-+ǟz{b%Kd}7fd1#˅C:o͟n7S>pV+756w=PʌEDD+Zz rvKŰ`Z @pPXXԯ(>1I}II;;1MVI tÁVXP=Dzz:G{F`X,x1<=۷m]v!WIIItH[:c̳ <;RSy'~Uvکq,^$3f.{ /䧟ItЁG~M61Q '0vmdgg9;CrO;JJQ*",,=dCTf6ՙ '(-!݇x(5vx5GM~Ғ=>!J<&J=ƟYbM"׵L,"""i*-/LVhZ0 |͊ Gib۱Zj=#:KOILL}viΔ)_˂!Ǐ& ફl|'S7rLntЁu7g8E}v >)_@s=ҋ/ϋ/s5s3첡Ջ?w'M46z4G;6~MJKKCnR%"5Xjʆ8W/~;~v~N5k@P Lc#P!"i-s㾜^䀑֮ "gTm#"ͨS n"!!>d[k*{|<k?} ϘAB|~w$ޝ4)ɧlC?O&WMiHHHj w]ȡfrDX'tѾCV"77prss ǎDžcWT|PC*EDDHD] (+-7ͪd3Xlbක`z.:OzqL/Wz?MrZEYl/`k^M?&""WTk׮cMZӛ:Ed7@cgƪUөb̴dz6  ťp-MC>ȹS|\1l_w-NgV5xl\|L’%K9n *7~s&%%Q^^NAAAXLt45Z5%'' |>aaaQPXXzkMz:K,#Oޜvꩌu+ ~VsuUs5U'&&vzˆ񐛛.iO?iؼ93d.C+r0S,""""cqy΢udM :8=;v݋pFX)+R3^uܯ"#(+3^`DmNA^>Z Edebק DBէL%%;W}WsPvS Xmi߯O?aw0vm ^Kw${%--gٲ{4U_)UÇSGEdmذ;ﺇJs~l4?V\? X[I 1PT1=6^׌ 2@yyqlݦe 0 oJ9\̥e%,ҁIyTWJřCii93;sJ歪ć'y9?8.BrrrxqiʙgW\`!=wի{HMM3⦛ݻ/2y?ҹ3)))\)}Ap)е둤 s EIOg8` 999d]:֭#u2wu'x" ssw!뿛W)i&~1}z!CDGG'9n 4UusWqr:ZJJ +о};Xv-/2 5D EDDQ_m@%Vj_^$JJK))) <ٳ{ӻaPRR¿2NW]Ɉ 0fT: L^83{m4k=06z4^O{N=Yz5ï^e&Ti_DDaJeT"oTUTmRl/f"n:C>HRb"/oF/xqz8K.I) jn:?+2e ;xGC?үo_nq#^0̝7۷# )++VBz\|Yd K,i|{,wu]G㏹;83XZ7PObB׭'%%pomذ-[ЩS'Fx#.nݺ4xDEq/m{,iKCw/ 555p80a\.?>.]:ך;%5V<˚tn3O0rԭssѹS'nFn7y%\ڷqp0+yп71w}VqGп_}񴉈\`eła9ޘzQuСu} {_]0j-,w^zWu 瓚KDDW\~9 k_M:ͷߦu<ܳ<3wyᎻ$ ]ߐ75 ygءkfϝמϪtԉ;VI3wï_- o)._~UeW ߟuwnǼ>cnVqym>պZB9<}~bD*-wpŻߩM_Yش3(}֙\.s5K&>.3M簴4Yǟ| OnG]VV; ॗ#.) IDATCii%#oSz$/?0̞3[p=z+|XN9<>۩SiժGuJrr:{|Jo87ދR*"!* NP@"d<(SY*CYfnvr?Ҧ--B-Uq M9wAkբoeѷߞzIwuZ)1y{:/0gb2ܥ>LC%dfeΦM9R K]/2˯xtt:8y3o 3-T6l^y˖ ,_Igen36c'xrw) kI Mhe_b*,ujHt'ǫEOll8SA)@Bc>f{Rڵ=%Ky)<ܳtM Ϊ~ lVy)YCFAmom/θe9.YԩFAJX|J/۰i)bɄD222hԨ}NfMokן{O7^z%o#?Z_*=inժT7vm|6mB@@`ZR#AAj?//JOx9>3OH^ p~(g[m[ 5[ ' ?j5wuϿ@Xx/~- B-p8i2^x9ٻo6IS)8=ʱX6irMG_߾FN?0a⻌eء댪SO3aDƼ2_͝dS?AA\c'$pՏ+Uk|:_O3gr4&~Fvq؝;-1u4Nov%- B ;,{O2XbE;v}Kfffn}eYYdYѣ[J0O13f]x1 /nM*6 WF6@:5LY_؝ҿz*^ynmsu(T*E)UA- 76nLJJ ?-z^n\\\/ NV7c6$))i˖*,  PUk oW1%=)S6f zKחs &33={vGB =bŊd4 K۶1}4 ?ge~ӣgO֭hر,Zl>x*- &&?tvUn PLG.\)(9oӬiSz=iiiꕄ7^TWwAF0f3Eヿ?^AjTE жm;9p u}Gll,v"2{aΜ9U+^ɲL&M8}T>(<|9w{f{IYt֍T݋':u~jҤI ˯'_.A~ƫz<ۯ1&xvDUAocE,W[ Ã#^gxxĉݻ{W3y{{Ю][44l:oaFXY=W /Fsμ3]:kVqBtt=>R#le˖{}xzyZ<OH[ېŊu+Z_}ߏVel߾=zP^}-$`.X#1O W^ϲe?@nS{8vn®]={ҴISLfϖ-X,=z ((wuxGڭ7obˣ1MPPP@-P ^^^̝% <'OVqAAjWrJY3D,כLӝww/l1[S*P hh4ɲ$I8Nxyy?#wKb?K,py*Re@Tj5^I@@̤d_,Omr8V˔kז׭gmұCT*5$N9ut,`p߶%=#ܿQ=6p1r@@nj}ԭ[?yWKp\ F?@||sԺ{ԩv 0`Чp8p5?4jܘ^z AAuY/cZ(w \Gx#ʳ/ #55@e>ƎM@?w'ʸc׷/ΝSg?b2xǑ$Ξͼ au{8w~;6>VqWNL#vE:u[xiܨǎք >sf͚1 f1aD֭p{8xIҋ Fd| =6prxx8?R23*F~~СC4!<<^ϡ}Shx}x0r( ?²e? ѽ{NF׮Xpbƿ&ǎl,Z-Ægg,^=#Fүs̘xzzҷO>Dy5 G2}4K"##}zw-[h߾=6l#2M60LF/_7{F 02HNN`O? |lݺc  מ9#M9WɕP*o \6mѣʄN}gYYY7͛3t&&/޶Mx;z4߃4=x5{Y.Z644+Vx7xWرs{}n㇟~b?c4lL9z4vӧۻ33o[mcܘ14|8bU7_V\={ǎwN8={0d ֭_}Чܳp 6n\qǍC]v1݉?e2}A^Ո@yw${ptT*k pX^xÆ]v@9!!q○:!!!vη7Onn.3f\=<_~9;;ub8{xoV[s>;9y$nkWjU+]u0 `6ٵk]veX`kZ}I8u$뇂JW̙*Za;z\ˢ  \ۓ P%&OQugUMRKPYRgRֶ-*5kײuv=ƭmڠh-~[=HnclٺAO}Sn x;mniͭmpkW_ƿpϞ>}_< @``<4!X*P.yF:7kڄ&7ވFÃ[ZM2p=Z︃/]bZZ]:š,??V^\4P,ZNCq61];wbZq:8*/GR}t܄(?t?,3fL',,ӦK.XEz,4l؈Gz$I$''1qx0} w/  \;Eq.)b~UC6.w7B+#4ir#aaa8Wy_}~/*ynUKѱV+$''_0B|{IDx8Fc1L 2`00gDEչpVe};y2={hѼPw@rr2`Wzs( I}-_r%\BjBCQ_zVZ:00G–h4gZlIǎY(xeMN8w撎YRb4SCJ:y/<:={^X{vV,wgΐ?a/ȠkZ|%!xzzro{عs9GeٹO=XoSCعkE߆_}ӧ!(77[ZgԩS?v\Ț~cMgǎHlf/ٱs':+µK^={HvغeKoGLhf~bmM>E3g\V,_ΩSUV zI6n?@Jr 2ʲ~Ε-[xF:Lhh(i/c0xx:in?jc7'l۶{__ …Xj%)λOǎd={ֽ|E |q})'ѷO_^xaM4e޽h6iܹsʴ9ct҆{];w^(   @͘ͷbK/ң{wFΐi2N<ɤS(fLsػw{Ss/zZZ͚5gfidddۖf^79;vDEGOV ͛JQ{pՃ>tC].fNʷE繷#G2;6ndː]vf&&NdŊԉdc;F#XzUǷYvƍ{W_~ɶNHkOGq:X6Nb߾}{L<coХKWdf3zg}v;cƌ矗iJݏ  µMRhP/k4jdYJ%ReB*R _/$r$z q-$ Y.m5ZսGp VZY]5l0u f~!!!XV233]g[Hk֮%88FkGIixtc7,ITfcqa6]%[Ҷ}ECCf&V$}3`0t&VEVf&s<}g `,+I |rPPZƏ?-ooo F4baKeh/=g.!X/xܜ\^Z`rrrKVeO>Fɧqx,Ćqv:p/;ōF"=-c'//#xyya0Jr]]86ggg3jH<<ޗ<澜Ǩ#QTbZK}*y?>Kvm۶  PJF=Z=7FVu$pxEqÅG Nӎ*Cp(Cv(^w( }auikUwJh~M݅kn'dVuXNǵZJ<6p-bg[nAX,"d20ffeaIK; ߄\5m҄ .tC  \Vcu]ӣhJl]^xj5c4aYmvv+6ӆfs/w8셡ӁQ|䠊hڋʅtb?~bI/,sET*Yޑ],5X\-[6'>>p \F#_}Y Ũr5kְf͚>Jln/]Brd]n^9¤w'bؼi3CFuwIA"y{^^NVJ%VJt:02c0X,fl6kmu**0jkns &O~ӧϠxqddd0{\ {.(݋e˖WO,WA.w Fʕjr4׋Vy*KW98uI. 㻋OApCYVGBc/zOt:+4v?eaZX,ff^fѪ#śoʉ7o!#G-\/99/F²6[I*XruAA.O|H,*Оdd|  &dA|ZNKSޫJI~~Na1#fpƌ,*U(׌/l&**ѣGPPP,;…"fӕ.]:S +CEDDuQ4Je) X,V&1/ {* B5RYȂ  &*wP\T5!{qfcńdb1aZf\URb;k׹1U~aե?=X?bb0q,q.KY&"" 9Y}HZMtdgRY7שpJ›Vw/-GjǍB5^op&eAAkS}N:uzrh4Zt:t:}o2iӉlhh,l.d*&G_bmٳoڵ02ˬԯ_[vA'1,~8¥8Wj4ج:BJr Fhٲy/GQ}|$IusxvDUAoPGj}X#ׇu IDAT"( P%4lЀz>+6.fN>]cK* FZEqtCcYVQlIH8NV3Fc>&SAax*ϕj/3i~{eC 9r(ZLHH0iOr$+77 6JEJJ*b8qF@FZ@_UU&?V{*wF|D }A8?(   0IJ%#˪[VRQ5AJZ]vDPn!f+.z+QQժzy( ,_ I CwBQ\L&gq]wqUn(_{سgo1g&UI_JߗdYfVq$ğu*W?2 Y't:q* ԫ %_odY3jvzg]w8֣ͪ+tjr;Vw7. N"PAIn' Cgn|=Ra%I\^vuʼn@UPɽoѲP'V͂fj5cXXXffSai #(Mq-|\ +4i&[jݬY3vtEQ8r(}f߾={.o~8JK(C;G^k2|רd =II:LNN srsr9xpE 3?bڴψO]9Pp k{ ?r?<"PAA*P(L( }]!qoEJPh;=*htbYXLeB^^v ͆a/?unt;Eq믿aKjwJ]`yA 8q:0qd6bذԏK!NYPTpIEQ@Rn*Vr}R$O˓:ȲL!48qj5sF[\r6mB ؿ?gv4ߎ/7ml6Wi'E-cPSBk!L.r=<\"PA,1K'Ϝ7Sgr[_sgժŀk4OOot:O||hj$IJ%#IratAdIp:%8Uۏc: V Nc0Tq\;KxH\ǹdT*uzRaE$E|~Eۺe(foz[U&)UɓbNWղ1"I(j6S38Niyssl6;:{a eJ,KtS3 JCٻR2]rrdcwH@ӸQ#|h"Pde|!jۢ_v*wjr_vխUTri-AD\ɲL6\yyoq*  \\ra\I& Dffz= jPJUM) DQBQ I΃(ŠfWZ-瑞Bvv;P- \B^$Ua-\e,UpeK^|k-?m}J+텃m׵x< L&0\/\+\gHjU\At:h@" eIHHbiiiȲ䪣^VKAACjT*Qդ4Z&-=:茉$PRSSq:zpow=rNF+{` 0Le%j|rĥׁv/%TvWWRe+I5P6HL#CQoi޿wUwW*Me||} p!MOO#/7WAK {|qQu\T?Fivv;NBNkFC,kܣlU*=͆ј+vMW<ֵ_ ~~l6'N(l*ܰxuNNԇ@Qlڦ+@}m\C;K]v_hdw]m)o]yZ*aE̙3C"*T2j$ZTח49jAUs)>ޯ׉ZFV=7D݇fM/j ۵|@f1ݼ0E!$ٟgٵk>o"#[7xǎ=EQ<]=hѢ9}6ofܫ1n<֟OgbEw=3@EaL4 ȘѣXV ]=?PGP*tɂ \/CDDsw}7QQQHKK#11M6n:+ ^a2@JY4uUrYf1k֬*iN#n]#\#,,dXĬ ~kPΙU3h_Q}dIZZEQ@. BO Ӂf!j5VP0Hhr6Jjjuv0hvNDFF9oQ,y+_4_͛b6[h&/^&j]_dIFVh4@YՒǚkJ| >1.];UtE!4$ j/2ɓ9~Z&0| [Y)Lɩ)4WA̝9!!!4j{=Zh3yhݪuD1d`nؑon?tgś둇c.ZLLL8F<֭[1vh3ҙ:m;wf-N Y 00`t:4jF ,)Q~ǥtAuJ|+hժE."44 ?zot:jIht}hHpaC$I$IxzCnn&wj5CTTãu:u4 2HLxA|~^|5qq ;9z4o\G1?>͇o B&hJ^(hZT*5~<3t:$IVp"\_"i4T4{Ҭi3뇯ԯ_H4 ?3W?*KÇ#IO= v˗GVXZ~u ojNLߴ3husKzz &L|EQh׮jc'p_CGR(/X=6SDFFC@@02etb[0//@YZ*w{*(+QhW9Z.|R]T:Îlb1K^^6ec0j>(WR׮]yXt)ݺu#??6gΜ̙3_ooo}YVX[o뫡חL\/ȲLbB<~x{{ONvQu  #=1ɋ  TVvkT*]BJW>)8NEJZ cٽ{$&.SaaQZo~X6 N<!.4v~󿭰^{0:pQRacӁZAqPV5dI||TdY @YUH_:/Gi2cH6jJiiDDp>t%[G(ÜRdUtϱ兟/9ͷ>3vX,R$'%-|iJDD;4";@VV99L&cOJNH[cJm3~D *Yk z{{KFF6Sϟ 蹵yh:#KjuxxxxxxyD``P$l6 yydgBVVZoOʕ0h ~i~i7E9s&k׮eDDDp+SC吐Pw ?R -=JxD*eAAbg8{6νLӜ:xx G028XOZT( :܋ae?=7vp)Ξ=/7IQU!$vgO5Z܀G%_]/FffVuu񊻞dk(*H躑*O#dտGq:Wu"]*F,%/=T"&$dĸ_l6z㤤Р~},0Kt'{=aʻ9TX(\Ve&3`>l^x!O?͟n? m ??Mxvk VGÆ7HX,FN>ӠoL^^6C:)) bʈ@"u֍~~]RÇӯ_?.]Jrr|Te\47aa$= @d:=  •g28topi'$㏷?&{mA&E/,!!jn.NرF-)(С=hZmD@@0*tԭH|󎶾ޕ-ee\war%j*vYSSᮕQkxQ &$$OOkR|&ZB՜Pm][Z|3#^|xNogXx1NQ5b$SOgĉye;ļ@Y: hԨ9j<JbUWvK8NZm׮Ͽ ((I&￯w?fœ_=Gkz Ōb`(QF``07~RRIL<-eᲉ@"1ezYuSSS6l_5|\ ׃ZS\Ett#5 u護vpr^c Zƍo"44=p?vt*de&SZV'%:1HkFQΜ-UսԾ;$06ֹ Eqj ,9P2).8(,(={r߃GzFFo  DR3>c{/8m۰q#}},\}Jlēˋ~w뿯[J0} j M&$$Ʊc9{%כ\Ytmn(oewTtwЮݭ8z7Z'YiV5kѣ{IL<ѺuG@vv[7Nii?~ldʉYMэB$z6m80 $&,IU}@mztaIde`28ptc]z9ʌt|EaV0*U`gExyвmtdggp^KBjp!Lu(W$*Z~I"##˓oˋE*_3el6+HL{fĊ|=I=p*NP\s(NG'NpĉZ;ZDfmPԜ:KB>%}wg>222PhZVΕ%e`Mx?W )5z/f4hД>Ăpa"P@׮]ٸq#宏7.,??M6ѭ[*ӓnOOO;Fvv6aaaDGĉӺ<<4mZѣGJ}CNt FڄsY, DFF|YWVEKJJ2D-=jN')啭( Bۿ尰:*ڴ<ٌjuNv|sIOwN';uj|xx4TT* QEaINNtowKh5jz ""Ogiu( >Z7EZiP3Zf+ZA\B&20{TT`Y1c,Y.))jByBC#ݥGzz ۸/\#\EAU-11Ke,11 HJJrt 5 :{՞?%''}Chюo@TT HI/+p]wdɒ*owÆ 8J`6m>MdcqT*L&/8;vݻ<@N<ɰ1bd:uKxe8V^Cݻ3e{tU &IbkQxx*zAJr2 TKAg]T*nxyyөSwNs>V+H7n$ITjQ'HԭCݺ 028rpR))ģR`$IF"&F13gb)((j ͛DFxx8i? ""ǵ86-_!?{7z&V!}Nx_xy1R򴜵!9%\RS55Ypp811Ͱl=yU5XyVX)s׋nsjj:;A`` >ڇ+AQ ##(kΖ-[_Q0^z.77?tmtx?J/ (W^z8q'ĉDEEUijZ͋Çq"##bl/_ƍG޽bl>#\^{짟x,\СO3䩧%));3իWѮm:u꺛Tbp)23 5YHHzZyy"LAZpߛUjDE',,]cZIII"%%Vn7oo_vÐ$ ڷLbc_F ..Xz=эC$<<|iVNLcS+ oVݽsɋ$$&fοܩ3F%kЪ]﷍6;g;~QdgFA~z/@<}JfZ:F'a*SUYBiР v#GQPPW@hpQJteJ9˻^Mz)o9_Ø3g/ضm;3qq> 6;lw- uC-NÜȅ@8 ~ސWq~(6cObWdZ9s`?S "&Fv;'>>> R%C9r,AAAdggZر]|*S5Enn6۷muuٱwEYO,(_4Z kB `UdgթS>ʚ_eE~y4$a1=˴?3҈߯ҭAA⎑O۶Q4nܒhk ɉ n#j [\&==׿JrFc.G86m ""TZ4 $44EqÙ3)(jW V{3Th­wqUw?N4ѨjK6BH0-H]6d/! nB K>J 6`ܻ%.hFS}idY-Yyrx/n CC=4aޭ\r5Zu۷cCShoo'!!im7>>|0ݳC^^>۷o'"< 6 EQP޽p\<Ѓg?#=#=f}}owqEjR}X*, *B1vm(*ZEbb V/? ΝYbf͚+ػw;twwpĒ |n'UUSaROKK=` ;;f3` ::8tn'-qs͉yɰnܑuel=CӦ퇭DDFFtʣ##%Ltti6<12t|,MЈpucr3^b&3sהjGQTE>WVowIj׃fhh{>z}~A'WPPھ$P>:rss=PͥqZ12B?^xEt]穟92w}7wo۷}|Gy`>!WW_q+g3!~4:b!D!緒}47ײlTUe򵴶6RV,Oq^S)BU^މ墷df`4X"XBn7ǎNK_2jjHK&%%t]fs ;@@q*1Wx |fE|֖2LXHI"-- \.' r388;D _i| %pR[[{΅bL1ԦM J(`VUU5`40LL&fs8aD`G8 ~}8twwC=VۛIO_@UU1CCZMSغu+Gy+wygZlmmpaeoox3/??Plj1alB!&֭bұmmt|%ʒ%k8LwwAx.Vpll6SXCmmnX cc,ju`4*)h<47ϩO=xB3fP.f``R',prsHJ;8Zg%KꝄ8}MNwK+j'22 ́f#=}頳FKLy!XggqD6ŏ l8ZNEdd$W\qO?ttqJzz8Y͢њ?֭㿾=:ԗM=BܻPz$]&)Buv22rZHxx$]1vB {VVZh&/o 45Nlr()Ox<0L>r\ :OI$55H;jll( ^NZZn=āgd^wt][z^RXlv( %2Mdf摖*846tF5\O|/k ))~ zz2:uޯX<|b1׮=ʦx{יΜx> /^Moo--45L-\西4 (BKK [l_*O<Ĵկ~͛72-m/g^}I曑20'jB15` 0L[wmv{ŋ/$"FjjaaVKƴv(-=NNN! /SWWNmny4NJJ'99(&S%*FL2/u|x7|ۃ띕BgGprT@UQzzOLoFp+J?ĄTu,{7˦Mo=w}5~Y=~֯;rNǿ~&2^SIoo'%%Z#IM&##ի짺1sbb%P!(OA[[7xg[ikk;NHLLg塇:6&ZL`xlwK!f׮ͬZu)& bRSsHNN'"ʲe8thDŽmy^JJ`0Ypv  yyK|VJWW64㈌b `0mu݂VY냣OL3F͸_# !-)-BQ**9GQ3HKAQ3*m1E}qW0y8WBS.k0GIM$'e֑SȡC;'<:fswXY(O͛III#w}iT^h?OyٲeYy@r7f_'Nz$? !\ؽ-[j'==9gæcde-h4b>@;I{^`0_nGUIs:q:KNf'**-;zPEQ4(J044ɧ'tI=su^Q<22r Ra`x8+Nܮy~] Giݕ3v.;Zh Vq >t]lb\#ixhjj祗^?fqwrmo~~{z{n\=~͎4n '2B!F$/o1$$$*`hh(ҥRQqJKb0((XѨB:;ۨ*ftD0t|?}hzD(66k,wO珰pVbG34].M 55 @WW;IZp+5h#FB>(f ]Htt,wPifbN@4mٲn{~wy͛7SUUEGGxrss++ؼy37pÔ\ JkK|(&953Bb4b)0T8D'Dž2B!fJeQ|>IIiƣ(˩8墸x yy˩e,%%I@Q$&ࠓ\>ܝ-]~mꦛn>ISS3QQQ yoq?S*`0hFDGk|M.|-3qEٰrɜ>ir ]tdqF3~JJsC,[v1\r vmb ^gb.@ T~g+ !!vٺu+O?4--w}{XB-:ݟu}ܿ{']<ƍXVZxlc]E`#OccoJ !BUFRR:1,Z@NChjf\Z[imBJKKjj6Ίil oOoh; |u׽GCŅQUMӈo4Rhp:]c bcchkk-O&sNnNiSuOQ[BxGyajlgGdرẬgOzkjN83aAv6lwcZ[qd͚+XJoX,a躎38sBKK /"/ⴶؿg紶9_OmC:*Wc{;TO!3@ @JJ&6[xtTSqn Abb )PECCv{4K a4. ;Mmm--S gt7iC4@hyWW' ;l6o>@wwG]]]?F4n& p8|>~Q-[_`Ϟg;O. jj&3)XFUM=?VRSHMbt.&Cc1ZZ/BEݻkbK t%P$Pm6 p]M"e.B1RR*!33##%%=ݻ@^,+((Xֹ{y8cj8|(?3R\\;l wC:::Kkя* 45k.dǎ]$$sz#/ߤ{?9pY*ęe' Ca "p8b#**݁(~ZZꨮ.appt~!UUII --U5v8<bnxKb:}}]Q7$P B!MMMu|~22r h%%r]]%CCC$%aeѢO^l2@ <<ġ(VEEPT!ݭTWW̩kL{-*⢋ruo3tk@4~=˖-%,Bll 5Džl ׯ7M$%%xn}2]̫&kQ]Ssc2Y0ͨNLm@ 0zBEQlMӦQN54###H}}rT!tmaj!Bބknh${Axrv.]=ASSݴ?ݷۣIK":: ՊQUшdn!3s4PM |>^.ko߇3>hg]T'hkټ~|MMM}bو/x}ii=ж55(DŽ/ٳ{磿*l80I&TtwwBGG+g6MWD̔KYʎL8 s4TV+Ygwρ7ELL͵-1GH,B!Yڀ$$Cff>uuc9|xldf1 $'b`XB `01-X6B 26oЎOS_@ZZ*>M?DWW=.Ӊ<}~?]]Sim/dR |z8ݮi+_s6<z?RBpM1jXWc3}%,!,ۯL\Q\4OKK=YX,-1H,B!Y\&pĠ9Mi>,("66í={Fhlj6dXQE`a0z0T*QGQ^!TECC#n1C%IIyg۶M݅iqXEQITFk3kPTUM NO!?? w'm}J{%擎L∳>FQЙ~rF,a(Grr:K8MM'l6v2rR22.&nEQ`5߱F)'Yn#K4 \n+Z!B!fZcc @ttX3f<ii ZmZu Ng?N+ p8,Y' !ޚ+ ?Akc)cعv3X ˹ ?'-;?~}'FGxA" IDATC?&37XV^}na4s_Fu_t77/= w'00ˡ^I|ҚyM+i$15G7}>?_I u!B ^͎EQC5jkˇOCf4PȻG"9Yhz+蚆h|~<ۨu=xL o@Y!B̚c(#$4Myl䦦:Ab2ze<>^N7,^\3Ē%o71!8#dg .S{ƕl{Wݴ7_ދ[o _6PYU!Bq*PcILLE4Z[l#;Ytj`K.yz=/k ))~ zz2|v78,K;. -3HɈe Dy,_'|3 %]x$Pf4PVUezd]9yB!B̆r DEEi7r{6.bFIJJȑ3s(c.nZ{v{UΟ0Y٢ J_KBvl.7׭2>­[JC#Zwl.;ԮFok:Fo(u9₏ks~'k" Y 'VAc:yέ~ϊ m0g6}FwYYLjj Vk$fsbN@9↦N- * w1PWwRU:~z%iɱæB!8TW`)Vl@e6]a q8bc+ٿ^t|_҃G|{eӦ7.uS 1]穑# ';vT @dTCn/_φ܈ U!W`2Yh2xp;Bs{h'oQ oڲq}idOgzb> mdFO*χ硿I^'jgE6v38ফ) MV^ǎ% Ӣ'}~惈xCW&:}}ݳ91hN((޺Ƭ6M\V5+C#~g6G#[ TB!b(/?LQr2nGBnrL& W_NuZZ_=(}1fYoo?wo;oa^.hn|y˴5` 3a0g8܀l$F~O>[Yٵx&ycF_v~?Ls]p3?iґq#j'kD5C&k ;2n|xz;G3-'G@Um:Ϯ3]m}Qɻ)O_O_W} z~Y PX ECr=kwh{)撙 ! uǕP b6>eYQ^{s?N;xB!b*)9HQJ#GQq/Z[ .h4T5 p~]y& 1KZme${Ƭ'#oS͵mbb2GtTnZ1ܺGB_V^hxDl@@c`\FvwBN;NlsyЇCqҡoJmV|^7GƬKIq 15mF&;nԁ߯M8ȶ}ӦB!8cѢUlv22r0 46pCʢEQ# "3zgo]ii纋W y{ 1zsEb>m$L*٧(*EE+PU:U5АY쥘fE0,fʀr\|\1.\?0n6k1cB!bn +fa0pێ&}%K@D/Z*+pϧ=ճݍ1S!MٓT0=[gbYYXv["11DSSjbPVF׃P混G'mn(d]CF) !B9x? .%99EQ#;lXq &lRS9xp']3s![W~I##\ UUgeiڤWL̖Oc¢g>>v3~k]8ia *:h:q!Bq*+;H^RHJJd2QY9 {AVV &V|9s?$m|lwA!, W  c%I{{3Y꥘f4PV 8ZX||]'fL0h6kWzm477RB!|SYyM[Lbb )DD8thI-U.#*ʁ%\9;LbՇnc]>^ mz3s$TbFegdv.\Nx h,@Qtjkfwb>ʺ+('t 0m1)fer,Ǘ5t|?̻+B!8-Gz=dd`Ez۷@`9Ewo!<v5wo#|e˖5&n>ύۿ$??׋hb}fEllp|hiiַx|~>С\|v| _'~NBް/|L&~?Yd)>ȇ}!Bv;ٱm֬(%K.ͼٹs3$%%@DKװt44KԎGTkԝ#$TB1T`48-Wo 9 n6fYll,}}p]>^뮿˦y'1|>w1m_ꗨSO=MDD|3%%Ŭ]_{|bÿ ur-N~׆Cߠs|>^o_gwc0ӟ_fuI,B1>-.#DDD]H||*wZ=GcXh5񨪂fp9|vR[[EGGӴ>53]Xf-MYh1GW_@_@K+8|0%%ܱjVYMFF&? |P_Pᠿ'xh Ml6B!|w{,\t(.:kYOtkc_FLL<^'B!􋎎'+wX_L ࣴt,RG3^Cm8T uha~o[/fI9Јi*vyWHMM>rrrP]INN`0zrssC3\MEe%MM srrBۧn76/S8|0k^t:B!b~w7zel҈K`Ϟwq< lKeRRDFFb6G `4fs8QW((?|6g͸ `!blQ.'PRwh.\8#'|/H!5%Ae$_VU` ttM /il({ }FVzB0PI>},{hE7m?ucݷomɟ{8v;hoog׮]_rW ƶ[ RR\BBB+W_}ZB!vJZZ6K1,\tǩ*|ڎZOkkIIDGc1 b41TTUx44Y,!B1-UU))?$|))Iss Rg3^CʹI۟GI*s1\CYt4n4T&CC`od=mtɣ#u-X\c:#rJJ)*Z+/ZsϑµsÍ7r:tҶ^|bbb8<3l7O_G!)99|>7| j [oMB!s]cc MYs&"23طo.W8CMN}ҾD2BQCF=wp\ݗ+&[xqͭtwww$>R !sdf 1LTW1vaa,XP識1Y8U<>0Y&Xw~'\~͟s?22tOmmmho[XVzzzwG׶i'y |S7K.'O=MGG {﹇0"## M+/+/9_|y !B1y^{u Vl梋$zMQF׾86SG55e?OP]}+[M(w=Wqe63 mڵcm-b -ZF}}5--.I` #pO|7%/F>7 4\n/[zbm}tu9rGW04/А\4&Z1֬ն$;GNȂLX'v;/&Bݩ[ē?rQQ^wٿltǃ#oB!jDFFÕWH[[McQNX<~Htg}EQͥi2Y!ĬPeXv::t81tv8犙 %42g^'~_$}44TZ8RҀgKS.]BGc-~|^?+gQ]NoȕAUv~"ma"{d*җ7 @ss3~}c !Bc߉M`ٲ0$&q7z<]D(#zow3؟}Eի/ӟ^RSSز翰njrs/~nMB!NGnnqvRYytSHOrRZ:B Ce* Fׇ?Ad2Mb1a@l6 +*%u_Q`xi_Ǡ'4eo{a``gǜn> ?}Y qB!Ζ-!-- W`0IL3әjሚǸiii7pav d駟`wرcW]Q6n|N>wBq- !!s^-cFRP@Oq^ q*3^b$TNM"*2]p3ֈ0>}:ttblΗ>sAF;v)!1hEk p0`CeM0 g`0`YILL<!bX㡤dߤs&&-UU(.>̞P#5tE%"܂>2jYӉ&5pDE` bv'3DGF', LG e!B!c47#66ŋlfU,\{RZvTm71?Mz}www}_G>>Q*%S !8()ً7|^PT*jដs͌`7#a>&L4mxR=ЇCџqarpD0Yt&B!,uk ,YKRR*j "ҥtnۛ8v=mǞI&jfq$/u<#uټ] IDAT^))dggqZm2~E!ČIdJJvNmVVQQtwSW73W$sی흽tp#Fd}8 džqar080E_k&B!s^ lvV8.['++]rEkk=mm^R{*ʪ~< IL6nsuuuFCo޼|nF~_s! !%?1d.m%㢬['@}BbBthYePaxhp ;4}F O}h=4!B!XNg?w @x$$b6[PUí$'g(14rEWW'=G'hkټ3w|uܲ _?tq}۷B_غfÆ=. !n`9eep:'oF@@x83(^f?B!b.s:3tf#p+b@Qf3f -EYk5Vցߠi#tiHKKGꞩ:e3BqbFY١XCIĴIB!ρYf6IMf`Ne`y|i`Fn7ήSij1 !IarEgΙ>{lM#@(RK%(pEAI`W{UЋ Tn HO6{/3;cv'd7 [R>c;s|y|fyNjQ]WSNe!B!|;cAp^^.̟_  !8,mUUd GMM47HBcd)=i10-B.B!1o^KxgB1nwRTt &}tvz(,$<<jjfpd"1%Kile2-SX4~iUU$!!0\. $=!B׿^$~b߾rzzz%g4neBQFdB]]9)"66nwq"& ?>Or瓞Nbb"466~z|MZ0o38z `BeUUI3TTUd2 @MuTB!8U(+Jȶ^[W_7݇^x'aB\__IKKÄSg4MG%Z|9w=+V`ppp\ZjkkYf |+__f͚50Kww77pÔ$'* DE }= 99ΎN6M!Bw~w̶~nڝH$LB10b0yG^^ ~-|r״~(/| tMtMٳ簎׿5WG!%%UVMHT 2Q1@{[))@prBbB!0:j^\Qd!,sfrkardd4EE u}v(t@0Xn+WURV\s=GKKTS*,NbRMMf+9G}!BT[ Δ0Y!ġL6Fk&GRXP)+N[*J{$P> III{xr[[7|3O<v풚3`:_!B,˔sٙ>H,P683ŨJE.zz:ghBI|N}YJKK?v_c,_ẻǪ0ƔXwti}=$Idd$))o-4=^!B"c!bvN b6[hh??ܶA֯_ϊ+|>Inn.N2z{{IJJ"## zz¾}{LFFvNNN ׋n'55<)D&{@?->'c̾"""u֖giB!ǶdK$ϝQ̬ԅBp8(,\dr0jQRB}}5N(Osg~׮]˵^;r||& ::Z&loX).^j'%/&Iee[YYIzzi61z͜sY~=ߺ.~#,]zw⮻</ä|ngժU|✳ӓO͜s9,]z:'ݢ^jvEss3}]0B!iaTe9k~ۅB#ã;w>R]]>il6[(*:ASS=MM}2CyOCM܎_Kgg'~&+/`Eq~ĄN'̛?UUSP ,]_mZ~u^zg{(B!%0mlDGG׏9~ ikk\޾S8pTB\dd4%(Bu^z{&lo6)*:#&~£GCj@7^ye:;:Cx믽3<7 E;p7}v$''o!Ba/p8())Á㩧BMMulܸn.=ʆ yGݽ 9hBq%7À=L~dfNGG 55@y$&&R[[;&$$Lg G~a|{=.pE2<`>ڂxG1'g}}kּɍ7D]]۶m !B|_fhho|{|>rsmZcdV׏=Rr9҇d"&&3= DNޫ\0cB1bb0 *+007a09832`>B 'QWWG^^ޔyyy46Nϊ#3;::G?1V=a< s˭rm:?=Z4 G{'ԧ._/0-B!'p8%%Bn.PTVVs{ ehƋ/7yֽMss+{6[裭|wKTT$=EQ"!!>wBB M\.l6+/b>4YO!NlY$' Q^^7q?LGO}~aV\I[[Q?uB!B)NBBpb(<7&HيR.M5ݎk{,? 7\˯s;X,h<Y<~YQ ۷>ƍNvv&aaattt(J踑cgE;$LBXZZ)xV<]opp5pwf͚B!8٘Lf0gN&11IE::Zhkg_$X٠2ۧu+5:C;M=Ù[%LB(df%**EuqkjQPNkkU34Z!Ghݺu\qqY׳vZ*++5X|9>k׮+82$42kRa!B0""* %eEss--|Y&s瓗7UU+띙53f;ܝiH,'(EQʚKDD n{ѴCl b6[ijnF+ԑ@(T?/_5\CFFS__oo~ZZZ[>d(,.Ϻ~o|W3=ض1B! EQHLL#33xn͵47246##yXZ.W?6>ߩ,ˌom\ !AUU Mր$?>jZ[ghBL- ?~i~)W4~iJ<^B!i&9srfsJmm9]]mz#()Yiz{ox=B1TDNN!Ng}Օ8a/d2XM[ۉyW89H,B!q`$H.b{`\{JIɩe`P__ (/1B!d2SN7uu{JPUuutvh( !Bq ?#ŊM}}!WOHHaӱltwws&\N;\kg"Bl&;I__Q啠( 55LB B!8)BZZ99X64OU^+$faݻ}/1 |u-'`X)nwACCardd4ŀJM^z{ffBL3 B!8DGQPH4Mz߄Arx-Z;718?\al~[H5BxgX+jFSSͤDEŒ]aTWgF*̐@Y!Bcdǧ(HeIgϙKq)TVj/1~q E1]@Y=L+k+PY!cVbV+ʹOzLLLNuu)}30R!fB!B2EQ+BUMPQIS)*:9sr=lބ a9zGD;* !qnw[b֦IK"33@ @UU).s8I,B!, h>v0qVE$&&n}ghcILLd2i3SY$b*m/*&_9ayRIW{}-7FBq\q8`6in}09!!{pg`B< Bcԥ]>CǙW^~i de3gNmmTTMzlDD4栵ݻ7V@MRR*11 tvNe1}|%I/"*6l}rv\/mueX5* !q '/U5TMGGˤ$%A ࣲr{F*@Y!8޳g JJf{8a,&,, CY;ؘx/>Dy.jkyϟOJJʣf(&]Ӊ֊Kdo'mQFƄ4 ~nį0UN+vΙ93JBqL 7D]]]]NRR:~Rމx'B!3())sZ[܃ظ$/> ÀmާcoGs^Zً5_qsHI౟iJ/MLB?pW[`}~G;O>xk?{&Hˎ',N]e;̌\h+ * !1)""@؛Abb^R|D B!3d27t4OY6::Ɨf84_il߾g4SHOϦ8rrf?~##Z§o8[j1gĴvCη~v5aƘv= n/wI可Dj+ڦҢ,4I,ǔrr K__Ǥe硲raD0j%"*2Ꚏ[!89(>\TQcqUUz, NhHLLajzG\=/7Ꚛq}ׇ嚰4M=~':8EPT# mGT[155hƖ-ucil%71GloG߄v.[7kqoNG|oKN}U; )3( !8DGǓ]TU;a{EQ3'O L[V'HKKpYnݶN;@Osl@iiih<6'|r>;\u"VF3CA~> 9s24-@ aZ&k{iR[>86q|JM$+UUhjBl Oe˻ L%w2B22+X)[tf߯ok,0\AQ*kws-y\3'Hf\tݠj7/ު( yDE14䦺> q"@YQo/fjBuS83(}Kll]6CR]!q0 ȍv>" k<:06Ōjr5 +=^zFXyzïF*;<X3Yfdtv\V0X,Xeyx ߓN (ݻT<^/6-<]SU%}N:óz`\bBoZ[ v₩g~>̗q9 m?plb6[;wqq {TfRXx >-[6rM%pUW#--;TekC TFZ|Z.L^Z]9%h#ܨ#j0j40Y! )̙܃5"9w q"@dcE煾pꆎgë/ΒSt:xc32YtPn[twڤriKDFD`J,6Ya4wDa ?an$}hX!KUא1nrTT$s5-4ښZ2Yx !71ݷm۶p3":*.pCXXEn.Wq;ȈHb2.= `9믿'S/id⒋ +SZq^`>{5t^ںkK_ϫVbx^¨Ï> t^bcbbm޽cVE)lvz)+ہ7J">>%&۸݃S6@OEnST[7LYߓ9p(3G,J&5b{tcۍɬ:g0l>qS I.b%%(/TU%+(\jj3ǂY -+}$$2nb6)(̧wAWaXL^TUjkB!f(8U?:SNlVJZhβ^kyl89`k25+)W{Z@?@B||踡! Y\lyeu6h.=mwk?E ꫯV;~HCC+Nٰ]gb=G<6q숍Mdyjhq̟*`4LTÜ99%AKK`TuO/;{ν?o]0 />aԱ޳DƄq{y}cۍuO;>qS w!-%%l~&]@UMtF08Gmm=&Nj(Vz{klq M1LÁuX@Ѱ0'V}B!ĉF .@t{<9Ǵ4]Dyݘb3qqq50}~Z,N_8Uj kj l&<<ή`:fZ~GbHzZii@p6dBBb(Py $!q*55\t]l;GV <<  ;wntae{|ҥSPY~fT0Y!d{)+ۉ;&Bpzmm(뺎ni E}Ueh?0jߧv  "".o? !FMQ Ts֭ ar x=p; XB`ftYgIoO/:+d?/?xBRRYv-O?L M/_/4f(>`&J'p๻IHuںP]S[# TU@8*E%y(+9iƃq8XLL&{|tT梁z99E,`|03u%e& !ı"==T{|cJA"짬lQ5-rʙXVw4 Asu9eH$LBcBFF0p~W[,ٜtwwp%8QJlZIJN^6nh'/\Aqq300:jC GUUt< L&5n/B!ĉGASAoWTz 0:::BrOOPV|/^.P(\n=s6_w-J}}vϧ j簮K.Ąl6u\OO==?G[pW;8v_iMx֯_矇hZߟu׳ ().F4N\ɢ|3Xvڨ{T5Ealila~>짿=RK?IMjB!Fdf%!!AvLb7A{{ MM^CѬft@UM  bCugV˅ E׿KGG118#ǝ##3ζ6,V}.ca͛oNi#uBx ?)N\ ב}x}0x0(3AXvÁ TĐg,W^}u}gxqx?^޽ &!}о?>Dپ}{{Q[[GXXC罽L&nw1&-a2hlX3{ΝGttTWQ!v}…X 6o^7mB! ++T< m6;sj@s!T e ɤ>jq0'8v.Ob6QUe8P5X*+h "&Mlwf /dF^q|K_?V! -pp>M& c _X=VXrsu=}LRSp)-:kvuQUUJ^^1 ֭Nd J!S)++T\7yl;;w>f:ZZghB_fiĸ8t=Ccf(;N*#<*fYVItBAI]e%fUl M(geevu$(,,1|sYp wM_+(4 ,"=i*bf8~0PV&( qKO%))Ken+**sٹsaMNuuDDDJ~B;z'G畗_B)arp}0#/of[@ьʪɄFxD=].f3fvZZZ0Yl}11 x 0T δ:ztrl߾ ͭmNAA٫杷;n'0gΜ1_*?_;y^ux,X;v /Du֯_?&PK r?cSRRߞ뮻oU @ZZo|KBr8iT(ܸ|9K>-oͳ7);N ? vcCW`] ƮEmmǮ-SDxxmm !7v}…g2RoHlK!BNN&GDDW (ԔP8L3([zN\|qa0^z>יYc^뺾FՆ{d \.n :::|ժ?os `B/X{…UoNcc#^z);w.g͚5 MPxҗndݺu(*.&::~~_n's8LC-7zfN*srٻ.v;]]]l6<ֶVP{ł4,D$/J{{ 5{ѼDҲrQQ1|۱={>b޼X m{k`%BBNNᨙ&DKnnUU{랰b?uOhRiCGut]0#z.?hi)ɨfo>%^bȭ@:DG_T@*_|1viҋSQQ o.t:l`YF6>~5[ZBH%(!7W&jeG=0yG||< .3fwᵜPm2= N(2GX232L`/B.i?89E7U\KSSm6;u-h6AX,f-Z !bLvػwarLL<TT0Y#43Aj`Z_J_|\y=~Fgx5u nʕE^k_%K4‚Bv1؊ KnK/կ?^zzzظq#\r!+~sV+w`;Ν;]w !8&n+Ja֭ٻ7|χdBUU1ғڋK` %+ UTsϑzs.wze˖ǨΆ _ΩիWOyKf\*XEQ(*Z}mil6[¢EغݏB123HLLch޽' ʚTVbpF*ĉceho5X00t}c}k=fo_b_F(hA hGضmOhƽ~|3eJoNzBLaWHr"0P-5>ׇNwr=s6 T-p;k{3XF~ k|G1QE<;|>=GϟϿ_l?}WK_䖛oFQ^{uE% -%%d{rM~a M./?v&Oz/fL_ʎcdBWjjii|^JKO|[RRsivLx!NFXٳgѡ (999JGGjZM.Kut:-~ UU 3 #0/TvL’󉊌^4/:nɕL(ogg'o:mmעO0󷨸~}qݵ9B\\\.::EQ͖mvbqdRҳB].*_$TFFOw3'_B)reSwm fNQ/CF6moL~.\!?_EFyge˖rQ&7 iii̟7 6?ʫ/eyW[$22""#y~3N?m)+W^3:wV\T+/&1df%::w=SVd2xXVv<;O!!!.v|ׁBqINCVV>={>}RRy>vL<B'>+EQe@uX,>WU|>-!!A6"""<.L%M IDATt1 62ӓƵ5."wкoMjsO54b2[Pt/^-ZvXشq۶m?؞4M'm3 G=7dy<<lCf#L>^>?H CB( ^īX>uA&lV԰pLp<]x=>qGvM,0Y*oz' AGgs\txW~ӦMpYgQXXȵxq())s\Cdd7oB-[FRr(¿Woq\}g'DnnaaQ\TUi_<99Elv뫎0`(J|| ΝB!&Jvv~-&3gHgBh|/?9l̓p87~_\gμTLU#8=WU)]XҮMxoáMsOf*++8,Lwv%Ty[1'Ǥ* َYW5&4Į8lx,L>@eG6|^zyn{.0P^f-x?>'?Iq\+?ɻ]ǩK`X?LHU5H-%.`X;wvyGQd{$$R@JJPQx{ٽzD) (AIޓMIvǒ@HO6|> ;3gyg&;s{%$'ǶL8;TzRVVJzzI =':tJ#FL̙ELe@ t9..* 蓭zTX!& [cW/8sssJJٳWjyKN*xl2 kp*-RL6RRGkB6|iV DOb;WIʵ='耺pfOؙ2kY8}4z[nh=vppgiddd@VV6 `00{,N1no 22Mz477/^ٳgU|o@\\8w\vx""R 䊿0z=aTVYۗjbbN0 VAZ5f_0Ɍ>E~%(]T|*HsGo:GIYUpEgV7DDDv <]0uwu[݇`贘ZKY$nFN?O[ƹs1psIe^c{~!$0Y7P_6V`=UU&C$ ?J/jkkI<8^Obb$(z=^^EeV$AP(,\N||$%%-L+dvA%0,Zư@лUUǟ2svzMJA3``FHDq*ZQ &6, RRQZ,ፏ91Y$^%( Kmnnh@ 6,-:2,-m())Ht.i77dg_zSRj8П#&Ox # 99idfX^:/&\|AW"4_$Z-IC jLP+**dzڼFXd2`g0*Փҍ"^< ^^Q٘3aPfƠ!h+q z('%|d7fݥaffFNN:g,L&caaMT [Nԟ7^Ott8$榢0S->JOBL++IR$IezИWWVVd}uuMd3BBB zPNX)n喞6C ww/  $%Œ٥yzҚ܌KZLNC/#$$g#ky@ E-ɮ* v>>>5WNAO ɰhNբ{"A[ :Oo" qW*P[۶J%gIPP  df I`d2 ENWKllx;5^^j5%ti[}"#?ssES@pi5/ATUUu=''%:bbLJ@6m6ži!*w!(Bd2Bag?]r t:]O"Hi>lN ɾ{K:q5j~ +Wnuߠ _mHZ׿xbرX(&N;w>mJ K++-ƆuCRٹ¢SGiiʠAC13 55A/ETWk_}_|>wP(foX%uynf /ԕFЃrAmm )(閶x{HM5M??V{*ybn .ff愄A.mlg@`($ NSZZԮZ{;u:j;;;O>$ӦMc|w$$$RϏiӦ裏~>#rss{A@@@uMv!&Lo0,퍇'2v\'IISFɠ!Sܱ%6.1pWHNN sm7v,]Cff& dfeqQ^sA`xyW-ֽ_ce~wǓ 7ν~MBBsÞ{Yj5?>DBBs1|G.;'ƞQXZZS^^BLLx78?2TWA喨&28#qppaDG&4#!==ll E&Yg=c q+c>}:۷o'??3f/w^RRRˋ/Ȍ3Pl߾3fs=̜9ŋN;{{T*d2ia00 L&Cήƾ6u7S I~d2yqrR6)>&\t]z|O>aar뭷a/=oΗ_}Maa!~1#**s ;]!"2vEٳL4 g''zAT*w&]~y:={z^^5r,-mLԩ*&;8FEE"d[tDGVgceei ˠA8;+).Vcʆ1IL4uaOF.Er;yxFyy9|;+VÃuu:QTnn0Ndgt7y<<TRRҵ"f5UFm)#i-hvk];oG''*~/UP@{hBsԙ3$%%5h7++םCA17W0te8;S[[MLI ]&3h?zX Z`ГIee3lX# gqqQKUU%11͊bnnNRR4juC6AR2̌3x7o^BWDGG3o<6mDvv6{TcJQ.-Jww23|Ykȍd2ffM߮.AbogGiY2 TU޽\ܰiOYٙ66KKKy ٳw/%֍5ɰpS KKKv k\kP ̜bbz$d dPUURh40tHJi@ X[4@t?4YN.7#8x4&[zG3] A. A ĉYt) #_!b*wT :;;%[XYY,`$ mɓ&`k#0,$VŘ1!JPPCSdfiңG .**+bVo7GFE8p m?ٳfq5pq;Ɖae+kmv<=ǿ+xcRW`iiС#qrrE%!!̔X݃-)~0*F틥qI 1fff 6܌fIDPHlm$##[lniG9}MYAy̿c>&Nյ)I;z o <,m=lܸNƍy'xޝm~,YӧQYYt:Qرc+**pppaLrs!/d2vv}\μz{/OOrssf1nD~F .?,vq4R@6 /ZȢ &)9UVtl۶9];W^rX)n{CO!fJJJxp"qvvF̬,~1\]]),,~!BǍ/Y :F>c}|(JZ-EE|߱Nw I21hPr55V 񚀊RΜ9NPHJ/,-;N8!@ >%--w!88PTObb0˰6_O[Yf U [nEGmm-z~7Yf ?iXzɎaL>sqw{+6899&Syt:JPyx`oo=*J"NCi{;G5?kE)ùX:OW9MrZ-ZR24NkMr[^e2'Mλfwq2,o\.G$,,,lݽA(Ia8/ܧnywȑFqqvnm{{,,,BbKrss)((hq)??Kgb΄ ` 663g78:`g@YYI_TWk>>XZZ*LZ-xzzݭ/t뮤l<<<pvvvFQ#;~[nGmXkBBشN xl۶.Y³<;;6mgb㏱`| |f-+W"88~˯;w+9>xVˌgrʿ߭' M7s-g^^xfۺ;;;<@nngbdjjjxٶg-\=w߅⋕ZM?~'n&z=K|ٳf3~8*++y8~x] A̙3,~)I)23SHJGdx{HKi: 菻 C\EJs=mBZbcOჷ/M'ul@ h>#(/za|!yyأRPP>/ 2"O??/'<,w-Յ_|Ѯv*6nhٷo7ʁW2}9r9UUU<أ=rW^}ob\0DyQ/~I6cǎ_n.})W]mrS|wHO@hu l>_䕗_BRβe$ 3mT֮]Fƹs{ٽg+WE IHH @hh(`cc?hѮqcV[lkMdms'2/_Gcd22yI*.lyy^{U3_\Ë} AY& 8rhO!XXX1xP<=!IEEǟ5ft`0FS?IL M:B߻㻞fG4*Yo555DFd@4}"yG{ؿӦM',,h]9_OrrL>q߽#0a„v=p@L{@@BB 0ifffأpI8x}ҟ}9?lDuӶٸiΒP IDAT`aaE`H&M*Μ9FXFLV(,Q&;;dw^o{$@ tOρ8;RTOVVje ^'*Dso??5oy5g;[6O ARČ~!#$$>~ĩpN8N\\,C|}GDDчc3m[RI^U(J hg rx#^wNNN#GλF憕5 >LƷ߬EVz&;dܸqڵKlzJJ)))iS-55 292q$(2L!I_>4j2c JVDudegͩSIL2N}>~8SL7nӏ?Zklls[\N^GGG㏣GǧziZ/"Y,,2$OAd24JbJu|obm7QRRHTIXYY f &.%,- 9Te C%"#{̀rk7+qpp*))!66C?iSm}̾JkkkyGm=--Ç@MM ?QFa/XS oTk׮ر&z s:;vB:~[];wwy$ FUco-[ŨT*MG#ɥH[~{\}U2d2u8p_ T*wl1u,--ٵk;>z`|ՕWǟriƍGFF&k)Yp!))\1y2DDFb`ϴSyG@ ٻw_EX)nr<@*Q]/F 5Y]SBLVWߣ T$IJ%++W7w6璢;VGP[[Ӧ  HDPP(r911ah&BaArr,EE}qm2k,(--%??Xd2rreٸyn712^PiÇyGw駞bO`0qrrdҤ|' 1 Myyy(JRRR:spssgN@_"Iš99?'_`Ŋxxי޽{HMM%<>_RDRTTԠ4X}qֶ.'| 4 ZޟX+WT*[kP哯^\\6-:y펣3s8vЫ%OAT07`0MJJlU*=P(gSU%̞BדF3OOC9{62L hG2*''-?ȚߴopP0KmM"Ծt ̞ '..Cx{{t9z'NNA17w5**9{L7[1n3333֮]NAAA2$E\|wuϙCQQ[m!ge˖Λo $Q^^~0Ibڴiݻ$1}t8`:srr l2wك>ً/%K^t:|0S\35={6l޼ɤvF||:&D]ǟ?➻oBzO:/:&11o׭'/[۪MQW[ςXOyd(2һGrt`ˎޭŴӱ߽5j 6 PS%%%Գ}Ƴ\R9f݉$+ 2΢V=@WP$I&sY $q7do#x._|1渺RSSCAAA#\]]ƆiSb0$!.mɩPp'¸(*,l{ԢM"IJn2j>ѻr4Ӱcƍlܲf姭q-0c N ){b -ѧe~`@cTNܷo?8M>:"Z1uT>cS&j 'Nͷޢ gy[wQZ{bɛo;//zOW_``} Z-YYYğMh1p?zw :]˅ɧ[7n N2z2cc%*1^_d89Tz恭9!6 rk 2Dff:]їPsh?df&/%Hs睌37~\Qѝ)((@.qםw2bDD?Ͽ/SRR”3/n٧ژ[NNNf=3̙3ǟrݵp|t:<==ZCPd)TWW{Ϟ&Iel۾.Y2W^q$QQQG|-[:|ccc`Hi\ApXd204GKxx8;v2ɭhرs2n6 BBV[MTtcBǐΙ. b:}̬w\riA`udgg~.\m`…۷]ɹz~;ms9tzС.-+#iNY[[3v1~o< W纛^ϑG tFOu)ן?~] zB{D"&m[YBU\n$N0$rs3kcc vM A)++!&& aT^X[[gQ#ygPռl9Ϲ0 e̫tVƹL2gΰ˯{Z?~6s?xy?ϓ@0:0d2g# KDHH($&XMQYZZ\.',<u^^9} Ç ËhBIJNfժռM\\w-︃_y,!( _]G}ٽ{7kذavm̝;DuBLtxOXLP$m3@;ӂ~f{.=`}{~[}ic\7eQyJp,Sm ]qvv²~{UU%YYfRPE=I0`0u!p|}s"(h }MpGw.ɧng(++#8(W_h o駟puuiVu o#GP\T3133J uWI_ 0Q#GAtt4wf̫~uڹ؎ѣu9r0:zt?q>S*++i6X8';;\\))) ?q=_`\P=V66xxh4mG2ɪ* z<<<ࢰ,"ɘ_|u}ʣGdd2ns0A$￿(I^WT h/-ul'(-c>͊F1ywD A\:`k뀝=v(fPT&77RғHMUU㄰ރNWٳxy F"0p$IIV \,&_HRR2L2ɓ'qExɧ((,$''>2݋4(A"9q(JGG0bcOu iW kkk*++emm-kkf-qk|MHH06ɓa|a￷m۶%KxcӦMCpY,~1̟kֲr*Xs'/*y>o=ch̸z&w._Ν|zشy3r {_j6+&O~m`…s]XYY⋕ZM?~'n&z=K|ٳf3~8*++y8~xA۷OOO6mc=nO吐>sKEV a᧸Z]ɝ 4ۑ={Vcp⟓dP2cG1+d2re9 XXX]@B nS\gu33sݽudg96`0HFff299=m@fDV־ft/ww%[mם;yy?:I𢅤GrY}]]\yw2lgX-r7#vn:233/ټy3+Wl5 -=~;/2{&k-yj6mLVdŒ׎VAw`n K K,-P(,D0v(e23d2 L$@2hM#ײ}n>dh0ԉw]CX|~uتJs)//b**J/^^edeOгT`lHM=+f/ z=*H/Wsus-i()-4h ))g԰˯xEKl_>q>s^aϿ˯s<_ ׬ѣ >,{|]Oӏ?9ױy˖غm'L+}0MXY[qm2omTTV"E1``d2))gm5񔕕uF:ݮh).)A.#۽B9%h[ pQJKKQT8`:eJev_~5-_3 zR Io~9yS!:tѣGS\lKIXxxjzS0kL.>+O?C7gل~) {333^wwUv L;w.O<{۷j5nnn1}tNʾ};wn\"';+򢴤MN-?biazWM+#AWbmm66acc `nn-I4.G\5=Zz=FI%B'?K=yy)z^^C3~ =:j-ZmM%ZVCuCR''%Me12bb2$''7,,ILFVK-<$eÆsq 4h ֔j„s1YgW_ifjkk[_C;~'G''***(..߶{^vً r c ַdGuM O=,NڭѬEE<3XZZZ6=$IT֐PpvVR I/ȘO%1F*uܗDs%Ibƕ>8+pv0*((0iߺuMVV6N&1ɘL2|r߸O?c'Zl+3um-SSZfԑt:c_~F"ofA#PSO?e~ԏ呖ơCnS'O0bXCSa͏z7Ժ>އ{/G =PX .;bfhP`0TR\OEEQ1&R]mU d/; cCqdKk;;{󩩩ism*=$$I'vkCi3<W96/„q㰱KKK,,- r[()mOEe%͇A8)V4H6,Jm̜ bb0fTSR\LQnۋG jK{hCc,gfRGYii}"*;;vb˖L4 ?)5k_MerMyqqqʆ"zx*p)(=GsCm. I FHde5A0Š>#?,׌JΫ8_7(;{7:Gaɵ2nۆ' 窫@VKHNNFVFXXZȨ(FAZ[MGHH0/ZHMM {]j5۶mÓ\{+BPQ#f,&f(qwѭ>F0|JK(++iԦ T=W:oeGGk6G4*4mm/KȑannH ~=Dee=Nř7x2v(C* kkkrm IDATsG d2 ...SK\nv.I 1G_ /A:23Sz ͤ!Cʆd. 2\***1΄''%:]-=]]=pw@YYK޺:{2GeP(,p&#mnc~2*tLl{  >3>|JVțk,ھmik[SSSO>W+Q*TUUQRb|y |ߋA!e@턅ni3]H_e2JJO\ɌH ())v[S MU#IϦMٳgPTlݺ;<<<ضgvKKKVMsm?fff zz]N1m(n7z^$Aaa!6m̞={cNnt:=yL&' G&%%EZ^^|1f(O;, $$n__]wۋ_\>|e $srYY)"n?SʚXt:tQ{nӳ`AL>mCJEyya'@ƖA;\N` y<59ZNN jT..Sד= :VXl=@`RlmmJ卫 I \ rl>Xw]! "#X+\]]YzA &&{cooLJ'huÆp7;B^j.%ffwrrrؽ{666_@>(xTU͵Zyd"ghy5aQX^BTVV'TU) =@)RRv,qqQTz`cc Q[[Mvv9TUU^I71L˦p133CqcnjJKˈߏSt]Cj2)Jg33hGDDm뻘΂x{!I"_GӑNjYJJ {4m؀x QwёQ((,$d28UB49;9ackZ_?HPu5b,,,P*ݨTJzz:OP` ?{USIJ @Bml[`]uuWŵbþvW]׵/1t2I>$ $L{=d$'%1g)IJJb2lX:{_֙5s&W]y?I/dm-skb/Ep\\,uun=z} 1d0LEEIMsZZZpi#umI~U1ũ!I &u`|8 gɌ~_ȇ%sN oȈh㓉i U4x<;EFF1{ysպjjuǎi&--{:wypzvXh >v^Enw^:Xs[.\~~$ L&pgrr6l}sv{HOOcUJII Ŭ\}Q*唕jc>\wE=ܗǾIOV邡BadffKV*Aq,ZI3f**8N=6}$E^~qyk,@;lrW_{@Jr/~]w}KRSR())l4mTV,_?|r>3{6QQQ۷k> $dzgIIIEo n/gdd!I2] <IgroimkٱLu< @ 8an&mek_g/En&q_"=#:$SC ݆TE]]nq& `Ѣ;vBBBXyJKm…/ʀ_jAϮ&44'W_XxWe>147+ #22֣[o8,K@l;jr=c4ijj ^|FNG׉<d'<>=KBB6nֻBpܸ$I%,, UUC[TDQISz'o3H 8]PQ V+&;}ސ1YAY`4Ƒ7!TCMM9MM 6P>s:]<+~O/>+ҥ{%--]'*ZX] um~o]V?$dYdQ|no!%%1$ArϨU5 I^z֕l$.n wR\RBQ(**jוu9d9l7TTVrկ~/ fΘNVV٤C!I|g$&%267o IXxu޳8#&,k8| C ʾL}%e[bM#d2ϿDa4 {F`0pdqȲxR0/&&˩2?|ǐj-]EE3fL1v<PO-%%yߣ}_FJ0 pjk 'ARWWnel҆Fy!q ,ag=,^BpEԪ[O~r?vt8OeΜ<)nĸ>z=ee|)N5z &VKŭ!$kjjkIINK/aO~8n\H'ʐ,JLp1#S%馱MSp :"zbG ǭJTSST vXҥ{DEll<11DE$UJmm%uut?lձ\xOX۱cg?hii|f?? 1:Mi遣Wt477.23`СA2I 8}6-( /o3MXg^cS_b5}8e,[.?g-]iʳ[o)켟Ն TUU3st> Ͳ= 9%;v+v{3:]p_%#AYVىݤ`s]*hA*#4T]>UibQ#Eu(vzc` d ,I7 ~IMMfʎ?r ٳ TD "#%:Htt?7@KKuuTWrrŹ$[@mme`?>23sh$ #8ᣉ#+kٺ/ zZ]˯Wb$Oko(((Јu蠪[1R[[~dɲNXXEMxxTk"o#Amm&S5&S5NgI[8I5^3ϼة N)eN7S5' !![ ݣ( Nb0s,SM byƞ0a],`ٸwm!۶`5˷lտ фc2p8H:u.wO}o{Ν\~U bbbhjj{1K 1??x󭷺,wٯ $I"%e8ۜnYY1AD EPapY;SR(°ŷ'_[iO/, 4{zNƶ;7~5Wnj$AG׾Ȳ,H,k:]zJho@XX8!!>RMM 44XL44ZO^"""~9ų}D'xɎV##ctH8pp2V+Çg1bDeTV|ILK9(//<&[ihlvb۱UVI[V#"" ͆ða#)-- Y"De8'7W>ɋ]tD q88(;6 :#*Q@3+ąia de6c4Fjx$Ihbi#\p%|lNijjjm&755sϠ'\@cc4Ϲxv)_=cxvv,1"Nq86G0hh0SXQƐMXRR iAyWx镗 H'ѱHLUa\dƍASSÀq$哼bnBBB견LMu4O Ѻi^A9!!nQsVKUL>L::L&s;!sXMx<TUQPU[Q<\Nl6N-{$yk,Xnˇ>1 %QhdETT IXMTV nRP##G!::Z$Ń@ dPUHF(cl6=_hF@-}^oOn:?bccyow,< ?ȪU߰~U^ Q:.땘MTNNX 2FEU%+F ́{HM$111c&STT0@ 8QZsxI1kYzyUUe6$k? yB|++&L< ~sbFm~e l6iii!;;˅^pqFhZۻyGx( ^zEQgoWG}ܹga=W\_7nG}PޛbccӟKsP1mfٲǺXTT]wCll n_zƁ]2d>QÍWTr6UUiii 9!p>qS]]l #7Ϙ9s.ӦC{ٷo;f w#qɜBT> , \xE1#F?b 6lY`2d2aX A": f)SFρ>A=yhP5AL2QY}bτz&OĶm;;'I,> }KKK;5jQT iP;c}ۙ6`Pt:$N_ٽ{3eeELt ӦNcc=EE{(I";'$[@ޱ,¡;APNf3o94Xl0l6(H; aD\KTlvx@x5p.RΝ;f@ s..B""!)F&}tZmr<Ī^mYx ,jdd R ݆^uu s‚/$fͿҋヌp\]g`f1@0HOExx55:`r9),ɈY$;EIcFKYxt >r_JzFs3f*h7ۏ8˘9s:1fs-*D]]U먪BiiE$$5 dgO2*+cO|,Zt;vmٿޝwƶm; &Q9Db(ӖG{:ӉԵGb؍K; -pGDQ6ZIsA966dd M6/~KV^vAgʉ{xؽ;^ן1c[lu= ޛYfΜκu__z/c2e2˖=C-m3`(2P4NRjڻʭ"44] N22SOܳGGGЀ^salXdL^^ 98mƼyp{ܬy뭀T_  7WTT`*_[ ?Κ޽PUVfپ~GW&xglzZYٽ;ݻ󉍍!33ZmS_χ} T}.F#>kkyJq7df`0SQQBC9NB)(IJJ',,!@!0~6AgѣG]d">>pu ZR[[SO=fmA0wB_{Wcnc ?xV=$Ir˫?>:쉨ľ};pfAx߿$%;vlAd0ɧM&;1NMEE ddF,kh4h4hKF,HY$ Y I2ȭ,t:0kh4t:IҠj룉 ]\D4)j{:;UU)((AV5ȲUz+JZ4rIҢHR[]0-騲,(;FTkUUmWM -xn7qEi  Ӳ %7jhXv晧˻# 5"(Ro0g?#~H\V++n'11q\zwlD W|+t>лȑ,w%--m۶RUU_eeqDu?mgLdnݎ#7޸X*+TU`0T7`9Z.y7rf͚NDDx<nN SLw ,w-wQ?~,U}—R$/P(|#F4jǰa>L&L&, !!!޷MН3pW{E[`'$!Ck>R> $Y#V+[ne̙̙s*7~P>k,22#N͛{[_ @A9F`*bb7{L-[)ī CY$b#5e#2c\vic\.&oHIrhd(~#C2P_ׄu/~oww=%"=mO_rF$&?}QQ1dfr)(؁F [əHjj+>7]y8ԟY &@LkO ֎/k/zSDhl:mBowznO(GqyI 6Ep PUySSW@8r+Tt~0qթa:m;ETbroωt6)hh:Ǝ$IݻyJAۭٳ %Ja.=jpؽ,I{̂/DvU&_Fg-JivVo`7c8V_0c\9={HU__ɓضmsZדx:zj(W/!!FN'3f`ioِ,% C=Ul1))X^WIKK 111L&illEA/INQ_/2= Ν,Xy6{?~:|G KY/ %N̨>ik.:eoROhcd6c4Fjx$Ihbi@$X[֯fP70Q< azLS:' 96PSaAa|ۜeײi]>} ә8+C:ݓ{P?mz:=Inn66怺6[?Q7 Lxx[D_CZf 愋BFF6qqכ8|@z*<JzHƍŋwj㪫 3s8h42}u)Y,[XeW$mu\fi:G2v4N?B**J(*;{}8%k3|]\|DD[u>W_}Gy9sfs9grP1QQ\w-+bccYAo&lNKKDU7` 11vŋ 2V=NF0.=@0t C‡Utv/pv2$9W""p+ vIk Mb(wGuuu6 vLmE}@5_BT>7|tu9s/"6r?`oU,2 f_/~]>N߭YLtU Cx¦/=_OU߮RڦF:/K_i#~z6޽{ n(mwS䈈p"#B<"E444!IϿuׯS]I 1Fh!p""DEŐJBB*>`J76>>lv;q;F咓3ÇSUŜ@||$ckؿ@k/MGo4Ft]$1yDt: QT/eeEԔ3zX Mj,:*/ N4d_+EQMvکzl/^ҭrx챕X;wk ^_Wב@ii_L2e_l[ڦPVVN||G$H1n@v36>~n0:B$ф7G"0@ Qt|^TT]wCll n7$__iwbLy7ibdtYu- ++>EauPTPIRxouz-,ە%Pd ZDE06\E%E5.LqAe'[}m(;19""&FE]]I|ѧ{G{ꩳ /:.8sx啿uݣ[ ~QVOb[ۭ]CLL< )DG2jX\.'UUel zHrs w Ta#'g"ÇgFIkA{#su ()9̺u; w:y߬[~?_ǰa$''O>Veɒ(/n:N&#c4#G2ui(Bmm%. wv[~W<ޝϹÆcىEx$FB]HG@3gNgݺ/nK(*,G ʾfUKAƊBbQi[Yit3@3PXШ,nqC&D6e@Ͷ(ՙ-wozBBuhn ?k %KGstK߿AYQ}~Zw,{\N7ܶ_Z@E I~#R;!b7pVnC\\,M]E M|ɄhpdYFUU⨯{h vW_sWNmm%B@bb*gi}A8q477pݻ0f@c⋯p`c: e6O,gǎLQɻw^&>>+O>c͚qs}upz\.rPqqgNrr:X\\M}}]P;BGڸo*`t}_QQo|{?\s~~KW_p?qqqa l64 Y<ԳI;U@APo21GK}^aQ:|wMkx ^N² 8+m5'p@'*Qࣽs {uQn[oԛ<×`;.ptz-FTEEUϿ{y[N\bB}mS'|\>^ّoވGJLL`\wM(Ioy~o{5&>kQۍ{YȲ|p ؈!--'x}L>>G]q̛ A~6,{ UU<#l96=_`FLL<#HII'33ó-h'&I?~a:THMM W 8Q8vvLND8Ə޽;p: Rйi?`0^OJ5)hn_WWVEtK?UUIK"99bĈ,@dD}Y:֚+܍AǶT@/uhdX柔KlC̘1͛s/d"k ѣj~KA><w7uj^ $(r~QJIPNF уVTIɎņFkAa@pa۱pz_d39f ymPƎ;$LJ.--kn8:2<Eb8FCRR*ӧA}}-XL}9jm$? iTUh/vlƏ{0@p$zrn>j3ސGgVw߱=Fxxx@ȧ׆,h4Z4 %IFe$IK,ke IҠ(*K- fZ-!tt:BC E IR ` PW(5Z.W^V>s-EQe#G`qqݸn=RyiPU_/8F: ~'(2xEm4l# >NZ?3Jfr€qD-/jp"""IEEnEQfN誹.UflXlU;#22'1s\)(gCPF0rv;۷RǔKmtzhjt3/}A-+qOqrE瓜믿Az~̃ދbѢ%l]__xVU> 2i{5_j$ ZWľuڋu﷖ZMi8,QU IN;vNGk}.yQ˚me/:{ے[|}k[j??dy2TU`;:ǂ v [A}p#!IRD@̱"E;ɜy.mƀhZ`oxx<bcc7|Ǩ*ՙ9r Z'Jbbb԰a餤PQQXhjjLZZ䍩7mWUKzv|y,455m7DGǑ3T9xphמ6^Nmw+*TUUAQVGAQ܀>6p'e@մwg%y%֚1b q'>.(K;VAp('3|]pɜA )rs/rͿcU֑ڵ7r#If>msfl (++ʕYr9---ũSVVΪUqp˗?)jh0%ii#ʚ@vDRRFkW1gix<o.(d.%6&0CZ~c$N7Kt7Xmv^ۘ9̧+6 B+im|B rM m񥥀u|nO}۬n<OAQ7w V{HSSSgO`4q:XmCqUUGWޣyV+.c((,SSSAV39s.;)//qF&M ΝO ǃ\N1ptz\.Opb bLl---fa4 =j J%p+-Vo`o3nO;OwW|‚cH3RTT7lbi`X51\tJ)wg B3udF_<<tujldY&&ƈ(X, aB jjvY&^׫,uͳGRR"'Ou;.].'[)giL&&&瘮eh4ر_ fz{뮼'> 3rLCBBHLLcΔ#˲}'5Cuj 55FZZ 8; '797RRγvf1%Ia/;wVJyQ:޽'SXX#$%'O&77*{v8X4a*1YptT@*J J(-(gOWJ%b E0Tlӎ\{5v@~~dggs׮TÃaC^ܫW/f Xiw߅k~ޠqcry, 7mn~{u ]vaȑLH@GGGs:d)))W$(W ooo~{C hO^oo|?*]>N;O=5OG2d oFK``}J'BPn <2TPpJvQ(xxzdSXPdQ(C S=qشi3G1`@?O 't=Jqq1u]73g8>& -8)qT(G:t8ᆛI _ d#lC8R&d2a]T*1L(J\]])))5-[*~\{h^{m]ddY&))"#ѽ{/|b1J߾CX,Gͱ˭Yq̃|5#^P#f0G| ȧ|̀pJ$vg5.ʵ3^^t eUsҥ3 oxc|㍔KQ{h4:u͍y%%PT\o󜓧ZNgϞ'$0lP{WV~xC|*v R ̯ΤI#%%Ƹ}%..&&zk߰шˋ'b0pss#))GOO/c9yTF 1ѣ/} %!8Mf ?BTnɁKcMÚ3ud֭ Z'FJ76Lbr;FʗA`` c„ ڵ/3gΐ @@@aaaL09sk.}]y <Rbbb+UfĈ[DeBAhǎ"E*T* \RTXNvUPUP&?lۗ[MNN.$sO``ٲw,;&a->RRieذ^s3s}|DE\ \Kd ||YDDb1qkfA$\F92UX,5RZ-Ftl$ǁsO񥰰·穩i6qUTrםw@I5ϯd֯vtݤItڕIIEBb"={MPP G ʍ ߏ[iT*6Z7n&55BBrJ-TtOnS-;;2zHddΞu #sR "8aLyŊ $kv;[V+"5ܺon%/'xb6o̤I(**&99dv؁;f䥗^bǎv}jTT$((BAZy޸PTTD.Ў &7'|1uj!Gj^T,2}wq]7~jOT-rhe}g}S􆧹)+3pDD'83Le>ʂQ`͡lz=)}...UF.Lv&M*|}}QbJj 6 ??_$G''<<=mrrJr6GPT*njbk>}P(XfNLvD"lUiZTTdlu_J%nn888 ,QQTx$a,JϏ C/*Beٖj!33}F'2IBVHuFQjZ<==qrv5Jyt:f[oz$I aSa|Ddd$ص ^P*U I,X#m}(3f履Z});Dz^U:.b}.E_wteX$?oϥPXXh"˶2P*cv9v }s(*#\.EP{RpU4L\|Z4Q\#4i3g;h\Xz!&M  S!*_{)Stu wNǎ ġ g;9JY=Դ43J=]䄇YYYf^^68=h5zJ%;u틋SC˫:]l6c1[sg2pT̯2>q8;;ӥsZ5*\n333iT͍|Nii1ǎ`0бc7ulT?rib@e:_(?iuME`` -bƌW9++ٳggq S*/B,,*T*9%e>}zVpϊ^ ,osQ=qƯ3g70 V\B!у{6wXrM})uYRS=[=[JxxzLbq4q}T?%f Ei4KI,˸...Q82I0`˚kBjSݻws͘13mBi>޼³̟k֬b9w.!G1&%%/M^Ʉ$):P(--AKBTy۲T*ٳ?;a8vl?i99@xx_@rcl4o  $)7b'''lȁț^YEAsYY;wm~Ϟ=Q)V*ukdNn.:ggg?66ؚʅs듧Nx4*Rkmߧ#&(o;~rJ ))![,V^t|8;;T*)))]}zuoc!!Q($&`EVH[?4.4)];u~WlcdV}}Z7Jr; ʽzbtލ~~[NEB '';vT*Yv-g&ҋ/:M13a„&MSzjv|@FFFmj\]MBcD"''@J%<<Çƭ-W_}FKHH0|;Ça/kkWB]<.ؕ]i)U =ҹ:ܹ8N>YoJ⢈Hxx?c((ȫz0c]<<vp\MTϋQ+*(+=HLe?7 ' P-De;ӵ|eQRRv(H IDATVd.N띶yrrcyi5#>C駞f׮tܙg;gŗ_~ǫVq >#Zh\ _?_>^*1vX&?;w2mڴ&ؽg/*ߺrG(JJKK;wg ixLٳg=g?D:W_ٲg&O¢E7ګ&(&_M, iOAAU р5&3#fۚyb;)7fKIֶֽ~EEr `ذ!ΥO< 6:uT\\\3E].N?%s˶!Vү=(..$& 6.,ԑp=u"YM@qa!PUL&1PePe5f[P&cү0Q*7vb-た@ h|>,gBǪUkHLCϟϿnU+WoO?ĭ}c=Ά Xf̘>Hbb"\s5l3Æ '))4 KJ"7'\]kl \NC?Q1yWɛX,2u1cF3zH~Ar߾}uOj5d_bjG}v??_ΟOeDGם~Wʈ؆ Kct֛ʱﱻyٿ<IH8f˯X>}>DD 66g;(en oWWKKQTUio4ɺ/;ru` t VBa͕/D6lw~~ADF$66SY b;9}]lڴÇ0ӧɂ9ygk#*X$* !hJb7X #zm+ΊwC$$ӭEĉ]^_믛d" ƐC@@@ 2|J%So'OkpϽ+>>>BuCJJ-[qvvfذa/u ߦX,Ͽ\{,YɓuCsȥc(vÆ a]Ji"AKbtYQi;L}1 I΄"//m咔GDD'66^$1cDѽ{!tX)ZӇ"`jFjl4+f'ѿB0$&o@0£  9ΣVׇ0>e{xN`G&h/(L&ΙM|||ϟo߾9sшÇglڴiӧS矯[+y)[LnNm[xe/|Fz)$IPgŵo=c?NPP۷mJG#4̥3ٰKN>,Se%pI&LO\\,R0L 6/ʘW1*)J{{j~Wr.T}؟L5F85^TtA׮TJJJ&33Ik4Y( :uAxx_a0\fٳt 84 h48fw W팃#`V(D6lC 8ΘLF(픋7Lf<jrr.><3f$GDQ}["Exh2@\\\ms''@e=Ռ=ޯTZmGvv6$''_!߿Y"8r0z=믿puqwww$Iܹs$&$7_x+WұSGSرc;3f$%%f] <{;vֺ1oXҥٳU}vTۖ>ZU֭{$>>C]\ɴ(6!RZ*V1c [0Э>CAe\ {ҥKOBCT:PVhΟ?dP(СPX֤c&ߎJUP6~sBnvΜ9/j]vat (7bHF*JX,b4죨GX, ~~F'vF.kN 4Nz`4doE#I5z$IrΒ$cǰzW9 A6bcc⋍^_v$$ƌ'WqKk#%%&HKkTD(W^eÆȲ̻+V'3g\> &z 6VABDZZo91ZGŋ߰dɛFeĈaTw[jrZW_]Xeҥx9tH~J\\.0Qy2`@?x+_ hjڂ 5`sro+;wifϬHPt鉏?eezΞ#))cMGV  GB1LEeGqi)...l߾2J% "@vL E%Tʊxln:zFsw׺oŻaz?6w=zptQ!(_&eebb0xzc2ȸ @֨xV{R)1-HZNokӫW,(f VPXl,~uܐ$"ym&c޽L0;v4 &Nݻfff&Uؾ۷^E NPo>ƏF‚Cڵ+7p%%%|&!/_xxx{"h* @H{(JJJ() SLa޽zh&Ϛś˖ ?07MBbٓW_y=HHH 8w.J6Iqq!ǎdQ=c]~!M@ hk(/27n9sfq aն... ؟oJ*jM[T*mPEzzf]P(X,_riՂr,7yJ 222صk?0ov|ٹsg/lS 6@UA?͛``;ۍ&1/.~HXX7>h5'N1 %xxx郟_^^Q42 ΑJvvzNKKBPVѭ[IIqfY;Hv t`lʗe(-_ bZdj.OH #3${MC*mصv+/2g_\1UG-rTܿ?eo/O<Foחpif} 8qoa9ڃM!IkW$%%/M^dۯ=}b͚UX,~xf̝(}-[~aqݻeo^xY5kVp⡫irs?m6N[v@ hT?ZjjkU^1`@b?~,g&U~#+Ʈ8JT(_1tP>Zx6qrrB]wAVV/"~!wqYYYe'00?^xm썋d8lyT?pJ bŇh-SdZ3zcH@mzd'OCFֿdX/++C˥ < uk0[~;Y9,]8ᡦspRR,db!{P8(ppRtpFpƨ4Slg F3zwGL2$IFFɣΔ +udDdee1Y :OOliE.qR ZnP2^> BҖvh,.$MHHg"#qa{$v)W7{&LKtt 888$Y۾mvb֬eի?˓Koq\2C Cpp ÇY3(,,DPi3|6nʄ!IW_}FKHH0|;MvΝ; a̝;#{G}Ě5kصkW3y)O*DR9|aT_ի+»~D~~(*!;m319::R()M9r8ϧ"rEEX,f, fHYRR ),a0G,@nP}$' d*2`v~ {-@ERbm(u?kO>o6#$8O2~~x=<(K^_3fRVVVdff07v><wq;G9LzF~ql:udԨQ x ww;PX#%崽]Ҙ 1a~=ԥcN0eʍ[uڵYd!FdҤ Ϝ;f=sϽD^.]Dt1:ta޼s u< 6:u+~m!(_6l… Yo?B}qwwg֬Yy睼Kر*y+,*ߠ8^Mj_|/rT/QWE;+VD5؄@RpwwÓ}Ӄ^FT[`ۆ_yy/[n{ڵIL̙O>>F[x^xe[aÆTIQݏW_]Xeҥ֊Ae_|TMX{!ԂT+NMM#=='N养e۫Ns~iOHHWtb!'2m4} w! fTsڕ#e@p4pBE+ ki{<ݺu%==Ʉb"0;88`6מ6*Z,v..ҞKWAtbAi\ad@pt']Q!8z{ hdY&&8>:__zN,˘fzC ⥽oI@ DEp״iWek#Dڋd}h:0++Cc6O?mE!7WKn]ekN~rdq0 IDATJJJRФcPIOϠOtCHmELKpuumTAqq۴Cރ b&//nJ%-4M\CllF=dK@pU(({oQ=/O3v-Z@Noo5kI#e@f6B櫍FhHA+ ?^ܹ%00[c۶ǟE@RQ|С#\wDVX޽@Z}!L&3X}@&%%dVXFqq1.|piix8>eޮ."Zm8Bbk&?fDKg2#֯k왠9(--̙ٟ]{rI{$WI I,O~&++o_?/lg"!( 6ɵl9*T' NQQ1oWWW<<>^5~ѣ~z+;w/3gLn(3|:V7.aq!Oϓvyo~7Ǝ |-%;}:$U|~=_w<$>>>Ȳ={xm"JJJxyul ƏC'_7`XHIIgv!%匽]fBPIOdȐA:tAF ܱc(:]~!@vH!&7,BLQaaݘ={???VZCbJ%O?8]tŅ3fc&W{ZJy֮]߬6d[R1vhz9wJQQ1"Ҷk9q0{[H9w.n:.sYºw-?Y:)INn.ߺf[AVCjjݻ!44L]Pƍ_1g,na>>>\B( țo.Bgҷ= UgGjrBLnьӧŦM9|81},XY6OcD]S\\Lbf!A?JFF&aa݈gݺMW[ҷ0BCLBqWX,<#5j$}z߷awp1|rg6^_-] X ͚9F={())#00ܥK*6-7ȈY~{֭ :zs=mFbkϯjf 錫;%%EvI IR֓yٗ&/Ϛ*ZVg\\\X,Uu~i?r@birFIJ`G$ ԳȲl[j/BB8z4Y9>X,bcm`+XCT?՟+3jBBZB/%&toߡ(ʆ; P*zm#pM7SRZJP^^q!=) ?κ !((oIpoptpb"rEʦ( 8EEgdp>5u6o훠)HL`(x,>$UY, fs}z<,gM!E,Z=V1hT/d2V[-g3y1l[ګN^5Gsj$I`0K@H}qe;v޽V3`hbcRZZloZ<x۶o'9%?(((@ϟbܸ̙hy;w_3n8;;oĐ)**[B@s\2L!L&j5EEEDDD}6#yyȲZgoWiRhR7Jbr;GPCl=O 12F,W& XRnZJK:O8poo5e4 O{l6s!ԑde۵MII ӹl9,YY fwe(_]Ot k[h1 ٳqƲngle}9^~5~r?^e=R֭[6#f 77{"Mg,L,@ hV8ٲ,}O=5qqTVV҇7X^x>c櫟j5x<TJ/I7Tf8z$!+ t: bbѫW#+ *+]="km为+DDN=/בڪ}z9e2Tp \>ǝwގ3@qqPyxƏ?>g? @@z!,[о};̘1;wƊ7hf˯5mtbY_") C9u䲽J$:'D-T,Kwu7C~DŞ=;aaVԩc8{d'件#DDdIYP2;b\CeO@Z+emB$f˱Zm!5}nY^^||h>yyϵƾ}m뮉AemjJGb`L,TR:wp ؿ?]={GddW?~EWwy{ */f#rrN;DDN0PJNd?!FJtkɝ0.!0TH :ue#pؑKGPUO@ff+t:hZt(wǐ!iC 믿mNZyh4b֬0|0lٲ=F Z< InY"*fn常(.!;p6j z-1}&먓[pvDQGhn\z3A"44W3Eo^& "˱oΞ=.Dk];aLDnOe!11}0lP?O=5sSsNaP#gd5[DD$Iu'߃7`߾ɓ'a!I2ϺBeɎ@]|\,4EcNN.rrrmoxп?={;MCVAV9: bY'S,l98}QKQVVd)ju;Ɔgd…S0N;_%ecDV*>xwRwPXvDDվ)!l4ȲCx)PU(-- *;wf٦.Ou=pЖ*3̱(Q;Nr:u3#)i lú /jc\?BR rKD܊ؿkhDFvEޱk ."7 4\U !Ca:ΌÈ^i C룏`wf| G`` Z-QH={CDDȲC8q"DQe%a2-z@) 7@XX(l*hy@ =kBc]+rD.矟YBQQ:tDbN=z:tL2߅z=vJ4/luV۷ɓ'p\j0ml ATd29V؇ر;:vwDva6PP\hpHs8qa6pul}UGc؆:!tZaᇟX!ЦvLrB}N 2PXGa0BD9v eUx>8'ǚ54s/e"r{9995?˜999ヌힷu6lݺuO2r޴)VWXm| ̿~4Dј6aM!z?tjZOgLcǮۀ2 kP\l@iiqSԟq-EQ$IhDyclWI<#bP#H<}QQQ' YJļyO;v$B;/|?A$a%BTC Zm$3.^<3H&"V~//f $$CZY6e"˞=)س'YۼaZ-^o xq㍣?DD-_ii23"3 ڶ FXX{EB E׮Q% CdD2TT娪d;eF@?*|cG":tDDD86oނ_~ޜO臑}P## CC80OZ~8l.zl6cϞ}9r8DQ5tCJJ*m m[??" -^^ r;/ 74 rZDD͡66A⑒h 0%(" 3g 1P&fc5Ɓ-yNַ/[W??|Z"ԩL`BB R!((mۆ ((hpfDl$ly=j [֌9~?eP#p_\nh QRb=mԩSѮ] ڵKkn}Ѧ1c E(Bhv ^jWWWzt5(-- {źu̙0vPTXCޘxչ/ڬ "j5f3z~@@hYK醁6(5EtL_ƳYʍ/0Z0˗|]IB{o~~4jvBBBQ(Wl#-^^^AuuӞSj#ͻy/-fHj3QddBuuեU@YY K8ԩ3xP 0LBII)*++mm衇ǰa  U^ıcp,]Zmڴ,Xd9!f̘ޖm/^rΝ;&YѩHMMJD\\,-[׈<e"r*{䁴t\r L 9O믿ř3gDDKeׄ|M1uQ5$\ Bl?0vf/wf׌¾E۶(--֭ .^̃l,Kź7,mf9N^IPX)3v7r/)i/6mͿPifYFOs"1t̞ f3N}ߊkK#G^2A@GFZ׎ EQQe!p"Pgδ3/nz5?vi&jU̝4waǎW%""jlᄑǭqkar}1FVCjj:&OdU8q<~Kt _QQ~c?`َ?^oOjrhBUU%ڵ3˲gdd`!c`w3båmQQ=pyըO^xe?xb&meӯ?e"r&TNnkTBr LgĞ=)%"j(e( 0ٺ veuη+/F®cxj2h:_?vBݛo P0aԨXd!6#"`܇-)]D^| / PPA߾u tjxڴ)/Q]]eS!n{۷ҥˡbԨ0VXgcLDnagv_K`|% Å><ݺuAh 2O>&""X_>Y=,39Wv bwfMYyy%~}!00jM(+ /v]9AP XjO"jhO!3ɲ?!!!<r߱qwعs7FE`0@VCj6l(q!sxlڴn{Νsy;YOe"r g:P^6ؾ=Qq_ >Zbx4$e-XQ7ZFDD/9{_#!*O\|0}#ظ;F̟]v$IO9|( K+ヲ2B~ _U&-LT25Xqc])v.T[`Zw~NJmar]}1ј6m  jRZ& WVP$&®]())m4VښBC [o[Yr([ڕe-WwBiN>nP:ϩ &ADdYѣ;f̘VPdgt3gN,))w,k?ڵ߳'iP*CP^^2Kdc=ZTTTحw1 @͈g???[ʷn݆[/>}sk+CT2ٖnuXmADDDDDPT7Rw{~w1y$̟2AS7R///s ш2Ʉ&U\\z)1'DDtU&e,#$$퐚Y~aaPU+ fGAAA0s]Im-G([i/ex[WsDDDBmT*QTT lٯT ""^^x'q/II{]ujCdbLD.>.b?(.ga;/EDҜN?-z DDD6hC YPP={O<1r 9(Q;{ϩm 8.~>ᾮd`LDD-pBR#$$^^ A@HH0 "tztzW@;wAAmѦjk[zL(Q 1y;9~w@5~Za89)BDDd "aРx">~4Bh:! aa(,Ԣoˇh؎pvG&{Dt^2LnY\""VvE:|l$oˀܴϜkBdqDDrX[%fΜcoJBX~gQPZdu'p}`@ar$07""7%>O|nY}F~ Fc;M* BNs-J^odݻiiжm t:=dY:Նy(S4 {Ə{:[&DDOʂ @R(`Q!Bj0"u *˫QYQmsL:jJ*k]A,E`%2c^XtQ,Ce""r!$I(,-3vj׸ =e"r+qշګ ;;>O@ko荩ތ zDvQe?bcXAlzvm L9I()*GXD0v|+eC @.jllZuXÐe/>1s3zuAa^"# `ߍ^Ľ׽FoLgLDD.b?:x5~dO@݁t{a2y̜?O]4%›f!%1 |7ğn8[IԒ[g6 o}5 I#9='w>ۍwNAu ~>GbȗnAReK9Sp2Ce""jf Q,qU 2r7DDԼԬpה}>ވFoG1kmPXmFkjWA]O hQ@tN@y\h덪JUەոpZe=_ ׀C{O!;MR?& WwEcLD?Q#^zV"tH,Tm_20z|& #lg1ߎ"RdK2"`)s;+]~  $ti.eIyߞjn8cLD.q(e' $9}Na///P 2gEDDM[>źR) GUE5Dx|0hPU^S>^ER(`ݞ(e% NSb9'c)d;uDzDLEq9gLDDkru/Z6NyA #Y$I3!I5+o7`֬G`.{N޽p?vtt~ "<< ˼b3 6ȱjG΂o#?G6Px)?d:o/3^~ϡ2A.X..XQMXzaB6~>XGK F(7VCuU ȥ:RCRG?(Ce@]|\,z6V#6vHpK@( ѣ23C兠;u?Cr^ SOϽb3q "G]?ab&TA0UP/*5u l{F' e}Cd"0qڸ7%ooa{W@Y^SbӷZ/]N2L&""s/XV:]zԲlNq =Q;j//c]px{{c^}etxѢO^HH= ޽!?q'Vz?^}9"#ٴVбc۷80^)jL5k7%rmr !ȶu6ed@_ҫ:a2%n aaP(VS)ڻNjxn&w6'wˆ^u9ge"Ƹq 0070 =y{q㍣yOHK;0?bc㩧lСCC`V* E0jaVa6-h q "ǝ*dLDD-,rG1cZ-BCC{k}o9W۫-mNjG*;{%w@<$ؽ{]y7)Pg'={9{!e˜mh}No+]pf_1TwM6y=X~;6l9FաSNe@VKΖrZ<={8z4Gf…\u^!CCQPAAAe˚v[Ս^(Jd2CeH2hߟ2C-rNe^:G(5|󎏋E~Ÿ8NƯfwM?gѣ`4V#7߶c)۱v8pz获Z\cX6~Gxøq 4TU޴reT"֧[ήGJ5)#GLJ~ܼ#r!D41/SLcG}(,^/=m56nj %%Fvq̘1jh:L&9SE&&WwcN//)CBa0YӧdYFffD29Ekk4m1((4?],PQSCrs0hP^ #0P&"@G} Z:u=*z&R^YY3<6,j‹8v,KCաM6eK,G~~>A%ŋܪs`IV}t*RSӠR)eV\ Ctɕk'"""""""" Xm$P lSv ےb#''jaӦœ9cqps"C^=`޼8y4Ə#GMD\꼫PaKȩ(QuX]OǭC5ylDDDDDDKu[]yqzS̐$hBUU%ڵ3˲gdd`!c`w3båmQQ=pyՖUj|e?xb&m S^Q;>>(++,אdܗekDj:D2*wtR S^'_#)+SAAA(++\38&&/Ck /:um0ml dxחcٲ 0VݻF[{] e"r;I @ȾT*%t:^?Z$IW#<7LfL2}Dcڴ)(,"(-JJJj՛d( ^Z-B v RX jjO~w_>]e"jvqӯSH:rjr]0ܣGw̘1 Zx5>A0eBax>hk~k?ٿgO RSӠTe2Ʉ{j %[wqq c~~~˷oݺ [n;_`);} ̙״ pz;I'Z{u~5ƺDDDDDD%Iu#u'Oo}'O/{7O?.}pjB~6}چ*tu6P6A⑒h P\\YN:`([rq = e"jvq߃:~!?=|!y79(օ}3aRzE0hP/ZO =e"r+B~6 m*=m|phMY2zGzW]GJQV‘DDDDDD -9v<TJL&IV^ ??_`($IV;ɞ2 !?Tm IW_GVxmPܾK~>qゔXaPGᛵ5VHBݲ*TVV-?pacLDnAFO#E,AUF˨auDJ*PUilِ )`6!C @eպ8r,{yTamOHW'NDDDDDDe?:8a =e"jlt ?\S0t{Ca聳PŚW xջqMHU@WdX`Ŝ dGaz ARWYj)&e"jvqC!ػIs&ۙ7a=d<?vM%A2KQߞ_o!9ƒohX""""""jY:RCRG?,cLDF7óՈ(F7UFƵknk' =a7ŻFK!q m\E<7UXx79B0eaRVnc7n]-xr)e"r_]&?w zCDDDDDuEE0̖zJe4BrlNR)(qO*3HvDDtUbѹsg5RgDDDDD `Y#G?bTJft1P&"8r0\qߊ\03T&""""I4ONGHH0%` E0xܹ#$IBXX(nu\"w&  G4PRR"t]h4L$h4E1@嶲,+Kʫ3TZZî댓u>V7co9؎P U:Hp)/z~ P5^xE; ҥЦMȲ%K#?? `ƌ鈉KQ^^nUܹs0x@q$>:iPŲe+*'|sɲPәuL{k}݉EM$ja6fjQUUesNV7۬;ɵ_Xôi0g=i>;@СעGk0{37oN>@r,[z&܊{[ڨko_[+aLDNS*gaLDDDty(BKxؾ2x0°;) ]%HeQ!I~???PH]Gu CPP[̛ L&3L>}1mj%%XM2 V~ ZaaHL܅]vQRRlhhZ5'ֻگkou_ ȩ.ǹB{|||pZŸ;vOÇTs>%$PTt&\s]2dT*%,YѣGb[ЦVx)&`ڏv6IAjjRf2cCVv...wLP3yy[amc2 ,eO9)DDDDDDD-(P?ǩBZ{BK/"! hZ_A "OZHlRRRhR\gwy;-Z^Zc喱VHRGFhZ&  㩧mr۞S\3DDDDDDD$\aw\} {0,!vؿw>h-Æ_ي} Ri97m[߻oZ?[ƎJ^CDӏ㮻,?C$؎ŋb]H޵R>vVly v'_E?O?$݃Wn/[~u׷IQK#˲e;~$t:~bpih:Ȳݻ`Р8c\Im-e"""""""Mؓ{vC_|?o&6m7X|96~-ln߾=^ ,_dzg0r|x|lz}YƢgϞ5s&yYRWݰE(2a_FƬY3ڌŊ+q178e#r˅U*%t:NCHH2oXC~ٶ UUUejL."/Qp9(9R~w,];dHM,Ԝŗò%7& eːmj6#M uMf3ԌJY,KJK{"O> RP̗&D--ӧJh: ;wam& r ܽ0LP*Hܵ ӫ*5QX,#x{V ؿ͹0@v\dO9.'f|7#-- шE/-FYY>;wNlsտbJڵwuyMT*Xӑ/.Dii)dɀ$IӘE?/9˪˵E5E=x睕ǓO;ffl( (//ƍbѧO4~iչ3LLLDDDDDDԌnﶉw;{,ɵ ((:漁x'`h4Hd)w܉j3))(--uz{^7b􁟟/ q&D&PwCy }` Z_YjHܹY$jRWYj)vsdcLDDDDDD@Gz&ӮQ@ȑ801DDDDDDDn cnee#1Ѧ<$$B)ľѻW/t!77K*6]OWe@᥅ qB@SǎxiB$ك}[n?'M‚ (IHJIЛg =e""""""VHEI닀h Ԍ86())Gڪ2e6u_~e_'BȲHʊZ tQ˲9#%0Td Hh9<.lg9~~Q^Q'O "00]rr0λW^~F@uu5[m!&O3i,\-?,χ(I2w]ssr'Ltu郥˖Ao0B|\ F#M Basm݆Q#GØ\o='jdYl&݁^[kEϞ-EQ3;ćmuN͝mNzvu7#F{*DDDDDDD-ܸ[oAHܱ;~fU᫯_ϰǟpx{CTl:$%'O>u j%$Il))Xh).^̳o2iOXh97wg J?wR $"ibPQdEQAE*.]uQEW.*"Z@zT 2 Ld_Y2{5ABDDDDDD۷o??^,><>][k|؈?q}3 Ҳ2} g / /H#i£fYs}I"-e*;'Cir׵i}x"""""""""k'qChݺ5wuvo~0Ld爍_?MGcmڴn]k߀ZjEzzzmiZǫҞ EDDDDDD\I+E58|˱>>{sk9f?lSO=NffXsHMM0 nu}&77jmϚuC 濲~FB4h O?q\ |""""""".dqL7Ϭxf'W;q}pu6&N0>Lz?q5*;aҿl޼*LGC&ouK"""""""""rM:U>{eeXa@.Qܹ Îamۘ4*>l>!!\r_3=7Zڃ{(++3}ӧHVV6>>t؁9s^`׮[<eC۶X Kv9> ~AZnMII O>F>JKKj9l֮ڷoSO!==sύfq<e96 EDDDDDD\$q.]݅WFKILpI;"6g!lc,z."bVˣ>DNNmڴqh>ᔔykyYpQݛDzzc4)Pq^m\֮&*{eĻl~Ҋ]Ҏs 1}ߟʌ7 (++㡇K8ڶ0jT4:gΜl6̙3<T^^ٲ,LSYc@YDDDDDDąGlz<&*24EuLp0d@PP+ˁXVV6 eY, ^~5||hݺ5~9s?~k֬sQϺUSh(J*c&Qq̪ĚeY+ìsVպ}polˈ{oluh<N}n"MQ]i8j 44#mt }YrR^ngЧO/OLXl6^{%233gլ^ `lLb^zJUXG U͜[1 awpX|1o%?˦̀yK_Γ5̗Čx=N4lqt 6/f3+ʽLCJb&scHScYٯJ BXX(g?KLL{biGzz/*EEGe޼2ok_ /ps-M0rs(**<&LTx'%%Y??sb0?~5_'f۾:Þ*SkNr;S}b\=#yPx&Ҕ8_v=KȬYwW|9t,33G} _۠>HKKԴcn+77٠q "③=i!HTuG p:Ja~ amHMfʗ<7z(CI mqt 9ɖuhU5`n"ME-/bc,;p 4jm]6>'Fx(zjs煤166]u*H-VZ{`gq=. f~gt}[&LiiQ8*qt 2.ujmD>#UʈØ3EM۸N;苈4SQQQvZxX!;T'Z /"""G5{qF]<^*f2dgߎnyD*n}_{wGPrBYDTLà⃷i=,fo=ӀcwVrcWT;dɕm{SZxLyV9v,si èyU+fμ_?\9aT1g,-e(M=xlhfKBedQVrޥhwJw;ysUi|/+ΨvNcO +9dOvi9~9&` EEص+CPq&HUW&W"O%65^m*gse.=KarK@YDZ{ҌmټCfbWZj*ar%+TvƸ{"jĩ]X+ E(۶ow׷˴:YDDD:Bq0Bn;.iKUR{a@YDDDDDDą\HӢ@YDZWdKר(wADD(PqEADD<eE߾}h߮A2;wnw=V'xĵ?ZvPq"<= f1ۇbO~~>ڵc\yD6oK:ˤflQq IHLdLt5!!!,[=oCDDDDU]lLvၔ9W "`%e,l-?3`/caajz& {xEw|ff4s{Iq@YD<'`h l߾_{8K e Wr٨<+ruvd֯s…'4___).*"3+yˋ1c.+VP""""""'K=8N]#-&4eXG@s^HqA~ɺqq8,=z+&~'337sIL >3[nn3quv7.‚ܜ4.v`n{þ}_ a(sT~ܪc4a~60혦aՔz!d+wmNnSS z{r+yd@sg&M<״حiٸy3degsk'=#z0lĺ7ësrusϲ+Ch&! EDZʬclܴAm 6>8j]AjZq?*zI, 4FUXIܻ i>(43K&\~9$![V^d|ɧ4ybS(}4Z,""""q "jMMV&Wzn.ο|0,ſV "7 e䳵`T(3ܧϼ?]G!'3r^F 6A*&+-Weʕ5P^f f;*Vgi(H⢛yg&)I9B|?[_m`Yb:ŞCA+<5$Mkk%xzq0mqX0qHB#yuDzpYa/9 _/:u|Ȏ{|yEhD %e̚6=Dv >cז$ՋcC2ۘ6_)")$#-6my/"""""""͓eiQ\'{e&1e`eI9t xb1\>lZqY`~ se'zWū jfP{GZ lJeYt܆w{%gs價↑l۰ Ȏ}˔Ѧmg]-HFj.#FW2} 8âb/b9,xlae/"""""""Sws V=[R46ebλd .EX]XVJK'TҒ+JD`gٺ1pjS۞LFj^οSB nUo bͲ?_t1/"""""""͏V(6hˋN!>$$SЁj[^`O_mOoe˚ r0 &?ΟL1èXY]圚T)7 2ci3}UªuA^ɦi8|}r-m2ooqh/"""""""͓V(GkmSi@P i|Ty`o};>~'24`݌^ YfTiǑʩzfUb&ѳOG"ap}HٗEa^YԽ-^^&gP KҪ^^&cZ#"""""""RA+EDM7d&5̗au֩\++~6u>}m5gtNj}ه؊ŕR e 5PmtNF>]ʁYD>4 Ʀ^]xOpaU }uՅw[Ė5D2r\5<}v#==3uf>>>pxjʻ3M3@˲B Kl'q*"MWS8/( vV CEEEѳghcUW'@b\޷WF<"4"|'FHXYyVwRR\Ja~Ͽj0oη=ԓ*>Eq0l0GP]ZXXXffY@@HHHo߾#^DV!7/|7κms,¿/6mxX0kHNFsղa`U6m&C>~ބ&`y{`z/oadPZ\GSرaipX,l-  Rq߇쌼:k>7^^ò(edm#(4jk[DDDDDWe|<|O^ODSBQ,"fZ,B|pXs8KQJ q8ٝ9:Vs(+8VkpǓW|0wzי!e_6:᭧w2at/ (4 p~\syKHMd0筤KHm<4,=FKnz>yc#O{2x8m@'B#yKbz}^z+,⩷o"3 ڏ=qi^rKew[誡|լ[@еOd^l-=/+ۊEaa w\*dޒ{іݱզܡK8>^<9FcR8c䩼b}sxwUٓgK_nwp~Lu1w[DDDDDܦ9m.kc EDN6²,C:un3t&N;/}"z%Ҧ5g^9c٢W̮]'O֐r8WM6Oc]w' cXa2+lw{h}vEtAԆ7ǫ]x(/mҕXOv{ӈhR+PL"smS.'7CË^;׼EDDDDĵ</Gx/AjۓCRN2(HvnyQ^j` acyb3?xۻ8재n+޸4ƥ?hPV| ʳ$35ir0+~O;L9i,d {h<))-&aLo0SߓY,7Lp]ʾt.%[4 uCSypiζ geYxLJ)H9Ha^ŵLܕBH8rv_\4IKvM-ty{ڕ!֢6 @YD=I:tSΡ>NsO:;7!/ Ft<@YIm" c_b:s03Ө`M4*V֕9u$u|g%sޟ?E$"ڇӀحIY_mgol {cS?XȀYoOVz^O c)/-SpaT0`gF ض.远Οe Ż*VW96{|ŊSBIݟٿ;2gݚVԻ.ͧP 8EDDDDĽ!H3esUehm4HdvIk/]|kBf>?Qnwʇ0 W`9Y@Ǯ,f;v}bލ90 ٺJJ+|gi{y7?_?ol^6y?Y_9K:~Ѝ! ~sLa7SVZν_g~垧"1&oo{ҜL<ޜë?}}t-/|7Zm]"UW*-.ge7EDz/|vm;`L>\ ;7a~U =O?׿} Ffݼ7G߶=i{2NnC{G۷F^^ѭ[7#==ûUVeee>ieZWXue;>Siڟs~A;o0***=Bj|?HIس}1t(W iyhZӪy|lPȆ &ujǃZEfj.mϧιMph%%e| # l&mSHQA1a%lO-j8EDDDDnQQQve@ eMunyQ5PNI)g޽'sh'Utteadp8 boo24GBBhEDDX}yZBYD<ъ<zFY^p"kkan1G,wj}jBSުw^๾qQZT֠)+)'3࡭1aSc\~_h:(Pt_SMWۺC^fg]|5oyu,"""""""Re"OeWjq̶+""""""E߾}h߮A2;wnw=V'8"q{qh&ծW/n5*: {l3}PT\ϯ?Mv Xu_>䠠 .)~14X,[@Bzv. zP!1fx>E&7b= 0ؘX {]籪9, rMf'ֹ5?,_ɓ&͢E89pQl65~c߾} N EEqw[v"""""rd޺o>ylٺ6?P뜯WR\j_hnx\\<ˢg슉߰0̤yϟ%1q7'L :fμoNҒ\<e4LW7+Vþ9hNo~gd.DDDDDK3)_vHNN0 zD=?(G1EK~ $$M$&,RSRбbc粟|e(++wܓGt9 uk{+&J'p}lw`zUEhJW7/Ҭ9 KEU{9W0YDDDDĸ}c $/?i1wf2=Jݵ^lW﹏ݚƸyDaYGګz7ټe %%t\B|ẆaС}Xqs&99޽OVs83IJJ[or|̮¿i@YD􉈈HSsL vBBB ԞXv/^„/ѣ~ YޱcG:uM7NZUD4mFpe69'Vtt47oƂ#^lt gdp8x_UMXwqxusNNQ`pXDDDDDDDDRzah߾=Kuii8cnT9|,,h8ų|r^vqwADDDDDDD%.x|[_֫?FwY\\kp2v,|ǎ;z$'' x5IaS,""""""""r,_.2Ϫիg Lz_,\HSOeȳо=);vtE(˱lr)dggለnyVbph&M{y9}˫"7bzpiÊm.<:lZ'-P禿ĒŋIHHpbƂ_sǎ:ر#]w==,vˎϹ瞇i|V^ЩzVZ$))xCi֊Xh/Gf ,|O&!1Q!49s|чL<;:s5q>l#z(^ 2mͱK'΂_xb}q ֠iӆ{A0j(RR0&HkI! &6+Vh]+W&>!E]Ʀk:'e)S3W;Jzz:?9C%S_~>>>\}̘>-Vcmo~|wl8U+9Xvm5P\R̚5kH3eTmʆ ѣ'g<ց[ ~Q^^w.K/U0n%О}II|הɘ1իٴi#~z;v,Y|`L8UV/&M? H=|2u*?|=}cu1^^|˲8ׯ,Z nˆ΢sTgVZɶmetБk{EDDDDDDDDN 5k%,,"i{,:d(R8p Vk?='^I>}936L~zt51} ӯ_?Zn^=jINNg0|Fu{q;YYl^u_ߟO?!CFTΔӭ[7>|>[SO?WOcSxǹIIMa|'l6Nߟklѣ7jFFFbb۹<9)Ή&5%˲xGz rj^|g8[o#<<<.o6dff^fРA^oiT\MS֛瓝͔Siֆnݻsw~:^{nXYW|>>eq-7zСᆱ?Ѻujg?nݺ1!UQQQՏp~Ǎ#''[_OO>W+ux-ϯh#((g͢΢E=O?W^ys_p0~xjmoٲM7Q^^^mL/*6]tQtCiv*CemK <5Pn߾1M.Qq#ݻuktkn{Nhh(IIIsZ&^Νٴyyyy3r9[~7?4mڄ8W:/_ &`I]RbaÆЩS' Ćv" ؿ/ޱɖ-[ r̘ưzժ __zTcw^bc= 9nCy!7dffΝ;xЖ&NdȐLm˻wfʔ,ڵ_"!!"-Q^Ӻs'$??0} =VO9~{uD<#ۍt#//֭n LݪU+ﲲ24˲- x` %//׹___p0 .kkn Vh޴zm\JP^mꭴܷw}M1PQ@v~ #idݟzss?nS>'jղ^b[BsΏ)(jFFSgRT&OOOkaa%00kt@[&Ml%jT eBZZj& t[o5Fvv-71󝶥^ۓl&%%b_?FN9\-BX^RѸqc}1vKsjvqB!B!?^{*{ RO􄲨XB\mo=B!B!wJ*Q~O/d# 忹ӧyNۆ{F!B!Y%T?НTNU B!B!,V~({V E`ڷq`}6UvXm6j|ou]( :_Z_i;qU} pC~L?ON( !B!B4?|Nj)jxּ~?wcؾ()I%ߗծ[cjgh|<-ޮRv.*|>Ϫ2S9/ ^'R~nOw I( !B!B4 IӒi@=}[%㗁Uo3$%@qg5[Cԯʴy>>/i9 ( *zsRP7d}6>~Mr FTjVR翛ѻwr:m:ZMfffe/o]KHLLh4گgh'))"*B!Bk(ۀ-+`V;jqu!lD+Lrg3{11qs!+=.cA;1gzlc^yW7j 8}4/uޖ(,09t kӯ:v@C싌ˋW_{f͛3dP~;y#Gɣ>J``"##9xCtڍMڵSb-˥Kl޼EgϞ4hؐs_ժtE ߿ǏFhh&#=._w77|M4CXmV6_˗hڴ)f___ZnMJJ kVa-ZcС2:{> |~;yҡ=ФiS~?s'ȑ#싌t_!B!o* PXyỎf( r85JubUndEl\gRsMsٰPT+YRmnnަѨQk.cI-_W3gn|]2 *y!GPFv!ߘO^^}<)S5`B\]~h&Lx; D`` ̧3foݍ-As 3#O>A޽cMf6m:?^:B^^& WWW/XHPPM.^x8>C,g'Mbsq% 6d%S,^ cciذ!Z>#ryBB4i}Ç \9 F6m VZNG:u7ib֟ΘANn.j~^ƍWq%)޽z3%]PXm6 Ž^f͘`& ;;砠&Ӧ1hB!B!yTʵK9b*?|/nS^*N@ǞMQ)B. mu];yk9OAVF=t)WU ..*T jr;KGZኋ^:YwUGgnuI&-*rDDefbbbx7x͑8q:cvEaoٷoaa,?͛7ԯ߀cǎsNfT Ά Jラ!!!i݆}:x///-] c}@Vf*k֬OJL,1.((>tԑ|f͚??Ǻٽ{111/ԨQ^zөc ٶm3ԨQK.iF,=VX xcHƎC(,,䥗_W_-zfL.b ~}1<ʕ+n*n!COk6lHWB!BwӺ[rhW)'~{_ogҷӤ=h\]r)jDqu8abcNIg0|$^L'^JQsgjf|>h_y|N?GzU[F~Ee>’ɢ|UxBFZ5k2VOqI <}E롵EuJ̩Vyv:v숋 6:I:4hЀ-[~F(\|z,u%..ΞL8uuu藟τ 79sٳfs17h;Vq_%0ロKlٺE?/b޼y3e 4~ǺukƺD׭7=sٳ l<<OT;s3qծ]uk?=c=$$$H2Y!B!]>(q F>@i9*qX]ᙎ;9v̶߻[Dl/o#Zw_?OS l6{7Q`,$/amaXW.OA*{չu$O(L&V+>4)))Nfʼngg/)'77D_e˖| nj)5^7ĉF//k,wul޴^zW_ʈW(0IHH w/x5jժ7>s&*OuL.ժUc91& łTōk2Mϛ[,??Yؿ.k-Z,QY!B!Lq6+5 ;fbp:VZn{#!. o_BkO!%&XdQ.{es۵ZCV9Fp,y!m0ba0JE'XӭG&#,~=M,fB!BQ*oe\'Y3oo+YbRX_%*9K-Ͽ{Xl߾ ( 믿#Xrk׮e9|,YTYf5͜ٸ^{Sޏyqaq^^^,[t*Ylܰ1^}Ne1j:Y~ۗ+IIV O>OgNǨѣJ&錙+ǎ37cgqfؼi ll,ԩ)!B!BTߓ;/^E仒ӄ}xxr)%%%E1 JHHruuU檬VCc2\wJit6MDZWWWh4Z&Ιˊˉغ%IKKsZB# Kj5~~~ 9%6NR(T(QPP@NN6 Mݵt^;OŅ%//2ݪl29Ԙ.Vڞ*truc !B!G}y׽CKU/$ǏQJE\xܹcd(bZQT*ZXXh t:-00֤I[xxx_"]CEQ(,,Äl.f3@jjgRfYVcJSԖZј4} زf㖵,B!B߰vw;R򔖚J~^駇B!B!-+{BXUğpW'~{le/A!B!BTU+{ |ғ ?]PB!B!V-t'&ʒLs$,B!B!Ҭ%jա]Ra^_or F yl6;scL5C¹ WQŘo"+=Dgg p\YR! e!B!BVtusa j?\޾d#Rd ]xt\>'y95?|ՆdEh _l)1;a{&7w xԤ,xo%r<2CNpg_ȭ9{2[݃'1_B lVJae..jޛ=rfm`?7ᤲN$,B!B!ҊO(__ A+6.c3rEIbWw .lʎJW{_%K̙ޞT*:2Ss짖6dJz]>|r F¿:CBZq\4judRh4״&ġVq>?O & ኻ֕T**Qd[ٳ$W6&ųv%YkGx{p};SGJ\YU;mw,/ k?fXkXj%QO;3<b鶛׽{wvJb ٳn)ZMhh(?ZΝe%$''<7 z̝;B)OcƎe߿"B!BR:-Vboicn1DXtaU{'ٿ-jok^^ӛKԨϷ]ǾmQ<1A{{jcp]0zhC9sC2ѯ_??4L}ww-Swˁezj,X0Lw+Vdȳ:$[$%&VX/2+{B!B!F6ѧ.s4?nˉ˖G0d]l?B^NU$^LcNObwf f}bޓ(Ul1w[pBz<ފ#7G_[@왢Z_{кc}Zuϋb {;/tVY&r=kcg&!G;TI(2Ӧ8ӓ²KKiӶ-kfŊ帺2ζv14iʦM9rwQFPիM6a4돈 77oËÇ@f͉W^z*o_tԉ VY!ߟ[իz=;wxpuuiӦf|}}iպ5)))YuX>Mfrrs8w~ vd˗Q={ҠaCbŲ~:{Fѵk7\\\:mh4Nh\]qwsWjU~'>>>ٳcǎ@MOnݰYmRRR&B!B͆fc Hv!tՌ~wGfy{ƄҩgS=4gւ\MO_g{?Ww 5js\2vN>-ظ 87w>̮ 'ط-uou7{R]xyk^˟Ԓ/ǻ^ՔlmutŁgZ\0` AA5y3,j֬Ÿ"B!BR̅xh*Eӹx6cٰ =B?a|pR*Y9DF_GDZR*EalO꒛m$6*|8g M3c0}yhR^9Y;{F=5d\]]P) }>_[Abl6.jU=&eEY= _/ܵuT*&۟u'<2]ܢJn뺑$Gfrrr`СR.o9Ç_vo>V\e˰lҋ\\~- ䷓ZoooymrssYt)k׮s.l߾xɉ'h>x;vlGQ| wAki)T&N|ߒլYnݺөcYl7mrA5X|֯vF zM(,,d۶mDSJJVVVqn°a,Z3_UZrPQ]Vh.LŊn*!s2dpB*: Q)s2Jaa2W{l/o-cDNV-څxhIO)mT1@{k(Ek3h1=)ۡt݌3pqQӡGcuVz'+:]Sϕ./b.0ߢqg:'| W_"@o"MebRyPp?7y7~O Ƴ/217`I;=;}t%b/+Wko:E:jԬY}l/!Hj}c+KaN]fsipLyXn-4ݝU8Hdd$[Y~=7oof4΍֭M=(|}}p]=9߻B!B!NŧbfMYØO%9wW>CX,d_q{fE蓗uoW(n7*8qW2r97w j5o>n06=NcO=CV>5j3cRTy{>ELfF Ś~|tgز0//v֢pTY|?xyky"7*q&\hbδuL"IV哱>]2*5|QU,3q|~Z&bSzqfO} +Xp>[R:9\~RN9g}KC=ƙ;wø#^^^Zm 1ԾB!BqR]W5)>7'$\HONFS>~h0~m+ɊNEܙ͡]g⍹LVFC _Ovr‚B1On.]jR;Y1w}M'8 nxd orr7|0^M:旺s`i^femKfmc;!3T}sLP.M5h4E Qx8xExu■7#;;5CBHJJ*s̙(80_=zDߥKвE ~vڼ(|ڵVZ_Øf瞳jgWDE@ӦM_ӾzÇ4ǎח.]FVcf_c6R87ڱ}O<񄽖9?w!B!B9q!#i[^ԄL,& #9CfΝ!l}aO1\Ғf+3vaԽẹ0t[{3IKB9]6ԄL ozw",WPn۶ nj%-- N3~8׏6m20D)>#ƕ|oQjj*?Ob1d 7Yx߅ 2d(cƾMjU';>m۷c0O &99\֘Ä zl0dguӾ~: u:FјkS2zj5 ,-7gSILLD׳eJĹѼy?R^]6oJNNyyUB!B!8+,;+$#p׬lw!/= WN:(A QRRRT\jxxxhL&+RΝ˪!J# 忈ӧyR B!Bg;9,PB!B!插'4񎲿;I( !B!BJGn6w+IŠ+=[!B!BG*"IXQϊw4FFjm:__;"!B!BNӓ *<\J^{T<3wd 7띶 <7F#(o|'_~jժV$B!BN O(k4g)Vc ~)ܵ5ѣ wԴ4"n8mڶ%((V$B!B)(}ŋoy?Y/## xhּ9C巓'9rгgO4lHX֯_js.hc{7;qx\\;~O<@غe O<EiFpww[nԭ[,V^Evv6mڶo߾ج6RRSX0>-ZЩS'&3۷o#::OOO<Z;vr)Ztڕ[;6m׫W;q!EFR^=BCزe=Fvl:x9  CR~z.^ а0|}}͛7CFڵ...Dbmf͍>ԬYټy{dDlJ^AςB!B!'~1_EI_4$ ?Eh4X,0LODG󄆅2id a9{M:_.]Err2O`EeeԪU f͚ӢEK.аaCz>ި.J7|63X-Vĉ ML&~7{[nڵ+ <ƍoo0pfM}O~Ѻ;.02Q,^ cciذ!Z /"99ĤDZnj%(&/Pt|%lْߟiӧ2a»sT*ugkNΝ"!B!Bm]xs粜Uv,ユյJ2ϫ+WCxyylR%vzSm6"gGөQ.]bƍX,{cs |0u=FHHmZa_d$W,_&Mů0gi/… yTQ矣ٽ{111/4lؐ<"">dff2qf ;vADGG( sݻwxΞB!B!T2/sGʥߠZ~@n.&eVya4旈QZ?^ϿZ⭷t{ ٨3Qt FСC^6ZK$ժUɓNt9׆l<<<{m4222 "&7g cǎh b ,Y_de<ȣ^ĚJ{ 4C[B IDAT$:O~~>&g7pfϚLj$"b+֯g-|lWQQ 8Cze?bΞ-ܨ~F :ĕ+^B{r^!B!oIe!*$oO& FiFZ[|g}233nBAACGVeޏ9r${Ar1k*,,fj-nZ1Ւ/ҲeKFc޵{wh(C<{ϠhYnm1׭cM՛/WF±cGlL;}Y.]pg4R=OOO233o(iIMI… 7G!B!w?I W5g4o|q|}}ҵOџ6zl {x_VVX^qpPыz!1i69x PӸ4۷(z^Nn/_N:;~ ;XV-[ʨcwd-عקR]Clf_~輽QטM;wЭ{wh֬UURNlCv6;{˗/?׾B!B!B5ʿ+1+WvZΝkS2zj5 ,O? ˕$';jK_>^^^=z||}Xj5:ǎr , ;vdx?ħ3frbÆ y'PT̛#?ƍ|;g.睷btR> wPq˗-cĈWxj~{s[#"HINWgRx8ǏcVf hт)O%11^ϖ[Woɓ̞5e˗NŨQoa0ng@!B!BqR^ÕSN))))`PBBB:77WeZ5 T*Oͦl4i@@ZE V Mݵt^|}]t֍#V}wss#,5k$:w6oތjEV3ϰ`|, ;v$99h6mlחV[šի)((ӓ>TQK^LPPaaUj֯_ŋqNOB!B!BuGN(O2(ϧy4^ܮ&PڶiKhX(J.fcl޼~q&oߞvQ~f3O= ͛7ǃ=9r$]tU<ַ/6z8h0#^)J_څ|c>yyy 4Mؿ{HNNqy(Ix!<|Ou7k֜-Zw ׳m&>GRc2q<{yh4,Z-[3mt(;N?X_Zj <0$%ѻWo?VKhӶ-ԮSLHH~1Hnn.,p8-B!B!8wrirrr`СR.o9Ç_vo>V\e˰lҋ\|1{ѣ<أK/{[={vp! ++""qزy3111N۾};_}%VeKFbb'O`]l߾ip`ѩ-[pj5EQ7] Ү]{bcc˜?,L.YÎhРqq|r8-5>C,y!aadff2f(~.\O?z0Ӧ\B!B!BS .sC ȸqwts.xA6l{ᓘ0a<"#Kw><=-[`wX~=...wL_\?:fO1D!;BBB:}ޖ:ԍCRz lWKRQĜ=tWQQ/((lL uջÜl<<<[.'O,ѿAtБ~[}p!B!B!ԄN>u֖V!B!B!DŸ#5KSz 4MBT*{1{IurVMz!!$%%9&//ӧyc˖l/ā1ԩ]ǣ( =Qj|org8p]^zjKGС#ƕ|owK/̮]ضm'˲Kؾ}vzL&+/ANc'>1ri<ڵkYn=IIID;%]|;vekIIIDFJ||MS'O2{,-_NZZ:Fe/1s 5/bXسgM=x/kג==uakD))L gǎ!B!B!DٔpԩSJJJb0%%%EUYVwQV3dHaha%H3R BJ',AE+kݢz *Aˊ2)Lfus~z}0 Èܾ}sIb˕KqqjH^^yo\cz?5Og2&7*b۱l?~ l6STT?SWF ^okEV+aaa;v>^a>gc٨Qǎ d',,JP"gtvl+?ȅ֩S&)d2|>_>Z {oFXXp8#%%8=eCu\s;}\cOl Haa!?((o?vq}bϞ=|Ux*,&;߿eqq1N\]}nJDDDDDDDDDz#F~r$"""""""""A*(ʹn|˝0_DDDDDDDDDDAeEDDDDDDDDDJ.YA9(N  TK&EGn_4DDDDDDDDD%(_BBo6;vlgʕL6R,K߾p:7?ҋ/bFQQQ 4ƍPR۶J\\ZO=xee|21Zx8r˖.lO/OȜ9I[v;z͛6`2}ueĈ;Y__DDDDDDDDD풜P4}wuɊ;'!y?voO6mʴ7jԈ O/Xjbx<őث!0d-dff[ڹu2BΚA򂂂8p O<L f ]M55װ;<Ù$  Ibz&$$ vfY8{5Fbb"{o JJb͚5qǓkS.\P.F.7Lr0 *\'sM&W`ylBPP]ta+8~8%77Zq7c GL#^/#1!!!lذUV`o86oDzzzygnnD~}YbE111BZZknlڸǗ_bԿ?1boʼڵkӣGOjԨW_}?PfM7m6b0}Gⱱq\}w. zEEE1c8iQ=jɧѢE |8i?3<˄'xp8Lxyu*Bɧ5{~fҡCGÁ"h{qu]Sc{رcUڿ30L\u\sM K&Mx@4iYرcc{}p!ƌ}AIIm٘3g6 mێ;v3Ïpou(?Y&.=?]6YYY_kq>KIhX(YDz r 115Q&N͑Ç?9)>4iҤJUDDDDDDDDD.~ByԿ?k[˜9K ૯"s`|2Vql߾?wI}0XsuFFa+4x0}!Ƞ_>#֭9~xsԩxu֝N+]I-fW6><e˖vX,/_ا Xt);vλ3xr*| |3krf3˖-cIvv6 bo?㏧[. aĉ, pȑ#6lHV{lڸw;3gEĞ=طg}ʀXf $&?=ܡ\_W\m[EEEܱW\o;J;=~ׯO6mޭ;/"111$r_j4nܘCqN7@^Z ĿmJ˼4zm, 6lȦM*۹k+7Jsq, GXx8-+WӸq K&m/ᦛnv{o2'}ÆWm6߶mۈ 22 s̡s΄ҩS'ݻ+݋\^ren7j*BNNLjPRK.e՗\͓O>EBB;v져-[V8<:~:vUط~ viLcԨQ|Wva}J䧿3g6<,%^/K,/rʕtFkpUWQN6WrB\Y, [oAڢEsfP`xts`{7oo+yVڬ]ݻw/_XXHtt93s5 ` :=jݺu?_a6cez LXX9"bX2+駟ЧO_\߆ii缦\:6m;oY",,ѣrU;aЁG?=k3gbė:UL&3gq!iӦ O<$/_<~'22V:t8pчW>0id2V$7Ν;x=̝3Ν;kr}=_,_󈓈HOI!#c91m4!K}A^^<>z[_}M^^9'"""""""""elbr:&e79Nf}>588xl@l1 #0۷;dV+aaa;v:{ÏHMWyl&** sƏ5jz+,vl6[uCCC $++r ;aadgg bT̙;'7|sk^La sǶ s^DDDDDDDDL:ud2eL&Vc6=!!!b޽ 3`8| IvpԪEzz9|=z9TLEB ˴]nw!nwEAAYǘL&L&EDDDDDDDD򅒖oYÖ-[}N;DEEG9x'y˝Too>wӐ3ʢw˝N@DDDDDDDDDD~TP*QAYDDDDDDDDDD7WPlԮ]r!"""""""""sI f|VfWT׺uku~s-$aԮ]͸q㫕Ƕmx1ԩ[ZqDDDDDDDDDD\, #F]wyx}>jFGs`ǎ,Y0FО0֮[˚LBCCyᇹI>͛6c2֭;ͮlFNv6o~`|N'.ii~L2bo]DDDDDDDDD7墟Pn* ٵkm۵cF~>3Çe%<ĉm[B°Zx^ x<L2#YDFEh 22Fԯ_g|B@@i<=}97vz-"""""""""sO(7mڔm[ibܸX+:Urssyiy]Kdf235X :p"44c3V"66ݻwuV4hnbo_DDDDDDDDD7#"")Ӷ{noIvv61 KNCXaƍo޽{O8|pv+`p TAYDDDDDDDDD\􂲻M=L[HHd"<<|>ZhGrO1\a_IIIf36[ n""""""""""< IDAT+֦M"##HՋcc\.t?.$:*iFZJ 6ԯ;!<<>}'~L&GXxx"""""""""" n:6mJhhm ,u&O<$cz KTn}3gbEիQ9sr]wя1y.J#c*6kv|ڶm˚o`L42CBBxyDm⢼_~ENN˗/gL6 ȑűcYkSG"##?~~}RfMXAvлWb=!L2?c бC{:""""""""""r N(L43L|>'t:OuQ^t:3ܹ ۶n#sj۩E~%8 E8 \:rrp&M,dfjj9-["w̞= ƐC{I_̸3U5FBBs>| =_~M^sW_ѻOR? (=ܷo_{rرX6ƏW: ,g2w|ڶmDzeKɍ]onݺݳEHX.c4(+LM6n݆˗Wge JJb޼y̟7AID͟w\;F+x>_^xĞԌɮ֡I7oLpHM49%p2Rnb=ӛ?Y,gD</N]H`P 3>;~>rMɧnu(/4:q!k'p8Hy~9ǏW齊/dw(W$//l':* yQ[zc͚5̝3ԙ31 t?Sׇk=zI޽&fM5jĎ;[.+28s.4jԈI&R\\|Ʊm۶ns嗫xt+4n X :O8 e1-s fys2p &Lx h?^z$&cNo4y\L&Yf aGttڍFtOt؁B~ G}@AA>cnjJ;ibcؿ}cEz:3[{2!Cnaر 81h :pݺvI&9yyidfV;v^x())!)i0&DaA!aagCywY+;pPر_~_`ڭ $44PJ<%Ώo޽{O8|pv+Js3w3gdI Ĝs7jܘ Λ_/zEAA|laÆ۷ϿW-[_x<̛7ԩ׏W^y}I|6}vdܳA~ v{s)(' ӧk.6m=SLftЁެ$?_/yAt~ [-ýsgF?"7v{E⒒Е9ؾoJb^ 8 +En7wJcfE}r !''ZEe?S{}.X@dd$$w(WnzXDfԟ+^Æ mjůj\sСj РAby7I[EOػw/ݺuc֬4iڔ(}AAr>p{cرC\lv iFZJ?gw̙3g}M6q;ׯ@DD7toQ9qFiݺ?F=/+o>ϨGc9UZDDDDDDDD)(L&d2:U`,O_Ax8hF=Zc„뮻O={w൩Sa JJbNΚJ=z;GAY{>_^Mǎ+9vStؑ=zV9+q8,\9s\ŲeKYp!S^y|F~SpQ+WѴY{ҥ˰̞5\]=رOpQ|9vy ̚=sYn}٧tڕsqd_)))-[NrMNl,fg z<dX |Q۷ow. X,"""qr|tjX}Uu1zAAA[{8Ss֏+Dtt4ƮQEEŸݥ[,p\^q!sS\f"##ή҉nݻ3_>Z {oFXXp8#%%!~%+hvǃVs[&+&M~WfPPPP+cG'~t^\NgFs:8LDDF=_^RuEDDDDDDDD\o>m˝Tbؓ9sf|˝ȯ  .w r_zdx ߾s*(gee(,,4fjg6BbWmW'EDDDDDDDDDJ~seFڵ^zX, ѹnvJ:u.@F"""""""""".IAl6rjJ{ ZnMݫgωU'W0 #RU*(oݺ~%KNvo7nyضmO=5:uV+oUUJˆwrם#h޼9^\{رc;K,0JFО0֮[˚LBCCyᇹI>͛6c2֭;ͮlFNv6o~`|N'.ii~L2:u2`}^o{ɍ]onݺݳEzW״h4AII,[\v hպ5 ٺu #1!!!lذUV`o86oTfNHH7tG-233o}W\ш]R.dM'"""""""""rYO(dͯ]vж];N}.]nC?<|8>[P)L8۶%4, Պ률 /3;:EdT6"##ylh>Lx'ӗsc׮6,v=LIڹ[n>@Æ ce>ԬY[o{{9˜O4x0M4aDDDp1bbb1>bbb8tc>͠$~菦LLL}ǟSR馛ꪫht<>1c>ǿ/֭[T '6mʶ[˴eee1ndXL*q񴼮%k23YZBCC @ll,{Nq8j1c+Wݻٺu+ 4nwҮgӧ\}=U+x7>ڵmTn>1_ܜ/W*3}̚9^{sL ?Ȱd:t@@,^\aݻL1Çiwr H ݺ1`@BCC SRy;v8G<6lXvYƍӢE /JO,8]ǢN8e]p8FBBRi~B]&T-$$d2N~^>{-Z`#rx'nlf Z1-ýsgF?(Sz{xxxrq؃%K+WXXlZ+ߔy8+֦M"##HՋcc\.t?.$:*iFZJ g ~ߑGNNCqq۷~k7ߑ#G ܹ v{Eeff22VfЭ[w֭oQ߯[G{ѣg^P^nM6%44߶qy|:'x1O=%uf*>ԙxY"?gԈ9s뮻gǘm۶e7k0 k&NTVHppQe۷2#%/%u,n0Jd\I%L$++ W.5kbvuóffʔ)d^ @dd$g~I&R\\\?$$W;OJ`` YYYUsry 9\ba sǶM<:ul63L.[`6 f0UwUrE? 0yDz&_ a2|de-wYa1ѣb2tVܹsm/&g-&C]G ܼs*&é{.+7Wd(.G|rs)-'#c+.""""""""""v|3f\%EDDDDDDDDD$W^ȯ """"""""""R%*(H,""""""""""Ur>d箻bqZw?X,'Ә;w۶n0FLL >)S&zWqص\>p{=ϝ`g[׮]S.ӧTn|ڵ+9rŋazz艻ͪ+Z?r$iعsG8W\ш+ŚL/^|xIVfd7\TDDDDDDDDD,. 常8âE ٲy ]ybyW_}5^o _!πғ}%1'ǎ+^aя?jcqjԨzuh߾>4~'7oNII p:̟7", deJnۢŵtؑl͟+7(-w֝fW6#';t _ߖq:,NKjX<6mJ]`ۿ"=W忑%9<~8LQQQrWӴY3O),jي}zP\\̃>?,L}Ud'7y}4iZAII̛74(ߞȼN+qLj\yeO<>"iNSi1o~W#O>+hۮ{MzC؋/321-x<>6xqdz~֫c0eFy'YGnFAAAEn7:+gƍor~>3]w"""""""""=l2sGvv6ÇM|Æ<(֭][oY|cMf&︃'L^zp=ZXݣGOEvv65kҨQ#vAzuXq;wQFL4 ԭ[}VQx'Xv-PZ\ Q{Yn-?d2񏿿˗_~ @Mhݺ wyƍhzڵkݻޣ7tH^^?4 OW'ZjQPP_p cH]Ud޽cyȐ[;v,yF>:? ~Ab G} 3aKv999$y5l߾ܘB+DLLLnٲAI'OJع%8=ess nS~}&M? p8wOݻL1lgff&˗4.]ƻS惈"""""""""ra\+/<^8ʧ۸i#5k:.DJ礠)'s1vht[6o9*Hn޽+V-Of.rc1ԩՋGn"""""""""Eխٞܡ\uaZK1S[6lmV+ܹ -[byZJ?[oIڢE-Zħ~޽{֭fͤIӦwߟX,@{ *_ iݷ1cǖ[~=v䥗&)*z/:gZ <{xOW& AAAAփһ|-={pС* &44J?WVH((((AAAAW$<<ʱc0MZ,p\n{5(**.0@dd$f*yaٱm)""""""""rΝ;zنab1 v{kժݿp8|HHH0RRRN->G,'}>Ksp{^kx͛6c2֭;ͮlFNv6xIѷ_? Y`>N4nvLLu0`^oԣkrc[.{aѢEx^j֬IB:w3f_HDd$+3VuڵkӣGOjԨW_}?P^=iтiiXt)t֍6ЪukijucիGbb/BBBذa=VEkر#̛?Wnҷ_?Xz5>_?Y,z^JJJ8ʧP.sAPW,QXXhz:7Bv@v:5tL>RgJֱ,&2C@Æ cerx衇Y&:{9r1c&i`4iYرcзo?ƍ[.ӧSү_?s? N5״(DDDDDDDDDW)倀_aaaX ,nOtr @f z&jxNTzOѴiSA_eܸX+:Urssyiy]Kdf235X :p"44c3V"66ݻwuV4hnᆬ]+ӧ\}=pF~ U.d/ƍкuv'7`ƍߙ93J~Ŋ ڶcfj*wu7̘믿Vf==:7Цkמ={vӾ}:vhOAAgb˫zxVk-x<> ZPȑ#UWYADٔ`lRze֭[M|`_QQyfs""")Ӷ{noIvv61 KNCXa&ߐ{)&p2.W.vIaaa%ۇݺ1`@BCC sÇعd_ɾ `K}۶m#""ȨJ8Վ;*۰{ԯ_IpjkA:uٳ],""""""""" fޠ oAAl6{OduVp8N=|w()))RT9N'!!!|>a&dX,f[.M=L[HHd"<<|>ZhGrOTȍ\a_II7f36[ nwZ駟fxr2Νy*()P"7g q+Yvcix<|>~~ZjEPPٿf=ÎDDDDDDDDD0bJBBBfW\\u8>JkFBBzLUOII1edd].VZ朜s``Ңt㱙L` 0 aV l6^l6 0|>b1QfSϖeaX.w """""""""rx˝Be ?5l2 d`6}fg0 /Pb2<&KJJ p[bJWRTT䍈9rftWrAMNl,' ǁŁ6wz_L8SA2/>[i!r:Q@>D&0>X,>Jff|"N+&߿p8>aN[ yks> e2DIc-OKeIvF63`Z4N$(Ic.Q#*KR I qDIsxߖʒr2 ˤV(Ic./ I C 8O CU xh+A3AO=plدz0BP0T~IENDB`RaySession-0.12.2/resources/ui/000077500000000000000000000000001417052567600163375ustar00rootroot00000000000000RaySession-0.12.2/resources/ui/abort_copy.ui000066400000000000000000000064201417052567600210410ustar00rootroot00000000000000 Dialog 0 0 249 118 Abort Copy ? Qt::Vertical 20 40 Do you want to abort current copy ? 0 Qt::Vertical 20 40 Qt::Horizontal 40 20 Abort Copy .. Cancel .. pushButtonCancel clicked() Dialog reject() 198 92 124 58 pushButtonAbort clicked() Dialog accept() 98 92 124 58 RaySession-0.12.2/resources/ui/abort_session.ui000066400000000000000000000037761417052567600215650ustar00rootroot00000000000000 AbortSession Qt::NonModal 0 0 342 72 Abort Session ? false <html><head/><body><p>Are you sure to want to abort session without saving ?</p></body></html> Qt::AlignCenter Abort .. Cancel .. pushButtonCancel clicked() AbortSession reject() 326 120 187 79 RaySession-0.12.2/resources/ui/about_raysession.ui000066400000000000000000000073531417052567600222770ustar00rootroot00000000000000 DialogAboutRaysession 0 0 550 310 About RaySession 0 0 <html><head/><body><p><img src=":/128x128/raysession.png"/></p></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop <html><head/><body><p><span style=" font-weight:600;">RaySession</span></p><p>version : %s</p></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop <html><head/><body><p>Ray Session is a Qt interface for the ray-daemon.</p><p>Its goal is to manage together audio programs as Ardour, Carla, Qtractor, Non-Timeline in an unique session.</p><p>Programs just have to be compatible with the <a href="http://non.tuxfamily.org/wiki/Non%20Session%20Manager"><span style=" text-decoration: underline; color:#2980b9;">NSM</span></a> API to work with Ray Session.<br/></p><p align="right">Copyright (C) 2016-2021 houston4444</p><p><br/></p></body></html> true true Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() DialogAboutRaysession accept() 248 254 157 274 buttonBox rejected() DialogAboutRaysession reject() 316 260 286 274 RaySession-0.12.2/resources/ui/add_application.ui000066400000000000000000000620431417052567600220160ustar00rootroot00000000000000 DialogAddApplication Qt::NonModal 0 0 714 535 Add Application false 0 0 Filter : Filter application templates true Qt::Vertical Qt::LeftToRight Factory true <html><head/><body><p>NSM is the protocol used by modern audio programs to ensure a good session management.</p></body></html> NSM true User true <html><head/><body><p><span style=" font-weight:600;">Ray-Hack</span> is a fake protocol that tries to manage non NSM compatible programs as it can.</p><p>It can be useful :</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">for audio programs that don't have NSM implementation yet</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">for non-audio programs</li></ul></body></html> Ray-Hack true true 0 0 Refresh Applications .. Qt::Vertical 6 0 0 0 0 6 QToolButton{border:none} ... .. 64 64 12 75 true MacronDemission Qt::Horizontal 40 20 QToolButton::menu-indicator{ image: url(none.jpg);}\nQToolButton {border: none} ... :/scalable/breeze/im-user.svg:/scalable/breeze/im-user.svg 22 22 QToolButton::InstantPopup <html><head/><body><p>Add this template to favorites / Remove this template from favorites</p></body></html> QToolButton {border: none} ... :/scalable/breeze/draw-star.svg:/scalable/breeze/draw-star.svg 22 22 Qt::Vertical QSizePolicy::Maximum 20 20 true resistance to the oppression of pests true Qt::Horizontal Qt::Horizontal QToolButton{border:none} ... :/scalable/breeze/document-nosave.svg:/scalable/breeze/document-nosave.svg 32 32 11 50 false false false true QLabel{color:#f19d02} Non Saveable Program !!! Qt::AlignCenter Qt::Horizontal 0 0 : Protocol 0 0 Executable 0 0 : label Label 0 0 : lallement NLP Name : Program Name Qt::Vertical QSizePolicy::Expanding 20 40 Qt::Horizontal 40 20 <html><head/><body><p>Get more informations on this template.</p></body></html> ... .. Qt::Vertical QSizePolicy::Expanding 20 40 75 true false No template selected Qt::AlignCenter Qt::Vertical 20 40 false true true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Refresh\nApplications F5 OpenSessionFilterBar QLineEdit

surclassed_widgets
FakeToolButton QToolButton
surclassed_widgets
FavoriteToolButton QToolButton
surclassed_widgets
buttonBox accepted() DialogAddApplication accept() 248 254 157 274 buttonBox rejected() DialogAddApplication reject() 316 260 286 274 RaySession-0.12.2/resources/ui/ardour_convert.ui000066400000000000000000000045571417052567600217450ustar00rootroot00000000000000 Dialog 0 0 400 378 Convert Ardour session to Ray This script helps you to load an ardour session made with Ardour into a RaySession session. For performance reasons, the ardour project will be moved (and not copied) to the session directory. This script seems to work well, but there is absolutely no warranty that some problems could appear, so it is advisable to backup your ardour session first. In the future, think to always start Ardour from RaySession ! You can never be sure to not need another software, and auto snapshots can help you a lot. Now let choose the Ardour session you want to convert to a Ray session. true Do not display this message again Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/canvas_options.ui000066400000000000000000000114541417052567600217310ustar00rootroot00000000000000 Dialog 0 0 224 240 Canvas Options Qt::Vertical 20 40 <html><head/><body><p>Display shorter and more readable ports and groups names.</p><p>If unchecked, displayed port names will be the trought port names.</p></body></html> Use graceful names Group A2J hardware ports Boxes have shadows <html><head/><body><p>Always resize the canvas scene to the mininum contents.</p><p>This way, the view is directly optimized while moving boxes.</p></body></html> Elastic canvas <html><head/><body><p>When this option is active, boxes are automatically moved when another box has been moved over them.</p></body></html> Prevent overlapping of boxes false Qt::Horizontal 40 20 Maximum port width : 0 0 40 800 170 0 0 Theme : Qt::Vertical 20 40 RaySession-0.12.2/resources/ui/canvas_port_info.ui000066400000000000000000000200611417052567600222270ustar00rootroot00000000000000 Dialog 0 0 420 346 Port Infos 0 0 Full port name : Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft Qt::Horizontal 40 20 ... true Qt::Vertical 20 40 : 0 0 Type 0 0 : Flags Port Flags JACK UUID : true Audio Port Qt::Vertical 20 40 Metadatas : Port-Group 0 0 : : 0 0 Order 0 0 Pretty name Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/client_properties.ui000066400000000000000000000331701417052567600224340ustar00rootroot00000000000000 Dialog 0 0 472 532 0 0 Properties 0 General 0 0 : 0 0 : Qt::Horizontal QSizePolicy::Fixed 3 20 0 0 Client id Description Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 Icon 0 0 Protocol : Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 Label 0 0 : 0 0 : 0 0 client_protocol 0 0 nsmid 48 48 QToolButton{border:none} ... ../../../.designer/backup../../../.designer/backup 48 48 Qt::Vertical 20 40 Qt::Vertical QSizePolicy::MinimumExpanding 20 0 Snapshots 0 0 <html><head/><body><p>Edit here what types of files inside the client folders<br/>should be ignored in session snapshots.</p><p>Indexed files will remain so.</p></body></html> Snapshots ignored extensions : <html><head/><body><p>Edit here what types of files inside the client folders<br/>should be ignored in session snapshots.</p><p>Indexed files will remain so.</p></body></html> Qt::Vertical 20 40 Prevent to stop without recent or possible save true Protocol 0 0 0 0 0 0 Qt::Horizontal 40 20 Save Changes ../../../.designer/backup../../../.designer/backup FakeToolButton QToolButton
surclassed_widgets
RaySession-0.12.2/resources/ui/client_rename.ui000066400000000000000000000070531417052567600215100ustar00rootroot00000000000000 Dialog 0 0 346 177 Rename Client Qt::Vertical 20 40 ... 48 48 10 75 true TextLabel Qt::Horizontal Qt::Vertical 20 40 Rename this client to : Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok FakeToolButton QToolButton
surclassed_widgets
buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274
RaySession-0.12.2/resources/ui/client_slot.ui000066400000000000000000000437631417052567600212320ustar00rootroot00000000000000 ClientSlotWidget 0 0 514 199 Qt::DefaultContextMenu Frame 0 0 3 0 3 Qt::Vertical 20 40 2 Qt::Horizontal QSizePolicy::Fixed 4 20 0 0 32 32 32 32 QToolButton::menu-indicator{ image: url(none.jpg);} QToolButton {border: none} ... 32 32 QToolButton::InstantPopup Qt::Horizontal QSizePolicy::Fixed 5 20 Qt::Horizontal Qt::Vertical 20 40 false 0 0 16777215 16777215 font-weight : bold ClientName Qt::Vertical 20 40 Qt::Horizontal QSizePolicy::MinimumExpanding 0 20 0 0 0 0 0 0 Qt::Horizontal QSizePolicy::Expanding 0 20 0 0 36 20 36 24 Display client Ray-Hack properties false Hack :/scalable/breeze/layer-visible-on.png:/scalable/breeze/layer-visible-on.png 32 32 true Qt::ToolButtonTextOnly QToolButton{border:none} ../../../.designer/backup../../../.designer/backup 22 22 Qt::Horizontal QSizePolicy::Fixed 4 20 32 32 Launch QToolButton {border: none} ... :/scalable/breeze/media-playback-start.svg :/scalable/breeze/disabled/media-playback-start.svg:/scalable/breeze/media-playback-start.svg 32 32 false 32 32 <html><head/><body><p>Politely ask the client to stop.</p></body></html> QToolButton {border: none} ... :/scalable/breeze/media-playback-stop.svg :/scalable/breeze/disabled/media-playback-stop.svg:/scalable/breeze/media-playback-stop.svg 32 32 false 0 0 60 28 Serif 8 50 false Status stopped true Qt::AlignCenter true false 32 32 Save QToolButton {border: none} ... :/scalable/breeze/document-save.svg :/scalable/breeze/disabled/document-save.svg:/scalable/breeze/document-save.svg 32 32 Qt::Horizontal QSizePolicy::Fixed 6 20 0 0 22 22 Remove QToolButton {border: none} ... :/scalable/breeze/window-close.svg:/scalable/breeze/window-close.svg Qt::Vertical 20 40 Qt::Vertical 20 40 ../../../../../.designer/backup../../../../../.designer/backup Save As Application Template ../../../../../.designer/backup../../../../../.designer/backup Properties ../../../.designer/backup../../../.designer/backup Return To A Previous State ../../../.designer/backup../../../.designer/backup Rename Find boxes in patchbay StatusBar QLineEdit
surclassed_widgets
RayHackButton QToolButton
surclassed_widgets
RaySession-0.12.2/resources/ui/client_trash.ui000066400000000000000000000204161417052567600213600ustar00rootroot00000000000000 Dialog 0 0 333 311 Trashed client QToolButton{border:none} ... .. 64 64 12 75 true Prettier Name true Description Qt::Horizontal Client id 0 0 Executable 0 0 : 0 0 : nsmid Qt::Horizontal 40 20 executable Qt::Horizontal 40 20 <html><head/><body><p>Get more informations on this trashed client.</p></body></html> ... .. Qt::Horizontal Qt::Vertical 20 40 <html><head/><body><p align="center">Do you want to restore this client in the session ?<br/>You can also definitely remove the client and its files.</p></body></html> Qt::Vertical 20 40 <html><head/><body><p>Remove definitely the client and its files.</p></body></html> Remove .. <html><head/><body><p>Restore this client in current session.</p></body></html> Restore Client .. Cancel .. FakeToolButton QToolButton
surclassed_widgets
pushButtonCancel clicked() Dialog reject() 279 286 166 155 pushButtonRestore clicked() Dialog accept() 166 286 166 155
RaySession-0.12.2/resources/ui/daemon_url.ui000066400000000000000000000042111417052567600210210ustar00rootroot00000000000000 Dialog 0 0 289 146 Daemon URL Qt::AlignCenter ray-daemon url to connect to : Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft osc.udp://192.168.XX.XX:1234/ true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/donations.ui000066400000000000000000000055571417052567600207100ustar00rootroot00000000000000 Dialog 0 0 427 320 Donations <html><head/><body><p>Hi !</p><p>it seems that you appreciate RaySession, that is already a good new.<br/>This software is free as in Speech and as in Beer,<br/>but it has required and still takes time.</p><p>Make a donation (even small) is a simple way to say &quot;Thank you&quot;.<br/>You can donate <a href="https://liberapay.com/Houston4444"><span style=" text-decoration: underline; color:#2980b9;">here</span></a>.</p><p>If ever you donate nothing,<br/>this program will continue to work without limits of functionnality,<br/>without limit of duration, and even without insulting you ;) .</p></body></html> true Qt::Vertical 20 40 Do not show this message again false Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/error_dialog.ui000066400000000000000000000030021417052567600213410ustar00rootroot00000000000000 Dialog 0 0 102 70 Error ! Error Text Qt::Horizontal QDialogButtonBox::Cancel buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/filter_frame.ui000066400000000000000000000136321417052567600213420ustar00rootroot00000000000000 Frame 0 0 740 41 Frame QFrame{border:none} 0 2 2 Hide filter bar QToolButton{border:none} ... .. Qt::Vertical QSizePolicy::Minimum 20 10 Qt::Horizontal QSizePolicy::Fixed 6 20 Find a box... true ... .. ... .. Qt::Horizontal QSizePolicy::Fixed 6 20 60 0 Audio true Midi true Qt::Horizontal QSizePolicy::Fixed 60 20 adjust the opacity of boxes not matching with the filter Opacity : adjust the opacity of boxes not matching with the filter % 2 70 17 Qt::Horizontal QSizePolicy::Fixed 6 20 OpenSessionFilterBar QLineEdit
surclassed_widgets
RaySession-0.12.2/resources/ui/hydro_rh_nsm.ui000066400000000000000000000106371417052567600214000ustar00rootroot00000000000000 Dialog 0 0 318 349 Hydrogen NSM script Qt::Vertical 20 40 <html><head/><body><p>This script converts all regular <span style=" font-weight:600;">Hydrogen<br/></span>Ray-Hack clients to the NSM protocol.</p><p>Where do you want the script to proceed:</p></body></html> Qt::AlignCenter false Qt::Vertical 20 40 In the current session Qt::Horizontal In all sessions true In application templates true In session templates true Qt::Vertical 20 40 <html><head/><body><p><span style=" font-style:italic;">Note that you could lose some JACK connections,<br/>but it's still worth it.</span></p></body></html> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/jack_config_info.ui000066400000000000000000000216401417052567600221510ustar00rootroot00000000000000 Dialog 0 0 502 575 Jack Configuration Infos <html><head/><body><p>You create a session from the JACK configuration reminder template.</p><p>This means that when you re-open this session, JACK may be restarted with the configuration used by that session.</p><p>This session callback is made from the session scripts.</p></body></html> true Qt::Vertical QSizePolicy::Fixed 20 6 0 0 Session Scripts Infos Session Scripts Infos true <!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" /><title>Session Scripts Infos</title><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; 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;">Session scripts are located in the <span style=" font-style:italic;">ray-scripts</span> folder in the session folder, but they could also be located in a <span style=" font-style:italic;">ray-scripts</span> folder in a parent folder of the session folder.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For example:</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the scripts folder for this new session will be:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">But could just as well be:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and thus apply to all sessions contained in <span style=" font-weight:600;">%s</span>.</p></body></html> Qt::Vertical 20 40 0 0 Jack Config Script Infos true <!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:'Noto Sans'; font-size:10pt; 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;"><span style=" font-weight:600;">The principle is as follows:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Each time the session is saved, the JACK configuration is saved in the session.<br />Before opening, JACK is restarted if the session configuration is different from the current one.<br />After closing, JACK is restarted as it was configured before opening if needed.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If you open this session on another computer, the JACK configuration will not be recalled but will be overwritten when you save.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If you wish to open this session without reloading the JACK configuration, simply disable the session scripts.</p></body></html> Qt::Vertical 20 40 <html><head/><body><p>Unfortunately, at the moment it is not possible to get the current JACK configuration with certainty, so JACK will be restarted at the first session opening.<br/>You can work around this problem by automatically starting a light daemon at your desktop session startup.</p></body></html> Automatically start ray-jack_checker daemon at startup true Do not show this message again true Qt::Horizontal QDialogButtonBox::Ok checkBoxAutoStart checkBoxNotAgain buttonBox accepted() Dialog accept() 254 446 157 274 buttonBox rejected() Dialog reject() 322 446 286 274 RaySession-0.12.2/resources/ui/list_snapshots.ui000066400000000000000000000103321417052567600217520ustar00rootroot00000000000000 Dialog Qt::NonModal 0 0 399 397 Snapshots Manager false <html><head/><body><p>Select from the list below the snapshot to be recalled<br/>to return to a past state of the session :</p></body></html> Qt::Vertical QSizePolicy::Maximum 20 20 Qt::Horizontal 40 20 Take a snapshot now ! .. Qt::Horizontal 40 20 false false true 1 <html><head/><body><p>Make a snapshot at each session save.</p></body></html> Auto snapshot at save for this session true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/new_executable.ui000066400000000000000000000160661417052567600217010ustar00rootroot00000000000000 DialogNewExecutable Qt::NonModal 0 0 212 376 New Executable Client false Executable : <html><head/><body><p>If program is not compatible with the NSM API, </p><p>you should launch it in proxy to define a config file !</p></body></html> NSM Protocol true <html><head/><body><p>Show more options ...</p></body></html> ... .. Advanced <html><head/><body><p>The Prefix Mode determines the pattern of the client files.</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Session Name (Default) :<br/>The client files names start with the session name.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Client Name :<br/>The client files names start with the client name given by the client itself<br/>(as in Non Session Manager).</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Custom :<br/>The client files names start with the prefix written below.</li></ul></body></html> Prefix : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Client ID : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <html><head/><body><p>Use it If you want to add to session a file made outside from a session.</p><p>If you let this line empty, the client_id will be automaticely generated.</p></body></html> Prefix Mode : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Start the client true <html><head/><body><p>With this option checked, NSM programs should name their JACK client names starting with ClientName.ClientId (as in NSM), else it will be ClientName (with a digit suffix if needed).</p></body></html> Long JACK Naming Qt::Vertical 20 40 true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() DialogNewExecutable accept() 248 254 157 274 buttonBox rejected() DialogNewExecutable reject() 316 260 286 274 RaySession-0.12.2/resources/ui/new_session.ui000066400000000000000000000144711417052567600212410ustar00rootroot00000000000000 DialogNewSession Qt::NonModal 0 0 228 260 New Session false 0 <html><head/><body><p><span style=" font-size:9pt; font-weight:600;">Sessions Folder :</span></p></body></html> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter font-style : italic /home/user/Ray Sessions Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Folder .. Qt::Vertical 20 40 0 0 0 0 Original session : 75 true session name 0 0 Template : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::Horizontal 0 0 New Session Name : Qt::Vertical 20 40 true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() DialogNewSession accept() 248 254 157 274 buttonBox rejected() DialogNewSession reject() 316 260 286 274 RaySession-0.12.2/resources/ui/nsm_open_info.ui000066400000000000000000000040151417052567600215270ustar00rootroot00000000000000 Dialog 0 0 500 237 Opening NSM Session <html><head/><body><p>You are opening a session created by Non Session Manager.</p><p><br/>RaySession will open it, but changes won't be applied to NSM file (session.nsm).</p><p>Also, Once you start to work with RaySession, you have to continue with it !</p></body></html> Don't Show this Message Again Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/nsm_properties.ui000066400000000000000000000216711417052567600217560ustar00rootroot00000000000000 Frame 0 0 416 450 Frame client_name 0 0 : 0 0 client_capabilities Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 Name : Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 Capabilities Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 48 48 QToolButton{border:none} ... ../../../.designer/backup../../../.designer/backup 48 48 Qt::Vertical 20 40 9 true <html><head/><body><p>Edit executable is strongly discouraged !<br/>It can be useful if you use many versions of a same software.<br/>Change it only if you are sure of what you are doing.</p></body></html> Qt::Vertical 20 40 Executable : Qt::Vertical 20 40 9 true <html><head/><body><p>Arguments are supposed to not be supported by NSM protocol.<br/>In some cases it can works, but no warranty !</p></body></html> Qt::Vertical 20 40 Arguments : Qt::Vertical 20 40 Environment variables : <html><head/><body><p>Set here the environment variables you want to set to the process, separate them with spaces.<br/><br/>for example :</p><pre style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Hack';">MY_VAR1=my_value MY_VAR2=&quot;other value&quot;</span></pre></body></html> FakeToolButton QToolButton
surclassed_widgets
RaySession-0.12.2/resources/ui/open_session.ui000066400000000000000000000465421417052567600214150ustar00rootroot00000000000000 DialogOpenSession Qt::NonModal 0 0 580 551 Open Session false 0 0 0 0 0 Qt::Horizontal 6 false Filter : Qt::LeftToRight Sort by dates Qt::Vertical QSizePolicy::Fixed 6 6 PreviewFrame{background-color: rgba(127, 127, 127, 35);border-radius:4px} 6 6 16 16 16 16 75 true QLabel{color:green;background-color:black} >_ 0 0 16777215 16777215 0 -1 QToolButton::menu-indicator{ image: url(none.jpg);} QToolButton {border: none} ... .. QToolButton::InstantPopup QToolButton{border:none} ... .. 24 24 9 50 true false 0 Mo Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 250 0 QTabWidget::Rounded 0 false Clients QFrame{border:none} Notes true Snapshots false 1 0 <html><head/><body><p><span style=" font-size:9pt; font-weight:600;">Sessions Folder :</span></p></body></html> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter font-style : italic /ho&me/user/Ray Sessions Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Folder .. Qt::Vertical QSizePolicy::Fixed 20 10 2 0 0 true Listing sessions Qt::AlignCenter 0 0 Cancel .. 24 false Qt::Horizontal false QProgressBar::BottomToTop %p% 180 0 Qt::CustomContextMenu 0 false false false 4 true 20 20 false Name Notes Scripts Date QLayout::SetMinimumSize Save the current session true true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok OpenSessionFilterBar QLineEdit
surclassed_widgets
PreviewFrame QFrame
surclassed_widgets
1
ListWidgetPreviewClients QListWidget
list_widget_preview_clients
StackedSessionName QStackedWidget
surclassed_widgets
1
buttonBox accepted() DialogOpenSession accept() 248 254 157 274 buttonBox rejected() DialogOpenSession reject() 316 260 286 274
RaySession-0.12.2/resources/ui/patchbay_tools.ui000066400000000000000000000214501417052567600217130ustar00rootroot00000000000000 Form 0 0 885 34 Form QProgressBar{ border-radius: 0px; text-align:center; background-color: rgba(50%, 50%, 50%, 25%); } 0 1 0 1 Qt::Horizontal 40 20 90 16777215 true QSlider:focus{ border: none; } QSlider::handle:horizontal{ image: url(:scalable/breeze/zoom-centered.svg); } 0 1000 10 10 500 true Qt::Horizontal false false QSlider::TicksBelow 500 Qt::Horizontal QSizePolicy::Fixed 6 20 Qt::Vertical Qt::Horizontal QSizePolicy::Fixed 6 20 9 JACK Samplerate 48.000 9 Hz Qt::Horizontal QSizePolicy::Fixed 6 20 Qt::Vertical Qt::Horizontal QSizePolicy::Fixed 6 20 9 Buffer : Qt::Horizontal QSizePolicy::Fixed 2 20 16777215 16777215 9 QCombobox{align:right} Qt::Horizontal QSizePolicy::Fixed 6 20 Qt::Vertical 70 0 9 Number of audio Xruns. Click on it to reset them. QPushButton{border:none; text-align:right} QPushButton::hover{border: 1 px solid grey;text-align:right} 0 Xruns Qt::Horizontal QSizePolicy::Fixed 6 20 80 16777215 9 0 DSP: %p% <p style="color:red">JACK is not started !</p> ZoomSlider QSlider
surclassed_widgets
ProgressBarDsp QProgressBar
surclassed_widgets
RaySession-0.12.2/resources/ui/preview_client_slot.ui000066400000000000000000000151201417052567600227550ustar00rootroot00000000000000 ClientSlotWidget 0 0 514 199 Qt::DefaultContextMenu Frame 0 0 3 0 3 Qt::Vertical 20 40 2 Qt::Horizontal QSizePolicy::Fixed 4 20 0 0 32 32 32 32 QToolButton::menu-indicator{ image: url(none.jpg);} QToolButton {border: none} ... 32 32 QToolButton::InstantPopup Qt::Horizontal QSizePolicy::Fixed 5 20 Qt::Horizontal Qt::Vertical 20 40 false 0 0 16777215 16777215 font-weight : bold ClientName Qt::Vertical 20 40 Qt::Horizontal QSizePolicy::MinimumExpanding 0 20 Qt::Vertical 20 40 ../../../../../.designer/backup../../../../../.designer/backup Properties Add to the current session RaySession-0.12.2/resources/ui/proxy_copy.ui000066400000000000000000000060121417052567600211100ustar00rootroot00000000000000 Dialog 0 0 459 145 Copy File ? file is not in proxy directory. <html><head/><body><p>Do you want to copy this file to proxy directory or to use directly this file ?</p></body></html> Qt::Horizontal 40 20 Copy file and rename it with session name Copy And Rename File Copy File .. Use This File .. pushButtonCopy clicked() Dialog accept() 288 118 229 72 pushButtonUseThisFile clicked() Dialog reject() 395 118 229 72 RaySession-0.12.2/resources/ui/proxy_gui.ui000066400000000000000000000352101417052567600207240ustar00rootroot00000000000000 MainWindow 0 0 456 370 Ray Proxy <html><head/><body><p>Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly.</p><p>Some audio programs doesn't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> Config File : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <html><head/><body><p>Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly.</p><p>Some audio programs doesn't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> Executable : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <html><head/><body><p>Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly.</p><p>Some audio programs doesn't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> Browse .. Qt::ToolButtonTextBesideIcon <html><head/><body><p>The environment variables $NSM_CLIENT_ID and $RAY_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.<br/>The variable $CONFIG_FILE will contain the name of the config file selected above.</p></body></html> Arguments : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <html><head/><body><p>The environment variables $NSM_CLIENT_ID and $RAY_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.<br/>The variable $CONFIG_FILE will contain the name of the config file selected above.</p></body></html> Qt::Vertical 20 40 Wait window before reply (needs wmctrl) <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then Ray Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> 0 0 <html><head/><body><p>Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal.<br/>It's impossible to know which signal a specific program will respond to.<br/>A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK).<br/>Check the program's documentation or source code to determine which signal to use to stop it gracefully.</p></body></html> Stop Signal : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Test .. Qt::ToolButtonTextBesideIcon <html><head/><body><p>Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal.<br/>It's impossible to know which signal a specific program will respond to.<br/>A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK).<br/>Check the program's documentation or source code to determine which signal to use to stop it gracefully.</p></body></html> 0 0 <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then Ray Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> Save Signal : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 No Save Level : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 1 0 <html><head/><body><p>If this proxy has no save signal,<br/>it can sends to session manager this information.</p><p><ul><li>0 - this information is not sent.</li><li>1 - this information is sent, session manager will ask user to close programs himself at session unload.</li><li>2 - this information is sent, session manager can try to close window gracefully before to ask user to close programs himself at session unload. Good choice if the program displays a dialog if changes are not saved.</li></ul></p></body></html> color: red executable failed to launch ! Qt::AlignCenter Qt::Horizontal 40 20 Launch .. Stop .. RaySession-0.12.2/resources/ui/quit_app.ui000066400000000000000000000052551417052567600205270ustar00rootroot00000000000000 DialogQuitApp Qt::NonModal 0 0 564 159 Quit RaySession false <p>Session <bold>%s</bold> is running.</p><p>RaySession will be closed.</p><p>Do you want to save session ? Qt::AlignCenter Save && Quit .. Quit Without Saving .. Keep Daemon Running .. Cancel .. pushButtonCancel clicked() DialogQuitApp reject() 326 120 187 79 RaySession-0.12.2/resources/ui/ray_hack_copy.ui000066400000000000000000000061101417052567600215070ustar00rootroot00000000000000 Dialog 0 0 459 145 Copy File ? file is not in client working directory. <html><head/><body><p>Do you want to copy this file to client working directory or to use directly this file ?</p></body></html> Qt::Horizontal 40 20 Copy file and rename it with session name Copy And Rename File .. Copy File .. Use This File .. pushButtonCopy clicked() Dialog accept() 288 118 229 72 pushButtonUseThisFile clicked() Dialog reject() 395 118 229 72 RaySession-0.12.2/resources/ui/ray_hack_properties.ui000066400000000000000000000537171417052567600227500ustar00rootroot00000000000000 Frame 0 0 428 585 Frame <html><head/><body><p>here many fields are available to you. This is not necessarily good news, the idea is to be able to load a program into the session that is not (yet) compatible with NSM. If properly implemented in the client, the NSM protocol will always be much more comfortable to use and more reliable than this hack. That said, if we can expect the NSM implementation in all audio programs, this is not the case for other programs which can still be useful in the session.</p><p><br/></p><p>The Ray-Hack pseudo-protocol uses the attributes of proxies (nsm-proxy or ray-proxy), except that the client is launched directly in the session.</p></body></html> Folder : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <html><head/><body><p>Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly.</p><p>Some audio programs doesn't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> Executable : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> Config File : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <html><head/><body><p>The environment variables $NSM_CLIENT_ID and $RAY_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.<br/>The variable $CONFIG_FILE will contain the name of the config file selected above.</p></body></html> Arguments : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Environment : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <html><head/><body><p>The program will be started in the folder named above.</p><p>It is recommended that you only refer to files in the current directory.</p><p>$RAY_SESSION_NAME will be replaced with the name of the session.</p></body></html> <html><head/><body><p>The program will be started with its current directory being a uniquely named directory under the current session directory. </p><p>It is recommended that you only refer to files in the current directory.</p></body></html> Browse .. Qt::ToolButtonTextBesideIcon <html><head/><body><p>The environment variable $RAY_CLIENT_ID will contain the RaySession client_id of this client.$RAY_SESSION_NAME will contain the display name for the session.<br/>$RAY_JACK_CLIENT_NAME will contain a string suitable for use as e.g. a JACK client name.<br/>$CONFIG_FILE will contain the name of the config file selected above.</p></body></html> 48 48 QToolButton{border:none} ... ../../../.designer/backup../../../.designer/backup 48 48 Qt::Vertical 20 40 <html><head/><body><p>Ray Hack protocol is a convenience way to manage non NSM compatible programs in the session.</p><p>Some audio programs don't have NSM implementation yet, but they can have a LASH/LADISH implementation, and we can use it for the save signal.</p><p>Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. <br/><br/>Patching the program to use NSM natively will result in a better experience. </p></body></html> session_name.client_id <html><head/><body><p>Set here the environment variables you want to set to the process, separate them with spaces.<br/><br/>for example :</p><pre style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Hack';">MY_VAR1=my_value MY_VAR2=&quot;other value&quot;</span></pre></body></html> Qt::Vertical 20 40 <html><head/><body><p>If wmctrl is present and compatible with window manager,</p><p>and if this box is checked,</p><p>the program will be considered as ready only when it displays a window.</p><p>Else the program will be considered as ready after 500ms.</p></body></html> wait for a window before considering it ready (needs wmctrl) 0 0 <html><head/><body><p>Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal.<br/>It's impossible to know which signal a specific program will respond to.<br/>A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK).<br/>Check the program's documentation or source code to determine which signal to use to stop it gracefully.</p></body></html> Stop Signal : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then Ray Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> Save Signal : Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <html><head/><body><p>Some (very few) programs may respond to a specific Unix signal by somehow saving their state.</p><p>If 'Save Signal' is set to something other than 'None', then this signal will be sent to the program when we ask to save it.</p><p>If program is compatible with LASH/LADISH, save signal is SIGUSR1.</p><p>Most programs will treat these signals just like SIGTERM and die.</p><p>You have been warned.</p></body></html> <html><head/><body><p>Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal.<br/>It's impossible to know which signal a specific program will respond to.<br/>A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK).<br/>Check the program's documentation or source code to determine which signal to use to stop it gracefully.</p></body></html> Qt::Vertical 20 40 Without save method <html><head/><body><p>Because we have no method to save the state of this program,<br/>if this box is checked the program won't be closed by session manager at session close,</p><p>it will ask user to close it himself (saving changes or not).</p></body></html> Tell user to close program himself at session close <html><head/><body><p>If wmctrl is present and compatible with window manager,<br/>the program will try to close gracefully its windows before asking user to close them himself.<br/>This way, in a lot of cases, program will be closed when it has no unsaved changes,<br/>or will display an exit confirmation dialog to save changes or not. </p></body></html> Try to close window gracefully (needs wmctrl) Qt::Vertical 20 40 Test &Zone true true QFrame{border:None} QFrame::StyledPanel QFrame::Raised 6 0 0 0 0 Qt::Horizontal 40 20 Launch .. Stop .. false 0 0 60 28 Serif 8 50 false Status stopped true Qt::AlignCenter true Save .. Qt::Horizontal 40 20 color: red executable failed to launch ! Qt::AlignCenter FakeToolButton QToolButton
surclassed_widgets
StatusBar QLineEdit
surclassed_widgets
RaySession-0.12.2/resources/ui/ray_net_properties.ui000066400000000000000000000214011417052567600226110ustar00rootroot00000000000000 Frame 0 0 510 437 Frame 48 48 QToolButton{border:none} ... ../../../.designer/backup../../../.designer/backup 48 48 Qt::Vertical 20 40 : Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 Name 0 0 : 0 0 Capabilities Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 client_capabilities Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop client_name 9 true <html><head/><body><p>Edit the daemon URL only if you meet troubles !!!</p></body></html> Qt::Vertical 20 40 Daemon URL : Qt::Vertical 20 40 9 true <html><head/><body><p>Here, sessions root folder is the sessions root folder used by the slave daemon.<br/>Edit it only if you have changed the sessions root folder<br/>used by the slave daemon.</p></body></html> Qt::Vertical 20 40 Sessions root folder : Qt::Vertical 20 40 <html><head/><body><p>Template session that will be used on the slave daemon if there is no existing session at the same path than the master one (relatively to their sessions root folder).</p><p>The templates used in network sessions are in a hidden folder of the sessions root folder.</p></body></html> Template : FakeToolButton QToolButton
surclassed_widgets
RaySession-0.12.2/resources/ui/ray_to_nsm.ui000066400000000000000000000102241417052567600210470ustar00rootroot00000000000000 Dialog 0 0 399 342 convert to NSM file format Qt::Vertical 20 40 <html><head/><body><p>This script will convert a session to the NSM file format.<br/>This way, you will be able to open it with <span style=" font-weight:600;">New Session Manager</span>,<br/><span style=" font-weight:600;">Non Session Manager</span> or <span style=" font-weight:600;">Agordejo</span>, you will still can open it<br/>with <span style=" font-weight:600;">RaySession</span>.</p><p>Note that some specifics things will change :</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">All client projects will be named with their client name<br/>and not with the session name.</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Allmost JACK clients will have a longer name,<br/>containing the client_id.</li></ul></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false Qt::Vertical 20 40 <html><head/><body><p>jackpatch is the program in the session which<br/>remembers and connects JACK connections.<br/><br/>If this option is enabled, the session will replace ray-jackpatch<br/>with jackpatch (the NSM one), else session will works only if<br/>RaySession is installed.</p></body></html> Use NSM jackpatch true Qt::Horizontal QDialogButtonBox::Cancel buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/raysession.ui000066400000000000000000001615571417052567600211140ustar00rootroot00000000000000 MainWindow 0 0 1126 723 0 0 Qt::CustomContextMenu RaySession true QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks|QMainWindow::VerticalTabs true 0 0 16777215 16777215 0 0 0 0 0 Qt::Horizontal 0 true 0 QLayout::SetMaximumSize Qt::Vertical 0 QLayout::SetMaximumSize 0 false 201 0 480 16777215 SessionFrame{background-color: rgba(127, 127, 127, 35);border-radius:4px} 3 3 3 3 2 0 QToolButton::menu-indicator{ image: url(none.jpg);} QToolButton {border: none} ... .. QToolButton{border:none} ... .. true false QToolButton{border:none} Qt::Horizontal 0 20 0 0 16777215 16777215 0 -1 Qt::Horizontal 0 20 QToolButton{border: none} ... ../../../.designer/backup../../../.designer/backup 22 22 0 0 22 22 22 22 <html><head/><body><p>Save &amp; Close Session</p></body></html> QToolButton::menu-indicator{ image: url(none.jpg);} QToolButton {border: none} ... ../../../.designer/backup../../../.designer/backup 22 22 QToolButton::menu-indicator{ image: url(none.jpg);} QToolButton {border: none} ... .. Qt::Vertical QSizePolicy::Fixed 20 2 4 2 0 0 0 0 0 0 0 Qt::Horizontal QSizePolicy::Fixed 4 20 false 32 32 Open Session Folder QToolButton{border: none} ... ../../../.designer/backup../../../.designer/backup 32 32 Qt::Horizontal QSizePolicy::Fixed 4 20 Favorite Applications QToolButton::menu-indicator{ image: url(none.jpg);} QToolButton {border: none} ... :/scalable/breeze/star-yellow.svg:/scalable/breeze/star-yellow.svg 0 0 3200 32 Run Command QToolButton{margin:0px} Application ../../../.designer/backup../../../.designer/backup 22 22 Qt::ToolButtonTextBesideIcon Qt::Horizontal QSizePolicy::Preferred 6 20 0 0 3200 32 Run Command QToolButton{margin:0px} Executable ../../../.designer/backup../../../.designer/backup 22 22 Qt::ToolButtonTextBesideIcon 0 0 Qt::Horizontal QSizePolicy::MinimumExpanding 0 20 32 32 <html><head/><body><p>Go back to a previous state of the session.</p></body></html> QToolButton { border: none} Snapshots :/scalable/breeze/document-save.svg:/scalable/breeze/document-save.svg 16 16 60 0 60 16777215 Qt::NoContextMenu Server Status off Qt::AlignCenter true 32 32 Save Session QToolButton { border: none} Save Session :/scalable/breeze/document-save.svg:/scalable/breeze/document-save.svg 32 32 Qt::Horizontal QSizePolicy::Fixed 7 20 <html><head/><body><p>Trash</p><p>You will find here removed clients.</p></body></html> QToolButton::menu-indicator{ image: url(none.jpg);} QToolButton {border: none} ... ../../../.designer/backup../../../.designer/backup true QFrame{border:none} QAbstractScrollArea::AdjustToContentsOnFirstShow true QAbstractItemView::InternalMove QAbstractItemView::SingleSelection false 80 Qt::Vertical QSizePolicy::Fixed 20 3 0 0 0 30 480 16777215 QPlainTextEdit { font-size: 12px;border-radius:4px} true 0 0 0 20 0 -1 0 QGraphicsView{border:none} QAbstractScrollArea::AdjustToContents QGraphicsView::AnchorUnderMouse QGraphicsView::NoAnchor QFrame{border:none} QFrame::StyledPanel QFrame::Raised 0 0 1126 30 Fi&le &Recent sessions .. &Utilities .. &Session &View &Help Add Options 0 0 Qt::NoContextMenu toolBar false Qt::ToolButtonTextBesideIcon false TopToolBarArea false true ../../../.designer/backup../../../.designer/backup &Show Messages Ctrl+L false ../../../.designer/backup../../../.designer/backup &Save Ctrl+S Qt::ApplicationShortcut ../../../.designer/backup../../../.designer/backup &Open Session Ctrl+O ../../../.designer/backup../../../.designer/backup &New Session Ctrl+N ../../../.designer/backup../../../.designer/backup &Quit Ctrl+Q :/48x48/raysession.png:/48x48/raysession.png &About Ray Session true true ../../../.designer/backup../../../.designer/backup Show &Menu Bar Ctrl+M ../../../.designer/backup../../../.designer/backup Control Control false :/scalable/breeze/window-close.svg :/scalable/breeze/disabled/window-close.svg:/scalable/breeze/window-close.svg &Close Save and Close Session Ctrl+W false :/scalable/breeze/list-remove.svg :/scalable/breeze/disabled/list-remove.svg :/scalable/breeze/list-remove.svg:/scalable/breeze/list-remove.svg &Abort Abort Current Session Ctrl+Shift+W true ../../../.designer/backup../../../.designer/backup &Open Session Folder Open session folder with file manager true true ../../../.designer/backup../../../.designer/backup &Keep focus while opening clients Ctrl+H About &Qt false :/scalable/breeze/xml-node-duplicate.svg:/scalable/breeze/xml-node-duplicate.svg &Duplicate <html><head/><body><p>Duplicate the current session</p></body></html> Ctrl+D ../../../.designer/backup../../../.designer/backup &Executable Add executable to current session Ctrl+E Qt::WindowShortcut ../../../.designer/backup../../../.designer/backup Sa&ve As Template Save current session as template ../../../.designer/backup../../../.designer/backup &Application Add application to current session Ctrl+A false .. &Rename true true .. &Provide bookmarks for session folder true :/scalable/breeze/view-list-icons.svg:/scalable/breeze/view-list-icons.svg &Desktops Memory (requires wmctrl) false .. Return To A &Previous State (requires git) true true .. &Auto Snapshot At Save (requires git) Auto Snapshot at Save (requires git) .. &Donate true .. &Session Scripts Run the session scripts inside the directory ray-scripts true .. &Remember optional GUI states Remember if optional GUIs were shown .. &Edit Session Notes .. Make &reappear all dialog windows ../../../.designer/backup../../../.designer/backup Save as Template the current session Save current session as template false :/scalable/breeze/xml-node-duplicate.svg:/scalable/breeze/xml-node-duplicate.svg Duplicate the current session <html><head/><body><p>Duplicate the current session</p></body></html> Ctrl+D false .. Rename the current session .. &Online Manual Open the online manual in the web browser .. &Internal Manual Displays internal manual in a web browser true .. Show &JACK patchbay Ctrl+J :/scalable/raysession.svg:/scalable/raysession.svg System tray &icon options ezf .. Convert an &Ardour session to a Ray session .. Convert all &Hydrogen Ray-Hack clients to NSM .. Convert all &Jack Mixer Ray-Hack clients to NSM .. Convert &session to NSM file format SessionFrame QFrame
surclassed_widgets
1
ListWidgetClients QListWidget
list_widget_clients
StatusBarNegativ QLineEdit
surclassed_widgets
StackedSessionName QStackedWidget
surclassed_widgets
1
DraggableGraphicsView QGraphicsView
surclassed_widgets
CanvasSplitter QSplitter
surclassed_widgets
1
CanvasFilterFrame QFrame
canvas_filter_frame
1
actionShowMenuBar toggled(bool) menuBar setVisible(bool) -1 -1 251 12
RaySession-0.12.2/resources/ui/remove_template.ui000066400000000000000000000044541417052567600220750ustar00rootroot00000000000000 Dialog Qt::NonModal 0 0 342 72 Remove Template ? false <html><head/><body><p>Are you sure to want to remove this template ?</p></body></html> Qt::AlignCenter Remove .. Cancel .. pushButtonCancel clicked() Dialog reject() 326 120 187 79 pushButtonRemove clicked() Dialog accept() 87 47 170 35 RaySession-0.12.2/resources/ui/save_template_session.ui000066400000000000000000000123521417052567600232750ustar00rootroot00000000000000 DialogSaveTemplateSession Qt::NonModal 0 0 371 162 New Template false 0 0 Session : ... 48 48 75 true Client Label Qt::Horizontal Qt::Vertical 20 40 0 0 Session Template Name : 0 0 Qt::Vertical 20 40 QLayout::SetFixedSize Qt::Horizontal QSizePolicy::Expanding 40 20 0 0 Create Template .. 0 0 Cancel .. FakeToolButton QToolButton
surclassed_widgets
pushButtonCancel clicked() DialogSaveTemplateSession reject() 240 88 144 55
RaySession-0.12.2/resources/ui/script_info.ui000066400000000000000000000031311417052567600212130ustar00rootroot00000000000000 Dialog 0 0 372 161 Script Info Script info text true Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/script_user_action.ui000066400000000000000000000040331417052567600225750ustar00rootroot00000000000000 Dialog 0 0 372 161 Script User Action Info Label <html><head/><body><p><hr/></p></body></html> Script user action text. Are you ready ? true Qt::Horizontal QDialogButtonBox::Ignore|QDialogButtonBox::Yes buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/session_notes.ui000066400000000000000000000024501417052567600215720ustar00rootroot00000000000000 Dialog 0 0 519 446 Dialog 0 0 Notes of session : 75 true Session name RaySession-0.12.2/resources/ui/session_scripts_info.ui000066400000000000000000000146341417052567600231530ustar00rootroot00000000000000 Dialog 0 0 502 565 Session Scripts Infos <html><head/><body><p>You create a session with the basic session scripts.<br/>If you don't know what a script is, or you have absolutely no knowledge in shell scripting, you don't belong here, get out of here right now.</p><p>While you've not edited the scripts, session will behave as a normal session.</p><p>You will find in the session folder a <span style=" font-style:italic;">ray-scripts</span> folder.<br/>In the <span style=" font-style:italic;">ray-scripts </span>folder you will find 3 files:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">load.sh</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">save.sh</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">close.sh</li></ul><p>In theses 3 scripts you can edit some actions to do before or after load, save, or close the session.<br/>If you don't need custom actions at one of theses 3 steps, you can safely remove its file.</p></body></html> true Qt::Vertical QSizePolicy::Fixed 20 6 0 0 Session Scripts Infos Session Scripts Infos true <!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" /><title>Session Scripts Infos</title><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Noto Sans'; font-size:10pt; 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;">Session scripts are located in the <span style=" font-style:italic;">ray-scripts</span> folder in the session folder, but they could also be located in a <span style=" font-style:italic;">ray-scripts</span> folder in a parent folder of the session folder.</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For example:</p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the scripts folder for this new session will be:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">But could just as well be:<br /><span style=" font-weight:600;">%s</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and thus apply to all sessions contained in <span style=" font-weight:600;">%s</span>.</p></body></html> Do not show this message again true Qt::Horizontal QDialogButtonBox::Abort|QDialogButtonBox::Ok checkBoxNotAgain buttonBox accepted() Dialog accept() 254 446 157 274 buttonBox rejected() Dialog reject() 322 446 286 274 RaySession-0.12.2/resources/ui/snapshot_and_save.ui000066400000000000000000000047041417052567600224020ustar00rootroot00000000000000 DialogQuitApp Qt::NonModal 0 0 401 159 Quit RaySession false <html><head/><body><p>Do you want to save the session before snapshot ?</p><p>Save is recommended,<br/>unless you made unwanted changes since the last session save.</p></body></html> Qt::AlignCenter Save && Snapshot .. Snapshot .. Cancel .. pushButtonCancel clicked() DialogQuitApp reject() 326 120 187 79 RaySession-0.12.2/resources/ui/snapshot_name.ui000066400000000000000000000066321417052567600215440ustar00rootroot00000000000000 Dialog 0 0 401 198 Name Snapshot Qt::Vertical 20 40 Snapshot Name : Qt::Vertical 20 40 <html><head/><body><p>You can save the session before the snapshot.</p><p>Save is recommended,<br/>unless you made unwanted changes since the last session save.</p></body></html> Qt::AlignCenter Save && Snapshot .. Snapshot Only .. Cancel .. pushButtonCancel clicked() Dialog reject() 334 173 200 98 pushButtonSnapshot clicked() Dialog accept() 210 173 200 98 RaySession-0.12.2/resources/ui/snapshot_progress.ui000066400000000000000000000070721417052567600224670ustar00rootroot00000000000000 Dialog 0 0 357 202 Abort Copy ? Qt::Vertical 20 40 <html><head/><body><p>Snapshot process seems to be long.<br/>Maybe your session's folder contains too many new files<br/>whose extension is not ignored.</p><p>You can abort this snapshot,<br/>it will de-activate snapshots for this session.</p></body></html> 0 Qt::Vertical 20 40 Qt::Horizontal 40 20 Abort Snapshot .. Cancel .. pushButtonCancel clicked() Dialog reject() 198 92 124 58 pushButtonAbort clicked() Dialog accept() 98 92 124 58 RaySession-0.12.2/resources/ui/snapshots_info.ui000066400000000000000000000051501417052567600217340ustar00rootroot00000000000000 Dialog 0 0 403 300 Snapshots Informations <html><head/><body><p>Snapshots are NOT backups !!!</p><p>Besides, It's not overrated to copy your session folder elsewhere<br/>before to ask a previous snapshot.</p><p>Snapshots ignore audio files and other big files (&gt;50Mb),<br/>else snapshot process would be too long, <br/>and the session folder size would be too big.</p><p>That being said, you can decide that your work in the last hours<br/>was not a good idea and return to a previous snapshot !</p></body></html> Qt::Vertical 20 40 Do not show this message again true Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/startup_dialog.ui000066400000000000000000000150301417052567600217160ustar00rootroot00000000000000 Dialog 0 0 414 323 Previous session Qt::Horizontal 0 0 :/48x48/raysession.png <html><head/><body><p>Welcome to <span style=" font-weight:600;">RaySession</span> !</p></body></html> Qt::Horizontal Qt::Vertical QSizePolicy::MinimumExpanding 20 20 Qt::Vertical 20 40 New session .. Open session .. Qt::Vertical 20 40 Do you want to load this previous session ? 0 50 QListView::Fixed true Qt::Vertical QSizePolicy::MinimumExpanding 20 20 Display at startup true QDialogButtonBox::Cancel|QDialogButtonBox::Ok StartupDialogButtonBox QDialogButtonBox
surclassed_widgets
StartupDialogPushButtonNew QPushButton
surclassed_widgets
StartupDialogPushButtonOpen QPushButton
surclassed_widgets
buttonBox accepted() Dialog accept() 134 272 134 147 buttonBox rejected() Dialog reject() 134 272 134 147
RaySession-0.12.2/resources/ui/stop_client.ui000066400000000000000000000073251417052567600212300ustar00rootroot00000000000000 Dialog 0 0 315 159 Stop Client ? Qt::Vertical 20 40 <html><head/><body><p><span style=" font-weight:600;">%s</span> contains unsaved changes. </p><p>Do you really want to stop it ?</p></body></html> Qt::AlignCenter Qt::Vertical 20 40 Don't prevent to stop this client again ! Qt::Horizontal 40 20 Save && Stop .. Just Stop .. Cancel .. pushButtonClancel clicked() Dialog reject() 265 89 157 56 pushButtonStop clicked() Dialog accept() 172 89 157 56 RaySession-0.12.2/resources/ui/stop_client_no_save.ui000066400000000000000000000070131417052567600227340ustar00rootroot00000000000000 Dialog 0 0 400 172 Stop Client ? Qt::Vertical 20 40 <html><head/><body><p>We have no possibility to save the client <span style=" font-weight:600;">%s</span>.</p><p>For this reason, it's preferable that you close yourself this client,<br/>probably by closing its window, saving its changes or not.</p></body></html> Qt::AlignCenter Qt::Vertical 20 40 Don't prevent to stop this client again (discouraged) Qt::Horizontal 40 20 Stop Anyway .. Cancel .. pushButtonCancel clicked() Dialog reject() 265 89 157 56 pushButtonStop clicked() Dialog accept() 172 89 157 56 RaySession-0.12.2/resources/ui/systray_close.ui000066400000000000000000000050231417052567600216010ustar00rootroot00000000000000 Dialog 0 0 396 191 System Tray Qt::Vertical 20 40 Your session is still runing. RaySession will run in the background. You can make the window re-appear from your system tray. false Qt::Vertical 20 40 Do not show again true Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/systray_management.ui000066400000000000000000000070371417052567600226170ustar00rootroot00000000000000 Dialog 0 0 269 217 Tray Icon Options Pro&vide system tray icon true Only when session is running true Enable it if your systray is at bottom of the screen. Reversed menu order Qt::Vertical 20 40 <html><head/><body><p>Never ask what to do and close GUI process<br/>if you close RaySession while a session is running. </p><p>The session will still running and you just have<br/>to restart RaySession to manage it.</p><p>This method uses less RAM than<br/>keeping window in system tray.</p></body></html> Quit shutdowns the GUI Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 RaySession-0.12.2/resources/ui/template_slot.ui000066400000000000000000000057511417052567600215620ustar00rootroot00000000000000 Frame 0 0 369 33 Frame 4 2 4 2 QToolButton {border: none} ... 22 22 Template Name Qt::Horizontal 40 20 QToolButton::menu-indicator{ image: url(none.jpg);} QToolButton {border: none} ... :/scalable/breeze/im-user.svg:/scalable/breeze/im-user.svg QToolButton::InstantPopup QToolButton {border: none} ... :/scalable/breeze/draw-star.svg:/scalable/breeze/draw-star.svg FakeToolButton QToolButton
surclassed_widgets
FavoriteToolButton QToolButton
surclassed_widgets
RaySession-0.12.2/resources/ui/waiting_close_user.ui000066400000000000000000000117771417052567600226000ustar00rootroot00000000000000 Dialog 0 0 353 272 Close clients yourself ! <html><head/><body><p align="center">Some active clients do not offer any save possibility !</p><p align="center">Therefore, it is best that you close these clients yourself,<br/>probably by closing their windows and saving changes.</p><p align="center"><span style=" font-weight:600;">Please close yourself the programs with this save icon:</span></p></body></html> Qt::Horizontal 40 20 :/scalable/breeze/document-nosave.svg Qt::Horizontal 40 20 Qt::Vertical 20 40 <html><head/><body><p>You've got 2 minutes !<br/><span style=" font-style:italic;">You can do it without closing this dialog window.</span></p></body></html> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Vertical 20 40 Do not show again Qt::Horizontal 40 20 Undo .. Ok .. Skip .. pushButtonOk clicked() Dialog accept() 213 239 176 131 RaySession-0.12.2/resources/ui/zoom_slider.ui000066400000000000000000000033161417052567600212270ustar00rootroot00000000000000 Form 0 0 102 44 Form 0 2 2 9 100 % Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing QSlider:handle{ background-color: #55999999; border-radius:4px; } 20 300 100 Qt::Horizontal QSlider::TicksBelow 80 RaySession-0.12.2/session_scripts/000077500000000000000000000000001417052567600171425ustar00rootroot00000000000000RaySession-0.12.2/session_scripts/base scripts/000077500000000000000000000000001417052567600215245ustar00rootroot00000000000000RaySession-0.12.2/session_scripts/base scripts/ray-scripts000077700000000000000000000000001417052567600341312../../session_templates/scripted/ray-scriptsustar00rootroot00000000000000RaySession-0.12.2/session_scripts/save_jack_config/000077500000000000000000000000001417052567600224155ustar00rootroot00000000000000RaySession-0.12.2/session_scripts/save_jack_config/ray-scripts000077700000000000000000000000001417052567600364752../../session_templates/with_jack_config/ray-scriptsustar00rootroot00000000000000RaySession-0.12.2/session_scripts/save_via_window/000077500000000000000000000000001417052567600223265ustar00rootroot00000000000000RaySession-0.12.2/session_scripts/save_via_window/ray-scripts/000077500000000000000000000000001417052567600246065ustar00rootroot00000000000000RaySession-0.12.2/session_scripts/save_via_window/ray-scripts/save.sh000077500000000000000000000023331417052567600261040ustar00rootroot00000000000000#!/bin/bash ######################################################################## # # # Here you can edit the script runned each time the session is saved # # # # You have access the following environment variables # # RAY_SESSION_PATH : Folder of the current session # # RAY_SCRIPTS_DIR : Folder containing this script # # ray-scripts folder can be directly in current session # # or in a parent folder # # RAY_PARENT_SCRIPT_DIR : Folder containing the scripts that would # # be runned if RAY_SCRIPTS_DIR would not exists # # # # To get any other session informations, refers to ray_control help # # typing: ray_control --help # # # ######################################################################## "$RAY_SCRIPTS_DIR/save_via_windows.sh" ray_control run_step RaySession-0.12.2/session_scripts/save_via_window/ray-scripts/save_via_windows.sh000066400000000000000000000015231417052567600305120ustar00rootroot00000000000000#!/bin/bash for executable in xdotool;do if ! which "$executable" >/dev/null;then exit fi done [ -n "$WAYLAND_DISPLAY" ] && exit start_win=$(xdotool getactivewindow) focus_changed=false for client_id in `ray_control list_clients no_save_level`;do executable_line="$(ray_control client $client_id get_proxy_properties|grep ^executable:)" executable="$(basename "${executable_line#*:}")" [ -n "$executable" ] || continue wins=$(xdotool search --class "$executable") for windowid in $wins;do if [[ "$(xdotool getwindowname "$windowid")" ~= "*" ]];then focus_changed=true xdotool windowactivate "$windowid" xdotool key ctrl+s break fi done done if $focus_changed;then xdotool windowactivate "$start_win" fi exit 0 RaySession-0.12.2/session_scripts/slow_open/000077500000000000000000000000001417052567600211475ustar00rootroot00000000000000RaySession-0.12.2/session_scripts/slow_open/ray-scripts/000077500000000000000000000000001417052567600234275ustar00rootroot00000000000000RaySession-0.12.2/session_scripts/slow_open/ray-scripts/load.sh000066400000000000000000000042441417052567600247060ustar00rootroot00000000000000#!/bin/bash ######################################################################## # # # Here you can edit the script runned # # each time daemon order this session to be loaded # # WARNING: You can be here in a switch situation, # # some clients may be still alive # # if they are NSM compatible and capable of switch # # or if they are not NSM compatible at all # # and launched directly (not via proxy) # # # # You have access the following environment variables # # RAY_SESSION_PATH : Folder of the current session # # RAY_SCRIPTS_DIR : Folder containing this script # # ray-scripts folder can be directly in current session # # or in a parent folder. # # RAY_PARENT_SCRIPT_DIR : Folder containing the scripts that would # # be runned if RAY_SCRIPTS_DIR would not exists # # # # RAY_SWITCHING_SESSION: 'true' or 'false' # # 'true' if session is switching from another session # # and probably some clients are still alive. # # # # To get any other session informations, refers to ray_control help # # typing: ray_control --help # # # ######################################################################## # Load the session without start any client ray_control run_step open_off # Start all clients supposed to be started at session load # But each time, wait the client to be ready to start the next for client_id in ray_control list_clients auto_start;do ray_control client "$client_id" open done RaySession-0.12.2/session_templates/000077500000000000000000000000001417052567600174515ustar00rootroot00000000000000RaySession-0.12.2/session_templates/scripted/000077500000000000000000000000001417052567600212665ustar00rootroot00000000000000RaySession-0.12.2/session_templates/scripted/ray-scripts/000077500000000000000000000000001417052567600235465ustar00rootroot00000000000000RaySession-0.12.2/session_templates/scripted/ray-scripts/close.sh000077500000000000000000000046321417052567600252170ustar00rootroot00000000000000#!/bin/bash ######################################################################## # # # Here you can edit the script runned # # each time daemon order this session to be closed # # WARNING: You can be here in a switch situation, # # a session can be opened just after. # # # # You have access the following environment variables # # RAY_SESSION_PATH : Folder of the current session # # RAY_FUTURE_SESSION_PATH: Folder of the session that will be opened # # just after current session close. # # RAY_SCRIPTS_DIR : Folder containing this script # # ray-scripts folder can be directly in current session # # or in a parent folder. # # RAY_PARENT_SCRIPT_DIR : Folder containing the scripts that would # # be runned if RAY_SCRIPTS_DIR would not exists # # RAY_SWITCHING_SESSION: 'true' or 'false' # # 'true' if session is switching from another session # # and probably some clients are still alive. # # # # To get any other session informations, refers to ray_control help # # typing: ray_control --help # # # ######################################################################## # script here some actions to run before closing the session. # some clients may keep alive because # they are needed by the session to open just after. # if for some reasons you want all clients to stop # set this variable true ! close_all_clients=false if $close_all_clients;then # This command orders to ray-daemon to close the session closing all clients # even if a session has to be opened just after. ray_control run_step close_all else # This command orders to ray-daemon to close the session # If you don't run it, session will be closed after running the script ray_control run_step fi # script here some actions to run once the session is closed RaySession-0.12.2/session_templates/scripted/ray-scripts/load.sh000077500000000000000000000043501417052567600250260ustar00rootroot00000000000000#!/bin/bash ######################################################################## # # # Here you can edit the script runned # # each time daemon order this session to be loaded # # WARNING: You can be here in a switch situation, # # some clients may be still alive # # if they are NSM compatible and capable of switch, # # or if they are not NSM compatible at all # # but launched with NSM protocol and not via proxy # # # # You have access the following environment variables # # RAY_SESSION_PATH : Folder of the current session # # RAY_SCRIPTS_DIR : Folder containing this script # # ray-scripts folder can be directly in current session # # or in a parent folder. # # RAY_PARENT_SCRIPT_DIR : Folder containing the scripts that would # # be runned if RAY_SCRIPTS_DIR would not exists # # RAY_SWITCHING_SESSION: 'true' or 'false' # # 'true' if session is switching from another session # # and probably some clients are still alive. # # # # To get any other session informations, refers to ray_control help # # typing: ray_control --help # # # ######################################################################## # script here some actions to run before loading the session. # set this var true if you want all running clients to stop (see top of this file). clear_all_clients=false if $clear_all_clients;then ray_control script_info "Clearing clients..." ray_control clear_clients ray_control hide_script_info fi # order daemon to load the session ray_control run_step # script here some actions to run once the session is loaded. RaySession-0.12.2/session_templates/scripted/ray-scripts/save.sh000077500000000000000000000026231417052567600250460ustar00rootroot00000000000000#!/bin/bash ######################################################################## # # # Here you can edit the script runned each time the session is saved # # # # You have access the following environment variables # # RAY_SESSION_PATH : Folder of the current session # # RAY_SCRIPTS_DIR : Folder containing this script # # ray-scripts folder can be directly in current session # # or in a parent folder # # RAY_PARENT_SCRIPT_DIR : Folder containing the scripts that would # # be runned if RAY_SCRIPTS_DIR would not exists # # # # To get any other session informations, refers to ray_control help # # typing: ray_control --help # # # ######################################################################## # script here some actions to run before saving the session # This command orders to ray-daemon to save the session # If you don't run it, session won't be saved ray_control run_step # script here some actions to run after saving the session RaySession-0.12.2/session_templates/scripted/raysession.xml000066400000000000000000000002701417052567600242060ustar00rootroot00000000000000 RaySession-0.12.2/session_templates/with_jack_config/000077500000000000000000000000001417052567600227415ustar00rootroot00000000000000RaySession-0.12.2/session_templates/with_jack_config/ray-scripts/000077500000000000000000000000001417052567600252215ustar00rootroot00000000000000RaySession-0.12.2/session_templates/with_jack_config/ray-scripts/.directory000066400000000000000000000002001417052567600272160ustar00rootroot00000000000000[Dolphin] GroupedSorting=true SortRole=modificationtime Timestamp=2020,5,6,16,33,50 Version=4 [Settings] HiddenFilesShown=true RaySession-0.12.2/session_templates/with_jack_config/ray-scripts/.jack_config_script000066400000000000000000000003261417052567600310440ustar00rootroot00000000000000# This file is used by the script only to know if the session should be managed by the script # Do not remove it, else "switch" from one session to another could result in stop and start jack when it's not needed. RaySession-0.12.2/session_templates/with_jack_config/ray-scripts/close.sh000077500000000000000000000050441417052567600266700ustar00rootroot00000000000000#!/bin/bash ######################################################################## # # # Here you can edit the script runned # # each time daemon order this session to be closed # # WARNING: You can be here in a switch situation, # # a session can be opened just after. # # # # You have access the following environment variables # # RAY_SESSION_PATH : Folder of the current session # # RAY_FUTURE_SESSION_PATH: Folder of the session that will be opened # # just after current session close. # # RAY_SCRIPTS_DIR : Folder containing this script # # ray-scripts folder can be directly in current session # # or in a parent folder. # # RAY_PARENT_SCRIPT_DIR : Folder containing the scripts that would # # be runned if RAY_SCRIPTS_DIR would not exists # # RAY_SWITCHING_SESSION: 'true' or 'false' # # 'true' if session is switching from another session # # and probably some clients are still alive. # # # # To get any other session informations, refers to ray_control help # # typing: ray_control --help # # # ######################################################################## # set it to 'false' if you want the script # not to handle the ports of the PulseAudio -> JACK bridge export RAY_MANAGE_PULSEAUDIO=true # set it to 'false' if you want the script # if you want the script to trust the parameters of JACK export RAY_JACK_RELIABILITY_CHECK=true # set it to 'false' if you want the script to not consider hostname # then, a session can not be open on another machine # if it doesn't have the same sound interface export RAY_HOSTNAME_SENSIBLE=true close_all_if_needed='' if [[ "$RAY_FUTURE_SCRIPTS_DIR" != "$RAY_SCRIPTS_DIR" ]] &&\ ! [ -f "$RAY_FUTURE_SCRIPTS_DIR/.jack_config_script" ];then close_all_if_needed=close_all fi ray_control run_step $close_all_if_needed if [ -n "$close_all_if_needed" ];then ray-jack_config_script putback && ray_control hide_script_info fi exit 0 RaySession-0.12.2/session_templates/with_jack_config/ray-scripts/load.sh000077500000000000000000000045461417052567600265100ustar00rootroot00000000000000#!/bin/bash ######################################################################## # # # Here you can edit the script runned # # each time daemon order this session to be loaded # # WARNING: You can be here in a switch situation, # # some clients may be still alive # # if they are NSM compatible and capable of switch, # # or if they are not NSM compatible at all # # but launched with NSM protocol and not via proxy # # # # You have access the following environment variables # # RAY_SESSION_PATH : Folder of the current session # # RAY_SCRIPTS_DIR : Folder containing this script # # ray-scripts folder can be directly in current session # # or in a parent folder. # # RAY_PARENT_SCRIPT_DIR : Folder containing the scripts that would # # be runned if RAY_SCRIPTS_DIR would not exists # # RAY_SWITCHING_SESSION: 'true' or 'false' # # 'true' if session is switching from another session # # and probably some clients are still alive. # # # # To get any other session informations, refers to ray_control help # # typing: ray_control --help # # # ######################################################################## # set it to 'false' if you want the script # not to handle the ports of the PulseAudio -> JACK bridge export RAY_MANAGE_PULSEAUDIO=true # set it to 'false' if you want the script # if you want the script to trust the parameters of JACK export RAY_JACK_RELIABILITY_CHECK=true # set it to 'false' if you want the script to not consider hostname # then, a session can not be open on another machine # if it doesn't have the same sound interface export RAY_HOSTNAME_SENSIBLE=true ray-jack_config_script load || exit 0 ray_control hide_script_info ray_control run_step RaySession-0.12.2/session_templates/with_jack_config/ray-scripts/save.sh000077500000000000000000000032651417052567600265240ustar00rootroot00000000000000#!/bin/bash ######################################################################## # # # Here you can edit the script runned each time the session is saved # # # # You have access the following environment variables # # RAY_SESSION_PATH : Folder of the current session # # RAY_SCRIPTS_DIR : Folder containing this script # # ray-scripts folder can be directly in current session # # or in a parent folder # # RAY_PARENT_SCRIPT_DIR : Folder containing the scripts that would # # be runned if RAY_SCRIPTS_DIR would not exists # # # # To get any other session informations, refers to ray_control help # # typing: ray_control --help # # # ######################################################################## # set it to 'false' if you want the script # not to handle the ports of the PulseAudio -> JACK bridge export RAY_MANAGE_PULSEAUDIO=true # set it to 'false' if you want the script # if you want the script to trust the parameters of JACK export RAY_JACK_RELIABILITY_CHECK=true # set it to 'false' if you want the script to not consider hostname # then, a session can not be open on another machine # if it doesn't have the same sound interface export RAY_HOSTNAME_SENSIBLE=true ray-jack_config_script save ray_control run_step exit 0 RaySession-0.12.2/session_templates/with_jack_config/raysession.xml000066400000000000000000000004761417052567600256710ustar00rootroot00000000000000 RaySession-0.12.2/session_templates/with_jack_patch/000077500000000000000000000000001417052567600225735ustar00rootroot00000000000000RaySession-0.12.2/session_templates/with_jack_patch/raysession.xml000066400000000000000000000004761417052567600255230ustar00rootroot00000000000000 RaySession-0.12.2/src/000077500000000000000000000000001417052567600144775ustar00rootroot00000000000000RaySession-0.12.2/src/bin/000077500000000000000000000000001417052567600152475ustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray-daemon000077700000000000000000000000001417052567600233052../daemon/ray-daemon.pyustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray-jack_checker_daemon000077700000000000000000000000001417052567600322222../jack_config_script/jack_checker_daemon.pyustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray-jack_config_script000077700000000000000000000000001417052567600312372../jack_config_script/script_starter.shustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray-jackpatch000077700000000000000000000000001417052567600266052../clients/jackpatch/ray-jackpatch.pyustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray-jackpatch-mon000077700000000000000000000000001417052567600322022../clients/jackpatch_monitor_test/ray-jackpatch.pyustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray-jackpatch_to_osc000077700000000000000000000000001417052567600322612../jack_patchbay_to_osc/ray-jackpatch_to_osc.pyustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray-network000077500000000000000000000000561417052567600174600ustar00rootroot00000000000000#!/bin/bash exec raysession --out-daemon "$@" RaySession-0.12.2/src/bin/ray-proxy000077700000000000000000000000001417052567600245202../clients/proxy/ray-proxy.pyustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray-pulse2jack000077700000000000000000000000001417052567600307622../jack_config_script/reconfigure-pulse2jack.shustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray_control000077700000000000000000000000001417052567600243202../control/ray_control.pyustar00rootroot00000000000000RaySession-0.12.2/src/bin/ray_git000077500000000000000000000001151417052567600166300ustar00rootroot00000000000000#!/bin/sh exec git --work-tree "$PWD" --git-dir "$PWD/.ray-snapshots" "$@" RaySession-0.12.2/src/bin/raysession000077700000000000000000000000001417052567600231342../gui/raysession.pyustar00rootroot00000000000000RaySession-0.12.2/src/bin/sooperlooper_lash000077700000000000000000000000001417052567600310122../clients/sooperlooper/sooperlooper_lashustar00rootroot00000000000000RaySession-0.12.2/src/bin/sooperlooper_nsm000077700000000000000000000000001417052567600311552../clients/sooperlooper/sooperlooper_nsm.pyustar00rootroot00000000000000RaySession-0.12.2/src/bin/utility_script_keeper.sh000077500000000000000000000003311417052567600222250ustar00rootroot00000000000000#!/bin/bash message="Press any key to close this terminal" case $LANG in fr_*) message="Appuyez sur n'importe quelle touche pour fermer ce terminal" ;; esac "$@" && read -n 1 -s -r -p "$message" RaySession-0.12.2/src/bin/utility_script_starter.sh000066400000000000000000000027501417052567600224420ustar00rootroot00000000000000#!/bin/bash terminal_title="Ray utility script" if [[ "$1" == "--terminal-title" ]];then shift terminal_title="$1" shift fi script="$1" shift main_command="$(dirname "$(dirname "$(dirname "$BASH_SOURCE")")")/scripts/$script" echo "$command" terminals="" # get the terminal to launch with the desktop environment case $XDG_CURRENT_DESKTOP in GNOME ) terminals=gnome-terminal ;; KDE ) terminals=konsole ;; MATE ) terminals=mate-terminal ;; XFCE ) terminals="xfce-terminal xfce4-terminal" ;; LXDE ) terminals=lxterminal ;; esac terminals="${terminals} gnome-terminal mate-terminal xfce4-terminal xterm konsole lxterminal rxvt" terminal="" for term in $terminals; do if which $term > /dev/null;then terminal="$term" break fi done if [ -z "$terminal" ];then echo "No terminal found, abort." >2 exit 1 fi # execute the good terminal with good arguments case $terminal in gnome-terminal ) gnome-terminal --hide-menubar -- "$main_command" "$@" ;; konsole ) konsole --hide-tabbar --hide-menubar -p tabtitle="$terminal_title" -e "$main_command" "$@" ;; mate-terminal ) mate-terminal --hide-menubar --title "$terminal_title" -- "$main_command" "$@" ;; xfce4-terminal ) xfce4-terminal --hide-menubar --hide-toolbar -T "$terminal_title" -e "$main_command" "$@" ;; * ) $terminal -e "$main_command" "$@" ;; esac RaySession-0.12.2/src/clean_lines.sh000077500000000000000000000004761417052567600173210ustar00rootroot00000000000000#!/bin/bash cd $(dirname "$0") for py_file in daemon/*.py gui/*.py gui/patchcanvas/*.py ;do case "$py_file" in ui_*.py|resources_rc.py) continue esac [ -f "$py_file" ] || continue [ -L "$py_file" ] && continue echo "clean file: $py_file" sed -i 's/ *$//' "$py_file" done RaySession-0.12.2/src/clients/000077500000000000000000000000001417052567600161405ustar00rootroot00000000000000RaySession-0.12.2/src/clients/jackpatch/000077500000000000000000000000001417052567600200705ustar00rootroot00000000000000RaySession-0.12.2/src/clients/jackpatch/jacklib.py000077700000000000000000000000001417052567600257012../../shared/jacklib.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/jackpatch/nsm_client.py000077700000000000000000000000001417052567600271712../../shared/nsm_client.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/jackpatch/ray-jackpatch.py000077500000000000000000000350521417052567600231730ustar00rootroot00000000000000#!/usr/bin/python3 -u import os import signal import sys from PyQt5.QtCore import QCoreApplication, QObject, QTimer, pyqtSignal from PyQt5.QtXml import QDomDocument #from shared import * import jacklib import nsm_client import ray connection_list = [] saved_connections = [] port_list = [] PORT_MODE_OUTPUT = 0 PORT_MODE_INPUT = 1 PORT_MODE_NULL = 2 PORT_TYPE_AUDIO = 0 PORT_TYPE_MIDI = 1 PORT_TYPE_NULL = 2 file_path = "" is_dirty = False pending_connection = False def signalHandler(sig, frame): if sig in (signal.SIGINT, signal.SIGTERM): app.quit() class JackPort: #is_new is used to prevent reconnections # when a disconnection has not been saved and one new port append. id = 0 name = '' mode = PORT_MODE_NULL type = PORT_TYPE_NULL is_new = False class ConnectTimer(QObject): def __init__(self): self.timer = QTimer() self.timer.setInterval(200) self.timer.setSingleShot(True) self.timer.timeout.connect(makeMayConnections) def start(self): self.timer.start() def portExists(name, mode): for port in port_list: if port.name == name and port.mode == mode: return True return False def setDirtyClean(): global is_dirty is_dirty = False NSMServer.sendDirtyState(False) def timerDirtyFinish(): global is_dirty if is_dirty: return if isDirtyNow(): is_dirty = True NSMServer.sendDirtyState(True) def isDirtyNow(): for connection in connection_list: if not connection in saved_connections: return True output_ports = [] input_ports = [] for port in port_list: if port.mode == PORT_MODE_OUTPUT: output_ports.append(port.name) elif port.mode == PORT_MODE_INPUT: input_ports.append(port.name) for connection in saved_connections: if connection in connection_list: continue if connection[0] in output_ports and connection[1] in input_ports: return True return False class DirtyChecker(QObject): timer = QTimer() def __init__(self): self.timer.setInterval(500) self.timer.setSingleShot(True) self.timer.timeout.connect(timerDirtyFinish) def start(self): self.timer.start() def readyToConnect(): pass class Signaler(nsm_client.NSMSignaler): port_added = pyqtSignal(str, int, int) port_removed = pyqtSignal(str, int, int) port_renamed = pyqtSignal(str, str, int, int) connection_added = pyqtSignal(str, str) connection_removed = pyqtSignal(str, str) def JackShutdownCallback(arg=None): app.quit() return 0 def JackPortRegistrationCallback(portId, registerYesNo, arg=None): portPtr = jacklib.port_by_id(jack_client, portId) portFlags = jacklib.port_flags(portPtr) port_name = str(jacklib.port_name(portPtr), encoding="utf-8") port_mode = PORT_MODE_NULL if portFlags & jacklib.JackPortIsInput: port_mode = PORT_MODE_INPUT elif portFlags & jacklib.JackPortIsOutput: port_mode = PORT_MODE_OUTPUT port_type = PORT_TYPE_NULL portTypeStr = str(jacklib.port_type(portPtr), encoding="utf-8") if portTypeStr == jacklib.JACK_DEFAULT_AUDIO_TYPE: port_type = PORT_TYPE_AUDIO elif portTypeStr == jacklib.JACK_DEFAULT_MIDI_TYPE: port_type = PORT_TYPE_MIDI if registerYesNo: signaler.port_added.emit(port_name, port_mode, port_type) else: signaler.port_removed.emit(port_name, port_mode, port_type) return 0 def JackPortRenameCallback(portId, oldName, newName, arg=None): portPtr = jacklib.port_by_id(jack_client, portId) portFlags = jacklib.port_flags(portPtr) port_mode = PORT_MODE_NULL if portFlags & jacklib.JackPortIsInput: port_mode = PORT_MODE_INPUT elif portFlags & jacklib.JackPortIsOutput: port_mode = PORT_MODE_OUTPUT port_type = PORT_TYPE_NULL portTypeStr = str(jacklib.port_type(portPtr), encoding="utf-8") if portTypeStr == jacklib.JACK_DEFAULT_AUDIO_TYPE: port_type = PORT_TYPE_AUDIO elif portTypeStr == jacklib.JACK_DEFAULT_MIDI_TYPE: port_type = PORT_TYPE_MIDI signaler.port_renamed.emit(str(oldName, encoding='utf-8'), str(newName, encoding='utf-8'), port_mode, port_type) return 0 def JackPortConnectCallback(port_id_A, port_id_B, connect_yesno, arg=None): port_ptr_A = jacklib.port_by_id(jack_client, port_id_A) port_ptr_B = jacklib.port_by_id(jack_client, port_id_B) port_str_A = str(jacklib.port_name(port_ptr_A), encoding="utf-8") port_str_B = str(jacklib.port_name(port_ptr_B), encoding="utf-8") if connect_yesno: signaler.connection_added.emit(port_str_A, port_str_B) else: signaler.connection_removed.emit(port_str_A, port_str_B) return 0 def portAdded(port_name, port_mode, port_type): port = JackPort() port.name = port_name port.mode = port_mode port.type = port_type port.is_new = True port_list.append(port) connect_timer.start() def portRemoved(port_name, port_mode, port_type): for i in range(len(port_list)): port = port_list[i] if (port.name == port_name and port.mode == port_mode and port.type == port_type): break else: return port_list.__delitem__(i) def portRenamed(old_name, new_name, port_mode, port_type): for port in port_list: if (port.name == old_name and port.mode == port_mode and port.type == port_type): port.name = new_name port.is_new = True connect_timer.start() break def connectionAdded(port_str_A, port_str_B): connection_list.append((port_str_A, port_str_B)) if pending_connection: makeMayConnections() if (port_str_A, port_str_B) not in saved_connections: dirty_checker.start() def connectionRemoved(port_str_A, port_str_B): for i in range(len(connection_list)): if (connection_list[i][0] == port_str_A and connection_list[i][1] == port_str_B): connection_list.__delitem__(i) break dirty_checker.start() def makeAllSavedConnections(port): if port.mode == PORT_MODE_OUTPUT: connectAllInputs(port) elif port.mode == PORT_MODE_INPUT: connectAllOutputs(port) def connectAllInputs(port): if port.mode != PORT_MODE_OUTPUT: return input_ports = [] for jack_port in port_list: if jack_port.mode == PORT_MODE_INPUT: input_ports.append(jack_port.name) for connection in saved_connections: if connection in connection_list: continue if connection[0] == port.name and connection[1] in input_ports: jacklib.connect(jack_client, port.name, connection[1]) def connectAllOutputs(port): if port.mode != PORT_MODE_INPUT: return output_ports = [] for jack_port in port_list: if jack_port.mode == PORT_MODE_OUTPUT: output_ports.append(jack_port.name) for connection in saved_connections: if connection in connection_list: continue if connection[0] in output_ports and connection[1] == port.name: jacklib.connect(jack_client, connection[0], port.name) def makeMayConnections(): output_ports = [] input_ports = [] new_output_ports = [] new_input_ports = [] for port in port_list: if port.mode == PORT_MODE_OUTPUT: output_ports.append(port.name) if port.is_new: new_output_ports.append(port.name) elif port.mode == PORT_MODE_INPUT: input_ports.append(port.name) if port.is_new: new_input_ports.append(port.name) global pending_connection one_connected = False for connection in saved_connections: if (not connection in connection_list and connection[0] in output_ports and connection[1] in input_ports and (connection[0] in new_output_ports or connection[1] in new_input_ports)): if one_connected: pending_connection = True break jacklib.connect(jack_client, connection[0], connection[1]) one_connected = True else: pending_connection = False for port in port_list: port.is_new = False def c_char_p_p_to_list(c_char_p_p): i = 0 retList = [] if not c_char_p_p: return retList while True: new_char_p = c_char_p_p[i] if new_char_p: retList.append(str(new_char_p, encoding="utf-8")) i += 1 else: break jacklib.free(c_char_p_p) return retList def openFile(project_path, session_name, full_client_id): saved_connections.clear() global file_path file_path = "%s.xml" % project_path if os.path.isfile(file_path): try: file = open(file_path, 'r') except: sys.stderr.write('unable to read file %s\n' % file_path) app.quit() return xml = QDomDocument() xml.setContent(file.read()) content = xml.documentElement() if content.tagName() != "RAY-JACKPATCH": file.close() NSMServer.openReply() return cte = content.toElement() node = cte.firstChild() while not node.isNull(): el = node.toElement() if el.tagName() != "connection": continue port_from = el.attribute('from') port_to = el.attribute('to') saved_connections.append((port_from, port_to)) node = node.nextSibling() makeMayConnections() NSMServer.openReply() setDirtyClean() dirty_checker.start() def saveFile(): if not file_path: return for connection in connection_list: if not connection in saved_connections: saved_connections.append(connection) delete_list = [] # delete connection of the saved_connections # if its two ports are still presents and not connected for i in range(len(saved_connections)): if (portExists(saved_connections[i][0], PORT_MODE_OUTPUT) and portExists(saved_connections[i][1], PORT_MODE_INPUT)): if not saved_connections[i] in connection_list: delete_list.append(i) delete_list.reverse() for i in delete_list: saved_connections.__delitem__(i) try: file = open(file_path, 'w') except: sys.stderr.write('unable to write file %s\n' % file_path) app.quit() return xml = QDomDocument() p = xml.createElement('RAY-JACKPATCH') for con in saved_connections: ct = xml.createElement('connection') ct.setAttribute('from', con[0]) ct.setAttribute('to', con[1]) p.appendChild(ct) xml.appendChild(p) file.write(xml.toString()) file.close() NSMServer.saveReply() setDirtyClean() if __name__ == '__main__': NSM_URL = os.getenv('NSM_URL') if not NSM_URL: sys.stderr.write('Could not register as NSM client.\n') sys.exit() daemon_address = ray.get_liblo_address(NSM_URL) jack_client = jacklib.client_open( "ray-patcher", jacklib.JackNoStartServer | jacklib.JackSessionID, None) if not jack_client: sys.stderr.write('Unable to make a jack client !\n') sys.exit() jacklib.set_port_registration_callback(jack_client, JackPortRegistrationCallback, None) jacklib.set_port_connect_callback(jack_client, JackPortConnectCallback, None) jacklib.set_port_rename_callback(jack_client, JackPortRenameCallback, None) jacklib.on_shutdown(jack_client, JackShutdownCallback, None) jacklib.activate(jack_client) signaler = Signaler() signaler.port_added.connect(portAdded) signaler.port_removed.connect(portRemoved) signaler.port_renamed.connect(portRenamed) signaler.connection_added.connect(connectionAdded) signaler.connection_removed.connect(connectionRemoved) signaler.server_sends_open.connect(openFile) signaler.server_sends_save.connect(saveFile) #makeMayConnections() NSMServer = nsm_client.NSMThread('ray-jackpatch', signaler, daemon_address, False) NSMServer.start() NSMServer.announce('JACK Connections', ':dirty:switch:', 'ray-jackpatch') #connect signals signal.signal(signal.SIGINT, signalHandler) signal.signal(signal.SIGTERM, signalHandler) #get all currents Jack ports and connections portNameList = c_char_p_p_to_list(jacklib.get_ports(jack_client, "", "", 0)) for portName in portNameList: jack_port = JackPort() jack_port.name = portName portPtr = jacklib.port_by_name(jack_client, portName) portFlags = jacklib.port_flags(portPtr) if portFlags & jacklib.JackPortIsInput: jack_port.mode = PORT_MODE_INPUT elif portFlags & jacklib.JackPortIsOutput: jack_port.mode = PORT_MODE_OUTPUT else: jack_port.mode = PORT_MODE_NULL portTypeStr = str(jacklib.port_type(portPtr), encoding="utf-8") if portTypeStr == jacklib.JACK_DEFAULT_AUDIO_TYPE: jack_port.type = PORT_TYPE_AUDIO elif portTypeStr == jacklib.JACK_DEFAULT_MIDI_TYPE: jack_port.type = PORT_TYPE_MIDI else: jack_port.type = PORT_TYPE_NULL jack_port.is_new = True port_list.append(jack_port) if jacklib.port_flags(portPtr) & jacklib.JackPortIsInput: continue portConnectionNames = c_char_p_p_to_list( jacklib.port_get_all_connections(jack_client, portPtr)) for portConName in portConnectionNames: connection_list.append((portName, portConName)) app = QCoreApplication(sys.argv) #needed for signals SIGINT, SIGTERM timer = QTimer() timer.start(200) timer.timeout.connect(lambda: None) connect_timer = ConnectTimer() dirty_checker = DirtyChecker() app.exec() jacklib.deactivate(jack_client) jacklib.client_close(jack_client) RaySession-0.12.2/src/clients/jackpatch/ray.py000077700000000000000000000000001417052567600242712../../shared/ray.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/jackpatch_monitor_test/000077500000000000000000000000001417052567600226765ustar00rootroot00000000000000RaySession-0.12.2/src/clients/jackpatch_monitor_test/jacklib.py000077700000000000000000000000001417052567600305072../../shared/jacklib.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/jackpatch_monitor_test/nsm_client.py000077700000000000000000000000001417052567600317772../../shared/nsm_client.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/jackpatch_monitor_test/ray-jackpatch.py000077500000000000000000000350621417052567600260020ustar00rootroot00000000000000#!/usr/bin/python3 -u import os import signal import sys from PyQt5.QtCore import QCoreApplication, QObject, QTimer, pyqtSignal from PyQt5.QtXml import QDomDocument #from shared import * import jacklib import nsm_client import ray connection_list = [] saved_connections = [] port_list = [] PORT_MODE_OUTPUT = 0 PORT_MODE_INPUT = 1 PORT_MODE_NULL = 2 PORT_TYPE_AUDIO = 0 PORT_TYPE_MIDI = 1 PORT_TYPE_NULL = 2 file_path = "" is_dirty = False pending_connection = False def signalHandler(sig, frame): if sig in (signal.SIGINT, signal.SIGTERM): app.quit() class JackPort: #is_new is used to prevent reconnections # when a disconnection has not been saved and one new port append. id = 0 name = '' mode = PORT_MODE_NULL type = PORT_TYPE_NULL is_new = False class ConnectTimer(QObject): def __init__(self): self.timer = QTimer() self.timer.setInterval(200) self.timer.setSingleShot(True) self.timer.timeout.connect(makeMayConnections) def start(self): self.timer.start() def portExists(name, mode): for port in port_list: if port.name == name and port.mode == mode: return True return False def setDirtyClean(): global is_dirty is_dirty = False NSMServer.sendDirtyState(False) def timerDirtyFinish(): global is_dirty if is_dirty: return if isDirtyNow(): is_dirty = True NSMServer.sendDirtyState(True) def isDirtyNow(): for connection in connection_list: if not connection in saved_connections: return True output_ports = [] input_ports = [] for port in port_list: if port.mode == PORT_MODE_OUTPUT: output_ports.append(port.name) elif port.mode == PORT_MODE_INPUT: input_ports.append(port.name) for connection in saved_connections: if connection in connection_list: continue if connection[0] in output_ports and connection[1] in input_ports: return True return False class DirtyChecker(QObject): timer = QTimer() def __init__(self): self.timer.setInterval(500) self.timer.setSingleShot(True) self.timer.timeout.connect(timerDirtyFinish) def start(self): self.timer.start() def readyToConnect(): pass class Signaler(nsm_client.NSMSignaler): port_added = pyqtSignal(str, int, int) port_removed = pyqtSignal(str, int, int) port_renamed = pyqtSignal(str, str, int, int) connection_added = pyqtSignal(str, str) connection_removed = pyqtSignal(str, str) def JackShutdownCallback(arg=None): app.quit() return 0 def JackPortRegistrationCallback(portId, registerYesNo, arg=None): portPtr = jacklib.port_by_id(jack_client, portId) portFlags = jacklib.port_flags(portPtr) port_name = str(jacklib.port_name(portPtr), encoding="utf-8") port_mode = PORT_MODE_NULL if portFlags & jacklib.JackPortIsInput: port_mode = PORT_MODE_INPUT elif portFlags & jacklib.JackPortIsOutput: port_mode = PORT_MODE_OUTPUT port_type = PORT_TYPE_NULL portTypeStr = str(jacklib.port_type(portPtr), encoding="utf-8") if portTypeStr == jacklib.JACK_DEFAULT_AUDIO_TYPE: port_type = PORT_TYPE_AUDIO elif portTypeStr == jacklib.JACK_DEFAULT_MIDI_TYPE: port_type = PORT_TYPE_MIDI if registerYesNo: signaler.port_added.emit(port_name, port_mode, port_type) else: signaler.port_removed.emit(port_name, port_mode, port_type) return 0 def JackPortRenameCallback(portId, oldName, newName, arg=None): portPtr = jacklib.port_by_id(jack_client, portId) portFlags = jacklib.port_flags(portPtr) port_mode = PORT_MODE_NULL if portFlags & jacklib.JackPortIsInput: port_mode = PORT_MODE_INPUT elif portFlags & jacklib.JackPortIsOutput: port_mode = PORT_MODE_OUTPUT port_type = PORT_TYPE_NULL portTypeStr = str(jacklib.port_type(portPtr), encoding="utf-8") if portTypeStr == jacklib.JACK_DEFAULT_AUDIO_TYPE: port_type = PORT_TYPE_AUDIO elif portTypeStr == jacklib.JACK_DEFAULT_MIDI_TYPE: port_type = PORT_TYPE_MIDI signaler.port_renamed.emit(str(oldName, encoding='utf-8'), str(newName, encoding='utf-8'), port_mode, port_type) return 0 def JackPortConnectCallback(port_id_A, port_id_B, connect_yesno, arg=None): port_ptr_A = jacklib.port_by_id(jack_client, port_id_A) port_ptr_B = jacklib.port_by_id(jack_client, port_id_B) port_str_A = str(jacklib.port_name(port_ptr_A), encoding="utf-8") port_str_B = str(jacklib.port_name(port_ptr_B), encoding="utf-8") if connect_yesno: signaler.connection_added.emit(port_str_A, port_str_B) else: signaler.connection_removed.emit(port_str_A, port_str_B) return 0 def portAdded(port_name, port_mode, port_type): port = JackPort() port.name = port_name port.mode = port_mode port.type = port_type port.is_new = True port_list.append(port) connect_timer.start() def portRemoved(port_name, port_mode, port_type): for i in range(len(port_list)): port = port_list[i] if (port.name == port_name and port.mode == port_mode and port.type == port_type): break else: return port_list.__delitem__(i) def portRenamed(old_name, new_name, port_mode, port_type): for port in port_list: if (port.name == old_name and port.mode == port_mode and port.type == port_type): port.name = new_name port.is_new = True connect_timer.start() break def connectionAdded(port_str_A, port_str_B): connection_list.append((port_str_A, port_str_B)) if pending_connection: makeMayConnections() if (port_str_A, port_str_B) not in saved_connections: dirty_checker.start() def connectionRemoved(port_str_A, port_str_B): for i in range(len(connection_list)): if (connection_list[i][0] == port_str_A and connection_list[i][1] == port_str_B): connection_list.__delitem__(i) break dirty_checker.start() def makeAllSavedConnections(port): if port.mode == PORT_MODE_OUTPUT: connectAllInputs(port) elif port.mode == PORT_MODE_INPUT: connectAllOutputs(port) def connectAllInputs(port): if port.mode != PORT_MODE_OUTPUT: return input_ports = [] for jack_port in port_list: if jack_port.mode == PORT_MODE_INPUT: input_ports.append(jack_port.name) for connection in saved_connections: if connection in connection_list: continue if connection[0] == port.name and connection[1] in input_ports: jacklib.connect(jack_client, port.name, connection[1]) def connectAllOutputs(port): if port.mode != PORT_MODE_INPUT: return output_ports = [] for jack_port in port_list: if jack_port.mode == PORT_MODE_OUTPUT: output_ports.append(jack_port.name) for connection in saved_connections: if connection in connection_list: continue if connection[0] in output_ports and connection[1] == port.name: jacklib.connect(jack_client, connection[0], port.name) def makeMayConnections(): output_ports = [] input_ports = [] new_output_ports = [] new_input_ports = [] for port in port_list: if port.mode == PORT_MODE_OUTPUT: output_ports.append(port.name) if port.is_new: new_output_ports.append(port.name) elif port.mode == PORT_MODE_INPUT: input_ports.append(port.name) if port.is_new: new_input_ports.append(port.name) global pending_connection one_connected = False for connection in saved_connections: if (not connection in connection_list and connection[0] in output_ports and connection[1] in input_ports and (connection[0] in new_output_ports or connection[1] in new_input_ports)): if one_connected: pending_connection = True break jacklib.connect(jack_client, connection[0], connection[1]) one_connected = True else: pending_connection = False for port in port_list: port.is_new = False def c_char_p_p_to_list(c_char_p_p): i = 0 retList = [] if not c_char_p_p: return retList while True: new_char_p = c_char_p_p[i] if new_char_p: retList.append(str(new_char_p, encoding="utf-8")) i += 1 else: break jacklib.free(c_char_p_p) return retList def openFile(project_path, session_name, full_client_id): saved_connections.clear() global file_path file_path = "%s.xml" % project_path if os.path.isfile(file_path): try: file = open(file_path, 'r') except: sys.stderr.write('unable to read file %s\n' % file_path) app.quit() return xml = QDomDocument() xml.setContent(file.read()) content = xml.documentElement() if content.tagName() != "RAY-JACKPATCH": file.close() NSMServer.openReply() return cte = content.toElement() node = cte.firstChild() while not node.isNull(): el = node.toElement() if el.tagName() != "connection": continue port_from = el.attribute('from') port_to = el.attribute('to') saved_connections.append((port_from, port_to)) node = node.nextSibling() makeMayConnections() NSMServer.openReply() setDirtyClean() dirty_checker.start() def saveFile(): if not file_path: return for connection in connection_list: if not connection in saved_connections: saved_connections.append(connection) delete_list = [] # delete connection of the saved_connections # if its two ports are still presents and not connected for i in range(len(saved_connections)): if (portExists(saved_connections[i][0], PORT_MODE_OUTPUT) and portExists(saved_connections[i][1], PORT_MODE_INPUT)): if not saved_connections[i] in connection_list: delete_list.append(i) delete_list.reverse() for i in delete_list: saved_connections.__delitem__(i) try: file = open(file_path, 'w') except: sys.stderr.write('unable to write file %s\n' % file_path) app.quit() return xml = QDomDocument() p = xml.createElement('RAY-JACKPATCH') for con in saved_connections: ct = xml.createElement('connection') ct.setAttribute('from', con[0]) ct.setAttribute('to', con[1]) p.appendChild(ct) xml.appendChild(p) file.write(xml.toString()) file.close() NSMServer.saveReply() setDirtyClean() if __name__ == '__main__': NSM_URL = os.getenv('NSM_URL') if not NSM_URL: sys.stderr.write('Could not register as NSM client.\n') sys.exit() daemon_address = ray.get_liblo_address(NSM_URL) jack_client = jacklib.client_open( "ray-patcher", jacklib.JackNoStartServer | jacklib.JackSessionID, None) if not jack_client: sys.stderr.write('Unable to make a jack client !\n') sys.exit() jacklib.set_port_registration_callback(jack_client, JackPortRegistrationCallback, None) jacklib.set_port_connect_callback(jack_client, JackPortConnectCallback, None) jacklib.set_port_rename_callback(jack_client, JackPortRenameCallback, None) jacklib.on_shutdown(jack_client, JackShutdownCallback, None) jacklib.activate(jack_client) signaler = Signaler() signaler.port_added.connect(portAdded) signaler.port_removed.connect(portRemoved) signaler.port_renamed.connect(portRenamed) signaler.connection_added.connect(connectionAdded) signaler.connection_removed.connect(connectionRemoved) signaler.server_sends_open.connect(openFile) signaler.server_sends_save.connect(saveFile) #makeMayConnections() NSMServer = nsm_client.NSMThread('ray-jackpatch', signaler, daemon_address, False) NSMServer.start() NSMServer.announce('JACK Connections', ':dirty:switch:monitor:', 'ray-jackpatch') #connect signals signal.signal(signal.SIGINT, signalHandler) signal.signal(signal.SIGTERM, signalHandler) #get all currents Jack ports and connections portNameList = c_char_p_p_to_list(jacklib.get_ports(jack_client, "", "", 0)) for portName in portNameList: jack_port = JackPort() jack_port.name = portName portPtr = jacklib.port_by_name(jack_client, portName) portFlags = jacklib.port_flags(portPtr) if portFlags & jacklib.JackPortIsInput: jack_port.mode = PORT_MODE_INPUT elif portFlags & jacklib.JackPortIsOutput: jack_port.mode = PORT_MODE_OUTPUT else: jack_port.mode = PORT_MODE_NULL portTypeStr = str(jacklib.port_type(portPtr), encoding="utf-8") if portTypeStr == jacklib.JACK_DEFAULT_AUDIO_TYPE: jack_port.type = PORT_TYPE_AUDIO elif portTypeStr == jacklib.JACK_DEFAULT_MIDI_TYPE: jack_port.type = PORT_TYPE_MIDI else: jack_port.type = PORT_TYPE_NULL jack_port.is_new = True port_list.append(jack_port) if jacklib.port_flags(portPtr) & jacklib.JackPortIsInput: continue portConnectionNames = c_char_p_p_to_list( jacklib.port_get_all_connections(jack_client, portPtr)) for portConName in portConnectionNames: connection_list.append((portName, portConName)) app = QCoreApplication(sys.argv) #needed for signals SIGINT, SIGTERM timer = QTimer() timer.start(200) timer.timeout.connect(lambda: None) connect_timer = ConnectTimer() dirty_checker = DirtyChecker() app.exec() jacklib.deactivate(jack_client) jacklib.client_close(jack_client) RaySession-0.12.2/src/clients/jackpatch_monitor_test/ray.py000077700000000000000000000000001417052567600270772../../shared/ray.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/proxy/000077500000000000000000000000001417052567600173215ustar00rootroot00000000000000RaySession-0.12.2/src/clients/proxy/nsm_client.py000077700000000000000000000000001417052567600264222../../shared/nsm_client.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/proxy/ray-proxy.py000077500000000000000000000631761417052567600216650ustar00rootroot00000000000000#!/usr/bin/python3 -u import argparse import os import sys import time import signal import subprocess from PyQt5.QtCore import (QObject, QTimer, QProcess, QSettings, QLocale, QTranslator, QFile) from PyQt5.QtWidgets import (QApplication, QDialog, QFileDialog, QMainWindow) from PyQt5.QtXml import QDomDocument import ray import nsm_client import ui_proxy_gui import ui_proxy_copy ERR_OK = 0 ERR_NO_PROXY_FILE = -1 ERR_NOT_ENOUGHT_LINES = -2 ERR_NO_EXECUTABLE = -3 ERR_WRONG_ARGUMENTS = -4 ERR_WRONG_SAVE_SIGNAL = -5 ERR_WRONG_STOP_SIGNAL = -6 def signalHandler(sig, frame): if sig in (signal.SIGINT, signal.SIGTERM): if proxy.isRunning(): proxy.waitForStop() proxy.stopProcess() else: #sys.exit() app.quit() def ifDebug(string): if debug: sys.stderr.write(string + '\n') class ProxyCopyDialog(QDialog): def __init__(self): QDialog.__init__(self) self.ui = ui_proxy_copy.Ui_Dialog() self.ui.setupUi(self) self.rename_file = False self.ui.pushButtonCopyRename.clicked.connect(self.setRenameFile) def setRenameFile(self): self.rename_file = True self.accept() def setFile(self, path): self.ui.labelFileNotInFolder.setText( _translate( 'Dialog', '%s is not in proxy directory') % ('' + os.path.basename(path) + '')) class ProxyDialog(QMainWindow): def __init__(self, executable=''): QMainWindow.__init__(self) self.ui = ui_proxy_gui.Ui_MainWindow() self.ui.setupUi(self) self.server = server self.proxy = proxy self.config_file = '' self.args_edited = False self.fields_allow_start = False self.process_is_running = False self.ui.toolButtonBrowse.clicked.connect(self.browseFile) self.ui.lineEditExecutable.textEdited.connect( self.lineEditExecutableEdited) self.ui.lineEditArguments.textChanged.connect( self.lineEditArgumentsChanged) self.ui.lineEditConfigFile.textChanged.connect( self.lineEditConfigFileChanged) self.ui.comboSaveSig.addItem(_translate('proxy', 'None'), 0) self.ui.comboSaveSig.addItem('SIGUSR1', int(signal.SIGUSR1)) self.ui.comboSaveSig.addItem('SIGUSR2', int(signal.SIGUSR2)) self.ui.comboSaveSig.addItem('SIGINT', int(signal.SIGINT)) self.ui.comboSaveSig.activated.connect(self.comboSaveSigChanged) self.ui.comboSaveSig.setCurrentIndex(0) self.ui.comboNoSave.addItem( _translate('proxy', "0 - Ignore missing save")) self.ui.comboNoSave.addItem( _translate('proxy', "1 - Transmit missing save")) self.ui.comboNoSave.addItem( _translate('proxy', "2 - Accept windows close")) self.ui.comboNoSave.setCurrentIndex(2) self.ui.comboNoSave.activated.connect(self.comboNoSaveChanged) self.ui.labelNoSaveLevel.setToolTip(self.ui.comboNoSave.toolTip()) self.ui.comboStopSig.addItem('SIGTERM', int(signal.SIGTERM)) self.ui.comboStopSig.addItem('SIGINT', int(signal.SIGINT)) self.ui.comboStopSig.addItem('SIGHUP', int(signal.SIGHUP)) self.ui.comboStopSig.activated.connect(self.comboStopSigChanged) self.ui.comboStopSig.setCurrentIndex(0) self.ui.comboSaveSig.currentTextChanged.connect(self.allowSaveTest) self.ui.toolButtonTestSave.clicked.connect(self.testSave) self.ui.toolButtonTestSave.setEnabled(False) self.ui.pushButtonStart.clicked.connect(self.startProcess) self.ui.pushButtonStop.clicked.connect(self.stopProcess) self.ui.pushButtonStop.setEnabled(False) self.ui.lineEditExecutable.setText(executable) self.lineEditExecutableEdited(executable) self.ui.labelError.setText('') proxy.process.started.connect(self.proxyStarted) proxy.process.finished.connect(self.proxyFinished) if ray.QT_VERSION >= (5, 6): proxy.process.errorOccurred.connect(self.proxyErrorInProcess) def checkAllowStart(self): self.fields_allow_start = True if not self.ui.lineEditExecutable.text(): self.fields_allow_start = False if ray.shell_line_to_args(self.ui.lineEditArguments.text()) is None: self.fields_allow_start = False self.ui.pushButtonStart.setEnabled( bool(not self.process_is_running and self.fields_allow_start)) def updateValuesFromProxyFile(self): self.ui.lineEditExecutable.setText(proxy.executable) self.ui.lineEditConfigFile.setText(proxy.config_file) self.ui.lineEditArguments.setText(proxy.arguments_line) save_index = self.ui.comboSaveSig.findData(proxy.save_signal) self.ui.comboSaveSig.setCurrentIndex(save_index) self.ui.comboNoSave.setCurrentIndex(proxy.no_save_level) self.ui.comboNoSave.setEnabled(not bool(proxy.save_signal)) stop_index = self.ui.comboStopSig.findData(proxy.stop_signal) self.ui.comboStopSig.setCurrentIndex(stop_index) self.ui.checkBoxWaitWindow.setChecked(proxy.wait_window) self.checkAllowStart() def browseFile(self): config_file, ok = QFileDialog.getOpenFileName( self, _translate('Dialog', 'Select File to use as CONFIG_FILE')) if not ok: return if not config_file.startswith(os.getcwd() + '/'): qfile = QFile(config_file) if qfile.size() < 20971520: # if file < 20Mb copy_dialog = ProxyCopyDialog() copy_dialog.setFile(config_file) copy_dialog.exec() if copy_dialog.result(): if copy_dialog.rename_file: base, pt, extension = os.path.basename( config_file).rpartition('.') config_file = "%s.%s" % (proxy.session_name, extension) if not base: config_file = proxy.session_name else: config_file = os.path.basename(config_file) qfile.copy(config_file) self.config_file = os.path.relpath(config_file) if (proxy.session_name and (self.config_file == proxy.session_name or self.config_file.startswith("%s." % proxy.session_name))): self.config_file = self.config_file.replace(proxy.session_name, "$RAY_SESSION_NAME") self.ui.lineEditConfigFile.setText(self.config_file) def lineEditExecutableEdited(self, text): self.checkAllowStart() def lineEditArgumentsChanged(self, text): self.checkAllowStart() if ray.shell_line_to_args(text) is not None: self.ui.lineEditArguments.setStyleSheet('') else: self.ui.lineEditArguments.setStyleSheet( 'QLineEdit{background: red}') self.ui.pushButtonStart.setEnabled(False) def lineEditConfigFileChanged(self, text): if text and not self.ui.lineEditArguments.text(): self.ui.lineEditArguments.setText('"$CONFIG_FILE"') elif (not text and self.ui.lineEditArguments.text() == '"$CONFIG_FILE"'): self.ui.lineEditArguments.setText('') def comboSaveSigChanged(self, index): self.ui.comboNoSave.setEnabled(bool(index == 0)) save_signal = 0 if index == 1: save_signal = signal.SIGUSR1 elif index == 2: save_signal = signal.SIGUSR2 elif index == 3: save_signal = signal.SIGINT save_signal = int(save_signal) self.proxy.setSaveSignal(save_signal) def comboStopSigChanged(self, index): stop_signal = signal.SIGTERM if index == 1: stop_signal = signal.SIGINT elif index == 2: stop_signal = signal.SIGTERM stop_signal = int(stop_signal) self.proxy.setStopSignal(stop_signal) def comboNoSaveChanged(self, index): self.proxy.no_save_level = index self.proxy.sendNoSaveLevel() def allowSaveTest(self, text=None): if text is None: text = self.ui.comboSaveSig.currentText() self.ui.toolButtonTestSave.setEnabled( bool(self.process_is_running and text != 'None')) def testSave(self): save_signal = self.ui.comboSaveSig.currentData() proxy.saveProcess(save_signal) def saveProxy(self): executable = self.ui.lineEditExecutable.text() config_file = self.ui.lineEditConfigFile.text() arguments_line = self.ui.lineEditArguments.text() save_signal = self.ui.comboSaveSig.currentData() no_save_level = self.ui.comboNoSave.currentIndex() stop_signal = self.ui.comboStopSig.currentData() wait_window = self.ui.checkBoxWaitWindow.isChecked() proxy.updateAndSave( executable, config_file, arguments_line, save_signal, no_save_level, stop_signal, wait_window) def startProcess(self): self.saveProxy() if proxy.is_launchable: proxy.startProcess() def stopProcess(self): proxy.stopProcess(self.ui.comboStopSig.currentData()) def proxyStarted(self): self.process_is_running = True self.ui.pushButtonStart.setEnabled(False) self.ui.pushButtonStop.setEnabled(True) self.allowSaveTest() self.ui.labelError.setText('') def processTerminateShortly(self, duration): self.ui.labelError.setText('Process terminate in %f ms') def proxyFinished(self): self.process_is_running = False self.ui.pushButtonStart.setEnabled(self.fields_allow_start) self.ui.pushButtonStop.setEnabled(False) self.allowSaveTest() self.ui.labelError.setText('') def proxyErrorInProcess(self): self.ui.labelError.setText( _translate( 'Dialog', 'Executable failed to launch ! It\'s maybe not present on system.')) if not self.isVisible(): self.show() def closeEvent(self, event): server.sendToDaemon('/nsm/client/gui_is_hidden') settings.setValue( 'ProxyGui%s/geometry' % self.proxy.client_id, self.saveGeometry()) settings.setValue( 'ProxyGui%s/WindowState' % self.proxy.client_id, self.saveState()) settings.sync() if self.fields_allow_start: self.saveProxy() QMainWindow.closeEvent(self, event) # Quit if process is not running yet if not proxy.process.state() == QProcess.Running: sys.exit(0) def showEvent(self, event): self.server.sendToDaemon('/nsm/client/gui_is_shown') if settings.value('ProxyGui%s/geometry' % self.proxy.client_id): self.restoreGeometry( settings.value( 'ProxyGui%s/geometry' % self.proxy.client_id)) if settings.value('ProxyGui%s/WindowState' % self.proxy.client_id): self.restoreState( settings.value( 'ProxyGui%s/WindowState' % self.proxy.client_id)) self.updateValuesFromProxyFile() QMainWindow.showEvent(self, event) ########################## class Proxy(QObject): def __init__(self, executable=''): QObject.__init__(self) self.process = QProcess() self.process.setProcessChannelMode(QProcess.ForwardedChannels) self.process.finished.connect(self.processFinished) #self.proxy_file = None self.is_launchable = False self.project_path = "" self.path = "" self.session_name = "" self.client_id = "" self.jack_client_name = "" self.executable = executable self.arguments = [] self.arguments_line = '' self.config_file = "" self.save_signal = 0 self.no_save_level = 2 self.stop_signal = int(signal.SIGTERM) self.label = "" self.wait_window = False self._config_file_used = False self._wait_for_stop = False self.timer_save = QTimer() self.timer_save.setSingleShot(True) self.timer_save.setInterval(300) self.timer_save.timeout.connect(self.timerSaveFinished) self.timer_open = QTimer() self.timer_open.setSingleShot(True) self.timer_open.setInterval(500) self.timer_open.timeout.connect(self.timerOpenFinished) self.is_finishable = False self.timer_close = QTimer() self.timer_close.setSingleShot(True) self.timer_close.setInterval(2500) self.timer_close.timeout.connect(self.timerCloseFinished) self.timer_close.start() self.process_start_time = time.time() self.timer_window = QTimer() self.timer_window.setInterval(100) self.timer_window.timeout.connect(self.checkWindow) self.timer_window_n = 0 signaler.server_sends_open.connect(self.initialize) signaler.server_sends_save.connect(self.saveProcess) signaler.show_optional_gui.connect(self.showOptionalGui) signaler.hide_optional_gui.connect(self.hideOptionalGui) def isRunning(self): return bool(self.process.state() == QProcess.Running) def waitForStop(self): self._wait_for_stop = True def setSaveSignal(self, int_signal): self.save_signal = int_signal self.sendNoSaveLevel() def setStopSignal(self, int_signal): self.stop_signal = int_signal def readFile(self): self.is_launchable = False try: file = open(self.path, 'r') except BaseException: return xml = QDomDocument() xml.setContent(file.read()) content = xml.documentElement() if content.tagName() != "RAY-PROXY": file.close() return cte = content.toElement() file_version = cte.attribute('VERSION') self.executable = cte.attribute('executable') self.config_file = cte.attribute('config_file') self.arguments_line = cte.attribute('arguments') save_signal = cte.attribute('save_signal') no_save_level = cte.attribute('no_save_level') stop_signal = cte.attribute('stop_signal') wait_window = cte.attribute('wait_window') if wait_window.isdigit(): self.wait_window = bool(int(wait_window)) else: self.wait_window = False file.close() if save_signal.isdigit(): self.save_signal = int(save_signal) if no_save_level.isdigit(): self.no_save_level = int(no_save_level) else: self.no_save_level = 2 versions = [file_version, '0.7.1'] versions.sort() if file_version != versions[0]: # something was wrong in old version, # save signal was saved as stop signal too. # so don't read stop signal if this is an old file. if stop_signal.isdigit(): self.stop_signal = int(stop_signal) if not self.executable: return arguments = ray.shell_line_to_args(self.arguments_line) if arguments is None: return self.is_launchable = True def saveFile( self, executable, config_file, arguments_line, save_signal, no_save_level, stop_signal, wait_window): try: file = open(self.path, 'w') except BaseException: return if not save_signal: save_signal = 0 xml = QDomDocument() p = xml.createElement('RAY-PROXY') p.setAttribute('VERSION', ray.VERSION) p.setAttribute('executable', executable) p.setAttribute('arguments', arguments_line) p.setAttribute('config_file', config_file) p.setAttribute('save_signal', str(int(save_signal))) p.setAttribute('no_save_level', str(no_save_level)) p.setAttribute('stop_signal', str(int(stop_signal))) p.setAttribute('wait_window', wait_window) xml.appendChild(p) contents = "\n" contents += "\n" contents += xml.toString() file.write(contents) file.close() self.readFile() def updateValues(self, executable, config_file, arguments_line, save_signal, no_save_level, stop_signal, wait_window): self.executable = executable self.config_file = config_file self.arguments_line = arguments_line self.save_signal = save_signal self.no_save_level = no_save_level self.stop_signal = stop_signal self.wait_window = wait_window def saveProxyFile(self): self.saveFile( self.executable, self.config_file, self.arguments_line, self.save_signal, self.no_save_level, self.stop_signal, self.wait_window) def updateAndSave(self, executable, config_file, arguments_line, save_signal, no_save_level, stop_signal, wait_window): self.updateValues(executable, config_file, arguments_line, save_signal, no_save_level, stop_signal, wait_window) self.saveProxyFile() def processFinished(self, exit_code): if self._wait_for_stop: app.quit() if self.is_finishable: if not proxy_dialog.isVisible(): app.quit() else: duration = time.time() - self.process_start_time proxy_dialog.processTerminateShortly(duration) # proxy_dialog.show() def checkWindow(self): self.timer_window_n += 1 if self.timer_window_n > 600: # 600 x 50ms = 30s max until ray-proxy # replyOpen to Session Manager self.checkWindowEnded() return try: # get all windows and their PID with wmctrl wmctrl_all = subprocess.check_output( ['wmctrl', '-l', '-p']).decode() except BaseException: self.checkWindowEnded() return if not wmctrl_all: self.checkWindowEnded() return all_lines = wmctrl_all.split('\n') pids = [] # get all windows pids for line in all_lines: if not line: continue line_sep = line.split(' ') non_empt = [] for el in line_sep: if el: non_empt.append(el) if len(non_empt) >= 3 and non_empt[2].isdigit(): pids.append(int(non_empt[2])) else: # window manager seems to not work correctly with wmctrl, so # replyOpen now self.checkWindowEnded() return parent_pid = self.process.pid() # check in pids if one comes from this ray-proxy for pid in pids: if pid < parent_pid: continue ppid = pid while ppid != parent_pid and ppid > 1: try: proc_file = open('/proc/%i/status' % ppid, 'r') proc_contents = proc_file.read() except BaseException: self.checkWindowEnded() return for line in proc_contents.split('\n'): if line.startswith('PPid:'): ppid_str = line.rpartition('\t')[2] if ppid_str.isdigit(): ppid = int(ppid_str) break else: self.checkWindowEnded() return if ppid == parent_pid: # a window appears with a pid child of this ray-proxy, # replyOpen QTimer.singleShot(200, self.checkWindowEnded) break def checkWindowEnded(self): self.timer_window.stop() server.openReply() def initialize(self, project_path, session_name, jack_client_name): self.project_path = project_path self.session_name = session_name self.client_id = project_path.rpartition('.')[2] self.jack_client_name = jack_client_name server.sendGuiState(False) if not os.path.exists(project_path): os.mkdir(project_path) os.chdir(project_path) proxy_dialog.setWindowTitle("Ray Proxy - %s" % self.client_id) self.path = os.path.join(project_path, "ray-proxy.xml") self.readFile() proxy_dialog.updateValuesFromProxyFile() if not self.is_launchable: server.openReply() proxy_dialog.show() return self.startProcess() def sendNoSaveLevel(self): if ':no-save-level:' in server.getServerCapabilities(): nsl = self.no_save_level if self.save_signal: nsl = 0 server.sendToDaemon('/nsm/client/no_save_level', nsl) def startProcess(self): os.environ['NSM_CLIENT_ID'] = self.jack_client_name os.environ['RAY_CLIENT_ID'] = self.client_id os.environ['RAY_SESSION_NAME'] = self.session_name # enable environment vars in config_file config_file = os.path.expandvars(self.config_file) os.environ['CONFIG_FILE'] = config_file # because that is not done by python itself os.environ['PWD'] = os.getcwd() # Useful for launching NSM compatible clients with specifics arguments nsm_url = os.getenv('NSM_URL') ray_port_str = nsm_url.rpartition(':')[2] if ray_port_str.endswith('/'): ray_port_str = ray_port_str[:-1] if ray_port_str.isdigit(): os.environ['RAY_CONTROL_PORT'] = ray_port_str os.unsetenv('NSM_URL') arguments_line = os.path.expandvars(self.arguments_line) arguments = ray.shell_line_to_args(arguments_line) self._config_file_used = bool(config_file and config_file in arguments) self.sendNoSaveLevel() self.process.start(self.executable, arguments) self.timer_open.start() def saveProcess(self, save_signal=0): if not save_signal: save_signal = self.save_signal if self.isRunning() and save_signal: os.kill(self.process.processId(), save_signal) self.timer_save.start() def stopProcess(self, signal=signal.SIGTERM): if signal is None: return if not self.isRunning(): return os.kill(self.process.processId(), signal) def timerSaveFinished(self): server.saveReply() def timerOpenFinished(self): if self.wait_window: self.timer_window.start() else: server.openReply() if self.isRunning() and proxy_dialog.isVisible(): proxy_dialog.close() def timerCloseFinished(self): self.is_finishable = True def stop(self): if self.process.state: self.process.terminate() def showOptionalGui(self): proxy_dialog.show() def hideOptionalGui(self): if not proxy_dialog.isHidden(): proxy_dialog.close() class ProxyFile: def __init__(self, project_path, executable=''): self.executable = executable self.arguments_line = '' self.config_file = '' self.args_line = '' self.save_signal = 0 self.stop_signal = int(signal.SIGTERM) self.wait_window = False if __name__ == '__main__': NSM_URL = os.getenv('NSM_URL') if not NSM_URL: sys.stderr.write('Could not register as NSM client.\n') sys.exit() daemon_address = ray.get_liblo_address(NSM_URL) parser = argparse.ArgumentParser() parser.add_argument('--executable', default='') parser.add_argument('--debug', '-d', action='store_true', help='see all OSC messages') parser.add_argument('-v', '--version', action='version', version=ray.VERSION) parsed_args = parser.parse_args() debug = parsed_args.debug executable = parsed_args.executable app = QApplication(sys.argv) app.setApplicationName("RaySession") # app.setApplicationVersion(ray.VERSION) app.setOrganizationName("RaySession") app.setQuitOnLastWindowClosed(False) settings = QSettings() signal.signal(signal.SIGINT, signalHandler) signal.signal(signal.SIGTERM, signalHandler) # Translation process locale = QLocale.system().name() appTranslator = QTranslator() if appTranslator.load( "%s/locale/raysession_%s" % (os.path.dirname( os.path.dirname( os.path.dirname( sys.argv[0]))), locale)): app.installTranslator(appTranslator) _translate = app.translate timer = QTimer() timer.setInterval(200) timer.timeout.connect(lambda: None) timer.start() signaler = nsm_client.NSMSignaler() server = nsm_client.NSMThread('ray-proxy', signaler, daemon_address, debug) server.start() proxy = Proxy(executable) proxy_dialog = ProxyDialog() server.announce('Ray Proxy', ':optional-gui:warning-no-save:', 'ray-proxy') app.exec() settings.sync() server.stop() del server del proxy del app RaySession-0.12.2/src/clients/proxy/ray.py000077700000000000000000000000001417052567600235222../../shared/ray.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/sooperlooper/000077500000000000000000000000001417052567600206705ustar00rootroot00000000000000RaySession-0.12.2/src/clients/sooperlooper/jacklib.py000077700000000000000000000000001417052567600265012../../shared/jacklib.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/sooperlooper/nsm_client.py000077700000000000000000000000001417052567600277712../../shared/nsm_client.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/sooperlooper/ray.py000077700000000000000000000000001417052567600250712../../shared/ray.pyustar00rootroot00000000000000RaySession-0.12.2/src/clients/sooperlooper/sooperlooper_lash000077500000000000000000000111031417052567600243510ustar00rootroot00000000000000#!/usr/bin/python3 -u # old file, prefer use sooperlooper_nsm. But it's maybe used by someones. import sys import subprocess import time try: import liblo import xml.etree.ElementTree as ET from signal import signal, SIGINT, SIGTERM, SIGUSR1, SIGUSR2 except: sys.exit() class OSCServer(liblo.Server): def __init__(self): liblo.Server.__init__(self) self.m_number_of_loops = 0 self.m_last_called_looplen = 0 self.sl_url = liblo.Address(sooploop_port) self.m_save_last_called_loop = True self.add_method('/pingfromsl', None, self.pingFeedBack) self.add_method('/audio_save_error', None, self.audioSaveError) self.add_method('/loop_lenght', None, self.setLoopLenght) def pingFeedBack(self, path, arg_list): if len(arg_list) > 1: self.m_number_of_loops = arg_list[2] def setLoopLenght(self, path, arg_list): self.m_last_called_looplen = arg_list[2] def audioSaveError(self, path, arg_list): if len(arg_list) > 1: if arg_list[1] == 'Loop Save Failed': self.m_save_last_called_loop = False def saveSession(self): self.send(self.sl_url, '/ping', ('s', self.url), ('s', '/pingfromsl')) self.send(self.sl_url, '/save_session', ('s', filename), ('s', ''), ('s', '')) self.recv(1) #save audio loops basefile = filename.rsplit('.slsess', 1)[0] for i in range(self.m_number_of_loops): #send signal to know if loop contains audio self.send(self.sl_url, '/sl/%i/get' % i, ('s', 'loop_len'), ('s', self.url), ('s', '/loop_lenght')) self.recv(1) if self.m_last_called_looplen > 0: #if loop contains audio audio_filename = basefile + str(i) + '.wav' server.send(self.sl_url, '/sl/' + str(i) + '/save_loop', ('s', audio_filename), ('s', ''), ('s', ''), ('s', self.url), ('s', '/audio_save_error')) server.recv(10) if self.m_save_last_called_loop: #rewrite .slsess file to include audio tree = ET.parse(filename) root = tree.getroot() Loopers = root.find('Loopers') for Looper in Loopers.iter('Looper'): if str(Looper.get('index')) == str(i): Looper.set('loop_audio', audio_filename) tree.write(filename) self.m_save_last_called_loop = True def pingSooperLooper(self, port): self.send(self.sl_url, '/ping', ('s', self.url), ('s', '/pingfromsl')) self.recv(1) if self.sl_port == None: return False else: return self.sl_port def quitSooperLooper(self): self.send(self.sl_url, '/quit') def signalHandler(sig, frame): if sig in (SIGTERM, SIGINT): slgui_process.send_signal(SIGTERM) server.quitSooperLooper() elif sig == SIGUSR1: server.saveSession() return global main_loop main_loop = False ########################################SCRIPT START######################################################### #set filename from argument, exit if no argument try: filename = sys.argv[1] except: sys.stderr.write('need file as argument, exit\n') sys.exit(0) #get a free OSC port for sooperlooper, start from 9951 (default soopperlooper osc port) sooploop_port = 9951 UsedPort = True testport = None while UsedPort: try: testport = liblo.Server(sooploop_port) UsedPort = False except: sooploop_port += 1 UsedPort = True del testport, UsedPort #lanch sooperlooper sooperlooper_process = subprocess.Popen(['sooperlooper', '-p', str(sooploop_port),'--load-session', filename ]) #launch slgui slgui_process = subprocess.Popen(['slgui', '-P', str(sooploop_port)]) #construct OSC server server = OSCServer() main_loop = True while main_loop: #quit script if slgui closed if slgui_process.poll() != None: server.quitSooperLooper() break #send signal if any signal(SIGINT, signalHandler) signal(SIGTERM, signalHandler) signal(SIGUSR1, signalHandler) time.sleep(0.050) #refresh time (50ms) RaySession-0.12.2/src/clients/sooperlooper/sooperlooper_nsm.py000077500000000000000000000254261417052567600246630ustar00rootroot00000000000000#!/usr/bin/python3 -u import os import signal import sys from liblo import Address, make_method from PyQt5.QtCore import (QCoreApplication, pyqtSignal, QObject, QTimer, QProcess) from PyQt5.QtXml import QDomDocument import ray import nsm_client import jacklib def signalHandler(sig, frame): if sig in (signal.SIGINT, signal.SIGTERM): general_object.leave() class SlOSCThread(nsm_client.NSMThread): def __init__(self, name, signaler, daemon_address, debug): nsm_client.NSMThread.__init__(self, name, signaler, daemon_address, debug) self.sl_is_ready = False self.number_of_loops = 0 @make_method('/pongSL', 'ssi') def pong(self, path, args): self.sl_is_ready = True self.number_of_loops = args[2] if general_object.wait_for_load: general_object.sl_ready.emit() class GeneralObject(QObject): sl_ready = pyqtSignal() def __init__(self): QObject.__init__(self) self.sl_process = QProcess() self.sl_process.setProcessChannelMode(QProcess.ForwardedChannels) self.sl_process.finished.connect(self.slProcessFinished) self.sl_port = ray.get_free_osc_port(9951) self.sl_url = Address(self.sl_port) self.gui_process = QProcess() self.gui_process.setProcessChannelMode(QProcess.ForwardedChannels) self.gui_process.started.connect(self.guiProcessStarted) self.gui_process.finished.connect(self.guiProcessFinished) self.project_path = '' self.session_path = '' self.session_name = '' self.full_client_id = '' self.session_file = '' self.session_bak = '' self.midi_bindings_file = '' self.file_timer = QTimer() self.file_timer.setInterval(100) self.file_timer.timeout.connect(self.checkFile) self.n_file_timer = 0 signaler.server_sends_open.connect(self.initialize) signaler.server_sends_save.connect(self.saveSlSession) signaler.show_optional_gui.connect(self.showOptionalGui) signaler.hide_optional_gui.connect(self.hideOptionalGui) self.sl_ready.connect(self.loadSession) self._switching = False self.leaving = False self.wait_for_load = False self.ping_timer = QTimer() self.ping_timer.setInterval(100) self.ping_timer.timeout.connect(self.pingSL) self.ping_timer.start() self.transport_timer = QTimer() self.transport_timer.setInterval(2) self.transport_timer.timeout.connect(self.checkTransport) self.transport_playing = False self.will_trig = False self.jack_follow_naming = False def JackShutdownCallback(self, arg=None): self.transport_timer.stop() return 0 def checkTransport(self): pos = jacklib.jack_position_t() pos.valid = 0 state = jacklib.transport_query(jack_client, jacklib.pointer(pos)) if self.will_trig: if pos.beat == pos.beats_per_bar: if (pos.ticks_per_beat - pos.tick) <= 4: # we are at 4 ticks or less from next bar (arbitrary) # so we send a trig message to sooperlooper. server.send(self.sl_url, '/sl/-1/hit', 'trigger') self.will_trig = False return if (self.transport_playing and state == jacklib.JackTransportStopped): if self.will_trig: self.will_trig = False else: server.send(self.sl_url, '/sl/-1/hit', 'pause_on') self.transport_playing = False elif (not self.transport_playing and state == jacklib.JackTransportRolling): if pos.beat == 1 and pos.tick == 0: server.send(self.sl_url, '/sl/-1/hit', 'trigger') else: self.will_trig = True self.transport_playing = True def pingSL(self): if server.sl_is_ready: self.ping_timer.stop() else: server.send(self.sl_url, '/ping', server.url, '/pongSL') def leave(self): self.leaving = True if self.gui_process.state(): self.gui_process.terminate() else: if self.sl_process.state(): server.send(self.sl_url, '/quit') else: app.quit() def isGuiShown(self): return bool(self.sl_process.state() == QProcess.Running) def slProcessFinished(self, exit_code): if not self._switching: app.quit() def guiProcessStarted(self): server.sendGuiState(True) def guiProcessFinished(self, exit_code): if self.leaving: if self.sl_process.state(): server.send(self.sl_url, '/quit') else: app.quit() server.sendGuiState(False) def startFileChecker(self): self.n_file_timer = 0 if os.path.exists(self.session_file): self.stopFileChecker() return self.file_timer.start() def stopFileChecker(self): self.n_file_timer = 0 self.file_timer.stop() self.xmlCorrection() server.saveReply() def checkFile(self): if self.n_file_timer > 200: #more than 20 second self.stopFileChecker() return if os.path.exists(self.session_file): self.stopFileChecker() return self.n_file_timer += 1 def xmlCorrection(self): try: sl_file = open(self.session_file) xml = QDomDocument() xml.setContent(sl_file.read()) sl_file.close() except: return content = xml.documentElement() if content.tagName() != 'SLSession': return nodes = content.childNodes() for i in range(nodes.count()): node = nodes.at(i) if node.toElement().tagName() != 'Loopers': continue sub_nodes = node.childNodes() for j in range(sub_nodes.count()): sub_node = sub_nodes.at(j) element = sub_node.toElement() if element.tagName() != 'Looper': continue audio_file_name = str(element.attribute('loop_audio')) if audio_file_name.startswith("%s/" % self.project_path): element.setAttribute('loop_audio', os.path.relpath(audio_file_name)) try: sl_file = open(self.session_file, 'w') except: return sl_file.write(xml.toString()) sl_file.close() def initialize(self, project_path, session_name, full_client_id): self.project_path = project_path self.session_name = session_name self.session_file = "%s/session.slsess" % self.project_path self.session_bak = "%s/session.slsess.bak" % self.project_path self.midi_bindings_file = "%s/session.slb" % self.project_path #self.midi_bindings_bak = "%s/session.slb.bak" % self.project_path if not self.jack_follow_naming: full_client_id = 'sooperlooper' if full_client_id != self.full_client_id: self.full_client_id = full_client_id if self.gui_process.state(): self.gui_process.terminate() self.gui_process.waitForFinished(500) else: server.sendGuiState(False) self._switching = True if self.sl_process.state(): self.sl_process.terminate() self.sl_process.waitForFinished(500) self._switching = False self.sl_process.start( 'sooperlooper', ['-p', str(self.sl_port), '-j', self.full_client_id]) if not os.path.exists(self.project_path): os.makedirs(self.project_path) os.chdir(self.project_path) if server.sl_is_ready: self.loadSession() else: self.wait_for_load = True if jack_client: self.transport_timer.start() def loadSession(self): #self.sl_process.start('sooperlooper', ['-p', str(self.sl_port)]) self.wait_for_load = False server.send(self.sl_url, '/load_session', self.session_file, server.url, '/re-load') server.send(self.sl_url, '/load_midi_bindings', self.midi_bindings_file, '') if jack_client is not None: server.send(self.sl_url, '/set', 'sync_source', -1.0) server.send(self.sl_url, '/set', 'eighth_per_cycle', 8.0) server.send(self.sl_url, '/sl/0/set,' 'quantize', 1.0) server.openReply() def saveSlSession(self): if os.path.exists(self.session_bak): os.remove(self.session_bak) if os.path.exists(self.session_file): os.rename(self.session_file, self.session_bak) server.send(self.sl_url, '/save_session', self.session_file, server.url, '/re-save', 1) server.send(self.sl_url, '/save_midi_bindings', self.midi_bindings_file, '') self.startFileChecker() def showOptionalGui(self): if not self.gui_process.state(): self.gui_process.start('slgui', ['-P', str(self.sl_port)]) def hideOptionalGui(self): if self.gui_process.state(): self.gui_process.terminate() if __name__ == '__main__': NSM_URL = os.getenv('NSM_URL') if not NSM_URL: sys.stderr.write('Could not register as NSM client.\n') sys.exit() daemon_address = ray.get_liblo_address(NSM_URL) signal.signal(signal.SIGINT, signalHandler) signal.signal(signal.SIGTERM, signalHandler) app = QCoreApplication(sys.argv) app.setApplicationName("SooperLooperNSM") app.setOrganizationName("SooperLooperNSM") timer = QTimer() timer.setInterval(200) timer.timeout.connect(lambda: None) timer.start() signaler = nsm_client.NSMSignaler() server = SlOSCThread('sooperlooper_nsm', signaler, daemon_address, False) if len(sys.argv) > 1 and '--transport_workaround' in sys.argv[1:]: jack_client = jacklib.client_open( "sooper_ray_wk", jacklib.JackNoStartServer | jacklib.JackSessionID, None) else: jack_client = None general_object = GeneralObject() if "--follow-jack-naming" in sys.argv[1:]: general_object.jack_follow_naming = True server.start() capabilities = ':optional-gui:switch:' server.announce('SooperLooper', capabilities, 'sooperlooper_nsm') app.exec() server.stop() del server del app RaySession-0.12.2/src/control/000077500000000000000000000000001417052567600161575ustar00rootroot00000000000000RaySession-0.12.2/src/control/help_en_US000066400000000000000000000224361417052567600201320ustar00rootroot00000000000000control RaySession daemons --help Prints short help message --help-all Prints full help message --help-control Prints help for control commands --help-server Prints help for server commands --help-session Prints help for running session commands --help-clients Prints help for clients management --port Specify daemon OSC port. This port can also be specified with RAY_CONTROL_PORT environment variable. --detach Only send OSC message and do not wait for an answer * CONTROL_COMMANDS: start starts a daemon if there is no daemon started start_new starts a new daemon, returns its OSC port number start_new_hidden starts a new daemon, returns its OSC port number. This daemon will not be seen by ray_control unless its port is specified. This new daemon will be started without any option, and options states won't be saved when it ends. stop stops all running daemons list_daemons lists running daemons OSC ports get_port get default daemon OSC port get_root get daemon root directory for sessions get_pid get default daemon pid get_session_path get path of the running session, returns error code if no daemon is running or if no session is loaded. has_gui Returns error code if no gui is attached to this daemon has_local_gui Returns error code if no gui on this machine is attached to this daemon * SERVER_COMMANDS: new_session NEW_SESSION_NAME [SESSION_TEMPLATE] Saves current session (if any), then creates and loads NEW_SESSION_NAME, optionnally with SESSION_TEMPLATE open_session SESSION_NAME [SESSION_TEMPLATE] Saves current session (if any), Loads SESSION_NAME (create it if it does not exists optionnally with SESSION_TEMPLATE) open_session_off SESSION_NAME [SESSION_TEMPLATE] Same as 'open_session' but doesn't starts any client. list_sessions Lists available sessions in sessions root directory quit Aborts current session (if any) and stop the daemon change_root NEW_ROOT_FOLDER Changes root directory for the sessions to NEW_ROOT_FOLDER list_session_templates Lists session templates list_user_client_templates Lists user client templates list_factory_client_templates Lists factory client templates remove_client_template CLIENT_TEMPLATE Removes user CLIENT_TEMPLATE set_options OPTION1 [OPTION2] [OPTION3]... Set daemon options. Available options are: save_from_client bookmark_session_folder desktops_memory snapshots session_scripts gui_states precede the option with 'not_' to disable this option example: ray_control set_options bookmark_session_folder not_snapshots has_option OPTION Returns an error code if OPTION is not currently used script_info TEXT Displays an info dialog on RaySession's GUI. hide_script_info Hides the script info dialog on RaySession's GUI. script_user_action TEXT Displays a question dialog on RaySession's GUI. Returns when user accepted or rejected it. * SESSION_COMMANDS: All these commands work only when a session is loaded. save Saves the current session. TIP: affect 'ray_control save' command to a global keyboard shortcut save_as_template SESSION_TEMPLATE_NAME Saves the current session as template take_snapshot SNAPSHOT_NAME Takes a snapshot of the current session close Saves and Closes the current session abort Aborts current session duplicate NEW_SESSION_NAME Saves, duplicates the current session and load the new one process_step Runs the next process step. Useful only in session scripts. open_snapshot SNAPSHOT Saves, closes the session, back to SNAPSHOT and re-open it rename NEW_SESSION_NAME renames the current session to NEW_SESSION_NAME add_executable EXECUTABLE [OPTION1] [OPTION2]... Adds a client to the current session Available options are ray_hack runs the executable with Ray-Hack protocol (not NSM) via_proxy runs the executable into ray-proxy not_start prepare the client but not start it prefix_mode:client_name Set the prefix mode to client_name prefix_mode:session_name Set the prefix mode to session name prefix:$PREFIX Set the prefix mode to custom prefix and the prefix to $PREFIX client_id:$NEW_CLIENT_ID Try to use this client_id. Useful for use files copied to the session dir. add_factory_client_template CLIENT_TEMPLATE [not_start] Adds a client to the current session from factory CLIENT_TEMPLATE if not_started is provided as second arg, then template will be added but not start add_user_client_template CLIENT_TEMPLATE [not_start] Adds a client to the current session from user CLIENT_TEMPLATE if not_started is provided as second arg, then template will be added but not start list_snapshots Lists all snapshots of the current session list_clients [FILTER1] [FILTER2] [FILTER3]... Lists clients with their client_id. Available filters are: started active auto_start no_save_level precede the filter with 'not_' to revert the filter example: ray_control list_clients auto_start not_started will display all stopped clients that should be started at session open clear_clients [CLIENT_ID1] [CLIENT_ID2]... Usable only in the load.sh session script, before the run_step. Used to remove clients that could have been kept from the previous session. whitout arguments, removes all running clients, else removes clients given by their CLIENT_ID. set_notes NOTES Set the session notes to notes, use with care, it will erase notes show_notes Ask to all attached GUIs to show the notes dialog hide_notes Ask to all attached GUIs to hide the notes dialog * CLIENT_COMMANDS: all client commands have to be written this way: ray_control client CLIENT_ID command [*ARGUMENTS] example: ray_control client carla stop stop Stops the client kill Kills the client. To be used only as a last resort. trash Sends the client to trash. Client has to be stopped. start Starts the client resume Starts the client open Starts the client, returns only when client is ready, known as non active or too long to communicate. save Saves the client save_as_template TEMPLATE_NAME Saves the client as template TEMPLATE_NAME. Erase existant TEMPLATE_NAME if any. show_optional_gui shows client GUI if client is capable of hide_optional_gui Hides client GUI if client is capable of get_properties Get client properties set_properties PROPERTY1 [PROPERTY2] [PROPERTY3]... Set client properties. PROPERTY must contains property:value example: ray_control client carla set_properties icon:carla "label:My Carla Rack" get_proxy_properties Get client proxy properties only if client executable is ray-proxy set_proxy_properties PROPERTY1 [PROPERTY2] [PROPERTY3]... Set client proxy properties only if client executable is ray-proxy PROPERTY must contains property:value example: ray_control client lmms set_properties executable:lmms no_save_level:2 set_custom_data PROPERTY VALUE set a custom data to the client. This will not be used by the daemon. get_custom_data PROPERTY returns the value of custom_data property if it exists set_tmp_data PROPERTY VALUE set a tmp data to the client. This will not be used by the daemon. This data will not be saved at session save. get_tmp_data PROPERTY returns the value of tmp_data property if it exists list_files Lists directories and files used by client list_snapshots Lists session snapshot where this client exists open_snapshot SNAPSHOT Stops the client if running, loads SNAPSHOT only for client files, re-starts the client if it was started. is_started returns error code if client is not started get_pid returns the pid of the client process if it is running * TRASHED_CLIENT_OPTIONS: trashed client commands have to be written this way: ray_control trashed_client CLIENT_ID command [*ARGUMENTS] example: ray_control trashed_client carla restore restore restore the client in the session. client is restored stopped. remove_definitely remove all client files and directories. remove_keep_files remove client from trash, but do not remove its files. RaySession-0.12.2/src/control/help_fr_FR000066400000000000000000000256501417052567600201200ustar00rootroot00000000000000contrôle les démons de RaySession --help Afficher un court message d'aide --help-all Afficher toute l'aide --help-control Afficher l'aide des commandes de contrôle --help-server Afficher l'aide des commandes du serveur --help-session Afficher l'aide des commandes sur la session en cours --help-clients Afficher l'aide des commandes sur les clients --port Specifier le port OSC du démon. Ce port peut également être spécifié avec la variable d'environnement RAY_CONTROL_PORT --detach Envoyer seulement le message OSC et ne pas attendre de réponse * COMMANDES DE CONTRÔLE: start Démarre un démon si aucun n'est déjà démarré start_new Démarre un nouveau démon, renvoie son numéro de port OSC start_new_hidden Démarre un nouveau démon, renvoie son numéro de port OSC. Ce démon ne sera pas vu par ray_control sauf si son port est spécifié. Ce démon sera démarré sans aucune option, et l'état des options ne sera pas sauvegardé quand il s'arrêtera. stop Arrête tous les démons tournant list_daemons Liste les ports OSC des démons tournant get_port Renvoie le port OSC du démon par défaut get_root Renvoie le dossier racine des sessions get_pid Renvoie le PID du démon par défaut get_session_path Renvoie l'emplacement du dossier de la session en cours, retourne un code d'erreur si aucun démon ne tourne ou qu'aucune session n'est chargée. has_gui Retourne un code d'erreur si aucune IGU n'est attachée à ce démon has_local_gui Retourne un code d'erreur si aucune IGU sur cette machine n'est attachée à ce démon * COMMANDES DU SERVEUR: new_session NOUVELLE_SESSION [MODÈLE_DE_SESSION] Sauvegarde la session en cours (s'il y en a une) ensuite crée et charge NOUVELLE_SESSION, éventuellement à partir du modèle MODÈLE_DE_SESSION open_session NOM_DE_LA_SESSION [MODÈLE_DE_SESSION] Sauvegarde la session en cours (s'il y en a une) charge NOM_DE_LA_SESSION (en la créant si elle n'existe pas, éventuellement à partir du modèle MODÈLE_DE_SESSION. open_session_off NOM_DE_LA_SESSION [MODÈLE_DE_SESSION] Fait la même chose que open_session mais ne démarre aucun client. list_sessions Liste les sessions disponibles dans le dossier racine des sessions quit Abandonne la session en cours (si présente) puis arrête le démon. change_root NOUVEAU_DOSSIER_RACINE Change le dossier racine des session en NOUVEAU_DOSSIER_RACINE list_session_templates Liste les modèles de session list_user_client_templates Liste les modèles de client de l'utilisateur list_factory_client_templates Liste les modèles de client d'usine remove_client_template MODÈLE_DE_CLIENT Supprime le modèle de client de l'utilisateur MODÈLE_DE_CLIENT set_options OPTION1 [OPTION2] [OPTION3]... Configure les options du démon. Les options disponibles sont: save_from_client bookmark_session_folder desktops_memory snapshots session_scripts gui_states Précédez l'option de 'not_' pour désactiver cette option Exemple: ray_control set_options bookmark_session_folder not_snapshots has_option OPTION Retourne un code d'erreur si OPTION n'est pas enclenchée script_info TEXTE Affiche une fenêtre de dialogue d'information sur l'IGU de RaySession hide_script_info Cache la fenêtre de dialogue d'information de l'IGU de RaySession script_user_action TEXTE Affiche une fenêtre de dialogue de question sur l'IGU de RaySession Retourne quand l'utilisateur l'a acceptée ou refusée. has_attached_gui Retourne un code d'erreur si aucune IGU n'est attachée à ce démon * COMMANDES DE LA SESSION: Toutes ces commandes fonctionne uniquement quand une session est chargée. save Sauvegarde la session en cours. ASTUCE: affectez la commande 'ray_control save' à un raccourci clavier global save_as_template NOM_DU_MODÈLE_DE_SESSION Sauvegarde la session en cours comme modèle de session take_snapshot NOM_DU_CLICHÉ Prend un cliché de la session en cours close Sauvegarde et ferme la session en cours abort Abandonne la session en cours duplicate NOUVELLE_SESSION Sauvegarde et duplique la session en cours et charge NOUVELLE_SESSION process_step Procède à la prochaine étape du processus. Utile uniquement dans process_step_save.sh et process_step_close.sh dans les scripts de session. open_snapshot CLICHÉ Sauvegarde et ferme la session, retourne au cliché CLICHÉ et ré-ouvre la session rename NOUVEAU_NOM_DE_LA_SESSION renomme la session en cours en NOUVEAU_NOM_DE_LA_SESSION add_executable EXÉCUTABLE [OPTION1] [OPTION2]... Ajoute EXÉCUTABLE à la session en cours. Les options disponibles sont ray_hack lancer l'exécutable avec le protocole Ray-Hack (pas NSM) via_proxy lancer l'exécutable via un proxy not_start preparer le client mais ne pas le démarrer prefix_mode:client_name Mettre le mode de préfixe sur "Nom du client" prefix_mode:session_name Mettre le mode de préfixe sur "Nom de la session" prefix:$PREFIXE Mettre le mode de préfixe sur "Personnalisé" et le préfixe sur $PREFIXE client_id:$NOUVEAU_CLIENT_ID Essayer d'utiliser $NOUVEAU_CLIENT_ID. Très utile pour utiliser des fichiers préalablement copiés dans le repertoire de la session. add_factory_client_template MODÈLE_DE_CLIENT [not_start] Ajoute un client à la session selon MODÈLE_DE_CLIENT d'usine Avec l'argument not_started, le client sera ajouté mais ne sera pas lancé add_user_client_template MODÈLE_DE_CLIENT [not_start] Ajoute un client à la session selon MODÈLE_DE_CLIENT utilisateur Avec l'argument not_started, le client sera ajouté mais ne sera pas lancé list_snapshots Lister les clichés de la session list_clients [FILTER1] [FILTER2] [FILTER3]... Lister les clients de la session par leur client_id Les filtres disponibles sont: started active auto_start no_save_level Précédez le filtre avec 'not_' pour inverser le filtre Exemple: ray_control list_clients auto_start not_started Affichera tous les clients arrêtés qui doivent être démarrés à l'ouverture de la session clear_clients [CLIENT_ID1] [CLIENT_ID2]... Utilisable seulement dans le script de session load.sh, avant run_step. Utilisé pour supprimer les clients qui peuvent avoir été gardés de la session précédente. Sans arguments, ça supprime tous les clients tournants, sinon ça supprime les clients donnés par leur CLIENT_ID. set_notes NOTES Définir les notes de session comme étant NOTES. Attention, celà écrase les notes de session. show_notes Demande aux IGUs attachées d'afficher la boîte de notes hide_notes Demande aux IGUs attachées de cacher la boîte de notes * COMMANDES DE CLIENT: Les commandes de client doivent être écrites de cette manière: ray_control client CLIENT_ID commande [*ARGUMENTS] example: ray_control client carla stop stop Arrête le client poliment. kill Tue le client. À n'utiliser qu'en dernier recours trash Envoyer le client à la corbeille. Le client doit être arrêté. start Démarre le client resume Démarre le client open Démarre le client, ne retourne la commande qu'une fois que le client est prêt, connu comme étant non actif, ou trop long à communiquer. save Sauvegarde le client save_as_template NOM_DU_MODÈLE Sauvegarde le client comme modèle NOM_DU_MODÈLE. Écrase le modèle NOM_DU_MODÈLE s'il existe déjà. show_optional_gui Affiche l'IGU du client s'il en est capable hide_optional_gui Cache l'IGU du client s'il en est capable get_properties Renvoie les propriétés du client set_properties PROPRIÉTÉ1 [PROPRIÉTÉ2] [PROPRIÉTÉ3]... Définit les les propriétés du client. Le client doit être Ray Proxy et non démarré. PROPRIÉTÉ doit contenir propriété:valeur exemple: client carla set_properties icon:carla "label:Mon rack Carla" get_proxy_properties Renvoie les propriétés du proxy du client si son exécutable est ray-proxy set_proxy_properties PROPRIÉTÉ1 [PROPRIÉTÉ2] [PROPRIÉTÉ3]... Définit les les propriétés du proxy du client si son exécutable est ray-proxy. PROPRIÉTÉ doit contenir propriété:valeur example: ray_control client lmms set_properties executable:lmms no_save_level:2 set_custom_data PROPERTY VALUE Définir une propriété personnalisée pour le client. Elle ne sera pas utilisée par le démon. get_custom_data PROPERTY retourne la valeur de la propriété personnalisée. set_tmp_data PROPERTY VALUE Définir un propriété personnalisée temporaire pour le client. Elle ne sera pas utilisée par le démon. Cette propriété ne sera pas sauvegardée avec la session. get_tmp_data PROPERTY retourne la valeur de la propriété personnalisée temporaire. list_files Liste les fichiers et dossiers du client list_snapshots Liste les clichés de la session où le client existe open_snapshot CLICHÉ Arrête le client s'il est démarré, charge le CLICHÉ seulement pour les fichiers du client, redémarre le client s'il était démarré. is_started Retourne un code d'erreur si le client n'est pas démarré get_pid Retourne le pid du processus du client si il est démarré * COMMANDES DE CLIENT MIS À LA CORBEILLE: Les commandes de client mis à la corbeille doivent être écrites de cette manière: ray_control trashed_client CLIENT_ID command [*ARGUMENTS] exemple: ray_control trashed_client carla restore restore Restaure le client dans la session. Le client est restauré arrêté. remove_definitely Supprime définitivement le client et tous ses fichiers et dossiers. remove_keep_files Supprime le client de la corbeille, mais ne supprime pas ses fichiers. RaySession-0.12.2/src/control/osc_server.py000066400000000000000000000154401417052567600207070ustar00rootroot00000000000000 import os import sys import time import liblo # !!! we don't load ray.py to win import duration # if change in ray.Err numbers, this has to be changed too !!! ERR_UNKNOWN_MESSAGE = -18 def areTheyAllString(args): for arg in args: if not isinstance(arg, str): return False return True def highlightText(string): if "'" in string: return '"%s"' % string return "'%s'" % string class OscServer(liblo.Server): def __init__(self, detach=False): liblo.Server.__init__(self) self.m_daemon_address = None self.add_method('/reply', None, self.replyMessage) self.add_method('/error', 'sis', self.errorMessage) self.add_method('/minor_error', 'sis', self.minorErrorMessage) self.add_method('/ray/control/message', 's', self.rayControlMessage) self.add_method('/ray/control/server/announce', 'siisi', self.rayControlServerAnnounce) self._final_err = -1 self._wait_for_announce = False self._wait_for_start = False self._wait_for_start_only = False self._started_time = 0 self._stop_port_list = [] self._detach = detach self._announce_time = 0 self._osc_order_path = '' self._osc_order_args = [] def replyMessage(self, path, args, types, src_addr): if not areTheyAllString(args): return if len(args) >= 1: reply_path = args[0] else: return if reply_path == '/ray/server/controller_announce': self._wait_for_announce = False return elif reply_path == '/ray/server/quit': sys.stderr.write('--- Daemon at port %i stopped. ---\n' % src_addr.port) if self._stop_port_list: if src_addr.port == self._stop_port_list[0]: stopped_port = self._stop_port_list.pop(0) if self._stop_port_list: self.stopDaemon(self._stop_port_list[0]) else: self._final_err = 0 return if reply_path != self._osc_order_path: sys.stdout.write('bug: reply for a wrong path:%s instead of %s\n' % (highlightText(reply_path), highlightText(self._osc_order_path))) return if reply_path.endswith('/list_snapshots'): if len(args) >= 2: snapshots = args[1:] out_message = "" for snapshot_and_info in snapshots: snapshot, slash, info = snapshot_and_info.partition(':') out_message += "%s\n" % snapshot sys.stdout.write(out_message) return else: self._final_err = 0 elif os.path.basename(reply_path).startswith(('list_', 'get_')): if len(args) >= 2: sessions = args[1:] out_message = "" for session in sessions: out_message += "%s\n" % session sys.stdout.write(out_message) return else: self._final_err = 0 elif len(args) == 2: reply_path, message = args if os.path.basename(reply_path).startswith('add_'): sys.stdout.write("%s\n" % message) self._final_err = 0 def errorMessage(self, path, args, types, src_addr): error_path, err, message = args if error_path != self._osc_order_path: sys.stdout.write('bug: error for a wrong path:%s instead of %s\n' % (highlightText(error_path), highlightText(self._osc_order_path))) return sys.stderr.write('%s\n' % message) self._final_err = - err def minorErrorMessage(self, path, args, types, src_addr): error_path, err, message = args sys.stdout.write('\033[31m%s\033[0m\n' % message) if err == ERR_UNKNOWN_MESSAGE: self._final_err = -err def rayControlMessage(self, path, args, types, src_addr): message = args[0] sys.stdout.write("%s\n" % message) def rayControlServerAnnounce(self, path, args, types, src_addr): sys.stderr.write('--- Daemon started at port %i ---\n' % src_addr.port) self._wait_for_start = False self.m_daemon_address = src_addr if self._wait_for_start_only: self._final_err = 0 return self.sendOrderMessage() def setDaemonAddress(self, daemon_port): self.m_daemon_address = liblo.Address(daemon_port) self._wait_for_announce = True self._announce_time = time.time() self.toDaemon('/ray/server/controller_announce', os.getpid()) def getDaemonPort(self): if self.m_daemon_address: return self.m_daemon_address.port return None def toDaemon(self, *args): if self.m_daemon_address: self.send(self.m_daemon_address, *args) def setOrderPathArgs(self, path, args): self._osc_order_path = path self._osc_order_args = args def sendOrderMessage(self): if not self._osc_order_path: sys.stderr.write('error: order path was not set\n') sys.exit(101) self.toDaemon(self._osc_order_path, *self._osc_order_args) if self._detach: self._final_err = 0 def finalError(self): return self._final_err def waitForStart(self): self._wait_for_start = True self._started_time = time.time() def waitForStartOnly(self): self._wait_for_start_only = True def setStartedTime(self, started_time): self._started_time = started_time def isWaitingStartForALong(self): if not (self._wait_for_start or self._wait_for_announce): return False if self._wait_for_start: if time.time() - self._started_time > 3.00: sys.stderr.write("server didn't announce, sorry !\n") return True elif self._wait_for_announce: if time.time() - self._announce_time > 1: sys.stderr.write( 'Error: server did not reply, it may be busy !\n') return True return False def stopDaemon(self, port): sys.stderr.write('--- Stopping daemon at port %i ---\n' % port) self.setDaemonAddress(port) self.toDaemon('/ray/server/quit') def stopDaemons(self, stop_port_list): self._stop_port_list = stop_port_list if self._stop_port_list: self.stopDaemon(self._stop_port_list[0]) def disannounceToDaemon(self): self.toDaemon('/ray/server/controller_disannounce') RaySession-0.12.2/src/control/ray_control.py000077500000000000000000000420641417052567600210750ustar00rootroot00000000000000#!/usr/bin/python3 -u import os import signal import sys import xml.etree.ElementTree as ET import warnings # import subprocess and osc_server (local file) conditionnally # in order to answer faster in many cases. OPERATION_TYPE_NULL = 0 OPERATION_TYPE_CONTROL = 1 OPERATION_TYPE_SERVER = 2 OPERATION_TYPE_SESSION = 3 OPERATION_TYPE_CLIENT = 4 OPERATION_TYPE_TRASHED_CLIENT = 5 OPERATION_TYPE_ALL = 6 # for help message control_operations = ('start', 'start_new', 'start_new_hidden', 'stop', 'list_daemons', 'get_root', 'get_port', 'get_port_gui_free', 'get_pid', 'get_session_path', 'has_local_gui', 'has_gui') server_operations = ( 'quit', 'change_root', 'list_session_templates', 'list_user_client_templates', 'list_factory_client_templates', 'remove_client_template', 'list_sessions', 'new_session', 'open_session', 'open_session_off', 'save_session_template', 'rename_session', 'set_options', 'has_option', 'script_info', 'hide_script_info', 'script_user_action') def signalHandler(sig, frame): if sig in (signal.SIGINT, signal.SIGTERM): global terminate terminate = True def addSelfBinToPath(): # Add raysession/src/bin to $PATH to can use ray executables after make # Warning, will works only if link to this file is in RaySession/*/*/*.py this_path = os.path.realpath(os.path.dirname(os.path.realpath(__file__))) bin_path = "%s/bin" % os.path.dirname(this_path) if not os.environ['PATH'].startswith("%s:" % bin_path): os.environ['PATH'] = "%s:%s" % (bin_path, os.environ['PATH']) def pidExists(pid: int)->bool: if isinstance(pid, str): pid = int(pid) try: os.kill(pid, 0) except OSError: return False else: return True def pidIsStopped(pid: int)->bool: proc_file_path = '/proc/%i/status' % pid if os.path.exists(proc_file_path): proc_file = open(proc_file_path) for line in proc_file.readlines(): if line.startswith('State: '): value = line.replace('State: ', '', 1) if value and value[0] == 'T': return True return False return True def getDaemonList(): try: tree = ET.parse('/tmp/RaySession/multi-daemon.xml') except: return [] l_daemon_list = [] root = tree.getroot() for child in root: l_daemon = Daemon() for key in child.attrib.keys(): if key == 'root': l_daemon.root = child.attrib[key] elif key == 'session_path': l_daemon.session_path = child.attrib[key] elif key == 'user': l_daemon.user = child.attrib[key] elif key == 'not_default': l_daemon.not_default = bool(child.attrib[key] == '1') elif key == 'net_daemon_id': net_daemon_id = child.attrib[key] if net_daemon_id.isdigit(): l_daemon.net_daemon_id = int(net_daemon_id) elif key == 'pid': pid = child.attrib[key] if pid.isdigit() and pidExists(pid): l_daemon.pid = int(pid) elif key == 'port': l_port = child.attrib[key] if l_port.isdigit(): l_daemon.port = int(l_port) elif key == 'has_gui': l_daemon.has_local_gui = bool(child.attrib[key] == '3') l_daemon.has_gui = bool(child.attrib[key] == '1') elif key == 'local_gui_pids': gui_pids_str = child.attrib[key] for pid_str in gui_pids_str.split(':'): if pid_str.isdigit(): l_daemon.local_gui_pids.append(int(pid_str)) if not (l_daemon.net_daemon_id and l_daemon.pid and l_daemon.port): continue l_daemon_list.append(l_daemon) return l_daemon_list class Daemon: net_daemon_id = 0 root = "" session_path = "" pid = 0 port = 0 user = "" not_default = False has_gui = 0 has_local_gui = 0 def __init__(self): self.local_gui_pids = [] def printHelp(stdout=False, category=OPERATION_TYPE_NULL): script_dir = os.path.dirname(os.path.realpath(sys.argv[0])) lang_file = "help_en_US" if os.getenv('LANG').startswith('fr_'): lang_file = "help_fr_FR" help_path = "%s/%s" % (script_dir, lang_file) try: help_file = open(help_path, 'r') full_message = help_file.read() except: sys.stderr.write('error: help_file %s is missing\n' % help_path) sys.exit(101) message = '' stars = 0 if category == OPERATION_TYPE_ALL: message = full_message else: for line in full_message.split('\n'): if line.startswith('* '): stars += 1 if (stars == 0 or (stars == 1 and category == OPERATION_TYPE_CONTROL) or (stars == 2 and category == OPERATION_TYPE_SERVER) or (stars == 3 and category == OPERATION_TYPE_SESSION) or (stars >= 4 and category == OPERATION_TYPE_CLIENT)): message += "%s\n" % line if stdout: sys.stdout.write(message) else: sys.stderr.write(message) def autoTypeString(string): if string.isdigit(): return int(string) if string.replace('.', '', 1).isdigit(): return float(string) return string if __name__ == '__main__': warnings.filterwarnings("ignore", category=DeprecationWarning) addSelfBinToPath() if len(sys.argv) <= 1: printHelp() sys.exit(100) terminate = False operation_type = OPERATION_TYPE_NULL client_id = '' args = sys.argv[1:] wanted_port = 0 detach = False dport = os.getenv('RAY_CONTROL_PORT') if dport and dport.isdigit(): wanted_port = int(dport) while args and args[0].startswith('--'): option = args.pop(0) if option.startswith('--help'): if option == '--help': printHelp(True, OPERATION_TYPE_NULL) elif option == '--help-all': printHelp(True, OPERATION_TYPE_ALL) elif option == '--help-control': printHelp(True, OPERATION_TYPE_CONTROL) elif option == '--help-server': printHelp(True, OPERATION_TYPE_SERVER) elif option == '--help-session': printHelp(True, OPERATION_TYPE_SESSION) elif option in ('--help-client', '--help-clients'): printHelp(True, OPERATION_TYPE_CLIENT) else: printHelp() sys.exit(100) sys.exit(0) elif option == '--port': if not args: printHelp() sys.exit(100) port = args.pop(0) if not port.isdigit(): sys.stderr.write('Invalid value for port: %s . Use digits !' % port) sys.exit(100) wanted_port = int(port) elif option == '--detach': detach = True else: printHelp() sys.exit(100) operation = args.pop(0) if operation in ('client', 'trashed_client'): if len(args) < 2: printHelp(False, OPERATION_TYPE_CLIENT) sys.exit(100) operation_type = OPERATION_TYPE_CLIENT if operation == 'trashed_client': operation_type = OPERATION_TYPE_TRASHED_CLIENT client_id = args.pop(0) operation = args.pop(0) if not operation_type: if operation in control_operations: operation_type = OPERATION_TYPE_CONTROL elif operation in server_operations: operation_type = OPERATION_TYPE_SERVER else: operation_type = OPERATION_TYPE_SESSION arg_list = [autoTypeString(s) for s in args] if operation_type in (OPERATION_TYPE_CLIENT, OPERATION_TYPE_TRASHED_CLIENT): arg_list.insert(0, client_id) if operation in ('new_session', 'open_session', 'change_root', 'save_as_template', 'take_snapshot', 'duplicate', 'open_snapshot', 'rename', 'add_executable', 'add_client_template', 'script_info'): if not arg_list: sys.stderr.write('operation %s needs argument(s).\n' % operation) sys.exit(100) exit_code = 0 daemon_announced = False daemon_list = getDaemonList() daemon_port = 0 daemon_started = True for daemon in daemon_list: if ((daemon.user == os.environ['USER'] and not wanted_port and not daemon.not_default) or (wanted_port == daemon.port)): daemon_port = daemon.port break else: daemon_started = False if operation_type == OPERATION_TYPE_CONTROL: if operation == 'start': if daemon_started: sys.stderr.write('server already started.\n') sys.exit(0) elif operation in ('start_new', 'start_new_hidden'): pass elif operation == 'stop': if not daemon_started: sys.stderr.write('No server started.\n') sys.exit(0) elif operation == 'list_daemons': for daemon in daemon_list: if daemon.not_default: continue sys.stdout.write('%s\n' % str(daemon.port)) sys.exit(0) else: if not daemon_started: sys.stderr.write( 'No server started. So impossible to %s\n' % operation) sys.exit(100) if operation == 'get_pid': for daemon in daemon_list: if daemon.port == daemon_port: sys.stdout.write('%s\n' % str(daemon.pid)) sys.exit(0) elif operation == 'get_port': sys.stdout.write("%s\n" % str(daemon_port)) sys.exit(0) elif operation == 'get_port_gui_free': wanted_session_root = '' if args: wanted_session_root = args[0] for daemon in daemon_list: if (daemon.user == os.environ['USER'] and (daemon.root == wanted_session_root or not wanted_session_root) and not daemon.not_default): if not daemon.has_local_gui: sys.stdout.write('%s\n' % daemon.port) break for pid in daemon.local_gui_pids: if pid == 0: # This means we don't know the pid of the local GUI # So consider this daemon has already a GUI break if pidExists(pid) and not pidIsStopped(pid): break else: sys.stdout.write('%s\n' % daemon.port) break sys.exit(0) elif operation == 'get_root': for daemon in daemon_list: if daemon.port == daemon_port: sys.stdout.write('%s\n' % daemon.root) sys.exit(0) elif operation == 'get_session_path': for daemon in daemon_list: if daemon.port == daemon_port: if not daemon.session_path: sys.exit(1) sys.stdout.write('%s\n' % daemon.session_path) sys.exit(0) elif operation == 'has_local_gui': for daemon in daemon_list: if daemon.port == daemon_port: if daemon.has_local_gui: sys.exit(0) sys.exit(1) elif operation == 'has_gui': for daemon in daemon_list: if daemon.port == daemon_port: if daemon.has_gui: sys.exit(0) sys.exit(1) elif not daemon_started: at_port = '' if daemon_port: at_port = "at port %i" % daemon_port if operation_type == OPERATION_TYPE_SERVER: if operation == 'quit': sys.stderr.write('No server %s to quit !\n' % at_port) sys.exit(0) elif operation_type == OPERATION_TYPE_SESSION: sys.stderr.write("No server started %s. So no session to %s\n" % (at_port, operation)) sys.exit(100) elif operation_type == OPERATION_TYPE_CLIENT: sys.stderr.write("No server started %s. So no client to %s\n" % (at_port, operation)) sys.exit(100) elif operation_type == OPERATION_TYPE_CLIENT: sys.stderr.write( "No server started %s. So no trashed client to %s\n" % (at_port, operation)) sys.exit(100) else: printHelp() sys.exit(100) osc_order_path = '/ray/' if operation_type == OPERATION_TYPE_CLIENT: osc_order_path += 'client/' elif operation_type == OPERATION_TYPE_TRASHED_CLIENT: osc_order_path += 'trashed_client/' elif operation_type == OPERATION_TYPE_SERVER: osc_order_path += 'server/' elif operation_type == OPERATION_TYPE_SESSION: osc_order_path += 'session/' osc_order_path += operation if operation_type == OPERATION_TYPE_CONTROL and operation == 'stop': osc_order_path = '/ray/server/quit' import osc_server # see top of the file server = osc_server.OscServer(detach) server.setOrderPathArgs(osc_order_path, arg_list) daemon_process = None if (daemon_started and not (operation_type == OPERATION_TYPE_CONTROL and operation in ('start_new', 'start_new_hidden'))): if (operation_type == OPERATION_TYPE_CONTROL and operation == 'stop'): daemon_port_list = [] if wanted_port: daemon_port_list.append(wanted_port) else: for daemon in daemon_list: if (daemon.user == os.getenv('USER') and not daemon.not_default): daemon_port_list.append(daemon.port) server.stopDaemons(daemon_port_list) else: server.setDaemonAddress(daemon_port) server.sendOrderMessage() if detach: sys.exit(0) else: session_root = "%s/Ray Sessions" % os.getenv('HOME') try: settings_file = open( "%s/.config/RaySession/RaySession.conf" % os.getenv('HOME'), 'r') contents = settings_file.read() for line in contents.split('\n'): if line.startswith('default_session_root='): session_root = line.partition('=')[2] break except: pass # start a daemon because no one is running import subprocess # see top of the file process_args = ['ray-daemon', '--control-url', str(server.url), '--session-root', session_root] if wanted_port: process_args.append('--osc-port') process_args.append(str(wanted_port)) if (operation_type == OPERATION_TYPE_CONTROL and operation == 'start_new_hidden'): process_args.append('--hidden') process_args.append('--no-options') daemon_process = subprocess.Popen(process_args, -1, None, None, subprocess.DEVNULL, subprocess.DEVNULL) server.waitForStart() if (operation_type == OPERATION_TYPE_CONTROL and operation in ('start', 'start_new', 'start_new_hidden')): server.waitForStartOnly() #connect SIGINT and SIGTERM signal.signal(signal.SIGINT, signalHandler) signal.signal(signal.SIGTERM, signalHandler) exit_code = -1 while True: server.recv(50) if terminate: break exit_code = server.finalError() if exit_code >= 0: break if server.isWaitingStartForALong(): exit_code = 103 break if daemon_process and not daemon_process.poll() is None: sys.stderr.write('daemon terminates, sorry\n') exit_code = 104 break if (operation_type == OPERATION_TYPE_CONTROL and operation in ('start_new', 'start_new_hidden') and exit_code == 0): daemon_port = server.getDaemonPort() if daemon_port: sys.stdout.write("%i\n" % daemon_port) server.disannounceToDaemon() sys.exit(exit_code) RaySession-0.12.2/src/daemon/000077500000000000000000000000001417052567600157425ustar00rootroot00000000000000RaySession-0.12.2/src/daemon/bookmarker.py000066400000000000000000000420421417052567600204520ustar00rootroot00000000000000# -*- coding: utf-8 -*- import os import pathlib import sys from PyQt5.QtCore import QSettings, QDataStream, QIODevice, QUrl, QByteArray from PyQt5.QtXml import QDomDocument import ray from daemon_tools import get_app_config_path, dirname QFileDialogMagic = 190 class PickerType: def __init__(self, config_path): self.config_path = config_path self.written = False def _get_contents(self): if os.path.exists(self.config_path): try: file = open(self.config_path, 'r') contents = file.read() file.close() return contents except: return None else: return "" def _print_contents(self, contents): try: file = open(self.config_path, 'w') except: return False file.write(contents) file.close() return True def make_bookmark(self, spath): pass def remove_bookmark(self, spath): pass class PickerTypeGtk(PickerType): def make_bookmark(self, spath): if self.written: return url = pathlib.Path(spath).as_uri() config_dir = dirname(self.config_path) if not os.path.exists(config_dir): try: os.makedirs(config_dir) except: return contents = self._get_contents() if contents is None: return bookmarks = contents.split('\n') if url in bookmarks: return contents += "%s\n" % url if self._print_contents(contents): self.written = True def remove_bookmark(self, spath): if not self.written: return url = pathlib.Path(spath).as_uri() contents = self._get_contents() if not contents: self.written = False return bookmarks = contents.split('\n') if url in bookmarks: bookmarks.remove(url) else: self.written = False return contents = '' for url in bookmarks: if url: contents += "%s\n" % url self._print_contents(contents) self.written = False class PickerTypeFltk(PickerType): def make_bookmark(self, spath): if self.written: return contents = self._get_contents() if not contents: #we won't write a file for fltk if file doesn't already exists return lines = contents.split('\n') contents = "" num = -1 empty_fav = False fav0_found = False for line in lines: if line.startswith('favorite') and ':' in line: fav0_found = True if line.partition(':')[2]: if line.partition(':')[2] == spath: #bookmark already written, do nothing return num_s = line.partition(':')[0].replace('favorite', '', 1) if num_s.isdigit(): num = int(num_s) else: if not empty_fav: line += spath empty_fav = True if line or not fav0_found: contents += "%s\n" % line if not empty_fav: num += 1 contents += "favorite%.2d:%s" % (num, spath) if self._print_contents(contents): self.written = True def remove_bookmark(self, spath): if not self.written: return contents = self._get_contents() if not contents: self.written = False return lines = contents.split('\n') favorites = [] for line in lines: if line.startswith('favorite') and ':' in line: fav = line.partition(':')[2] favorites.append(fav) if not spath in favorites: self.written = False return favorites.remove(spath) contents = "" num = 0 for line in lines: if line.startswith('favorite') and ':' in line: fav = '' if num < len(favorites): fav = favorites[num] contents += "favorite%.2d:%s\n" % (num, fav) num += 1 else: contents += "%s\n" % line self._print_contents(contents) self.written = False class PickerTypeQt4(PickerType): def make_bookmark(self, spath): if self.written: return if not os.path.exists(self.config_path): #do not write shortcuts if file was not created by Qt4 himself return url = pathlib.Path(spath).as_uri() settings_qt4 = QSettings(self.config_path, QSettings.IniFormat) if not settings_qt4.isWritable(): return data = settings_qt4.value('Qt/filedialog') stream = QDataStream(data, QIODevice.ReadOnly) magic = stream.readUInt32() version = stream.readUInt32() if not (magic == QFileDialogMagic and version == 3): return split_states = stream.readBytes() bookmarks_len = stream.readUInt32() bookmarks = [] for bm in range(bookmarks_len): qUrl = QUrl() stream >> qUrl if qUrl.isLocalFile() and qUrl.toLocalFile() == spath: #spath already in qt4 bookmarks return bookmarks.append(qUrl) history_len = stream.readUInt32() history = [] for h in range(history_len): his = stream.readQString() history.append(his) current_dir = stream.readQString() header_data = stream.readBytes() view_mode = stream.readUInt32() #now rewrite bytes new_data = QByteArray() new_stream = QDataStream(new_data, QIODevice.WriteOnly) new_stream.writeUInt32(magic) new_stream.writeUInt32(3) new_stream.writeBytes(split_states) new_stream.writeUInt32(bookmarks_len+1) for bm in bookmarks: new_stream << bm qUrl = QUrl(url) new_stream << qUrl new_stream.writeQStringList(history) new_stream.writeQString(current_dir) new_stream.writeBytes(header_data) new_stream.writeUInt32(view_mode) settings_qt4.setValue('Qt/filedialog', new_data) settings_qt4.sync() self.written = True def remove_bookmark(self, spath): if not self.written: return if not os.path.exists(self.config_path): self.written = False return url = pathlib.Path(spath).as_uri() settings_qt4 = QSettings(self.config_path, QSettings.IniFormat) if not settings_qt4.isWritable(): self.written = False return data = settings_qt4.value('Qt/filedialog') stream = QDataStream(data, QIODevice.ReadOnly) magic = stream.readUInt32() version = stream.readUInt32() if not (magic == QFileDialogMagic and version == 3): self.written = False return split_states = stream.readBytes() bookmark_found = False bookmarks_len = stream.readUInt32() bookmarks = [] for bm in range(bookmarks_len): qUrl = QUrl() stream >> qUrl if qUrl.isLocalFile() and qUrl.toLocalFile() == spath: bookmark_found = True else: bookmarks.append(qUrl) if not bookmark_found: self.written = False return history_len = stream.readUInt32() history = [] for h in range(history_len): his = stream.readQString() history.append(his) current_dir = stream.readQString() header_data = stream.readBytes() view_mode = stream.readUInt32() #now rewrite bytes new_data = QByteArray() new_stream = QDataStream(new_data, QIODevice.WriteOnly) new_stream.writeUInt32(magic) new_stream.writeUInt32(3) new_stream.writeBytes(split_states) new_stream.writeUInt32(bookmarks_len-1) for bm in bookmarks: new_stream << bm qUrl = QUrl(url) new_stream << qUrl new_stream.writeQStringList(history) new_stream.writeQString(current_dir) new_stream.writeBytes(header_data) new_stream.writeUInt32(view_mode) settings_qt4.setValue('Qt/filedialog', new_data) settings_qt4.sync() self.written = False class PickerTypeQt5(PickerType): def make_bookmark(self, spath): if self.written: return if not os.path.exists(self.config_path): #do not write shortcuts if file was not created by Qt5 himself return url = pathlib.Path(spath).as_uri() settings_qt5 = QSettings(self.config_path, QSettings.IniFormat) if not settings_qt5.isWritable(): return shortcuts = ray.get_list_in_settings(settings_qt5, 'FileDialog/shortcuts') for sc in shortcuts: sc_url = QUrl(sc) if sc_url.isLocalFile() and sc_url.toLocalFile() == spath: return shortcuts.append(url) settings_qt5.setValue('FileDialog/shortcuts', shortcuts) settings_qt5.sync() self.written = True def remove_bookmark(self, spath): if not self.written: return if not os.path.exists(self.config_path): self.written = False return settings_qt5 = QSettings(self.config_path, QSettings.IniFormat) shortcuts = ray.get_list_in_settings(settings_qt5, 'FileDialog/shortcuts') for sc in shortcuts: sc_url = QUrl(sc) if sc_url.isLocalFile() and sc_url.toLocalFile() == spath: shortcuts.remove(sc) break else: self.written = False return settings_qt5.setValue('FileDialog/shortcuts', shortcuts) settings_qt5.sync() self.written = False class PickerTypeKde5(PickerType): def make_bookmark(self, spath): if self.written: return contents = self._get_contents() if not contents: #we won't write a file for kde5 if file doesn't already exists return url = pathlib.Path(spath).as_uri() xml = QDomDocument() xml.setContent(contents) content = xml.documentElement() if content.tagName() != 'xbel': return node = content.firstChild() while not node.isNull(): el = node.toElement() if el.tagName() == 'bookmark': if el.attribute('href') == url: #bookmark already exists return node = node.nextSibling() bk = xml.createElement('bookmark') bk.setAttribute('href', url) title = xml.createElement('title') title_text = xml.createTextNode(os.path.basename(spath)) title.appendChild(title_text) bk.appendChild(title) content.appendChild(bk) if self._print_contents(xml.toString()): self.written = True def remove_bookmark(self, spath): if not self.written: return contents = self._get_contents() if not contents: self.written = False return url = pathlib.Path(spath).as_uri() xml = QDomDocument() xml.setContent(contents) content = xml.documentElement() if content.tagName() != 'xbel': self.written = False return node = content.firstChild() while not node.isNull(): el = node.toElement() if el.tagName() == 'bookmark': if el.attribute('href') == url: content.removeChild(node) break node = node.nextSibling() else: self.written = False return self._print_contents(xml.toString()) self.written = False class BookMarker: def __init__(self): self._bookmarks_memory = "%s/bookmarks.xml" % get_app_config_path() self._daemon_port = 0 home = os.getenv('HOME') self._gtk2 = PickerTypeGtk("%s/.gtk-bookmarks" % home) self._gtk3 = PickerTypeGtk("%s/.config/gtk-3.0/bookmarks" % home) self._fltk = PickerTypeFltk( "%s/._fltk/fltk.org/filechooser.prefs" % home) self._kde5 = PickerTypeKde5("%s/.local/share/user-places.xbel" % home) self._qt4 = PickerTypeQt4("%s/.config/Trolltech.conf" % home) self._qt5 = PickerTypeQt5("%s/.config/QtProject.conf" % home) def _get_xml(self): xml = QDomDocument() file_exists = False if os.path.exists(self._bookmarks_memory): try: file = open(self._bookmarks_memory, 'r') xml.setContent(file.read()) file_exists = True except: try: os.path.remove(self._bookmarks_memory) except: return None if not file_exists: bms_xml = xml.createElement('Bookmarks') xml.appendChild(bms_xml) return xml def _write_xml_file(self, xml): try: file = open(self._bookmarks_memory, 'w') file.write(xml.toString()) except: return def _get_pickers_for_xml(self): string = ":" if self._gtk2.written: string += "gtk2:" if self._gtk3.written: string += "gtk3:" if self._fltk.written: string += "fltk:" if self._kde5.written: string += "kde5:" if self._qt4.written: string += "qt4:" if self._qt5.written: string += "qt5:" return string def set_daemon_port(self, port): self._daemon_port = port def make_all(self, spath): for picker in (self._gtk2, self._gtk3, self._fltk, self._kde5, self._qt4, self._qt5): picker.make_bookmark(spath) xml = self._get_xml() if not xml: return xml_content = xml.documentElement() bke = xml.createElement('bookmarker') bke.setAttribute('port', self._daemon_port) bke.setAttribute('session_path', spath) bke.setAttribute('pickers', self._get_pickers_for_xml()) xml_content.appendChild(bke) self._write_xml_file(xml) def remove_all(self, spath): for picker in (self._gtk2, self._gtk3, self._fltk, self._kde5, self._qt4, self._qt5): picker.remove_bookmark(spath) xml = self._get_xml() if not xml: return xml_content = xml.documentElement() nodes = xml_content.childNodes() for i in range(nodes.count()): node = nodes.at(i) bke = node.toElement() port = bke.attribute('port') session_path = bke.attribute('session_path') if (port.isdigit() and int(port) == self._daemon_port and session_path == spath): xml_content.removeChild(node) break self._write_xml_file(xml) def clean(self, all_session_paths): xml = self._get_xml() if not xml: return xml_content = xml.documentElement() nodes = xml_content.childNodes() nodes_to_remove = [] for i in range(nodes.count()): node = nodes.at(i) bke = node.toElement() spath = bke.attribute('session_path') pickers = bke.attribute('pickers') if not spath: nodes_to_remove.append(node) continue if not spath in all_session_paths: if ":gtk2:" in pickers: self._gtk2.written = True self._gtk2.remove_bookmark(spath) if ":gtk3:" in pickers: self._gtk3.written = True self._gtk3.remove_bookmark(spath) if ":fltk:" in pickers: self._fltk.written = True self._fltk.remove_bookmark(spath) if ":kde5:" in pickers: self._kde5.written = True self._kde5.remove_bookmark(spath) if ":qt4:" in pickers: self._qt4.written = True self._qt4.remove_bookmark(spath) if ":qt5:" in pickers: self._qt5.written = True self._qt5.remove_bookmark(spath) nodes_to_remove.append(node) for node in nodes_to_remove: xml_content.removeChild(node) self._write_xml_file(xml) if __name__ == '__main__': bm_maker = BookMarker() bm_maker.make_all(sys.argv[1]) RaySession-0.12.2/src/daemon/canvas_saver.py000066400000000000000000000204051417052567600207700ustar00rootroot00000000000000 import json import os import tempfile import time import ray from daemon_tools import RS, dirname, Terminal from server_sender import ServerSender JSON_PATH = 'ray_canvas.json' class CanvasSaver(ServerSender): def __init__(self, session): ServerSender.__init__(self) self.session = session self.group_positions_session = [] self.group_positions_config = [] self.portgroups = [] self._config_json_path = "%s/%s" % ( dirname(RS.settings.fileName()), JSON_PATH) if not os.path.exists(self._config_json_path): return with open(self._config_json_path, 'r') as f: json_contents = {} gpos_list = [] pg_list = [] try: json_contents = json.load(f) except json.JSONDecodeError: Terminal.message("Failed to load patchcanvas config file %s" % f) if type(json_contents) == dict: if 'group_positions' in json_contents.keys(): gpos_list = json_contents['group_positions'] if 'portgroups' in json_contents.keys(): pg_list = json_contents['portgroups'] for gpos_dict in gpos_list: gpos = ray.GroupPosition() gpos.write_from_dict(gpos_dict) self.group_positions_config.append(gpos) for pg_dict in pg_list: portgroup = ray.PortGroupMemory() portgroup.write_from_dict(pg_dict) self.portgroups.append(portgroup) def get_all_group_positions(self)->list: group_positions_config_exclu = [] for gpos_cf in self.group_positions_config: for gpos_ss in self.group_positions_session: if (gpos_ss.port_types_view == gpos_cf.port_types_view and gpos_ss.group_name == gpos_cf.group_name): break else: group_positions_config_exclu.append(gpos_cf) return self.group_positions_session + group_positions_config_exclu def send_session_group_positions(self): server = self.get_server() if not server: return local_guis = [] distant_guis = [] for gui_addr in server.gui_list: if ray.are_on_same_machine(server.url, gui_addr.url): local_guis.append(gui_addr) else: distant_guis.append(gui_addr) if local_guis: session_gpos_dict = {'group_positions': []} for gpos in self.group_positions_session: session_gpos_dict['group_positions'].append(gpos.to_dict()) for gui_addr in local_guis: file = tempfile.NamedTemporaryFile(delete=False, mode='w+') json.dump(session_gpos_dict, file) self.send(gui_addr, '/ray/gui/patchbay/fast_temp_file_memory', file.name) if distant_guis: for gui_addr in distant_guis: for gpos in self.group_positions_session: self.send(gui_addr, '/ray/gui/patchbay/update_group_position', *gpos.spread()) def send_all_group_positions(self, src_addr): if ray.are_on_same_machine(self.get_server_url(), src_addr.url): # GUI is on the same machine than the daemon # send group positions via a tmp file because they can be many # it can be faster, it also prevents to lose packets canvas_dict = {'group_positions': [], 'portgroups': []} for gpos in self.group_positions_session: canvas_dict['group_positions'].append(gpos.to_dict()) for gpos_cf in self.group_positions_config: for gpos_ss in self.group_positions_session: if (gpos_ss.port_types_view == gpos_cf.port_types_view and gpos_ss.group_name == gpos_cf.group_name): break else: canvas_dict['group_positions'].append(gpos_cf.to_dict()) for portgroup in self.portgroups: canvas_dict['portgroups'].append(portgroup.to_dict()) file = tempfile.NamedTemporaryFile(delete=False, mode='w+') json.dump(canvas_dict, file) file.close() self.send(src_addr, '/ray/gui/patchbay/fast_temp_file_memory', file.name) return i = 0 for gpos in self.group_positions_session: self.send(src_addr, '/ray/gui/patchbay/update_group_position', *gpos.spread()) i += 1 if i == 50: # we need to slow big process of canvas memory # to prevent loss OSC packets time.sleep(0.020) i = 0 for gpos_cf in self.group_positions_config: for gpos_ss in self.group_positions_session: if (gpos_ss.port_types_view == gpos_cf.port_types_view and gpos_ss.group_name == gpos_cf.group_name): break else: self.send(src_addr, '/ray/gui/patchbay/update_group_position', *gpos_cf.spread()) i += 1 if i == 50: time.sleep(0.020) i = 0 for portgroup in self.portgroups: self.send(src_addr, '/ray/gui/patchbay/update_portgroup', *portgroup.spread()) i += 1 if i == 50: time.sleep(0.020) def save_group_position(self, *args): gp = ray.GroupPosition.new_from(*args) for group_positions in (self.group_positions_session, self.group_positions_config): for gpos in group_positions: if gpos.is_same(gp): gpos.update(*args) break else: group_positions.append(gp) def load_json_session_canvas(self, session_path: str): self.group_positions_session.clear() session_canvas_file = "%s/.%s" % (session_path, JSON_PATH) if not os.path.exists(session_canvas_file): return with open(session_canvas_file, 'r') as f: json_contents = {} gpos_list = [] try: json_contents = json.load(f) except json.JSONDecodeError: Terminal.message("Failed to load session canvas file %s" % f) if (type(json_contents) == dict and 'group_positions' in json_contents.keys()): gpos_list = json_contents['group_positions'] for gpos_dict in gpos_list: gpos = ray.GroupPosition() gpos.write_from_dict(gpos_dict) self.group_positions_session.append(gpos) def save_json_session_canvas(self, session_path: str): session_json_path = "%s/.%s" % (session_path, JSON_PATH) if not self.group_positions_session: return json_contents = {} json_contents['group_positions'] = [ gpos.to_dict() for gpos in self.group_positions_session] with open(session_json_path, 'w+') as f: json.dump(json_contents, f, indent=2) def save_config_file(self): if not self.group_positions_config: return json_contents = {} json_contents['group_positions'] = [ gpos.to_dict() for gpos in self.group_positions_config] json_contents['portgroups'] = [ portgroup.to_dict() for portgroup in self.portgroups] with open(self._config_json_path, 'w+') as f: json.dump(json_contents, f, indent=2) def save_portgroup(self, *args): new_portgroup = ray.PortGroupMemory.new_from(*args) remove_list = [] # remove any portgroup with a commmon port with the new one for portgroup in self.portgroups: if portgroup.has_a_common_port_with(new_portgroup): remove_list.append(portgroup) for portgroup in remove_list: self.portgroups.remove(portgroup) self.portgroups.append(new_portgroup) RaySession-0.12.2/src/daemon/client.py000066400000000000000000002515021417052567600175770ustar00rootroot00000000000000import os import shlex import shutil import signal import subprocess import time from liblo import Address from PyQt5.QtCore import (QCoreApplication, QProcess, QProcessEnvironment, QTimer) from PyQt5.QtXml import QDomDocument import ray from server_sender import ServerSender from daemon_tools import (TemplateRoots, Terminal, RS, get_code_root, highlight_text) from signaler import Signaler from scripter import ClientScripter NSM_API_VERSION_MAJOR = 1 NSM_API_VERSION_MINOR = 0 OSC_SRC_START = 0 OSC_SRC_OPEN = 1 OSC_SRC_SAVE = 2 OSC_SRC_SAVE_TP = 3 OSC_SRC_STOP = 4 _translate = QCoreApplication.translate signaler = Signaler.instance() def basename(*args): return os.path.basename(*args) class Client(ServerSender, ray.ClientData): _reply_errcode = 0 _reply_message = None #can be directly changed by OSC thread gui_visible = False gui_has_been_visible = False show_gui_ordered = False dirty = 0 progress = 0 #have to be modified by main thread for security addr = None pid = 0 pending_command = ray.Command.NONE active = False did_announce = False status = ray.ClientStatus.STOPPED running_executable = '' running_arguments = '' tmp_arguments = '' auto_start = True start_gui_hidden = False no_save_level = 0 is_external = False sent_to_gui = False switch_state = ray.SwitchState.NONE last_save_time = 0.00 last_dirty = 0.00 _last_announce_time = 0.00 last_open_duration = 0.00 has_been_started = False _desktop_label = "" _desktop_icon = "" _desktop_description = "" jack_naming = ray.JackNaming.SHORT def __init__(self, parent_session): ServerSender.__init__(self) self.session = parent_session self.is_dummy = self.session.is_dummy # process_env = QProcessEnvironment.systemEnvironment() # process_env.insert('NSM_URL', self.get_server_url()) self.custom_data = {} self.custom_tmp_data = {} self._process = QProcess() self._process.started.connect(self._process_started) if ray.QT_VERSION >= (5, 6): self._process.errorOccurred.connect(self._error_in_process) self._process.finished.connect(self._process_finished) self._process.readyReadStandardError.connect(self._standard_error) self._process.readyReadStandardOutput.connect(self._standard_output) # self._process.setProcessEnvironment(process_env) #if client is'n't stopped 2secs after stop, #another stop becames a kill! self._stopped_since_long_ = False self._stopped_timer = QTimer() self._stopped_timer.setSingleShot(True) self._stopped_timer.setInterval(2000) #2sec self._stopped_timer.timeout.connect(self._stopped_since_long) self.net_daemon_copy_timer = QTimer() self.net_daemon_copy_timer.setSingleShot(True) self.net_daemon_copy_timer.setInterval(3000) self.net_daemon_copy_timer.timeout.connect(self._net_daemon_out_of_time) # stock osc src_addr and src_path of respectively # start, open, save, save_tp, stop self._osc_srcs = [(None, ''), (None, ''), (None, ''), (None, ''), (None, '')] self._open_timer = QTimer() self._open_timer.setSingleShot(True) self._open_timer.timeout.connect(self._open_timer_timeout) self.ray_hack = ray.RayHack() self.ray_net = ray.RayNet() self.scripter = ClientScripter(self) self.ray_hack_waiting_win = False @staticmethod def short_client_id(wanted:str)->str: if '_' in wanted: begin, udsc, end = wanted.rpartition('_') if not end: return wanted if not end.isdigit(): return wanted return begin return wanted def _standard_error(self): standard_error = self._process.readAllStandardError().data() Terminal.client_message(standard_error, self.name, self.client_id) def _standard_output(self): standard_output = self._process.readAllStandardOutput().data() Terminal.client_message(standard_output, self.name, self.client_id) def _process_started(self): self.has_been_started = True self._stopped_since_long_ = False self.pid = self._process.pid() self.set_status(ray.ClientStatus.LAUNCH) #Terminal.message("Process has pid: %i" % self.pid) self.send_gui_message(_translate("GUIMSG", " %s: launched") % self.gui_msg_style()) self.session.send_monitor_event('started', self.client_id) self._send_reply_to_caller(OSC_SRC_START, 'client started') if self.is_ray_hack(): if self.noSaveLevel(): self.send_gui('/ray/gui/client/no_save_level', self.client_id, self.noSaveLevel()) if self.ray_hack.config_file: self.pending_command = ray.Command.OPEN self.set_status(ray.ClientStatus.OPEN) QTimer.singleShot(500, self._ray_hack_near_ready) def _process_finished(self, exit_code, exit_status): self._stopped_timer.stop() self.is_external = False if self.pending_command == ray.Command.STOP: self.send_gui_message(_translate('GUIMSG', " %s: terminated by server instruction") % self.gui_msg_style()) self.session.send_monitor_event( 'client_stopped_by_server', self.client_id) else: self.send_gui_message(_translate('GUIMSG', " %s: terminated itself.") % self.gui_msg_style()) self.session.send_monitor_event( 'client_stopped_by_itself', self.client_id) self._send_reply_to_caller(OSC_SRC_STOP, 'client stopped') for osc_src in (OSC_SRC_OPEN, OSC_SRC_SAVE): self._send_error_to_caller(osc_src, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s died !' % self.gui_msg_style())) self.set_status(ray.ClientStatus.STOPPED) self.pending_command = ray.Command.NONE self.active = False self.pid = 0 self.addr = None self.session.set_renameable(True) if self.scripter.pending_command() == ray.Command.STOP: return if self.session.wait_for: self.session.end_timer_if_last_expected(self) def _error_in_process(self, error): if error == QProcess.FailedToStart: self.send_gui_message( _translate('GUIMSG', " %s: Failed to start !") % self.gui_msg_style()) self.active = False self.pid = 0 self.set_status(ray.ClientStatus.STOPPED) self.pending_command = ray.Command.NONE if self.session.osc_src_addr: error_message = "Failed to launch process!" if not self.session.osc_path.startswith('/nsm/server/'): error_message = _translate( 'client', " %s: Failed to launch process !" % self.gui_msg_style()) self.session.osc_reply( "/error", self.session.osc_path, ray.Err.LAUNCH_FAILED, error_message) for osc_slot in (OSC_SRC_START, OSC_SRC_OPEN): self._send_error_to_caller(osc_slot, ray.Err.LAUNCH_FAILED, _translate('GUIMSG', '%s failed to launch') % self.gui_msg_style()) if self.session.wait_for: self.session.end_timer_if_last_expected(self) self.session.set_renameable(True) def _stopped_since_long(self): self._stopped_since_long_ = True self.send_gui('/ray/gui/client/still_running', self.client_id) def _send_reply_to_caller(self, slot, message): src_addr, src_path = self._osc_srcs[slot] if src_addr: self.send(src_addr, '/reply', src_path, message) self._osc_srcs[slot] = (None, '') if (self.scripter.is_running() and self.scripter.pending_command() == self.pending_command): self._osc_srcs[slot] = self.scripter.initial_caller() if slot == OSC_SRC_OPEN: self._open_timer.stop() def _send_error_to_caller(self, slot, err, message): src_addr, src_path = self._osc_srcs[slot] if src_addr: self.send(src_addr, '/error', src_path, err, message) self._osc_srcs[slot] = (None, '') if (self.scripter.is_running() and self.scripter.pending_command() == self.pending_command): self._osc_srcs[slot] = self.scripter.initial_caller() if slot == OSC_SRC_OPEN: self._open_timer.stop() def _open_timer_timeout(self): self._send_error_to_caller(OSC_SRC_OPEN, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s is started but not active') % self.gui_msg_style()) def _send_status_to_gui(self): self.send_gui('/ray/gui/client/status', self.client_id, self.status) def _net_daemon_out_of_time(self): self.ray_net.duplicate_state = -1 if self.session.wait_for == ray.WaitFor.DUPLICATE_FINISH: self.session.end_timer_if_last_expected(self) def _pretty_client_id(self): wanted = self.client_id if self.executable_path == 'ray-proxy': proxy_file = "%s/ray-proxy.xml" % self.get_project_path() if os.path.exists(proxy_file): file = open(proxy_file, 'r') xml = QDomDocument() xml.setContent(file.read()) file.close() content = xml.documentElement() if content.tagName() == 'RAY-PROXY': executable = content.attribute('executable') if executable: wanted = executable return self.short_client_id(wanted) def _get_proxy_executable(self): if os.path.basename(self.executable_path) != 'ray-proxy': return "" xml_file = "%s/ray-proxy.xml" % self.get_project_path() xml = QDomDocument() try: file = open(xml_file, 'r') xml.setContent(file.read()) except: return "" content = xml.documentElement() if content.tagName() != "RAY-PROXY": file.close() return "" executable = content.attribute('executable') file.close() return executable def _ray_hack_near_ready(self): if not self.is_ray_hack(): return if not self.is_running(): return if self.ray_hack.wait_win: self.ray_hack_waiting_win = True if not self.session.window_waiter.isActive(): self.session.window_waiter.start() else: self.ray_hack_ready() def _ray_hack_saved(self): if not self.is_ray_hack(): return if self.pending_command == ray.Command.SAVE: self.pending_command = ray.Command.NONE self.set_status(ray.ClientStatus.READY) self.last_save_time = time.time() self.send_gui_message( _translate('GUIMSG', ' %s: saved') % self.gui_msg_style()) self._send_reply_to_caller(OSC_SRC_SAVE, 'client saved.') if self.session.wait_for == ray.WaitFor.REPLY: self.session.end_timer_if_last_expected(self) def _set_infos_from_desktop_contents(self, contents: str): lang = os.getenv('LANG') lang_strs = ("[%s]" % lang[0:5], "[%s]" % lang[0:2], "") all_data = {'Comment': ['', '', ''], 'Name': ['', '', ''], 'Icon': ['', '', '']} for line in contents.split('\n'): if line.startswith('[') and line != "[Desktop Entry]": break if '=' not in line: continue var, egal, value = line.partition('=') found = False for searched in all_data: for i in range(len(lang_strs)): lang_str = lang_strs[i] if var == searched + lang_str: all_data[searched][i] = value found = True break if found: break for data in all_data: for str_value in all_data[data]: if data == "Comment": if str_value and not self.description: self._desktop_description = str_value self.description = str_value break elif data == "Name": if str_value and not self.label: self._desktop_label = str_value self.label = str_value break elif data == "Icon": if str_value and not self.icon: self._desktop_icon = str_value self.icon = str_value break def _rename_files( self, spath, old_session_name, new_session_name, old_prefix, new_prefix, old_client_id, new_client_id, old_client_links_dir, new_client_links_dir): # rename client script dir scripts_dir = "%s/%s.%s" % (spath, ray.SCRIPTS_DIR, old_client_id) if os.access(scripts_dir, os.W_OK) and old_client_id != new_client_id: os.rename(scripts_dir, "%s/%s.%s" % (spath, ray.SCRIPTS_DIR, new_client_id)) project_path = "%s/%s.%s" % (spath, old_prefix, old_client_id) files_to_rename = [] do_rename = True if self.is_ray_hack(): if os.path.isdir(project_path): if not os.access(project_path, os.W_OK): do_rename = False else: os.environ['RAY_SESSION_NAME'] = old_session_name os.environ['RAY_CLIENT_ID'] = old_client_id pre_config_file = os.path.expandvars( self.ray_hack.config_file) os.environ['RAY_SESSION_NAME'] = new_session_name os.environ['RAY_CLIENT_ID'] = new_client_id post_config_file = os.path.expandvars( self.ray_hack.config_file) os.unsetenv('RAY_SESSION_NAME') os.unsetenv('RAY_CLIENT_ID') full_pre_config_file = "%s/%s" % (project_path, pre_config_file) full_post_config_file = "%s/%s" % (project_path, post_config_file) if os.path.exists(full_pre_config_file): files_to_rename.append((full_pre_config_file, full_post_config_file)) files_to_rename.append((project_path, "%s/%s.%s" % (spath, new_prefix, new_client_id))) else: for file_path in os.listdir(spath): if file_path.startswith("%s.%s." % (old_prefix, old_client_id)): if not os.access("%s/%s" % (spath, file_path), os.W_OK): do_rename = False break endfile = file_path.replace( "%s.%s." % (old_prefix, old_client_id), '', 1) next_path = "%s/%s.%s.%s" % (spath, new_prefix, new_client_id, endfile) if os.path.exists(next_path): do_rename = False break files_to_rename.append(("%s/%s" % (spath, file_path), next_path)) elif file_path == "%s.%s" % (old_prefix, old_client_id): if not os.access("%s/%s" % (spath, file_path), os.W_OK): do_rename = False break next_path = "%s/%s.%s" % (spath, new_prefix, new_client_id) if os.path.exists(next_path): do_rename = False break # only for hydrogen hydrogen_file = "%s/%s.%s.h2song" % ( project_path, old_prefix, old_client_id) hydrogen_autosave = "%s/%s.%s.autosave.h2song" % ( project_path, old_prefix, old_client_id) if (os.path.isfile(hydrogen_file) and os.access(hydrogen_file, os.W_OK)): new_hydro_file = "%s/%s.%s.h2song" % ( project_path, new_prefix, new_client_id) if os.path.exists(new_hydro_file): do_rename = False break files_to_rename.append((hydrogen_file, new_hydro_file)) if (os.path.isfile(hydrogen_autosave) and os.access(hydrogen_autosave, os.W_OK)): new_hydro_autosave = "%s/%s.%s.autosave.h2song" % ( project_path, new_prefix, new_client_id) if os.path.exists(new_hydro_autosave): do_rename = False break files_to_rename.append((hydrogen_autosave, new_hydro_autosave)) # only for ardour ardour_file = "%s/%s.ardour" % (project_path, old_prefix) ardour_bak = "%s/%s.ardour.bak" % (project_path, old_prefix) ardour_audio = "%s/interchange/%s.%s" % (project_path, old_prefix, old_client_id) if os.path.isfile(ardour_file) and os.access(ardour_file, os.W_OK): new_ardour_file = "%s/%s.ardour" % (project_path, new_prefix) if os.path.exists(new_ardour_file): do_rename = False break files_to_rename.append((ardour_file, new_ardour_file)) # change ardour session name try: file = open(ardour_file, 'r') xml = QDomDocument() xml.setContent(file.read()) file.close() root = xml.documentElement() if root.tagName() == 'Session': root.setAttribute('name', new_prefix) file = open(ardour_file, 'w') file.write(xml.toString()) except: False if os.path.isfile(ardour_bak) and os.access(ardour_bak, os.W_OK): new_ardour_bak = "%s/%s.ardour.bak" % (project_path, new_prefix) if os.path.exists(new_ardour_bak): do_rename = False break files_to_rename.append((ardour_bak, new_ardour_bak)) if os.path.isdir(ardour_audio) and os.access(ardour_audio, os.W_OK): new_ardour_audio = "%s/interchange/%s.%s" % (project_path, new_prefix, new_client_id) if os.path.exists(new_ardour_audio): do_rename = False break files_to_rename.append((ardour_audio, new_ardour_audio)) # for Vee One Suite for extfile in ('samplv1', 'synthv1', 'padthv1', 'drumkv1'): old_veeone_file = "%s/%s.%s" % (project_path, old_session_name, extfile) new_veeone_file = "%s/%s.%s" % (project_path, new_session_name, extfile) if (os.path.isfile(old_veeone_file) and os.access(old_veeone_file, os.W_OK)): if os.path.exists(new_veeone_file): do_rename = False break files_to_rename.append((old_veeone_file, new_veeone_file)) # for ray-proxy, change config_file name proxy_file = "%s/ray-proxy.xml" % project_path if os.path.isfile(proxy_file): try: file = open(proxy_file, 'r') xml = QDomDocument() xml.setContent(file.read()) file.close() content = xml.documentElement() if content.tagName() == "RAY-PROXY": cte = content.toElement() config_file = cte.attribute('config_file') if (('$RAY_SESSION_NAME' or '${RAY_SESSION_NAME}') in config_file): for env in ('"$RAY_SESSION_NAME"', '"${RAY_SESSION_NAME}"', "$RAY_SESSION_NAME", "${RAY_SESSION_NAME}"): config_file = \ config_file.replace(env, old_session_name) if (config_file and (config_file.split('.')[0] == old_session_name)): config_file_path = "%s/%s" % ( project_path, config_file) new_config_file_path = "%s/%s" % ( project_path, config_file.replace(old_session_name, new_session_name)) if os.path.exists(new_config_file_path): # replace config_file attribute # with variable replaced cte.setAttribute('config_file', config_file) try: file = open(proxy_file, 'w') file.write(xml.toString()) except: False elif (os.path.exists(config_file_path) and os.access(config_file_path, os.W_OK)): files_to_rename.append( (config_file_path, new_config_file_path)) except: False files_to_rename.append(("%s/%s" % (spath, file_path), next_path)) elif file_path == old_client_links_dir: # this section only concerns Carla links dir # used to save links for convolutions files or soundfonts # or any other linked resource. if old_client_links_dir == new_client_links_dir: continue full_old_client_links_dir = os.path.join(spath, file_path) if not os.path.isdir(full_old_client_links_dir): continue if not os.access(full_old_client_links_dir, os.W_OK): do_rename = False break files_to_rename.append( (full_old_client_links_dir, os.path.join(spath, new_client_links_dir))) if not do_rename: self.prefix_mode = ray.PrefixMode.CUSTOM self.custom_prefix = old_prefix # it should not be a client_id problem here return # change last_used snapshot of ardour instant_file = "%s/instant.xml" % project_path if os.path.isfile(instant_file) and os.access(instant_file, os.W_OK): try: file = open(instant_file, 'r') xml = QDomDocument() xml.setContent(file.read()) file.close() content = xml.documentElement() if content.tagName() == 'instant': node = content.firstChild() while not node.isNull(): tag = node.toElement() if tag.tagName() == 'LastUsedSnapshot': if tag.attribute('name') == old_prefix: tag.setAttribute('name', new_prefix) file = open(instant_file, 'w') file.write(xml.toString()) break node = node.nextSibling() except: False for now_path, next_path in files_to_rename: os.rename(now_path, next_path) def _save_as_template_substep1(self, template_name): self.set_status(self.status) # see set_status to see why if self.prefix_mode != ray.PrefixMode.CUSTOM: self.adjust_files_after_copy(template_name, ray.Template.CLIENT_SAVE) xml_file = "%s/%s" % (TemplateRoots.user_clients, 'client_templates.xml') # security check if os.path.exists(xml_file): if not os.access(xml_file, os.W_OK): self._send_error_to_caller( OSC_SRC_SAVE_TP, ray.Err.CREATE_FAILED, _translate('GUIMSG', '%s is not writeable !') % xml_file) return if os.path.isdir(xml_file): #should not be a dir, remove it ! shutil.rmtree(xml_file) if not os.path.isdir(TemplateRoots.user_clients): os.makedirs(TemplateRoots.user_clients) #create client_templates.xml if not exists if not os.path.isfile(xml_file): file = open(xml_file, 'w') xml = QDomDocument() rct = xml.createElement('RAY-CLIENT-TEMPLATES') xml.appendChild(rct) file.write(xml.toString()) file.close() del xml file = open(xml_file, 'r') xml = QDomDocument() xml.setContent(file.read()) file.close() content = xml.documentElement() if not content.tagName() == 'RAY-CLIENT-TEMPLATES': return # remove existing template if it has the same name as the new one node = content.firstChild() while not node.isNull(): if node.toElement().tagName() != 'Client-Template': node = node.nextSibling() continue if node.toElement().attribute('template-name') == template_name: content.removeChild(node) node = node.nextSibling() #create template rct = xml.createElement('Client-Template') self.write_xml_properties(rct) rct.setAttribute('template-name', template_name) rct.setAttribute('client_id', self._pretty_client_id()) if not self.is_running(): rct.setAttribute('launched', False) content.appendChild(rct) file = open(xml_file, 'w') file.write(xml.toString()) file.close() self.template_origin = template_name self.send_gui_client_properties() template_data_base_users = self.get_client_templates_database('user') template_data_base_users.clear() self.send_gui_message( _translate('message', 'Client template %s created') % template_name) self._send_reply_to_caller(OSC_SRC_SAVE_TP, 'client template created') def _save_as_template_aborted(self, template_name): self.set_status(self.status) self._send_error_to_caller(OSC_SRC_SAVE_TP, ray.Err.COPY_ABORTED, _translate('GUIMSG', 'Copy has been aborted !')) def get_links_dir(self)->str: ''' returns the dir path used by carla for links such as audio convolutions or soundfonts ''' links_dir = self.get_jack_client_name() for c in ('-', '.'): links_dir = links_dir.replace(c, '_') return links_dir def is_ray_hack(self)->bool: return bool(self.protocol == ray.Protocol.RAY_HACK) def send_to_self_address(self, *args): if not self.addr: return self.send(self.addr, *args) def message(self, message: str): if self.session is None: return self.session.message(message) def get_jack_client_name(self): if self.protocol == ray.Protocol.RAY_NET: # ray-net will use jack_client_name for template # quite dirty, but this is the easier way return self.ray_net.session_template # return same jack_client_name as NSM does # if client seems to have been made by NSM itself # else, jack connections could be lose # at NSM session import if self.jack_naming == ray.JackNaming.LONG: return "%s.%s" % (self.name, self.client_id) jack_client_name = self.name # Mostly for ray_hack if not jack_client_name: jack_client_name = os.path.basename(self.executable_path) jack_client_name.capitalize() numid = '' if '_' in self.client_id: numid = self.client_id.rpartition('_')[2] if numid.isdigit(): jack_client_name += '_' jack_client_name += numid return jack_client_name def read_xml_properties(self, ctx): #ctx is an xml sibling for client self.executable_path = ctx.attribute('executable') self.arguments = ctx.attribute('arguments') self.name = ctx.attribute('name') self.desktop_file = ctx.attribute('desktop_file') self.label = ctx.attribute('label') self.description = ctx.attribute('description') self.icon = ctx.attribute('icon') self.auto_start = bool(ctx.attribute('launched') != '0') self.check_last_save = bool(ctx.attribute('check_last_save') != '0') self.start_gui_hidden = bool(ctx.attribute('gui_visible') == '0') self.template_origin = ctx.attribute('template_origin') if (ctx.attribute('from_nsm_file') == '1' or ctx.attribute('jack_naming') in ('1', 'long')): self.jack_naming = ray.JackNaming.LONG # ensure client has a name if not self.name: self.name = basename(self.executable_path) self.update_infos_from_desktop_file() ign_exts = ctx.attribute('ignored_extensions').split(' ') unign_exts = ctx.attribute('unignored_extensions').split(' ') global_exts = ray.GIT_IGNORED_EXTENSIONS.split(' ') self.ignored_extensions = "" for ext in global_exts: if ext and not ext in unign_exts: self.ignored_extensions += " %s" % ext for ext in ign_exts: if ext and not ext in global_exts: self.ignored_extensions += " %s" % ext open_duration = ctx.attribute('last_open_duration') if open_duration.replace('.', '', 1).isdigit(): self.last_open_duration = float(open_duration) prefix_mode = ctx.attribute('prefix_mode') if (prefix_mode and prefix_mode.isdigit() and 0 <= int(prefix_mode) <= 2): self.prefix_mode = int(prefix_mode) if self.prefix_mode == ray.PrefixMode.CUSTOM: self.custom_prefix = ctx.attribute('custom_prefix') self.protocol = ray.protocol_from_str(ctx.attribute('protocol')) if self.protocol == ray.Protocol.RAY_HACK: self.ray_hack.config_file = ctx.attribute('config_file') ray_hack_save_sig = ctx.attribute('save_signal') if ray_hack_save_sig.isdigit(): self.ray_hack.save_sig = int(ray_hack_save_sig) ray_hack_stop_sig = ctx.attribute('stop_signal') if ray_hack_stop_sig.isdigit(): self.ray_hack.stop_sig = int(ray_hack_stop_sig) self.ray_hack.wait_win = bool(ctx.attribute('wait_window') == "1") no_save_level = ctx.attribute('no_save_level') if no_save_level.isdigit() and 0 <= int(no_save_level) <= 2: self.ray_hack.no_save_level = int(no_save_level) # backward compatibility with network session if (self.protocol == ray.Protocol.NSM and basename(self.executable_path) == 'ray-network'): self.protocol = ray.Protocol.RAY_NET if self.arguments: eat_url = eat_root = False for arg in shlex.split(self.arguments): if arg in ('--daemon-url', '-u'): eat_url = True continue elif arg in ('--session-root', '-r'): eat_root = True continue elif not (eat_url or eat_root): eat_url = False eat_root = False continue if eat_url: self.ray_net.daemon_url = arg eat_url = False elif eat_root: self.ray_net.session_root = arg eat_root = False self.ray_net.session_template = ctx.attribute('net_session_template') elif self.protocol == ray.Protocol.RAY_NET: self.ray_net.daemon_url = ctx.attribute('net_daemon_url') self.ray_net.session_root = ctx.attribute('net_session_root') self.ray_net.session_template = ctx.attribute('net_session_template') if self.protocol == ray.Protocol.RAY_NET: # neeeded only to know if RAY_NET client is capable of switch self.executable_path = ray.RAYNET_BIN if self.ray_net.daemon_url and self.ray_net.session_root: self.arguments = self.get_ray_net_arguments_line() if ctx.attribute('id'): # session uses "id" for absolutely needed client_id self.client_id = ctx.attribute('id') else: # template uses "client_id" for wanted client_id self.client_id = self.session.generate_client_id( ctx.attribute('client_id')) nodes = ctx.childNodes() for i in range(nodes.count()): node = nodes.at(i) el = node.toElement() if el.tagName() == 'custom_data': attributes = el.attributes() for j in range(attributes.count()): attribute = attributes.item(j) attribute_str = attribute.toAttr().name() value = el.attribute(attribute_str) self.custom_data[attribute_str] = value def write_xml_properties(self, ctx): if self.protocol != ray.Protocol.RAY_NET: ctx.setAttribute('executable', self.executable_path) if self.arguments: ctx.setAttribute('arguments', self.arguments) ctx.setAttribute('name', self.name) if self.desktop_file: ctx.setAttribute('desktop_file', self.desktop_file) if self.label != self._desktop_label: ctx.setAttribute('label', self.label) if self.description != self._desktop_description: ctx.setAttribute('description', self.description) if self.icon != self._desktop_icon: ctx.setAttribute('icon', self.icon) if not self.check_last_save: ctx.setAttribute('check_last_save', 0) if self.prefix_mode != ray.PrefixMode.SESSION_NAME: ctx.setAttribute('prefix_mode', self.prefix_mode) if self.prefix_mode == ray.PrefixMode.CUSTOM: ctx.setAttribute('custom_prefix', self.custom_prefix) if self.is_capable_of(':optional-gui:'): ctx.setAttribute('gui_visible', str(int(not self.start_gui_hidden))) if self.jack_naming == ray.JackNaming.LONG: ctx.setAttribute('jack_naming', ray.JackNaming.LONG) if self.template_origin: ctx.setAttribute('template_origin', self.template_origin) if self.protocol != ray.Protocol.NSM: ctx.setAttribute('protocol', ray.protocol_to_str(self.protocol)) if self.protocol == ray.Protocol.RAY_HACK: ctx.setAttribute('config_file', self.ray_hack.config_file) ctx.setAttribute('save_signal', self.ray_hack.save_sig) ctx.setAttribute('stop_signal', self.ray_hack.stop_sig) ctx.setAttribute('wait_win', int(self.ray_hack.wait_win)) ctx.setAttribute('no_save_level', self.ray_hack.no_save_level) elif self.protocol == ray.Protocol.RAY_NET: ctx.setAttribute('net_daemon_url', self.ray_net.daemon_url) ctx.setAttribute('net_session_root', self.ray_net.session_root) ctx.setAttribute('net_session_template', self.ray_net.session_template) if self.ignored_extensions != ray.GIT_IGNORED_EXTENSIONS: ignored = "" unignored = "" client_exts = [e for e in self.ignored_extensions.split(' ') if e] global_exts = [e for e in ray.GIT_IGNORED_EXTENSIONS.split(' ') if e] for cext in client_exts: if not cext in global_exts: ignored += " %s" % cext for gext in global_exts: if not gext in client_exts: unignored += " %s" % gext if ignored: ctx.setAttribute('ignored_extensions', ignored) else: ctx.removeAttribute('ignored_extensions') if unignored: ctx.setAttribute('unignored_extensions', unignored) else: ctx.removeAttribute('unignored_extensions') if self.last_open_duration >= 5.0: ctx.setAttribute('last_open_duration', str(self.last_open_duration)) if self.custom_data: xml = QDomDocument() cdt_xml = xml.createElement('custom_data') for data in self.custom_data: cdt_xml.setAttribute(data, self.custom_data[data]) ctx.appendChild(cdt_xml) def set_reply(self, errcode, message): self._reply_message = message self._reply_errcode = errcode if self._reply_errcode: self.message("Client \"%s\" replied with error: %s (%i)" % (self.name, message, errcode)) if self.pending_command == ray.Command.SAVE: self._send_error_to_caller(OSC_SRC_SAVE, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s failed to save!') % self.gui_msg_style()) self.session.send_monitor_event( 'save_error', self.client_id) elif self.pending_command == ray.Command.OPEN: self._send_error_to_caller(OSC_SRC_OPEN, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s failed to open!') % self.gui_msg_style()) self.session.send_monitor_event( 'open_error', self.client_id) self.set_status(ray.ClientStatus.ERROR) else: if self.pending_command == ray.Command.SAVE: self.last_save_time = time.time() self.send_gui_message( _translate('GUIMSG', ' %s: saved') % self.gui_msg_style()) self._send_reply_to_caller(OSC_SRC_SAVE, 'client saved.') self.session.send_monitor_event( 'saved', self.client_id) elif self.pending_command == ray.Command.OPEN: self.send_gui_message( _translate('GUIMSG', ' %s: project loaded') % self.gui_msg_style()) self.last_open_duration = \ time.time() - self._last_announce_time self._send_reply_to_caller(OSC_SRC_OPEN, 'client opened') self.session.send_monitor_event( 'ready', self.client_id) if self.has_server_option(ray.Option.GUI_STATES): if (self.session.wait_for == ray.WaitFor.NONE and self.is_capable_of(':optional-gui:') and not self.start_gui_hidden and not self.gui_visible and not self.gui_has_been_visible): self.send_to_self_address('/nsm/client/show_optional_gui') self.set_status(ray.ClientStatus.READY) #self.message( "Client \"%s\" replied with: %s in %fms" #% (client.name, message, #client.milliseconds_since_last_command())) if (self.scripter.is_running() and self.scripter.pending_command() == self.pending_command): return self.pending_command = ray.Command.NONE if self.session.wait_for == ray.WaitFor.REPLY: self.session.end_timer_if_last_expected(self) def set_label(self, label:str): self.label = label self.send_gui_client_properties() def has_error(self)->bool: return bool(self._reply_errcode) def is_reply_pending(self)->bool: return bool(self.pending_command) def is_dumb_client(self)->bool: if self.is_ray_hack(): return False return bool(not self.did_announce) def is_capable_of(self, capability: str)->bool: return bool(capability in self.capabilities) def gui_msg_style(self)->str: return "%s (%s)" % (self.name, self.client_id) def set_network_properties(self, net_daemon_url, net_session_root): if self.protocol != ray.Protocol.RAY_NET: return self.ray_net.daemon_url = net_daemon_url self.ray_net.running_daemon_url = net_daemon_url self.ray_net.session_root = net_session_root self.ray_net.running_session_root = net_session_root self.send_gui_client_properties() def get_ray_net_arguments_line(self)->str: if self.protocol != ray.Protocol.RAY_NET: return '' return '--daemon-url %s --net-session-root "%s"' % ( self.ray_net.daemon_url, self.ray_net.session_root.replace('"', '\\"')) def set_status(self, status): # ray.ClientStatus.COPY is not a status as the other ones. # GUI needs to know if client is started/open/stopped while files are # copied, so self.status doesn't remember ray.ClientStatus.COPY, # although it is sent to GUI if status != ray.ClientStatus.COPY: self.status = status self._send_status_to_gui() if (status == ray.ClientStatus.COPY or self.session.file_copier.is_active(self.client_id)): self.send_gui("/ray/gui/client/status", self.client_id, ray.ClientStatus.COPY) def get_prefix_string(self): if self.prefix_mode == ray.PrefixMode.SESSION_NAME: return self.session.name if self.prefix_mode == ray.PrefixMode.CLIENT_NAME: return self.name if self.prefix_mode == ray.PrefixMode.CUSTOM: return self.custom_prefix return '' def get_project_path(self): if self.protocol == ray.Protocol.RAY_NET: return self.session.get_short_path() if self.prefix_mode == ray.PrefixMode.SESSION_NAME: return "%s/%s.%s" % (self.session.path, self.session.name, self.client_id) if self.prefix_mode == ray.PrefixMode.CLIENT_NAME: return "%s/%s.%s" % (self.session.path, self.name, self.client_id) if self.prefix_mode == ray.PrefixMode.CUSTOM: return "%s/%s.%s" % (self.session.path, self.custom_prefix, self.client_id) # should not happens return "%s/%s.%s" % (self.session.path, self.session.name, self.client_id) def set_default_git_ignored(self, executable=""): executable = executable if executable else self.executable_path executable = os.path.basename(executable) if executable == 'ray-proxy': executable = self._get_proxy_executable() if executable in ( 'ardour', 'ardour4', 'ardour5', 'ardour6', 'Ardour', 'Ardour4', 'Ardour5', 'Ardour6', 'qtractor'): self.ignored_extensions += " .mid" elif executable in ('luppp', 'sooperlooper', 'sooperlooper_nsm'): if '.wav' in self.ignored_extensions: self.ignored_extensions = \ self.ignored_extensions.replace('.wav', '') elif executable == 'samplv1_jack': for ext in ('.wav', '.flac', '.ogg', '.mp3'): if ext in self.ignored_extensions: self.ignored_extensions = \ self.ignored_extensions.replace(ext, '') def start(self, src_addr=None, src_path='', wait_open_to_reply=False): if src_addr and not wait_open_to_reply: self._osc_srcs[OSC_SRC_START] = (src_addr, src_path) self.session.set_renameable(False) self.last_dirty = 0.00 self.gui_has_been_visible = False self.gui_visible = False self.show_gui_ordered = False if self.is_dummy: self._send_error_to_caller(OSC_SRC_START, ray.Err.GENERAL_ERROR, _translate('GUIMSG', "can't start %s, it is a dummy client !") % self.gui_msg_style()) return if (self.protocol == ray.Protocol.RAY_NET and not self.session.path.startswith(self.session.root + '/')): self._send_error_to_caller(OSC_SRC_START, ray.Err.GENERAL_ERROR, _translate('GUIMSG', "Impossible to run Ray-Net client when session is not in root folder")) return if self.scripter.start(ray.Command.START, src_addr, self._osc_srcs[OSC_SRC_START]): self.set_status(ray.ClientStatus.SCRIPT) return self.pending_command = ray.Command.START process_env = QProcessEnvironment.systemEnvironment() pre_env_splitted = shlex.split(self.pre_env) for pes in pre_env_splitted: if not '=' in pes: continue envvar, egal, value = pes.partition('=') if envvar: process_env.insert(envvar, value) if self.protocol != ray.Protocol.RAY_HACK: process_env.insert('NSM_URL', self.get_server_url()) arguments = [] if self.protocol == ray.Protocol.RAY_NET: server = self.get_server() if not server: return arguments += ['--net-daemon-id', str(server.net_daemon_id)] if self.ray_net.daemon_url: arguments += ['--daemon-url', self.ray_net.daemon_url] if self.ray_net.session_root: arguments += ['--session-root', self.ray_net.session_root] self.ray_net.running_daemon_url = self.ray_net.daemon_url self.ray_net.running_session_root = self.ray_net.session_root self._process.setProcessEnvironment(process_env) self._process.start(ray.RAYNET_BIN, arguments) return if self.tmp_arguments: arguments += shlex.split(self.tmp_arguments) arguments_line = self.arguments if self.is_ray_hack(): all_envs = {'CONFIG_FILE': ('', ''), 'RAY_SESSION_NAME': ('', ''), 'RAY_CLIENT_ID': ('', ''), 'RAY_JACK_CLIENT_NAME': ('', '')} all_envs['RAY_SESSION_NAME'] = (os.getenv('RAY_SESSION_NAME'), self.session.name) all_envs['RAY_CLIENT_ID'] = (os.getenv('RAY_CLIENT_ID'), self.client_id) all_envs['RAY_JACK_CLIENT_NAME'] = ( os.getenv('RAY_JACK_CLIENT_NAME'), self.get_jack_client_name()) # The only way I found to expand vars is to set environment vars # globally, and remove them just after. # In case you see a better way, please say it. for env in all_envs: os.environ[env] = all_envs[env][1] os.environ['CONFIG_FILE'] = os.path.expandvars( self.ray_hack.config_file) back_pwd = os.getenv('PWD') ray_hack_pwd = self.get_project_path() os.environ['PWD'] = ray_hack_pwd if not os.path.exists(ray_hack_pwd): try: os.makedirs(ray_hack_pwd) except: os.environ['PWD'] = back_pwd # TODO return arguments_line = os.path.expandvars(self.arguments) if back_pwd is None: os.unsetenv('PWD') else: os.environ['PWD'] = back_pwd for env in all_envs: if all_envs[env][0] is None: os.unsetenv(env) else: os.environ[env] = all_envs[env][0] if self.arguments: arguments += shlex.split(arguments_line) self.running_executable = self.executable_path self.running_arguments = self.arguments if self.is_ray_hack(): self._process.setWorkingDirectory(ray_hack_pwd) process_env.insert('RAY_SESSION_NAME', self.session.name) process_env.insert('RAY_CLIENT_ID', self.client_id) self.jack_client_name = self.get_jack_client_name() self.send_gui_client_properties() self.session.send_monitor_event( 'start_request', self.client_id) self._process.setProcessEnvironment(process_env) self._process.start(self.executable_path, arguments) ## Here for another way to debug clients. ## Konsole is a terminal software. #self.process.start( #'konsole', #['--hide-tabbar', '--hide-menubar', '-e', self.executable_path] #+ arguments) def load(self, src_addr=None, src_path=''): if src_addr: self._osc_srcs[OSC_SRC_OPEN] = (src_addr, src_path) if self.active: self._send_reply_to_caller(OSC_SRC_OPEN, 'client active') return if self.pending_command == ray.Command.STOP: self._send_error_to_caller(OSC_SRC_OPEN, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s is exiting.') % self.gui_msg_style()) if self.is_running() and self.is_dumb_client(): self._send_error_to_caller(OSC_SRC_OPEN, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s seems to can not open') % self.gui_msg_style()) duration = max(8000, 2 * self.last_open_duration) self._open_timer.setInterval(duration) self._open_timer.start() if self.pending_command == ray.Command.OPEN: return if not self.is_running(): if self.executable_path in RS.non_active_clients: if src_addr: self._osc_srcs[OSC_SRC_START] = (src_addr, src_path) self._osc_srcs[OSC_SRC_OPEN] = (None, '') self.start(src_addr, src_path, True) return def terminate(self): if self.is_running(): if self.is_external: os.kill(self.pid, 15) # 15 means signal.SIGTERM else: self._process.terminate() def kill(self): if self.is_external: os.kill(self.pid, 9) # 9 means signal.SIGKILL return if self.is_running(): self._process.kill() def send_signal(self, sig: int, src_addr=None, src_path=""): try: tru_sig = signal.Signals(sig) except: if src_addr: self.send(src_addr, '/error', src_path, ray.Err.GENERAL_ERROR, 'invalid signal %i' % sig) return if not self.is_running(): if src_addr: self.send(src_addr, '/error', src_path, ray.Err.GENERAL_ERROR, 'client %s is not running' % self.client_id) return os.kill(self.pid, sig) self.send(src_addr, '/reply', src_path, 'signal sent') def is_running(self): if self.is_external: return True return bool(self._process.state() == 2) def external_finished(self): self._process_finished(0, 0) def script_finished(self, exit_code): if self.scripter.is_asked_for_terminate(): if self.session.wait_for == ray.WaitFor.QUIT: self.session.end_timer_if_last_expected(self) return scripter_pending_command = self.scripter.pending_command() if exit_code: error_text = "script %s ended with an error code" \ % self.scripter.get_path() if scripter_pending_command == ray.Command.SAVE: self._send_error_to_caller(OSC_SRC_SAVE, - exit_code, error_text) elif scripter_pending_command == ray.Command.START: self._send_error_to_caller(OSC_SRC_START, - exit_code, error_text) elif scripter_pending_command == ray.Command.STOP: self._send_error_to_caller(OSC_SRC_STOP, - exit_code, error_text) else: if scripter_pending_command == ray.Command.SAVE: self._send_reply_to_caller(OSC_SRC_SAVE, 'saved') elif scripter_pending_command == ray.Command.START: self._send_reply_to_caller(OSC_SRC_START, 'started') elif scripter_pending_command == ray.Command.STOP: self._send_reply_to_caller(OSC_SRC_STOP, 'stopped') if scripter_pending_command == self.pending_command: self.pending_command = ray.Command.NONE if (scripter_pending_command == ray.Command.STOP and self.is_running()): # if stop script ends with a not stopped client # We must stop it, else it would prevent session close self.stop() if self.session.wait_for: self.session.end_timer_if_last_expected(self) def ray_hack_ready(self): self.send_gui_message( _translate('GUIMSG', ' %s: project probably loaded') % self.gui_msg_style()) self._send_reply_to_caller(OSC_SRC_OPEN, 'client opened') self.pending_command = ray.Command.NONE self.set_status(ray.ClientStatus.READY) if self.session.wait_for == ray.WaitFor.REPLY: self.session.end_timer_if_last_expected(self) def terminate_scripts(self): self.scripter.terminate() def tell_client_session_is_loaded(self): if self.active and not self.is_dumb_client(): self.message("Telling client %s that session is loaded." % self.name) self.send_to_self_address("/nsm/client/session_is_loaded") def can_save_now(self): if self.is_ray_hack(): if not self.ray_hack.saveable(): return False return bool(self.is_running() and self.pending_command == ray.Command.NONE) return bool(self.active and not self.no_save_level) def save(self, src_addr=None, src_path=''): if self.switch_state in (ray.SwitchState.RESERVED, ray.SwitchState.NEEDED): if src_addr: self.send(src_addr, '/error', src_path, ray.Err.NOT_NOW, "Save cancelled because client has not switch yet !") return if src_addr: self._osc_srcs[OSC_SRC_SAVE] = (src_addr, src_path) if self.is_running(): if self.scripter.start(ray.Command.SAVE, src_addr, self._osc_srcs[OSC_SRC_SAVE]): self.set_status(ray.ClientStatus.SCRIPT) return if self.pending_command == ray.Command.SAVE: self._send_error_to_caller(OSC_SRC_SAVE, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s is already saving, please wait!') % self.gui_msg_style()) if self.is_running(): self.session.send_monitor_event( 'save_request', self.client_id) if self.is_ray_hack(): self.pending_command = ray.Command.SAVE self.set_status(ray.ClientStatus.SAVE) if self.ray_hack.save_sig > 0: os.kill(self._process.processId(), self.ray_hack.save_sig) QTimer.singleShot(300, self._ray_hack_saved) elif self.can_save_now(): self.message("Telling %s to save" % self.name) self.send_to_self_address("/nsm/client/save") self.pending_command = ray.Command.SAVE self.set_status(ray.ClientStatus.SAVE) elif self.is_dumb_client(): self.set_status(ray.ClientStatus.NOOP) if self.is_capable_of(':optional-gui:'): self.start_gui_hidden = not bool(self.gui_visible) def stop(self, src_addr=None, src_path=''): if self.switch_state == ray.SwitchState.NEEDED: if src_addr: self.send(src_addr, '/error', src_path, ray.Err.NOT_NOW, "Stop cancelled because client is needed for opening session") return if src_addr: self._osc_srcs[OSC_SRC_STOP] = (src_addr, src_path) self.send_gui_message(_translate('GUIMSG', " %s: stopping") % self.gui_msg_style()) if self.is_running(): if self.scripter.start(ray.Command.STOP, src_addr, self._osc_srcs[OSC_SRC_STOP]): self.set_status(ray.ClientStatus.SCRIPT) return self.pending_command = ray.Command.STOP self.set_status(ray.ClientStatus.QUIT) if not self._stopped_timer.isActive(): self._stopped_timer.start() self.session.send_monitor_event( 'stop_request', self.client_id) if self.is_external: os.kill(self.pid, 15) # 15 means signal.SIGTERM elif self.is_ray_hack() and self.ray_hack.stop_sig != 15: os.kill(self._process.pid(), self.ray_hack.stop_sig) else: self._process.terminate() else: self._send_reply_to_caller(OSC_SRC_STOP, 'client stopped.') def quit(self): self.message("Commanding %s to quit" % self.name) if self.is_running(): self.pending_command = ray.Command.STOP self.terminate() self.set_status(ray.ClientStatus.QUIT) else: self.send_gui("/ray/gui/client/status", self.client_id, ray.ClientStatus.REMOVED) def eat_attributes(self, new_client): #self.client_id = new_client.client_id self.executable_path = new_client.executable_path self.arguments = new_client.arguments self.name = new_client.name self.prefix_mode = new_client.prefix_mode self.custom_prefix = new_client.custom_prefix self.desktop_file = new_client.desktop_file self.label = new_client.label self.description = new_client.description self.icon = new_client.icon self.auto_start = new_client.auto_start self.check_last_save = new_client.check_last_save self.ignored_extensions = new_client.ignored_extensions self.custom_data = new_client.custom_data self.description = new_client.description self.jack_naming = new_client.jack_naming self._desktop_label = new_client._desktop_label self._desktop_description = new_client._desktop_description self._desktop_icon = new_client._desktop_icon #self.gui_visible = new_client.gui_visible self.gui_has_been_visible = self.gui_visible def switch(self): self.jack_client_name = self.get_jack_client_name() client_project_path = self.get_project_path() self.send_gui_client_properties() self.message("Commanding %s to switch \"%s\"" % (self.name, client_project_path)) self.send_to_self_address("/nsm/client/open", client_project_path, self.session.name, self.jack_client_name) self.pending_command = ray.Command.OPEN self.set_status(ray.ClientStatus.SWITCH) if self.is_capable_of(':optional-gui:'): self.send_gui('/ray/gui/client/gui_visible', self.client_id, int(self.gui_visible)) def can_switch_with(self, other_client)->bool: if self.protocol == ray.Protocol.RAY_HACK: return False if self.protocol != other_client.protocol: return False if not ((self.active and self.is_capable_of(':switch:')) or (self.is_dumb_client() and self.is_running())): return False if self.protocol == ray.Protocol.RAY_NET: return bool(self.ray_net.running_daemon_url == other_client.ray_net.daemon_url and self.ray_net.running_session_root == other_client.ray_net.session_root) return bool(self.running_executable == other_client.executable_path and self.running_arguments == other_client.arguments) def send_gui_client_properties(self, removed=False): ad = '/ray/gui/client/update' if self.sent_to_gui else '/ray/gui/client/new' hack_ad = '/ray/gui/client/ray_hack_update' net_ad = '/ray/gui/client/ray_net_update' if removed: ad = '/ray/gui/trash/add' hack_ad = '/ray/gui/trash/ray_hack_update' net_ad = '/ray/gui/trash/ray_net_update' self.send_gui(ad, *ray.ClientData.spread_client(self)) if self.protocol == ray.Protocol.RAY_HACK: self.send_gui( hack_ad, self.client_id, *self.ray_hack.spread()) elif self.protocol == ray.Protocol.RAY_NET: self.send_gui( net_ad, self.client_id, *self.ray_net.spread()) self.sent_to_gui = True def set_properties_from_message(self, message:str): for line in message.splitlines(): prop, colon, value = line.partition(':') if prop == 'client_id': # do not change client_id !!! continue elif prop == 'executable': self.executable_path = value elif prop == 'environment': self.pre_env = value elif prop == 'arguments': self.arguments = value elif prop == 'name': # do not change client name, # It will be re-sent by client itself continue elif prop == 'prefix_mode': if value.isdigit() and 0 <= int(value) <= 2: self.prefix_mode = int(value) elif prop == 'custom_prefix': self.custom_prefix = value elif prop == 'jack_naming': if value.isdigit() and 0 <= int(value) <= 1: self.jack_naming = int(value) elif prop == 'jack_name': # do not change jack name # only allow to change jack_naming continue elif prop == 'label': self.label = value elif prop == 'desktop_file': self.desktop_file = value elif prop == 'description': # description could contains many lines continue elif prop == 'icon': self.icon = value elif prop == 'capabilities': # do not change capabilities, no sense ! continue elif prop == 'check_last_save': if value.isdigit(): self.check_last_save = bool(int(value)) elif prop == 'ignored_extensions': self.ignored_extensions = value elif prop == 'protocol': # do not change protocol value continue if self.protocol == ray.Protocol.RAY_HACK: if prop == 'config_file': self.ray_hack.config_file = value elif prop == 'save_sig': try: sig = signal.Signals(int(value)) self.ray_hack.save_sig = int(value) except: continue elif prop == 'stop_sig': try: sig = signal.Signals(int(value)) self.ray_hack.stop_sig = int(value) except: continue elif prop == 'wait_win': self.ray_hack.wait_win = bool( value.lower() in ('1', 'true')) elif prop == 'no_save_level': if value.isdigit() and 0 <= int(value) <= 2: self.ray_hack.no_save_level = int(value) elif self.protocol == ray.Protocol.RAY_NET: if prop == 'net_daemon_url': self.ray_net.daemon_url = value elif prop == 'net_session_root': self.ray_net.session_root = value elif prop == 'net_session_template': self.ray_net.session_template = value self.send_gui_client_properties() def get_properties_message(self): message = """client_id:%s protocol:%s executable:%s environment:%s arguments:%s name:%s prefix_mode:%i custom_prefix:%s jack_naming:%i jack_name:%s desktop_file:%s label:%s icon:%s check_last_save:%i ignored_extensions:%s""" % (self.client_id, ray.protocol_to_str(self.protocol), self.executable_path, self.pre_env, self.arguments, self.name, self.prefix_mode, self.custom_prefix, self.jack_naming, self.get_jack_client_name(), self.desktop_file, self.label, self.icon, int(self.check_last_save), self.ignored_extensions) if self.protocol == ray.Protocol.NSM: message += "\ncapabilities:%s" % self.capabilities elif self.protocol == ray.Protocol.RAY_HACK: message += """\nconfig_file:%s save_sig:%i stop_sig:%i wait_win:%i no_save_level:%i""" % (self.ray_hack.config_file, self.ray_hack.save_sig, self.ray_hack.stop_sig, int(self.ray_hack.wait_win), self.ray_hack.no_save_level) elif self.protocol == ray.Protocol.RAY_NET: message += """\nnet_daemon_url:%s net_session_root:%s net_session_template:%s""" % (self.ray_net.daemon_url, self.ray_net.session_root, self.ray_net.session_template) return message def noSaveLevel(self)->int: ''' This method will be renamed or deleted later no_save_level will be deprecated for NSM client it will applies only on Ray-Hack clients ''' if self.is_ray_hack(): return self.ray_hack.noSaveLevel() return self.no_save_level def get_project_files(self): ''' returns a list of full filenames ''' client_files = [] project_path = self.get_project_path() if os.path.exists(project_path): client_files.append(project_path) if project_path.startswith('%s/' % self.session.path): base_project = project_path.replace('%s/' % self.session.path, '', 1) for filename in os.listdir(self.session.path): if filename == base_project: full_file_name = "%s/%s" % (self.session.path, filename) if not full_file_name in client_files: client_files.append(full_file_name) elif filename.startswith('%s.' % base_project): client_files.append('%s/%s' % (self.session.path, filename)) scripts_dir = "%s/%s.%s" % (self.session.path, ray.SCRIPTS_DIR, self.client_id) if os.path.exists(scripts_dir): client_files.append(scripts_dir) full_links_dir = os.path.join(self.session.path, self.get_links_dir()) if os.path.exists(full_links_dir): client_files.append(full_links_dir) return client_files def update_infos_from_desktop_file(self): if self.icon and self.description and self.label: return desk_path_list = ( '%s/data' % get_code_root(), '%s/.local' % os.getenv('HOME'), '/usr/local', '/usr') desktop_file = self.desktop_file if desktop_file == '//not_found': return if not desktop_file: desktop_file = os.path.basename(self.executable_path) if not desktop_file.endswith('.desktop'): desktop_file += ".desktop" for desk_path in desk_path_list: org_prefixs = ('', 'org.gnome.', 'org.kde.') desk_file = '' for org_prefix in org_prefixs: desk_file = "%s/share/applications/%s%s" % ( desk_path, org_prefix, desktop_file) if os.path.isfile(desk_file): break else: continue try: file = open(desk_file, 'r') contents = file.read() except: continue self._set_infos_from_desktop_contents(contents) break else: desk_file_found = False for desk_path in desk_path_list: full_desk_path = "%s/share/applications" % desk_path if not os.path.isdir(full_desk_path): # applications folder doesn't exists continue if not os.access(full_desk_path, os.R_OK): # no permission to read this applications folder continue for desk_file in os.listdir(full_desk_path): if not desk_file.endswith('.desktop'): continue full_desk_file = "%s/share/applications/%s" \ % (desk_path, desk_file) if os.path.isdir(full_desk_file): continue try: file = open(full_desk_file, 'r') contents = file.read() except: continue for line in contents.split('\n'): if line.startswith('Exec='): value = line.partition('=')[2] if (value == self.executable_path or value.startswith( "%s " % self.executable_path) or value.endswith( " %s" % self.executable_path) or " %s " in value): #if self.executable_path in value: desk_file_found = True self.desktop_file = desk_file self._set_infos_from_desktop_contents(contents) break if desk_file_found: break if desk_file_found: break else: self.desktop_file = '//not_found' def save_as_template(self, template_name, src_addr=None, src_path=''): if src_addr: self._osc_srcs[OSC_SRC_SAVE_TP] = (src_addr, src_path) #copy files client_files = self.get_project_files() template_dir = "%s/%s" % (TemplateRoots.user_clients, template_name) if os.path.exists(template_dir): if os.access(template_dir, os.W_OK): shutil.rmtree(template_dir) else: self._send_error_to_caller( OSC_SRC_SAVE_TP, ray.Err.CREATE_FAILED, _translate('GUIMSG', 'impossible to remove %s !') % highlight_text(template_dir)) return os.makedirs(template_dir) if self.protocol == ray.Protocol.RAY_NET: if self.ray_net.daemon_url: self.ray_net.session_template = template_name net_session_root = self.ray_net.session_root if self.is_running(): net_session_root = self.ray_net.running_session_root self.send(Address(self.ray_net.daemon_url), '/ray/server/save_session_template', self.session.name, template_name, net_session_root) if client_files: self.set_status(ray.ClientStatus.COPY) self.session.file_copier.start_client_copy( self.client_id, client_files, template_dir, self._save_as_template_substep1, self._save_as_template_aborted, [template_name]) else: self._save_as_template_substep1(template_name) def eat_other_session_client(self, src_addr, osc_path, client): # eat attributes but keep client_id self.eat_attributes(client) self.send_gui_client_properties() tmp_basedir = ".tmp_ray_workdir" while os.path.exists("%s/%s" % (self.session.path, tmp_basedir)): tmp_basedir += 'X' tmp_work_dir = "%s/%s" % (self.session.path, tmp_basedir) try: os.makedirs(tmp_work_dir) except: self.send(src_addr, '/error', osc_path, ray.Err.CREATE_FAILED, "impossible to make a tmp workdir at %s. Abort." % tmp_work_dir) self.session._remove_client(self) return self.set_status(ray.ClientStatus.PRECOPY) self.session.file_copier.start_client_copy( self.client_id, client.get_project_files(), tmp_work_dir, self.eat_other_session_client_step_1, self.eat_other_session_client_aborted, [src_addr, osc_path, client, tmp_work_dir]) def eat_other_session_client_step_1(self, src_addr, osc_path, client, tmp_work_dir): self._rename_files( tmp_work_dir, client.session.name, self.session.name, client.get_prefix_string(), self.get_prefix_string(), client.client_id, self.client_id, client.get_links_dir(), self.get_links_dir()) has_move_errors = False for file_path in os.listdir(tmp_work_dir): try: os.rename("%s/%s" % (tmp_work_dir, file_path), "%s/%s" % (self.session.path, file_path)) except: Terminal.message( _translate( 'client', 'failed to move %s/%s to %s/%s, sorry.') % (tmp_work_dir, file_path, self.session.path, file_path)) has_move_errors = True if not has_move_errors: try: shutil.rmtree(tmp_work_dir) except: Terminal.message( 'client' 'fail to remove temp directory %s. sorry.' % tmp_work_dir) self.send(src_addr, '/reply', osc_path, "Client copied from another session") if self.auto_start: self.start() else: self.set_status(ray.ClientStatus.STOPPED) def eat_other_session_client_aborted(self, src_addr, osc_path, client, tmp_work_dir): shutil.rmtree(tmp_work_dir) self.session._remove_client(self) self.send(src_addr, '/error', osc_path, ray.Err.COPY_ABORTED, "Copy was aborted by user") def change_prefix(self, prefix_mode: int, custom_prefix: str): if self.is_running(): return old_prefix = self.session.name if self.prefix_mode == ray.PrefixMode.CLIENT_NAME: old_prefix = self.name elif self.prefix_mode == ray.PrefixMode.CUSTOM: old_prefix = self.custom_prefix new_prefix = self.session.name if prefix_mode == ray.PrefixMode.CLIENT_NAME: new_prefix = self.name elif prefix_mode == ray.PrefixMode.CUSTOM: new_prefix = custom_prefix links_dir = self.get_links_dir() self._rename_files( self.session.path, self.session.name, self.session.name, old_prefix, new_prefix, self.client_id, self.client_id, links_dir, links_dir) self.prefix_mode = prefix_mode self.custom_prefix = custom_prefix self.send_gui_client_properties() def adjust_files_after_copy(self, new_session_full_name, template_save=ray.Template.NONE): spath = self.session.path old_session_name = self.session.name new_session_name = basename(new_session_full_name) new_client_id = self.client_id old_client_id = self.client_id new_client_links_dir = self.get_links_dir() old_client_links_dir = new_client_links_dir xsessionx = "XXX_SESSION_NAME_XXX" xclient_idx = "XXX_CLIENT_ID_XXX" x_client_links_dirx = "XXX_CLIENT_LINKS_DIR_XXX" # used for Carla links dir if template_save == ray.Template.NONE: if self.prefix_mode != ray.PrefixMode.SESSION_NAME: return spath = self.session.get_full_path(new_session_full_name) elif template_save == ray.Template.RENAME: spath = self.session.path elif template_save == ray.Template.SESSION_SAVE: spath = ray.get_full_path(TemplateRoots.user_sessions, new_session_full_name) new_session_name = xsessionx elif template_save == ray.Template.SESSION_SAVE_NET: spath = "%s/%s/%s" % (self.session.root, TemplateRoots.net_session_name, new_session_full_name) new_session_name = xsessionx elif template_save == ray.Template.SESSION_LOAD: spath = self.session.get_full_path(new_session_full_name) old_session_name = xsessionx elif template_save == ray.Template.SESSION_LOAD_NET: spath = self.session.get_full_path(new_session_full_name) old_session_name = xsessionx elif template_save == ray.Template.CLIENT_SAVE: spath = "%s/%s" % (TemplateRoots.user_clients, new_session_full_name) new_session_name = xsessionx new_client_id = xclient_idx new_client_links_dir = x_client_links_dirx elif template_save == ray.Template.CLIENT_LOAD: spath = self.session.path old_session_name = xsessionx old_client_id = xclient_idx old_client_links_dir = x_client_links_dirx old_prefix = old_session_name new_prefix = new_session_name if self.prefix_mode == ray.PrefixMode.CLIENT_NAME: old_prefix = new_prefix = self.name elif self.prefix_mode == ray.PrefixMode.CUSTOM: old_prefix = new_prefix = self.custom_prefix self._rename_files( spath, old_session_name, new_session_name, old_prefix, new_prefix, old_client_id, new_client_id, old_client_links_dir, new_client_links_dir) def server_announce(self, path, args, src_addr, is_new): client_name, capabilities, executable_path, major, minor, pid = args if self.pending_command == ray.Command.STOP: # assume to not answer to a dying client. # He will never know, or perhaps, it depends on beliefs. return if major > NSM_API_VERSION_MAJOR: self.message( "Client is using incompatible and more recent " + "API version %i.%i" % (major, minor)) self.send(src_addr, "/error", path, ray.Err.INCOMPATIBLE_API, "Server is using an incompatible API version.") return self.capabilities = capabilities self.addr = src_addr self.name = client_name self.active = True self.did_announce = True if is_new: self.is_external = True self.pid = pid self.running_executable = executable_path if self.executable_path in RS.non_active_clients: RS.non_active_clients.remove(self.executable_path) self.message("Process has pid: %i" % pid) self.message( "The client \"%s\" at \"%s\" " % (self.name, self.addr.url) + "informs us it's ready to receive commands.") server = self.get_server() if not server: return self.send_gui_message( _translate('GUIMSG', " %s: announced" % self.gui_msg_style())) # if this daemon is under another NSM session # do not enable server-control # because new, open and duplicate are forbidden server_capabilities = "" if not server.is_nsm_locked: server_capabilities += ":server-control" server_capabilities += ":broadcast:optional-gui:no-save-level:monitor:" self.send(src_addr, "/reply", path, "Well hello, stranger. Welcome to the party." if is_new else "Howdy, what took you so long?", ray.APP_TITLE, server_capabilities) client_project_path = self.get_project_path() self.jack_client_name = self.get_jack_client_name() if self.protocol == ray.Protocol.RAY_NET: client_project_path = self.session.get_short_path() self.jack_client_name = self.ray_net.session_template self.send_gui_client_properties() self.set_status(ray.ClientStatus.OPEN) if ':monitor:' in self.capabilities: self.session.send_initial_monitor(self.addr) self.send(src_addr, "/nsm/client/open", client_project_path, self.session.name, self.jack_client_name) self.pending_command = ray.Command.OPEN self._last_announce_time = time.time() RaySession-0.12.2/src/daemon/daemon_tools.py000066400000000000000000000214141417052567600210010ustar00rootroot00000000000000import argparse import os import sys from PyQt5.QtCore import (QCoreApplication, QStandardPaths, QSettings, QDateTime, QLocale) import ray settings = QSettings() def dirname(*args)->str: return os.path.dirname(*args) def basename(*args)->str: return os.path.basename(*args) def get_app_config_path()->str: return "%s/%s" % ( QStandardPaths.writableLocation(QStandardPaths.ConfigLocation), QCoreApplication.organizationName()) def get_code_root()->str: return dirname(dirname(dirname(os.path.realpath(__file__)))) def is_pid_child_of(child_pid, parent_pid)->bool: if child_pid < parent_pid: return False ppid = child_pid while ppid > parent_pid: try: proc_file = open('/proc/%i/status' % ppid, 'r') proc_contents = proc_file.read() except BaseException: return False for line in proc_contents.split('\n'): if line.startswith('PPid:'): ppid_str = line.rpartition('\t')[2] if ppid_str.isdigit(): ppid = int(ppid_str) break else: return False #while ppid != parent_pid and ppid > 1 and ppid != this_pid: #try: #ppid = int(subprocess.check_output( #['ps', '-o', 'ppid=', '-p', str(ppid)])) #except BaseException: #return False if ppid == parent_pid: return True return False def highlight_text(string)->str: if "'" in string: return '"%s"' % string return "'%s'" % string def init_daemon_tools(): if CommandLineArgs.config_dir: l_settings = QSettings(CommandLineArgs.config_dir) else: l_settings = QSettings() RS.set_settings(l_settings) RS.set_non_active_clients( ray.get_list_in_settings(l_settings, 'daemon/non_active_list')) RS.set_favorites(ray.get_list_in_settings(l_settings, 'daemon/favorites')) TemplateRoots.init_config() def get_git_default_un_and_ignored(executable:str)->tuple: ignored = [] unignored = [] if executable in ('luppp', 'sooperlooper', 'sooperlooper_nsm'): unignored.append('.wav') elif executable == 'samplv1_jack': unignored = ['.wav', '.flac', '.ogg', '.mp3'] return (ignored, unignored) class RS: settings = QSettings() non_active_clients = [] favorites = [] @classmethod def set_settings(cls, settings): del cls.settings cls.settings = settings @classmethod def set_non_active_clients(cls, nalist): del cls.non_active_clients cls.non_active_clients = nalist @classmethod def set_favorites(cls, favorites): cls.favorites = favorites class TemplateRoots: net_session_name = ".ray-net-session-templates" factory_sessions = "%s/session_templates" % get_code_root() factory_clients = "%s/client_templates" % get_code_root() factory_clients_xdg = "/etc/xdg/raysession/client_templates" @classmethod def init_config(cls): if CommandLineArgs.config_dir: app_config_path = CommandLineArgs.config_dir else: app_config_path = get_app_config_path() cls.user_sessions = "%s/session_templates" % app_config_path cls.user_clients = "%s/client_templates" % app_config_path class Terminal: _last_client_name = '' @classmethod def message(cls, string, server_port=0): if cls._last_client_name and cls._last_client_name != 'daemon': sys.stderr.write('\n') sys.stderr.write('[\033[90mray-daemon\033[0m]\033[92m%s\033[0m\n' % string) log_dir = "%s/logs" % get_app_config_path() if server_port: log_file_path = "%s/%i" % (log_dir, server_port) else: log_file_path = "%s/dummy" % log_dir if not os.path.exists(log_dir): os.makedirs(log_dir) log_file = open(log_file_path, 'a') date_time = QDateTime.currentDateTime() locale = QLocale(QLocale.English) date_format = locale.toString(date_time, "ddd MMM d hh:mm:ss yyyy") log_file.write("%s: %s\n" % (date_format, string)) cls._last_client_name = 'daemon' @classmethod def snapshoter_message(cls, byte_string, command=''): snapshoter_str = "snapshoter:.%s" % command if cls._last_client_name != snapshoter_str: sys.stderr.write('\n[\033[90mray-daemon-git%s\033[0m]\n' % command) sys.stderr.buffer.write(byte_string) cls._last_client_name = snapshoter_str @classmethod def scripter_message(cls, byte_string, command=''): scripter_str = "scripter:.%s" % command if cls._last_client_name != scripter_str: sys.stderr.write('\n[\033[90mray-daemon %s script\033[0m]\n' % command) sys.stderr.buffer.write(byte_string) cls._last_client_name = scripter_str @classmethod def client_message(cls, byte_string, client_name, client_id): client_str = "%s.%s" % (client_name, client_id) if (not CommandLineArgs.debug_only and not CommandLineArgs.no_client_messages): if cls._last_client_name != client_str: sys.stderr.write('\n[\033[90m%s-%s\033[0m]\n' % (client_name, client_id)) sys.stderr.buffer.write(byte_string) cls._last_client_name = client_str @classmethod def warning(cls, string): sys.stderr.write('[\033[90mray-daemon\033[0m]%s\033[0m\n' % string) cls._last_client_name = 'daemon' class CommandLineArgs(argparse.Namespace): session_root = '' osc_port = 0 findfreeport = True gui_url = None gui_port = 0 gui_pid = 0 config_dir = '' debug = False debug_only = False no_client_messages = False session = '' @classmethod def eat_attributes(cls, parsed_args): for attr_name in dir(parsed_args): if not attr_name.startswith('_'): setattr(cls, attr_name, getattr(parsed_args, attr_name)) if cls.debug_only: cls.debug = True if cls.osc_port == 0: cls.osc_port = 16187 cls.findfreeport = True if cls.config_dir and not os.access(cls.config_dir, os.W_OK): sys.stderr.write( '%s is not a writable config dir, try another one\n' % cls.config_dir) sys.exit(1) class ArgParser(argparse.ArgumentParser): def __init__(self): argparse.ArgumentParser.__init__(self) _translate = QCoreApplication.translate default_root = "%s/%s" % ( os.getenv('HOME'), _translate('daemon', 'Ray Network Sessions')) self.add_argument('--session-root', '-r', type=str, default=default_root, help='set root folder for sessions') self.add_argument('--session', '-s', type=str, default='', help='session to load at startup') self.add_argument('--osc-port', '-p', type=int, default=0, help='select OSC port for the daemon') self.add_argument('--findfreeport', action='store_true', help='find another port if port is not free') self.add_argument('--gui-url', type=ray.get_liblo_address, help=argparse.SUPPRESS) self.add_argument('--gui-port', type=ray.get_liblo_address_from_port, help=argparse.SUPPRESS) self.add_argument('--gui-pid', type=int, help=argparse.SUPPRESS) self.add_argument('--control-url', type=ray.get_liblo_address, help=argparse.SUPPRESS) self.add_argument('--no-options', action='store_true', help='start without any option and do not save options at quit') self.add_argument('--hidden', action='store_true', help='hide for ray_control') self.add_argument('--config-dir', '-c', type=str, default='', help='use a custom config dir') self.add_argument('--debug', '-d', action='store_true', help='see all OSC messages') self.add_argument('--debug-only', '-do', action='store_true', help='debug without client messages') self.add_argument('--no-client-messages', '-ncm', action='store_true', help='do not print client messages') self.add_argument('-v', '--version', action='version', version=ray.VERSION) parsed_args = argparse.ArgumentParser.parse_args(self) CommandLineArgs.eat_attributes(parsed_args) RaySession-0.12.2/src/daemon/desktops_memory.py000077500000000000000000000147131417052567600215510ustar00rootroot00000000000000#!/usr/bin/python3 -u import os import subprocess import sys import warnings from PyQt5.QtCore import QProcess import ray from daemon_tools import is_pid_child_of def move_win(win_id, desktop_from, desktop_to): if desktop_from == desktop_to: return if desktop_to == -1: subprocess.run(['wmctrl', 'i', '-r', win_id, '-b', 'add,sticky']) return if desktop_from == -1: subprocess.run(['wmctrl', 'i', '-r', win_id, '-b', 'remove,sticky']) subprocess.run(['wmctrl', '-i', '-r', win_id, '-t', str(desktop_to)]) class WindowProperties: id = "" desktop = 0 pid = 0 wclass = "" name = "" class DesktopsMemory: def __init__(self, session): self.session = session self._active_window_list = [] self._daemon_pids = [] self._non_daemon_pids = [] self.saved_windows = [] def _is_child_of_daemon(self, pid)->bool: if pid in self._daemon_pids: return True if pid in self._non_daemon_pids: return False daemon_pid = os.getpid() if pid < daemon_pid: self._non_daemon_pids.append(pid) return False if is_pid_child_of(pid, daemon_pid): self._daemon_pids.append(pid) return True self._non_daemon_pids.append(pid) return False def _is_name_in_session(self, name: str)->bool: for client in self.session.clients: if client.name == name and client.active: return True return False def set_active_window_list(self): try: wmctrl_all = subprocess.check_output(['wmctrl', '-l', '-p', '-x']).decode() except: warnings.warn('unable to use wmctrl') return self._active_window_list.clear() all_lines = wmctrl_all.split('\n') for line in all_lines: if not line: continue line_sep = line.split(' ') properties = [] for el in line_sep: if el: properties.append(el) if (len(properties) >= 6 and properties[1].lstrip('-').isdigit() and properties[2].isdigit()): wid = properties[0] desktop = int(properties[1]) pid = int(properties[2]) wclass = properties[3] ignore_pid = False # fltk based apps don't send their pids to wmctrl, # so if win seems to be one of these apps # and app is running in the session, # assume that this window is child of this ray-daemon if pid == 0 and '.' in wclass: class_name = wclass.split('.')[0] exceptions = {'luppp' : 'Luppp', 'Non-Mixer' : 'Non-Mixer', 'Non-Sequencer': 'Non-Sequencer', 'Non-Timeline' : 'Non-Timeline'} if class_name in exceptions: if self._is_name_in_session(exceptions[class_name]): ignore_pid = True if not (ignore_pid or self._is_child_of_daemon(pid)): continue name = "" for prop in properties[5:]: name += prop name += " " name = name[:-1] #remove last space awin = WindowProperties() awin.id = wid awin.pid = pid awin.desktop = desktop awin.wclass = wclass awin.name = name self._active_window_list.append(awin) def save(self): self.set_active_window_list() if not self._active_window_list: return for awin in self._active_window_list: for win in self.saved_windows: if win.wclass == awin.wclass and win.name == awin.name: win.desktop = awin.desktop break else: win = WindowProperties() win.id = awin.id win.desktop = awin.desktop win.wclass = awin.wclass win.name = awin.name self.saved_windows.append(win) def replace(self): if not self.saved_windows: return self.set_active_window_list() if not self._active_window_list: return for awin in self._active_window_list: for win in self.saved_windows: if win.wclass == awin.wclass and win.name == awin.name: win.id = awin.id move_win(awin.id, awin.desktop, win.desktop) break elif win.wclass == awin.wclass: if self.session.name: win_name_sps = win.name.split(self.session.name, 1) if (len(win_name_sps) == 2 and awin.name.startswith(win_name_sps[0]) and awin.name.endswith(win_name_sps[1])): move_win(awin.id, awin.desktop, win.desktop) break def read_xml(self, xml_element): self.saved_windows.clear() nodes = xml_element.childNodes() for i in range(nodes.count()): node = nodes.at(i) el = node.toElement() if el.tagName() != "window": continue win = WindowProperties() win.wclass = el.attribute('class') win.name = el.attribute('name') desktop = el.attribute('desktop') if desktop.lstrip('-').isdigit(): win.desktop = int(desktop) self.saved_windows.append(win) def has_window(self, pid)->bool: if not self._active_window_list: # here fo ray_hack check window # if window manager doesn't supports wmctrl # lie saying there is a window return True for awin in self._active_window_list: if is_pid_child_of(awin.pid, pid): return True return False def find_and_close(self, pid): for awin in self._active_window_list: if is_pid_child_of(awin.pid, pid): QProcess.startDetached('wmctrl', ['-i', '-c', awin.id]) RaySession-0.12.2/src/daemon/file_copier.py000066400000000000000000000201651417052567600206000ustar00rootroot00000000000000import os import shutil import subprocess import warnings from PyQt5.QtCore import QProcess, QTimer from osc_server_thread import OscServerThread from server_sender import ServerSender import ray class CopyFile: orig_path = "" dest_path = "" state = 0 size = 0 class FileCopier(ServerSender): def __init__(self, session): ServerSender.__init__(self) self.session = session self._client_id = '' self._next_function = None self._abort_function = None self._next_args = [] self._copy_files = [] self._copy_size = 0 self._aborted = False self._is_active = False self._process = QProcess() self._process.finished.connect(self._process_finished) if ray.QT_VERSION >= (5, 6): self._process.errorOccurred.connect(self._error_occurred) self._timer = QTimer() self._timer.setInterval(250) self._timer.setSingleShot(True) self._timer.timeout.connect(self._check_progress_size) self._abort_src_addr = None self._abort_src_path = '' def _get_file_size(self, filepath): if not os.path.exists(filepath): return 0 try: du_full = subprocess.check_output( ['nice', '-n', '15', 'du', '-sb', filepath]).decode() except: warnings.warn('unable to decode size of file %s' % filepath) du_full = "" if not du_full: return 0 du_str = du_full.split('\t')[0] if not du_str.isdigit(): return 0 return int(du_str) def _check_progress_size(self): current_size = 0 self._timer.stop() for copy_file in self._copy_files: if copy_file.state == 2: current_size += copy_file.size elif copy_file.state == 1: current_size += self._get_file_size(copy_file.dest_path) break if current_size and self._copy_size: progress = float(current_size/self._copy_size) if self._client_id: self.send_gui('/ray/gui/client/progress', self._client_id, progress) elif self.session.session_id: self.send_gui('/ray/gui/server/parrallel_copy_progress', self.session.session_id, progress) else: self.send_gui('/ray/gui/server/progress', progress) self.session.osc_reply('/ray/net_daemon/duplicate_state', progress) self._timer.start() def _process_finished(self, exit_code, exit_status): self._timer.stop() for copy_file in self._copy_files: if copy_file.state == 1: copy_file.state = 2 break if self._aborted: ##remove all created files for copy_file in self._copy_files: if copy_file.state > 0: file_to_remove = copy_file.dest_path if os.path.exists(file_to_remove): try: if os.path.isfile(file_to_remove): os.remove(file_to_remove) elif os.path.isdir(file_to_remove): shutil.rmtree(file_to_remove) except: if self._abort_src_addr and self._abort_src_path: self.send(self._abort_src_addr, '/error_minor', self._abort_src_path, ray.Err.SUBPROCESS_CRASH, "%s hasn't been removed !") self._is_active = False self._send_copy_state_to_gui(0) self._abort_function(*self._next_args) return # run next_function if copy is terminated for copy_file in self._copy_files: if copy_file.state != 2: break else: self._is_active = False self._send_copy_state_to_gui(0) if self._next_function: self._next_function(*self._next_args) return self._next_process() def _error_occurred(self): #todo make something else self._process_finished(0, 0) def _next_process(self): self._is_active = True for copy_file in self._copy_files: if copy_file.state == 0: copy_file.state = 1 self._process.start('nice', ['-n', '+15', 'cp', '-R', copy_file.orig_path, copy_file.dest_path]) break self._timer.start() def _start(self, src_list, dest_dir, next_function, abort_function, next_args=[]): self._abort_function = abort_function self._next_function = next_function self._next_args = next_args self._aborted = False self._copy_size = 0 self._copy_files.clear() dest_path_exists = bool(os.path.exists(dest_dir)) if dest_path_exists: if not os.path.isdir(dest_dir): #TODO send error, but it should not append self._abort_function(*self._next_args) return if isinstance(src_list, str): src_dir = src_list src_list = [] if not os.path.isdir(src_dir): self._abort_function(*self._next_args) return try: tmp_list = os.listdir(src_dir) except: self._abort_function(*self._next_args) return for path in tmp_list: if path == '.ray-snapshots': continue full_path = "%s/%s" % (src_dir, path) src_list.append(full_path) if not dest_path_exists: try: os.makedirs(dest_dir) except: self._abort_function(*self._next_args) return for orig_path in src_list: copy_file = CopyFile() copy_file.state = 0 copy_file.orig_path = orig_path copy_file.size = self._get_file_size(orig_path) self._copy_size += copy_file.size if dest_path_exists: copy_file.dest_path = "%s/%s" % (dest_dir, os.path.basename(orig_path)) else: #WARNING works only with one file !!! copy_file.dest_path = dest_dir self._copy_files.append(copy_file) if self._copy_files: self._send_copy_state_to_gui(1) self._next_process() else: self._next_function(*self._next_args) def _send_copy_state_to_gui(self, state:int): if self.session.session_id: self.send_gui('/ray/gui/server/parrallel_copy_state', self.session.session_id, state) else: self.send_gui('/ray/gui/server/copying', state) def start_client_copy(self, client_id, src_list, dest_dir, next_function, abort_function, next_args=[]): self._client_id = client_id self._start(src_list, dest_dir, next_function, abort_function, next_args) def start_session_copy(self, src_dir, dest_dir, next_function, abort_function, next_args=[]): self._client_id = '' self._start(src_dir, dest_dir, next_function, abort_function, next_args) def abort(self, abort_function=None, next_args=[]): if abort_function: self._abort_function = abort_function self._next_args = next_args self._timer.stop() if self._process.state() == QProcess.Running: self._aborted = True self._process.terminate() def is_active(self, client_id=''): if client_id and client_id != self._client_id: return False return self._is_active RaySession-0.12.2/src/daemon/list_nsm_desktop.py000077500000000000000000000044351417052567600217060ustar00rootroot00000000000000#!/usr/bin/python3 import os def get_nsm_capable_apps_from_desktop_file()->list: ''' returns a list of tuples {'executable': str, 'desktop_file': str, nsm_capable: bool} ''' desk_path_list = ( '%s/.local' % os.getenv('HOME'), '/usr/local', '/usr') application_dicts = [] for desk_path in desk_path_list: full_desk_path = "%s/share/applications" % desk_path if not os.path.isdir(full_desk_path): # applications folder doesn't exists continue if not os.access(full_desk_path, os.R_OK): # no permission to read this applications folder continue for root, dirs, files in os.walk(full_desk_path): for f in files: if not f.endswith('.desktop'): continue if f in [apd['desktop_file'] for apd in application_dicts]: # desktop file already seen in a prior desk_path continue full_desk_file = os.path.join(root, f) try: file = open(full_desk_file, 'r') contents = file.read() except: continue executable = '' has_nsm_mention = False nsm_capable = True for line in contents.splitlines(): if line.startswith('Exec='): executable_and_args = line.partition('=')[2] executable = executable_and_args.partition(' ')[0] elif line.lower().startswith('x-nsm-capable='): has_nsm_mention = True value = line.partition('=')[2] nsm_capable = bool(value.strip().lower() == 'true') if has_nsm_mention and executable: application_dicts.append( {'executable': executable, 'desktop_file': f, 'nsm_capable': nsm_capable}) return [a for a in application_dicts if a['nsm_capable']] application_dicts = get_nsm_capable_apps_from_desktop_file() for a in application_dicts: print(a['executable']) RaySession-0.12.2/src/daemon/multi_daemon_file.py000066400000000000000000000205741417052567600220000ustar00rootroot00000000000000import os from PyQt5.QtXml import QDomDocument, QDomElement import ray instance = None class Daemon: net_daemon_id = 0 root = "" session_path = "" pid = 0 port = 0 user = "" not_default = False class MultiDaemonFile: file_path = '/tmp/RaySession/multi-daemon.xml' def __init__(self, session, server): self.session = session self.server = server self._xml = QDomDocument() global instance instance = self self._locked_session_paths = set() @staticmethod def get_instance(): return instance def _pid_exists(self, pid)->bool: if isinstance(pid, str): pid = int(pid) try: os.kill(pid, 0) except OSError: return False else: return True def _remove_file(self): try: os.remove(self.file_path) except: return def _open_file(self)->bool: if not os.path.exists(self.file_path): dir_path = os.path.dirname(self.file_path) if not os.path.exists(dir_path): os.makedirs(dir_path) # give read/write access for all users os.chmod(dir_path, 0o777) return False try: file = open(self.file_path, 'r') self._xml.setContent(file.read()) file.close() return True except: self._remove_file() return False def _write_file(self): try: file = open(self.file_path, 'w') file.write(self._xml.toString()) file.close() except: return def _set_attributes(self, element): element.setAttribute('net_daemon_id', self.server.net_daemon_id) element.setAttribute('root', self.session.root) element.setAttribute('session_path', self.session.path) element.setAttribute('pid', os.getpid()) element.setAttribute('port', self.server.port) element.setAttribute('user', os.getenv('USER')) element.setAttribute('not_default', int(bool(self.server.is_nsm_locked or self.server.not_default))) element.setAttribute('has_gui', int(self.server.has_gui())) element.setAttribute('version', ray.VERSION) element.setAttribute('local_gui_pids', self.server.get_local_gui_pid_list()) for locked_path in self._locked_session_paths: locked_paths_xml = self._xml.createElement('locked_session') locked_paths_xml.setAttribute('path', locked_path) element.appendChild(locked_paths_xml) def _clean_dirty_pids(self): xml_content = self._xml.documentElement() nodes = xml_content.childNodes() rm_nodes = [] for i in range(nodes.count()): node = nodes.at(i) dxe = node.toElement() pid = dxe.attribute('pid') if not pid.isdigit() or not self._pid_exists(int(pid)): rm_nodes.append(node) for node in rm_nodes: xml_content.removeChild(node) def update(self): has_dirty_pid = False if not self._open_file(): ds = self._xml.createElement('Daemons') dm_xml = self._xml.createElement('Daemon') self._set_attributes(dm_xml) ds.appendChild(dm_xml) self._xml.appendChild(ds) else: xml_content = self._xml.documentElement() nodes = xml_content.childNodes() self_node = None for i in range(nodes.count()): node = nodes.at(i) dxe = node.toElement() pid = dxe.attribute('pid') if pid.isdigit() and pid == str(os.getpid()): self_node = node elif not pid.isdigit() or not self._pid_exists(int(pid)): has_dirty_pid = True if self_node is not None: xml_content.removeChild(self_node) dm_xml = self._xml.createElement('Daemon') self._set_attributes(dm_xml) self._xml.firstChild().appendChild(dm_xml) if has_dirty_pid: self._clean_dirty_pids() self._write_file() def quit(self): if not self._open_file(): return xml_content = self._xml.documentElement() nodes = xml_content.childNodes() for i in range(nodes.count()): node = nodes.at(i) dxe = node.toElement() pid = dxe.attribute('pid') if pid.isdigit() and pid == str(os.getpid()): break else: return xml_content.removeChild(node) self._write_file() def is_free_for_root(self, daemon_id, root_path)->bool: if not self._open_file(): return True xml_content = self._xml.documentElement() nodes = xml_content.childNodes() for i in range(nodes.count()): node = nodes.at(i) dxe = node.toElement() if (dxe.attribute('net_daemon_id') == str(daemon_id) and dxe.attribute('root') == root_path): pid = dxe.attribute('pid') if pid.isdigit() and self._pid_exists(int(pid)): return False return True def is_free_for_session(self, session_path)->bool: if not self._open_file(): return True xml_content = self._xml.documentElement() nodes = xml_content.childNodes() for i in range(nodes.count()): node = nodes.at(i) dxe = node.toElement() pid = dxe.attribute('pid') if dxe.attribute('session_path') == session_path: if pid.isdigit() and self._pid_exists(int(pid)): return False sub_nodes = node.childNodes() for j in range(sub_nodes.count()): sub_node = sub_nodes.at(j) sub_nod_el = sub_node.toElement() if sub_nod_el.attribute('path') == session_path: if pid.isdigit() and self._pid_exists(int(pid)): return False return True def get_all_session_paths(self)->list: if not self._open_file(): return [] all_session_paths = [] xml_content = self._xml.documentElement() nodes = xml_content.childNodes() for i in range(nodes.count()): node = nodes.at(i) dxe = node.toElement() spath = dxe.attribute('session_path') pid = dxe.attribute('pid') if spath and pid.isdigit() and self._pid_exists(int(pid)): all_session_paths.append(spath) return all_session_paths def add_locked_path(self, path:str): self._locked_session_paths.add(path) self.update() def unlock_path(self, path:str): self._locked_session_paths.discard(path) self.update() def get_daemon_list(self)->list: daemon_list = [] has_dirty_pid = False if not self._open_file(): return daemon_list xml_content = self._xml.documentElement() nodes = xml_content.childNodes() for i in range(nodes.count()): node = nodes.at(i) dxe = node.toElement() daemon = Daemon() daemon.root = dxe.attribute('root') daemon.session_path = dxe.attribute('session_path') daemon.user = dxe.attribute('user') daemon.not_default = bool(dxe.attribute('not_default') == 'true') net_daemon_id = dxe.attribute('net_daemon_id') pid = dxe.attribute('pid') port = dxe.attribute('port') if net_daemon_id.isdigit(): daemon.net_daemon_id = net_daemon_id if pid.isdigit(): daemon.pid = pid if port.isdigit(): daemon.port = port if not self._pid_exists(daemon.pid): has_dirty_pid = True continue if not (daemon.net_daemon_id and daemon.pid and daemon.port): continue daemon_list.append(daemon) if has_dirty_pid: self._clean_dirty_pids() return daemon_list RaySession-0.12.2/src/daemon/osc_server_thread.py000066400000000000000000001537621417052567600220330ustar00rootroot00000000000000import os import sys import random import shutil import subprocess import time import liblo from PyQt5.QtCore import QCoreApplication from PyQt5.QtXml import QDomDocument import ray from signaler import Signaler from multi_daemon_file import MultiDaemonFile from daemon_tools import (TemplateRoots, CommandLineArgs, Terminal, RS, get_code_root) instance = None signaler = Signaler.instance() _translate = QCoreApplication.translate def _path_is_valid(path: str)->bool: if path.startswith(('./', '../')): return False for forbidden in ('//', '/./', '/../'): if forbidden in path: return False if path.endswith(('/.', '/..')): return False return True def ray_method(path, types): def decorated(func): @liblo.make_method(path, types) def wrapper(*args, **kwargs): t_thread, t_path, t_args, t_types, src_addr, rest = args if CommandLineArgs.debug: sys.stderr.write('\033[94mOSC::daemon_receives\033[0m %s, %s, %s, %s\n' % (t_path, t_types, t_args, src_addr.url)) response = func(*args[:-1], **kwargs) if response != False: signaler.osc_recv.emit(t_path, t_args, t_types, src_addr) return response return wrapper return decorated class Controller: addr = None pid = 0 class GuiAdress(liblo.Address): gui_pid = 0 # Osc server thread separated in many classes for confort. # ClientCommunicating contains NSM protocol. # OSC paths have to be never changed. class ClientCommunicating(liblo.ServerThread): def __init__(self, session, osc_num=0): liblo.ServerThread.__init__(self, osc_num) self.session = session self._nsm_locker_url = '' self._net_master_daemon_url = '' self._list_asker_addr = None self.gui_list = [] self.controller_list = [] self.monitor_list = [] self.server_status = ray.ServerStatus.OFF self.is_nsm_locked = False self.not_default = False self.net_daemon_id = random.randint(1, 999999999) self.options = 0 @ray_method('/osc/ping', '') def oscPing(self, path, args, types, src_addr): self.send(src_addr, "/reply", path) @ray_method('/reply', None) def reply(self, path, args, types, src_addr): if not ray.types_are_all_strings(types): self._unknown_message(path, types, src_addr) if not len(args) >= 1: self._unknown_message(path, types, src_addr) return False reply_path = args[0] if reply_path == '/ray/server/list_sessions': # this reply is only used here for reply from net_daemon # it directly resend its infos # to the last addr that asked session list if self._list_asker_addr: self.send(self._list_asker_addr, path, *args) return False if reply_path == '/ray/gui/script_user_action': self.send_gui('/ray/gui/hide_script_user_action') for controller in self.controller_list: self.send(controller.addr, '/reply', '/ray/server/script_user_action', 'User action dialog validate') return False if not len(args) == 2: # assume this is a normal client, not a net_daemon self._unknown_message(path, types, src_addr) return False @ray_method('/error', 'sis') def error(self, path, args, types, src_addr): error_path, error_code, error_string = args if error_path == '/ray/gui/script_user_action': self.send_gui('/ray/gui/hide_script_user_action') for controller in self.controller_list: self.send(controller.addr, '/error', '/ray/server/script_user_action', -1, 'User action dialog aborted !') return False @ray_method('/minor_error', 'sis') def minor_error(self, path, args, types, src_addr): # prevent minor_error to minor_error loop in daemon <-> daemon communication pass # SERVER_CONTROL messages # following messages only for :server-control: capability @ray_method('/nsm/server/add', 's') def nsmServerAdd(self, path, args, types, src_addr): executable_path = args[0] if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "Cannot add to session because no session is loaded.") return False if '/' in executable_path: self.send(src_addr, "/error", path, ray.Err.LAUNCH_FAILED, "Absolute paths are not permitted. Clients must be in $PATH") return False @ray_method('/nsm/server/save', '') def nsmServerSave(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to save.") return False @ray_method('/nsm/server/open', 's') def nsmServerOpen(self, path, args, types, src_addr): pass @ray_method('/nsm/server/new', 's') def nsmServerNew(self, path, args, types, src_addr): if self.is_nsm_locked: return False if not _path_is_valid(args[0]): self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid session name.") return False @ray_method('/nsm/server/duplicate', 's') def nsmServerDuplicate(self, path, args, types, src_addr): if self.is_nsm_locked or not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to duplicate.") return False if not _path_is_valid(args[0]): self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid session name.") return False @ray_method('/nsm/server/close', '') def nsmServerClose(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to close.") return False @ray_method('/nsm/server/abort', '') def nsmServerAbort(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to abort.") return False @ray_method('/nsm/server/quit', '') def nsmServerQuit(self, path, args, types, src_addr): pass @ray_method('/nsm/server/list', '') def nsmServerList(self, path, args, types, src_addr): pass # END OF SERVER_CONTROL messages @ray_method('/nsm/server/announce', 'sssiii') def nsmServerAnnounce(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "Sorry, but there's no session open " + "for this application to join.") return False @ray_method('/nsm/server/broadcast', None) def nsmServerBroadcast(self, path, args, types, src_addr): if not args: return False #don't allow clients to broadcast NSM commands if args[0].startswith('/nsm/') or args[0].startswith('/ray'): return False for client in self.session.clients: if not client.addr: continue if not ray.are_same_osc_port(client.addr.url, src_addr.url): self.send(client.addr, liblo.Message(*args)) # TODO broadcast to slave daemons #for gui_addr in self.gui_list: ##also relay to attached GUI so that the broadcast can be ##propagated to another NSMD instance #if gui_addr.url != src_addr.url: #self.send(gui_addr, Message(*args)) @ray_method('/nsm/server/monitor_reset', '') def nsmServerGetAllStates(self, path, args, types, src_addr): self.send(src_addr, '/reply', path, 'monitor reset') self.session.send_initial_monitor(src_addr, monitor_is_client=True) @ray_method('/nsm/client/progress', 'f') def nsmClientProgress(self, path, args, types, src_addr): client = self.session.get_client_by_address(src_addr) if not client: return False client.progress = args[0] self.send_gui("/ray/gui/client/progress", client.client_id, client.progress) @ray_method('/nsm/client/is_dirty', '') def nsmClientIs_dirty(self, path, args, types, src_addr): client = self.session.get_client_by_address(src_addr) if not client: return False Terminal.message("%s sends dirty" % client.client_id) client.dirty = 1 client.last_dirty = time.time() self.send_gui("/ray/gui/client/dirty", client.client_id, client.dirty) @ray_method('/nsm/client/is_clean', '') def nsmClientIs_clean(self, path, args, types, src_addr): client = self.session.get_client_by_address(src_addr) if not client: return False Terminal.message("%s sends clean" % client.client_id) client.dirty = 0 self.send_gui("/ray/gui/client/dirty", client.client_id, client.dirty) return False @ray_method('/nsm/client/message', 'is') def nsmClientMessage(self, path, args, types, src_addr): client = self.session.get_client_by_address(src_addr) if not client: return False self.send_gui("/ray/gui/client/message", client.client_id, args[0], args[1]) @ray_method('/nsm/client/gui_is_hidden', '') def nsmClientGui_is_hidden(self, path, args, types, src_addr): client = self.session.get_client_by_address(src_addr) if not client: return False Terminal.message("Client '%s' sends gui hidden" % client.client_id) client.gui_visible = False self.send_gui("/ray/gui/client/gui_visible", client.client_id, int(client.gui_visible)) @ray_method('/nsm/client/gui_is_shown', '') def nsmClientGui_is_shown(self, path, args, types, src_addr): client = self.session.get_client_by_address(src_addr) if not client: return False Terminal.message("Client '%s' sends gui shown" % client.client_id) client.gui_visible = True client.gui_has_been_visible = True self.send_gui("/ray/gui/client/gui_visible", client.client_id, int(client.gui_visible)) @ray_method('/nsm/client/label', 's') def nsmClientLabel(self, path, args, types, src_addr): pass @ray_method('/nsm/client/network_properties', 'ss') def nsmClientNetworkProperties(self, path, args, types, src_addr): pass @ray_method('/nsm/client/no_save_level', 'i') def nsmClientNoSaveLevel(self, path, args, types, src_addr): pass def _unknown_message(self, path, types, src_addr): self.send(src_addr, '/minor_error', path, ray.Err.UNKNOWN_MESSAGE, "unknown osc message: %s %s" % (path, types)) class OscServerThread(ClientCommunicating): def __init__(self, session, osc_num=0): ClientCommunicating.__init__(self, session, osc_num) self.options_dict = { 'save_from_client': ray.Option.SAVE_FROM_CLIENT, 'bookmark_session_folder': ray.Option.BOOKMARK_SESSION, 'desktops_memory': ray.Option.DESKTOPS_MEMORY, 'snapshots': ray.Option.SNAPSHOTS, 'session_scripts': ray.Option.SESSION_SCRIPTS, 'gui_states': ray.Option.GUI_STATES} self.options = RS.settings.value( 'daemon/options', ray.Option.BOOKMARK_SESSION + ray.Option.SNAPSHOTS + ray.Option.SESSION_SCRIPTS + ray.Option.GUI_STATES, type=int) if CommandLineArgs.no_options: self.options = 0 if shutil.which('wmctrl'): self.options |= ray.Option.HAS_WMCTRL else: self.options &= ~ray.Option.HAS_WMCTRL if shutil.which('git'): self.options |= ray.Option.HAS_GIT else: self.options &= ~ray.Option.HAS_GIT self.client_templates_database = { 'factory': [], 'user': []} self.session_to_preview = '' global instance instance = self @staticmethod def getInstance(): return instance @ray_method('/ray/server/gui_announce', 'sisii') def rayGuiGui_announce(self, path, args, types, src_addr): (version, int_nsm_locked, net_master_daemon_url, gui_pid, net_daemon_id) = args nsm_locked = bool(int_nsm_locked) is_net_free = True if nsm_locked: self._net_master_daemon_url = net_master_daemon_url self.is_nsm_locked = True self._nsm_locker_url = src_addr.url for gui_addr in self.gui_list: if not ray.are_same_osc_port(gui_addr.url, src_addr.url): self.send(gui_addr, '/ray/gui/server/nsm_locked', 1) self.net_daemon_id = net_daemon_id multi_daemon_file = MultiDaemonFile.get_instance() if multi_daemon_file: is_net_free = multi_daemon_file.is_free_for_root( self.net_daemon_id, self.session.root) self.announce_gui(src_addr.url, nsm_locked, is_net_free, gui_pid) @ray_method('/ray/server/gui_disannounce', '') def rayGuiGui_disannounce(self, path, args, types, src_addr): for addr in self.gui_list: if ray.are_same_osc_port(addr.url, src_addr.url): break else: return False self.gui_list.remove(addr) if src_addr.url == self._nsm_locker_url: self.net_daemon_id = random.randint(1, 999999999) self.is_nsm_locked = False self._nsm_locker_url = '' self.send_gui('/ray/gui/server/nsm_locked', 0) multi_daemon_file = MultiDaemonFile.get_instance() if multi_daemon_file: multi_daemon_file.update() @ray_method('/ray/server/ask_for_patchbay', '') def rayServerGetPatchbayPort(self, path, args, types, src_addr): patchbay_file = '/tmp/RaySession/patchbay_daemons/' + str(self.port) patchbay_port = 0 if not os.path.exists(patchbay_file): return True with open(patchbay_file, 'r') as file: file = open(patchbay_file, 'r') contents = file.read() #file.close() for line in contents.splitlines(): if line.startswith('pid:'): pid_str = line.rpartition(':')[2] if pid_str.isdigit(): pid = int(pid_str) try: os.kill(pid, 0) except OSError: # go to main thread (session_signaled.py) return True else: # pid is okay, let check the osc port next continue else: return True if line.startswith('port:'): port_str = line.rpartition(':')[2] good_port = False try: patchbay_addr = liblo.Address(int(port_str)) good_port = True except: patchbay_addr = None sys.stderr.write( 'port given for patchbay %s is not a valid osc port') if good_port: self.send(patchbay_addr, '/ray/patchbay/add_gui', src_addr.url) return False break # continue in main thread if patchbay_to_osc is not started yet # see session_signaled.py -> _ray_server_ask_for_patchbay @ray_method('/ray/server/controller_announce', 'i') def rayServerControllerAnnounce(self, path, args, types, src_addr): controller = Controller() controller.addr = src_addr controller.pid = args[0] self.controller_list.append(controller) self.send(src_addr, '/reply', path, 'announced') @ray_method('/ray/server/controller_disannounce', '') def rayServerControllerDisannounce(self, path, args, types, src_addr): for controller in self.controller_list: if controller.addr.url == src_addr.url: break else: return self.controller_list.remove(controller) self.send(src_addr, '/reply', path, 'disannounced') @ray_method('/ray/server/monitor_announce', '') def rayServerMonitorAnnounce(self, path, args, types, src_addr): monitor_addr = src_addr self.monitor_list.append(monitor_addr) self.session.send_initial_monitor(src_addr, monitor_is_client=False) self.send(src_addr, '/reply', path, 'announced') @ray_method('/ray/server/monitor_quit', '') def rayServerMonitorDisannounce(self, path, args, types, src_addr): for monitor_addr in self.monitor_list: if monitor_addr.url == src_addr.url: break else: return self.monitor_list.remove(monitor_addr) self.send(src_addr, '/reply', path, 'monitor exit') @ray_method('/ray/server/set_nsm_locked', '') def rayServerSetNsmLocked(self, path, args, types, src_addr): self.is_nsm_locked = True self._nsm_locker_url = src_addr.url for gui_addr in self.gui_list: if gui_addr.url != src_addr.url: self.send(gui_addr, '/ray/gui/server/nsm_locked', 1) @ray_method('/ray/server/quit', '') def rayServerQuit(self, path, args, types, src_addr): pass @ray_method('/ray/server/abort_copy', '') def rayServerAbortCopy(self, path, args, types, src_addr): pass @ray_method('/ray/server/abort_parrallel_copy', 'i') def rayServerAbortParrallelCopy(self, path, args, types, src_addr): pass @ray_method('/ray/server/abort_snapshot', '') def rayServerAbortSnapshot(self, path, args, types, src_addr): pass @ray_method('/ray/server/change_root', 's') def rayServerChangeRoot(self, path, args, types, src_addr): new_root = args[0] if not(new_root.startswith('/') and _path_is_valid(new_root)): self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, "invalid session root !") if self._is_operation_pending(src_addr, path): self.send(src_addr, '/error', path, ray.Err.OPERATION_PENDING, "Can't change session_root. Operation pending") return False @ray_method('/ray/server/list_path', '') def rayServerListPath(self, path, args, types, src_addr): exec_list = [] tmp_exec_list = [] n = 0 pathlist = os.getenv('PATH').split(':') for pathdir in pathlist: if os.path.isdir(pathdir): listexe = os.listdir(pathdir) for exe in listexe: fullexe = pathdir + '/' + exe if (os.path.isfile(fullexe) and os.access(fullexe, os.X_OK) and not exe in exec_list): exec_list.append(exe) tmp_exec_list.append(exe) n += len(exe) if n >= 20000: self.send(src_addr, '/reply', path, *tmp_exec_list) tmp_exec_list.clear() n = 0 if tmp_exec_list: self.send(src_addr, '/reply', path, *tmp_exec_list) @ray_method('/ray/server/list_session_templates', '') def rayServerListSessionTemplates(self, path, args, types, src_addr): if not os.path.isdir(TemplateRoots.user_sessions): self.send(src_addr, '/reply', path) return False template_list = [] all_files = os.listdir(TemplateRoots.user_sessions) for file in all_files: if os.path.isdir("%s/%s" % (TemplateRoots.user_sessions, file)): template_list.append(file) if len(template_list) == 100: self.send(src_addr, '/reply', path, *template_list) template_list.clear() if template_list: self.send(src_addr, '/reply', path, *template_list) self.send(src_addr, '/reply', path) @ray_method('/ray/server/list_user_client_templates', None) def rayServerListUserClientTemplates(self, path, args, types, src_addr): for a in types: if a != 's': self._unknown_message(path, types, src_addr) return False @ray_method('/ray/server/list_factory_client_templates', None) def rayServerListFactoryClientTemplates(self, path, args, types, src_addr): for a in types: if a != 's': self._unknown_message(path, types, src_addr) return False @ray_method('/ray/server/remove_client_template', 's') def rayServerRemoveClientTemplate(self, path, args, types, src_addr): template_name = args[0] templates_root = TemplateRoots.user_clients templates_file = "%s/%s" % (templates_root, 'client_templates.xml') if not os.path.isfile(templates_file): self.send(src_addr, '/error', path, ray.Err.NO_SUCH_FILE, "file %s is missing !" % templates_file) return False if not os.access(templates_file, os.W_OK): self.send(src_addr, '/error', path, ray.Err.NO_SUCH_FILE, "file %s in unwriteable !" % templates_file) return False file = open(templates_file, 'r') xml = QDomDocument() xml.setContent(file.read()) file.close() content = xml.documentElement() if content.tagName() != "RAY-CLIENT-TEMPLATES": self.send(src_addr, '/error', path, ray.Err.BAD_PROJECT, "file %s is not write correctly !" % templates_file) return False nodes = content.childNodes() for i in range(nodes.count()): node = nodes.at(i) ct = node.toElement() tag_name = ct.tagName() if tag_name != 'Client-Template': continue if template_name == ct.attribute('template-name'): break else: self.send(src_addr, '/error', path, ray.Err.NO_SUCH_FILE, "No template \"%s\" to remove !" % template_name) return False content.removeChild(nodes.at(i)) file = open(templates_file, 'w') file.write(xml.toString()) file.close() template_dir = '%s/%s' % (templates_root, template_name) if os.path.isdir(template_dir): subprocess.run(['rm', '-R', template_dir]) self.send(src_addr, '/reply', path, "template \"%s\" removed." % template_name) @ray_method('/ray/server/list_sessions', '') def rayServerListSessions(self, path, args, types, src_addr): self._list_asker_addr = src_addr @ray_method('/ray/server/list_sessions', 'i') def rayServerListSessionsWithNet(self, path, args, types, src_addr): self._list_asker_addr = src_addr @ray_method('/ray/server/new_session', None) def rayServerNewSession(self, path, args, types, src_addr): if not ray.types_are_all_strings(types): self._unknown_message(path, types, src_addr) return False if self.is_nsm_locked: return False if not _path_is_valid(args[0]): self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid session name.") return False @ray_method('/ray/server/open_session', 's') def rayServerOpenSession(self, path, args, types, src_addr): pass @ray_method('/ray/server/open_session', 'si') def rayServerOpenSessionWithoutSave(self, path, args, types, src_addr): pass @ray_method('/ray/server/open_session', 'sis') def rayServerOpenSessionWithTemplate(self, path, args, types, src_addr): pass @ray_method('/ray/server/open_session_off', 's') def rayServerOpenSessionOff(self, path, args, types, src_addr): pass @ray_method('/ray/server/open_session_off', 'si') def rayServerOpenSessionWithoutSaveOff(self, path, args, types, src_addr): pass @ray_method('/ray/server/save_session_template', 'ss') def rayServerSaveSessionTemplate(self, path, args, types, src_addr): #save as template an not loaded session session_name, template_name = args if not _path_is_valid(session_name): self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid session name.") return False if '/' in template_name: self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid template name.") return False @ray_method('/ray/server/rename_session', 'ss') def rayServerRenameSession(self, path, args, types, src_addr): pass @ray_method('/ray/server/save_session_template', 'sss') def rayServerSaveSessionTemplateWithRoot(self, path, args, types, src_addr): #save as template an not loaded session session_name, template_name, sess_root = args if not _path_is_valid(session_name): self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid template name.") return False if '/' in template_name: self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid session name.") return False @ray_method('/ray/server/get_session_preview', 's') def rayServerGetSessionPreview(self, path, args, types, src_addr): self.session_to_preview = args[0] @ray_method('/ray/server/script_info', 's') def rayServerScriptInfo(self, path, args, types, src_addr): self.send_gui('/ray/gui/script_info', args[0]) self.send(src_addr, "/reply", path, "Info sent") @ray_method('/ray/server/hide_script_info', '') def rayServerHideScriptInfo(self, path, args, types, src_addr): self.send_gui('/ray/gui/hide_script_info') self.send(src_addr, "/reply", path, "Info hidden") @ray_method('/ray/server/script_user_action', 's') def rayServerScriptUserAction(self, path, args, types, src_addr): if not self.gui_list: self.send(src_addr, '/error', path, ray.Err.LAUNCH_FAILED, "This server has no attached GUI") return self.send_gui('/ray/gui/script_user_action', args[0]) # set option from GUI @ray_method('/ray/server/set_option', 'i') def rayServerSetOption(self, path, args, types, src_addr): option = args[0] self._set_option(option) for gui_addr in self.gui_list: if not ray.are_same_osc_port(gui_addr.url, src_addr.url): self.send(gui_addr, '/ray/gui/server/options', self.options) # set options from ray_control @ray_method('/ray/server/set_options', None) def rayServerSetOptions(self, path, args, types, src_addr): if not ray.types_are_all_strings(types): self._unknown_message(path, types, src_addr) return False for option_str in args: option_value = True if option_str.startswith('not_'): option_value = False option_str = option_str.replace('not_', '', 1) if option_str in self.options_dict: option = self.options_dict[option_str] if option_value: if (option == ray.Option.DESKTOPS_MEMORY and not self.options & ray.Option.HAS_WMCTRL): self.send(src_addr, '/minor_error', path, "wmctrl is not present. Impossible to activate 'desktops_memory' option") continue if (option == ray.Option.SNAPSHOTS and not self.options & ray.Option.HAS_GIT): self.send(src_addr, '/minor_error', path, "git is not present. Impossible to activate 'snapshots' option") continue if not option_value: option = -option self._set_option(option) for gui_addr in self.gui_list: if not ray.are_same_osc_port(gui_addr.url, src_addr.url): self.send(gui_addr, '/ray/gui/server/options', self.options) self.send(src_addr, '/reply', path, 'Options set') @ray_method('/ray/server/has_option', 's') def rayServerHasOption(self, path, args, types, src_addr): option_str = args[0] option_value = False if option_str not in self.options_dict: self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, "option \"%s\" doesn't exists" % option_str) return if self.options & self.options_dict[option_str]: self.send(src_addr, '/reply', path, 'Has option') else: self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, "Option %s is not currently used" % option_str) @ray_method('/ray/server/clear_client_templates_database', '') def rayServerClearClientTemplatesDatabase(self, path, args, types, src_addr): self.client_templates_database['factory'].clear() self.client_templates_database['user'].clear() self.send(src_addr, '/reply', path, 'database cleared') @ray_method('/ray/server/open_file_manager_at', 's') def rayServerOpenFileManagerAt(self, path, args, types, src_addr): folder_path = args[0] if os.path.isdir(folder_path): subprocess.Popen(['xdg-open', folder_path]) self.send(src_addr, '/reply', path, '') @ray_method('/ray/server/exotic_action', 's') def rayServerExoticAction(self, path, args, types, src_addr): action = args[0] autostart_dir = "%s/.config/autostart" % os.getenv('HOME') desk_file = "ray-jack_checker.desktop" if action == 'set_jack_checker_autostart': if not os.path.exists(autostart_dir): os.makedirs(autostart_dir) src_full_file = "%s/data/share/applications/%s" % (get_code_root(), desk_file) dest_full_path = "%s/%s" % (autostart_dir, desk_file) shutil.copyfile(src_full_file, dest_full_path) elif action == 'unset_jack_checker_autostart': os.remove("%s/%s" % (autostart_dir, desk_file)) @ray_method('/ray/server/patchbay/save_group_position', ray.GroupPosition.sisi()) def rayServerPatchbaySaveCoordinates(self, path, args, types, src_addr): # here send to others GUI the new group position for gui_addr in self.gui_list: if not ray.are_same_osc_port(gui_addr.url, src_addr.url): self.send(gui_addr, '/ray/gui/patchbay/update_group_position', *args) @ray_method('/ray/server/patchbay/save_portgroup', None) def rayServerPatchbaySavePortGroup(self, path, args, types, src_addr): # args must be group_name, port_type, port_mode, above_metadatas, *port_names # where port_names are all strings # so types must start with 'siiis' and may continue with strings only if not types.startswith('siiis'): self._unknown_message(path, types, src_addr) return False other_types = types.replace('siiis', '', 1) for t in other_types: if t != 's': self._unknown_message(path, types, src_addr) return False @ray_method('/ray/session/save', '') def raySessionSave(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to save.") return False @ray_method('/ray/session/run_step', None) def raySessionProcessStep(self, path, args, types, src_addr): if not ray.types_are_all_strings(types): self._unknown_message(path, types, src_addr) return False @ray_method('/ray/session/save_as_template', 's') def raySessionSaveAsTemplate(self, path, args, types, src_addr): template_name = args[0] if '/' in template_name or template_name == '.': self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid session template name.") return False @ray_method('/ray/session/get_session_name', '') def raySessionGetSessionName(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session loaded.") return False self.send(src_addr, '/reply', path, self.session.name) self.send(src_addr, '/reply', path) return False @ray_method('/ray/session/take_snapshot', 's') def raySessionTakeSnapshotOnly(self, path, args, types, src_addr): if not self.options & ray.Option.HAS_GIT: self.send(src_addr, '/error', path, "snapshot impossible because git is not installed") return False @ray_method('/ray/session/take_snapshot', 'si') def raySessionTakeSnapshot(self, path, args, types, src_addr): if not self.options & ray.Option.HAS_GIT: self.send(src_addr, '/error', path, "snapshot impossible because git is not installed") return False @ray_method('/ray/session/close', '') def raySessionClose(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to close.") return False @ray_method('/ray/session/abort', '') def raySessionAbort(self, path, args, types, src_addr): pass @ray_method('/ray/session/cancel_close', '') def raySessionCancelClose(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to cancel close.") return False @ray_method('/ray/session/skip_wait_user', '') def raySessionSkipWaitUser(self, path, args, types, src_addr): if self.server_status != ray.ServerStatus.WAIT_USER: return False @ray_method('/ray/session/duplicate', 's') def raySessionDuplicate(self, path, args, types, src_addr): if self.is_nsm_locked: return False if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to duplicate.") return False if not _path_is_valid(args[0]): self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid session name.") return False @ray_method('/ray/session/duplicate_only', 'sss') def nsmServerDuplicateOnly(self, path, args, types, src_addr): self.send(src_addr, '/ray/net_daemon/duplicate_state', 0) @ray_method('/ray/session/open_snapshot', 's') def raySessionOpenSnapshot(self, path, args, types, src_addr): pass @ray_method('/ray/session/rename', 's') def rayServerRename(self, path, args, types, src_addr): new_session_name = args[0] #prevent rename session in network session if self._nsm_locker_url: NSM_URL = os.getenv('NSM_URL') if not NSM_URL: return False if not ray.are_same_osc_port(self._nsm_locker_url, NSM_URL): return False if '/' in new_session_name: self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, "Invalid session name.") return False if self._is_operation_pending(src_addr, path): return False if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to rename.") return False @ray_method('/ray/session/set_notes', 's') def raySessionSetNotes(self, path, args, types, src_addr): self.session.notes = args[0] for gui_addr in self.gui_list: if not ray.are_same_osc_port(gui_addr.url, src_addr.url): self.send(gui_addr, '/ray/gui/session/notes', self.session.notes) @ray_method('/ray/session/get_notes', '') def raySessionGetNotes(self, path, args, types, src_addr): pass @ray_method('/ray/session/add_executable', 'siiissi') def raySessionAddExecutableAdvanced(self, path, args, types, src_addr): executable_path, auto_start, protocol, \ prefix_mode, prefix_pattern, client_id, jack_naming = args if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "Cannot add to session because no session is loaded.") return False if protocol == ray.Protocol.NSM and '/' in executable_path: self.send(src_addr, "/error", path, ray.Err.LAUNCH_FAILED, "Absolute paths are not permitted. Clients must be in $PATH") return False @ray_method('/ray/session/add_executable', None) def raySessionAddExecutableStrings(self, path, args, types, src_addr): if not (types and ray.types_are_all_strings(types)): self._unknown_message(path, types, src_addr) return False if not self.session.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "Cannot add to session because no session is loaded.") return False executable_path = args[0] via_proxy = bool(len(args) > 1 and 'via_proxy' in args[1:]) ray_hack = bool(len(args) > 1 and 'ray_hack' in args[1:]) if '/' in executable_path and not (via_proxy or ray_hack): self.send(src_addr, "/error", path, ray.Err.LAUNCH_FAILED, "Absolute paths are not permitted. Clients must be in $PATH") return False @ray_method('/ray/session/add_client_template', 'is') def rayServerAddClientTemplate(self, path, args, types, src_addr): pass @ray_method('/ray/session/add_factory_client_template', None) def raySessionAddFactoryClientTemplate(self, path, args, types, src_addr): if not (types and ray.types_are_all_strings(types)): self._unknown_message(path, types, src_addr) return False @ray_method('/ray/session/add_user_client_template', None) def raySessionAddUserClientTemplate(self, path, args, types, src_addr): if not (types and ray.types_are_all_strings(types)): self._unknown_message(path, types, src_addr) return False @ray_method('/ray/session/add_other_session_client', 'ss') def raySessionEatOtherSessionClient(self, path, args, types, src_addr): pass @ray_method('/ray/session/reorder_clients', None) def rayServerReorderClients(self, path, args, types, src_addr): if not (types and ray.types_are_all_strings(types)): self._unknown_message(path, types, src_addr) return False @ray_method('/ray/session/list_snapshots', '') def rayServerListSnapshots(self, path, args, types, src_addr): pass @ray_method('/ray/session/set_auto_snapshot', 'i') def rayServerSetAutoSnapshot(self, path, args, types, src_addr): pass @ray_method('/ray/session/open_folder', '') def rayServerOpenFolder(self, path, args, types, src_addr): if self.session.path: subprocess.Popen(['xdg-open', self.session.path]) self.send(src_addr, '/reply', path, '') @ray_method('/ray/session/clear_clients', None) def raySessionStopClients(self, path, args, types, src_addr): if not ray.types_are_all_strings(types): self._unknown_message(path, types, src_addr) return False @ray_method('/ray/session/show_notes', '') def raySessionShowNotes(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, '/error', path, ray.Err.NO_SESSION_OPEN, "No session to show notes") return False self.session.notes_shown = True self.send_gui('/ray/gui/session/notes_shown') self.send(src_addr, '/reply', path, 'notes shown') @ray_method('/ray/session/hide_notes', '') def raySessionHideNotes(self, path, args, types, src_addr): if not self.session.path: self.send(src_addr, '/error', path, ray.Err.NO_SESSION_OPEN, "No session to hide notes") return False self.session.notes_shown = False self.send_gui('/ray/gui/session/notes_hidden') self.send(src_addr, '/reply', path, 'notes hidden') @ray_method('/ray/session/list_clients', None) def raySessionListClients(self, path, args, types, src_addr): if not ray.types_are_all_strings(types): self._unknown_message(path, types, src_addr) return False @ray_method('/ray/session/list_trashed_clients', '') def raySessionListTrashedClients(self, path, args, types, src_addr): pass @ray_method('/ray/client/stop', 's') def rayGuiClientStop(self, path, args, types, src_addr): pass @ray_method('/ray/client/kill', 's') def rayGuiClientKill(self, path, args, types, src_addr): pass @ray_method('/ray/client/trash', 's') def rayGuiClientRemove(self, path, args, types, src_addr): pass @ray_method('/ray/client/start', 's') def rayGuiClientStart(self, path, args, types, src_addr): pass @ray_method('/ray/client/resume', 's') def rayGuiClientResume(self, path, args, types, src_addr): pass @ray_method('/ray/client/open', 's') def rayClientOpen(self, path, args, types, src_addr): pass @ray_method('/ray/client/save', 's') def rayGuiClientSave(self, path, args, types, src_addr): pass @ray_method('/ray/client/save_as_template', 'ss') def rayGuiClientSaveAsTemplate(self, path, args, types, src_addr): pass @ray_method('/ray/client/show_optional_gui', 's') def nsmGuiClientShow_optional_gui(self, path, args, types, src_addr): pass @ray_method('/ray/client/hide_optional_gui', 's') def nsmGuiClientHide_optional_gui(self, path, args, types, src_addr): pass @ray_method('/ray/client/update_properties', ray.ClientData.sisi()) def rayGuiClientUpdateProperties(self, path, args, types, src_addr): pass @ray_method('/ray/client/update_ray_hack_properties', 's' + ray.RayHack.sisi()) def rayClientUpdateRayHackProperties(self, path, args, types, src_addr): pass @ray_method('/ray/client/update_ray_net_properties', 's' + ray.RayNet.sisi()) def rayClientUpdateRayNetProperties(self, path, args, types, src_addr): pass @ray_method('/ray/client/get_properties', 's') def rayClientGetProperties(self, path, args, types, src_addr): pass @ray_method('/ray/client/set_properties', None) def rayGuiClientSetProperties(self, path, args, types, src_addr): if not (len(args) >= 2 and ray.types_are_all_strings(types)): self._unknown_message(path, types, src_addr) return @ray_method('/ray/client/get_proxy_properties', 's') def rayClientGetProxyProperties(self, path, args, types, src_addr): pass @ray_method('/ray/client/set_proxy_properties', None) def rayClientSetProxyProperties(self, path, args, types, src_addr): if not (len(args) >= 2 and ray.types_are_all_strings(types)): self._unknown_message(path, types, src_addr) return @ray_method('/ray/client/change_prefix', None) def rayClientChangePrefix(self, path, args, types, src_addr): # here message can be si, ss, sis, sss invalid = False if len(args) < 2: invalid = True elif args[1] in (ray.PrefixMode.CUSTOM, 'custom'): if len(args) < 3: invalid = True if invalid: self._unknown_message(path, types, src_addr) return False @ray_method('/ray/client/set_description', 'ss') def rayClientSetDescription(self, path, args, types, src_addr): pass @ray_method('/ray/client/get_description', 's') def rayClientGetDescription(self, path, args, types, src_addr): pass @ray_method('/ray/client/get_pid', 's') def ratClientGetPid(self, path, args, types, src_addr): pass @ray_method('/ray/client/list_files', 's') def rayClientListFiles(self, path, args, types, src_addr): pass @ray_method('/ray/client/list_snapshots', 's') def rayClientListSnapshots(self, path, args, types, src_addr): pass @ray_method('/ray/client/open_snapshot', 'ss') def rayClientLoadSnapshot(self, path, args, types, src_addr): pass @ray_method('/ray/client/is_started', 's') def rayClientIsStarted(self, path, args, types, src_addr): pass @ray_method('/ray/client/set_custom_data', 'sss') def rayClientSetCustomData(self, path, args, types, src_addr): pass @ray_method('/ray/client/get_custom_data', 'ss') def rayClientGetCustomData(self, path, args, types, src_addr): pass @ray_method('/ray/client/set_tmp_data', 'sss') def rayClientSetTmpData(self, path, args, types, src_addr): pass @ray_method('/ray/client/get_tmp_data', 'ss') def rayClientGetTmpData(self, path, args, types, src_addr): pass @ray_method('/ray/client/send_signal', 'si') def rayClientSendSignal(self, path, args, types, src_addr): pass @ray_method('/ray/trashed_client/restore', 's') def rayTrashedClientRestore(self, path, args, types, src_addr): pass @ray_method('/ray/trashed_client/remove_definitely', 's') def rayTrashedClientRemoveDefinitely(self, path, args, types, src_addr): pass @ray_method('/ray/trashed_client/remove_keep_files', 's') def rayTrashedClientRemoveKeepFiles(self, path, args, types, src_addr): pass @ray_method('/ray/net_daemon/duplicate_state', 'f') def rayDuplicateState(self, path, args, types, src_addr): pass @ray_method('/ray/favorites/add', 'ssi') def rayFavoriteAdd(self, path, args, types, src_addr): name, icon, int_factory = args for favorite in RS.favorites: if (favorite.name == name and bool(int_factory) == favorite.factory): favorite.icon = icon break else: RS.favorites.append(ray.Favorite(name, icon, bool(int_factory))) self.send_gui('/ray/gui/favorites/added', *args) @ray_method('/ray/favorites/remove', 'si') def rayFavoriteRemove(self, path, args, types, src_addr): name, int_factory = args for favorite in RS.favorites: if (favorite.name == name and bool(int_factory) == favorite.factory): RS.favorites.remove(favorite) break self.send_gui('/ray/gui/favorites/removed', *args) @ray_method(None, None) def noneMethod(self, path, args, types, src_addr): types_str = '' for t in types: types_str += t self._unknown_message(path, types, src_addr) return False def _is_operation_pending(self, src_addr, path): if self.session.file_copier.is_active(): self.send(src_addr, "/error", path, ray.Err.COPY_RUNNING, "ray-daemon is copying files. " + "Wait copy finish or abort copy, " + "and restart operation !") return True if self.session.steps_order: self.send(src_addr, "/error", path, ray.Err.OPERATION_PENDING, "An operation pending.") return True return False def _set_option(self, option: int): if option >= 0: self.options |= option else: self.options &= ~abs(option) def send(self, *args): if CommandLineArgs.debug: sys.stderr.write( '\033[96mOSC::daemon sends\033[0m ' + str(args[1:]) + '\n') ClientCommunicating.send(self, *args) def send_gui(self, *args): for gui_addr in self.gui_list: self.send(gui_addr, *args) def set_server_status(self, server_status:int): self.server_status = server_status self.send_gui('/ray/gui/server/status', server_status) def send_renameable(self, renameable:bool): if not renameable: self.send_gui('/ray/gui/session/renameable', 0) return if self._nsm_locker_url: nsm_url = os.getenv('NSM_URL') if not nsm_url: return if not ray.are_same_osc_port(self._nsm_locker_url, nsm_url): return self.send_gui('/ray/gui/session/renameable', 1) def announce_gui(self, url, nsm_locked=False, is_net_free=True, gui_pid=0): gui_addr = GuiAdress(url) gui_addr.gui_pid = gui_pid self.send(gui_addr, "/ray/gui/server/announce", ray.VERSION, self.server_status, self.options, self.session.root, int(is_net_free)) self.send(gui_addr, "/ray/gui/server/status", self.server_status) self.send(gui_addr, "/ray/gui/session/name", self.session.name, self.session.path) self.send(gui_addr, '/ray/gui/session/notes', self.session.notes) self.session.canvas_saver.send_all_group_positions(gui_addr) for favorite in RS.favorites: self.send(gui_addr, "/ray/gui/favorites/added", favorite.name, favorite.icon, int(favorite.factory)) for client in self.session.clients: self.send(gui_addr, '/ray/gui/client/new', *client.spread()) if client.protocol == ray.Protocol.RAY_HACK: self.send(gui_addr, '/ray/gui/client/ray_hack_update', client.client_id, *client.ray_hack.spread()) elif client.protocol == ray.Protocol.RAY_NET: self.send(gui_addr, '/ray/gui/client/ray_net_update', client.client_id, *client.ray_net.spread()) self.send(gui_addr, "/ray/gui/client/status", client.client_id, client.status) if client.is_capable_of(':optional-gui:'): self.send(gui_addr, '/ray/gui/client/gui_visible', client.client_id, int(client.gui_visible)) if client.is_capable_of(':dirty:'): self.send(gui_addr, '/ray/gui/client/dirty', client.client_id, client.dirty) for trashed_client in self.session.trashed_clients: self.send(gui_addr, '/ray/gui/trash/add', *trashed_client.spread()) if trashed_client.protocol == ray.Protocol.RAY_HACK: self.send(gui_addr, '/ray/gui/trash/ray_hack_update', trashed_client.client_id, *trashed_client.ray_hack.spread()) elif trashed_client.protocol == ray.Protocol.RAY_NET: self.send(gui_addr, '/ray/gui/trash/ray_net_update', trashed_client.client_id, *trashed_client.ray_net.spread()) self.session.check_recent_sessions_existing() if self.session.root in self.session.recent_sessions.keys(): self.send(gui_addr, '/ray/gui/server/recent_sessions', *self.session.recent_sessions[self.session.root]) self.send(gui_addr, '/ray/gui/server/message', _translate('daemon', "daemon runs at %s") % self.url) self.gui_list.append(gui_addr) multi_daemon_file = MultiDaemonFile.get_instance() if multi_daemon_file: multi_daemon_file.update() Terminal.message("GUI connected at %s" % gui_addr.url) def announce_controller(self, control_address): controller = Controller() controller.addr = control_address self.controller_list.append(controller) self.send(control_address, "/ray/control/server/announce", ray.VERSION, self.server_status, self.options, self.session.root, 1) def send_controller_message(self, message): for controller in self.controller_list: self.send(controller.addr, '/ray/control/message', message) def has_gui(self)->int: has_gui = False for gui_addr in self.gui_list: if ray.are_on_same_machine(self.url, gui_addr.url): # we've got a local GUI return 3 has_gui = True if has_gui: return 1 return 0 def get_local_gui_pid_list(self)->str: pid_list = [] for gui_addr in self.gui_list: if ray.are_on_same_machine(gui_addr.url, self.url): pid_list.append(str(gui_addr.gui_pid)) return ':'.join(pid_list) def is_gui_address(self, addr)->bool: for gui_addr in self.gui_list: if ray.are_same_osc_port(gui_addr.url, addr.url): return True return False RaySession-0.12.2/src/daemon/ray-daemon.py000077500000000000000000000112071417052567600203540ustar00rootroot00000000000000#!/usr/bin/python3 -u import os import signal import sys from PyQt5.QtCore import (QCoreApplication, QTimer, QLocale, QTranslator) import ray from daemon_tools import (init_daemon_tools, RS, get_code_root, CommandLineArgs, ArgParser, Terminal) from osc_server_thread import OscServerThread from multi_daemon_file import MultiDaemonFile from session_signaled import SignaledSession def signal_handler(sig, frame): if sig in (signal.SIGINT, signal.SIGTERM): session.terminate() if __name__ == '__main__': #add RaySession/src/bin to $PATH ray.add_self_bin_to_path() #create app app = QCoreApplication(sys.argv) app.setApplicationName("RaySession") app.setOrganizationName("RaySession") init_daemon_tools() ### Translation process locale = QLocale.system().name() appTranslator = QTranslator() if appTranslator.load("%s/locale/raysession_%s" % (get_code_root(), locale)): app.installTranslator(appTranslator) _translate = app.translate #check arguments parser = ArgParser() #manage session_root session_root = CommandLineArgs.session_root if not session_root: session_root = "%s/%s" % (os.getenv('HOME'), _translate('daemon', 'Ray Network Sessions')) #make session_root folder if needed if not os.path.isdir(session_root): if os.path.exists(session_root): sys.stderr.write( "%s exists and is not a dir, please choose another path !\n" % session_root) sys.exit(1) try: os.makedirs(session_root) except: sys.stderr.write("impossible to make dir %s , aborted !\n" % session_root) sys.exit(1) #create session session = SignaledSession(session_root) #create and start server if CommandLineArgs.findfreeport: server = OscServerThread(session, ray.get_free_osc_port( CommandLineArgs.osc_port)) else: if ray.is_osc_port_free(CommandLineArgs.osc_port): server = OscServerThread(session, CommandLineArgs.osc_port) else: sys.stderr.write( _translate('daemon', 'port %i is not free, try another one\n') % CommandLineArgs.osc_port) sys.exit() server.start() if CommandLineArgs.hidden: server.not_default = True #announce server to GUI if CommandLineArgs.gui_url: server.announce_gui(CommandLineArgs.gui_url.url, gui_pid=CommandLineArgs.gui_pid) elif CommandLineArgs.gui_port: server.announce_gui(CommandLineArgs.gui_port.url, gui_pid=CommandLineArgs.gui_pid) # announce to ray_control if launched from it. if CommandLineArgs.control_url: server.announce_controller(CommandLineArgs.control_url) #print server url Terminal.message('URL : %s' % ray.get_net_url(server.port)) Terminal.message(' %s' % server.url) Terminal.message('ROOT: %s' % CommandLineArgs.session_root) #create or update multi_daemon_file in /tmp multi_daemon_file = MultiDaemonFile(session, server) multi_daemon_file.update() #clean bookmarks created by crashed daemons session.bookmarker.clean(multi_daemon_file.get_all_session_paths()) #load session asked from command line if CommandLineArgs.session: session.server_open_session_at_start(CommandLineArgs.session) #connect SIGINT and SIGTERM signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) #needed for SIGINT and SIGTERM timer = QTimer() timer.setInterval(200) timer.timeout.connect(lambda: None) timer.start() #start app app.exec() #app is stopped #update multi_daemon_file without this server multi_daemon_file.quit() #save RS.settings RS.settings.setValue('daemon/non_active_list', RS.non_active_clients) RS.settings.setValue('daemon/favorites', RS.favorites) RS.settings.setValue('daemon/recent_sessions', session.recent_sessions) if not CommandLineArgs.no_options: RS.settings.setValue('daemon/options', server.options) # save JSON config group positions session.canvas_saver.save_config_file() # save sessions infos in cache session.save_folder_sizes_cache_file() RS.settings.sync() #stop the server server.stop() del server del session del app RaySession-0.12.2/src/daemon/ray.py000077700000000000000000000000001417052567600217302../shared/ray.pyustar00rootroot00000000000000RaySession-0.12.2/src/daemon/scripter.py000066400000000000000000000175701417052567600201610ustar00rootroot00000000000000import os from PyQt5.QtCore import QProcess, QProcessEnvironment, QCoreApplication import ray from daemon_tools import Terminal, dirname, highlight_text from server_sender import ServerSender _translate = QCoreApplication.translate class Scripter(ServerSender): def __init__(self): ServerSender.__init__(self) self._src_addr = None self._src_path = '' self._process = QProcess() self._process.started.connect(self._process_started) self._process.finished.connect(self._process_finished) self._process.readyReadStandardError.connect(self._standard_error) self._process.readyReadStandardOutput.connect(self._standard_output) self._asked_for_terminate = False def _process_started(self): pass def _process_finished(self, exit_code, exit_status): if exit_code: if exit_code == 101: message = _translate('GUIMSG', 'script %s failed to start !') % ( highlight_text(self.get_path())) else: message = _translate('GUIMSG', 'script %s terminated with exit code %i') % ( highlight_text(self.get_path()), exit_code) if self._src_addr: self.send(self._src_addr, '/error', self._src_path, - exit_code, message) else: self.send_gui_message( _translate('GUIMSG', '...script %s finished. ---') % highlight_text(self.get_path())) if self._src_addr: self.send(self._src_addr, '/reply', self._src_path, 'script finished') def _standard_error(self): standard_error = self._process.readAllStandardError().data() Terminal.scripter_message(standard_error, self._get_command_name()) def _standard_output(self): standard_output = self._process.readAllStandardOutput().data() Terminal.scripter_message(standard_output, self._get_command_name()) def is_running(self): return bool(self._process.state()) def terminate(self): self._asked_for_terminate = True self._process.terminate() def is_asked_for_terminate(self): return self._asked_for_terminate def kill(self): self._process.kill() def get_path(self): return self._process.program() def _get_command_name(self): return self.get_path().rpartition('/')[2] def get_pid(self): if self._process.state(): return self._process.pid() return 0 class StepScripter(Scripter): def __init__(self, session): Scripter.__init__(self) self.session = session self.is_dummy = self.session.is_dummy self._step_str = '' self._stepper_has_call = False def _get_script_dirs(self, spath): base_path = spath scripts_dir = '' parent_scripts_dir = '' while base_path not in ('/', ''): tmp_scripts_dir = "%s/%s" % (base_path, ray.SCRIPTS_DIR) if os.path.isdir(tmp_scripts_dir): if not scripts_dir: scripts_dir = tmp_scripts_dir else: parent_scripts_dir = tmp_scripts_dir break base_path = dirname(base_path) return (scripts_dir, parent_scripts_dir) def _process_started(self): pass def _process_finished(self, exit_code, exit_status): Scripter._process_finished(self, exit_code, exit_status) self.session.step_scripter_finished() self._stepper_has_call = False def start(self, step_str, arguments, src_addr=None, src_path=''): if self.is_running(): return False if not self.session.path: return False scripts_dir, parent_scripts_dir = self._get_script_dirs( self.session.path) future_scripts_dir, future_parent_scripts_dir = self._get_script_dirs( self.session.future_session_path) script_path = "%s/%s.sh" % (scripts_dir, step_str) if not os.access(script_path, os.X_OK): return False self._src_addr = src_addr self._src_path = src_path self._stepper_has_call = False self._step_str = step_str self.send_gui_message( _translate('GUIMSG', '--- Custom step script %s started...') % highlight_text(script_path)) process_env = QProcessEnvironment.systemEnvironment() process_env.insert('RAY_CONTROL_PORT', str(self.get_server_port())) process_env.insert('RAY_SCRIPTS_DIR', scripts_dir) process_env.insert('RAY_PARENT_SCRIPTS_DIR', parent_scripts_dir) process_env.insert('RAY_FUTURE_SESSION_PATH', self.session.future_session_path) process_env.insert('RAY_FUTURE_SCRIPTS_DIR', future_scripts_dir) process_env.insert('RAY_SWITCHING_SESSION', str(self.session.switching_session).lower()) process_env.insert('RAY_SESSION_PATH', self.session.path) self._process.setProcessEnvironment(process_env) self._process.start(script_path, [str(a) for a in arguments]) return True def get_step(self): return self._step_str def stepper_has_called(self): return self._stepper_has_call def set_stepper_has_call(self, call: bool): self._stepper_has_call = call class ClientScripter(Scripter): def __init__(self, client): Scripter.__init__(self) self._client = client self._pending_command = ray.Command.NONE self._initial_caller = (None, '') def _process_finished(self, exit_code, exit_status): Scripter._process_finished(self, exit_code, exit_status) self._client.script_finished(exit_code) self._pending_command = ray.Command.NONE self._initial_caller = (None, '') self._src_addr = None def start(self, command, src_addr=None, previous_slot=(None, '')): if self.is_running(): return False command_string = '' if command == ray.Command.START: command_string = 'start' elif command == ray.Command.SAVE: command_string = 'save' elif command == ray.Command.STOP: command_string = 'stop' else: return False scripts_dir = "%s/%s.%s" % \ (self._client.session.path, ray.SCRIPTS_DIR, self._client.client_id) script_path = "%s/%s.sh" % (scripts_dir, command_string) if not os.access(script_path, os.X_OK): return False self._pending_command = command if src_addr: # Remember the caller of the function calling the script # Then, when script is finished # We could reply to this (address, path) self._initial_caller = previous_slot self._src_addr = src_addr process_env = QProcessEnvironment.systemEnvironment() process_env.insert('RAY_CONTROL_PORT', str(self.get_server_port())) process_env.insert('RAY_CLIENT_SCRIPTS_DIR', scripts_dir) process_env.insert('RAY_CLIENT_ID', self._client.client_id) process_env.insert('RAY_CLIENT_EXECUTABLE', self._client.executable_path) process_env.insert('RAY_CLIENT_ARGUMENTS', self._client.arguments) self._process.setProcessEnvironment(process_env) self.send_gui_message( _translate('GUIMSG', '--- Custom script %s started...%s') % (highlight_text(script_path), self._client.client_id)) self._process.start(script_path, []) return True def pending_command(self): return self._pending_command def initial_caller(self): return self._initial_caller RaySession-0.12.2/src/daemon/server_sender.py000066400000000000000000000055301417052567600211650ustar00rootroot00000000000000 from PyQt5.QtCore import QObject import ray from osc_server_thread import OscServerThread class ServerSender(QObject): def __init__(self): QObject.__init__(self) self.is_dummy = False def has_server(self): if not OscServerThread.getInstance(): return False return not self.is_dummy def send(self, *args): if self.is_dummy: return server = OscServerThread.getInstance() if not server: return server.send(*args) def send_even_dummy(self, *args): server = OscServerThread.getInstance() if not server: return server.send(*args) def send_gui(self, *args): if self.is_dummy: return server = OscServerThread.getInstance() if not server: return server.send_gui(*args) def send_gui_message(self, message:str): self.send_gui('/ray/gui/server/message', message) server = OscServerThread.getInstance() if server: server.send_controller_message(message) def set_server_status(self, server_status:int): if self.is_dummy: return server = OscServerThread.getInstance() if not server: return server.set_server_status(server_status) def get_server_status(self): if self.is_dummy: return -1 server = OscServerThread.getInstance() if not server: return -1 return server.server_status def is_nsm_locked(self): if self.is_dummy: return False server = OscServerThread.getInstance() if not server: return False return server.is_nsm_locked def get_server(self): if self.is_dummy: return None return OscServerThread.getInstance() def get_server_even_dummy(self): return OscServerThread.getInstance() def get_server_url(self): server = OscServerThread.getInstance() if server: return server.url return '' def get_server_port(self): server = OscServerThread.getInstance() if server: return server.port return 0 def answer(self, src_addr, src_path, message, err=ray.Err.OK): if err == ray.Err.OK: self.send(src_addr, '/reply', src_path, message) else: self.send(src_addr, '/error', src_path, err, message) def has_server_option(self, option: int)->bool: server = self.get_server() if not server: return False return bool(server.options & option) def get_client_templates_database(self, base:str)->list: server = OscServerThread.getInstance() if server: return server.client_templates_database[base] return [] RaySession-0.12.2/src/daemon/session.py000066400000000000000000003107431417052567600200070ustar00rootroot00000000000000import functools import math import os import random import shutil import string import subprocess import sys import time from liblo import Address from PyQt5.QtCore import QCoreApplication, QTimer, QProcess from PyQt5.QtXml import QDomDocument import ray from bookmarker import BookMarker from desktops_memory import DesktopsMemory from snapshoter import Snapshoter from multi_daemon_file import MultiDaemonFile from signaler import Signaler from server_sender import ServerSender from file_copier import FileCopier from client import Client from scripter import StepScripter from canvas_saver import CanvasSaver from daemon_tools import ( TemplateRoots, RS, Terminal, get_git_default_un_and_ignored, dirname, basename, highlight_text) _translate = QCoreApplication.translate signaler = Signaler.instance() class Session(ServerSender): def __init__(self, root, session_id=0): ServerSender.__init__(self) self.root = root self.is_dummy = False self.session_id = session_id self.clients = [] self.future_clients = [] self.trashed_clients = [] self.future_trashed_clients = [] self.new_client_exec_args = [] self.favorites = [] self.recent_sessions = {} self.name = "" self.path = "" self.future_session_path = "" self.future_session_name = "" self.notes = "" self.future_notes = "" self.notes_shown = False self.future_notes_shown = False self.load_locked = False self.is_renameable = True self.forbidden_ids_set = set() self.file_copier = FileCopier(self) self.bookmarker = BookMarker() self.desktops_memory = DesktopsMemory(self) self.snapshoter = Snapshoter(self) self.step_scripter = StepScripter(self) self.canvas_saver = CanvasSaver(self) ############# def osc_reply(self, *args): if not self.osc_src_addr: return self.send(self.osc_src_addr, *args) def set_renameable(self, renameable:bool): server = self.get_server() if server is None: return if not renameable: if self.is_renameable: self.is_renameable = False if server: server.send_renameable(False) return for client in self.clients: if client.is_running(): return self.is_renameable = True server.send_renameable(True) def message(self, string, even_dummy=False): if self.is_dummy and not even_dummy: return server = self.get_server() if server is not None: Terminal.message(string, server.port) else: Terminal.message(string) def _set_name(self, session_name): self.name = session_name def _set_path(self, session_path, session_name=''): if not self.is_dummy: if self.path: self.bookmarker.remove_all(self.path) self.path = session_path if session_name: self._set_name(session_name) else: self._set_name(session_path.rpartition('/')[2]) if self.is_dummy: return multi_daemon_file = MultiDaemonFile.get_instance() if multi_daemon_file: multi_daemon_file.update() if self.path: if (self.has_server_option(ray.Option.BOOKMARK_SESSION)): self.bookmarker.set_daemon_port(self.get_server_port()) self.bookmarker.make_all(self.path) def _no_future(self): self.future_clients.clear() self.future_session_path = '' self.future_session_name = '' self.future_trashed_clients.clear() self.future_notes = "" self.future_notes_shown = False def get_short_path(self): if self.path.startswith("%s/" % self.root): return self.path.replace("%s/" % self.root, '', 1) return self.name def get_full_path(self, session_name: str)->str: spath = "%s%s%s" % (self.root, os.sep, session_name) if session_name.startswith(os.sep): spath = session_name if spath.endswith(os.sep): spath = spath[:-1] return spath def remember_as_recent(self): # put loaded session (if exists) in recent sessions if self.name and not self.is_dummy: long_name = self.path.replace(self.root + '/', '', 1) if not self.root in self.recent_sessions.keys(): self.recent_sessions[self.root] = [] if long_name in self.recent_sessions[self.root]: self.recent_sessions[self.root].remove(long_name) self.recent_sessions[self.root].insert(0, long_name) if len(self.recent_sessions[self.root]) > 7: self.recent_sessions[self.root] = self.recent_sessions[self.root][:7] self.send_gui('/ray/gui/server/recent_sessions', *self.recent_sessions[self.root]) def get_client(self, client_id:str)->Client: for client in self.clients: if client.client_id == client_id: return client sys.stderr.write("client_id %s is not in ray-daemon session\n") def get_client_by_address(self, addr)->Client: if not addr: return None for client in self.clients: if client.addr and client.addr.url == addr.url: return client def _new_client(self, executable, client_id=None)->Client: client = Client(self) client.executable_path = executable client.name = basename(executable) client.client_id = client_id if not client_id: client.client_id = self.generate_client_id(executable) self.clients.append(client) return client def _trash_client(self, client:Client): if not client in self.clients: raise NameError("No client to trash: %s" % client.client_id) return client.set_status(ray.ClientStatus.REMOVED) ## Theses lines are commented because finally choice is to ## always send client to trash ## comment self.trashed_client.append(client) if choice is reversed !!! #if client.is_ray_hack(): #client_dir = client.get_project_path() #if os.path.isdir(client_dir): #if os.listdir(client_dir): #self.trashed_clients.append(client) #client.send_gui_client_properties(removed=True) #else: #try: #os.removedirs(client_dir) #except: #self.trashed_clients.append(client) #client.send_gui_client_properties(removed=True) #elif client.getProjectFiles() or client.net_daemon_url: #self.trashed_clients.append(client) #client.send_gui_client_properties(removed=True) self.trashed_clients.append(client) client.send_gui_client_properties(removed=True) self.clients.remove(client) def _remove_client(self, client:Client): client.terminate_scripts() client.terminate() if not client in self.clients: raise NameError("No client to remove: %s" % client.client_id) return client.set_status(ray.ClientStatus.REMOVED) self.clients.remove(client) def _restore_client(self, client)->bool: client.sent_to_gui = False if not self._add_client(client): return False self.send_gui('/ray/gui/trash/remove', client.client_id) self.trashed_clients.remove(client) return True def _clients_have_errors(self): for client in self.clients: if client.active and client.has_error(): return True return False def _update_forbidden_ids_set(self): if not self.path: return self.forbidden_ids_set.clear() for file in os.listdir(self.path): if os.path.isdir("%s/%s" % (self.path, file)) and '.' in file: client_id = file.rpartition('.')[2] self.forbidden_ids_set.add(client_id) elif os.path.isfile("%s/%s" % (self.path, file)) and '.' in file: for string in file.split('.')[1:]: self.forbidden_ids_set.add(string) for client in self.clients + self.trashed_clients: self.forbidden_ids_set.add(client.client_id) def _get_search_template_dirs(self, factory)->list: if factory: # search templates in /etc/xdg (RaySession installed) templates_root = TemplateRoots.factory_clients_xdg # search templates in source code if not os.path.isdir(templates_root): templates_root = TemplateRoots.factory_clients if (os.path.isdir(templates_root) and os.access(templates_root, os.R_OK)): return ["%s/%s" % (templates_root, f) for f in sorted(os.listdir(templates_root))] return [] return [TemplateRoots.user_clients] def _generate_client_id_as_nsm(self)->str: client_id = 'n' for i in range(4): client_id += random.choice(string.ascii_uppercase) return client_id def _save_session_file(self)->int: session_file = self.path + '/raysession.xml' if self.is_nsm_locked() and os.getenv('NSM_URL'): session_file = self.path + '/raysubsession.xml' if (os.path.isfile(session_file) and not os.access(session_file, os.W_OK)): return ray.Err.CREATE_FAILED try: file = open(session_file, 'w') except: return ray.Err.CREATE_FAILED xml = QDomDocument() p = xml.createElement('RAYSESSION') p.setAttribute('VERSION', ray.VERSION) p.setAttribute('name', self.name) if self.notes_shown: p.setAttribute('notes_shown', 'true') xml_cls = xml.createElement('Clients') xml_rmcls = xml.createElement('RemovedClients') xml_wins = xml.createElement('Windows') # save clients attributes for client in self.clients: cl = xml.createElement('client') cl.setAttribute('id', client.client_id) launched = int(bool(client.is_running() or (client.auto_start and not client.has_been_started))) cl.setAttribute('launched', launched) client.write_xml_properties(cl) xml_cls.appendChild(cl) # save trashed clients attributes for client in self.trashed_clients: cl = xml.createElement('client') cl.setAttribute('id', client.client_id) client.write_xml_properties(cl) xml_rmcls.appendChild(cl) # save desktop memory of windows if needed if self.has_server_option(ray.Option.DESKTOPS_MEMORY): self.desktops_memory.save() for win in self.desktops_memory.saved_windows: xml_win = xml.createElement('window') xml_win.setAttribute('class', win.wclass) xml_win.setAttribute('name', win.name) xml_win.setAttribute('desktop', win.desktop) xml_wins.appendChild(xml_win) p.appendChild(xml_cls) p.appendChild(xml_rmcls) p.appendChild(xml_wins) xml.appendChild(p) contents = ("\n" "\n") contents += xml.toString() try: file.write(contents) except: file.close() return ray.Err.CREATE_FAILED #self.save_error(ray.Err.CREATE_FAILED) file.close() def generate_abstract_client_id(self, wanted_id:str)->str: ''' generates a client_id from wanted_id not regarding the existing ids in the session or session directory. Useful for templates ''' for to_rm in ('ray-', 'non-', 'carla-'): if wanted_id.startswith(to_rm): wanted_id = wanted_id.replace(to_rm, '', 1) break wanted_id = wanted_id.replace('jack', '') #reduce string if contains '-' if '-' in wanted_id: new_wanted_id = '' seplist = wanted_id.split('-') for sep in seplist[:-1]: if sep: new_wanted_id += (sep[0] + '_') new_wanted_id += seplist[-1] wanted_id = new_wanted_id #prevent non alpha numeric characters new_wanted_id = '' last_is_ = False for char in wanted_id: if char.isalnum(): new_wanted_id += char else: if not last_is_: new_wanted_id += '_' last_is_ = True wanted_id = new_wanted_id while wanted_id and wanted_id.startswith('_'): wanted_id = wanted_id[1:] while wanted_id and wanted_id.endswith('_'): wanted_id = wanted_id[:-1] #limit string to 10 characters if len(wanted_id) >= 11: wanted_id = wanted_id[:10] return wanted_id def generate_client_id(self, wanted_id="", abstract=False)->str: self._update_forbidden_ids_set() wanted_id = basename(wanted_id) if wanted_id: wanted_id = self.generate_abstract_client_id(wanted_id) if not wanted_id: wanted_id = self._generate_client_id_as_nsm() while wanted_id in self.forbidden_ids_set: wanted_id = self._generate_client_id_as_nsm() if not wanted_id in self.forbidden_ids_set: self.forbidden_ids_set.add(wanted_id) return wanted_id n = 2 while "%s_%i" % (wanted_id, n) in self.forbidden_ids_set: n += 1 self.forbidden_ids_set.add(wanted_id) return "%s_%i" % (wanted_id, n) client_id = 'n' for l in range(4): client_id += random.choice(string.ascii_uppercase) while client_id in self.forbidden_ids_set: client_id = 'n' for l in range(4): client_id += random.choice(string.ascii_uppercase) self.forbidden_ids_set.add(client_id) return client_id def _add_client(self, client)->bool: if self.load_locked or not self.path: return False if client.is_ray_hack(): project_path = client.get_project_path() if not os.path.isdir(project_path): try: os.makedirs(project_path) except: return False client.update_infos_from_desktop_file() self.clients.append(client) client.send_gui_client_properties() self._update_forbidden_ids_set() return True def _re_order_clients(self, client_ids_list, src_addr=None, src_path=''): client_newlist = [] for client_id in client_ids_list: for client in self.clients: if client.client_id == client_id: client_newlist.append(client) break if len(client_newlist) != len(self.clients): if src_addr: self.send(src_addr, '/error', src_path, ray.Err.GENERAL_ERROR, "%s clients are missing or incorrect" \ % (len(self.clients) - len(client_ids_list))) return self.clients.clear() for client in client_newlist: self.clients.append(client) if src_addr: self.answer(src_addr, src_path, "clients reordered") self.send_gui('/ray/gui/session/sort_clients', *[c.client_id for c in self.clients]) def _is_path_in_a_session_dir(self, spath): if self.is_nsm_locked() and os.getenv('NSM_URL'): return False base_path = spath while not base_path in ('/', ''): base_path = dirname(base_path) if os.path.isfile("%s/raysession.xml" % base_path): return True return False def _rewrite_user_templates_file(self, content, templates_file)->bool: if not os.access(templates_file, os.W_OK): return False file_version = content.attribute('VERSION') if ray.version_to_tuple(file_version) >= ray.version_to_tuple(ray.VERSION): return False content.setAttribute('VERSION', ray.VERSION) if ray.version_to_tuple(file_version) >= (0, 8, 0): return True nodes = content.childNodes() for i in range(nodes.count()): node = nodes.at(i) ct = node.toElement() tag_name = ct.tagName() if tag_name != 'Client-Template': continue executable = ct.attribute('executable') if not executable: continue ign_list, unign_list = get_git_default_un_and_ignored(executable) if ign_list: ct.setAttribute('ignored_extensions', " ".join(ign_list)) if unign_list: ct.setAttribute('unignored_extensions', " ".join(unign_list)) return True def export_user_client_template(self, src_addr, template_name:str, export_path:str)->bool: # still work in progress and not used function # will see later if it is really useful templates_file = "%s/%s" % ( TemplateRoots.user_clients, 'client_templates.xml') if not os.path.isfile(templates_file): return False if not os.access(templates_file, os.R_OK): return False file = open(templates_file, 'r') xml = QDomDocument() xml.setContent(file.read()) file.close() new_xml = QDomDocument() content = xml.documentElement() if content.tagName() != "RAY-CLIENT-TEMPLATES": return False nodes = content.childNodes() for i in range(nodes.count()): node = nodes.at(i) ct = node.toElement() tag_name = ct.tagName() if tag_name != 'Client-Template': continue if ct.attribute('template-name') == template_name: break else: return False def send_initial_monitor(self, monitor_addr, monitor_is_client=True): ''' send clients states to a new monitor ''' prefix = '/nsm/client/monitor/' if not monitor_is_client: prefix = '/ray/monitor/' for client in self.clients: if (client.addr is not None and ray.are_same_osc_port(client.addr.url, monitor_addr.url)): continue self.send( monitor_addr, prefix + 'client_state', client.client_id, int(client.is_running())) for client in self.trashed_clients: self.send( monitor_addr, prefix + 'client_state', client.client_id, 0) def send_monitor_event(self, event:str, client_id = ''): ''' send an event message to clients capable of ":monitor:" ''' for client in self.clients: if (client.client_id != client_id and client.is_capable_of(':monitor:')): client.send_to_self_address( '/nsm/client/monitor/client_event', client_id, event) server = self.get_server() if server is not None: for monitor_addr in server.monitor_list: self.send(monitor_addr, '/ray/monitor/client_event', client_id, event) def _rebuild_templates_database(self, base): def get_nsm_capable_execs_from_desktop_files()->list: ''' returns a list of tuples {'executable': str, 'name': str, 'desktop_file': str, 'nsm_capable': True, 'skipped': False} ''' desk_path_list = ( '%s/.local' % os.getenv('HOME'), '/usr/local', '/usr') application_dicts = [] lang = os.getenv('LANG') lang_strs = ("[%s]" % lang[0:5], "[%s]" % lang[0:2], "") for desk_path in desk_path_list: full_desk_path = "%s/share/applications" % desk_path if not os.path.isdir(full_desk_path): # applications folder doesn't exists continue if not os.access(full_desk_path, os.R_OK): # no permission to read this applications folder continue for root, dirs, files in os.walk(full_desk_path): for f in files: if not f.endswith('.desktop'): continue if f in [apd['desktop_file'] for apd in application_dicts]: # desktop file already seen in a prior desk_path continue full_desk_file = os.path.join(root, f) try: file = open(full_desk_file, 'r') contents = file.read() except: continue executable = '' has_nsm_mention = False nsm_capable = True name = '' for line in contents.splitlines(): if line.startswith('Exec='): executable_and_args = line.partition('=')[2].strip() executable = executable_and_args.partition(' ')[0] elif line.lower().startswith('x-nsm-capable='): has_nsm_mention = True value = line.partition('=')[2] nsm_capable = bool(value.strip().lower() == 'true') elif line.startswith('Name='): name = line.partition('=')[2].strip() if (has_nsm_mention and executable and shutil.which(executable)): # prevent several desktop files with same executable if executable in [apd['executable'] for apd in application_dicts]: continue name = executable name_found = False for lang_str in lang_strs: for line in contents.splitlines(): if line.startswith('Name%s=' % lang_str): name = line.partition('=')[2].strip() name_found = True break if name_found: break # 'skipped' key may be set to True later, # if a template does not want to be erased # by the template created # with this .desktop file. application_dicts.append( {'executable': executable, 'name': name, 'desktop_file': f, 'nsm_capable': nsm_capable, 'skipped': False}) return [a for a in application_dicts if a['nsm_capable']] # discovery start factory = bool(base == 'factory') templates_database = self.get_client_templates_database(base) templates_database.clear() template_names = set() from_desktop_execs = [] if base == 'factory': from_desktop_execs = get_nsm_capable_execs_from_desktop_files() search_paths = self._get_search_template_dirs(factory) file_rewritten = False for search_path in search_paths: templates_file = "%s/%s" % (search_path, 'client_templates.xml') if not os.path.isfile(templates_file): continue if not os.access(templates_file, os.R_OK): sys.stderr.write("ray-daemon:No access to %s in %s, ignore it" % (templates_file, search_path)) continue file = open(templates_file, 'r') xml = QDomDocument() xml.setContent(file.read()) file.close() content = xml.documentElement() if content.tagName() != "RAY-CLIENT-TEMPLATES": continue if not factory: # we may rewrite user client templates file if content.attribute('VERSION') != ray.VERSION: file_rewritten = self._rewrite_user_templates_file( content, templates_file) erased_by_nsm_desktop_global = bool( content.attribute('erased_by_nsm_desktop_file').lower() == 'true') nodes = content.childNodes() for i in range(nodes.count()): node = nodes.at(i) ct = node.toElement() tag_name = ct.tagName() if tag_name != 'Client-Template': continue template_name = ct.attribute('template-name') if (not template_name or '/' in template_name or template_name in template_names): continue executable = ct.attribute('executable') protocol = ray.protocol_from_str(ct.attribute('protocol')) # check if we wan't this template to be erased by a .desktop file # with X-NSM-Capable=true if ct.attribute('erased_by_nsm_desktop_file'): erased_by_nsm_desktop = bool( ct.attribute('erased_by_nsm_desktop_file').lower() == 'true') else: erased_by_nsm_desktop = erased_by_nsm_desktop_global nsm_desktop_prior_found = False # With 'needs_nsm_desktop_file', this template will be provided only if # a *.desktop file with the same executable contains X-NSM-Capable=true needs_nsm_desktop_file = bool( ct.attribute('needs_nsm_desktop_file').lower() == True) has_nsm_desktop = False # Parse .desktop files in memory for fde in from_desktop_execs: if fde['executable'] == executable: has_nsm_desktop = True if erased_by_nsm_desktop: # This template won't be provided nsm_desktop_prior_found = True else: # The .desktop file will be skipped, # we use this template instead fde['skipped'] = True break else: # No *.desktop file with same executable as this template if needs_nsm_desktop_file: # This template needs a *.desktop file with X-NSM-Capable # and there is no one, skip this template continue if nsm_desktop_prior_found: continue # check if needed executables are present if protocol != ray.Protocol.RAY_NET: if not executable: continue try_exec_line = ct.attribute('try-exec') try_exec_list = try_exec_line.split(';') if try_exec_line else [] if not has_nsm_desktop: try_exec_list.append(executable) try_exec_ok = True for try_exec in try_exec_list: if not shutil.which(try_exec): try_exec_ok = False break if not try_exec_ok: continue if not has_nsm_desktop: # search for '/nsm/server/announce' in executable binary # if it is asked by "check_nsm_bin" key if ct.attribute('check_nsm_bin') in ("1", "true"): result = QProcess.execute( 'grep', ['-q', '/nsm/server/announce', shutil.which(executable)]) if result: continue # check if a version is at least required for this template # don't use needed-version without check how the program acts ! needed_version = ct.attribute('needed-version') if (needed_version.startswith('.') or needed_version.endswith('.') or not needed_version.replace('.', '').isdigit()): #needed-version not writed correctly, ignores it needed_version = '' if needed_version: version_process = QProcess() version_process.start(executable, ['--version']) version_process.waitForFinished(500) # do not allow program --version to be longer than 500ms if version_process.state(): version_process.terminate() version_process.waitForFinished(500) continue full_program_version = str( version_process.readAllStandardOutput(), encoding='utf-8') previous_is_digit = False program_version = '' for character in full_program_version: if character.isdigit(): program_version += character previous_is_digit = True elif character == '.': if previous_is_digit: program_version += character previous_is_digit = False else: if program_version: break if not program_version: continue neededs = [int(s) for s in needed_version.split('.')] progvss = [int(s) for s in program_version.split('.')] if neededs > progvss: # program is too old, ignore this template continue template_client = Client(self) template_client.read_xml_properties(ct) template_client.client_id = ct.attribute('client_id') if not template_client.client_id: template_client.client_id == self.generate_abstract_client_id( template_client.executable_path) template_client.update_infos_from_desktop_file() display_name = '' if ct.attribute('tp_display_name_is_label') == 'true': display_name = template_client.label template_dict = {'template_name': template_name, 'template_client': template_client, 'display_name': display_name, 'templates_root': search_path} template_names.add(template_name) templates_database.append(template_dict) # add fake templates from desktop files for fde in from_desktop_execs: if fde['skipped']: continue template_name = '/' + fde['executable'] display_name = fde['name'] template_client = Client(self) template_client.executable_path = fde['executable'] template_client.desktop_file = fde['desktop_file'] template_client.client_id = self.generate_abstract_client_id( fde['executable']) # this client has probably not been tested in RS # let it behaves as in NSM template_client.prefix_mode = ray.PrefixMode.CLIENT_NAME template_client.jack_naming = ray.JackNaming.LONG template_client.update_infos_from_desktop_file() template_dict = { 'template_name': template_name, 'template_client': template_client, 'display_name': fde['name'], 'templates_root': ''} template_names.add(template_name) templates_database.append(template_dict) if file_rewritten: try: file = open(templates_file, 'w') file.write(xml.toString()) file.close() except: sys.stderr.write( 'unable to rewrite User Client Templates XML File\n') class OperatingSession(Session): def __init__(self, root, session_id=0): Session.__init__(self, root, session_id) self.wait_for = ray.WaitFor.NONE self.timer = QTimer() self.timer_redondant = False self.expected_clients = [] self.timer_launch = QTimer() self.timer_launch.setInterval(100) self.timer_launch.timeout.connect(self._timer_launch_timeout) self.clients_to_launch = [] self.timer_quit = QTimer() self.timer_quit.setInterval(100) self.timer_quit.timeout.connect(self._timer_quit_timeout) self.clients_to_quit = [] self.timer_waituser_progress = QTimer() self.timer_waituser_progress.setInterval(500) self.timer_waituser_progress.timeout.connect( self._timer_wait_user_progress_timeOut) self.timer_wu_progress_n = 0 self.osc_src_addr = None self.osc_path = '' self.osc_args = [] self.steps_order = [] self.terminated_yet = False # externals are clients not launched from the daemon # but with NSM_URL=... self.externals_timer = QTimer() self.externals_timer.setInterval(100) self.externals_timer.timeout.connect(self._check_externals_states) self.window_waiter = QTimer() self.window_waiter.setInterval(200) self.window_waiter.timeout.connect(self._check_windows_appears) #self.window_waiter_clients = [] self.run_step_addr = None self.switching_session = False def remember_osc_args(self, path, args, src_addr): self.osc_src_addr = src_addr self.osc_path = path self.osc_args = args def _forget_osc_args(self): self.osc_src_addr = None self.osc_path = '' self.osc_args.clear() def _wait_and_go_to(self, duration: int, follow, wait_for: int, redondant=False): self.timer.stop() # we need to delete timer to change the timeout connect del self.timer self.timer = QTimer() if type(follow) in (list, tuple): if len(follow) == 0: return if len(follow) == 1: follow = follow[0] else: follow = functools.partial(follow[0], *follow[1:]) if wait_for == ray.WaitFor.SCRIPT_QUIT: if self.step_scripter.is_running(): self.wait_for = wait_for self.timer.setSingleShot(True) self.timer.timeout.connect(follow) self.timer.start(duration) else: follow() return if self.expected_clients: n_expected = len(self.expected_clients) if wait_for == ray.WaitFor.ANNOUNCE: if n_expected == 1: message = _translate('GUIMSG', 'waiting announce from %s...' % self.expected_clients[0].gui_msg_style()) else: message = _translate('GUIMSG', 'waiting announce from %i clients...' % n_expected) self.send_gui_message(message) elif wait_for == ray.WaitFor.QUIT: if n_expected == 1: message = _translate('GUIMSG', 'waiting for %s to stop...' % self.expected_clients[0].gui_msg_style()) else: message = _translate('GUIMSG', 'waiting for %i clients to stop...' % n_expected) self.timer_redondant = redondant self.wait_for = wait_for self.timer.setSingleShot(True) self.timer.timeout.connect(follow) self.timer.start(duration) else: follow() def end_timer_if_last_expected(self, client): if self.wait_for == ray.WaitFor.QUIT and client in self.clients: self._remove_client(client) if client in self.expected_clients: self.expected_clients.remove(client) if self.timer_redondant: self.timer.start() if self.timer_waituser_progress.isActive(): self.timer_wu_progress_n = 0 self.timer_waituser_progress.start() if not self.expected_clients: self.timer.setSingleShot(True) self.timer.stop() self.timer.start(0) self.timer_waituser_progress.stop() def _clean_expected(self): if self.expected_clients: client_names = [] for client in self.expected_clients: client_names.append(client.gui_msg_style()) if self.wait_for == ray.WaitFor.ANNOUNCE: self.send_gui_message( _translate('GUIMSG', "%s didn't announce.") % ', '.join(client_names)) elif self.wait_for == ray.WaitFor.QUIT: self.send_gui_message(_translate('GUIMSG', "%s still alive !") % ', '.join(client_names)) self.expected_clients.clear() self.wait_for = ray.WaitFor.NONE def next_function(self, from_run_step=False, run_step_args=[]): if self.run_step_addr and not from_run_step: self.answer(self.run_step_addr, '/ray/session/run_step', 'step done') self.run_step_addr = None return if not self.steps_order: return next_item = self.steps_order[0] next_function = next_item arguments = [] if isinstance(next_item, (tuple, list)): if not next_item: return next_function = next_item[0] if len(next_item) > 1: arguments = next_item[1:] if (self.has_server_option(ray.Option.SESSION_SCRIPTS) and not self.step_scripter.is_running() and self.path and not from_run_step): for step_string in ('load', 'save', 'close'): if next_function == self.__getattribute__(step_string): if (step_string == 'load' and arguments and arguments[0] == True): # prevent use of load session script # with open_session_off break if self.step_scripter.start(step_string, arguments, self.osc_src_addr, self.osc_path): self.set_server_status(ray.ServerStatus.SCRIPT) return break if (from_run_step and next_function and self.step_scripter.is_running()): if (next_function == self.__getattribute__( self.step_scripter.get_step())): self.step_scripter.set_stepper_has_call(True) if next_function == self.load: if 'open_off' in run_step_args: arguments = [True] elif next_function == self.close: if 'close_all' in run_step_args: arguments = [True] self.steps_order.__delitem__(0) next_function(*arguments) def _timer_launch_timeout(self): if self.clients_to_launch: self.clients_to_launch[0].start() self.clients_to_launch.__delitem__(0) if not self.clients_to_launch: self.timer_launch.stop() def _timer_quit_timeout(self): if self.clients_to_quit: client = self.clients_to_quit.pop(0) client.stop() if not self.clients_to_quit: self.timer_quit.stop() def _timer_wait_user_progress_timeOut(self): if not self.expected_clients: self.timer_waituser_progress.stop() self.timer_wu_progress_n += 1 ratio = float(self.timer_wu_progress_n / 240) self.send_gui('/ray/gui/server/progress', ratio) def _check_externals_states(self): has_externals = False for client in self.clients: if client.is_external: has_externals = True if not os.path.exists('/proc/%i' % client.pid): client.external_finished() if not has_externals: self.externals_timer.stop() def _check_windows_appears(self): for client in self.clients: if client.is_running() and client.ray_hack_waiting_win: break else: self.window_waiter.stop() return if self.has_server_option(ray.Option.HAS_WMCTRL): self.desktops_memory.set_active_window_list() for client in self.clients: if client.ray_hack_waiting_win: if self.desktops_memory.has_window(client.pid): client.ray_hack_waiting_win = False client.ray_hack_ready() def _send_reply(self, *messages): if not (self.osc_src_addr and self.osc_path): return self.send_even_dummy(self.osc_src_addr, '/reply', self.osc_path, *messages) def _send_error(self, err, error_message): #clear process order to allow other new operations self.steps_order.clear() if self.run_step_addr: self.answer(self.run_step_addr, '/ray/session/run_step', error_message, err) if not (self.osc_src_addr and self.osc_path): return self.send_even_dummy(self.osc_src_addr, "/error", self.osc_path, err, error_message) def _send_minor_error(self, err, error_message): if not (self.osc_src_addr and self.osc_path): return self.send_even_dummy(self.osc_src_addr, "/minor_error", self.osc_path, err, error_message) def step_scripter_finished(self): if self.wait_for == ray.WaitFor.SCRIPT_QUIT: self.timer.setSingleShot(True) self.timer.stop() self.timer.start(0) return if not self.step_scripter.stepper_has_called(): # script has not call # the next_function (save, close, load) if self.step_scripter.get_step() in ('load', 'close'): self.steps_order.clear() self.steps_order = [(self.close, True), self.abort_done] # Fake the next_function to come from run_step message # This way, we are sure the close step # is not runned with a script. self.next_function(True) return if self.steps_order: self.steps_order.__delitem__(0) self.next_function() def adjust_files_after_copy(self, new_session_full_name, template_mode): new_session_name = basename(new_session_full_name) spath = "%s/%s" % (self.root, new_session_full_name) if new_session_full_name.startswith('/'): spath = new_session_full_name # create tmp clients from raysession.xml to adjust files after copy session_file = "%s/%s" % (spath, "raysession.xml") try: ray_file = open(session_file, 'r') except: self._send_error(ray.Err.BAD_PROJECT, _translate("error", "impossible to read %s") % session_file) return tmp_clients = [] xml = QDomDocument() xml.setContent(ray_file.read()) content = xml.documentElement() if content.tagName() != "RAYSESSION": ray_file.close() self.load_error(ray.Err.BAD_PROJECT) return content.setAttribute('name', new_session_name) nodes = content.childNodes() for i in range(nodes.count()): node = nodes.at(i) tag_name = node.toElement().tagName() if tag_name in ('Clients', 'RemovedClients'): clients_xml = node.toElement().childNodes() for j in range(clients_xml.count()): client_xml = clients_xml.at(j) client = Client(self) cx = client_xml.toElement() client.read_xml_properties(cx) if not client.executable_path: continue tmp_clients.append(client) ray_file.close() ray_file_w = open(session_file, 'w') ray_file_w.write(xml.toString()) ray_file_w.close() for client in tmp_clients: client.adjust_files_after_copy(new_session_full_name, template_mode) ############################## COMPLEX OPERATIONS ################### # All functions are splitted when we need to wait clients # for something (announce, reply, quit). # For example, at the end of save(), timer is launched, # then, when timer is timeout or when all client replied, # save_substep1 is launched. def save(self, outing=False): if not self.path: self.next_function() return if outing: self.set_server_status(ray.ServerStatus.OUT_SAVE) else: self.set_server_status(ray.ServerStatus.SAVE) self.send_gui_message(_translate('GUIMSG', '-- Saving session %s --') % highlight_text(self.get_short_path())) for client in self.clients: if client.can_save_now(): self.expected_clients.append(client) client.save() if self.expected_clients: if len(self.expected_clients) == 1: self.send_gui_message( _translate('GUIMSG', 'waiting for %s to save...') % self.expected_clients[0].gui_msg_style()) else: self.send_gui_message( _translate('GUIMSG', 'waiting for %i clients to save...') % len(self.expected_clients)) self._wait_and_go_to(10000, (self.save_substep1, outing), ray.WaitFor.REPLY) def save_substep1(self, outing=False): self._clean_expected() if outing: for client in self.clients: if client.has_error(): self._send_error(ray.Err.GENERAL_ERROR, "Some clients could not save") break if not self.path: self.next_function() return err = self._save_session_file() if err: self.save_error(ray.Err.CREATE_FAILED) return self.canvas_saver.save_json_session_canvas(self.path) full_notes_path = "%s/%s" % (self.path, ray.NOTES_PATH) if self.notes: try: notes_file = open(full_notes_path, 'w') notes_file.write(self.notes) notes_file.close() except: self.message("unable to save notes in %s" % full_notes_path) elif os.path.isfile(full_notes_path): try: os.remove(full_notes_path) except: self.message("unable to remove %s" % full_notes_path) self.send_gui_message(_translate('GUIMSG', "Session '%s' saved.") % self.get_short_path()) self.message("Session %s saved." % self.get_short_path()) self.next_function() def save_done(self): self.message("Done.") self._send_reply("Saved.") self.set_server_status(ray.ServerStatus.READY) def save_error(self, err_saving): self.message("Failed") m = _translate('Load Error', "Unknown error") if err_saving == ray.Err.CREATE_FAILED: m = _translate( 'GUIMSG', "Can't save session, session file is unwriteable !") self.message(m) self.send_gui_message(m) self._send_error(ray.Err.CREATE_FAILED, m) self.set_server_status(ray.ServerStatus.READY) self.steps_order.clear() self._forget_osc_args() def snapshot(self, snapshot_name='', rewind_snapshot='', force=False, outing=False): if not force: if not (self.has_server_option(ray.Option.SNAPSHOTS) and not self.snapshoter.is_auto_snapshot_prevented() and self.snapshoter.has_changes()): self.next_function() return if outing: self.set_server_status(ray.ServerStatus.OUT_SNAPSHOT) else: self.set_server_status(ray.ServerStatus.SNAPSHOT) self.send_gui_message(_translate('GUIMSG', "snapshot started...")) self.snapshoter.save(snapshot_name, rewind_snapshot, self.snapshot_substep1, self.snapshot_error) def snapshot_substep1(self, aborted=False): if aborted: self.message('Snapshot aborted') self.send_gui_message(_translate('GUIMSG', 'Snapshot aborted!')) self.send_gui_message(_translate('GUIMSG', '...Snapshot finished.')) self.next_function() def snapshot_done(self): self.set_server_status(ray.ServerStatus.READY) self._send_reply("Snapshot taken.") def snapshot_error(self, err_snapshot, info_str=''): m = _translate('Snapshot Error', "Unknown error") if err_snapshot == ray.Err.SUBPROCESS_UNTERMINATED: m = _translate('Snapshot Error', "git didn't stop normally.\n%s") % info_str elif err_snapshot == ray.Err.SUBPROCESS_CRASH: m = _translate('Snapshot Error', "git crashes.\n%s") % info_str elif err_snapshot == ray.Err.SUBPROCESS_EXITCODE: m = _translate('Snapshot Error', "git exit with an error code.\n%s") % info_str self.message(m) self.send_gui_message(m) # quite dirty # minor error is not a fatal error # it's important for ray_control to not stop # if operation is not snapshot (ex: close or save) if self.next_function.__name__ == 'snapshot_done': self._send_error(err_snapshot, m) self._forget_osc_args() return self._send_minor_error(err_snapshot, m) self.next_function() def close_no_save_clients(self): self._clean_expected() if self.has_server_option(ray.Option.HAS_WMCTRL): has_nosave_clients = False for client in self.clients: if client.is_running() and client.noSaveLevel() == 2: has_nosave_clients = True break if has_nosave_clients: self.desktops_memory.set_active_window_list() for client in self.clients: if client.is_running() and client.noSaveLevel() == 2: self.expected_clients.append(client) self.desktops_memory.find_and_close(client.pid) if self.expected_clients: self.send_gui_message( _translate( 'GUIMSG', 'waiting for no saveable clients to be closed gracefully...')) duration = int(1000 * math.sqrt(len(self.expected_clients))) self._wait_and_go_to(duration, self.close_no_save_clients_substep1, ray.WaitFor.QUIT) def close_no_save_clients_substep1(self): self._clean_expected() has_nosave_clients = False for client in self.clients: if (client.is_running() and client.noSaveLevel()): self.expected_clients.append(client) has_nosave_clients = True if has_nosave_clients: self.set_server_status(ray.ServerStatus.WAIT_USER) self.timer_wu_progress_n = 0 self.timer_waituser_progress.start() self.send_gui_message(_translate('GUIMSG', 'waiting you to close yourself unsaveable clients...')) # Timer (2mn) is restarted if an expected client has been closed self._wait_and_go_to(120000, self.next_function, ray.WaitFor.QUIT, True) def close(self, clear_all_clients=False): self.expected_clients.clear() if not self.path: self.next_function() return keep_client_list = [] # clients we will keep alive byebye_client_list = [] # stopped clients we will remove immediately if not clear_all_clients: for future_client in self.future_clients: if not future_client.auto_start: continue for client in self.clients: if client in keep_client_list: continue if client.can_switch_with(future_client): client.switch_state = ray.SwitchState.RESERVED keep_client_list.append(client) break for client in self.clients: if client not in keep_client_list: # client is not capable of switch, or is not wanted # in the new session if client.is_running(): self.expected_clients.append(client) else: byebye_client_list.append(client) if keep_client_list: self.set_server_status(ray.ServerStatus.CLEAR) else: self.set_server_status(ray.ServerStatus.CLOSE) for client in byebye_client_list: if client in self.clients: self._remove_client(client) else: raise NameError('no client %s to remove' % client.client_id) if self.expected_clients: if len(self.expected_clients) == 1: self.send_gui_message( _translate('GUIMSG', 'waiting for %s to quit...') % self.expected_clients[0].gui_msg_style()) else: self.send_gui_message( _translate('GUIMSG', 'waiting for %i clients to quit...') % len(self.expected_clients)) for client in self.expected_clients.__reversed__(): self.clients_to_quit.append(client) self.timer_quit.start() self.trashed_clients.clear() self.send_gui('/ray/gui/trash/clear') self._wait_and_go_to(30000, (self.close_substep1, clear_all_clients), ray.WaitFor.QUIT) def close_substep1(self, clear_all_clients=False): for client in self.expected_clients: client.kill() self._wait_and_go_to(1000, (self.close_substep2, clear_all_clients), ray.WaitFor.QUIT) def close_substep2(self, clear_all_clients=False): self._clean_expected() # remember in recent sessions # only if session has been open at least 30 seconds # to prevent remember when session is open just for a little script if time.time() - self._time_at_open > 30: self.remember_as_recent() if clear_all_clients: self._set_path('') self.next_function() def close_done(self): self._clean_expected() self.clients.clear() self._set_path('') self.send_gui('/ray/gui/session/name', '', '') self.send_gui('/ray/gui/session/notes', '') self.send_gui('/ray/gui/session/notes_hidden') self._no_future() self._send_reply("Closed.") self.message("Done") self.set_server_status(ray.ServerStatus.OFF) self._forget_osc_args() def abort_done(self): self._clean_expected() self.clients.clear() self._set_path('') self.send_gui('/ray/gui/session/name', '', '') self.send_gui('/ray/gui/notes', '') self.send_gui('/ray/gui/session/notes_hidden') self._no_future() self._send_reply("Aborted.") self.message("Done") self.set_server_status(ray.ServerStatus.OFF) self._forget_osc_args() def new(self, new_session_name): self.send_gui_message( _translate('GUIMSG', "Creating new session \"%s\"") % new_session_name) spath = self.get_full_path(new_session_name) if self._is_path_in_a_session_dir(spath): self._send_error( ray.Err.SESSION_IN_SESSION_DIR, """Can't create session in a dir containing a session for better organization.""") return try: os.makedirs(spath) except: self._send_error(ray.Err.CREATE_FAILED, "Could not create the session directory") return self.set_server_status(ray.ServerStatus.NEW) self._set_path(spath) self.send_gui("/ray/gui/session/name", self.name, self.path) self.next_function() def new_done(self): self.send_gui_message(_translate('GUIMSG', 'Session is ready')) self._send_reply("Created.") self.set_server_status(ray.ServerStatus.READY) self._forget_osc_args() def init_snapshot(self, spath, snapshot): self.set_server_status(ray.ServerStatus.REWIND) if self.snapshoter.load(spath, snapshot, self.init_snapshot_error): self.next_function() def init_snapshot_error(self, err, info_str=''): m = _translate('Snapshot Error', "Snapshot error") if err == ray.Err.SUBPROCESS_UNTERMINATED: m = _translate('Snapshot Error', "command didn't stop normally:\n%s") % info_str elif err == ray.Err.SUBPROCESS_CRASH: m = _translate('Snapshot Error', "command crashes:\n%s") % info_str elif err == ray.Err.SUBPROCESS_EXITCODE: m = _translate('Snapshot Error', "command exit with an error code:\n%s") % info_str elif err == ray.Err.NO_SUCH_FILE: m = _translate('Snapshot Error', "error reading file:\n%s") % info_str self.message(m) self.send_gui_message(m) self._send_error(err, m) self.set_server_status(ray.ServerStatus.OFF) self.steps_order.clear() def duplicate(self, new_session_full_name): if self._clients_have_errors(): self._send_error( ray.Err.GENERAL_ERROR, _translate('error', "Some clients could not save")) return self.send_gui('/ray/gui/trash/clear') self.send_gui_message( _translate('GUIMSG', '-- Duplicating session %s to %s --') % (highlight_text(self.get_short_path()), highlight_text(new_session_full_name))) for client in self.clients: if client.protocol == ray.Protocol.RAY_NET: client.ray_net.duplicate_state = -1 if (client.ray_net.daemon_url and ray.is_valid_osc_url(client.ray_net.daemon_url)): self.send(Address(client.ray_net.daemon_url), '/ray/session/duplicate_only', self.get_short_path(), new_session_full_name, client.ray_net.session_root) self.expected_clients.append(client) if self.expected_clients: self.send_gui_message( _translate('GUIMSG', 'waiting for network daemons to start duplicate...')) self._wait_and_go_to( 2000, (self.duplicate_substep1, new_session_full_name), ray.WaitFor.DUPLICATE_START) def duplicate_substep1(self, new_session_full_name): spath = self.get_full_path(new_session_full_name) self.set_server_status(ray.ServerStatus.COPY) self.send_gui_message(_translate('GUIMSG', 'start session copy...')) # lock the directory of the new session created multi_daemon_file = MultiDaemonFile.get_instance() if multi_daemon_file: multi_daemon_file.add_locked_path(spath) self.file_copier.start_session_copy( self.path, spath, self.duplicate_substep2, self.duplicate_aborted, [new_session_full_name]) def duplicate_substep2(self, new_session_full_name): self._clean_expected() self.send_gui_message(_translate('GUIMSG', '...session copy finished.')) for client in self.clients: if (client.protocol == ray.Protocol.RAY_NET and 0 <= client.ray_net.duplicate_state < 1): self.expected_clients.append(client) if self.expected_clients: self.send_gui_message( _translate('GUIMSG', 'waiting for network daemons to finish duplicate')) self._wait_and_go_to( 3600000, #1Hour (self.duplicate_substep3, new_session_full_name), ray.WaitFor.DUPLICATE_FINISH) def duplicate_substep3(self, new_session_full_name): self.adjust_files_after_copy(new_session_full_name, ray.Template.NONE) # unlock the directory of the new session created multi_daemon_file = MultiDaemonFile.get_instance() if multi_daemon_file: multi_daemon_file.unlock_path( self.get_full_path(new_session_full_name)) self.next_function() def duplicate_aborted(self, new_session_full_name): self.steps_order.clear() # unlock the directory of the aborted session multi_daemon_file = MultiDaemonFile.get_instance() if multi_daemon_file: multi_daemon_file.unlock_path( self.get_full_path(new_session_full_name)) if self.osc_path == '/nsm/server/duplicate': # for nsm server control API compatibility # abort duplication is not possible in Non/New NSM # so, send the only known error self._send_error(ray.Err.NO_SUCH_FILE, "No such file.") if self.osc_src_addr is not None: self.send(self.osc_src_addr, '/ray/net_daemon/duplicate_state', 1) self.set_server_status(ray.ServerStatus.READY) self._forget_osc_args() def save_session_template(self, template_name: str, net=False): template_root = TemplateRoots.user_sessions if net: template_root = "%s/%s" \ % (self.root, TemplateRoots.net_session_name) spath = "%s/%s" % (template_root, template_name) #overwrite existing template if os.path.isdir(spath): if not os.access(spath, os.W_OK): self._send_error( ray.Err.GENERAL_ERROR, _translate( "error", "Impossible to save template, unwriteable file !")) self.set_server_status(ray.ServerStatus.READY) return shutil.rmtree(spath) if not os.path.exists(template_root): os.makedirs(template_root) # For network sessions, # save as template the network session only # if there is no other server on this same machine. # Else, one could erase template just created by another one. # To prevent all confusion, # all seen machines are sent to prevent an erase by looping # (a network session can contains another network session # on the machine where is the master daemon, for example). for client in self.clients: if (client.protocol == ray.Protocol.RAY_NET and client.ray_net.daemon_url): self.send(Address(client.ray_net.daemon_url), '/ray/server/save_session_template', self.get_short_path(), template_name, client.ray_net.session_root) self.set_server_status(ray.ServerStatus.COPY) self.send_gui_message( _translate('GUIMSG', 'start session copy to template...')) self.file_copier.start_session_copy( self.path, spath, self.save_session_template_substep_1, self.save_session_template_aborted, [template_name, net]) def save_session_template_substep_1(self, template_name: str, net: bool): tp_mode = ray.Template.SESSION_SAVE if net: tp_mode = ray.Template.SESSION_SAVE_NET for client in self.clients + self.trashed_clients: client.adjust_files_after_copy(template_name, tp_mode) self.message("Done") self.send_gui_message( _translate('GUIMSG', "...session saved as template named %s") % highlight_text(template_name)) self._send_reply("Saved as template.") self.set_server_status(ray.ServerStatus.READY) def save_session_template_aborted(self, template_name: str, net: bool): self.steps_order.clear() self._send_reply("Session template aborted") self.set_server_status(ray.ServerStatus.READY) def prepare_template(self, new_session_full_name, template_name, net=False): template_root = TemplateRoots.user_sessions if net: template_root = "%s/%s" \ % (self.root, TemplateRoots.net_session_name) template_path = "%s/%s" % (template_root, template_name) if template_name.startswith('///'): # we use here a factory session template template_name = template_name.replace('///', '') template_path = "%s/%s" \ % (TemplateRoots.factory_sessions, template_name) if not os.path.isdir(template_path): self._send_minor_error(ray.Err.GENERAL_ERROR, _translate("error", "No template named %s") % template_name) self.next_function() return spath = self.get_full_path(new_session_full_name) if os.path.exists(spath): self._send_error(ray.Err.CREATE_FAILED, _translate("error", "Folder\n%s\nalready exists") % spath) return if self._is_path_in_a_session_dir(spath): self._send_error( ray.Err.SESSION_IN_SESSION_DIR, _translate("error", "Can't create session in a dir containing a session" + '\n' + "for better organization.")) return if self.path: self.set_server_status(ray.ServerStatus.COPY) else: self.set_server_status(ray.ServerStatus.PRECOPY) self.send_gui_message( _translate('GUIMSG', 'start copy from template to session folder')) self.file_copier.start_session_copy( template_path, spath, self.prepare_template_substep1, self.prepare_template_aborted, [new_session_full_name]) def prepare_template_substep1(self, new_session_full_name): self.adjust_files_after_copy(new_session_full_name, ray.Template.SESSION_LOAD) self.next_function() def prepare_template_aborted(self, new_session_full_name): self.steps_order.clear() if self.path: self.set_server_status(ray.ServerStatus.READY) else: self.set_server_status(ray.ServerStatus.OFF) self._set_path('') self.send_gui('/ray/gui/session/name', '', '') def rename(self, new_session_name:str): spath = "%s/%s" % (dirname(self.path), new_session_name) if os.path.exists(spath): self._send_error( ray.Err.CREATE_FAILED, _translate('rename', "Folder %s already exists,") % new_session_name + '\n' + _translate('rename', 'Impossible to rename session.')) return try: subprocess.run(['mv', self.path, spath]) except: self._send_error( ray.Err.GENERAL_ERROR, "failed to rename session") return self._set_path(spath) self.send_gui_message( _translate('GUIMSG', 'Session directory is now: %s') % self.path) for client in self.clients + self.trashed_clients: client.adjust_files_after_copy( new_session_name, ray.Template.RENAME) self.next_function() def rename_done(self, new_session_name): self.send_gui_message( _translate('GUIMSG', 'Session %s has been renamed to %s .') % (self.name, new_session_name)) self._send_reply("Session '%s' has been renamed to '%s' ." % (self.name, new_session_name)) self._forget_osc_args() def preload(self, session_full_name, auto_create=True): # load session data in self.future* (clients, trashed_clients, # session_path, session_name) spath = self.get_full_path(session_full_name) if spath == self.path: self.load_error(ray.Err.SESSION_LOCKED) return session_ray_file = "%s/raysession.xml" % spath session_nsm_file = "%s/session.nsm" % spath if os.path.exists(spath): # session directory exists for sess_file in session_ray_file, session_nsm_file: if os.path.exists(sess_file): break else: # session directory doesn't contains session file. # Check if it contains another session file in a subfolder # and in this case, prevent to create this session for root, dirs, files in os.walk(spath): #exclude hidden files and dirs files = [f for f in files if not f.startswith('.')] dirs[:] = [d for d in dirs if not d.startswith('.')] if root == spath: continue for file in files: if file in ('raysession.xml', 'session.nsm'): # dir contains a session inside, # do not try to load it self.load_error(ray.Err.SESSION_IN_SESSION_DIR) return else: if not auto_create: self.load_error(ray.Err.NO_SUCH_FILE) return # session directory doesn't exists, # create this session. if self._is_path_in_a_session_dir(spath): # prevent to create a session in a session directory # for better user organization self.load_error(ray.Err.SESSION_IN_SESSION_DIR) return try: os.makedirs(spath) except: self.load_error(ray.Err.CREATE_FAILED) return multi_daemon_file = MultiDaemonFile.get_instance() if (multi_daemon_file and not multi_daemon_file.is_free_for_session(spath)): Terminal.warning("Session %s is used by another daemon" % spath) self.load_error(ray.Err.SESSION_LOCKED) return self.message("Attempting to open %s" % spath) # change session file only for raysession launched with NSM_URL env # Not sure that this feature is really useful. # Any cases, It's important to rename it # because we want to prevent session creation in a session folder if self.is_nsm_locked() and os.getenv('NSM_URL'): session_ray_file = "%s/raysubsession.xml" % spath is_ray_file = True try: ray_file = open(session_ray_file, 'r') except: is_ray_file = False if not is_ray_file: try: file = open(session_nsm_file, 'r') except: try: ray_file = open(session_ray_file, 'w') xml = QDomDocument() p = xml.createElement('RAYSESSION') p.setAttribute('VERSION', ray.VERSION) if self.is_nsm_locked(): name = basename(session_full_name).rpartition('.')[0] p.setAttribute('name', name) xml.appendChild(p) ray_file.write(xml.toString()) ray_file.close() ray_file = open(session_ray_file, 'r') is_ray_file = True except: self.load_error(ray.Err.CREATE_FAILED) return self._no_future() sess_name = "" if is_ray_file: xml = QDomDocument() try: xml.setContent(ray_file.read()) except: self.load_error(ray.Err.BAD_PROJECT) return content = xml.documentElement() if content.tagName() != "RAYSESSION": ray_file.close() self.load_error(ray.Err.BAD_PROJECT) return sess_name = content.attribute('name') if content.attribute('notes_shown').lower() in ('1', 'true'): self.future_notes_shown = True client_id_list = [] nodes = content.childNodes() for i in range(nodes.count()): node = nodes.at(i) tag_name = node.toElement().tagName() if tag_name in ('Clients', 'RemovedClients'): clients_xml = node.toElement().childNodes() for j in range(clients_xml.count()): client_xml = clients_xml.at(j) client = Client(self) cx = client_xml.toElement() client.read_xml_properties(cx) if not client.executable_path: continue if client.client_id in client_id_list: # prevent double same id continue if tag_name == 'Clients': self.future_clients.append(client) elif tag_name == 'RemovedClients': self.future_trashed_clients.append(client) else: continue client_id_list.append(client.client_id) elif tag_name == "Windows": if self.has_server_option(ray.Option.DESKTOPS_MEMORY): self.desktops_memory.read_xml(node.toElement()) ray_file.close() else: # prevent to load a locked NSM session if os.path.isfile(spath + '/.lock'): Terminal.warning("Session %s is locked by another process") self.load_error(ray.Err.SESSION_LOCKED) return for line in file.read().split('\n'): elements = line.split(':') if len(elements) >= 3: client = Client(self) client.name = elements[0] client.executable_path = elements[1] client.client_id = elements[2] client.prefix_mode = ray.PrefixMode.CLIENT_NAME client.auto_start = True client.jack_naming = ray.JackNaming.LONG self.future_clients.append(client) file.close() self.send_gui('/ray/gui/session/is_nsm') self.canvas_saver.load_json_session_canvas(spath) full_notes_path = "%s/%s" % (spath, ray.NOTES_PATH) if (os.path.isfile(full_notes_path) and os.access(full_notes_path, os.R_OK)): notes_file = open(full_notes_path) # limit notes characters to 65000 to prevent OSC message accidents self.future_notes = notes_file.read(65000) notes_file.close() self.future_session_path = spath self.future_session_name = sess_name self.switching_session = bool(self.path) self.next_function() def take_place(self): self._set_path(self.future_session_path, self.future_session_name) if (self.name and self.name != basename(self.path)): # session folder has been renamed # so rename session to it for client in self.future_clients + self.future_trashed_clients: client.adjust_files_after_copy(self.path, ray.Template.RENAME) self._set_path(self.future_session_path) # session has been renamed and client files have been moved # save session file is required here, else clients could not # find their files at reload (after session abort). self._save_session_file() self.send_gui("/ray/gui/session/name", self.name, self.path) self.trashed_clients.clear() self.notes = self.future_notes self.send_gui('/ray/gui/session/notes', self.notes) self.notes_shown = self.future_notes_shown if self.notes_shown: self.send_gui('/ray/gui/session/notes_shown') else: self.send_gui('/ray/gui/session/notes_hidden') self.canvas_saver.send_session_group_positions() self.load_locked = True self._time_at_open = time.time() self.next_function() def load(self, open_off=False): self._clean_expected() self.clients_to_quit.clear() # first quit unneeded clients # It has probably been done but we can't know if during the load script # some clients could have been stopped. # Because adding client is not allowed # during the load script before run_step, # we can assume all these clients are needed if they are running. # 'open_off' decided during the load script # is a good reason to stop all clients. for client in self.clients.__reversed__(): if (open_off or not client.is_running() or (client.is_reply_pending() and not client.is_dumb_client()) or client.switch_state != ray.SwitchState.RESERVED): self.clients_to_quit.append(client) self.expected_clients.append(client) else: client.switch_state = ray.SwitchState.NEEDED self.timer_quit.start() self._wait_and_go_to(5000, (self.load_substep2, open_off), ray.WaitFor.QUIT) def load_substep2(self, open_off): for client in self.expected_clients: client.kill() self._wait_and_go_to(1000, (self.load_substep3, open_off), ray.WaitFor.QUIT) def load_substep3(self, open_off): self._clean_expected() self.load_locked = False self.send_gui_message(_translate('GUIMSG', "-- Opening session %s --") % highlight_text(self.get_short_path())) for trashed_client in self.future_trashed_clients: self.trashed_clients.append(trashed_client) trashed_client.send_gui_client_properties(removed=True) self.message("Commanding smart clients to switch") has_switch = False new_client_id_list = [] # remove stopped clients rm_indexes = [] for i in range(len(self.clients)): client = self.clients[i] if not client.is_running(): rm_indexes.append(i) rm_indexes.reverse() for i in rm_indexes: self._remove_client(self.clients[i]) # Lie to the GUIs saying all clients are removed. # Clients will reappear just in a few time # It prevents GUI to have 2 clients with the same client_id # in the same time for client in self.clients: client.set_status(ray.ClientStatus.REMOVED) client.sent_to_gui = False for future_client in self.future_clients: client = None # This part needs care # we add future_clients to clients. # At this point, # running clients waiting for switch have SwitchState NEEDED # running clients already choosen for switch have SwitchState DONE # clients just added from future clients without switch # have SwitchState NONE. if future_client.auto_start: for client in self.clients: if (client.switch_state == ray.SwitchState.NEEDED and client.client_id == future_client.client_id and client.can_switch_with(future_client)): #we found the good existing client break else: for client in self.clients: if (client.switch_state == ray.SwitchState.NEEDED and client.can_switch_with(future_client)): # we found a switchable client break else: client = None if client: client.switch_state = ray.SwitchState.DONE client.client_id = future_client.client_id client.eat_attributes(future_client) has_switch = True else: if not self._add_client(future_client): continue if future_client.auto_start and not (self.is_dummy or open_off): self.clients_to_launch.append(future_client) if (not future_client.executable_path in RS.non_active_clients): self.expected_clients.append(future_client) new_client_id_list.append(future_client.client_id) for client in self.clients: if client.switch_state == ray.SwitchState.DONE: client.switch() self._re_order_clients(new_client_id_list) self.send_gui('/ray/gui/session/sort_clients', *new_client_id_list) self._no_future() if has_switch: self.set_server_status(ray.ServerStatus.SWITCH) else: self.set_server_status(ray.ServerStatus.LAUNCH) #* this part is a little tricky... the clients need some time to #* send their 'announce' messages before we can send them 'open' #* and know that a reply is pending and we should continue waiting #* until they finish. #* dumb clients will never send an 'announce message', so we need #* to give up waiting on them fairly soon. */ self.timer_launch.start() wait_time = 4000 + len(self.expected_clients) * 1000 self._wait_and_go_to(wait_time, self.load_substep4, ray.WaitFor.ANNOUNCE) def load_substep4(self): for client in self.expected_clients: if not client.executable_path in RS.non_active_clients: RS.non_active_clients.append(client.executable_path) RS.settings.setValue('daemon/non_active_list', RS.non_active_clients) self._clean_expected() self.set_server_status(ray.ServerStatus.OPEN) for client in self.clients: if client.active and client.is_reply_pending(): self.expected_clients.append(client) elif client.is_running() and client.is_dumb_client(): client.set_status(ray.ClientStatus.NOOP) if self.expected_clients: n_expected = len(self.expected_clients) if n_expected == 1: self.send_gui_message( _translate('GUIMSG', 'waiting for %s to load its project...') % self.expected_clients[0].gui_msg_style()) else: self.send_gui_message( _translate('GUIMSG', 'waiting for %s clients to load their project...') % n_expected) wait_time = 8000 + len(self.expected_clients) * 2000 for client in self.expected_clients: wait_time = int(max(2 * 1000 * client.last_open_duration, wait_time)) self._wait_and_go_to(wait_time, self.load_substep5, ray.WaitFor.REPLY) def load_substep5(self): self._clean_expected() if self.has_server_option(ray.Option.DESKTOPS_MEMORY): self.desktops_memory.replace() self.message("Telling all clients that session is loaded...") for client in self.clients: client.tell_client_session_is_loaded() self.message('Loaded') self.send_gui_message( _translate('GUIMSG', 'session %s is loaded.') % highlight_text(self.get_short_path())) self.send_gui("/ray/gui/session/name", self.name, self.path) self.switching_session = False # display optional GUIs we want to be shown now if self.has_server_option(ray.Option.GUI_STATES): for client in self.clients: if (client.is_running() and client.is_capable_of(':optional-gui:') and not client.start_gui_hidden and not client.gui_has_been_visible): client.send_to_self_address('/nsm/client/show_optional_gui') self.next_function() def load_done(self): self._send_reply("Loaded.") self.message("Done") self.set_server_status(ray.ServerStatus.READY) self._forget_osc_args() def load_error(self, err_loading): self.message("Failed") m = _translate('Load Error', "Unknown error") if err_loading == ray.Err.CREATE_FAILED: m = _translate('Load Error', "Could not create session file!") elif err_loading == ray.Err.SESSION_LOCKED: m = _translate('Load Error', "Session is locked by another process!") elif err_loading == ray.Err.NO_SUCH_FILE: m = _translate('Load Error', "The named session does not exist.") elif err_loading == ray.Err.BAD_PROJECT: m = _translate('Load Error', "Could not load session file.") elif err_loading == ray.Err.SESSION_IN_SESSION_DIR: m = _translate( 'Load Error', "Can't create session in a dir containing a session\n" + "for better organization.") self._send_error(err_loading, m) if self.path: self.set_server_status(ray.ServerStatus.READY) else: self.set_server_status(ray.ServerStatus.OFF) self.steps_order.clear() def duplicate_only_done(self): self.send(self.osc_src_addr, '/ray/net_daemon/duplicate_state', 1) self._send_reply("Duplicated only done.") self._forget_osc_args() def duplicate_done(self): self.message("Done") self._send_reply("Duplicated.") self.set_server_status(ray.ServerStatus.READY) self._forget_osc_args() def exit_now(self): self.set_server_status(ray.ServerStatus.OFF) self._set_path('') self.message("Bye Bye...") self._send_reply("Bye Bye...") self.send_gui('/ray/gui/server/disannounce') QCoreApplication.quit() def add_client_template(self, src_addr, src_path, template_name, factory=False, auto_start=True): search_paths = self._get_search_template_dirs(factory) base = 'factory' if factory else 'user' templates_database = self.get_client_templates_database(base) # if this client template is not present in the database # first, rebuild the database if template_name not in [t['template_name'] for t in templates_database]: self._rebuild_templates_database(base) for t in templates_database: if t['template_name'] == template_name: full_name_files = [] template_path = "%s/%s" % (t['templates_root'], template_name) if t['templates_root'] and os.path.isdir(template_path): for file in os.listdir(template_path): full_name_files.append( "%s/%s" % (template_path, file)) template_client = t['template_client'] client = Client(self) client.protocol = template_client.protocol client.ray_hack = template_client.ray_hack client.ray_net = template_client.ray_net client.template_origin = template_name if t['display_name']: client.template_origin = t['display_name'] client.eat_attributes(template_client) client.auto_start = auto_start client.client_id = self.generate_client_id(template_client.client_id) if not self._add_client(client): self.answer(src_addr, src_path, "Session does not accept any new client now", ray.Err.NOT_NOW) return if full_name_files: client.set_status(ray.ClientStatus.PRECOPY) self.file_copier.start_client_copy( client.client_id, full_name_files, self.path, self.add_client_template_step_1, self.add_client_template_aborted, [src_addr, src_path, client]) else: self.add_client_template_step_1(src_addr, src_path, client) return # no template found with that name for favorite in RS.favorites: if (favorite.name == template_name and favorite.factory == factory): self.send_gui('/ray/gui/favorites/removed', favorite.name, int(favorite.factory)) RS.favorites.remove(favorite) break self.send(src_addr, '/error', src_path, ray.Err.NO_SUCH_FILE, _translate('GUIMSG', "%s is not an existing template !") % highlight_text(template_name)) def add_client_template_step_1(self, src_addr, src_path, client): client.adjust_files_after_copy(self.name, ray.Template.CLIENT_LOAD) if client.auto_start: client.start() else: client.set_status(ray.ClientStatus.STOPPED) self.answer(src_addr, src_path, client.client_id) def add_client_template_aborted(self, src_addr, src_path, client): self._remove_client(client) self.send(src_addr, '/error', src_path, ray.Err.COPY_ABORTED, _translate('GUIMSG', 'Copy has been aborted !')) def close_client(self, client): self.set_server_status(ray.ServerStatus.READY) self.expected_clients.append(client) client.stop() self._wait_and_go_to(30000, (self.close_client_substep1, client), ray.WaitFor.STOP_ONE) def close_client_substep1(self, client): if client in self.expected_clients: client.kill() self._wait_and_go_to(1000, self.next_function, ray.WaitFor.STOP_ONE) def load_client_snapshot(self, client_id, snapshot): self.set_server_status(ray.ServerStatus.REWIND) if self.snapshoter.load_client_exclusive( client_id, snapshot, self.load_client_snapshot_error): self.set_server_status(ray.ServerStatus.READY) self.next_function() def load_client_snapshot_error(self, err, info_str=''): m = _translate('Snapshot Error', "Snapshot error") if err == ray.Err.SUBPROCESS_UNTERMINATED: m = _translate('Snapshot Error', "command didn't stop normally:\n%s") % info_str elif err == ray.Err.SUBPROCESS_CRASH: m = _translate('Snapshot Error', "command crashes:\n%s") % info_str elif err == ray.Err.SUBPROCESS_EXITCODE: m = _translate('Snapshot Error', "command exit with an error code:\n%s") % info_str elif err == ray.Err.NO_SUCH_FILE: m = _translate('Snapshot Error', "error reading file:\n%s") % info_str self.message(m) self.send_gui_message(m) self._send_error(err, m) self.set_server_status(ray.ServerStatus.OFF) self.steps_order.clear() def load_client_snapshot_done(self): self.send(self.osc_src_addr, '/reply', self.osc_path, 'Client snapshot loaded') def start_client(self, client): client.start() self.next_function() def terminate_step_scripter(self): if self.step_scripter.is_running(): self.step_scripter.terminate() self._wait_and_go_to(5000, self.terminate_step_scripter_substep2, ray.WaitFor.SCRIPT_QUIT) def terminate_step_scripter_substep2(self): if self.step_scripter.is_running(): self.step_scripter.kill() self._wait_and_go_to(1000, self.terminate_step_scripter_substep3, ray.WaitFor.SCRIPT_QUIT) def terminate_step_scripter_substep3(self): self.next_function() def clear_clients(self, src_addr, src_path, *client_ids): self.clients_to_quit.clear() self.expected_clients.clear() for client in self.clients: if client.client_id in client_ids or not client_ids: self.clients_to_quit.append(client) self.expected_clients.append(client) self.timer_quit.start() self._wait_and_go_to( 5000, (self.clear_clients_substep2, src_addr, src_path), ray.WaitFor.QUIT) def clear_clients_substep2(self, src_addr, src_path): for client in self.expected_clients: client.kill() self._wait_and_go_to( 1000, (self.clear_clients_substep3, src_addr, src_path), ray.WaitFor.QUIT) def clear_clients_substep3(self, src_addr, src_path): self.answer(src_addr, src_path, 'Clients cleared') def send_preview(self, src_addr, folder_sizes:list): # prevent long list of OSC sends if preview order already changed server = self.get_server_even_dummy() if server and server.session_to_preview != self.get_short_path(): return self.send_even_dummy(src_addr, '/ray/gui/preview/clear') self.send_even_dummy(src_addr, '/ray/gui/preview/notes', self.notes) for client in self.clients: self.send_even_dummy( src_addr, '/ray/gui/preview/client/update', *client.spread()) self.send_even_dummy( src_addr, '/ray/gui/preview/client/is_started', client.client_id, int(client.auto_start)) if client.protocol == ray.Protocol.RAY_HACK: self.send_even_dummy( src_addr, '/ray/gui/preview/client/ray_hack_update', client.client_id, *client.ray_hack.spread()) elif client.protocol == ray.Protocol.RAY_NET: self.send_even_dummy( src_addr, '/ray/gui/preview/client/ray_net_update', client.client_id, *client.ray_net.spread()) i = 0 for snapshot in self.snapshoter.list(): self.send_even_dummy( src_addr, '/ray/gui/preview/snapshot', snapshot) i += 1 if i == 100: # slow package send to try to prevent UDP loss # and check if preview is still wanted on this session if server and server.session_to_preview != self.get_short_path(): return time.sleep(0.010) i = 0 # re check here if preview didn't change before calculate session size if server and server.session_to_preview != self.get_short_path(): return total_size = 0 size_unreadable = False # get last modified session folder to prevent recalculate # if we already know its size modified = int(os.path.getmtime(self.path)) # check if size is already in memory for folder_size in folder_sizes: if folder_size['path'] == self.path: if folder_size['modified'] == modified: total_size = folder_size['size'] break # calculate session size if not total_size: for root, dirs, files in os.walk(self.path): # check each loop if it is still pertinent to walk if server and server.session_to_preview != self.get_short_path(): return # exclude symlinks directories from count dirs[:] = [dir for dir in dirs if not os.path.islink(os.path.join(root, dir))] for file_path in files: full_file_path = os.path.join(root, file_path) # ignore file if it is a symlink if os.path.islink(os.path.join(root, file_path)): continue file_size = 0 try: file_size = os.path.getsize(full_file_path) except: sys.stderr.write("Unable to read %s size\n" % full_file_path) size_unreadable = True break total_size += os.path.getsize(full_file_path) if size_unreadable: total_size = -1 break for folder_size in folder_sizes: if folder_size['path'] == self.path: folder_size['modified'] = modified folder_size['size'] = total_size break else: folder_sizes.append( {'path': self.path, 'modified': modified, 'size': total_size}) self.send_even_dummy( src_addr, '/ray/gui/preview/session_size', total_size) self.send_even_dummy( src_addr, '/reply', '/ray/server/get_session_preview') del self RaySession-0.12.2/src/daemon/session_signaled.py000066400000000000000000002161641417052567600216570ustar00rootroot00000000000000 import json import os import shutil import subprocess import sys import time import xdg.BaseDirectory from liblo import Address from PyQt5.QtCore import QCoreApplication, QProcess from PyQt5.QtXml import QDomDocument import ray from client import Client from multi_daemon_file import MultiDaemonFile from signaler import Signaler from daemon_tools import (Terminal, RS, dirname, is_pid_child_of, highlight_text) from session import OperatingSession _translate = QCoreApplication.translate signaler = Signaler.instance() def session_operation(func): def wrapper(*args, **kwargs): if len(args) < 4: return sess, path, osc_args, src_addr, *rest = args if sess.steps_order: sess.send(src_addr, "/error", path, ray.Err.OPERATION_PENDING, "An operation pending.") return if sess.file_copier.is_active(): if path.startswith('/nsm/server/'): sess.send(src_addr, "/error", path, ray.Err.OPERATION_PENDING, "An operation pending.") else: sess.send(src_addr, "/error", path, ray.Err.COPY_RUNNING, "ray-daemon is copying files.\n" + "Wait copy finish or abort copy,\n" + "and restart operation !\n") return sess.remember_osc_args(path, osc_args, src_addr) response = func(*args) sess.next_function() return response return wrapper def client_action(func): def wrapper(*args, **kwargs): if len(args) < 4: return sess, path, osc_args, src_addr, *rest = args client_id = osc_args.pop(0) for client in sess.clients: if client.client_id == client_id: response = func(*args, client) break else: sess.send_error_no_client(src_addr, path, client_id) return return response return wrapper # There is only one possible instance of SignaledSession # This is not the case for Session and OperatingSession. # This session receives signals from OSC server. class SignaledSession(OperatingSession): def __init__(self, root): OperatingSession.__init__(self, root) signaler.osc_recv.connect(self.osc_receive) signaler.dummy_load_and_template.connect(self.dummy_load_and_template) self.recent_sessions = RS.settings.value( 'daemon/recent_sessions', {}, type=dict) self.check_recent_sessions_existing() self.preview_dummy_session = None self.dummy_sessions = [] self._next_session_id = 1 self._folder_sizes_and_dates = [] self._cache_folder_sizes_path = \ xdg.BaseDirectory.xdg_cache_home + "/RaySession/folder_sizes.json" if os.path.isfile(self._cache_folder_sizes_path): try: self._folder_sizes_and_dates = json.load( self._cache_folder_sizes_path) except: # cache file load failed and this is really not strong pass def _get_new_dummy_session_id(self)->int: to_return = self._next_session_id self._next_session_id += 1 return to_return def _new_dummy_session(self, root:str): new_dummy = DummySession(root, self._get_new_dummy_session_id()) self.dummy_sessions.append(new_dummy) return new_dummy def save_folder_sizes_cache_file(self): cache_dir = dirname(self._cache_folder_sizes_path) if not os.path.exists(cache_dir): try: os.makedirs(cache_dir) except: # can't save cache file, this is really not strong return try: file = open(self._cache_folder_sizes_path, 'w') json.dump(self._folder_sizes_and_dates, file) file.close() except: # cache file save failed, not strong pass def osc_receive(self, path, args, types, src_addr): nsm_equivs = {"/nsm/server/add" : "/ray/session/add_executable", "/nsm/server/save": "/ray/session/save", "/nsm/server/open": "/ray/server/open_session", "/nsm/server/new" : "/ray/server/new_session", "/nsm/server/duplicate": "/ray/session/duplicate", "/nsm/server/close": "/ray/session/close", "/nsm/server/abort": "/ray/session/abort", "/nsm/server/quit" : "/ray/server/quit"} # /nsm/server/list is not used here because it doesn't # works as /ray/server/list_sessions nsm_path = nsm_equivs.get(path) func_path = nsm_path if nsm_path else path func_name = func_path.replace('/', '_') if func_name in self.__dir__(): function = self.__getattribute__(func_name) function(path, args, src_addr) def send_error_no_client(self, src_addr, path, client_id): self.send(src_addr, "/error", path, ray.Err.CREATE_FAILED, _translate('GUIMSG', "No client with this client_id:%s") % client_id) def send_error_copy_running(self, src_addr, path): self.send(src_addr, "/error", path, ray.Err.COPY_RUNNING, _translate('GUIMSG', "Impossible, copy running !")) ############## FUNCTIONS CONNECTED TO SIGNALS FROM OSC ################### def _nsm_server_announce(self, path, args, src_addr): client_name, capabilities, executable_path, major, minor, pid = args if self.wait_for == ray.WaitFor.QUIT: if path.startswith('/nsm/server/'): # Error is wrong but compatible with NSM API self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "Sorry, but there's no session open " + "for this application to join.") return # we can't be absolutely sure that the announcer is the good one # but if client announce a known PID, # we can be sure of which client is announcing for client in self.clients: if client.pid == pid and not client.active and client.is_running(): client.server_announce(path, args, src_addr, False) break else: for client in self.clients: if (not client.active and client.is_running() and is_pid_child_of(pid, client.pid)): client.server_announce(path, args, src_addr, False) break else: # Client launched externally from daemon # by command : $:NSM_URL=url executable client = self._new_client(executable_path) self.externals_timer.start() self.send_monitor_event('joined', client.client_id) client.server_announce(path, args, src_addr, True) #n = 0 #for client in self.clients: #if (os.path.basename(client.executable_path) \ #== os.path.basename(executable_path) #and not client.active #and client.pending_command == ray.Command.START): #n+=1 #if n>1: #break #if n == 0: ## Client launched externally from daemon ## by command : $:NSM_URL=url executable #client = self._new_client(args[2]) #client.is_external = True #self.externals_timer.start() #client.server_announce(path, args, src_addr, True) #return #elif n == 1: #for client in self.clients: #if (os.path.basename(client.executable_path) \ #== os.path.basename(executable_path) #and not client.active #and client.pending_command == ray.Command.START): #client.server_announce(path, args, src_addr, False) #break #else: #for client in self.clients: #if (not client.active #and client.pending_command == ray.Command.START): #if is_pid_child_of(pid, client.pid): #client.server_announce(path, args, #src_addr, False) #break if self.wait_for == ray.WaitFor.ANNOUNCE: self.end_timer_if_last_expected(client) def _reply(self, path, args, src_addr): if self.wait_for == ray.WaitFor.QUIT: return message = args[1] client = self.get_client_by_address(src_addr) if client: client.set_reply(ray.Err.OK, message) server = self.get_server() if (server is not None and server.server_status == ray.ServerStatus.READY and server.options & ray.Option.DESKTOPS_MEMORY): self.desktops_memory.replace() else: self.message("Reply from unknown client") def _error(self, path, args, src_addr): path, errcode, message = args client = self.get_client_by_address(src_addr) if client: client.set_reply(errcode, message) if self.wait_for == ray.WaitFor.REPLY: self.end_timer_if_last_expected(client) else: self.message("error from unknown client") def _nsm_client_label(self, path, args, src_addr): client = self.get_client_by_address(src_addr) if client: client.set_label(args[0]) def _nsm_client_network_properties(self, path, args, src_addr): client = self.get_client_by_address(src_addr) if client: net_daemon_url, net_session_root = args client.set_network_properties(net_daemon_url, net_session_root) def _nsm_client_no_save_level(self, path, args, src_addr): client = self.get_client_by_address(src_addr) if client and client.is_capable_of(':warning-no-save:'): client.no_save_level = args[0] self.send_gui('/ray/gui/client/no_save_level', client.client_id, client.no_save_level) def _ray_server_ask_for_patchbay(self, path, args, src_addr): # if we are here, this means we need a patchbay to osc to run server = self.get_server() if server is None: return QProcess.startDetached('ray-jackpatch_to_osc', [str(server.port), src_addr.url]) def _ray_server_abort_copy(self, path, args, src_addr): self.file_copier.abort() def _ray_server_abort_parrallel_copy(self, path, args, src_addr): session_id = args[0] for dummy_session in self.dummy_sessions: if dummy_session.session_id == session_id: dummy_session.file_copier.abort() break self.send(src_addr, '/reply', path, 'Parrallel copy aborted') def _ray_server_abort_snapshot(self, path, args, src_addr): self.snapshoter.abort() def _ray_server_change_root(self, path, args, src_addr): session_root = args[0] if self.path: self.send(src_addr, '/error', path, ray.Err.SESSION_LOCKED, "impossible to change root. session %s is loaded" % self.path) return if not os.path.exists(session_root): try: os.makedirs(session_root) except: self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, "invalid session root !") return if not os.access(session_root, os.W_OK): self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, "unwriteable session root !") return self.root = session_root multi_daemon_file = MultiDaemonFile.get_instance() if multi_daemon_file: multi_daemon_file.update() self.send(src_addr, '/reply', path, "root folder changed to %s" % self.root) self.send_gui('/ray/gui/server/root', self.root) if self.root not in self.recent_sessions.keys(): self.recent_sessions[self.root] = [] self.send_gui('/ray/gui/server/recent_sessions', *self.recent_sessions[self.root]) def _ray_server_list_client_templates(self, path, args, src_addr): def send_gui_template_update(template_dict: dict): template_name = template_dict['template_name'] template_client = template_dict['template_client'] display_name = template_dict['display_name'] self.send_gui( '/ray/gui/client_template_update', int(factory), template_name, display_name, *template_client.spread()) if template_client.protocol == ray.Protocol.RAY_HACK: self.send_gui( '/ray/gui/client_template_ray_hack_update', int(factory), template_name, *template_client.ray_hack.spread()) elif template_client.protocol == ray.Protocol.RAY_NET: self.send_gui( '/ray/gui/client_template_ray_net_update', int(factory), template_name, *template_client.ray_net.spread()) # if src_addr is an announced ray GUI # server will send it all templates properties # else, server replies only templates names src_addr_is_gui = False server = self.get_server() if server is not None: src_addr_is_gui = server.is_gui_address(src_addr) template_names = set() filters = args factory = bool('factory' in path) base = 'factory' if factory else 'user' templates_database = self.get_client_templates_database(base) if not templates_database: self._rebuild_templates_database(base) templates_database = self.get_client_templates_database(base) for t in templates_database: if filters: skipped_by_filter = False message = t['template_client'].get_properties_message() for filt in filters: for line in message.splitlines(): if line == filt: break else: skipped_by_filter = True break if skipped_by_filter: continue template_names.add(t['template_name']) self.send(src_addr, '/reply', path, *template_names) if src_addr_is_gui: for template_dict in templates_database: template_name = template_dict['template_name'] template_client = template_dict['template_client'] display_name = template_dict['display_name'] self.send_gui( '/ray/gui/client_template_update', int(factory), template_name, display_name, *template_client.spread()) if template_client.protocol == ray.Protocol.RAY_HACK: self.send_gui( '/ray/gui/client_template_ray_hack_update', int(factory), template_name, *template_client.ray_hack.spread()) elif template_client.protocol == ray.Protocol.RAY_NET: self.send_gui( '/ray/gui/client_template_ray_net_update', int(factory), template_name, *template_client.ray_net.spread()) self.send(src_addr, '/reply', path) def _ray_server_list_factory_client_templates(self, path, args, src_addr): self._ray_server_list_client_templates(path, args, src_addr) def _ray_server_list_user_client_templates(self, path, args, src_addr): self._ray_server_list_client_templates(path, args, src_addr) def _ray_server_list_sessions(self, path, args, src_addr): with_net = False last_sent_time = time.time() if args: with_net = args[0] if with_net: for client in self.clients: if (client.protocol == ray.Protocol.RAY_NET and client.ray_net.daemon_url): self.send(Address(client.ray_net.daemon_url), '/ray/server/list_sessions', 1) if not self.root: self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, "no session root, so no sessions to list") return session_list = [] sessions_set = set() n = 0 for root, dirs, files in os.walk(self.root): #exclude hidden files and dirs files = [f for f in files if not f.startswith('.')] dirs[:] = [d for d in dirs if not d.startswith('.')] if root == self.root: continue for file in files: if file in ('raysession.xml', 'session.nsm'): # prevent search in sub directories dirs.clear() basefolder = root.replace(self.root + '/', '', 1) session_list.append(basefolder) sessions_set.add(basefolder) n += len(basefolder) if n >= 10000 or time.time() - last_sent_time > 0.300: last_sent_time = time.time() self.send(src_addr, "/reply", path, *session_list) session_list.clear() n = 0 break if session_list: self.send(src_addr, "/reply", path, *session_list) self.send(src_addr, "/reply", path) search_scripts_dir = self.root has_general_scripts = False while search_scripts_dir and not search_scripts_dir != '/': if os.path.isdir(search_scripts_dir + '/' + ray.SCRIPTS_DIR): has_general_scripts = True break search_scripts_dir = dirname(search_scripts_dir) locked_sessions = [] multi_daemon_file = MultiDaemonFile.get_instance() if multi_daemon_file is not None: locked_sessions = multi_daemon_file.get_all_session_paths() for root, dirs, files in os.walk(self.root): #exclude hidden files and dirs files = [f for f in files if not f.startswith('.')] dirs[:] = [d for d in dirs if not d.startswith('.')] if root == self.root: if has_general_scripts: self.send(src_addr, '/ray/gui/listed_session/scripted_dir', '', ray.ScriptFile.PARENT) continue basefolder = root.replace(self.root + '/', '', 1) if ray.SCRIPTS_DIR in dirs: script_files = ray.ScriptFile.PREVENT for action in ('load', 'save', 'close'): if os.access( "%s/%s/%s.sh" % (root, ray.SCRIPTS_DIR, action), os.X_OK): script_files += ray.ScriptFile.by_string(action) self.send(src_addr, '/ray/gui/listed_session/scripted_dir', basefolder, script_files) if basefolder not in sessions_set: continue has_notes = bool(ray.NOTES_PATH in files) last_modified = int(os.path.getmtime(root)) locked = bool(root in locked_sessions) self.send(src_addr, '/ray/gui/listed_session/details', basefolder, int(has_notes), last_modified, int(locked)) # prevent search in sub directories dirs.clear() def _nsm_server_list(self, path, args, src_addr): if self.root: for root, dirs, files in os.walk(self.root): #exclude hidden files and dirs files = [f for f in files if not f.startswith('.')] dirs[:] = [d for d in dirs if not d.startswith('.')] if root == self.root: continue for file in files: if file in ('raysession.xml', 'session.nsm'): basefolder = root.replace(self.root + '/', '', 1) self.send(src_addr, '/reply', path, basefolder) self.send(src_addr, '/reply', path, "") @session_operation def _ray_server_new_session(self, path, args, src_addr): if len(args) == 2 and args[1]: session_name, template_name = args spath = '' if session_name.startswith('/'): spath = session_name else: spath = "%s/%s" % (self.root, session_name) if not os.path.exists(spath): self.steps_order = [self.save, self.close_no_save_clients, self.snapshot, (self.prepare_template, *args, False), (self.preload, session_name), self.close, self.take_place, self.load, self.new_done] return self.steps_order = [self.save, self.close_no_save_clients, self.snapshot, self.close, (self.new, args[0]), self.save, self.new_done] @session_operation def _ray_server_open_session(self, path, args, src_addr, open_off=False): session_name = args[0] save_previous = True template_name = '' if len(args) >= 2: save_previous = bool(args[1]) if len(args) >= 3: template_name = args[2] if (not session_name or '//' in session_name or session_name.startswith(('../', '.ray-', 'ray-'))): self._send_error(ray.Err.CREATE_FAILED, 'invalid session name.') return if template_name: if '/' in template_name: self._send_error(ray.Err.CREATE_FAILED, 'invalid template name') return spath = '' if session_name.startswith('/'): spath = session_name else: spath = "%s/%s" % (self.root, session_name) if spath == self.path: self._send_error(ray.Err.SESSION_LOCKED, _translate('GUIMSG', 'session %s is already opened !') % highlight_text(session_name)) return multi_daemon_file = MultiDaemonFile.get_instance() if (multi_daemon_file and not multi_daemon_file.is_free_for_session(spath)): Terminal.warning("Session %s is used by another daemon" % highlight_text(spath)) self._send_error(ray.Err.SESSION_LOCKED, _translate('GUIMSG', 'session %s is already used by another daemon !') % highlight_text(session_name)) return # don't use template if session folder already exists if os.path.exists(spath): template_name = '' self.steps_order = [] if save_previous: self.steps_order += [(self.save, True)] self.steps_order += [self.close_no_save_clients] if save_previous: self.steps_order += [(self.snapshot, '', '', False, True)] if template_name: self.steps_order += [(self.prepare_template, session_name, template_name, True)] self.steps_order += [(self.preload, session_name), (self.close, open_off), self.take_place, (self.load, open_off), self.load_done] def _ray_server_open_session_off(self, path, args, src_addr): self._ray_server_open_session(path, args, src_addr, open_off=True) def _ray_server_rename_session(self, path, args, src_addr): old_session_name, new_session_name = args spath = self.get_full_path(old_session_name) for f in 'raysession.xml', 'session.nsm': if os.path.isfile("%s/%s" % (spath, f)): break else: self.send(src_addr, '/error', path, ray.Err.BAD_PROJECT, "%s is not an existing session, can't rename !" % old_session_name) if '/' in new_session_name: self.send(src_addr, '/error', path, ray.Err.BAD_PROJECT, "'/' is not allowed in new_session_name") return False tmp_session = self._new_dummy_session(self.root) tmp_session.ray_server_rename_session(path, args, src_addr) def _ray_server_save_session_template(self, path, args, src_addr): if len(args) == 2: session_name, template_name = args sess_root = self.root net = False else: session_name, template_name, sess_root = args net = True if (sess_root != self.root or session_name != self.get_short_path()): tmp_session = self._new_dummy_session(sess_root) tmp_session.ray_server_save_session_template( path, [session_name, template_name, net], src_addr) return self._ray_session_save_as_template( path, [template_name, net], src_addr) def _ray_server_get_session_preview(self, path, args, src_addr): session_name = args[0] server = self.get_server() if server is None: return if server.session_to_preview != session_name: # prevent to open a dummy session # in case user change preview so fastly # that this thread is late and user already # changed the session to preview return del self.preview_dummy_session self.preview_dummy_session = DummySession(self.root) self.preview_dummy_session.ray_server_get_session_preview( path, args, src_addr, self._folder_sizes_and_dates) def _ray_server_set_option(self, path, args, src_addr): option = args[0] if abs(option) == ray.Option.BOOKMARK_SESSION: if self.path: if option > 0: self.bookmarker.make_all(self.path) else: self.bookmarker.remove_all(self.path) def _ray_server_patchbay_save_group_position(self, path, args, src_addr): self.canvas_saver.save_group_position(*args) def _ray_server_patchbay_save_portgroup(self, path, args, src_addr): self.canvas_saver.save_portgroup(*args) @session_operation def _ray_session_save(self, path, args, src_addr): self.steps_order = [self.save, self.snapshot, self.save_done] @session_operation def _ray_session_save_as_template(self, path, args, src_addr): template_name = args[0] net = False if len(args) < 2 else args[1] for client in self.clients: if client.protocol == ray.Protocol.RAY_NET: client.ray_net.session_template = template_name self.steps_order = [self.save, self.snapshot, (self.save_session_template, template_name, net)] @session_operation def _ray_session_take_snapshot(self, path, args, src_addr): if not self.path: self.send(src_addr, '/error', path, ray.Err.NO_SESSION_OPEN, 'No session is loaded, impossible to take snapshot') return snapshot_name = '' with_save = 0 if len(args) == 2: snapshot_name, with_save = args else: snapshot_name = args[0] self.steps_order.clear() if with_save: self.steps_order.append(self.save) self.steps_order += [(self.snapshot, snapshot_name, '', True), self.snapshot_done] @session_operation def _ray_session_close(self, path, args, src_addr): self.steps_order = [(self.save, True), self.close_no_save_clients, self.snapshot, (self.close, True), self.close_done] def _ray_session_abort(self, path, args, src_addr): if not self.path: self.file_copier.abort() self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "No session to abort.") return self.wait_for = ray.WaitFor.NONE self.timer.stop() # Non Session Manager can't abort if an operation pending # RS can and it would be a big regression to remove this feature # So before to abort we need to send an error reply # to the last server control message # if an operation pending. if self.steps_order: if self.osc_path.startswith('/nsm/server/'): short_path = self.osc_path.rpartition('/')[2] if short_path == 'save': self.save_error(ray.Err.CREATE_FAILED) elif short_path == 'open': self.load_error(ray.Err.SESSION_LOCKED) elif short_path == 'new': self._send_error(ray.Err.CREATE_FAILED, "Could not create the session directory") elif short_path == 'duplicate': self.duplicate_aborted(self.osc_args[0]) elif short_path in ('close', 'abort', 'quit'): # let the current close works here self.send(src_addr, "/error", path, ray.Err.OPERATION_PENDING, "An operation pending.") return else: self._send_error(ray.Err.ABORT_ORDERED, _translate('GUIMSG', 'abort ordered from elsewhere, sorry !')) self.remember_osc_args(path, args, src_addr) self.steps_order = [(self.close, True), self.abort_done] if self.file_copier.is_active(): self.file_copier.abort(self.next_function, []) else: self.next_function() def _ray_server_quit(self, path, args, src_addr): self.remember_osc_args(path, args, src_addr) self.steps_order = [self.terminate_step_scripter, self.close, self.exit_now] if self.file_copier.is_active(): self.file_copier.abort(self.next_function, []) else: self.next_function() def _ray_session_cancel_close(self, path, args, src_addr): if not self.steps_order: return self.timer.stop() self.timer_waituser_progress.stop() self.steps_order.clear() self._clean_expected() self.set_server_status(ray.ServerStatus.READY) def _ray_session_skip_wait_user(self, path, args, src_addr): if not self.steps_order: return self.timer.stop() self.timer_waituser_progress.stop() self._clean_expected() self.next_function() @session_operation def _ray_session_duplicate(self, path, args, src_addr): new_session_full_name = args[0] spath = '' if new_session_full_name.startswith('/'): spath = new_session_full_name else: spath = "%s/%s" % (self.root, new_session_full_name) if os.path.exists(spath): self._send_error(ray.Err.CREATE_FAILED, _translate('GUIMSG', "%s already exists !") % highlight_text(spath)) return multi_daemon_file = MultiDaemonFile.get_instance() if (multi_daemon_file and not multi_daemon_file.is_free_for_session(spath)): Terminal.warning("Session %s is used by another daemon" % highlight_text(new_session_full_name)) self._send_error(ray.Err.SESSION_LOCKED, _translate('GUIMSG', 'session %s is already used by this or another daemon !') % highlight_text(new_session_full_name)) return self.steps_order = [self.save, self.close_no_save_clients, self.snapshot, (self.duplicate, new_session_full_name), (self.preload, new_session_full_name), self.close, self.take_place, self.load, self.duplicate_done] def _ray_session_duplicate_only(self, path, args, src_addr): session_to_load, new_session, sess_root = args spath = '' if new_session.startswith('/'): spath = new_session else: spath = "%s/%s" % (sess_root, new_session) if os.path.exists(spath): self.send(src_addr, '/ray/net_daemon/duplicate_state', 1) self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, _translate('GUIMSG', "%s already exists !") % highlight_text(spath)) return if sess_root == self.root and session_to_load == self.get_short_path(): if (self.steps_order or self.file_copier.is_active()): self.send(src_addr, '/ray/net_daemon/duplicate_state', 1) return self.remember_osc_args(path, args, src_addr) self.steps_order = [self.save, self.snapshot, (self.duplicate, new_session), self.duplicate_only_done] self.next_function() else: tmp_session = self._new_dummy_session(sess_root) tmp_session.osc_src_addr = src_addr tmp_session.dummy_duplicate(path, args, src_addr) @session_operation def _ray_session_open_snapshot(self, path, args, src_addr): if not self.path: return snapshot = args[0] self.steps_order = [self.save, self.close_no_save_clients, (self.snapshot, '', snapshot, True), (self.close, True), (self.init_snapshot, self.path, snapshot), (self.preload, self.path), self.take_place, self.load, self.load_done] def _ray_session_rename(self, path, args, src_addr): new_session_name = args[0] if self.steps_order: return if not self.path: return if self.file_copier.is_active(): return if new_session_name == self.name: return if not self.is_nsm_locked(): for filename in os.listdir(dirname(self.path)): if filename == new_session_name: # another directory exists with new session name return for client in self.clients: if client.is_running(): self.send_gui_message( _translate('GUIMSG', 'Stop all clients before rename session !')) return for client in self.clients + self.trashed_clients: client.adjust_files_after_copy(new_session_name, ray.Template.RENAME) if not self.is_nsm_locked(): try: spath = "%s/%s" % (dirname(self.path), new_session_name) subprocess.run(['mv', self.path, spath]) self._set_path(spath) self.send_gui_message( _translate('GUIMSG', 'Session directory is now: %s') % self.path) except: pass # we need to save the session file here # because session just has been renamed # and clients dependant of the session name # would not find there files if session is aborted just after self._save_session_file() self.send_gui_message( _translate('GUIMSG', 'Session %s has been renamed to %s .') % (self.name, new_session_name)) self.send_gui('/ray/gui/session/name', self.name, self.path) def _ray_session_set_notes(self, path, args, src_addr): self.notes = args[0] self.send(src_addr, '/reply', path, 'Notes has been set') def _ray_session_get_notes(self, path, args, src_addr): self.send(src_addr, '/reply', path, self.notes) self.send(src_addr, '/reply', path) def _ray_session_add_executable(self, path, args, src_addr): protocol = ray.Protocol.NSM executable = args[0] via_proxy = 0 prefix_mode = ray.PrefixMode.SESSION_NAME custom_prefix = '' client_id = "" start_it = 1 jack_naming = 0 if len(args) == 1: pass elif ray.are_they_all_strings(args): via_proxy = int(bool('via_proxy' in args[1:])) start_it = int(bool('not_start' not in args[1:])) if 'ray_hack' in args[1:]: protocol = ray.Protocol.RAY_HACK for arg in args[1:]: if arg == 'prefix_mode:client_name': prefix_mode = ray.PrefixMode.CLIENT_NAME elif arg == 'prefix_mode:session_name': prefix_mode = ray.PrefixMode.SESSION_NAME elif arg.startswith('prefix:'): custom_prefix = arg.partition(':')[2] if not custom_prefix or '/' in custom_prefix: self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, "wrong custom prefix !") return prefix_mode = ray.PrefixMode.CUSTOM elif arg.startswith('client_id:'): client_id = arg.partition(':')[2] if not client_id.replace('_', '').isalnum(): self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, "client_id %s is not alphanumeric") return # Check if client_id already exists for client in self.clients + self.trashed_clients: if client.client_id == client_id: self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, "client_id %s is already used" % client_id) return elif arg.startswith('jack_naming:'): str_jack_naming = arg.partition(':')[2] if str_jack_naming.lower() in ('1', 'long'): jack_naming = 1 else: executable, start_it, protocol, \ prefix_mode, custom_prefix, client_id, jack_naming = args if prefix_mode == ray.PrefixMode.CUSTOM and not custom_prefix: prefix_mode = ray.PrefixMode.SESSION_NAME if client_id: if not client_id.replace('_', '').isalnum(): self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, _translate("error", "client_id %s is not alphanumeric") % client_id) return # Check if client_id already exists for client in self.clients + self.trashed_clients: if client.client_id == client_id: self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, _translate("error", "client_id %s is already used") % client_id) return if not client_id: client_id = self.generate_client_id(executable) client = Client(self) client.protocol = protocol if client.protocol == ray.Protocol.NSM and via_proxy: client.executable_path = 'ray-proxy' else: client.executable_path = executable client.name = os.path.basename(executable) client.client_id = client_id client.prefix_mode = prefix_mode client.custom_prefix = custom_prefix client.set_default_git_ignored(executable) client.jack_naming = jack_naming if self._add_client(client): if start_it: client.start() reply_str = client.client_id if path.startswith('/nsm/server/'): reply_str = "Launched." self.send(src_addr, '/reply', path, reply_str) else: self.send(src_addr, '/error', path, ray.Err.NOT_NOW, "Impossible to add client now") def _ray_session_add_client_template(self, path, args, src_addr): if not self.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "Cannot add to session because no session is loaded.") return factory = bool(args[0]) template_name = args[1] auto_start = bool(len(args) <= 2 or args[2] != 'not_start') self.add_client_template(src_addr, path, template_name, factory, auto_start) def _ray_session_add_factory_client_template(self, path, args, src_addr): self._ray_session_add_client_template(path, [1] + args, src_addr) def _ray_session_add_user_client_template(self, path, args, src_addr): self._ray_session_add_client_template(path, [0] + args, src_addr) @session_operation def _ray_session_add_other_session_client(self, path, args, src_addr): other_session, client_id = args # @session_operation remember them but this is not needed here self._forget_osc_args() dummy_session = DummySession(self.root) dummy_session.dummy_load(other_session) # hopefully for a dummy session, # there is nothing to wait to have a loaded session # This is quite dirty but so easier if not dummy_session.path: self.send(src_addr, '/error', path, ray.Err.NOT_NOW, "falied to load other session %s" % other_session) return for client in dummy_session.clients: if client.client_id == client_id: new_client = Client(self) new_client.client_id = self.generate_client_id( Client.short_client_id(client_id)) ok = self._add_client(new_client) if not ok: self.send(src_addr, '/error', path, ray.Err.NOT_NOW, 'session is busy') return new_client.eat_other_session_client(src_addr, path, client) break else: self.send(src_addr, '/error', path, ray.Err.NO_SUCH_FILE, 'no client %s found in session %s' % (client_id, other_session)) def _ray_session_reorder_clients(self, path, args, src_addr): client_ids_list = args if not self.path: self.send(src_addr, '/error', path, ray.Err.NO_SESSION_OPEN, "no session to reorder clients") if len(self.clients) < 2: self.send(src_addr, '/reply', path, "clients reordered") return self._re_order_clients(client_ids_list, src_addr, path) def _ray_session_clear_clients(self, path, args, src_addr): if not self.load_locked: self.send(src_addr, '/error', path, ray.Err.NOT_NOW, "clear_clients has to be used only during the load script !") return self.clear_clients(src_addr, path, *args) def _ray_session_list_snapshots(self, path, args, src_addr, client_id=""): if not self.path: self.send(src_addr, '/error', path, ray.Err.NO_SESSION_OPEN, "no session to list snapshots") return auto_snapshot = not self.snapshoter.is_auto_snapshot_prevented() self.send_gui('/ray/gui/session/auto_snapshot', int(auto_snapshot)) snapshots = self.snapshoter.list(client_id) i = 0 snap_send = [] for snapshot in snapshots: if i == 20: self.send(src_addr, '/reply', path, *snap_send) snap_send.clear() i = 0 else: snap_send.append(snapshot) i += 1 if snap_send: self.send(src_addr, '/reply', path, *snap_send) self.send(src_addr, '/reply', path) def _ray_session_set_auto_snapshot(self, path, args, src_addr): self.snapshoter.set_auto_snapshot(bool(args[0])) def _ray_session_list_clients(self, path, args, src_addr): if not self.path: self.send(src_addr, '/error', path, ray.Err.NO_SESSION_OPEN, _translate('GUIMSG', 'No session to list clients !')) return f_started = -1 f_active = -1 f_auto_start = -1 f_no_save_level = -1 search_properties = [] for arg in args: cape = 1 if arg.startswith('not_'): cape = 0 arg = arg.replace('not_', '', 1) if ':' in arg: search_properties.append((cape, arg)) elif arg == 'started': f_started = cape elif arg == 'active': f_active = cape elif arg == 'auto_start': f_auto_start = cape elif arg == 'no_save_level': f_no_save_level = cape client_id_list = [] for client in self.clients: if ((f_started < 0 or f_started == client.is_running()) and (f_active < 0 or f_active == client.active) and (f_auto_start < 0 or f_auto_start == client.auto_start) and (f_no_save_level < 0 or f_no_save_level == int(bool(client.noSaveLevel())))): if search_properties: message = client.get_properties_message() for cape, search_prop in search_properties: line_found = False for line in message.split('\n'): if line == search_prop: line_found = True break if cape != line_found: break else: client_id_list.append(client.client_id) else: client_id_list.append(client.client_id) if client_id_list: self.send(src_addr, '/reply', path, *client_id_list) self.send(src_addr, '/reply', path) def _ray_session_list_trashed_clients(self, path, args, src_addr): client_id_list = [] for trashed_client in self.trashed_clients: client_id_list.append(trashed_client.client_id) if client_id_list: self.send(src_addr, '/reply', path, *client_id_list) self.send(src_addr, '/reply', path) def _ray_session_run_step(self, path, args, src_addr): if not self.step_scripter.is_running(): self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, 'No stepper script running, run run_step from session scripts') return if self.step_scripter.stepper_has_called(): self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, 'step already done. Run run_step only one time in the script') return if not self.steps_order: self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, 'No operation pending !') return self.run_step_addr = src_addr self.next_function(True, args) @client_action def _ray_client_stop(self, path, args, src_addr, client:Client): client.stop(src_addr, path) @client_action def _ray_client_kill(self, path, args, src_addr, client:Client): client.kill() self.send(src_addr, "/reply", path, "Client killed.") @client_action def _ray_client_trash(self, path, args, src_addr, client:Client): if client.is_running(): self.send(src_addr, '/error', path, ray.Err.OPERATION_PENDING, "Stop client before to trash it !") return if self.file_copier.is_active(client.client_id): self.file_copier.abort() self.send(src_addr, '/error', path, ray.Err.COPY_RUNNING, "Files were copying for this client.") return self._trash_client(client) self.send(src_addr, "/reply", path, "Client removed.") def _ray_client_start(self, path, args, src_addr): self._ray_client_resume(path, args, src_addr) @client_action def _ray_client_resume(self, path, args, src_addr, client:Client): if client.is_running(): self.send_gui_message( _translate('GUIMSG', 'client %s is already running.') % client.gui_msg_style()) # make ray_control exit code 0 in this case self.send(src_addr, '/reply', path, 'client running') return if self.file_copier.is_active(client.client_id): self.send_error_copy_running(src_addr, path) return client.start(src_addr, path) @client_action def _ray_client_open(self, path, args, src_addr, client:Client): if self.file_copier.is_active(client.client_id): self.send_error_copy_running(src_addr, path) return if client.active: self.send_gui_message( _translate('GUIMSG', 'client %s is already active.') % client.gui_msg_style()) # make ray_control exit code 0 in this case self.send(src_addr, '/reply', path, 'client active') else: client.load(src_addr, path) @client_action def _ray_client_save(self, path, args, src_addr, client:Client): if client.can_save_now(): if self.file_copier.is_active(client.client_id): self.send_error_copy_running(src_addr, path) return client.save(src_addr, path) else: self.send_gui_message(_translate('GUIMSG', "%s is not saveable.") % client.gui_msg_style()) self.send(src_addr, '/reply', path, 'client saved') @client_action def _ray_client_save_as_template(self, path, args, src_addr, client:Client): template_name = args[0] if self.file_copier.is_active(): self.send_error_copy_running(src_addr, path) return client.save_as_template(template_name, src_addr, path) @client_action def _ray_client_show_optional_gui(self, path, args, src_addr, client:Client): client.send_to_self_address("/nsm/client/show_optional_gui") client.show_gui_ordered = True self.send(src_addr, '/reply', path, 'show optional GUI asked') @client_action def _ray_client_hide_optional_gui(self, path, args, src_addr, client:Client): client.send_to_self_address("/nsm/client/hide_optional_gui") self.send(src_addr, '/reply', path, 'hide optional GUI asked') @client_action def _ray_client_update_properties(self, path, args, src_addr, client:Client): client.update_secure(client.client_id, *args) client.send_gui_client_properties() self.send(src_addr, '/reply', path, 'client properties updated') @client_action def _ray_client_update_ray_hack_properties(self, path, args, src_addr, client:Client): ex_no_save_level = client.noSaveLevel() if client.is_ray_hack(): client.ray_hack.update(*args) no_save_level = client.noSaveLevel() if no_save_level != ex_no_save_level: self.send_gui('/ray/gui/client/no_save_level', client.client_id, no_save_level) self.send(src_addr, '/reply', path, 'ray_hack updated') @client_action def _ray_client_update_ray_net_properties(self, path, args, src_addr, client:Client): if client.protocol == ray.Protocol.RAY_NET: client.ray_net.update(*args) self.send(src_addr, '/reply', path, 'ray_net updated') @client_action def _ray_client_set_properties(self, path, args, src_addr, client:Client): message = '' for arg in args: message += "%s\n" % arg client.set_properties_from_message(message) self.send(src_addr, '/reply', path, 'client properties updated') @client_action def _ray_client_get_properties(self, path, args, src_addr, client:Client): message = client.get_properties_message() self.send(src_addr, '/reply', path, message) self.send(src_addr, '/reply', path) @client_action def _ray_client_get_proxy_properties(self, path, args, src_addr, client:Client): proxy_file = '%s/ray-proxy.xml' % client.get_project_path() if not os.path.isfile(proxy_file): self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s seems to not be a proxy client !') % client.gui_msg_style()) return try: file = open(proxy_file, 'r') xml = QDomDocument() xml.setContent(file.read()) content = xml.documentElement() file.close() except: self.send(src_addr, '/error', path, ray.Err.BAD_PROJECT, _translate('GUIMSG', "impossible to read %s correctly !") % proxy_file) return if content.tagName() != "RAY-PROXY": self.send(src_addr, '/error', path, ray.Err.BAD_PROJECT, _translate('GUIMSG', "impossible to read %s correctly !") % proxy_file) return cte = content.toElement() message = "" for prop in ('executable', 'arguments', 'config_file', 'save_signal', 'stop_signal', 'no_save_level', 'wait_window', 'VERSION'): message += "%s:%s\n" % (prop, cte.attribute(prop)) # remove last empty line message = message.rpartition('\n')[0] self.send(src_addr, '/reply', path, message) self.send(src_addr, '/reply', path) @client_action def _ray_client_set_proxy_properties(self, path, args, src_addr, client:Client): message = '' for arg in args: message += "%s\n" % arg if client.is_running(): self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, _translate('GUIMSG', 'Impossible to set proxy properties while client is running.')) return proxy_file = '%s/ray-proxy.xml' % client.get_project_path() if (not os.path.isfile(proxy_file) and client.executable_path != 'ray-proxy'): self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s seems to not be a proxy client !') % client.gui_msg_style()) return if os.path.isfile(proxy_file): try: file = open(proxy_file, 'r') xml = QDomDocument() xml.setContent(file.read()) content = xml.documentElement() file.close() except: self.send(src_addr, '/error', path, ray.Err.BAD_PROJECT, _translate('GUIMSG', "impossible to read %s correctly !") % proxy_file) return else: xml = QDomDocument() p = xml.createElement('RAY-PROXY') p.setAttribute('VERSION', ray.VERSION) xml.appendChild(p) content = xml.documentElement() if not os.path.isdir(client.get_project_path()): try: os.makedirs(client.get_project_path()) except: self.send(src_addr, '/error', path, ray.Err.CREATE_FAILED, "Impossible to create proxy directory") return if content.tagName() != "RAY-PROXY": self.send(src_addr, '/error', path, ray.Err.BAD_PROJECT, _translate('GUIMSG', "impossible to read %s correctly !") % proxy_file) return cte = content.toElement() for line in message.split('\n'): prop, colon, value = line.partition(':') if prop in ( 'executable', 'arguments', 'config_file', 'save_signal', 'stop_signal', 'no_save_level', 'wait_window', 'VERSION'): cte.setAttribute(prop, value) try: file = open(proxy_file, 'w') file.write(xml.toString()) file.close() except: self.send(src_addr, '/error', path, ray.Err.BAD_PROJECT, _translate('GUIMSG', "%s is not writeable") % proxy_file) return self.send(src_addr, '/reply', path, message) self.send(src_addr, '/reply', path) @client_action def _ray_client_get_description(self, path, args, src_addr, client:Client): self.send(src_addr, '/reply', path, client.description) self.send(src_addr, '/reply', path) @client_action def _ray_client_set_description(self, path, args, src_addr, client:Client): client.description = args[0] self.send(src_addr, '/reply', path, 'Description updated') @client_action def _ray_client_list_files(self, path, args, src_addr, client:Client): client_files = client.get_project_files() self.send(src_addr, '/reply', path, *client_files) self.send(src_addr, '/reply', path) @client_action def _ray_client_get_pid(self, path, args, src_addr, client:Client): if client.is_running(): self.send(src_addr, '/reply', path, str(client.pid)) self.send(src_addr, '/reply', path) else: self.send(src_addr, '/error', path, ray.Err.NOT_NOW, "client is not running, impossible to get its pid") def _ray_client_list_snapshots(self, path, args, src_addr): self._ray_session_list_snapshots(path, [], src_addr, args[0]) @session_operation def _ray_client_open_snapshot(self, path, args, src_addr): client_id, snapshot = args for client in self.clients: if client.client_id == client_id: if client.is_running(): self.steps_order = [ self.save, (self.snapshot, '', snapshot, True), (self.close_client, client), (self.load_client_snapshot, client_id, snapshot), (self.start_client, client), self.load_client_snapshot_done] else: self.steps_order = [ self.save, (self.snapshot, '', snapshot, True), (self.load_client_snapshot, client_id, snapshot), self.load_client_snapshot_done] break else: self.send_error_no_client(src_addr, path, client_id) @client_action def _ray_client_is_started(self, path, args, src_addr, client:Client): if client.is_running(): self.send(src_addr, '/reply', path, 'client running') else: self.send(src_addr, '/error', path, ray.Err.GENERAL_ERROR, _translate('GUIMSG', '%s is not running.') % client.gui_msg_style()) @client_action def _ray_client_send_signal(self, path, args, src_addr, client:Client): sig = args[0] client.send_signal(sig, src_addr, path) @client_action def _ray_client_set_custom_data(self, path, args, src_addr, client:Client): data, value = args client.custom_data[data] = value self.send(src_addr, '/reply', path, 'custom data set') @client_action def _ray_client_get_custom_data(self, path, args, src_addr, client:Client): data = args[0] if data not in client.custom_data: self.send(src_addr, '/error', path, ray.Err.NO_SUCH_FILE, "client %s has no custom_data key '%s'" % (client.client_id, data)) return self.send(src_addr, '/reply', path, client.custom_data[data]) self.send(src_addr, '/reply', path) @client_action def _ray_client_set_tmp_data(self, path, args, src_addr, client:Client): data, value = args client.custom_tmp_data[data] = value self.send(src_addr, '/reply', path, 'custom tmp data set') @client_action def _ray_client_get_tmp_data(self, path, args, src_addr, client:Client): data = args[0] if data not in client.custom_tmp_data: self.send(src_addr, '/error', path, ray.Err.NO_SUCH_FILE, "client %s has no tmp_custom_data key '%s'" % (client.client_id, data)) return self.send(src_addr, '/reply', path, client.custom_tmp_data[data]) self.send(src_addr, '/reply', path) @client_action def _ray_client_change_prefix(self, path, args, src_addr, client:Client): if client.is_running(): self.send(src_addr, '/error', path, ray.Err.NOT_NOW, "impossible to change prefix while client is running") return prefix_mode = args[0] custom_prefix = '' if prefix_mode in (ray.PrefixMode.SESSION_NAME, 'session_name'): prefix_mode = ray.PrefixMode.SESSION_NAME elif prefix_mode in (ray.PrefixMode.CLIENT_NAME, 'client_name'): prefix_mode = ray.PrefixMode.CLIENT_NAME else: prefix_mode = ray.PrefixMode.CUSTOM if prefix_mode == ray.PrefixMode.CUSTOM: custom_prefix = args[1] if not custom_prefix: self.send( src_addr, '/error', path, ray.err.GENERAL_ERROR, "You need to specify a custom prefix as 2nd argument") return client.change_prefix(prefix_mode, custom_prefix) # we need to save session file here # else, if session is aborted # client won't find its files at next restart self._save_session_file() self.send(src_addr, '/reply', path, 'prefix changed') def _ray_trashed_client_restore(self, path, args, src_addr): if not self.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "Nothing in trash because no session is loaded.") return for client in self.trashed_clients: if client.client_id == args[0]: if self._restore_client(client): self.send(src_addr, '/reply', path, "client restored") else: self.send(src_addr, '/error', path, ray.Err.NOT_NOW, "Session is in a loading locked state") break else: self.send(src_addr, "/error", path, -10, "No such client.") def _ray_trashed_client_remove_definitely(self, path, args, src_addr): if not self.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "Nothing in trash because no session is loaded.") return client_id = args[0] for client in self.trashed_clients: if client.client_id == client_id: break else: self.send(src_addr, "/error", path, -10, "No such client.") return self.send_gui('/ray/gui/trash/remove', client.client_id) for file in client.get_project_files(): try: subprocess.run(['rm', '-R', file]) except: self.send(src_addr, '/minor_error', path, -10, "Error while removing client file %s" % file) continue self.trashed_clients.remove(client) self._save_session_file() self.send(src_addr, '/reply', path, "client definitely removed") self.send_monitor_event('removed', client_id) def _ray_trashed_client_remove_keep_files(self, path, args, src_addr): if not self.path: self.send(src_addr, "/error", path, ray.Err.NO_SESSION_OPEN, "Nothing in trash because no session is loaded.") return client_id = args[0] for client in self.trashed_clients: if client.client_id == client_id: break else: self.send(src_addr, "/error", path, -10, "No such client.") return self.send_gui('/ray/gui/trash/remove', client.client_id) self.trashed_clients.remove(client) self.send(src_addr, '/reply', path, "client removed") self.send_monitor_event('removed', client_id) def _ray_net_daemon_duplicate_state(self, path, args, src_addr): state = args[0] for client in self.clients: if (client.protocol == ray.Protocol.RAY_NET and client.ray_net.daemon_url and ray.are_same_osc_port(client.ray_net.daemon_url, src_addr.url)): client.ray_net.duplicate_state = state client.net_daemon_copy_timer.stop() break else: return if state == 1: if self.wait_for == ray.WaitFor.DUPLICATE_FINISH: self.end_timer_if_last_expected(client) return if (self.wait_for == ray.WaitFor.DUPLICATE_START and state == 0): self.end_timer_if_last_expected(client) client.net_daemon_copy_timer.start() def check_recent_sessions_existing(self): # check here if recent sessions still exist if self.root in self.recent_sessions.keys(): to_remove_list = [] for sess in self.recent_sessions[self.root]: if not os.path.exists( "%s/%s/raysession.xml" % (self.root, sess)): to_remove_list.append(sess) for sess in to_remove_list: self.recent_sessions[self.root].remove(sess) def server_open_session_at_start(self, session_name): self.steps_order = [(self.preload, session_name), self.take_place, self.load, self.load_done] self.next_function() def dummy_load_and_template(self, session_name, template_name, sess_root): tmp_session = self._new_dummy_session(sess_root) tmp_session.dummy_load_and_template(session_name, template_name) def terminate(self): if self.terminated_yet: return if self.file_copier.is_active(): self.file_copier.abort() self.terminated_yet = True self.steps_order = [self.terminate_step_scripter, self.close, self.exit_now] self.next_function() class DummySession(OperatingSession): ''' A dummy session allows to make such operations on not current session It is used for session preview, or duplicate a session for example. When a session is dummy, it has no server options (bookmarks, snapshots, session scripts...). All clients are dummy and can't be started. Their file copier is not dummy, it can send OSC messages to gui, That is why we need a session_id to find it ''' def __init__(self, root, session_id=0): OperatingSession.__init__(self, root, session_id) self.is_dummy = True self.canvas_saver.is_dummy = True def dummy_load_and_template(self, session_full_name, template_name): self.steps_order = [(self.preload, session_full_name), self.take_place, self.load, (self.save_session_template, template_name, True)] self.next_function() def dummy_duplicate(self, path, args, src_addr): self.remember_osc_args(path, args, src_addr) session_to_load, new_session_full_name, sess_root = args self.steps_order = [(self.preload, session_to_load), self.take_place, self.load, (self.duplicate, new_session_full_name), self.duplicate_only_done] self.next_function() def ray_server_save_session_template(self, path, args, src_addr): self.remember_osc_args(path, args, src_addr) session_name, template_name, net = args self.steps_order = [(self.preload, session_name), self.take_place, self.load, (self.save_session_template, template_name, net)] self.next_function() def ray_server_rename_session(self, path, args, src_addr): self.remember_osc_args(path, args, src_addr) full_session_name, new_session_name = args self.steps_order = [(self.preload, full_session_name), self.take_place, self.load, (self.rename, new_session_name), self.save, (self.rename_done, new_session_name)] self.next_function() def ray_server_get_session_preview(self, path, args, src_addr, folder_sizes:list): session_name = args[0] self.steps_order = [(self.preload, session_name, False), self.take_place, self.load, (self.send_preview, src_addr, folder_sizes)] self.next_function() def dummy_load(self, session_name): self.steps_order = [(self.preload, session_name, False), self.take_place, self.load] self.next_function() RaySession-0.12.2/src/daemon/signaler.py000066400000000000000000000006751417052567600201300ustar00rootroot00000000000000from PyQt5.QtCore import QObject, pyqtSignal instance = None class Signaler(QObject): osc_recv = pyqtSignal(str, list, str, object) dummy_load_and_template = pyqtSignal(str, str, str) @staticmethod def instance(): global instance if not instance: instance = Signaler() return instance def __init__(self): QObject.__init__(self) global instance instance = self RaySession-0.12.2/src/daemon/snapshoter.py000066400000000000000000000501701417052567600205050ustar00rootroot00000000000000 import os import socket from PyQt5.QtCore import QProcess, QObject, QDateTime from PyQt5.QtXml import QDomDocument import ray from daemon_tools import Terminal def git_stringer(string:str)->str: for char in (' ', '*', '?', '[', ']', '(', ')'): string = string.replace(char, "\\" + char) for char in ('#', '!'): if string.startswith(char): string = "\\" + string return string def full_ref_for_gui(ref, name, rw_ref, rw_name='', ss_name=''): if ss_name: return "%s:%s\n%s:%s\n%s" % (ref, name, rw_ref, rw_name, ss_name) return "%s:%s\n%s:%s" % (ref, name, rw_ref, rw_name) class Snapshoter(QObject): def __init__(self, session): QObject.__init__(self) self.session = session self._git_exec = 'git' self._gitdir = '.ray-snapshots' self._exclude_path = 'info/exclude' self._history_path = "session_history.xml" self._max_file_size = 50 #in Mb self._next_snapshot_name = '' self._rw_snapshot = '' self._changes_checker = QProcess() self._changes_checker.readyReadStandardOutput.connect( self._changes_checker_standard_output) self._adder_process = QProcess() self._adder_process.finished.connect(self._save_step_1) self._adder_process.readyReadStandardOutput.connect( self._adder_standard_output) self._adder_aborted = False self._git_process = QProcess() self._git_process.readyReadStandardOutput.connect(self._standard_output) self._git_process.readyReadStandardError.connect(self._standard_error) self._git_command = '' self._n_file_changed = 0 self._n_file_treated = 0 self._changes_counted = False self._next_function = None self._error_function = None def _changes_checker_standard_output(self): standard_output = self._changes_checker.readAllStandardOutput().data() self._n_file_changed += len(standard_output.splitlines()) -1 def _adder_standard_output(self): standard_output = self._adder_process.readAllStandardOutput().data() Terminal.snapshoter_message(standard_output, ' add -A -v') if not self._n_file_changed: return self._n_file_treated += len(standard_output.splitlines()) -1 self.session.send_gui('/ray/gui/server/progress', self._n_file_treated / self._n_file_changed) def _standard_error(self): standard_error = self._git_process.readAllStandardError().data() Terminal.snapshoter_message(standard_error, self._git_command) def _standard_output(self): standard_output = self._git_process.readAllStandardOutput().data() Terminal.snapshoter_message(standard_output, self._git_command) def _run_git_process(self, *all_args): return self._run_git_process_at(self.session.path, *all_args) def _run_git_process_at(self, spath, *all_args): self._git_command = '' for arg in all_args: self._git_command += ' %s' % arg err = ray.Err.OK git_args = self._get_git_command_list_at(spath, *all_args) self._git_process.start(self._git_exec, git_args) if not self._git_process.waitForFinished(2000): self._git_process.kill() err = ray.Err.SUBPROCESS_UNTERMINATED else: if self._git_process.exitStatus(): err = ray.Err.SUBPROCESS_CRASH elif self._git_process.exitCode(): err = ray.Err.SUBPROCESS_EXITCODE if err and self._error_function: self._error_function(err, ' '.join(all_args)) return not bool(err) def _get_git_command_list(self, *args): return self._get_git_command_list_at(self.session.path, *args) def _get_git_command_list_at(self, spath, *args): first_args = ['--work-tree', spath, '--git-dir', "%s/%s" % (spath, self._gitdir)] return first_args + list(args) def _get_history_full_path(self): return "%s/%s/%s" % ( self.session.path, self._gitdir, self._history_path) def _get_history_xml_document_element(self): if not self._is_init(): return None file_path = self._get_history_full_path() xml = QDomDocument() try: history_file = open(file_path, 'r') xml.setContent(history_file.read()) history_file.close() except BaseException: return None SNS_xml = xml.documentElement() if SNS_xml.tagName() != 'SNAPSHOTS': return None return SNS_xml def _get_tag_date(self)->str: date_time = QDateTime.currentDateTimeUtc() date = date_time.date() time = date_time.time() tagdate = "%s_%s_%s_%s_%s_%s" % ( date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second()) return tagdate def _write_history_file(self, date_str, snapshot_name='', rewind_snapshot=''): if not self.session.path: return ray.Err.NO_SESSION_OPEN file_path = self._get_history_full_path() xml = QDomDocument() try: history_file = open(file_path, 'r') xml.setContent(history_file.read()) history_file.close() except: pass if xml.firstChild().isNull(): SNS_xml = xml.createElement('SNAPSHOTS') xml.appendChild(SNS_xml) else: SNS_xml = xml.firstChild() snapshot_el = xml.createElement('Snapshot') snapshot_el.setAttribute('ref', date_str) snapshot_el.setAttribute('name', snapshot_name) snapshot_el.setAttribute('rewind_snapshot', rewind_snapshot) snapshot_el.setAttribute('session_name', self.session.name) snapshot_el.setAttribute('VERSION', ray.VERSION) for client in self.session.clients + self.session.trashed_clients: client_el = xml.createElement('client') client.write_xml_properties(client_el) client_el.setAttribute('client_id', client.client_id) for client_file_path in client.get_project_files(): base_path = client_file_path.replace( "%s/" % self.session.path, '', 1) file_xml = xml.createElement('file') file_xml.setAttribute('path', base_path) client_el.appendChild(file_xml) snapshot_el.appendChild(client_el) SNS_xml.appendChild(snapshot_el) try: history_file = open(file_path, 'w') history_file.write(xml.toString()) history_file.close() except: return ray.Err.CREATE_FAILED return ray.Err.OK def _get_exclude_file_full_path(self)->str: return "%s/%s/%s" % ( self.session.path, self._gitdir, self._exclude_path) def _write_exclude_file(self)->int: file_path = self._get_exclude_file_full_path() try: exclude_file = open(file_path, 'w') except: return ray.Err.CREATE_FAILED contents = "" contents += "# This file is generated by ray-daemon at each snapshot\n" contents += "# Don't edit this file.\n" contents += "# If you want to add/remove files managed by git\n" contents += "# Create/Edit .gitignore in the session folder\n" contents += "\n" contents += "%s\n" % self._gitdir contents += "\n" contents += "# Globally ignored extensions\n" session_ignored_extensions = ray.GIT_IGNORED_EXTENSIONS session_ign_list = session_ignored_extensions.split(' ') session_ign_list = tuple(filter(bool, session_ign_list)) # write global ignored extensions for extension in session_ign_list: contents += "*%s\n" % extension for client in self.session.clients: cext_list = client.ignored_extensions.split(' ') if not extension in cext_list: contents += "!%s.%s/**/*%s\n" % ( git_stringer(client.get_prefix_string()), git_stringer(client.client_id), extension) contents += "!%s.%s.**/*%s\n" % ( git_stringer(client.get_prefix_string()), git_stringer(client.client_id), extension) contents += '\n' contents += "# Extensions ignored by clients\n" # write client specific ignored extension for client in self.session.clients: cext_list = client.ignored_extensions.split(' ') for extension in cext_list: if not extension: continue if extension in session_ignored_extensions: continue contents += "%s.%s/**/*%s\n" % ( git_stringer(client.get_prefix_string()), git_stringer(client.client_id), extension) contents += "%s.%s.**/*%s\n" % ( git_stringer(client.get_prefix_string()), git_stringer(client.client_id), extension) contents += '\n' contents += "# Too big Files\n" no_check_list = (self._gitdir) # check too big files for foldername, subfolders, filenames in os.walk(self.session.path): subfolders[:] = [d for d in subfolders if d not in no_check_list] if foldername == "%s/%s" % (self.session.path, self._gitdir): continue for filename in filenames: if filename.endswith(session_ign_list): if os.path.islink(filename): short_folder = foldername.replace( self.session.path + '/', '', 1) line = git_stringer("%s/%s" % (short_folder, filename)) contents += '!%s\n' % line # file with extension globally ignored but # unignored by its client will not be ignored # and that is well as this. continue if os.path.islink(filename): continue try: file_size = os.path.getsize(os.path.join(foldername, filename)) except: continue if file_size > self._max_file_size*1024**2: if foldername == self.session.path: line = git_stringer(filename) else: short_folder = foldername.replace( self.session.path + '/', '', 1) line = git_stringer("%s/%s" % (short_folder, filename)) contents += "%s\n" % line try: exclude_file.write(contents) exclude_file.close() except: return ray.Err.CREATE_FAILED return ray.Err.OK def _is_init(self)->bool: if not self.session.path: return False return os.path.isfile("%s/%s/%s" % ( self.session.path, self._gitdir, self._exclude_path)) def _can_save(self): if not self.session.path: return False if not self._is_init(): if not self._run_git_process('init'): return False user_name = os.getenv('USER') if not user_name: user_name = 'someone' machine_name = socket.gethostname() if not machine_name: machine_name = 'somewhere' if not self._run_git_process( 'config', 'user.email', '%s@%s' % (user_name, machine_name)): return False user_name = os.getenv('USER') if not user_name: user_name = 'someone' if not self._run_git_process('config', 'user.name', user_name): return False if not self._is_init(): return False return True def _error_quit(self, err): if self._error_function: self._error_function(err) self._error_function = None def _save_step_1(self): if self._adder_aborted: if self._next_function: self._next_function(aborted=True) return if self._n_file_changed: if not self._run_git_process('commit', '-m', 'ray'): return if (self._n_file_changed or self._next_snapshot_name or self._rw_snapshot): ref = self._get_tag_date() if not self._run_git_process('tag', '-a', ref, '-m', 'ray'): return err = self._write_history_file(ref, self._next_snapshot_name, self._rw_snapshot) if err: if self._error_function: self._error_function(err) # not really a reply, not strong. self.session.send_gui('/reply', '/ray/session/list_snapshots', full_ref_for_gui(ref, self._next_snapshot_name, self._rw_snapshot)) self._error_function = None self._next_snapshot_name = '' self._rw_snapshot = '' if self._next_function: self._next_function() def list(self, client_id=""): SNS_xml = self._get_history_xml_document_element() if not SNS_xml: return [] nodes = SNS_xml.childNodes() all_tags = [] all_snaps = [] prv_session_name = self.session.name for i in range(nodes.count()): node = nodes.at(i) el = node.toElement() if client_id: client_nodes = node.childNodes() for j in range(client_nodes.count()): client_node = client_nodes.at(j) client_el = client_node.toElement() if client_el.attribute('client_id') == client_id: break else: continue ref = el.attribute('ref') name = el.attribute('name') rw_sn = el.attribute('rewind_snapshot') rw_name = "" session_name = el.attribute('session_name') # don't list snapshot from client before session renamed if client_id and session_name != self.session.name: client = self.session.get_client(client_id) if (client and (client.prefix_mode == ray.PrefixMode.SESSION_NAME)): continue ss_name = "" if session_name != prv_session_name: ss_name = session_name prv_session_name = session_name if not ref.replace('_', '').isdigit(): continue if '\n' in name: name = "" if not rw_sn.replace('_', '').isdigit(): rw_sn = "" if rw_sn: for snap in all_snaps: if snap[0] == rw_sn and not '\n' in snap[1]: rw_name = snap[1] break all_snaps.append((ref, name)) snapsss = full_ref_for_gui(ref, name, rw_sn, rw_name, ss_name) all_tags.append(snapsss) all_tags.reverse() return all_tags def has_changes(self): if not self.session.path: return False if not self._is_init(): return True if self._changes_checker.state(): self._changes_checker.kill() self._n_file_changed = 0 self._n_file_treated = 0 self._changes_counted = True args = self._get_git_command_list( 'ls-files', '--exclude-standard', '--others', '--modified') self._changes_checker.start(self._git_exec, args) self._changes_checker.waitForFinished(2000) return bool(self._n_file_changed) def save(self, name='', rewind_snapshot='', next_function=None, error_function=None): self._next_snapshot_name = name self._rw_snapshot = rewind_snapshot self._next_function = next_function self._error_function = error_function if not self._can_save(): Terminal.message("can't snapshot") return err = self._write_exclude_file() if err: self._error_quit(err) return self._adder_aborted = False if not self._changes_counted: self.has_changes() self._changes_counted = False if self._n_file_changed: all_args = self._get_git_command_list('add', '-A', '-v') self._adder_process.start(self._git_exec, all_args) else: self._save_step_1() # self.adder_process.finished is connected to self._save_step_1 def load(self, spath, snapshot, error_function): self._error_function = error_function snapshot_ref = snapshot.partition('\n')[0].partition(':')[0] if not self._run_git_process_at(spath, 'reset', '--hard'): return False if not self._run_git_process_at(spath, 'checkout', snapshot_ref): return False return True def load_client_exclusive(self, client_id, snapshot, error_function): self._error_function = error_function SNS_xml = self._get_history_xml_document_element() if not SNS_xml: self._error_function(ray.Err.NO_SUCH_FILE, self._get_history_full_path()) return False nodes = SNS_xml.childNodes() client_path_list = [] for i in range(nodes.count()): node = nodes.at(i) el = node.toElement() if el.attribute('ref') != snapshot: continue client_nodes = node.childNodes() for j in range(client_nodes.count()): client_node = client_nodes.at(j) client_el = client_node.toElement() if client_el.attribute('client_id') != client_id: continue file_nodes = client_node.childNodes() for k in range(file_nodes.count()): file_node = file_nodes.at(k) file_el = file_node.toElement() file_path = file_el.attribute('path') if file_path: client_path_list.append(file_path) if not self._run_git_process('reset', '--hard'): return False if not self._run_git_process('checkout', snapshot, '--', *client_path_list): return False return True def abort(self): if not self._adder_process.state(): return self.set_auto_snapshot(False) self._adder_aborted = True self._adder_process.terminate() def set_auto_snapshot(self, bool_snapshot): auto_snap_file = "%s/%s/prevent_auto_snapshot" % (self.session.path, self._gitdir) file_exists = bool(os.path.exists(auto_snap_file)) if bool_snapshot: if file_exists: try: os.remove(auto_snap_file) except PermissionError: return else: if not file_exists: contents = "# This file prevent auto snapshots for this session (RaySession)\n" contents += "# remove it if you want auto snapshots back" try: file = open(auto_snap_file, 'w') file.write(contents) file.close() except PermissionError: return def is_auto_snapshot_prevented(self)->bool: auto_snap_file = "%s/%s/prevent_auto_snapshot" % (self.session.path, self._gitdir) return bool(os.path.exists(auto_snap_file)) RaySession-0.12.2/src/gui/000077500000000000000000000000001417052567600152635ustar00rootroot00000000000000RaySession-0.12.2/src/gui/add_application_dialog.py000066400000000000000000000515101417052567600222710ustar00rootroot00000000000000from PyQt5.QtCore import Qt, QSize from PyQt5.QtWidgets import (QDialogButtonBox, QListWidgetItem, QFrame, QMenu, QAction, QShortcut) from PyQt5.QtGui import QIcon import client_properties_dialog import ray from gui_tools import RS, _translate, is_dark_theme, get_app_icon from child_dialogs import ChildDialog import ui.add_application import ui.template_slot import ui.remove_template TEMPLATE_NAME_DATA = Qt.UserRole DISPLAY_NAME_DATA = Qt.UserRole +1 class TemplateSlot(QFrame): def __init__(self, list_widget, session, name, factory, client_data): QFrame.__init__(self) self.ui = ui.template_slot.Ui_Frame() self.ui.setupUi(self) self._factory = factory self._list_widget = list_widget self._name = name self._user_menu = QMenu() self.session = session self.client_data = client_data self.ui.toolButtonIcon.setIcon( get_app_icon(self.client_data.icon, self)) self.ui.label.setText(name) self.ui.toolButtonUser.setVisible(not factory) act_remove_template = QAction(QIcon.fromTheme('edit-delete-remove'), _translate('menu', 'remove'), self._user_menu) act_remove_template.triggered.connect(self.remove_template) self._user_menu.addAction(act_remove_template) self.ui.toolButtonUser.setMenu(self._user_menu) self.ui.toolButtonFavorite.set_session(self.session) self.ui.toolButtonFavorite.set_template( self._name, self.client_data.icon, self._factory) if is_dark_theme(self): self.ui.toolButtonUser.setIcon( QIcon(':scalable/breeze-dark/im-user.svg')) self.ui.toolButtonFavorite.set_dark_theme() def update_client_data(self, *args): self.client_data.update(*args) self.ui.toolButtonIcon.setIcon( get_app_icon(self.client_data.icon, self)) self.ui.toolButtonFavorite.set_template( self._name, self.client_data.icon, self._factory) def update_ray_hack_data(self, *args): if self.client_data.ray_hack is None: self.client_data.ray_hack = ray.RayHack.new_from(*args) self.client_data.ray_hack.update(*args) def update_ray_net_data(self, *args): if self.client_data.ray_net is None: self.client_data.ray_net = ray.RayNet.new_from(*args) self.client_data.ray_net.update(*args) def set_display_name(self, display_name: str): self.ui.label.setText(display_name) def get_display_name(self)->str: return self.ui.label.text() def remove_template(self): add_app_dialog = self._list_widget.parent() add_app_dialog.remove_template(self._name, self._factory) def set_as_favorite(self, yesno: bool): self.ui.toolButtonFavorite.set_as_favorite(yesno) def mouseDoubleClickEvent(self, event): self._list_widget.parent().accept() class TemplateItem(QListWidgetItem): def __init__(self, parent, session, name, factory): QListWidgetItem.__init__(self, parent, QListWidgetItem.UserType + 1) self.client_data = ray.ClientData() self._widget = TemplateSlot(parent, session, name, factory, self.client_data) self.setData(TEMPLATE_NAME_DATA, name) self.setData(DISPLAY_NAME_DATA, name) parent.setItemWidget(self, self._widget) self.setSizeHint(QSize(100, 28)) self.is_factory = factory def __lt__(self, other): self_name = self.data(DISPLAY_NAME_DATA) other_name = other.data(DISPLAY_NAME_DATA) if other_name is None or not other_name: return False if self_name == other_name: # make the user template on top return not self.is_factory return bool(self_name.lower() < other_name.lower()) def matches_with(self, factory, name: str): return bool(bool(factory) == bool(self.is_factory) and name == self.data(TEMPLATE_NAME_DATA)) def update_client_data(self, *args): self._widget.update_client_data(*args) def update_ray_hack_data(self, *args): self._widget.update_ray_hack_data(*args) def update_ray_net_data(self, *args): self._widget.update_ray_net_data(*args) def set_display_name(self, display_name: str): self.setData(DISPLAY_NAME_DATA, display_name) self._widget.set_display_name(display_name) def get_display_name(self)->str: return self._widget.get_display_name() def set_as_favorite(self, yesno: bool): self._widget.set_as_favorite(yesno) class RemoveTemplateDialog(ChildDialog): def __init__(self, parent, template_name): ChildDialog.__init__(self, parent) self.ui = ui.remove_template.Ui_Dialog() self.ui.setupUi(self) self.ui.label.setText( _translate( 'add_app_dialog', '

Are you sure to want to remove
the template "%s" and all its files ?

') % template_name) self.ui.pushButtonCancel.setFocus() class AddApplicationDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.add_application.Ui_DialogAddApplication() self.ui.setupUi(self) self.session = parent.session self.ui.checkBoxFactory.setChecked(RS.settings.value( 'AddApplication/factory_box', True, type=bool)) self.ui.checkBoxUser.setChecked(RS.settings.value( 'AddApplication/user_box', True, type=bool)) self.ui.checkBoxRayHack.setChecked(RS.settings.value( 'AddApplication/ray_hack_box', True, type=bool)) self.ui.widgetTemplateInfos.setVisible(False) self.ui.checkBoxFactory.stateChanged.connect(self._factory_box_changed) self.ui.checkBoxUser.stateChanged.connect(self._user_box_changed) self.ui.checkBoxNsm.stateChanged.connect(self._nsm_box_changed) self.ui.checkBoxRayHack.stateChanged.connect(self._ray_hack_box_changed) self.ui.pushButtonRefresh.clicked.connect(self._refresh_database) self._refresh_shortcut = QShortcut('F5', self) self._refresh_shortcut.activated.connect(self._refresh_database) self.ui.templateList.currentItemChanged.connect( self._current_item_changed) self.ui.templateList.setFocus(Qt.OtherFocusReason) self.ui.filterBar.textEdited.connect(self._update_filtered_list) self.ui.filterBar.up_down_pressed.connect(self._up_down_pressed) self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.user_menu = QMenu() act_remove_template = QAction(QIcon.fromTheme('edit-delete-remove'), _translate('menu', 'remove'), self.user_menu) act_remove_template.triggered.connect(self._remove_current_template) self.user_menu.addAction(act_remove_template) self.ui.toolButtonUser.setMenu(self.user_menu) self.ui.toolButtonFavorite.set_session(self.session) self.ui.widgetNonSaveable.setVisible(False) self.ui.toolButtonAdvanced.clicked.connect( self._tool_button_advanced_clicked) if is_dark_theme(self): self.ui.toolButtonUser.setIcon( QIcon(':scalable/breeze-dark/im-user.svg')) self.ui.toolButtonFavorite.set_dark_theme() self.ui.toolButtonNoSave.setIcon( QIcon(':scalable/breeze-dark/document-nosave.svg')) self.signaler.user_client_template_found.connect( self._add_user_templates) self.signaler.factory_client_template_found.connect( self._add_factory_templates) self.signaler.client_template_update.connect( self._update_client_template) self.signaler.client_template_ray_hack_update.connect( self._update_client_template_ray_hack) self.signaler.client_template_ray_net_update.connect( self._update_client_template_ray_net) self.signaler.favorite_added.connect(self._favorite_added) self.signaler.favorite_removed.connect(self._favorite_removed) self.to_daemon('/ray/server/list_user_client_templates') self.to_daemon('/ray/server/list_factory_client_templates') self.listing_finished = 0 self.user_template_list = [] self.factory_template_list = [] self._server_will_accept = False self.has_selection = False self._server_status_changed(self.session.server_status) self.ui.filterBar.setFocus() def _favorite_added(self, template_name: str, template_icon: str, factory: bool): for i in range(self.ui.templateList.count()): item = self.ui.templateList.item(i) if item is None: continue if (item.data(TEMPLATE_NAME_DATA) == template_name and item.is_factory == factory): item.set_as_favorite(True) if item == self.ui.templateList.currentItem(): self.ui.toolButtonFavorite.set_as_favorite(True) break def _favorite_removed(self, template_name: str, factory: bool): for i in range(self.ui.templateList.count()): item = self.ui.templateList.item(i) if item is None: continue if (item.data(TEMPLATE_NAME_DATA) == template_name and item.is_factory == factory): item.set_as_favorite(False) if item == self.ui.templateList.currentItem(): self.ui.toolButtonFavorite.set_as_favorite(False) break def _factory_box_changed(self, state): if not state: self.ui.checkBoxUser.setChecked(True) self._update_filtered_list() def _user_box_changed(self, state): if not state: self.ui.checkBoxFactory.setChecked(True) self._update_filtered_list() def _nsm_box_changed(self, state): if not state: self.ui.checkBoxRayHack.setChecked(True) self._update_filtered_list() def _ray_hack_box_changed(self, state): if not state: self.ui.checkBoxNsm.setChecked(True) self._update_filtered_list() def _refresh_database(self): self.ui.pushButtonRefresh.setEnabled(False) self.ui.templateList.clear() self.user_template_list.clear() self.factory_template_list.clear() self.to_daemon('/ray/server/clear_client_templates_database') self.to_daemon('/ray/server/list_user_client_templates') self.to_daemon('/ray/server/list_factory_client_templates') def _add_user_templates(self, template_list): for template_name in template_list: if template_name in self.user_template_list: continue self.user_template_list.append(template_name) item = TemplateItem( self.ui.templateList, self.session, template_name, False) if self.session.is_favorite(template_name, False): item.set_as_favorite(True) self.ui.templateList.addItem(item) self.ui.templateList.sortItems() self._update_filtered_list() def _add_factory_templates(self, template_list): for template_name in template_list: if template_name in self.factory_template_list: continue self.factory_template_list.append(template_name) item = TemplateItem( self.ui.templateList, self.session, template_name, True) if self.session.is_favorite(template_name, True): item.set_as_favorite(True) self.ui.templateList.addItem(item) self.ui.templateList.sortItems() self._update_filtered_list() if not template_list: self.ui.pushButtonRefresh.setEnabled(True) def _update_client_template(self, args): factory = bool(args[0]) template_name = args[1] display_name = args[2] for i in range(self.ui.templateList.count()): item = self.ui.templateList.item(i) if item.matches_with(factory, template_name): if display_name: item.set_display_name(display_name) item.update_client_data(*args[3:]) if self.ui.templateList.currentItem() == item: self._update_template_infos(item) break def _update_client_template_ray_hack(self, args): factory = bool(args[0]) template_name = args[1] for i in range(self.ui.templateList.count()): item = self.ui.templateList.item(i) if item.matches_with(factory, template_name): item.update_ray_hack_data(*args[2:]) if self.ui.templateList.currentItem() == item: self._update_template_infos(item) break def _update_client_template_ray_net(self, args): factory = bool(args[0]) template_name = args[1] for i in range(self.ui.templateList.count()): item = self.ui.templateList.item(i) if item.matches_with(factory, template_name): item.update_ray_net_data(*args[2:]) if self.ui.templateList.currentItem() == item: self._update_template_infos(item) break def _update_filtered_list(self, filt=''): filter_text = self.ui.filterBar.displayText() # show all items for i in range(self.ui.templateList.count()): self.ui.templateList.item(i).setHidden(False) # hide all non matching items for i in range(self.ui.templateList.count()): item = self.ui.templateList.item(i) template_name = item.data(TEMPLATE_NAME_DATA) if not filter_text.lower() in template_name.lower(): item.setHidden(True) if item.is_factory and not self.ui.checkBoxFactory.isChecked(): item.setHidden(True) if not item.is_factory and not self.ui.checkBoxUser.isChecked(): item.setHidden(True) if item.client_data is not None: if (item.client_data.protocol == ray.Protocol.RAY_HACK and not self.ui.checkBoxRayHack.isChecked()): item.setHidden(True) if (item.client_data.protocol != ray.Protocol.RAY_HACK and not self.ui.checkBoxNsm.isChecked()): item.setHidden(True) # if selected item not in list, then select the first visible if (not self.ui.templateList.currentItem() or self.ui.templateList.currentItem().isHidden()): for i in range(self.ui.templateList.count()): if not self.ui.templateList.item(i).isHidden(): self.ui.templateList.setCurrentRow(i) break if (not self.ui.templateList.currentItem() or self.ui.templateList.currentItem().isHidden()): if self.ui.filterBar.text(): self.ui.filterBar.setStyleSheet( "QLineEdit { background-color: red}") self.ui.templateList.setCurrentItem(None) else: self.ui.filterBar.setStyleSheet("") self.ui.templateList.scrollTo(self.ui.templateList.currentIndex()) def _up_down_pressed(self, key): row = self.ui.templateList.currentRow() if key == Qt.Key_Up: if row == 0: return row -= 1 while self.ui.templateList.item(row).isHidden(): if row == 0: return row -= 1 elif key == Qt.Key_Down: if row == self.ui.templateList.count() - 1: return row += 1 while self.ui.templateList.item(row).isHidden(): if row == self.ui.templateList.count() - 1: return row += 1 self.ui.templateList.setCurrentRow(row) def _update_template_infos(self, item): self.ui.widgetTemplateInfos.setVisible(bool(item)) self.ui.widgetNoTemplate.setVisible(not bool(item)) if not item: return cdata = item.client_data self.ui.toolButtonIcon.setIcon( get_app_icon(cdata.icon, self)) template_name = item.data(TEMPLATE_NAME_DATA) self.ui.labelTemplateName.setText(item.get_display_name()) #self.ui.labelTemplateName.setText(template_name) self.ui.labelDescription.setText(cdata.description) self.ui.labelProtocol.setText(ray.protocol_to_str(cdata.protocol)) self.ui.labelExecutable.setText(cdata.executable_path) self.ui.labelLabel.setText(cdata.label) self.ui.labelName.setText(cdata.name) for widget in (self.ui.labelProtocolTitle, self.ui.labelProtocolColon, self.ui.labelProtocol): widget.setVisible(bool(cdata.protocol != ray.Protocol.NSM)) for widget in (self.ui.labelLabelTitle, self.ui.labelLabelColon, self.ui.labelLabel): widget.setVisible(bool(cdata.label)) for widget in (self.ui.labelNameTitle, self.ui.labelNameColon, self.ui.labelName): widget.setVisible(bool(cdata.protocol == ray.Protocol.NSM)) self.ui.toolButtonUser.setVisible(not item.is_factory) self.ui.toolButtonFavorite.set_template( item.data(TEMPLATE_NAME_DATA), cdata.icon, item.is_factory) self.ui.toolButtonFavorite.set_as_favorite(self.session.is_favorite( item.data(TEMPLATE_NAME_DATA), item.is_factory)) self.ui.widgetNonSaveable.setVisible(bool( cdata.ray_hack is not None and cdata.protocol == ray.Protocol.RAY_HACK and cdata.ray_hack.no_save_level > 0)) # little security # client_properties_dialog could crash if ray_hack has not been updated yet # (never seen this appears, but it could with slow systems) self.ui.toolButtonAdvanced.setEnabled( bool(cdata.protocol != ray.Protocol.RAY_HACK or cdata.ray_hack is not None)) def _current_item_changed(self, item, previous_item): self.has_selection = bool(item) self._update_template_infos(item) self._prevent_ok() def _tool_button_advanced_clicked(self): item = self.ui.templateList.currentItem() if item is None: return properties_dialog = client_properties_dialog.ClientPropertiesDialog.create( self, item.client_data) properties_dialog.update_contents() properties_dialog.set_for_template(item.data(TEMPLATE_NAME_DATA)) properties_dialog.show() def _prevent_ok(self): self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(self._server_will_accept and self.has_selection)) def _remove_current_template(self): item = self.ui.templateList.currentItem() if not item: return self.remove_template(item.data(TEMPLATE_NAME_DATA), False) def _server_status_changed(self, server_status): self._server_will_accept = bool( server_status not in ( ray.ServerStatus.OFF, ray.ServerStatus.CLOSE) and not self.server_copying) self._prevent_ok() def get_selected_template(self)->tuple: item = self.ui.templateList.currentItem() if item: return (item.data(TEMPLATE_NAME_DATA), item.is_factory) def remove_template(self, template_name, factory): dialog = RemoveTemplateDialog(self, template_name) dialog.exec() if not dialog.result(): return self.to_daemon('/ray/server/remove_client_template', template_name) for i in range(self.ui.templateList.count()): item = self.ui.templateList.item(i) if (not item.is_factory and template_name == item.data(TEMPLATE_NAME_DATA)): item.setHidden(True) if item == self.ui.templateList.currentItem(): self._update_template_infos(None) self.ui.templateList.removeItemWidget(item) break def save_check_boxes(self): RS.settings.setValue( 'AddApplication/factory_box', self.ui.checkBoxFactory.isChecked()) RS.settings.setValue( 'AddApplication/user_box', self.ui.checkBoxUser.isChecked()) RS.settings.setValue( 'AddApplication/ray_hack_box', self.ui.checkBoxRayHack.isChecked()) RS.settings.sync() RaySession-0.12.2/src/gui/canvas_filter_frame.py000066400000000000000000000122131417052567600216260ustar00rootroot00000000000000 from PyQt5.QtWidgets import QFrame from PyQt5.QtCore import pyqtSignal, Qt from gui_tools import RS import patchbay_manager import patchcanvas import ui.filter_frame class CanvasFilterFrame(QFrame): def __init__(self, parent): QFrame.__init__(self, parent) self.ui = ui.filter_frame.Ui_Frame() self.ui.setupUi(self) self.patchbay_manager = None self.ui.lineEditGroupFilter.textEdited.connect(self._text_changed) self.ui.lineEditGroupFilter.up_down_pressed.connect(self._up_down_pressed) self.ui.toolButtonUp.clicked.connect(self._up_pressed) self.ui.toolButtonDown.clicked.connect(self._down_pressed) self.ui.checkBoxAudioFilter.stateChanged.connect( self._check_box_audio_checked) self.ui.checkBoxMidiFilter.stateChanged.connect( self._check_box_midi_checked) self.ui.spinBoxOpacity.valueChanged.connect( self._set_semi_hide_opacity) self.ui.toolButtonCloseFilterBar.clicked.connect( self.hide) self._n_selected = 0 self._n_boxes = 0 self.ui.spinBoxOpacity.setValue( int(RS.settings.value('Canvas/semi_hide_opacity', type=float) * 100)) def _filter_groups(self): if self.patchbay_manager is None: return filter_text = self.ui.lineEditGroupFilter.text() self.ui.labelBoxes.setText('') self._n_boxes = self.patchbay_manager.filter_groups( filter_text, self._n_selected) if self._n_boxes: self.ui.lineEditGroupFilter.setStyleSheet('') if filter_text: self.ui.labelBoxes.setText( '%i / %i' % (self._n_selected, self._n_boxes)) else: self.ui.lineEditGroupFilter.setStyleSheet( 'QLineEdit{background-color:#800000}') self.ui.toolButtonUp.setEnabled(self._n_boxes >= 2) self.ui.toolButtonDown.setEnabled(self._n_boxes >= 2) def _text_changed(self, text: str): if text: self._n_selected = 1 else: self._n_selected = 0 self._filter_groups() def _up_pressed(self): self._n_selected += 1 if self._n_selected > self._n_boxes: self._n_selected = 1 self._filter_groups() def _down_pressed(self): self._n_selected -= 1 if self._n_selected < 1: self._n_selected = self._n_boxes self._filter_groups() def _up_down_pressed(self, key: int): if not self.ui.toolButtonUp.isEnabled(): # could be toolButtonDown # they both are enable/disable together return if key == Qt.Key_Up: self._up_pressed() elif key == Qt.Key_Down: self._down_pressed() def _change_port_types_view(self): if self.patchbay_manager is None: return port_types_view = ( int(self.ui.checkBoxAudioFilter.isChecked()) * patchbay_manager.PORT_TYPE_AUDIO + int(self.ui.checkBoxMidiFilter.isChecked()) * patchbay_manager.PORT_TYPE_MIDI) self.patchbay_manager.change_port_types_view(port_types_view) self._filter_groups() def _check_box_audio_checked(self, state: int): if not state: self.ui.checkBoxMidiFilter.setChecked(True) self._change_port_types_view() def _check_box_midi_checked(self, state: int): if not state: self.ui.checkBoxAudioFilter.setChecked(True) self._change_port_types_view() def _port_types_view_changed(self, port_types_view: int): self.ui.checkBoxAudioFilter.setChecked( bool(port_types_view & patchbay_manager.PORT_TYPE_AUDIO)) self.ui.checkBoxMidiFilter.setChecked( bool(port_types_view & patchbay_manager.PORT_TYPE_MIDI)) def _set_semi_hide_opacity(self, value:int): if self.patchbay_manager is None: return self.patchbay_manager.set_semi_hide_opacity(float(value / 100)) def showEvent(self, event): self.ui.lineEditGroupFilter.setFocus() self.ui.toolButtonDown.setEnabled(False) self.ui.toolButtonUp.setEnabled(False) self.ui.labelBoxes.setText('') def hideEvent(self, event): self.ui.lineEditGroupFilter.setText('') self._n_selected = 0 self._filter_groups() RS.settings.setValue( 'Canvas/semi_hide_opacity', float(self.ui.spinBoxOpacity.value() / 100)) def set_patchbay_manager(self, patchbay_manager): self.patchbay_manager = patchbay_manager self.patchbay_manager.session.signaler.port_types_view_changed.connect( self._port_types_view_changed) def set_filter_text(self, text: str): ''' used to find client boxes from client widget ''' self.ui.lineEditGroupFilter.setText(text) if text: self._n_selected = 1 else: self._n_selected = 0 self._filter_groups() RaySession-0.12.2/src/gui/canvas_options.py000066400000000000000000000072311417052567600206660ustar00rootroot00000000000000 from PyQt5.QtWidgets import QDialog, QApplication from PyQt5.QtCore import Qt from gui_tools import RS import ui.canvas_options _translate = QApplication.translate class CanvasOptionsDialog(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.ui = ui.canvas_options.Ui_Dialog() self.ui.setupUi(self) self.gracious_names = RS.settings.value( 'Canvas/use_graceful_names', True, type=bool) self.a2j_grouped = RS.settings.value( 'Canvas/group_a2j_ports', True, type=bool) self.use_shadows = RS.settings.value( 'Canvas/box_shadows', False, type=bool) self.elastic_canvas = RS.settings.value( 'Canvas/elastic', True, type=bool) self.prevent_overlap = RS.settings.value( 'Canvas/prevent_overlap', True, type=bool) self.max_port_width = RS.settings.value( 'Canvas/max_port_width', 170, type=int) self.ui.checkBoxGracefulNames.setChecked( self.gracious_names) self.ui.checkBoxA2J.setChecked( self.a2j_grouped) self.ui.checkBoxShadows.setChecked( self.use_shadows) self.ui.checkBoxElastic.setChecked( self.elastic_canvas) self.ui.checkBoxPreventOverlap.setChecked( self.prevent_overlap) self.ui.comboBoxTheme.addItem(_translate('patchbay', 'Silver Gold')) self.ui.comboBoxTheme.addItem(_translate('patchbay', 'Black Gold')) self.ui.comboBoxTheme.addItem(_translate('patchbay', 'Modern Dark')) current_theme = RS.settings.value('Canvas/theme', 'Silver Gold', type=str) if current_theme == "Black Gold": self.ui.comboBoxTheme.setCurrentIndex(1) elif current_theme == "Modern Dark": self.ui.comboBoxTheme.setCurrentIndex(2) self.ui.spinBoxMaxPortWidth.setValue(self.max_port_width) self.gracious_names_checked = self.ui.checkBoxGracefulNames.stateChanged self.a2j_grouped_checked = self.ui.checkBoxA2J.stateChanged self.group_shadows_checked = self.ui.checkBoxShadows.stateChanged self.theme_changed = self.ui.comboBoxTheme.currentIndexChanged self.elastic_checked = self.ui.checkBoxElastic.stateChanged self.prevent_overlap_checked = self.ui.checkBoxPreventOverlap.stateChanged self.max_port_width_changed = self.ui.spinBoxMaxPortWidth.valueChanged def get_gracious_names(self)->bool: return self.ui.checkBoxGracefulNames.isChecked() def get_a2j_grouped(self)->bool: return self.ui.checkBoxA2J.isChecked() def get_group_shadows(self)->bool: return self.ui.checkBoxShadows.isChecked() def get_elastic(self)->bool: return self.ui.checkBoxElastic.isChecked() def get_prevent_overlap(self)->bool: return self.ui.checkBoxPreventOverlap.isChecked() def get_max_port_width(self)->int: return self.ui.spinBoxMaxPortWidth.value() def closeEvent(self, event): RS.settings.setValue('Canvas/use_graceful_names', self.get_gracious_names()) RS.settings.setValue('Canvas/group_a2j_ports', self.get_a2j_grouped()) RS.settings.setValue('Canvas/box_shadows', self.get_group_shadows()) RS.settings.setValue('Canvas/elastic', self.get_elastic()) RS.settings.setValue('Canvas/prevent_overlap', self.get_prevent_overlap()) RS.settings.setValue('Canvas/max_port_width', self.get_max_port_width()) QDialog.closeEvent(self, event) RaySession-0.12.2/src/gui/child_dialogs.py000066400000000000000000001365161417052567600204360ustar00rootroot00000000000000import os import sys import time import subprocess from PyQt5.QtWidgets import ( QDialog, QDialogButtonBox, QTreeWidget, QTreeWidgetItem, QCompleter, QMessageBox, QFileDialog, QApplication, QListWidgetItem) from PyQt5.QtGui import QIcon, QPixmap, QGuiApplication from PyQt5.QtCore import Qt, QTimer import client_properties_dialog import ray from gui_server_thread import GuiServerThread from gui_tools import (ErrDaemon, _translate, get_app_icon, CommandLineArgs, RS, is_dark_theme) from patchcanvas import patchcanvas import ui.new_session import ui.save_template_session import ui.nsm_open_info import ui.abort_session import ui.about_raysession import ui.donations import ui.jack_config_info import ui.new_executable import ui.error_dialog import ui.quit_app import ui.script_info import ui.script_user_action import ui.session_notes import ui.session_scripts_info import ui.stop_client import ui.stop_client_no_save import ui.abort_copy import ui.client_trash import ui.daemon_url import ui.snapshot_progress import ui.waiting_close_user import ui.client_rename import ui.canvas_port_info import ui.startup_dialog import ui.systray_close import ui.systray_management class ChildDialog(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.session = parent.session self.signaler = self.session.signaler self.daemon_manager = self.session.daemon_manager self.signaler.server_status_changed.connect(self._server_status_changed) self.signaler.server_copying.connect(self._server_copying) self._root_folder_file_dialog = None self._root_folder_message_box = QMessageBox( QMessageBox.Critical, _translate('root_folder_dialogs', 'unwritable dir'), '', QMessageBox.NoButton, self) self.server_copying = parent.server_copying @classmethod def to_daemon(cls, *args): server = GuiServerThread.instance() if server: server.to_daemon(*args) else: sys.stderr.write('Error No GUI OSC Server, can not send %s.\n' % args) def _server_status_changed(self, server_status: int): pass def _server_copying(self, copying: bool): self.server_copying = copying self._server_status_changed(self.session.server_status) def _change_root_folder(self): # construct this here only because it can be quite long if self._root_folder_file_dialog is None: self._root_folder_file_dialog = QFileDialog( self, _translate("root_folder_dialogs", "Choose root folder for sessions"), CommandLineArgs.session_root) self._root_folder_file_dialog.setFileMode(QFileDialog.Directory) self._root_folder_file_dialog.setOption(QFileDialog.ShowDirsOnly) else: self._root_folder_file_dialog.setDirectory(CommandLineArgs.session_root) self._root_folder_file_dialog.exec() if not self._root_folder_file_dialog.result(): return selected_files = self._root_folder_file_dialog.selectedFiles() if not selected_files: return root_folder = selected_files[0] # Security, kde dialogs sends $HOME if user type a folder path # that doesn't already exists. if os.getenv('HOME') and root_folder == os.getenv('HOME'): return self._root_folder_message_box.setText( _translate('root_folder_dialogs', "

You have no permissions for %s,
choose another directory !

") % root_folder) if not os.path.exists(root_folder): try: os.makedirs(root_folder) except: self._root_folder_message_box.exec() return if not os.access(root_folder, os.W_OK): self._root_folder_message_box.exec() return RS.settings.setValue('default_session_root', root_folder) self.to_daemon('/ray/server/change_root', root_folder) def leaveEvent(self, event): if self.isActiveWindow(): self.parent().mouse_is_inside = False QDialog.leaveEvent(self, event) def enterEvent(self, event): self.parent().mouse_is_inside = True QDialog.enterEvent(self, event) class NewSessionDialog(ChildDialog): def __init__(self, parent, duplicate_window=False): ChildDialog.__init__(self, parent) self.ui = ui.new_session.Ui_DialogNewSession() self.ui.setupUi(self) self._is_duplicate = bool(duplicate_window) self.ui.currentSessionsFolder.setText(CommandLineArgs.session_root) self.ui.toolButtonFolder.clicked.connect(self._change_root_folder) self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.ui.lineEdit.setFocus(Qt.OtherFocusReason) self.ui.lineEdit.textChanged.connect(self._text_changed) self.session_list = [] self.template_list = [] self.sub_folders = [] self.signaler.server_status_changed.connect(self._server_status_changed) self.signaler.add_sessions_to_list.connect(self._add_sessions_to_list) self.signaler.session_template_found.connect(self._add_templates_to_list) self.signaler.root_changed.connect(self._root_changed) self.to_daemon('/ray/server/list_sessions', 1) if self._is_duplicate: self.ui.labelTemplate.setVisible(False) self.ui.comboBoxTemplate.setVisible(False) self.ui.labelOriginalSessionName.setText(self.session.get_short_path()) self.ui.labelNewSessionName.setText( _translate('Duplicate', 'Duplicated session name :')) self.setWindowTitle(_translate('Duplicate', 'Duplicate Session')) else: self.ui.frameOriginalSession.setVisible(False) self.to_daemon('/ray/server/list_session_templates') if not self.daemon_manager.is_local: self.ui.toolButtonFolder.setVisible(False) self.ui.currentSessionsFolder.setVisible(False) self.ui.labelSessionsFolder.setVisible(False) self._init_templates_combo_box() self._set_last_template_selected() self._server_will_accept = False self._text_is_valid = False self._completer = QCompleter(self.sub_folders) self.ui.lineEdit.setCompleter(self._completer) self._server_status_changed(self.session.server_status) self._text_was_empty = True def _server_status_changed(self, server_status): self.ui.toolButtonFolder.setEnabled( bool(server_status == ray.ServerStatus.OFF)) self._server_will_accept = bool( server_status in ( ray.ServerStatus.OFF, ray.ServerStatus.READY) and not self.server_copying) if self._is_duplicate: self._server_will_accept = bool( server_status == ray.ServerStatus.READY and not self.server_copying) if server_status != ray.ServerStatus.OFF: if self._root_folder_file_dialog is not None: self._root_folder_file_dialog.reject() self._root_folder_message_box.reject() self._prevent_ok() def _root_changed(self, session_root): self.ui.currentSessionsFolder.setText(session_root) self.session_list.clear() self.sub_folders.clear() self.to_daemon('/ray/server/list_sessions', 1) def _init_templates_combo_box(self): self.ui.comboBoxTemplate.clear() self.ui.comboBoxTemplate.addItem( _translate('session_template', "empty")) self.ui.comboBoxTemplate.addItem( _translate('session_template', "with JACK patch memory")) self.ui.comboBoxTemplate.addItem( _translate('session_template', "with JACK config memory")) self.ui.comboBoxTemplate.addItem( _translate('session_template', "with basic scripts")) misscount = self.ui.comboBoxTemplate.count() \ - 1 - len(ray.FACTORY_SESSION_TEMPLATES) for i in range(misscount): self.ui.comboBoxTemplate.addItem( ray.FACTORY_SESSION_TEMPLATES[-i]) self.ui.comboBoxTemplate.insertSeparator( len(ray.FACTORY_SESSION_TEMPLATES) + 1) def _set_last_template_selected(self): last_used_template = RS.settings.value('last_used_template', type=str) if last_used_template.startswith('///'): last_factory_template = last_used_template.replace('///', '', 1) for i in range(len(ray.FACTORY_SESSION_TEMPLATES)): factory_template = ray.FACTORY_SESSION_TEMPLATES[i] if factory_template == last_factory_template: self.ui.comboBoxTemplate.setCurrentIndex(i+1) break else: if last_used_template in self.template_list: self.ui.comboBoxTemplate.setCurrentText(last_used_template) if not last_used_template: self.ui.comboBoxTemplate.setCurrentIndex(1) def _set_last_sub_folder_selected(self): last_subfolder = '' for sess in self.session.recent_sessions: if sess.startswith('/'): continue if '/' in sess: last_subfolder, sep, sess_name = sess.rpartition('/') break if last_subfolder and not self.ui.lineEdit.text(): self.ui.lineEdit.setText(last_subfolder + '/') def _add_sessions_to_list(self, session_names): self.session_list += session_names for session_name in session_names: if '/' in session_name: new_dir = os.path.dirname(session_name) if not new_dir in self.sub_folders: self.sub_folders.append(new_dir) self.sub_folders.sort() del self._completer self._completer = QCompleter([f + '/' for f in self.sub_folders]) self.ui.lineEdit.setCompleter(self._completer) if not session_names: # all sessions are listed, pre-fill last subfolder self._set_last_sub_folder_selected() def _add_templates_to_list(self, template_list): for template in template_list: if template not in self.template_list: self.template_list.append(template) if not self.template_list: return self.template_list.sort() self._init_templates_combo_box() for template_name in self.template_list: self.ui.comboBoxTemplate.addItem(template_name) self._set_last_template_selected() def _text_changed(self, text): self._text_is_valid = bool(text and not text.endswith('/') and text not in self.session_list) self._prevent_ok() if self._text_was_empty: if text: self._completer.setCompletionMode(QCompleter.PopupCompletion) self._completer.complete() self._text_was_empty = False elif not text: QTimer.singleShot(50, self._set_completer_for_empty_text) self._text_was_empty = True def _set_completer_for_empty_text(self): #print('set currow', self._completer.setCurrentIndex(0)) del self._completer self._completer = QCompleter([f + '/' for f in self.sub_folders]) self._completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.ui.lineEdit.setCompleter(self._completer) QTimer.singleShot(50, self._completer.complete) def _show_completer_at_start(self): self._completer.complete() def showEvent(self, event): ChildDialog.showEvent(self, event) QTimer.singleShot(800, self._show_completer_at_start) def _prevent_ok(self): self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(self._server_will_accept and self._text_is_valid)) def get_session_short_path(self)->str: return self.ui.lineEdit.text() def get_template_name(self)->str: index = self.ui.comboBoxTemplate.currentIndex() if index == 0: return "" if index <= len(ray.FACTORY_SESSION_TEMPLATES): return '///' + ray.FACTORY_SESSION_TEMPLATES[index-1] return self.ui.comboBoxTemplate.currentText() class AbstractSaveTemplateDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.save_template_session.Ui_DialogSaveTemplateSession() self.ui.setupUi(self) self._server_will_accept = False self._update_template_text = _translate( "session template", "Update the template") self._create_template_text = self.ui.pushButtonAccept.text() self._overwrite_message_box = QMessageBox( QMessageBox.Question, _translate( 'session template', 'Overwrite Template ?'), '', QMessageBox.Yes | QMessageBox.No, self) self.template_list = [] self.ui.lineEdit.textEdited.connect(self._text_edited) self.ui.pushButtonAccept.clicked.connect(self._verify_and_accept) self.ui.pushButtonAccept.setEnabled(False) def _text_edited(self, text): if '/' in text: self.ui.lineEdit.setText(text.replace('/', '⁄')) if self.ui.lineEdit.text() in self.template_list: self.ui.pushButtonAccept.setText(self._update_template_text) else: self.ui.pushButtonAccept.setText(self._create_template_text) self._allow_ok_button() def _allow_ok_button(self, text=''): self.ui.pushButtonAccept.setEnabled( bool(self._server_will_accept and self.ui.lineEdit.text())) def _verify_and_accept(self): template_name = self.get_template_name() if template_name in self.template_list: self._overwrite_message_box.setText( _translate( 'session_template', 'Template %s already exists.\nOverwrite it ?') % template_name) self._overwrite_message_box.exec() if (self._overwrite_message_box.clickedButton() == self._overwrite_message_box.button(QMessageBox.No)): return self.accept() def _add_templates_to_list(self, template_list): self.template_list += template_list for template in template_list: if template == self.ui.lineEdit.text(): self.ui.pushButtonAccept.setText(self._update_template_text) break def get_template_name(self)->str: return self.ui.lineEdit.text() class SaveTemplateSessionDialog(AbstractSaveTemplateDialog): def __init__(self, parent): AbstractSaveTemplateDialog.__init__(self, parent) self.ui.toolButtonClientIcon.setVisible(False) self.ui.labelLabel.setText(self.session.get_short_path()) self.signaler.session_template_found.connect(self._add_templates_to_list) self.to_daemon('/ray/server/list_session_templates') self._server_status_changed(self.session.server_status) def _server_status_changed(self, server_status): self._server_will_accept = bool(server_status == ray.ServerStatus.READY) if server_status == ray.ServerStatus.OFF: self._overwrite_message_box.reject() self.reject() self._allow_ok_button() class SaveTemplateClientDialog(AbstractSaveTemplateDialog): def __init__(self, parent, client): AbstractSaveTemplateDialog.__init__(self, parent) self.ui.labelSessionTitle.setVisible(False) self.ui.toolButtonClientIcon.setIcon( get_app_icon(client.icon, self)) self.ui.labelLabel.setText(client.prettier_name()) self.ui.pushButtonAccept.setEnabled(False) self.ui.labelNewTemplateName.setText( _translate( 'new client template', "New application template name :")) self.signaler.user_client_template_found.connect( self._add_templates_to_list) self.to_daemon('/ray/server/list_user_client_templates') self.ui.lineEdit.setText(client.template_origin) self.ui.lineEdit.selectAll() self.ui.lineEdit.setFocus() self._server_status_changed(self.session.server_status) def _server_status_changed(self, server_status): self._server_will_accept = bool( server_status not in ( ray.ServerStatus.OFF, ray.ServerStatus.CLOSE) and not self.server_copying) if server_status in (ray.ServerStatus.OFF, ray.ServerStatus.CLOSE): self._overwrite_message_box.reject() self.reject() self._allow_ok_button() class ClientTrashDialog(ChildDialog): def __init__(self, parent, client_data): ChildDialog.__init__(self, parent) self.ui = ui.client_trash.Ui_Dialog() self.ui.setupUi(self) self.client_data = client_data self.ui.labelPrettierName.setText(self.client_data.prettier_name()) self.ui.labelDescription.setText(self.client_data.description) self.ui.labelExecutable.setText(self.client_data.executable_path) self.ui.labelId.setText(self.client_data.client_id) self.ui.toolButtonIcon.setIcon(QIcon.fromTheme(self.client_data.icon)) self.ui.toolButtonAdvanced.clicked.connect(self._show_properties) self.ui.pushButtonRemove.clicked.connect(self._remove_client) self.ui.pushButtonCancel.setFocus() self._remove_client_message_box = QMessageBox( QMessageBox.Warning, _translate('trashed_client', 'Remove definitely'), _translate('trashed_client', "Are you sure to want to remove definitely this client and all its files ?"), QMessageBox.Ok | QMessageBox.Cancel, self ) self._remove_client_message_box.setDefaultButton(QMessageBox.Cancel) def _server_status_changed(self, server_status): if server_status in (ray.ServerStatus.CLOSE, ray.ServerStatus.OFF, ray.ServerStatus.OUT_SAVE, ray.ServerStatus.OUT_SNAPSHOT, ray.ServerStatus.WAIT_USER): self._remove_client_message_box.reject() self.reject() def _remove_client(self): self._remove_client_message_box.exec() if (self._remove_client_message_box.clickedButton() != self._remove_client_message_box.button(QMessageBox.Ok)): return self.to_daemon( '/ray/trashed_client/remove_definitely', self.client_data.client_id) self.reject() def _show_properties(self): properties_dialog = client_properties_dialog.ClientPropertiesDialog.create( self, self.client_data) properties_dialog.update_contents() properties_dialog.lock_widgets() properties_dialog.show() class AbortSessionDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.abort_session.Ui_AbortSession() self.ui.setupUi(self) self.ui.pushButtonAbort.clicked.connect(self.accept) self.ui.pushButtonCancel.clicked.connect(self.reject) self.ui.pushButtonCancel.setFocus(Qt.OtherFocusReason) self._server_status_changed(self.session.server_status) def _server_status_changed(self, server_status): self.ui.pushButtonAbort.setEnabled( not bool( server_status in ( ray.ServerStatus.CLOSE, ray.ServerStatus.OFF, ray.ServerStatus.COPY))) if server_status == ray.ServerStatus.OFF: self.reject() class AbortServerCopyDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.abort_copy.Ui_Dialog() self.ui.setupUi(self) self.signaler.server_progress.connect(self._set_progress) self._server_status_changed(self.session.server_status) def _server_status_changed(self, server_status): if server_status not in ( ray.ServerStatus.PRECOPY, ray.ServerStatus.COPY): self.reject() def _set_progress(self, progress: float): self.ui.progressBar.setValue(progress * 100) class AbortClientCopyDialog(ChildDialog): def __init__(self, parent, client_id: str): ChildDialog.__init__(self, parent) self.ui = ui.abort_copy.Ui_Dialog() self.ui.setupUi(self) self._client_id = client_id self.signaler.client_progress.connect(self._set_progress) def _set_progress(self, client_id: str, progress: float): if client_id != self._client_id: return self.ui.progressBar.setValue(progress * 100) def _server_status_changed(self, server_status): if not self.server_copying: self.reject() class SessionNotesDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.session_notes.Ui_Dialog() self.ui.setupUi(self) if RS.settings.value('SessionNotes/geometry'): self.restoreGeometry(RS.settings.value('SessionNotes/geometry')) if RS.settings.value('SessionNotes/position'): self.move(RS.settings.value('SessionNotes/position')) self._message_box = None self.update_session() self.ui.plainTextEdit.textChanged.connect(self._text_edited) # use a timer to prevent osc message each time a letter is written # here, a message is sent when user made not change during 400ms self._timer_text = QTimer() self._timer_text.setInterval(400) self._timer_text.setSingleShot(True) self._timer_text.timeout.connect(self._send_notes) self.server_off = False self._anti_timer = False self.notes_updated() def _server_status_changed(self, server_status): if server_status == ray.ServerStatus.OFF: self.server_off = True if self._message_box is not None: self._message_box.close() self.close() else: self.server_off = False def _text_edited(self): if not self._anti_timer: self._timer_text.start() self._anti_timer = False def _send_notes(self): notes = self.ui.plainTextEdit.toPlainText() if len(notes) >= 65000: self._message_box = QMessageBox( QMessageBox.Critical, _translate('session_notes', 'Too long notes'), _translate('session_notes', "

Because notes are spread to the OSC server,
they can't be longer than 65000 characters.
Sorry !

"), QMessageBox.Cancel, self) self._message_box.exec() self.ui.plainTextEdit.setPlainText(notes[:64999]) return self.session.notes = notes self.to_daemon('/ray/session/set_notes', self.session.notes) def update_session(self): self.setWindowTitle(_translate('notes_dialog', "%s Notes - %s") % (ray.APP_TITLE, self.session.name)) self.ui.labelSessionName.setText(self.session.name) def notes_updated(self): self._anti_timer = True self.ui.plainTextEdit.setPlainText(self.session.notes) def closeEvent(self, event): RS.settings.setValue('SessionNotes/geometry', self.saveGeometry()) RS.settings.setValue('SessionNotes/position', self.pos()) if not self.server_off: self.to_daemon('/ray/session/hide_notes') ChildDialog.closeEvent(self, event) class OpenNsmSessionInfoDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.nsm_open_info.Ui_Dialog() self.ui.setupUi(self) self.ui.checkBox.stateChanged.connect(self._show_this) def _show_this(self, state: bool): RS.set_hidden(RS.HD_OpenNsmSession, bool(state)) class QuitAppDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.quit_app.Ui_DialogQuitApp() self.ui.setupUi(self) self.ui.pushButtonCancel.setFocus(Qt.OtherFocusReason) self.ui.pushButtonSaveQuit.clicked.connect(self._close_session) self.ui.pushButtonQuitNoSave.clicked.connect(self._abort_session) self.ui.pushButtonDaemon.clicked.connect(self._leave_daemon_running) original_text = self.ui.labelMainText.text() self.ui.labelMainText.setText( original_text % ('%s' % self.session.name)) if CommandLineArgs.under_nsm: self.ui.pushButtonDaemon.setVisible(False) self._server_status_changed(self.session.server_status) def _server_status_changed(self, server_status): if server_status == ray.ServerStatus.OFF: self.accept() return self.ui.pushButtonSaveQuit.setEnabled( bool(server_status == ray.ServerStatus.READY)) self.ui.pushButtonQuitNoSave.setEnabled( bool(server_status != ray.ServerStatus.CLOSE)) def _close_session(self): self.to_daemon('/ray/session/close') def _abort_session(self): self.to_daemon('/ray/session/abort') def _leave_daemon_running(self): if CommandLineArgs.under_nsm: return self.daemon_manager.disannounce() QTimer.singleShot(10, QGuiApplication.quit) class WrongVersionLocalDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.quit_app.Ui_DialogQuitApp() self.ui.setupUi(self) self.ui.pushButtonCancel.setVisible(False) self.ui.pushButtonSaveQuit.clicked.connect(self._close_session) self.ui.pushButtonQuitNoSave.clicked.connect(self._abort_session) self.ui.pushButtonDaemon.clicked.connect(self._leave_daemon_running) #original_text = self.ui.labelMainText.text() #self.ui.labelMainText.setText( #original_text % #('%s' % #self.session.name)) self.ui.labelMainText.setText( _translate( 'wrong_version', "The running daemon has not the same version than the interface\n" "RaySession will quit now.\n\n" "What do you want to do with the current session ?")) def _close_session(self): # can make the GUI freeze a little # but the GUI will quit just after # and this case is rare enough to be acceptable subprocess.run(['ray_control', 'close']) self.accept() def _abort_session(self): # see _close_session subprocess.run(['ray_control', 'abort']) self.accept() def _leave_daemon_running(self): QTimer.singleShot(10, QGuiApplication.quit) class AboutRaySessionDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.about_raysession.Ui_DialogAboutRaysession() self.ui.setupUi(self) all_text = self.ui.labelRayAndVersion.text() self.ui.labelRayAndVersion.setText(all_text % ray.VERSION) class NewExecutableDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.new_executable.Ui_DialogNewExecutable() self.ui.setupUi(self) self.ui.groupBoxAdvanced.setVisible(False) self.resize(0, 0) self.ui.labelPrefixMode.setToolTip( self.ui.comboBoxPrefixMode.toolTip()) self.ui.labelClientId.setToolTip(self.ui.lineEditClientId.toolTip()) self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.ui.lineEdit.setFocus(Qt.OtherFocusReason) self.ui.lineEdit.textChanged.connect(self._check_allow) self.ui.checkBoxNsm.stateChanged.connect(self._check_allow) self.ui.lineEditPrefix.setEnabled(False) self.ui.toolButtonAdvanced.clicked.connect(self._show_advanced) self.ui.comboBoxPrefixMode.addItem( _translate('new_executable', 'Custom')) self.ui.comboBoxPrefixMode.addItem( _translate('new_executable', 'Client Name')) self.ui.comboBoxPrefixMode.addItem( _translate('new_executable', 'Session Name')) self.ui.comboBoxPrefixMode.setCurrentIndex(2) self.ui.comboBoxPrefixMode.currentIndexChanged.connect( self._prefix_mode_changed) self.signaler.new_executable.connect(self._add_executable_to_completer) self.to_daemon('/ray/server/list_path') self.exec_list = [] self._completer = QCompleter(self.exec_list) self.ui.lineEdit.setCompleter(self._completer) self.ui.lineEdit.returnPressed.connect(self._close_now) self._server_status_changed(self.session.server_status) def _server_status_changed(self, server_status): if server_status in (ray.ServerStatus.OUT_SAVE, ray.ServerStatus.OUT_SNAPSHOT, ray.ServerStatus.WAIT_USER, ray.ServerStatus.CLOSE, ray.ServerStatus.OFF): self.reject() def _show_advanced(self): self.ui.groupBoxAdvanced.setVisible(True) self.ui.toolButtonAdvanced.setVisible(False) def _prefix_mode_changed(self, index: int): self.ui.lineEditPrefix.setEnabled(bool(index == 0)) def _add_executable_to_completer(self, executable_list): self.exec_list += executable_list self.exec_list.sort() del self._completer self._completer = QCompleter(self.exec_list) self.ui.lineEdit.setCompleter(self._completer) def _is_allowed(self): nsm = self.ui.checkBoxNsm.isChecked() text = self.ui.lineEdit.text() allow = bool(bool(text) and (not nsm or text in self.exec_list)) return allow def _check_allow(self): allow = self._is_allowed() self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(allow) def _close_now(self): if self._is_allowed(): self.accept() def get_selection(self)->tuple: return (self.ui.lineEdit.text(), self.ui.checkBoxStartClient.isChecked(), not self.ui.checkBoxNsm.isChecked(), self.ui.comboBoxPrefixMode.currentIndex(), self.ui.lineEditPrefix.text(), self.ui.lineEditClientId.text(), self.ui.checkBoxJackNaming.isChecked()) class StopClientDialog(ChildDialog): def __init__(self, parent, client_id): ChildDialog.__init__(self, parent) self.ui = ui.stop_client.Ui_Dialog() self.ui.setupUi(self) self._client_id = client_id self._wait_for_save = False self.client = self.session.get_client(client_id) if self.client: text = self.ui.label.text() % self.client.prettier_name() if not self.client.has_dirty: minutes = int((time.time() - self.client.last_save) / 60) text = _translate( 'client_stop', "%s seems to has not been saved for %i minute(s).
Do you really want to stop it ?") \ % (self.client.prettier_name(), minutes) self.ui.label.setText(text) self.client.status_changed.connect(self._server_updates_client_status) self.ui.pushButtonSaveStop.clicked.connect(self._save_and_stop) self.ui.checkBox.stateChanged.connect(self._check_box_clicked) def _save_and_stop(self): self._wait_for_save = True self.to_daemon('/ray/client/save', self._client_id) def _check_box_clicked(self, state): self.client.check_last_save = not bool(state) self.client.send_properties_to_daemon() def _server_updates_client_status(self, status: int): if status in (ray.ClientStatus.STOPPED, ray.ClientStatus.REMOVED): self.reject() return if status == ray.ClientStatus.READY and self._wait_for_save: self._wait_for_save = False self.accept() class StopClientNoSaveDialog(ChildDialog): def __init__(self, parent, client_id): ChildDialog.__init__(self, parent) self.ui = ui.stop_client_no_save.Ui_Dialog() self.ui.setupUi(self) self.client = self.session.get_client(client_id) if self.client: text = self.ui.label.text() % self.client.prettier_name() self.ui.label.setText(text) self.client.status_changed.connect(self._server_updates_client_status) self.ui.checkBox.stateChanged.connect(self._check_box_clicked) self.ui.pushButtonCancel.setFocus(True) def _server_updates_client_status(self, status: int): if status in (ray.ClientStatus.STOPPED, ray.ClientStatus.REMOVED): self.reject() return def _check_box_clicked(self, state): self.client.check_last_save = not bool(state) self.client.send_properties_to_daemon() class ClientRenameDialog(ChildDialog): def __init__(self, parent, client): ChildDialog.__init__(self, parent) self.ui = ui.client_rename.Ui_Dialog() self.ui.setupUi(self) self.client = client self.ui.toolButtonIcon.setIcon(get_app_icon(client.icon, self)) self.ui.labelClientLabel.setText(client.prettier_name()) self.ui.lineEdit.setText(client.prettier_name()) self.ui.lineEdit.selectAll() self.ui.lineEdit.setFocus() def get_new_label(self)->str: return self.ui.lineEdit.text() class SnapShotProgressDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.snapshot_progress.Ui_Dialog() self.ui.setupUi(self) self.signaler.server_progress.connect(self.server_progress) def _server_status_changed(self, server_status): self.close() def server_progress(self, value): self.ui.progressBar.setValue(value * 100) class ScriptInfoDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.script_info.Ui_Dialog() self.ui.setupUi(self) def set_info_label(self, text: str): self.ui.infoLabel.setText(text) def should_be_removed(self): return False class ScriptUserActionDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.script_user_action.Ui_Dialog() self.ui.setupUi(self) self.ui.buttonBox.clicked.connect(self._button_box_clicked) self.ui.infoLabel.setVisible(False) self.ui.infoLine.setVisible(False) self._is_terminated = False def _validate(self): self.to_daemon('/reply', '/ray/gui/script_user_action', 'Dialog window validated') self._is_terminated = True self.accept() def _abort(self): self.to_daemon('/error', '/ray/gui/script_user_action', ray.Err.ABORT_ORDERED, 'Script user action aborted!') self._is_terminated = True self.accept() def _button_box_clicked(self, button): if button == self.ui.buttonBox.button(QDialogButtonBox.Yes): self._validate() elif button == self.ui.buttonBox.button(QDialogButtonBox.Ignore): self._abort() def set_main_text(self, text: str): self.ui.label.setText(text) def should_be_removed(self): return self._is_terminated class SessionScriptsInfoDialog(ChildDialog): def __init__(self, parent, session_path): ChildDialog.__init__(self, parent) self.ui = ui.session_scripts_info.Ui_Dialog() self.ui.setupUi(self) scripts_dir = "%s/%s" % (session_path, ray.SCRIPTS_DIR) parent_path = os.path.dirname(session_path) parent_scripts = "%s/%s" % (parent_path, ray.SCRIPTS_DIR) session_scripts_text = self.ui.textSessionScripts.toHtml() self.ui.textSessionScripts.setHtml( session_scripts_text % (scripts_dir, parent_scripts, parent_path)) def not_again_value(self)->bool: return self.ui.checkBoxNotAgain.isChecked() class JackConfigInfoDialog(ChildDialog): def __init__(self, parent, session_path): ChildDialog.__init__(self, parent) self.ui = ui.jack_config_info.Ui_Dialog() self.ui.setupUi(self) scripts_dir = "%s/%s" % (session_path, ray.SCRIPTS_DIR) parent_path = os.path.dirname(session_path) parent_scripts = "%s/%s" % (parent_path, ray.SCRIPTS_DIR) session_scripts_text = self.ui.textSessionScripts.toHtml() self.ui.textSessionScripts.setHtml( session_scripts_text % (scripts_dir, parent_scripts, parent_path)) def not_again_value(self)->bool: return self.ui.checkBoxNotAgain.isChecked() def auto_start_value(self)->bool: return self.ui.checkBoxAutoStart.isChecked() class DaemonUrlWindow(ChildDialog): def __init__(self, parent, err_code, ex_url): ChildDialog.__init__(self, parent) self.ui = ui.daemon_url.Ui_Dialog() self.ui.setupUi(self) self.ui.lineEdit.textChanged.connect(self._allow_url) error_text = '' if err_code == ErrDaemon.NO_ANNOUNCE: error_text = _translate( "url_window", "

daemon at
%s
didn't announce !

") % ex_url elif err_code == ErrDaemon.NOT_OFF: error_text = _translate( "url_window", "

daemon at
%s
has a loaded session.
It can't be used for slave session

") % ex_url elif err_code == ErrDaemon.WRONG_ROOT: error_text = _translate( "url_window", "

daemon at
%s
uses an other session root folder !<.p>") % ex_url elif err_code == ErrDaemon.FORBIDDEN_ROOT: error_text = _translate( "url_window", "

daemon at
%s
uses a forbidden session root folder !<.p>") % ex_url elif err_code == ErrDaemon.WRONG_VERSION: error_text = _translate( "url_window", "

daemon at
%s
uses another %s version.<.p>") % (ex_url, ray.APP_TITLE) else: error_text = _translate("url window", "

To run a network session,
open a terminal on another computer of this network.
Launch ray-daemon on port 1234 (for example)
by typing the command :

ray-daemon -p 1234

Then paste below the first url
that ray-daemon gives you at startup.

") self.ui.labelError.setText(error_text) self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.tried_urls = ray.get_list_in_settings(RS.settings, 'network/tried_urls') last_tried_url = RS.settings.value('network/last_tried_url', '', type=str) self._completer = QCompleter(self.tried_urls) self.ui.lineEdit.setCompleter(self._completer) if ex_url: self.ui.lineEdit.setText(ex_url) elif last_tried_url: self.ui.lineEdit.setText(last_tried_url) def _allow_url(self, text: str): if not text: self.ui.lineEdit.completer().complete() self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) return if not text.startswith('osc.udp://'): self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) return try: addr = ray.get_liblo_address(text) self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True) except BaseException: self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) def get_url(self): return self.ui.lineEdit.text() class WaitingCloseUserDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.waiting_close_user.Ui_Dialog() self.ui.setupUi(self) if is_dark_theme(self): self.ui.labelSaveIcon.setPixmap( QPixmap(':scalable/breeze-dark/document-nosave.svg')) self.ui.pushButtonOk.setFocus(True) self.ui.pushButtonUndo.clicked.connect(self._undo_close) self.ui.pushButtonSkip.clicked.connect(self._skip) self.ui.checkBox.setChecked(not RS.is_hidden(RS.HD_WaitCloseUser)) self.ui.checkBox.clicked.connect(self._check_box_clicked) def _server_status_changed(self, server_status): if server_status != ray.ServerStatus.WAIT_USER: self.accept() def _undo_close(self): self.to_daemon('/ray/session/cancel_close') def _skip(self): self.to_daemon('/ray/session/skip_wait_user') def _check_box_clicked(self, state): RS.set_hidden(RS.HD_WaitCloseUser, bool(state)) class CanvasPortInfoDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.canvas_port_info.Ui_Dialog() self.ui.setupUi(self) def set_infos(self, port_full_name: str, port_uuid: int, port_type: str, port_flags: str, pretty_name: str, port_order: int, portgroup_name: str): self.ui.lineEditFullPortName.setText(port_full_name) self.ui.lineEditUuid.setText(str(port_uuid)) self.ui.labelPortType.setText(port_type) self.ui.labelPortFlags.setText(port_flags) self.ui.labelPrettyName.setText(pretty_name) self.ui.labelPortOrder.setText(port_order) self.ui.labelPortGroup.setText(portgroup_name) if not (pretty_name or port_order or portgroup_name): self.ui.groupBoxMetadatas.setVisible(False) class DonationsDialog(ChildDialog): def __init__(self, parent, display_no_again): ChildDialog.__init__(self, parent) self.ui = ui.donations.Ui_Dialog() self.ui.setupUi(self) self.ui.checkBox.setVisible(display_no_again) self.ui.checkBox.clicked.connect(self._check_box_clicked) def _check_box_clicked(self, state): RS.set_hidden(RS.HD_Donations, state) class SystrayCloseDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.systray_close.Ui_Dialog() self.ui.setupUi(self) def not_again(self)->bool: return self.ui.checkBox.isChecked() class SystrayManagement(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.systray_management.Ui_Dialog() self.ui.setupUi(self) self.ui.groupBoxSystray.toggled.connect( self.ui.checkBoxOnlySessionRunning.setEnabled) def set_systray_mode(self, systray_mode: int): self.ui.groupBoxSystray.setChecked( systray_mode != ray.Systray.OFF) self.ui.checkBoxOnlySessionRunning.setChecked( systray_mode == ray.Systray.SESSION_ONLY) def set_wild_shutdown(self, wild_shutdown: bool): self.ui.checkBoxShutdown.setChecked(wild_shutdown) def set_reversed_state(self, reversed: bool): self.ui.checkBoxReversedMenu.setChecked(reversed) def get_systray_mode(self)->int: if self.ui.groupBoxSystray.isChecked(): if self.ui.checkBoxOnlySessionRunning.isChecked(): return ray.Systray.SESSION_ONLY return ray.Systray.ALWAYS return ray.Systray.OFF def wild_shutdown(self)->bool: return self.ui.checkBoxShutdown.isChecked() def menu_should_be_reversed(self)->bool: return self.ui.checkBoxReversedMenu.isChecked() class StartupDialog(ChildDialog): ACTION_NO = 0 ACTION_NEW = 1 ACTION_OPEN = 2 def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.startup_dialog.Ui_Dialog() self.ui.setupUi(self) self._clicked_action = self.ACTION_NO self.ui.listWidgetRecentSessions.itemDoubleClicked.connect( self.accept) for recent_session in self.session.recent_sessions: session_item = QListWidgetItem(recent_session.replace('/', ' / '), self.ui.listWidgetRecentSessions) session_item.setData(Qt.UserRole, recent_session) self.ui.listWidgetRecentSessions.addItem(session_item) self.ui.listWidgetRecentSessions.setMinimumHeight( 30 * len(self.session.recent_sessions)) self.ui.listWidgetRecentSessions.setCurrentRow(0) self.ui.pushButtonNewSession.clicked.connect( self._new_session_clicked) self.ui.pushButtonOpenSession.clicked.connect( self._open_session_clicked) #self.ui.buttonBox.key_event.connect(self._up_down_pressed) self.ui.pushButtonNewSession.focus_on_list.connect( self._focus_on_list) self.ui.pushButtonOpenSession.focus_on_list.connect( self._focus_on_list) self.ui.pushButtonNewSession.focus_on_open.connect( self._focus_on_open) self.ui.pushButtonOpenSession.focus_on_new.connect( self._focus_on_new) self.ui.listWidgetRecentSessions.setFocus(Qt.OtherFocusReason) def _server_status_changed(self, server_status): if server_status != ray.ServerStatus.OFF: self.reject() def _new_session_clicked(self): self._clicked_action = self.ACTION_NEW self.reject() def _open_session_clicked(self): self._clicked_action = self.ACTION_OPEN self.reject() def _focus_on_list(self): self.ui.listWidgetRecentSessions.setFocus(Qt.OtherFocusReason) def _focus_on_new(self): self.ui.pushButtonNewSession.setFocus(Qt.OtherFocusReason) def _focus_on_open(self): self.ui.pushButtonOpenSession.setFocus(Qt.OtherFocusReason) def not_again_value(self)->bool: return not self.ui.checkBox.isChecked() def get_selected_session(self)->str: current_item = self.ui.listWidgetRecentSessions.currentItem() if current_item: return current_item.data(Qt.UserRole) return '' def get_clicked_action(self)->int: return self._clicked_action def keyPressEvent(self, event): if event.key() == Qt.Key_Left: self.ui.pushButtonNewSession.setFocus(Qt.OtherFocusReason) elif event.key() == Qt.Key_Right: self.ui.pushButtonOpenSession.setFocus(Qt.OtherFocusReason) elif event.key() in (Qt.Key_Up, Qt.Key_Down): self.ui.listWidgetRecentSessions.setFocus(Qt.OtherFocusReason) if QApplication.keyboardModifiers() & Qt.ControlModifier: if event.key() == Qt.Key_N: self._new_session_clicked() elif event.key() == Qt.Key_O: self._open_session_clicked() ChildDialog.keyPressEvent(self, event) class ErrorDialog(ChildDialog): def __init__(self, parent, message): ChildDialog.__init__(self, parent) self.ui = ui.error_dialog.Ui_Dialog() self.ui.setupUi(self) self.ui.label.setText(message) RaySession-0.12.2/src/gui/client_properties_dialog.py000066400000000000000000000502461417052567600227150ustar00rootroot00000000000000import os import signal from PyQt5.QtCore import QTimer, QFile from PyQt5.QtWidgets import QFileDialog, QFrame import ray from gui_tools import _translate, client_status_string, get_app_icon from child_dialogs import ChildDialog import ui.ray_hack_copy import ui.client_properties import ui.nsm_properties import ui.ray_hack_properties import ui.ray_net_properties class RayHackCopyDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.ray_hack_copy.Ui_Dialog() self.ui.setupUi(self) self.rename_file = False self.ui.pushButtonCopyRename.clicked.connect(self._set_rename_file) def _set_rename_file(self): self.rename_file = True self.accept() def set_file(self, path): self.ui.labelFileNotInFolder.setText( _translate( 'Dialog', '%s is not in client working directory') % ('' + os.path.basename(path) + '')) class ClientPropertiesDialog(ChildDialog): def __init__(self, parent, client): ChildDialog.__init__(self, parent) self.ui = ui.client_properties.Ui_Dialog() self.ui.setupUi(self) self.client = client self.setWindowTitle( _translate('client_properties', "Properties of client %s") % client.client_id) self._acceptable_arguments = True self._current_status = ray.ClientStatus.STOPPED self.ui.lineEditIcon.textEdited.connect(self._change_icon_with_text) self.ui.pushButtonSaveChanges.clicked.connect(self._save_changes) self.ui.tabWidget.setCurrentIndex(0) def _change_icon_with_text(self, text: str): icon = get_app_icon(text, self) self.ui.toolButtonIcon.setIcon(icon) def _get_capacities_line(self): capas_en = [c for c in self.client.capabilities.split(':') if c] capas_tr = [] for capa in capas_en: if capa == 'switch': capa_tr = _translate('capabilities', 'switch') elif capa == 'dirty': capa_tr = _translate('capabilities', 'dirty') elif capa == 'optional-gui': capa_tr = _translate('capabilities', 'optional-gui') else: capa_tr = capa capas_tr.append(capa_tr) return '\n'.join(capas_tr) def _save_changes(self): self.client.label = self.ui.lineEditLabel.text() self.client.description = \ self.ui.plainTextEditDescription.toPlainText() self.client.icon = self.ui.lineEditIcon.text() self.client.check_last_save = self.ui.checkBoxSaveStop.isChecked() self.client.ignored_extensions = \ self.ui.lineEditIgnoredExtensions.text() self.client.send_properties_to_daemon() # better for user to wait a little before close the window QTimer.singleShot(150, self.accept) @staticmethod def create(window, client): if client.protocol == ray.Protocol.NSM: return NsmClientPropertiesDialog(window, client) if client.protocol == ray.Protocol.RAY_HACK: return RayHackClientPropertiesDialog(window, client) if client.protocol == ray.Protocol.RAY_NET: return RayNetClientPropertiesDialog(window, client) return ClientPropertiesDialog(window, client) def lock_widgets(self): self.ui.lineEditIcon.setReadOnly(True) self.ui.lineEditLabel.setReadOnly(True) self.ui.lineEditIgnoredExtensions.setReadOnly(True) self.ui.checkBoxSaveStop.setEnabled(False) self.ui.pushButtonSaveChanges.setVisible(False) def set_for_template(self, template_name: str): self.lock_widgets() self.setWindowTitle( _translate('client_properties', "Properties of template %s") % template_name) def set_on_second_tab(self): self.ui.tabWidget.setCurrentIndex(1) def update_status(self, status): pass def update_contents(self): self.ui.labelId.setText(self.client.client_id) self.ui.labelProtocol.setText(ray.protocol_to_str(self.client.protocol)) self.ui.lineEditIcon.setText(self.client.icon) self.ui.lineEditLabel.setText(self.client.label) self.ui.plainTextEditDescription.setPlainText(self.client.description) self.ui.checkBoxSaveStop.setChecked(self.client.check_last_save) self.ui.lineEditIgnoredExtensions.setText( self.client.ignored_extensions) self._change_icon_with_text(self.client.icon) class NsmClientPropertiesDialog(ClientPropertiesDialog): def __init__(self, parent, client): ClientPropertiesDialog.__init__(self, parent, client) self.nsmui_frame = QFrame() self.nsmui = ui.nsm_properties.Ui_Frame() self.nsmui.setupUi(self.nsmui_frame) self.ui.verticalLayoutProtocol.addWidget(self.nsmui_frame) self.ui.tabWidget.setTabText(1, 'NSM') def _save_changes(self): self.client.executable_path = self.nsmui.lineEditExecutable.text() self.client.arguments = self.nsmui.lineEditArguments.text() self.client.pre_env = self.nsmui.lineEditEnviron.text() ClientPropertiesDialog._save_changes(self) def _change_icon_with_text(self, text: str): icon = get_app_icon(text, self) self.ui.toolButtonIcon.setIcon(icon) self.nsmui.toolButtonIcon.setIcon(icon) def lock_widgets(self): ClientPropertiesDialog.lock_widgets(self) self.nsmui.lineEditExecutable.setReadOnly(True) self.nsmui.lineEditArguments.setReadOnly(True) for widget in (self.nsmui.labelCapabilitiesTitle, self.nsmui.labelCapabilitiesColon, self.nsmui.labelCapabilities, self.nsmui.labelExecutableWarning): widget.setVisible(False) def update_contents(self): ClientPropertiesDialog.update_contents(self) self.nsmui.labelClientName.setText(self.client.name) self.nsmui.labelCapabilities.setText(self._get_capacities_line()) self.nsmui.lineEditExecutable.setText(self.client.executable_path) self.nsmui.lineEditArguments.setText(self.client.arguments) self.nsmui.lineEditEnviron.setText(self.client.pre_env) class RayHackClientPropertiesDialog(ClientPropertiesDialog): def __init__(self, parent, client): ClientPropertiesDialog.__init__(self, parent, client) self.ray_hack_frame = QFrame() self.rhack = ui.ray_hack_properties.Ui_Frame() self.rhack.setupUi(self.ray_hack_frame) self.config_file = "" self.ui.verticalLayoutProtocol.addWidget(self.ray_hack_frame) self.ui.tabWidget.setTabText(1, 'Ray-Hack') self.rhack.labelWorkingDir.setText(self._get_work_dir_base()) self.rhack.toolButtonBrowse.setEnabled(self.daemon_manager.is_local) self.rhack.toolButtonBrowse.clicked.connect(self._browse_config_file) self.rhack.lineEditArguments.textChanged.connect( self._line_edit_arguments_changed) self.rhack.lineEditConfigFile.textChanged.connect( self._line_edit_config_file_changed) self.rhack.pushButtonStart.clicked.connect(self._start_client) self.rhack.pushButtonStop.clicked.connect(self._stop_client) self.rhack.pushButtonSave.clicked.connect(self._save_client) self.rhack.comboSaveSig.addItem(_translate('ray_hack', 'None'), 0) self.rhack.comboSaveSig.addItem('SIGUSR1', 10) self.rhack.comboSaveSig.addItem('SIGUSR2', 12) self.rhack.comboSaveSig.currentIndexChanged.connect( self._current_save_sig_changed) self.rhack.comboStopSig.addItem('SIGTERM', 15) self.rhack.comboStopSig.addItem('SIGINT', 2) self.rhack.comboStopSig.addItem('SIGHUP', 1) self.rhack.comboStopSig.addItem('SIGKILL', 9) self.rhack.checkBoxTellUser.stateChanged.connect( self.rhack.checkBoxCloseGracefully.setEnabled) self.rhack.labelError.setVisible(False) self.rhack.pushButtonStart.setEnabled(False) self.rhack.pushButtonStop.setEnabled(False) self.rhack.pushButtonSave.setEnabled(False) self.rhack.groupBoxNoSave.setEnabled(False) self.rhack.groupBoxTestZone.setChecked(False) self.rhack.groupBoxTestZone.toggled.connect( self.rhack.frameTestZone.setEnabled) def _current_save_sig_changed(self, index): self.rhack.groupBoxNoSave.setEnabled( bool(self.rhack.lineEditConfigFile.text() and self.rhack.comboSaveSig.currentData() == 0)) self.update_status(self._current_status) def _change_icon_with_text(self, text: str): icon = get_app_icon(text, self) self.ui.toolButtonIcon.setIcon(icon) self.rhack.toolButtonIcon.setIcon(icon) def _save_changes(self): self.client.ray_hack.config_file = self.rhack.lineEditConfigFile.text() self.client.ray_hack.save_sig = self.rhack.comboSaveSig.currentData() self.client.ray_hack.stop_sig = self.rhack.comboStopSig.currentData() self.client.ray_hack.wait_win = \ self.rhack.checkBoxWaitWindow.isChecked() no_save_level = 0 if self.rhack.checkBoxCloseGracefully.isChecked(): no_save_level = 2 elif self.rhack.checkBoxTellUser.isChecked(): no_save_level = 1 self.client.ray_hack.no_save_level = no_save_level #self.client.ray_hack.close_gracefully = \ #self.rhack.checkBoxCloseGracefully.isChecked() self.client.send_ray_hack() self.client.executable_path = self.rhack.lineEditExecutable.text() self.client.arguments = self.rhack.lineEditArguments.text() self.client.pre_env = self.rhack.lineEditEnviron.text() ClientPropertiesDialog._save_changes(self) def _get_work_dir_base(self)->str: prefix = self.session.name if self.client.prefix_mode == ray.PrefixMode.CLIENT_NAME: prefix = self.client.name elif self.client.prefix_mode == ray.PrefixMode.CUSTOM: prefix = self.client.custom_prefix return "%s.%s" % (prefix, self.client.client_id) def _browse_config_file(self): work_dir_base = self._get_work_dir_base() work_dir = "%s/%s" % (self.session.path, work_dir_base) config_file, ok = QFileDialog.getOpenFileName( self, _translate('Dialog', 'Select File to use as CONFIG_FILE'), work_dir) if not ok: return if not config_file.startswith(work_dir + '/'): qfile = QFile(config_file) if qfile.size() < 20971520: # if file < 20Mb copy_dialog = RayHackCopyDialog(self) copy_dialog.set_file(config_file) copy_dialog.exec() if copy_dialog.result(): if copy_dialog.rename_file: base, pt, extension = os.path.basename( config_file).rpartition('.') config_file = "%s.%s" % (self.session.name, extension) if not base: config_file = self.session.name else: config_file = os.path.basename(config_file) qfile.copy(config_file) self.config_file = os.path.relpath(config_file, work_dir) if (self.session.name and (self.config_file == self.session.name or self.config_file.startswith("%s." % self.session.name))): self.config_file = self.config_file.replace(self.session.name, "$RAY_SESSION_NAME") self.rhack.lineEditConfigFile.setText(self.config_file) def _is_allowed(self): return self._acceptable_arguments def _line_edit_arguments_changed(self, text: str): if ray.shell_line_to_args(text) is not None: self._acceptable_arguments = True self.rhack.lineEditArguments.setStyleSheet('') else: self._acceptable_arguments = False self.rhack.lineEditArguments.setStyleSheet( 'QLineEdit{background: red}') self.rhack.pushButtonStart.setEnabled( bool(self._acceptable_arguments and self._current_status == ray.ClientStatus.STOPPED)) self.ui.pushButtonSaveChanges.setEnabled(self._is_allowed()) def _line_edit_config_file_changed(self, text): if text and not self.rhack.lineEditArguments.text(): self.rhack.lineEditArguments.setText('"$CONFIG_FILE"') elif (not text and self.rhack.lineEditArguments.text() == '"$CONFIG_FILE"'): self.rhack.lineEditArguments.setText('') self.rhack.groupBoxNoSave.setEnabled( bool(text and self.rhack.comboSaveSig.currentData() == 0)) def _start_client(self): executable = self.client.executable_path arguments = self.client.arguments config_file = self.client.ray_hack.config_file self.client.executable_path = self.rhack.lineEditExecutable.text() self.client.arguments = self.rhack.lineEditArguments.text() self.client.ray_hack.config_file = self.rhack.lineEditConfigFile.text() self.client.send_properties_to_daemon() self.to_daemon('/ray/client/resume', self.client.client_id) self.client.executable_path = executable self.client.arguments = arguments self.client.ray_hack.config_file = config_file self.client.send_properties_to_daemon() def _stop_client(self): self.to_daemon('/ray/client/send_signal', self.client.client_id, self.rhack.comboStopSig.currentData()) def _save_client(self): self.to_daemon('/ray/client/send_signal', self.client.client_id, self.rhack.comboSaveSig.currentData()) def lock_widgets(self): ClientPropertiesDialog.lock_widgets(self) self.rhack.lineEditExecutable.setReadOnly(True) self.rhack.lineEditArguments.setReadOnly(True) self.rhack.lineEditConfigFile.setReadOnly(True) self.rhack.checkBoxCloseGracefully.setEnabled(False) self.rhack.checkBoxTellUser.setEnabled(False) self.rhack.checkBoxWaitWindow.setEnabled(False) self.rhack.comboSaveSig.setEnabled(False) self.rhack.comboStopSig.setEnabled(False) self.rhack.groupBoxTestZone.setVisible(False) self.rhack.toolButtonBrowse.setVisible(False) def set_for_template(self, template_name: str): ClientPropertiesDialog.set_for_template(self, template_name) self.rhack.labelWorkingDirTitle.setVisible(False) self.rhack.labelWorkingDir.setVisible(False) def update_status(self, status): self._current_status = status self.rhack.lineEditClientStatus.setText(client_status_string(status)) if status in (ray.ClientStatus.LAUNCH, ray.ClientStatus.OPEN, ray.ClientStatus.SWITCH, ray.ClientStatus.NOOP): self.rhack.pushButtonStart.setEnabled(False) self.rhack.pushButtonStop.setEnabled(True) self.rhack.pushButtonSave.setEnabled(False) elif status == ray.ClientStatus.READY: self.rhack.pushButtonStart.setEnabled(False) self.rhack.pushButtonStop.setEnabled(True) self.rhack.pushButtonSave.setEnabled( bool(self.rhack.comboSaveSig.currentData() != 0)) elif status == ray.ClientStatus.STOPPED: self.rhack.pushButtonStart.setEnabled(self._is_allowed()) self.rhack.pushButtonStop.setEnabled(False) self.rhack.pushButtonSave.setEnabled(False) elif status == ray.ClientStatus.PRECOPY: self.rhack.pushButtonStart.setEnabled(False) self.rhack.pushButtonStart.setEnabled(False) self.rhack.pushButtonSave.setEnabled(False) def update_contents(self): ClientPropertiesDialog.update_contents(self) self.rhack.lineEditExecutable.setText(self.client.executable_path) self.rhack.lineEditArguments.setText(self.client.arguments) self.rhack.lineEditEnviron.setText(self.client.pre_env) self.rhack.lineEditConfigFile.setText( self.client.ray_hack.config_file) save_sig = self.client.ray_hack.save_sig for i in range(self.rhack.comboSaveSig.count()): if self.rhack.comboSaveSig.itemData(i) == save_sig: self.rhack.comboSaveSig.setCurrentIndex(i) break else: try: signal_text = str( signal.Signals(save_sig)).rpartition('.')[2] self.rhack.comboSaveSig.addItem(signal_text, save_sig) self.rhack.comboSaveSig.setCurrentIndex(i+1) except: self.rhack.comboSaveSig.setCurrentIndex(0) stop_sig = self.client.ray_hack.stop_sig for i in range(self.rhack.comboStopSig.count()): if self.rhack.comboStopSig.itemData(i) == stop_sig: self.rhack.comboStopSig.setCurrentIndex(i) break else: try: signal_text = str(signal.Signals( stop_sig)).rpartition('.')[2] self.rhack.comboStopSig.addItem(signal_text, stop_sig) self.rhack.comboStopSig.setCurrentIndex(i+1) except: self.rhack.comboStopSig.setCurrentIndex(0) self.rhack.checkBoxWaitWindow.setChecked( bool(self.client.ray_hack.wait_win)) self.rhack.checkBoxTellUser.setChecked( bool(self.client.ray_hack.no_save_level >= 1)) self.rhack.checkBoxCloseGracefully.setChecked( bool(self.client.ray_hack.no_save_level == 2)) def enable_test_zone(self, yesno: bool): self.rhack.groupBoxTestZone.setChecked(yesno) def hideEvent(self, event): ClientPropertiesDialog.hideEvent(self, event) self.signaler.client_properties_state_changed.emit( self.client.client_id, False) def showEvent(self, event): ClientPropertiesDialog.showEvent(self, event) self.signaler.client_properties_state_changed.emit( self.client.client_id, True) class RayNetClientPropertiesDialog(ClientPropertiesDialog): def __init__(self, parent, client): ClientPropertiesDialog.__init__(self, parent, client) self.ray_net_frame = QFrame() self.rnet = ui.ray_net_properties.Ui_Frame() self.rnet.setupUi(self.ray_net_frame) self.ui.groupBoxSnapshots.setVisible(False) self.ui.verticalLayoutProtocol.addWidget(self.ray_net_frame) self.ui.tabWidget.setTabText(1, 'Ray-Net') def lock_widgets(self): ClientPropertiesDialog.lock_widgets(self) self.rnet.lineEditDaemonUrl.setReadOnly(True) self.rnet.lineEditSessionRoot.setReadOnly(True) self.rnet.lineEditTemplate.setReadOnly(True) def update_contents(self): ClientPropertiesDialog.update_contents(self) self.rnet.labelClientName.setText(self.client.name) self.rnet.labelCapabilities.setText(self._get_capacities_line()) self.rnet.lineEditDaemonUrl.setText(self.client.ray_net.daemon_url) self.rnet.lineEditSessionRoot.setText(self.client.ray_net.session_root) self.rnet.lineEditTemplate.setText(self.client.ray_net.session_template) def _save_changes(self): new_url = self.rnet.lineEditDaemonUrl.text() new_root = self.rnet.lineEditSessionRoot.text() new_template = self.rnet.lineEditTemplate.text() if ray.is_valid_osc_url(new_url): self.client.ray_net.daemon_url = new_url if ray.is_valid_full_path(new_root): self.client.ray_net.session_root = new_root if '/' not in new_template: self.client.ray_net.session_template = new_template self.client.send_ray_net() ClientPropertiesDialog._save_changes(self) def _change_icon_with_text(self, text: str): icon = get_app_icon(text, self) self.ui.toolButtonIcon.setIcon(icon) self.rnet.toolButtonIcon.setIcon(icon) RaySession-0.12.2/src/gui/daemon_manager.py000066400000000000000000000207201417052567600205730ustar00rootroot00000000000000 import os import socket import sys from PyQt5.QtCore import QObject, QProcess, QTimer from PyQt5.QtWidgets import QApplication from liblo import Address import ray from gui_server_thread import GuiServerThread from gui_tools import CommandLineArgs, ErrDaemon, _translate class DaemonManager(QObject): def __init__(self, session): QObject.__init__(self) self.session = session self.signaler = self.session.signaler self.main_win = None self._process = QProcess() if ray.QT_VERSION >= (5, 6): self._process.errorOccurred.connect(self._error_in_process) self._process.setProcessChannelMode(QProcess.ForwardedChannels) self._announce_timer = QTimer() self._announce_timer.setInterval(2000) self._announce_timer.setSingleShot(True) self._announce_timer.timeout.connect(self._announce_timer_out) self._port = None self._is_announced = False self._is_nsm_locked = False self.is_local = True self.launched_before = False self.address = None self.url = '' self.session_root = "" self.signaler.daemon_announce.connect(self._receive_announce) self.signaler.daemon_url_changed.connect(self._change_url) def _error_in_process(self, error): if self.main_win is None: return self.main_win.daemon_crash() def _change_url(self, new_url: str): try: self.set_osc_address(ray.get_liblo_address(new_url)) except BaseException: return self._call_daemon() def _call_daemon(self): if not self.address: # I don't know really why, but it works only with a timer QTimer.singleShot(5, self._show_daemon_url_window) return self._announce_timer.start() server = GuiServerThread.instance() if not server: sys.stderr.write( 'GUI can not call daemon, GUI OSC server is missing.\n') return server.announce() def _show_daemon_url_window(self): self.signaler.daemon_url_request.emit(ErrDaemon.NO_ERROR, self.url) def _announce_timer_out(self): if self.launched_before: self.signaler.daemon_url_request.emit( ErrDaemon.NO_ANNOUNCE, self.url) else: sys.stderr.write( _translate( 'error', "No announce from ray-daemon. RaySession can't works. Sorry.\n")) QApplication.quit() def _receive_announce( self, src_addr, version, server_status, options, session_root, is_net_free): self._announce_timer.stop() if version.split('.')[:2] != ray.VERSION.split('.')[:2]: # works only if the two firsts digits are the same (ex: 0.6) self.signaler.daemon_url_request.emit( ErrDaemon.WRONG_VERSION, self.url) self.disannounce(src_addr) return if (CommandLineArgs.net_session_root and session_root != CommandLineArgs.net_session_root): self.signaler.daemon_url_request.emit( ErrDaemon.WRONG_ROOT, self.url) self.disannounce(src_addr) return if not is_net_free: self.signaler.daemon_url_request.emit( ErrDaemon.FORBIDDEN_ROOT, self.url) self.disannounce(src_addr) return if (CommandLineArgs.out_daemon and server_status != ray.ServerStatus.OFF): self.signaler.daemon_url_request.emit(ErrDaemon.NOT_OFF, self.url) self.disannounce(src_addr) return self._is_announced = True self.address = src_addr self._port = src_addr.port self.url = src_addr.url self.session_root = session_root CommandLineArgs.change_session_root(self.session_root) self._is_nsm_locked = options & ray.Option.NSM_LOCKED if self._is_nsm_locked: if self.main_win is not None: self.main_win.set_nsm_locked(True) elif CommandLineArgs.under_nsm: server = GuiServerThread.instance() server.to_daemon('/ray/server/set_nsm_locked') if self.main_win is not None and self.main_win.waiting_for_patchbay: self.main_win.waiting_for_patchbay = False server = GuiServerThread.instance() server.to_daemon('/ray/server/ask_for_patchbay') self.signaler.daemon_announce_ok.emit() self.session.set_daemon_options(options) def finish_init(self): self.main_win = self.session.main_win def disannounce(self, address=None): if not address: address = self.address if address: server = GuiServerThread.instance() server.disannounce(address) self._port = None self.url = '' del self.address self.address = None self._is_announced = False def set_external(self): self.launched_before = True def set_osc_address(self, address): self.address = address self.launched_before = True self._port = self.address.port self.url = self.address.url self.is_local = bool(self.address.hostname == socket.gethostname()) def start(self): if self.launched_before: self._call_daemon() return if not CommandLineArgs.force_new_daemon: ray_control_process = QProcess() ray_control_process.start( "ray_control", ['get_port_gui_free', CommandLineArgs.session_root]) ray_control_process.waitForFinished(2000) if ray_control_process.exitCode() == 0: port_str_lines = \ ray_control_process.readAllStandardOutput().data().decode('utf-8') port_str = port_str_lines.partition('\n')[0] if port_str and port_str.isdigit(): self.address = Address(int(port_str)) self._port = self.address.port self.url = self.address.url self.launched_before = True self.is_local = True self._call_daemon() sys.stderr.write( "\033[92m%s\033[0m\n" % ( _translate('GUI_daemon', "Connecting GUI to existing ray-daemon port %i") % self._port)) if CommandLineArgs.start_session: server = GuiServerThread.instance() if server: server.send(self.address, '/ray/server/open_session', CommandLineArgs.start_session) return server = GuiServerThread.instance() if not server: sys.stderr.write( "impossible for GUI to launch daemon. server missing.\n") # start process arguments = ['--gui-url', str(server.url), '--gui-pid', str(os.getpid()), '--osc-port', str(self._port), '--session-root', CommandLineArgs.session_root] if CommandLineArgs.start_session: arguments.append('--session') arguments.append(CommandLineArgs.start_session) if CommandLineArgs.debug_only: arguments.append('--debug-only') elif CommandLineArgs.debug: arguments.append('--debug') elif CommandLineArgs.no_client_messages: arguments.append('--no-client-messages') if CommandLineArgs.config_dir: arguments.append('--config-dir') arguments.append(CommandLineArgs.config_dir) self._process.startDetached('ray-daemon', arguments) #self.process.start('konsole', ['-e', 'ray-daemon'] + arguments) def stop(self): if self.launched_before: self.disannounce() QTimer.singleShot(10, QApplication.quit) return server = GuiServerThread.instance() server.to_daemon('/ray/server/quit') QTimer.singleShot(50, QApplication.quit) def set_new_osc_address(self): if not (self.address or self._port): self._port = ray.get_free_osc_port() self.address = Address(self._port) def is_announced(self): return self._is_announced def get_port(self): return self._port RaySession-0.12.2/src/gui/gui_client.py000066400000000000000000000143721417052567600177660ustar00rootroot00000000000000import time import sys from PyQt5.QtCore import QObject, pyqtSignal import ray from gui_server_thread import GuiServerThread from client_properties_dialog import ClientPropertiesDialog class Client(QObject, ray.ClientData): status_changed = pyqtSignal(int) def __init__(self, session, client_id: str, protocol: int): QObject.__init__(self) ray.ClientData.gui_init(self, client_id, protocol) self.session = session self.main_win = self.session.main_win self._previous_status = ray.ClientStatus.STOPPED self.ray_hack = ray.RayHack() self.ray_net = ray.RayNet() self.status = ray.ClientStatus.STOPPED self.has_gui = False self.gui_state = False self.has_dirty = False self.dirty_state = True self.no_save_level = 0 self.last_save = time.time() self.check_last_save = True self.widget = self.main_win.create_client_widget(self) self.properties_dialog = ClientPropertiesDialog.create(self.main_win, self) def set_status(self, status: int): self._previous_status = self.status self.status = status self.status_changed.emit(status) if (not self.has_dirty and self.status == ray.ClientStatus.READY and self._previous_status in ( ray.ClientStatus.OPEN, ray.ClientStatus.SAVE)): self.last_save = time.time() self.widget.update_status(status) self.properties_dialog.update_status(status) def set_gui_enabled(self): self.has_gui = True self.widget.show_gui_button() def set_gui_state(self, state: bool): self.set_gui_enabled() self.gui_state = state self.widget.set_gui_state(state) def set_dirty_state(self, dirty: bool): self.has_dirty = True self.dirty_state = dirty self.widget.set_dirty_state(dirty) def set_no_save_level(self, no_save_level: int): self.no_save_level = no_save_level self.widget.set_no_save_level(no_save_level) def set_progress(self, progress: float): self.widget.set_progress(progress) def allow_kill(self): self.widget.allow_kill() def update_properties(self, *args): self.update(*args) self.widget.update_client_data() def update_ray_hack(self, *args): self.ray_hack.update(*args) self.widget.update_client_data() def update_ray_net(self, *args): self.ray_net.update(*args) self.widget.update_client_data() def send_properties_to_daemon(self): server = GuiServerThread.instance() if not server: sys.stderr.write( 'Server not found. Client %s can not send its properties\n' % self.client_id) return server.to_daemon('/ray/client/update_properties', *ray.ClientData.spread_client(self)) def send_ray_hack(self): if self.protocol != ray.Protocol.RAY_HACK: return server = GuiServerThread.instance() if not server: return server.to_daemon('/ray/client/update_ray_hack_properties', self.client_id, *self.ray_hack.spread()) def send_ray_net(self): if self.protocol != ray.Protocol.RAY_NET: return server = GuiServerThread.instance() if not server: return server.to_daemon('/ray/client/update_ray_net_properties', self.client_id, *self.ray_net.spread()) def show_properties_dialog(self, second_tab=False): self.properties_dialog.update_contents() if second_tab: if self.protocol == ray.Protocol.RAY_HACK: self.properties_dialog.enable_test_zone(True) self.properties_dialog.set_on_second_tab() self.properties_dialog.show() if ray.get_window_manager() != ray.WindowManager.WAYLAND: self.properties_dialog.activateWindow() def re_create_widget(self): del self.widget self.widget = self.main_win.create_client_widget(self) self.widget.update_client_data() if self.has_gui: self.set_gui_enabled() # method not used yet def get_project_path(self)->str: if not self.session.path: return '' prefix = self.session.name if self.prefix_mode == ray.PrefixMode.CLIENT_NAME: prefix = self.name elif self.prefix_mode == ray.PrefixMode.CUSTOM: prefix = self.custom_prefix return "%s/%s.%s" % (self.session.path, prefix, self.client_id) # method not used yet def get_icon_search_path(self)->list: if not self.session.daemon_manager.is_local: return [] project_path = self.get_project_path() if not project_path: return [] search_list = [] main_icon_path = '.local/share/icons' search_list.append("%s/%s" % (search_list, main_icon_path)) for path in ('16x16', '24x24', '32x32', '64x64', 'scalable'): search_list.append("%s/%s/%s" % (project_path, main_icon_path, path)) return search_list def can_be_own_jack_client(self, jack_client_name:str)->bool: if self.status in (ray.ClientStatus.STOPPED, ray.ClientStatus.PRECOPY): return False if jack_client_name == self.jack_client_name: return True if jack_client_name.startswith(self.jack_client_name + '/'): return True if (jack_client_name.startswith(self.jack_client_name + ' (') and ')' in jack_client_name): return True # Carla often puts a .0 at end of client name if it doesn't find # any '.' in jack_client_name jack_client_name = jack_client_name.partition('/')[0] if (not self.jack_client_name.endswith('.' + self.client_id) and jack_client_name == self.jack_client_name + '.0'): return True return False class TrashedClient(ray.ClientData): def __init__(self): self.menu_action = None def set_menu_action(self, menu_action): self.menu_action = menu_action RaySession-0.12.2/src/gui/gui_server_thread.py000066400000000000000000000327341417052567600213470ustar00rootroot00000000000000import os import sys import liblo import ray from gui_tools import CommandLineArgs _instance = None def ray_method(path, types): def decorated(func): @liblo.make_method(path, types) def wrapper(*args, **kwargs): t_thread, t_path, t_args, t_types, src_addr, rest = args if CommandLineArgs.debug: sys.stderr.write( '\033[93mOSC::gui_receives\033[0m %s, %s, %s, %s\n' % (t_path, t_types, t_args, src_addr.url)) if t_thread.stopping: return response = func(*args[:-1], **kwargs) if not response is False: t_thread.signaler.osc_receive.emit(t_path, t_args) return response return wrapper return decorated class GuiServerThread(liblo.ServerThread): def __init__(self): liblo.ServerThread.__init__(self) global _instance _instance = self self.patchbay_addr = None # Try to prevent impossibility to stop server # while receiving messages self.stopping = False self._parrallel_copy_id_queue = [] self._parrallel_new_session_name = '' def stop(self): self.stopping = True if self.patchbay_addr: self.send(self.patchbay_addr, '/ray/patchbay/gui_disannounce') liblo.ServerThread.stop(self) def finish_init(self, session): self.session = session self.signaler = self.session.signaler self.daemon_manager = self.session.daemon_manager # all theses OSC messages are directly treated by # SignaledSession in gui_session.py # in the function with the the name of the message # with '/' replaced with '_' # for example /ray/gui/session/name goes to # _ray_gui_session_name for path_types in ( ('/error', 'sis'), ('/minor_error', 'sis'), ('/ray/gui/server/disannounce', ''), ('/ray/gui/server/nsm_locked', 'i'), ('/ray/gui/server/options', 'i'), ('/ray/gui/server/message', 's'), ('/ray/gui/session/name', 'ss'), ('/ray/gui/session/notes', 's'), ('/ray/gui/session/notes_shown', ''), ('/ray/gui/session/notes_hidden', ''), ('/ray/gui/session/is_nsm', ''), ('/ray/gui/session/renameable', 'i'), ('/ray/gui/client/new', ray.ClientData.sisi()), ('/ray/gui/client/update', ray.ClientData.sisi()), ('/ray/gui/client/ray_hack_update', 's' + ray.RayHack.sisi()), ('/ray/gui/client/switch', 'ss'), ('/ray/gui/client/status', 'si'), ('/ray/gui/client/dirty', 'si'), ('/ray/gui/client/has_optional_gui', 's'), ('/ray/gui/client/gui_visible', 'si'), ('/ray/gui/client/still_running', 's'), ('/ray/gui/client/no_save_level', 'si'), ('/ray/gui/trash/add', ray.ClientData.sisi()), ('/ray/gui/trash/ray_hack_update', 's' + ray.RayHack.sisi()), ('/ray/gui/trash/ray_net_update', 's' + ray.RayNet.sisi()), ('/ray/gui/trash/remove', 's'), ('/ray/gui/trash/clear', ''), ('/ray/gui/favorites/added', 'ssi'), ('/ray/gui/favorites/removed', 'si'), ('/ray/gui/preview/clear', ''), ('/ray/gui/preview/notes', 's'), ('/ray/gui/preview/client/update', ray.ClientData.sisi()), ('/ray/gui/preview/client/ray_hack_update', 's' + ray.RayHack.sisi()), ('/ray/gui/preview/client/ray_net_update', 's' + ray.RayNet.sisi()), ('/ray/gui/preview/client/is_started', 'si'), ('/ray/gui/preview/snapshot', 's'), ('/ray/gui/preview/session_size', 'h'), ('/ray/gui/script_info', 's'), ('/ray/gui/hide_script_info', ''), ('/ray/gui/script_user_action', 's'), ('/ray/gui/hide_script_user_action', ''), ('/ray/gui/patchbay/port_added', 'siih'), ('/ray/gui/patchbay/port_renamed', 'ss'), ('/ray/gui/patchbay/port_removed', 's'), ('/ray/gui/patchbay/connection_added', 'ss'), ('/ray/gui/patchbay/connection_removed', 'ss'), ('/ray/gui/patchbay/server_stopped', ''), ('/ray/gui/patchbay/update_group_position', ray.GroupPosition.sisi()), ('/ray/gui/patchbay/metadata_updated', 'hss'), ('/ray/gui/patchbay/dsp_load', 'i'), ('/ray/gui/patchbay/add_xrun', ''), ('/ray/gui/patchbay/buffer_size', 'i'), ('/ray/gui/patchbay/sample_rate', 'i'), ('/ray/gui/patchbay/server_started', ''), ('/ray/gui/patchbay/big_packets', 'i'), ('/ray/gui/patchbay/server_lose', ''), ('/ray/gui/patchbay/fast_temp_file_memory', 's'), ('/ray/gui/patchbay/fast_temp_file_running', 's'), ('/ray/gui/patchbay/client_name_and_uuid', 'sh')): self.add_method(path_types[0], path_types[1], self._generic_callback) @staticmethod def instance(): return _instance def _generic_callback(self, path, args, types, src_addr): if self.stopping: return if CommandLineArgs.debug: sys.stderr.write('\033[93mOSC::gui_receives\033[0m (%s, %s, %s)\n' % (path, args, types)) self.signaler.osc_receive.emit(path, args) @ray_method('/reply', None) def _reply(self, path, args, types, src_addr): if not (types and ray.types_are_all_strings(types)): return False new_args = args.copy() reply_path = new_args.pop(0) if reply_path == '/ray/server/list_sessions': self.signaler.add_sessions_to_list.emit(new_args) elif reply_path == '/ray/server/list_path': self.signaler.new_executable.emit(new_args) elif reply_path == '/ray/server/list_session_templates': self.signaler.session_template_found.emit(new_args) elif reply_path == '/ray/server/list_user_client_templates': self.signaler.user_client_template_found.emit(new_args) elif reply_path == '/ray/server/list_factory_client_templates': self.signaler.factory_client_template_found.emit(new_args) elif reply_path in ('/ray/session/list_snapshots', '/ray/client/list_snapshots'): self.signaler.snapshots_found.emit(new_args) elif reply_path == '/ray/server/get_session_preview': self.signaler.session_preview_update.emit() elif reply_path == '/ray/server/rename_session': self.signaler.other_session_renamed.emit() elif reply_path == '/ray/session/duplicate_only': self.signaler.other_session_duplicated.emit() elif reply_path == '/ray/server/save_session_template': self.signaler.other_session_templated.emit() elif reply_path == '/ray/server/abort_parrallel_copy': self.signaler.parrallel_copy_aborted.emit() @ray_method('/ray/gui/server/announce', 'siisi') def _server_announce(self, path, args, types, src_addr): if self.daemon_manager.is_announced(): return version, server_status, options, session_root, is_net_free = args self.signaler.daemon_announce.emit( src_addr, version, server_status, options, session_root, is_net_free) @ray_method('/ray/gui/server/root', 's') def _server_root(self, path, args, types, src_addr): session_root = args[0] CommandLineArgs.change_session_root(session_root) self.signaler.root_changed.emit(session_root) @ray_method('/ray/gui/server/status', 'i') def _server_status(self, path, args, types, src_addr): server_status = args[0] self.signaler.server_status_changed.emit(server_status) @ray_method('/ray/gui/server/copying', 'i') def _server_copying(self, path, args, types, src_addr): copying = args[0] self.signaler.server_copying.emit(bool(copying)) @ray_method('/ray/gui/server/parrallel_copy_state', 'ii') def _server_parrallel_copy_state(self, path, args, types, src_addr): session_id, state = args if state: # copy is starting if self._parrallel_copy_id_queue: if session_id not in self._parrallel_copy_id_queue: self._parrallel_copy_id_queue.append(session_id) else: self._parrallel_copy_id_queue.append(session_id) self.signaler.parrallel_copy_state.emit(*args) else: # copy is finished if session_id in self._parrallel_copy_id_queue: self._parrallel_copy_id_queue.remove(session_id) self.signaler.parrallel_copy_state.emit(*args) @ray_method('/ray/gui/server/parrallel_copy_progress', 'if') def _server_copy_progress(self, path, args, types, src_addr): session_id, progress = args if not self._parrallel_copy_id_queue: return if session_id == self._parrallel_copy_id_queue[0]: self.signaler.parrallel_copy_progress.emit(*args) @ray_method('/ray/gui/server/progress', 'f') def _server_progress(self, path, args, types, src_addr): progress = args[0] self.signaler.server_progress.emit(progress) @ray_method('/ray/gui/server/recent_sessions', None) def _server_recent_sessions(self, path, args, types, src_addr): for t in types: if t != 's': return False @ray_method('/ray/gui/session/auto_snapshot', 'i') def _session_auto_snapshot(self, path, args, types, src_addr): self.signaler.reply_auto_snapshot.emit(bool(args[0])) @ray_method('/ray/gui/session/sort_clients', None) def _session_sort_clients(self, path, args, types, src_addr): if not ray.types_are_all_strings(types): return False @ray_method('/ray/gui/listed_session/details', 'sihi') def _listed_session_details(self, path, args, types, src_addr): self.signaler.session_details.emit(*args) @ray_method('/ray/gui/listed_session/scripted_dir', 'si') def _listed_session_scripted_dir(self, path, args, types, src_addr): self.signaler.scripted_dir.emit(*args) @ray_method('/ray/gui/client_template_update', 'iss' + ray.ClientData.sisi()) def _client_template_update(self, path, args, types, src_addr): self.signaler.client_template_update.emit(args) @ray_method('/ray/gui/client_template_ray_hack_update', 'is' + ray.RayHack.sisi()) def _client_template_ray_hack_update(self, path, args, types, src_addr): self.signaler.client_template_ray_hack_update.emit(args) @ray_method('/ray/gui/client_template_ray_net_update', 'is' + ray.RayNet.sisi()) def _client_template_ray_net_update(self, path, args, types, src_addr): self.signaler.client_template_ray_net_update.emit(args) @ray_method('/ray/gui/client/progress', 'sf') def _client_progress(self, path, args, types, src_addr): self.signaler.client_progress.emit(*args) return True @ray_method('/ray/gui/patchbay/announce', 'iii') def _ray_gui_patchbay_announce(self, path, args, types, src_addr): self.patchbay_addr = src_addr @ray_method('/ray/gui/patchbay/update_portgroup', None) def _patchbay_update_portgroup(self, path, args, types, src_addr): if not types.startswith('siiis'): return False types_end = types.replace('siiis', '', 1) for c in types_end: if c != 's': return False def send(self, *args): if CommandLineArgs.debug: sys.stderr.write( '\033[95mOSC::gui sends\033[0m %s\n' % str(args[1:])) liblo.ServerThread.send(self, *args) def to_daemon(self, *args): self.send(self.daemon_manager.address, *args) def announce(self): if CommandLineArgs.debug: sys.stderr.write('serverOSC::raysession_sends announce\n') NSM_URL = os.getenv('NSM_URL') if not NSM_URL: NSM_URL = "" self.send(self.daemon_manager.address, '/ray/server/gui_announce', ray.VERSION, int(CommandLineArgs.under_nsm), NSM_URL, os.getpid(), CommandLineArgs.net_daemon_id) def disannounce(self, src_addr): self.send(src_addr, '/ray/server/gui_disannounce') def open_session(self, session_name, save_previous=1, session_template=''): self.to_daemon('/ray/server/open_session', session_name, save_previous, session_template) def save_session(self): self.to_daemon('/ray/session/save') def close_session(self): self.to_daemon('/ray/session/close') def abort_session(self): self.to_daemon('/ray/session/abort') def duplicate_a_session(self, session_name:str, new_session_name:str): self._parrallel_new_session_name = new_session_name self.to_daemon('/ray/gui/session/duplicate_only', session_name, new_session_name, CommandLineArgs.session_root) def get_parrallel_copy_id(self)->int: ''' used by open session dialog to know if a parrallel copy is running ''' if not self._parrallel_copy_id_queue: return 0 return self._parrallel_copy_id_queue[0] def get_parrallel_new_session_name(self)->str: return self._parrallel_new_session_name RaySession-0.12.2/src/gui/gui_session.py000066400000000000000000000437471417052567600202030ustar00rootroot00000000000000 import sys from PyQt5.QtWidgets import QApplication import ray from patchcanvas import patchcanvas from daemon_manager import DaemonManager from gui_client import Client, TrashedClient from gui_signaler import Signaler from gui_server_thread import GuiServerThread from gui_tools import CommandLineArgs, RS, error_text from main_window import MainWindow from nsm_child import NsmChild, NsmChildOutside from patchbay_manager import PatchbayManager class Session: def __init__(self): self.client_list = [] self.trashed_clients = [] self.favorite_list = [] self.recent_sessions = [] self.name = '' self.path = '' self.notes = '' self.server_status = ray.ServerStatus.OFF self.is_renameable = True self.signaler = Signaler() self.patchbay_manager = PatchbayManager(self) server = GuiServerThread.instance() server.start() self.daemon_manager = DaemonManager(self) if CommandLineArgs.daemon_url: self.daemon_manager.set_osc_address(CommandLineArgs.daemon_url) elif CommandLineArgs.daemon_port: self.daemon_manager.set_osc_address(CommandLineArgs.daemon_port) elif not CommandLineArgs.out_daemon: self.daemon_manager.set_new_osc_address() # build nsm_child if NSM_URL in env self.nsm_child = None if CommandLineArgs.under_nsm: if CommandLineArgs.out_daemon: self.nsm_child = NsmChildOutside(self) self.daemon_manager.set_external() else: self.nsm_child = NsmChild(self) # build and show Main UI self.main_win = MainWindow(self) self.daemon_manager.finish_init() self.patchbay_manager.finish_init() server.finish_init(self) self.main_win.show() # display donations dialog under conditions if not RS.is_hidden(RS.HD_Donations): coreff_counter = RS.settings.value('coreff_counter', 0, type=int) coreff_counter += 1 RS.settings.setValue('coreff_counter', coreff_counter) if coreff_counter % 44 == 29: self.main_win.donate(True) def quit(self): self.patchbay_manager.clear_all() self.main_win.hide() del self.main_win def is_running(self)->bool: return bool(self.server_status != ray.ServerStatus.OFF) def update_server_status(self, server_status: int): self.server_status = server_status def _set_name(self, session_name: str): self.name = session_name def _set_path(self, session_path: str): self.path = session_path def get_short_path(self): if self.path.startswith(CommandLineArgs.session_root): return self.path.replace( '%s/' % CommandLineArgs.session_root, '', 1) return self.path def get_client(self, client_id: str)->Client: for client in self.client_list: if client.client_id == client_id: return client if CommandLineArgs.debug: sys.stderr.write("gui_session does not contains client %s\n" % client_id) return None def add_favorite(self, template_name: str, icon_name: str, factory: bool): server = GuiServerThread.instance() if server: server.to_daemon('/ray/favorites/add', template_name, icon_name, int(factory)) def remove_favorite(self, template_name: str, factory: bool): for favorite in self.favorite_list: if favorite.name == template_name and favorite.factory == factory: break server = GuiServerThread.instance() if server: server.to_daemon('/ray/favorites/remove', template_name, int(factory)) def is_favorite(self, template_name: str, factory: bool): for favorite in self.favorite_list: if favorite.name == template_name and favorite.factory == factory: return True return False def set_daemon_options(self, options): self.main_win.set_daemon_options(options) for client in self.client_list: client.widget.set_daemon_options(options) class SignaledSession(Session): def __init__(self): Session.__init__(self) self.signaler.osc_receive.connect(self._osc_receive) self.daemon_manager.start() self.canvas_groups = [] self.canvas_ports = [] self.next_canvas_port_id = -1 self.preview_notes = '' self.preview_client_list = [] self.preview_started_clients = set() self.preview_snapshots = [] self.preview_size = -1 def _osc_receive(self, path, args): func_path = path func_name = func_path.replace('/', '_') if func_name in self.__dir__(): function = self.__getattribute__(func_name) function(path, args) def _reply(self, path, args): if len(args) == 2: if args[0] == '/ray/session/add_executable': client_id = args[1] for client in self.client_list: if (client.client_id == client_id and client.protocol == ray.Protocol.RAY_HACK): client.show_properties_dialog(second_tab=True) break def _error(self, path, args): err_path, err_code, err_message = args # don't shows a window error if error is OK # or related to an abort made by user if err_code in (ray.Err.OK, ray.Err.ABORT_ORDERED, ray.Err.COPY_ABORTED): return message = error_text(err_code) if message: err_message = message self.main_win.error_message(err_message) def _minor_error(self, path, args): err_path, err_code, err_message = args # don't shows a window error if error is OK # or if it comes from just an unknown (and untreated) message if err_code in (ray.Err.OK, ray.Err.UNKNOWN_MESSAGE): return self.main_win.error_message(err_message) def _ray_gui_server_disannounce(self, path, args): QApplication.quit() def _ray_gui_server_nsm_locked(self, path, args): nsm_locked = bool(args[0]) self.main_win.set_nsm_locked(nsm_locked) def _ray_gui_server_message(self, path, args): message = args[0] self.main_win.print_message(message) def _ray_gui_server_options(self, path, args): options = args[0] self.set_daemon_options(options) def _ray_gui_server_recent_sessions(self, path, args): self.recent_sessions = args self.main_win.update_recent_sessions_menu() def _ray_gui_session_name(self, path, args): sname, spath = args self._set_name(sname) self._set_path(spath) self.main_win.rename_session(sname, spath) def _ray_gui_session_is_nsm(self, path, args): self.main_win.opening_nsm_session() def _ray_gui_session_renameable(self, path, args): self.is_renameable = bool(args[0]) bool_set_edit = bool(self.is_renameable and self.server_status == ray.ServerStatus.READY and not CommandLineArgs.out_daemon) self.main_win.set_session_name_editable(bool_set_edit) def _ray_gui_session_notes(self, path, args): self.notes = args[0] if self.main_win.notes_dialog is not None: self.main_win.notes_dialog.notes_updated() def _ray_gui_session_notes_shown(self, path, args): self.main_win.edit_notes() def _ray_gui_session_notes_hidden(self, path, args): self.main_win.edit_notes(close=True) def _ray_gui_session_sort_clients(self, path, args): new_client_list = [] for client_id in args: client = self.get_client(client_id) if not client: return new_client_list.append(client) if args == [c.client_id for c in self.client_list]: # no change between existing and new order return self.client_list.clear() self.main_win.re_create_list_widget() self.client_list = new_client_list for client in self.client_list: client.re_create_widget() client.widget.update_status(client.status) def _ray_gui_client_new(self, path, args): client = Client(self, *args[:2]) client.update_properties(*args) self.client_list.append(client) def _ray_gui_client_update(self, path, args): client_id = args[0] client = self.get_client(client_id) if client: client.update_properties(*args) def _ray_gui_client_ray_hack_update(self, path, args): client_id = args.pop(0) client = self.get_client(client_id) if client and client.protocol == ray.Protocol.RAY_HACK: client.update_ray_hack(*args) def _ray_gui_client_ray_net_update(self, path, args): client_id = args.pop(0) client = self.get_client(client_id) if client and client.protocol == ray.Protocol.RAY_NET: client.update_ray_net(*args) def _ray_gui_client_switch(self, path, args): old_id, new_id = args for client in self.client_list: if client.client_id == old_id: client.client_id = new_id break def _ray_gui_client_status(self, path, args): client_id, status = args client = self.get_client(client_id) if client: client.set_status(status) if status == ray.ClientStatus.REMOVED: self.main_win.remove_client(client_id) client.properties_dialog.close() self.client_list.remove(client) del client self.main_win.client_status_changed(client_id, status) def _ray_gui_client_progress(self, path, args): client_id, progress = args client = self.get_client(client_id) if client: client.set_progress(progress) def _ray_gui_client_dirty(self, path, args): client_id, int_dirty = args client = self.get_client(client_id) if client: client.set_dirty_state(bool(int_dirty)) def _ray_gui_client_has_optional_gui(self, path, args): client_id = args[0] client = self.get_client(client_id) if client: client.set_gui_enabled() def _ray_gui_client_gui_visible(self, path, args): client_id, int_state = args client = self.get_client(client_id) if client: client.set_gui_state(bool(int_state)) self.patchbay_manager.optional_gui_state_changed( client_id, bool(int_state)) def _ray_gui_client_still_running(self, path, args): client_id = args[0] client = self.get_client(client_id) if client: client.allow_kill() def _ray_gui_client_no_save_level(self, path, args): client_id, no_save_level = args client = self.get_client(client_id) if client: client.set_no_save_level(no_save_level) def _ray_gui_trash_add(self, path, args): trashed_client = TrashedClient() trashed_client.update(*args) trash_action = self.main_win.trash_add(trashed_client) trashed_client.set_menu_action(trash_action) self.trashed_clients.append(trashed_client) def _ray_gui_trash_ray_hack_update(self, path, args): client_id = args.pop(0) for trashed_client in self.trashed_clients: if trashed_client.client_id == client_id: trashed_client.ray_hack = ray.RayHack.new_from(*args) break def _ray_gui_trash_ray_net_update(self, path, args): client_id = args.pop(0) for trashed_client in self.trashed_clients: if trashed_client.client_id == client_id: trashed_client.ray_net = ray.RayNet.new_from(*args) break def _ray_gui_trash_remove(self, path, args): client_id = args[0] for trashed_client in self.trashed_clients: if trashed_client.client_id == client_id: break else: return self.trashed_clients.remove(trashed_client) self.main_win.trash_remove(trashed_client.menu_action) def _ray_gui_trash_clear(self, path, args): self.trashed_clients.clear() self.main_win.trash_clear() def _ray_gui_favorites_added(self, path, args): template_name, icon_name, int_factory = args for favorite in self.favorite_list: if (favorite.name == template_name and favorite.factory == bool(int_factory)): # favorite already exists, update the icon favorite.icon = icon_name break else: fav = ray.Favorite(template_name, icon_name, bool(int_factory)) self.favorite_list.append(fav) self.signaler.favorite_added.emit( template_name, icon_name, bool(int_factory)) self.main_win.update_favorites_menu() def _ray_gui_favorites_removed(self, path, args): template_name, int_factory = args for favorite in self.favorite_list: if (favorite.name == template_name and favorite.factory == bool(int_factory)): break else: return self.favorite_list.remove(favorite) self.signaler.favorite_removed.emit(template_name, bool(int_factory)) self.main_win.update_favorites_menu() def _ray_gui_preview_clear(self, path, args): self.preview_notes = '' self.preview_client_list.clear() self.preview_started_clients.clear() self.preview_snapshots.clear() self.preview_size = -1 def _ray_gui_preview_notes(self, path, args): self.preview_notes = args[0] def _ray_gui_preview_client_update(self, path, args): client = ray.ClientData.new_from(*args) for pv_client in self.preview_client_list: if pv_client.client_id == client.client_id: pv_client.update(*args) break else: self.preview_client_list.append(client) def _ray_gui_preview_client_ray_hack_update(self, path, args): client_id = args.pop(0) for pv_client in self.preview_client_list: if pv_client.client_id == client_id: pv_client.set_ray_hack(ray.RayHack.new_from(*args)) break def _ray_gui_preview_client_ray_net_update(self, path, args): client_id = args.pop(0) for pv_client in self.preview_client_list: if pv_client.client_id == client_id: pv_client.set_ray_net(ray.RayNet.new_from(*args)) break def _ray_gui_preview_client_is_started(self, path, args): client_id, is_started = args for pv_client in self.preview_client_list: if pv_client.client_id == client_id: if is_started: self.preview_started_clients.add(client_id) break def _ray_gui_preview_snapshot(self, path, args): self.preview_snapshots.append(args[0]) def _ray_gui_preview_session_size(self, path, args): self.preview_size = args[0] def _ray_gui_script_info(self, path, args): text = args[0] self.main_win.show_script_info(text) def _ray_gui_hide_script_info(self, path, args): self.main_win.hide_script_info_dialog() def _ray_gui_script_user_action(self, path, args): text = args[0] self.main_win.show_script_user_action_dialog(text) def _ray_gui_hide_script_user_action(self, path, args): self.main_win.hide_script_user_action_dialog() def _ray_gui_patchbay_announce(self, path, args): self.patchbay_manager.patchbay_announce(*args) def _ray_gui_patchbay_client_name_and_uuid(self, path, args): self.patchbay_manager.client_name_and_uuid(*args) def _ray_gui_patchbay_port_added(self, path, args): self.patchbay_manager.add_port(*args) def _ray_gui_patchbay_port_removed(self, path, args): self.patchbay_manager.remove_port(*args) def _ray_gui_patchbay_port_renamed(self, path, args): self.patchbay_manager.rename_port(*args) def _ray_gui_patchbay_metadata_updated(self, path, args): self.patchbay_manager.metadata_update(*args) def _ray_gui_patchbay_connection_added(self, path, args): self.patchbay_manager.add_connection(*args) def _ray_gui_patchbay_connection_removed(self, path, args): self.patchbay_manager.remove_connection(*args) def _ray_gui_patchbay_update_group_position(self, path, args): self.patchbay_manager.update_group_position(*args) def _ray_gui_patchbay_update_portgroup(self, path, args): self.patchbay_manager.update_portgroup(*args) def _ray_gui_patchbay_server_started(self, path, args): self.patchbay_manager.server_started(*args) def _ray_gui_patchbay_server_stopped(self, path, args): self.patchbay_manager.server_stopped(*args) def _ray_gui_patchbay_server_lose(self, path, args): self.patchbay_manager.server_lose(*args) def _ray_gui_patchbay_dsp_load(self, path, args): self.patchbay_manager.set_dsp_load(*args) def _ray_gui_patchbay_add_xrun(self, path, args): self.patchbay_manager.add_xrun(*args) def _ray_gui_patchbay_buffer_size(self, path, args): self.patchbay_manager.buffer_size_changed(*args) def _ray_gui_patchbay_sample_rate(self, path, args): self.patchbay_manager.sample_rate_changed(*args) def _ray_gui_patchbay_big_packets(self, path, args): self.patchbay_manager.receive_big_packets(*args) def _ray_gui_patchbay_fast_temp_file_memory(self, path, args): self.patchbay_manager.fast_temp_file_memory(*args) def _ray_gui_patchbay_fast_temp_file_running(self, path, args): self.patchbay_manager.fast_temp_file_running(*args) RaySession-0.12.2/src/gui/gui_signaler.py000066400000000000000000000034151417052567600203100ustar00rootroot00000000000000 from PyQt5.QtCore import QObject, pyqtSignal from liblo import Address class Signaler(QObject): osc_receive = pyqtSignal(str, list) daemon_announce = pyqtSignal(Address, str, int, int, str, int) daemon_announce_ok = pyqtSignal() daemon_nsm_locked = pyqtSignal(bool) server_copying = pyqtSignal(bool) add_sessions_to_list = pyqtSignal(list) new_executable = pyqtSignal(list) session_template_found = pyqtSignal(list) user_client_template_found = pyqtSignal(list) factory_client_template_found = pyqtSignal(list) snapshots_found = pyqtSignal(list) reply_auto_snapshot = pyqtSignal(bool) server_progress = pyqtSignal(float) client_progress = pyqtSignal(str, float) server_status_changed = pyqtSignal(int) daemon_url_request = pyqtSignal(int, str) daemon_url_changed = pyqtSignal(str) client_template_update = pyqtSignal(list) client_template_ray_hack_update = pyqtSignal(list) client_template_ray_net_update = pyqtSignal(list) root_changed = pyqtSignal(str) session_preview_update = pyqtSignal() session_details = pyqtSignal(str, int, int, int) scripted_dir = pyqtSignal(str, int) parrallel_copy_state = pyqtSignal(int, int) parrallel_copy_progress = pyqtSignal(int, float) parrallel_copy_aborted = pyqtSignal() other_session_renamed = pyqtSignal() other_session_duplicated = pyqtSignal() other_session_templated = pyqtSignal() client_added_reply = pyqtSignal(str) client_properties_state_changed = pyqtSignal(str, bool) favorite_added = pyqtSignal(str, str, bool) favorite_removed = pyqtSignal(str, bool) canvas_callback = pyqtSignal(int, int, int, str) port_types_view_changed = pyqtSignal(int) def __init__(self): QObject.__init__(self) RaySession-0.12.2/src/gui/gui_tools.py000066400000000000000000000274151417052567600176520ustar00rootroot00000000000000import argparse import os import sys from PyQt5.QtCore import QSettings, QSize, QFile from PyQt5.QtWidgets import QApplication from PyQt5.QtGui import QIcon, QPixmap, QPalette import ray _translate = QApplication.translate class RS: settings = QSettings() # HD for Hideable dialog HD_Donations = 0x001 HD_OpenNsmSession = 0x002 HD_SnapshotsInfo = 0x004 HD_WaitCloseUser = 0x008 HD_JackConfigScript = 0x010 HD_SessionScripts = 0x020 HD_SystrayClose = 0x040 HD_StartupRecentSessions = 0x080 HD_ArdourConversion = 0x100 @classmethod def set_settings(cls, settings): del cls.settings cls.settings = settings @classmethod def is_hidden(cls, hideable_dialog: int)->bool: hidden_dialogs = cls.settings.value('hidden_dialogs', 0, type=int) return bool(hidden_dialogs & hideable_dialog) @classmethod def set_hidden(cls, hiddeable_dialog: int, hide=True): hidden_dialogs = cls.settings.value('hidden_dialogs', 0, type=int) if hide: hidden_dialogs |= hiddeable_dialog else: hidden_dialogs &= ~hiddeable_dialog cls.settings.setValue('hidden_dialogs', hidden_dialogs) @classmethod def reset_hiddens(cls): cls.settings.setValue('hidden_dialogs', 0) class ErrDaemon: # for use on network session under NSM NO_ERROR = 0 NO_ANNOUNCE = -1 NOT_OFF = -2 WRONG_ROOT = -3 FORBIDDEN_ROOT = -4 NOT_NSM_LOCKED = -5 WRONG_VERSION = -6 class RayIcon(QIcon): def __init__(self, icon_name: str, dark=False): QIcon.__init__(self) breeze = 'breeze-dark' if dark else 'breeze' self.addFile(':scalable/%s/%s' % (breeze, icon_name), QSize(22, 22)) self.addPixmap( QPixmap( ':scalable/%s/disabled/%s' % (breeze, icon_name)), QIcon.Disabled, QIcon.Off) class CommandLineArgs(argparse.Namespace): daemon_url = None out_daemon = False config_dir = '' debug = False debug_only = False no_client_messages = False net_session_root = '' net_daemon_id = 0 under_nsm = False NSM_URL = '' session_root = '' start_session = '' force_new_daemon = False @classmethod def eat_attributes(cls, parsed_args): for attr_name in dir(parsed_args): if not attr_name.startswith('_'): setattr(cls, attr_name, getattr(parsed_args, attr_name)) if cls.debug_only: cls.debug = True if cls.debug or cls.no_client_messages: cls.force_new_daemon = True if cls.config_dir and not os.access(cls.config_dir, os.W_OK): sys.stderr.write( '%s is not a writable config dir, try another one\n' % cls.config_dir) sys.exit(1) if os.getenv('NSM_URL'): try: cls.NSM_URL = ray.get_liblo_address(os.getenv('NSM_URL')) except BaseException: sys.stderr.write('%s is not a valid NSM_URL\n' % os.getenv('NSM_URL')) sys.exit(1) cls.under_nsm = True if (cls.session_root is not None and cls.session_root.endswith('/')): cls.session_root = cls.session_root[:-1] @classmethod def change_session_root(cls, path: str): cls.session_root = path class ArgParser(argparse.ArgumentParser): def __init__(self): argparse.ArgumentParser.__init__( self, description=_translate( 'help', 'A session manager based on the Non-Session-Manager API ' + 'for sound applications.')) self.add_argument('--daemon-url', '-u', type=ray.get_liblo_address, help=_translate('help', 'connect to this daemon url')) self.add_argument('--daemon-port', '-p', type=ray.get_liblo_address_from_port, help=_translate('help', 'connect to this daemon port')) self.add_argument('--out-daemon', action='store_true', help=argparse.SUPPRESS) self.add_argument('--session-root', '-r', type=str, help=_translate( 'help', 'Use this folder as root for sessions')) self.add_argument('--start-session', '-s', type=str, help=_translate('help', 'Open this session at startup')) self.add_argument('--config-dir', '-c', type=str, default='', help=_translate('help', 'use a custom config dir')) self.add_argument('--debug', '-d', action='store_true', help=_translate('help', 'display OSC messages')) self.add_argument('--debug-only', '-do', action='store_true', help=_translate('help', 'debug without client messages')) self.add_argument('---no-client-messages', '-ncm', action='store_true', help=_translate('help', 'do not print client messages')) self.add_argument( '--force-new-daemon', '-fnd', action='store_true', help=_translate('help', 'prevent to attach to an already running daemon')) self.add_argument('--net-session-root', type=str, default='', help=argparse.SUPPRESS) self.add_argument('--net-daemon-id', type=int, default=0, help=argparse.SUPPRESS) self.add_argument('-v', '--version', action='version', version=ray.VERSION) parsed_args = argparse.ArgumentParser.parse_args(self) CommandLineArgs.eat_attributes(parsed_args) def init_gui_tools(): if CommandLineArgs.under_nsm: settings = QSettings('%s/child_sessions' % QApplication.organizationName()) elif CommandLineArgs.config_dir: settings = QSettings(CommandLineArgs.config_dir) else: settings = QSettings() RS.set_settings(settings) if not CommandLineArgs.session_root: CommandLineArgs.change_session_root( settings.value('default_session_root', ray.DEFAULT_SESSION_ROOT, type=str)) def is_dark_theme(widget)->bool: return bool( widget.palette().brush(QPalette.Active, QPalette.WindowText).color().lightness() > 128) def split_in_two(string: str)->tuple: middle = int(len(string)/2) sep_indexes = [] last_was_digit = False for sep in (' ', '-', '_', 'capital'): for i in range(len(string)): c = string[i] if sep == 'capital': if c.upper() == c: if not c.isdigit() or not last_was_digit: sep_indexes.append(i) last_was_digit = c.isdigit() elif c == sep: sep_indexes.append(i) if sep_indexes: break if not sep_indexes or sep_indexes == [0]: return (string, '') best_index = 0 best_dif = middle for s in sep_indexes: dif = abs(middle - s) if dif < best_dif: best_index = s best_dif = dif if sep == ' ': return (string[:best_index], string[best_index+1:]) return (string[:best_index], string[best_index:]) def dirname(*args)->str: return os.path.dirname(*args) def basename(*args)->str: return os.path.basename(*args) def get_code_root()->str: return dirname(dirname(dirname(os.path.realpath(__file__)))) def server_status_string(server_status: int)->str: server_status_strings = { ray.ServerStatus.OFF : _translate('server status', "off"), ray.ServerStatus.NEW : _translate('server status', "new"), ray.ServerStatus.OPEN : _translate('server status', "open"), ray.ServerStatus.CLEAR : _translate('server status', "clear"), ray.ServerStatus.SWITCH : _translate('server status', "switch"), ray.ServerStatus.LAUNCH : _translate('server status', "launch"), ray.ServerStatus.PRECOPY : _translate('server status', "copy"), ray.ServerStatus.COPY : _translate('server status', "copy"), ray.ServerStatus.READY : _translate('server status', "ready"), ray.ServerStatus.SAVE : _translate('server status', "save"), ray.ServerStatus.CLOSE : _translate('server status', "close"), ray.ServerStatus.SNAPSHOT: _translate('server_status', "snapshot"), ray.ServerStatus.REWIND : _translate('server_status', "rewind"), ray.ServerStatus.WAIT_USER : _translate('server_status', "waiting"), ray.ServerStatus.OUT_SAVE : _translate('server_status', "save"), ray.ServerStatus.OUT_SNAPSHOT: _translate('server_status', "snapshot"), ray.ServerStatus.SCRIPT : _translate('server_status', "script")} if not 0 <= server_status < len(server_status_strings): return _translate('server status', "invalid") return server_status_strings[server_status] def client_status_string(client_status: int)->str: client_status_strings = { ray.ClientStatus.STOPPED: _translate('client status', "stopped"), ray.ClientStatus.LAUNCH : _translate('client status', "launch"), ray.ClientStatus.OPEN : _translate('client status', "open"), ray.ClientStatus.READY : _translate('client status', "ready"), ray.ClientStatus.PRECOPY: _translate('client status', "copy"), ray.ClientStatus.COPY : _translate('client status', "copy"), ray.ClientStatus.SAVE : _translate('client status', "save"), ray.ClientStatus.SWITCH : _translate('client status', "switch"), ray.ClientStatus.QUIT : _translate('client status', "quit"), ray.ClientStatus.NOOP : _translate('client status', "noop"), ray.ClientStatus.ERROR : _translate('client status', "error"), ray.ClientStatus.REMOVED: _translate('client status', "removed"), ray.ClientStatus.UNDEF : _translate('client_status', ""), ray.ClientStatus.SCRIPT : _translate('client_status', 'script')} if not 0 <= client_status < len(client_status_strings): return _translate('client_status', 'invalid') return client_status_strings[client_status] def error_text(error:int)->str: text = '' if error == ray.Err.SESSION_IN_SESSION_DIR: text = _translate( 'guimsg', """Can't create session in a dir containing a session" for better organization.""") return text def get_app_icon(icon_name, widget): dark = bool( widget.palette().brush( 2, QPalette.WindowText).color().lightness() > 128) icon = QIcon.fromTheme(icon_name) if icon.isNull(): for ext in ('svg', 'svgz', 'png'): filename = ":app_icons/%s.%s" % (icon_name, ext) darkname = ":app_icons/dark/%s.%s" % (icon_name, ext) if dark and QFile.exists(darkname): filename = darkname if QFile.exists(filename): del icon icon = QIcon() icon.addFile(filename) break if icon.isNull(): for path in ('/usr/local', '/usr', '%s/.local' % os.getenv('HOME')): for ext in ('png', 'svg', 'svgz', 'xpm'): filename = "%s/share/pixmaps/%s.%s" % (path, icon_name, ext) if QFile.exists(filename): del icon icon = QIcon() icon.addFile(filename) break return icon RaySession-0.12.2/src/gui/list_widget_clients.py000066400000000000000000000522221417052567600216770ustar00rootroot00000000000000from PyQt5.QtWidgets import QListWidget, QListWidgetItem, QFrame, QMenu, QBoxLayout from PyQt5.QtGui import QIcon, QPixmap, QFont, QFontDatabase, QFontMetrics from PyQt5.QtCore import pyqtSlot, QSize import ray from gui_server_thread import GuiServerThread from gui_tools import (client_status_string, _translate, is_dark_theme, RayIcon, split_in_two, get_app_icon) import child_dialogs import snapshots_dialog import ui.client_slot class ClientSlot(QFrame): def __init__(self, list_widget, list_widget_item, client): QFrame.__init__(self) self.ui = ui.client_slot.Ui_ClientSlotWidget() self.ui.setupUi(self) self.client = client self.main_win = self.client.session.main_win self._list_widget = list_widget self._list_widget_item = list_widget_item self._gui_state = False self._stop_is_kill = False self._very_short = False self._icon_on = QIcon() self._icon_off = QIcon() self.ui.toolButtonGUI.setVisible(False) if client.protocol != ray.Protocol.RAY_HACK: self.ui.toolButtonHack.setVisible(False) # connect buttons to functions self.ui.toolButtonHack.order_hack_visibility.connect( self._order_hack_visibility) self.ui.toolButtonGUI.clicked.connect(self._change_gui_state) self.ui.startButton.clicked.connect(self._start_client) self.ui.stopButton.clicked.connect(self._stop_client) self.ui.saveButton.clicked.connect(self._save_client) self.ui.closeButton.clicked.connect(self._trash_client) self.ui.lineEditClientStatus.status_pressed.connect(self._abort_copy) self.ui.actionSaveAsApplicationTemplate.triggered.connect( self._save_as_application_template) self.ui.actionRename.triggered.connect(self._rename_dialog) self.ui.actionReturnToAPreviousState.triggered.connect( self._open_snapshots_dialog) self.ui.actionFindBoxesInPatchbay.triggered.connect( self._find_patchbay_boxes) self.ui.actionProperties.triggered.connect( self.client.show_properties_dialog) self._menu = QMenu(self) self._menu.addAction(self.ui.actionSaveAsApplicationTemplate) self._menu.addAction(self.ui.actionRename) self._menu.addAction(self.ui.actionReturnToAPreviousState) self._menu.addAction(self.ui.actionFindBoxesInPatchbay) self._menu.addAction(self.ui.actionProperties) self.ui.actionReturnToAPreviousState.setVisible( self.main_win.has_git) self.ui.iconButton.setMenu(self._menu) dark = is_dark_theme(self) self._save_icon = RayIcon('document-save', dark) self._saved_icon = RayIcon('document-saved', dark) self._unsaved_icon = RayIcon('document-unsaved', dark) self._no_save_icon = RayIcon('document-nosave', dark) self._icon_visible = RayIcon('visibility', dark) self._icon_invisible = RayIcon('hint', dark) self._stop_icon = RayIcon('media-playback-stop', dark) self._kill_icon = RayIcon('media-playback-stop_red', dark) self.ui.startButton.setIcon(RayIcon('media-playback-start', dark)) self.ui.closeButton.setIcon(RayIcon('window-close', dark)) self.ui.saveButton.setIcon(self._save_icon) self.ui.stopButton.setIcon(self._stop_icon) if ':optional-gui:' in self.client.capabilities: self.set_gui_state(self.client.gui_state) self.ui.toolButtonGUI.setVisible(True) if self.client.has_dirty: self.set_dirty_state(self.client.dirty_state) self.update_client_data() @classmethod def to_daemon(cls, *args): server = GuiServerThread.instance() if server: server.to_daemon(*args) def _change_gui_state(self): if self._gui_state: self.to_daemon('/ray/client/hide_optional_gui', self.get_client_id()) else: self.to_daemon('/ray/client/show_optional_gui', self.get_client_id()) def _order_hack_visibility(self, state): if self.client.protocol != ray.Protocol.RAY_HACK: return if state: self.client.show_properties_dialog(second_tab=True) else: self.client.properties_dialog.hide() def _start_client(self): self.to_daemon('/ray/client/resume', self.get_client_id()) def _stop_client(self): if self._stop_is_kill: self.to_daemon('/ray/client/kill', self.get_client_id()) return # we need to prevent accidental stop with a window confirmation # under conditions self.main_win.stop_client(self.get_client_id()) def _save_client(self): self.to_daemon('/ray/client/save', self.get_client_id()) def _trash_client(self): self.to_daemon('/ray/client/trash', self.get_client_id()) def _abort_copy(self): self.main_win.abort_copy_client(self.get_client_id()) def _save_as_application_template(self): dialog = child_dialogs.SaveTemplateClientDialog( self.main_win, self.client) dialog.exec() if not dialog.result(): return template_name = dialog.get_template_name() self.to_daemon('/ray/client/save_as_template', self.get_client_id(), template_name) def _open_snapshots_dialog(self): dialog = snapshots_dialog.ClientSnapshotsDialog(self.main_win, self.client) dialog.exec() if dialog.result(): snapshot = dialog.get_selected_snapshot() self.to_daemon('/ray/client/open_snapshot', self.get_client_id(), snapshot) def _find_patchbay_boxes(self): self.main_win.set_patchbay_filter_text( 'client:' + self.get_client_id()) self._list_widget_item.setSelected(True) def _rename_dialog(self): dialog = child_dialogs.ClientRenameDialog(self.main_win, self.client) dialog.exec() if dialog.result(): self.client.label = dialog.get_new_label() self.client.send_properties_to_daemon() def _set_very_short(self, yesno: bool): self._very_short = yesno if yesno: if not (self.ui.startButton.isEnabled() or self.ui.stopButton.isEnabled()): self.ui.startButton.setVisible(True) self.ui.stopButton.setVisible(False) else: self.ui.startButton.setVisible( self.ui.startButton.isEnabled()) self.ui.stopButton.setVisible(self.ui.stopButton.isEnabled()) self.ui.toolButtonHack.setVisible(False) else: self.ui.startButton.setVisible(True) self.ui.stopButton.setVisible(True) self.ui.toolButtonHack.setVisible( self.client.protocol == ray.Protocol.RAY_HACK) def _set_fat(self, yesno: bool, very_fat=False): if yesno: self.ui.mainLayout.setDirection(QBoxLayout.TopToBottom) self.ui.spacerLeftOfDown.setVisible(True) self._list_widget_item.setSizeHint( QSize(100, 80 if very_fat else 70)) else: self.ui.spacerLeftOfDown.setVisible(False) self.ui.mainLayout.setDirection(QBoxLayout.LeftToRight) self._list_widget_item.setSizeHint(QSize(100, 45)) def _gray_icon(self, gray: bool): if gray: self.ui.iconButton.setIcon(self._icon_off) else: self.ui.iconButton.setIcon(self._icon_on) def get_client_id(self): return self.client.client_id def update_disposition(self): default_font_size = 13 font = self.ui.ClientName.font() main_size = QFontMetrics(font).width(self.client.prettier_name()) layout_width = self._list_widget.width() self._set_very_short(layout_width < 233) scroll_bar = self._list_widget.verticalScrollBar() if scroll_bar.isVisible(): layout_width -= scroll_bar.width() max_label_width = layout_width - 231 if self.ui.toolButtonGUI.isVisible(): max_label_width -= self.ui.toolButtonGUI.width() if self.ui.toolButtonHack.isVisible(): max_label_width -= self.ui.toolButtonHack.width() if main_size <= max_label_width: self.ui.ClientName.setText(self.client.prettier_name()) self._set_fat(False) return # split title in two lines top, bottom = split_in_two(self.client.prettier_name()) max_size = 0 for text in (top, bottom): if not text: continue size = QFontMetrics(font).width(text) max_size = max(max_size, size) if max_size <= max_label_width: self.ui.ClientName.setText('\n'.join((top, bottom))) self._set_fat(False) return # responsive design, put label at top of the controls # if there is not enought space for label max_label_width = layout_width - 50 if main_size <= max_label_width: self._set_fat(True) self.ui.ClientName.setText(self.client.prettier_name()) return self._set_fat(True, very_fat=True) top, bottom = split_in_two(self.client.prettier_name()) self.ui.ClientName.setText('\n'.join((top, bottom))) def update_client_data(self): # set main label and main disposition self.update_disposition() # set tool tip tool_tip = "" tool_tip += "

%s
" \ % self.client.name tool_tip += "%s

" \ % self.client.description tool_tip += "

" tool_tip += "

%s : %s
" \ % (_translate('client_slot', 'Protocol'), ray.protocol_to_str(self.client.protocol)) tool_tip += "%s : %s
" \ % (_translate('client_slot', 'Executable'), self.client.executable_path) tool_tip += "%s : %s

" \ % (_translate('client_slot', 'client id'), self.client.client_id) tool_tip += "" self.ui.ClientName.setToolTip(tool_tip) # set icon self._icon_on = get_app_icon(self.client.icon, self) self._icon_off = QIcon(self._icon_on.pixmap(32, 32, QIcon.Disabled)) self._gray_icon( bool(self.client.status in ( ray.ClientStatus.STOPPED, ray.ClientStatus.PRECOPY))) self.ui.toolButtonGUI.setVisible( bool(':optional-gui:' in self.client.capabilities)) if self.client.executable_path in ('ray-proxy', 'nsm-proxy'): if is_dark_theme(self): self._icon_visible = QIcon() self._icon_visible.addPixmap( QPixmap(':scalable/breeze-dark/emblem-symbolic-link'), QIcon.Normal, QIcon.Off) self._icon_invisible = QIcon() self._icon_invisible.addPixmap( QPixmap(':scalable/breeze-dark/link'), QIcon.Normal, QIcon.Off) self._icon_invisible.addPixmap( QPixmap(':scalable/breeze-dark/disabled/link'), QIcon.Disabled, QIcon.Off) else: self._icon_visible = QIcon() self._icon_visible.addPixmap( QPixmap(':scalable/breeze/emblem-symbolic-link'), QIcon.Normal, QIcon.Off) self._icon_invisible = QIcon() self._icon_invisible.addPixmap( QPixmap(':scalable/breeze/link'), QIcon.Normal, QIcon.Off) self._icon_invisible.addPixmap( QPixmap(':scalable/breeze/disabled/link'), QIcon.Disabled, QIcon.Off) def update_status(self, status: int): self.ui.lineEditClientStatus.setText(client_status_string(status)) self.ui.lineEditClientStatus.setEnabled( status != ray.ClientStatus.STOPPED) self.ui.actionFindBoxesInPatchbay.setEnabled( status not in (ray.ClientStatus.STOPPED, ray.ClientStatus.PRECOPY)) ray_hack = bool(self.client.protocol == ray.Protocol.RAY_HACK) if status in ( ray.ClientStatus.LAUNCH, ray.ClientStatus.OPEN, ray.ClientStatus.SWITCH, ray.ClientStatus.NOOP): self.ui.startButton.setEnabled(False) self.ui.stopButton.setEnabled(True) self.ui.saveButton.setEnabled(False) self.ui.closeButton.setEnabled(False) self.ui.ClientName.setStyleSheet('QLabel {font-weight : bold}') self.ui.ClientName.setEnabled(True) self.ui.toolButtonGUI.setEnabled(True) self._gray_icon(False) if self._very_short: self.ui.startButton.setVisible(False) self.ui.stopButton.setVisible(True) elif status == ray.ClientStatus.READY: self.ui.startButton.setEnabled(False) self.ui.stopButton.setEnabled(True) self.ui.closeButton.setEnabled(False) self.ui.ClientName.setStyleSheet('QLabel {font-weight : bold}') self.ui.ClientName.setEnabled(True) self.ui.toolButtonGUI.setEnabled(True) self.ui.saveButton.setEnabled(True) self._gray_icon(False) if self._very_short: self.ui.startButton.setVisible(False) self.ui.stopButton.setVisible(True) elif status == ray.ClientStatus.STOPPED: self.ui.startButton.setEnabled(True) self.ui.stopButton.setEnabled(False) self.ui.saveButton.setEnabled(False) self.ui.closeButton.setEnabled(True) self.ui.ClientName.setStyleSheet('QLabel {font-weight : normal}') self.ui.ClientName.setEnabled(False) self.ui.toolButtonGUI.setEnabled(False) self._gray_icon(True) if self._very_short: self.ui.startButton.setVisible(True) self.ui.stopButton.setVisible(False) self.ui.saveButton.setIcon(self._save_icon) self.ui.stopButton.setIcon(self._stop_icon) self._stop_is_kill = False if not ray_hack: self.set_gui_state(False) elif status == ray.ClientStatus.PRECOPY: self.ui.startButton.setEnabled(False) self.ui.stopButton.setEnabled(False) self.ui.saveButton.setEnabled(False) self.ui.closeButton.setEnabled(True) self.ui.ClientName.setStyleSheet('QLabel {font-weight : normal}') self.ui.ClientName.setEnabled(False) self.ui.toolButtonGUI.setEnabled(False) self._gray_icon(True) if self._very_short: self.ui.startButton.setVisible(True) self.ui.stopButton.setVisible(False) self.ui.saveButton.setIcon(self._save_icon) self.ui.stopButton.setIcon(self._stop_icon) self._stop_is_kill = False elif status == ray.ClientStatus.COPY: self.ui.saveButton.setEnabled(False) def allow_kill(self): self._stop_is_kill = True self.ui.stopButton.setIcon(self._kill_icon) def flash_if_open(self, flash: bool): if flash: self.ui.lineEditClientStatus.setText( client_status_string(ray.ClientStatus.OPEN)) else: self.ui.lineEditClientStatus.setText('') def set_hack_button_state(self, state: bool): self.ui.toolButtonHack.setChecked(state) def show_gui_button(self): self.ui.toolButtonGUI.setIcon(self._icon_invisible) self.ui.toolButtonGUI.setVisible(True) def set_gui_state(self, state: bool): if state: self.ui.toolButtonGUI.setIcon(self._icon_visible) else: self.ui.toolButtonGUI.setIcon(self._icon_invisible) self._gui_state = state def set_dirty_state(self, dirty: bool): self.ui.saveButton.setIcon( self._unsaved_icon if dirty else self._saved_icon) def set_no_save_level(self, no_save_level: int): self.ui.saveButton.setIcon( self._no_save_icon if no_save_level else self._save_icon) def set_progress(self, progress: float): self.ui.lineEditClientStatus.set_progress(progress) def set_daemon_options(self, options): has_git = bool(options & ray.Option.HAS_GIT) self.ui.actionReturnToAPreviousState.setVisible(has_git) def patchbay_is_shown(self, yesno: bool): self.ui.actionFindBoxesInPatchbay.setVisible(yesno) def contextMenuEvent(self, event): act_selected = self._menu.exec(self.mapToGlobal(event.pos())) event.accept() class ClientItem(QListWidgetItem): def __init__(self, parent, client_data): QListWidgetItem.__init__(self, parent, QListWidgetItem.UserType + 1) self.sort_number = 0 self.widget = ClientSlot(parent, self, client_data) parent.setItemWidget(self, self.widget) self.setSizeHint(QSize(100, 45)) def __lt__(self, other): return self.sort_number < other.sort_number def __gt__(self, other): return self.sort_number > other.sort_number def get_client_id(self): return self.widget.get_client_id() class ListWidgetClients(QListWidget): def __init__(self, parent): QListWidget.__init__(self, parent) self._last_n = 0 self.session = None @classmethod def to_daemon(self, *args): server = GuiServerThread.instance() if server: server.to_daemon(*args) @pyqtSlot() def _launch_favorite(self): template_name, factory = self.sender().data() self.to_daemon('/ray/session/add_client_template', int(factory), template_name) def create_client_widget(self, client_data): item = ClientItem(self, client_data) item.sort_number = self._last_n self._last_n += 1 return item.widget def remove_client_widget(self, client_id): for i in range(self.count()): item = self.item(i) if item.get_client_id() == client_id: widget = item.widget self.takeItem(i) del item break def client_properties_state_changed(self, client_id: str, visible: bool): for i in range(self.count()): item = self.item(i) if item.get_client_id() == client_id: widget = item.widget widget.set_hack_button_state(visible) break def set_session(self, session): self.session = session def patchbay_is_shown(self, yesno: bool): for i in range(self.count()): item = self.item(i) widget = item.widget widget.patchbay_is_shown(yesno) def dropEvent(self, event): QListWidget.dropEvent(self, event) client_ids_list = [] for i in range(self.count()): item = self.item(i) #widget = self.itemWidget(item) client_id = item.get_client_id() client_ids_list.append(client_id) server = GuiServerThread.instance() if server: server.to_daemon('/ray/session/reorder_clients', *client_ids_list) def mousePressEvent(self, event): if not self.itemAt(event.pos()): self.setCurrentRow(-1) QListWidget.mousePressEvent(self, event) def contextMenuEvent(self, event): if not self.itemAt(event.pos()): self.setCurrentRow(-1) if (self.session is not None and not self.session.server_status in ( ray.ServerStatus.OFF, ray.ServerStatus.CLOSE, ray.ServerStatus.OUT_SAVE, ray.ServerStatus.WAIT_USER, ray.ServerStatus.OUT_SNAPSHOT)): menu = QMenu() fav_menu = QMenu(_translate('menu', 'Favorites'), menu) fav_menu.setIcon(QIcon(':scalable/breeze/star-yellow')) for favorite in self.session.favorite_list: act_app = fav_menu.addAction( get_app_icon(favorite.icon, self), favorite.name) act_app.setData([favorite.name, favorite.factory]) act_app.triggered.connect(self._launch_favorite) menu.addMenu(fav_menu) menu.addAction( self.session.main_win.ui.actionAddApplication) menu.addAction(self.session.main_win.ui.actionAddExecutable) act_selected = menu.exec(self.mapToGlobal(event.pos())) event.accept() return def resizeEvent(self, event): QListWidget.resizeEvent(self, event) for i in range(self.count()): item = self.item(i) widget = self.itemWidget(item) if widget is not None: widget.update_disposition() RaySession-0.12.2/src/gui/list_widget_preview_clients.py000066400000000000000000000162631417052567600234450ustar00rootroot00000000000000from PyQt5.QtWidgets import QListWidget, QListWidgetItem, QFrame, QMenu, QBoxLayout from PyQt5.QtGui import QIcon, QPixmap, QFont, QFontDatabase, QFontMetrics from PyQt5.QtCore import pyqtSlot, QSize, pyqtSignal import ray from gui_server_thread import GuiServerThread from gui_tools import (client_status_string, _translate, is_dark_theme, RayIcon, split_in_two, get_app_icon) import child_dialogs import snapshots_dialog import ui.preview_client_slot class ClientSlot(QFrame): def __init__(self, list_widget, list_widget_item, client): QFrame.__init__(self) self.ui = ui.preview_client_slot.Ui_ClientSlotWidget() self.ui.setupUi(self) self.client = client self._list_widget = list_widget self._list_widget_item = list_widget_item self._icon_on = QIcon() self._icon_off = QIcon() self.ui.actionAddToTheCurrentSession.triggered.connect( self._add_to_the_current_session) self.ui.actionProperties.triggered.connect( self._properties_request) self._menu = QMenu(self) self._menu.addAction(self.ui.actionAddToTheCurrentSession) self._menu.addAction(self.ui.actionProperties) self.ui.iconButton.setMenu(self._menu) dark = is_dark_theme(self) self.update_client_data() self._server_status = ray.ServerStatus.OFF @classmethod def to_daemon(cls, *args): server = GuiServerThread.instance() if server: server.to_daemon(*args) def _gray_icon(self, gray: bool): if gray: self.ui.iconButton.setIcon(self._icon_off) else: self.ui.iconButton.setIcon(self._icon_on) def _properties_request(self): self._list_widget.properties_request.emit(self.get_client_id()) def _add_to_the_current_session(self): self._list_widget.add_to_session_request.emit(self.get_client_id()) def set_launched(self, launched: bool): self._gray_icon(not launched) self.ui.ClientName.setEnabled(launched) def server_status_changed(self, server_status:int): self.ui.actionAddToTheCurrentSession.setEnabled( server_status == ray.ServerStatus.READY) def get_client_id(self): return self.client.client_id def update_disposition(self): default_font_size = 13 font = self.ui.ClientName.font() main_size = QFontMetrics(font).width(self.client.prettier_name()) layout_width = self._list_widget.width() scroll_bar = self._list_widget.verticalScrollBar() if scroll_bar.isVisible(): layout_width -= scroll_bar.width() max_label_width = layout_width - 50 if main_size <= max_label_width: self.ui.ClientName.setText(self.client.prettier_name()) #self._set_fat(False) return # split title in two lines top, bottom = split_in_two(self.client.prettier_name()) max_size = 0 for text in (top, bottom): if not text: continue size = QFontMetrics(font).width(text) max_size = max(max_size, size) if max_size <= max_label_width: self.ui.ClientName.setText('\n'.join((top, bottom))) #self._set_fat(False) return # responsive design, put label at top of the controls # if there is not enought space for label max_label_width = layout_width - 50 if main_size <= max_label_width: #self._set_fat(True) self.ui.ClientName.setText(self.client.prettier_name()) return #self._set_fat(True, very_fat=True) top, bottom = split_in_two(self.client.prettier_name()) self.ui.ClientName.setText('\n'.join((top, bottom))) def update_client_data(self): # set main label and main disposition self.update_disposition() # set tool tip tool_tip = "" tool_tip += "

%s
" \ % self.client.name tool_tip += "%s

" \ % self.client.description tool_tip += "

" tool_tip += "

%s : %s
" \ % (_translate('client_slot', 'Protocol'), ray.protocol_to_str(self.client.protocol)) tool_tip += "%s : %s
" \ % (_translate('client_slot', 'Executable'), self.client.executable_path) tool_tip += "%s : %s

" \ % (_translate('client_slot', 'client id'), self.client.client_id) tool_tip += "" self.ui.ClientName.setToolTip(tool_tip) # set icon self._icon_on = get_app_icon(self.client.icon, self) self._icon_off = QIcon(self._icon_on.pixmap(32, 32, QIcon.Disabled)) self._gray_icon(False) def contextMenuEvent(self, event): act_selected = self._menu.exec(self.mapToGlobal(event.pos())) event.accept() class ClientItem(QListWidgetItem): def __init__(self, parent, client_data): QListWidgetItem.__init__(self, parent, QListWidgetItem.UserType + 1) self.sort_number = 0 self.widget = ClientSlot(parent, self, client_data) parent.setItemWidget(self, self.widget) self.setSizeHint(QSize(100, 45)) def __lt__(self, other): return self.sort_number < other.sort_number def __gt__(self, other): return self.sort_number > other.sort_number def get_client_id(self): return self.widget.get_client_id() class ListWidgetPreviewClients(QListWidget): properties_request = pyqtSignal(str) add_to_session_request = pyqtSignal(str) def __init__(self, parent): QListWidget.__init__(self, parent) self._last_n = 0 self.session = None self.server_status = ray.ServerStatus.OFF @classmethod def to_daemon(self, *args): server = GuiServerThread.instance() if server: server.to_daemon(*args) def server_status_changed(self, server_status:int): self.server_status = server_status for i in range(self.count()): item = self.item(i) item.widget.server_status_changed(server_status) def create_client_widget(self, client_data): item = ClientItem(self, client_data) item.sort_number = self._last_n item.widget.server_status_changed(self.server_status) self._last_n += 1 return item.widget def remove_client_widget(self, client_id): for i in range(self.count()): item = self.item(i) if item.get_client_id() == client_id: widget = item.widget self.takeItem(i) del item break def mousePressEvent(self, event): if not self.itemAt(event.pos()): self.setCurrentRow(-1) QListWidget.mousePressEvent(self, event) def resizeEvent(self, event): QListWidget.resizeEvent(self, event) for i in range(self.count()): item = self.item(i) widget = self.itemWidget(item) if widget is not None: widget.update_disposition() RaySession-0.12.2/src/gui/main_window.py000066400000000000000000002013351417052567600201540ustar00rootroot00000000000000import time import os import subprocess from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenu, QDialog, QMessageBox, QToolButton, QAbstractItemView, QBoxLayout, QSystemTrayIcon, QAction, QShortcut) from PyQt5.QtGui import QIcon, QDesktopServices, QFontMetrics, QKeySequence from PyQt5.QtCore import QTimer, pyqtSlot, QUrl, QLocale, Qt from gui_tools import ( RS, RayIcon, CommandLineArgs, _translate, server_status_string, is_dark_theme, get_code_root, get_app_icon) import add_application_dialog import open_session_dialog import child_dialogs import snapshots_dialog from gui_server_thread import GuiServerThread from patchcanvas import patchcanvas import patchbay_manager from utility_scripts import UtilityScriptLauncher import ray import list_widget_clients import ui.raysession import ui.patchbay_tools UI_PATCHBAY_UNDEF = 0 UI_PATCHBAY_HIDDEN = 1 UI_PATCHBAY_SHOWN = 2 class MainWindow(QMainWindow): def __init__(self, session): QMainWindow.__init__(self) self.ui = ui.raysession.Ui_MainWindow() self.ui.setupUi(self) self.session = session self.daemon_manager = self.session.daemon_manager self.mouse_is_inside = False self.terminate_request = False self.notes_dialog = None self.util_script_launcher = UtilityScriptLauncher(self, session) # timer for keep focus while client opening self._timer_raisewin = QTimer() self._timer_raisewin.setInterval(50) self._timer_raisewin.timeout.connect(self._raise_window) # timer for flashing effect of 'open' status self._timer_flicker_open = QTimer() self._timer_flicker_open.setInterval(400) self._timer_flicker_open.timeout.connect(self._flash_open) self.flash_open_list = [] self._flash_open_bool = False # timer for too long snapshots, display snapshot progress dialog self._timer_snapshot = QTimer() self._timer_snapshot.setSingleShot(True) self._timer_snapshot.setInterval(2000) self._timer_snapshot.timeout.connect(self._show_snapshot_progress_dialog) self.server_copying = False self._keep_focus = RS.settings.value('keepfocus', False, type=bool) self.ui.actionKeepFocus.setChecked(self._keep_focus) # do not enable keep focus option under Wayland # because activate a window from it self on Wayland not allowed if ray.get_window_manager() == ray.WindowManager.WAYLAND: self._keep_focus = False self.ui.actionKeepFocus.setEnabled(False) # calculate tool button size with action labels self._tool_bar_main_actions_width = 0 for action in (self.ui.actionNewSession, self.ui.actionOpenSession, self.ui.actionControlMenu): button = self.ui.toolBar.widgetForAction(action) self._tool_bar_main_actions_width += button.iconSize().width() self._tool_bar_main_actions_width += QFontMetrics(button.font()).width(button.text()) self._tool_bar_main_actions_width += 6 # manage geometry depending of use of embedded jack patchbay show_patchbay = RS.settings.value( 'MainWindow/show_patchbay', True, type=bool) self.ui.actionShowJackPatchbay.setChecked(show_patchbay) self.waiting_for_patchbay = show_patchbay if show_patchbay: patchbay_geom = RS.settings.value('MainWindow/patchbay_geometry') if patchbay_geom: self.restoreGeometry(patchbay_geom) self.ui.graphicsView.setVisible(True) splitter_sizes = RS.settings.value( 'MainWindow/splitter_canvas_sizes', [420, 706], type=list) self.ui.splitterMainVsCanvas.setSizes( int(s) for s in splitter_sizes) else: self.ui.graphicsView.setVisible(False) self.ui.splitterMainVsCanvas.setSizes([100, 0]) self.ui.splitterMainVsCanvas.set_active(False) geom = RS.settings.value('MainWindow/geometry') if geom: self.restoreGeometry(geom) else: rect = self.geometry() x = rect.x() y = rect.y() height = rect.height() self.setMinimumWidth(450) self.setGeometry(x, y, 460, height) splitter_sizes = RS.settings.value( "MainWindow/splitter_messages", [466, 84], type=list) self.ui.splitterSessionVsMessages.setSizes( [int(s) for s in splitter_sizes]) if RS.settings.value('MainWindow/WindowState'): self.restoreState(RS.settings.value('MainWindow/WindowState')) self.ui.actionShowMenuBar.activate(RS.settings.value( 'MainWindow/ShowMenuBar', False, type=bool)) self.ui.actionToggleShowMessages.triggered.connect( self._show_messages_widget) self.ui.actionToggleShowMessages.setChecked( bool(self.ui.splitterSessionVsMessages.sizes()[1] > 0)) # set default action for tools buttons self.ui.closeButton.setDefaultAction(self.ui.actionCloseSession) self.ui.toolButtonSaveSession.setDefaultAction( self.ui.actionSaveSession) self.ui.toolButtonAbortSession.setDefaultAction( self.ui.actionAbortSession) self.ui.toolButtonNotes.setDefaultAction( self.ui.actionSessionNotes) self.ui.toolButtonFileManager.setDefaultAction( self.ui.actionOpenSessionFolder) self.ui.toolButtonAddApplication.setDefaultAction( self.ui.actionAddApplication) self.ui.toolButtonAddExecutable.setDefaultAction( self.ui.actionAddExecutable) self.ui.toolButtonSnapshots.setDefaultAction( self.ui.actionReturnToAPreviousState) # connect actions self.ui.actionNewSession.triggered.connect(self._create_new_session) self.ui.actionOpenSession.triggered.connect(self._open_session) self.ui.actionConvertArdourSession.triggered.connect( self.util_script_launcher.convert_ardour_to_session) self.ui.actionConvertHydrogenRhNsm.triggered.connect( self.util_script_launcher.convert_ray_hack_to_nsm_hydrogen) self.ui.actionConvertJackMixerRhNsm.triggered.connect( self.util_script_launcher.convert_ray_hack_to_nsm_jack_mixer) self.ui.actionConvertToNsmFileFormat.triggered.connect( self.util_script_launcher.convert_to_nsm_file_format) self.ui.actionQuit.triggered.connect(self._quit_app) self.ui.actionSaveSession.triggered.connect(self._save_session) self.ui.actionCloseSession.triggered.connect(self._close_session) self.ui.actionAbortSession.triggered.connect(self._abort_session) self.ui.actionRenameSession.triggered.connect( self._rename_session_action) self.ui.actionRenameSession_2.triggered.connect( self._rename_session_action) self.ui.actionDuplicateSession.triggered.connect( self._duplicate_session) self.ui.actionDuplicateSession_2.triggered.connect( self._duplicate_session) self.ui.actionSaveTemplateSession.triggered.connect( self._save_template_session) self.ui.actionSaveTemplateSession_2.triggered.connect( self._save_template_session) self.ui.actionSessionNotes.triggered.connect( self._toggle_notes_visibility) self.ui.actionReturnToAPreviousState.triggered.connect( self._return_to_a_previous_state) self.ui.actionOpenSessionFolder.triggered.connect( self._open_file_manager) self.ui.actionAddApplication.triggered.connect(self._add_application) self.ui.actionAddExecutable.triggered.connect(self._add_executable) self.ui.actionShowJackPatchbay.toggled.connect(self._show_jack_patchbay) self.ui.actionKeepFocus.toggled.connect(self._toggle_keep_focus) self.ui.actionBookmarkSessionFolder.triggered.connect( self._bookmark_session_folder_toggled) self.ui.actionDesktopsMemory.triggered.connect( self._desktops_memory_toggled) self.ui.actionAutoSnapshot.triggered.connect( self._auto_snapshot_toggled) self.ui.actionSessionScripts.triggered.connect( self._session_scripts_toggled) self.ui.actionRememberOptionalGuiStates.triggered.connect( self._remember_optional_gui_states_toggled) self.ui.actionAboutRaySession.triggered.connect(self._about_raysession) self.ui.actionAboutQt.triggered.connect(QApplication.aboutQt) self.ui.actionOnlineManual.triggered.connect(self._online_manual) self.ui.actionInternalManual.triggered.connect(self._internal_manual) self.ui.actionDonate.triggered.connect(self.donate) self.ui.actionSystemTrayIconOptions.triggered.connect( self._open_systray_options) self.ui.actionMakeReappearDialogs.triggered.connect( self._make_all_dialogs_reappear) self.ui.lineEditServerStatus.status_pressed.connect( self._status_bar_pressed) self.ui.stackedWidgetSessionName.name_changed.connect( self._rename_session_conditionnaly) self.ui.frameCurrentSession.frame_resized.connect( self._session_frame_resized) # set session menu self._session_menu = QMenu() self._session_menu.addAction(self.ui.actionSaveTemplateSession_2) self._session_menu.addAction(self.ui.actionDuplicateSession_2) self._session_menu.addAction(self.ui.actionRenameSession_2) self.ui.toolButtonSessionMenu.setPopupMode(QToolButton.InstantPopup) self.ui.toolButtonSessionMenu.setMenu(self._session_menu) # set control menu self._control_menu = QMenu() self._control_menu.addAction(self.ui.actionShowMenuBar) self._control_menu.addAction(self.ui.actionToggleShowMessages) self._control_menu.addAction(self.ui.actionShowJackPatchbay) self._control_menu.addSeparator() self._control_menu.addAction(self.ui.actionKeepFocus) self._control_menu.addSeparator() self._control_menu.addAction(self.ui.actionBookmarkSessionFolder) self._control_menu.addAction(self.ui.actionAutoSnapshot) self._control_menu.addAction(self.ui.actionDesktopsMemory) self._control_menu.addAction(self.ui.actionSessionScripts) self._control_menu.addAction(self.ui.actionRememberOptionalGuiStates) self._control_menu.addSeparator() self._control_menu.addAction(self.ui.actionMakeReappearDialogs) self._control_tool_button = self.ui.toolBar.widgetForAction( self.ui.actionControlMenu) self._control_tool_button.setPopupMode(QToolButton.InstantPopup) self._control_tool_button.setMenu(self._control_menu) self.ui.toolButtonControl2.setPopupMode(QToolButton.InstantPopup) self.ui.toolButtonControl2.setMenu(self._control_menu) # set favorites menu self._favorites_menu = QMenu(_translate('menu', 'Favorites')) self._favorites_menu.setIcon(QIcon(':scalable/breeze/star-yellow')) self.ui.toolButtonFavorites.setPopupMode(QToolButton.InstantPopup) self.ui.toolButtonFavorites.setMenu(self._favorites_menu) self.ui.menuAdd.addMenu(self._favorites_menu) # set trash menu self._trash_menu = QMenu() self.ui.trashButton.setPopupMode(QToolButton.InstantPopup) self.ui.trashButton.setMenu(self._trash_menu) # connect OSC signals from daemon sg = self.session.signaler sg.server_progress.connect(self._server_progress) sg.server_status_changed.connect(self._server_status_changed) sg.server_copying.connect(self._server_copying) sg.daemon_url_request.connect(self._show_daemon_url_window) sg.client_properties_state_changed.connect( self._client_properties_state_changed) sg.canvas_callback.connect( self.session.patchbay_manager.canvas_callbacks) # set spare icons if system icons not avalaible dark = is_dark_theme(self) if self.ui.actionNewSession.icon().isNull(): self.ui.actionNewSession.setIcon(RayIcon('folder-new', dark)) if self.ui.actionOpenSession.icon().isNull(): self.ui.actionOpenSession.setIcon(RayIcon('document-open', dark)) if self.ui.actionControlMenu.icon().isNull(): self.ui.actionControlMenu.setIcon( QIcon.fromTheme('configuration_section')) if self.ui.actionControlMenu.icon().isNull(): self.ui.actionControlMenu.setIcon(RayIcon('configure', dark)) if self.ui.actionOpenSessionFolder.icon().isNull(): self.ui.actionOpenSessionFolder.setIcon( RayIcon('system-file-manager', dark)) if self.ui.actionAddApplication.icon().isNull(): self.ui.actionAddApplication.setIcon(RayIcon('list-add', dark)) if self.ui.actionAddExecutable.icon().isNull(): self.ui.actionAddExecutable.setIcon(QIcon.fromTheme('system-run')) if self.ui.actionAddExecutable.icon().isNull(): self.ui.actionAddExecutable.setIcon(RayIcon('run-install')) self.ui.actionReturnToAPreviousState.setIcon( RayIcon('media-seek-backward', dark)) self.ui.actionRememberOptionalGuiStates.setIcon( RayIcon('visibility', dark)) self.ui.trashButton.setIcon(RayIcon('trash-empty', dark)) if self.ui.trashButton.icon().isNull(): self.ui.trashButton.setIcon(RayIcon('trash'), dark) self.ui.actionDuplicateSession.setIcon( RayIcon('xml-node-duplicate', dark)) self.ui.actionDuplicateSession_2.setIcon( RayIcon('xml-node-duplicate', dark)) self.ui.actionSaveTemplateSession.setIcon( RayIcon('document-save-as-template', dark)) self.ui.actionSaveTemplateSession_2.setIcon( RayIcon('document-save-as-template', dark)) self.ui.actionCloseSession.setIcon(RayIcon('window-close', dark)) self.ui.actionAbortSession.setIcon(RayIcon('list-remove', dark)) self.ui.actionSaveSession.setIcon(RayIcon('document-save', dark)) self.ui.toolButtonSaveSession.setIcon(RayIcon('document-save', dark)) self.ui.actionSessionNotes.setIcon(RayIcon('notes', dark)) self.ui.toolButtonNotes.setIcon(RayIcon('notes', dark)) self.ui.actionDesktopsMemory.setIcon(RayIcon('view-list-icons', dark)) self.ui.toolButtonSessionMenu.setIcon(RayIcon('application-menu', dark)) self.ui.listWidget.set_session(self.session) # concerns patchbay filters bar (activable with Ctrl+F) self.ui.framePatchbayFilters.set_patchbay_manager( self.session.patchbay_manager) self.ui.framePatchbayFilters.setVisible(False) filter_bar_shortcut = QShortcut('Ctrl+F', self) filter_bar_shortcut.setContext(Qt.ApplicationShortcut) filter_bar_shortcut.activated.connect(self.toggle_patchbay_filters_bar) # prevent to hide the session frame with session/messages splitter self.ui.splitterSessionVsMessages.setCollapsible(0, False) self.ui.splitterSessionVsMessages.splitterMoved.connect( self._splitter_session_vs_messages_moved) self._canvas_tools_action = None self._canvas_menu = None self.scene = patchcanvas.PatchScene(self, self.ui.graphicsView) self.ui.graphicsView.setScene(self.scene) self._setup_canvas() self.set_nsm_locked(CommandLineArgs.under_nsm) self._script_info_dialog = None self._script_action_dialog = None # disable "keep focus" if daemon is not on this machine (it takes no # sense in this case) if not self.daemon_manager.is_local: self.ui.actionKeepFocus.setChecked(False) self.ui.actionKeepFocus.setEnabled(False) self.server_progress = 0.0 self._progress_dialog_visible = False self.has_git = False self._were_visible_before_fullscreen = 0 self._geom_before_fullscreen = None self._splitter_pos_before_fullscreen = [100, 100] self._fullscreen_patchbay = False self.hidden_maximized = False # systray icon and related self._wild_shutdown = RS.settings.value( 'wild_shutdown', False, type=bool) self._systray_mode = RS.settings.value( 'systray_mode', ray.Systray.SESSION_ONLY, type=int) self._reversed_systray_menu = RS.settings.value( 'reversed_systray_menu', False, type=bool) self._systray = QSystemTrayIcon(self) self._systray.activated.connect(self._systray_activated) self._systray.setIcon(QIcon(':48x48/raysession')) self._systray.setToolTip(ray.APP_TITLE) self._systray_menu = QMenu() self._systray_menu_add = QMenu(self._systray_menu) self._build_systray_menu() if (not CommandLineArgs.under_nsm and (self._systray_mode == ray.Systray.ALWAYS or (self._systray_mode == ray.Systray.SESSION_ONLY and self.session.server_status != ray.ServerStatus.OFF))): self._systray.show() self._startup_time = time.time() def _splitter_session_vs_messages_moved(self, pos: int, index: int): self.ui.actionToggleShowMessages.setChecked( bool(pos < self.ui.splitterSessionVsMessages.height() -10)) def _session_frame_resized(self): width = self.ui.frameCurrentSession.width() if width <= 283: # reorganize the window because session frame is not large self.ui.layoutSessionDown.setDirection(QBoxLayout.TopToBottom) # move down the session name label self.ui.layoutTopSession.removeWidget( self.ui.stackedWidgetSessionName) self.ui.layoutSessionDown.insertWidget( 0, self.ui.stackedWidgetSessionName) # keep the file manager tool button at bottom left # of the session header self.ui.layoutSessionToolsLeft.removeWidget( self.ui.fullButtonFolder) self.ui.layoutSessionToolsRight.insertWidget( 0, self.ui.fullButtonFolder) # set visible spacer between file manager button # and snapshots buttons self.ui.widgetPreRewindSpacer.setVisible(True) else: #self.ui.toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.ui.layoutSessionDown.setDirection(QBoxLayout.LeftToRight) self.ui.layoutSessionDown.removeWidget( self.ui.stackedWidgetSessionName) self.ui.layoutTopSession.insertWidget( 4, self.ui.stackedWidgetSessionName) self.ui.layoutSessionToolsRight.removeWidget( self.ui.fullButtonFolder) self.ui.layoutSessionToolsLeft.insertWidget( 0, self.ui.fullButtonFolder) self.ui.widgetPreRewindSpacer.setVisible(False) app = self.ui.toolButtonAddApplication exe = self.ui.toolButtonAddExecutable if width >= 419: app.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) exe.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) elif width >= 350: app.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) exe.setToolButtonStyle(Qt.ToolButtonIconOnly) elif width > 283: app.setToolButtonStyle(Qt.ToolButtonIconOnly) exe.setToolButtonStyle(Qt.ToolButtonIconOnly) elif width > 260: app.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) exe.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) else: app.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) exe.setToolButtonStyle(Qt.ToolButtonIconOnly) @classmethod def to_daemon(cls, *args): server = GuiServerThread.instance() if server: server.to_daemon(*args) def _show_messages_widget(self, yesno: bool): sizes = [10, 0] if yesno: sizes = [30, 10] self.ui.splitterSessionVsMessages.setSizes(sizes) def _setup_canvas(self): options = patchcanvas.options_t() options.theme_name = RS.settings.value( 'Canvas/theme', 'Black Gold', type=str) options.antialiasing = patchcanvas.ANTIALIASING_SMALL options.eyecandy = patchcanvas.EYECANDY_NONE if RS.settings.value('Canvas/box_shadows', False, type=bool): options.eyecandy = patchcanvas.EYECANDY_SMALL options.auto_hide_groups = True options.auto_select_items = False options.inline_displays = False options.use_bezier_lines = True options.elastic = RS.settings.value('Canvas/elastic', True, type=bool) options.prevent_overlap = RS.settings.value( 'Canvas/prevent_overlap', True, type=bool) options.max_port_width = RS.settings.value( 'Canvas/max_port_width', 160, type=int) features = patchcanvas.features_t() features.group_info = False features.group_rename = False features.port_info = True features.port_rename = False features.handle_group_pos = False patchcanvas.setOptions(options) patchcanvas.setFeatures(features) patchcanvas.init( ray.APP_TITLE, self.scene, self.canvas_callback, False) patchcanvas.set_semi_hide_opacity(RS.settings.value( 'Canvas/semi_hide_opacity', 0.17, type=float)) def _open_file_manager(self): self.to_daemon('/ray/session/open_folder') def _open_systray_options(self): dialog = child_dialogs.SystrayManagement(self) dialog.set_systray_mode(self._systray_mode) dialog.set_wild_shutdown(self._wild_shutdown) dialog.set_reversed_state(self._reversed_systray_menu) dialog.exec() if not dialog.result(): return self._systray_mode = dialog.get_systray_mode() self._wild_shutdown = dialog.wild_shutdown() reversed_systray_menu = dialog.menu_should_be_reversed() RS.settings.setValue('systray_mode', self._systray_mode) RS.settings.setValue('wild_shutdown', self._wild_shutdown) RS.settings.setValue('reversed_systray_menu', reversed_systray_menu) if reversed_systray_menu != self._reversed_systray_menu: self._reversed_systray_menu = reversed_systray_menu self._build_systray_menu() if self._systray_mode == ray.Systray.OFF: self._systray.hide() elif self._systray_mode == ray.Systray.SESSION_ONLY: if self.session.server_status == ray.ServerStatus.OFF: self._systray.hide() else: self._systray.show() elif self._systray_mode == ray.Systray.ALWAYS: self._systray.show() def _raise_window(self): if self.mouse_is_inside: self.activateWindow() def _toggle_keep_focus(self, keep_focus: bool): self._keep_focus = keep_focus if self.daemon_manager.is_local: RS.settings.setValue('keepfocus', self._keep_focus) if not keep_focus: self._timer_raisewin.stop() def _set_option(self, option: int, state: bool): if not state: option = -option self.to_daemon('/ray/server/set_option', option) def _bookmark_session_folder_toggled(self, state): self._set_option(ray.Option.BOOKMARK_SESSION, state) def _desktops_memory_toggled(self, state): self._set_option(ray.Option.DESKTOPS_MEMORY, state) def _auto_snapshot_toggled(self, state): self._set_option(ray.Option.SNAPSHOTS, state) def _session_scripts_toggled(self, state): self._set_option(ray.Option.SESSION_SCRIPTS, state) def _remember_optional_gui_states_toggled(self, state): self._set_option(ray.Option.GUI_STATES, state) def _flash_open(self): for client in self.session.client_list: if client.status == ray.ClientStatus.OPEN: client.widget.flash_if_open(self._flash_open_bool) self._flash_open_bool = not self._flash_open_bool def _quit_app(self): if self._wild_shutdown and not CommandLineArgs.under_nsm: self.daemon_manager.disannounce() QTimer.singleShot(10, QApplication.quit) return if self.session.is_running(): self.show() dialog = child_dialogs.QuitAppDialog(self) dialog.exec() if not dialog.result(): return False self._quit_app_now() return True def _quit_app_now(self): self.daemon_manager.stop() def _create_new_session(self): # from systray menu, better to show main window in the background # before open dialog self.show() dialog = child_dialogs.NewSessionDialog(self) dialog.exec() if not dialog.result(): return session_short_path = dialog.get_session_short_path() template_name = dialog.get_template_name() subfolder = session_short_path.rpartition('/')[0] RS.settings.setValue('last_used_template', template_name) if not template_name: self.to_daemon('/ray/server/new_session', session_short_path) return if template_name.startswith('///'): if template_name == '///' + ray.FACTORY_SESSION_TEMPLATES[1]: if not RS.is_hidden(RS.HD_JackConfigScript): # display jack_config_script info dialog # and manage ray-jack_checker auto_start session_path = "%s/%s" % (CommandLineArgs.session_root, session_short_path) dialog = child_dialogs.JackConfigInfoDialog( self, session_path) dialog.exec() if not dialog.result(): return RS.set_hidden(RS.HD_JackConfigScript, dialog.not_again_value()) autostart_jack_checker = dialog.auto_start_value() action = 'set_jack_checker_autostart' if not autostart_jack_checker: action = 'unset_jack_checker_autostart' self.to_daemon('/ray/server/exotic_action', action) elif template_name == '///' + ray.FACTORY_SESSION_TEMPLATES[2]: if not RS.is_hidden(RS.HD_SessionScripts): # display session scripts info dialog session_path = "%s/%s" % (CommandLineArgs.session_root, session_short_path) dialog = child_dialogs.SessionScriptsInfoDialog( self, session_path) dialog.exec() if not dialog.result(): return RS.set_hidden(RS.HD_SessionScripts, dialog.not_again_value()) self.to_daemon('/ray/server/new_session', session_short_path, template_name) def _open_session(self): # from systray, better to show main window in the background # before open dialog self.show() dialog = open_session_dialog.OpenSessionDialog(self) dialog.exec() if not dialog.result(): return session_name = dialog.get_selected_session() save_previous = int(dialog.want_to_save_previous()) self.to_daemon('/ray/server/open_session', session_name, save_previous) def _close_session(self): self.to_daemon('/ray/session/close') def _abort_session(self): self.show() dialog = child_dialogs.AbortSessionDialog(self) dialog.exec() if dialog.result(): self.to_daemon('/ray/session/abort') def _rename_session_action(self): if not self.session.is_renameable: QMessageBox.information( self, _translate("rename_session", "Rename Session"), _translate("rename_session", "

In order to rename current session,
" + "please first stop all clients.
" + "then, double click on session name.

")) return self.ui.stackedWidgetSessionName.toggle_edit() def _duplicate_session(self): dialog = child_dialogs.NewSessionDialog(self, True) dialog.exec() if not dialog.result(): return session_name = dialog.get_session_short_path() self.to_daemon('/ray/session/duplicate', session_name) def _save_template_session(self): dialog = child_dialogs.SaveTemplateSessionDialog(self) dialog.exec() if not dialog.result(): return session_template_name = dialog.get_template_name() self.to_daemon('/ray/session/save_as_template', session_template_name) def _return_to_a_previous_state(self): dialog = snapshots_dialog.SessionSnapshotsDialog(self) dialog.exec() if not dialog.result(): return snapshot = dialog.get_selected_snapshot() self.to_daemon('/ray/session/open_snapshot', snapshot) def _about_raysession(self): dialog = child_dialogs.AboutRaySessionDialog(self) dialog.exec() def _online_manual(self): short_locale = 'en' locale_str = QLocale.system().name() if (len(locale_str) > 2 and '_' in locale_str and locale_str[:2] in ('en', 'fr', 'de')): short_locale = locale_str[:2] QDesktopServices.openUrl( QUrl('http://raysession.tuxfamily.org/%s/manual.html' % short_locale)) def _internal_manual(self): short_locale = 'en' manual_dir = "%s/manual" % get_code_root() locale_str = QLocale.system().name() if (len(locale_str) > 2 and '_' in locale_str and os.path.isfile( "%s/%s/manual.html" % (manual_dir, locale_str[:2]))): short_locale = locale_str[:2] QDesktopServices.openUrl( QUrl("%s/%s/manual.html" % (manual_dir, short_locale))) def _save_session(self): self.to_daemon('/ray/session/save') def _toggle_notes_visibility(self): if (self.notes_dialog is None or not self.notes_dialog.isVisible()): self.to_daemon('/ray/session/show_notes') else: self.to_daemon('/ray/session/hide_notes') def _add_application(self): if self.session.server_status in ( ray.ServerStatus.CLOSE, ray.ServerStatus.OFF): return dialog = add_application_dialog.AddApplicationDialog(self) dialog.exec() dialog.save_check_boxes() if dialog.result(): template_name, factory = dialog.get_selected_template() self.to_daemon( '/ray/session/add_client_template', int(factory), template_name) def _add_executable(self): if self.session.server_status in ( ray.ServerStatus.CLOSE, ray.ServerStatus.OFF): return dialog = child_dialogs.NewExecutableDialog(self) dialog.exec() if not dialog.result(): return command, auto_start, via_proxy, \ prefix_mode, prefix, client_id, jack_naming = dialog.get_selection() self.to_daemon( '/ray/session/add_executable', command, int(auto_start), int(via_proxy), prefix_mode, prefix, client_id, int(jack_naming)) def _show_jack_patchbay(self, yesno: bool): self.save_window_settings( UI_PATCHBAY_HIDDEN if yesno else UI_PATCHBAY_SHOWN) if self._canvas_tools_action is not None: self._canvas_tools_action.setVisible(yesno) if self._canvas_menu is not None: self._canvas_menu.setVisible(yesno) rect = self.geometry() x = rect.x() y = rect.y() height = rect.height() if yesno: self.to_daemon('/ray/server/ask_for_patchbay') patchbay_geom = RS.settings.value('MainWindow/patchbay_geometry') sizes = RS.settings.value('MainWindow/splitter_canvas_sizes') if patchbay_geom: self.restoreGeometry(patchbay_geom) else: self.setGeometry(x, y, max(rect.width(), 1024), height) if sizes: self.ui.splitterMainVsCanvas.setSizes([int(s) for s in sizes]) else: self.session.patchbay_manager.disannounce() if self.isMaximized(): self.showNormal() geom = RS.settings.value('MainWindow/geometry') if geom: self.restoreGeometry(geom) else: self.setGeometry(x, y, 460, height) self.ui.splitterMainVsCanvas.setSizes([100, 0]) self.ui.graphicsView.setVisible(yesno) self.ui.framePatchbayFilters.setVisible(False) self.ui.splitterMainVsCanvas.set_active(yesno) self.ui.listWidget.patchbay_is_shown(yesno) def _status_bar_pressed(self): status = self.session.server_status if status not in ( ray.ServerStatus.PRECOPY, ray.ServerStatus.COPY, ray.ServerStatus.SNAPSHOT, ray.ServerStatus.OUT_SNAPSHOT, ray.ServerStatus.WAIT_USER): return if status in (ray.ServerStatus.PRECOPY, ray.ServerStatus.COPY): if not self.server_copying: return dialog = child_dialogs.AbortServerCopyDialog(self) dialog.exec() if not dialog.result(): return self.to_daemon('/ray/server/abort_copy') elif status in (ray.ServerStatus.SNAPSHOT, ray.ServerStatus.OUT_SNAPSHOT): self._show_snapshot_progress_dialog() elif status == ray.ServerStatus.WAIT_USER: dialog = child_dialogs.WaitingCloseUserDialog(self) dialog.exec() def _rename_session_conditionnaly(self, new_session_name): self.to_daemon('/ray/session/rename', new_session_name) def _show_snapshot_progress_dialog(self): if self._progress_dialog_visible: return self._progress_dialog_visible = True dialog = child_dialogs.SnapShotProgressDialog(self) dialog.server_progress(self.server_progress) dialog.exec() self._progress_dialog_visible = False if not dialog.result(): return self.to_daemon('/ray/server/abort_snapshot') def _show_daemon_url_window(self, err_code, ex_url=''): if not CommandLineArgs.under_nsm: server = GuiServerThread.instance() if server and ray.are_on_same_machine(server.url, ex_url): # here we are in the case daemon and GUI have not the same VERSION # If a session is running, inform user # else, just stop the daemon and quit session_path = subprocess.run( ['ray_control', 'get_session_path'], capture_output=True) if session_path.stdout: dialog = child_dialogs.WrongVersionLocalDialog(self) dialog.exec() if dialog.result(): subprocess.run(['ray_control', 'quit']) self._quit_app_now() else: subprocess.run(['ray_control', 'quit']) self._quit_app_now() return dialog = child_dialogs.DaemonUrlWindow(self, err_code, ex_url) dialog.exec() if not dialog.result(): if (CommandLineArgs.under_nsm and self.daemon_manager.launched_before): QApplication.quit() return new_url = dialog.get_url() tried_urls = ray.get_list_in_settings(RS.settings, 'network/tried_urls') if new_url not in tried_urls: tried_urls.append(new_url) RS.settings.setValue('network/tried_urls', tried_urls) RS.settings.setValue('network/last_tried_url', new_url) self.session.signaler.daemon_url_changed.emit(new_url) def _client_properties_state_changed(self, client_id: str, visible: bool): self.ui.listWidget.client_properties_state_changed( client_id, visible) def _server_progress(self, progress: float): self.server_progress = progress self.ui.lineEditServerStatus.set_progress(progress) def _server_copying(self, copying: bool): self.server_copying = copying self._server_status_changed(self.session.server_status) def _server_status_changed(self, server_status): self.session.update_server_status(server_status) self.ui.lineEditServerStatus.setText( server_status_string(server_status)) self.ui.frameCurrentSession.setEnabled( bool(server_status != ray.ServerStatus.OFF)) if self._systray_mode == ray.Systray.SESSION_ONLY: if server_status == ray.ServerStatus.OFF: self._systray.hide() else: self._systray.show() if server_status in (ray.ServerStatus.SNAPSHOT, ray.ServerStatus.OUT_SNAPSHOT): self._timer_snapshot.start() elif self._timer_snapshot.isActive(): self._timer_snapshot.stop() if server_status == ray.ServerStatus.COPY: self.ui.actionSaveSession.setEnabled(False) self.ui.actionCloseSession.setEnabled(False) self.ui.actionAbortSession.setEnabled(False) self.ui.actionReturnToAPreviousState.setEnabled(False) return if server_status == ray.ServerStatus.PRECOPY: self.ui.actionSaveSession.setEnabled(False) self.ui.actionCloseSession.setEnabled(False) self.ui.actionAbortSession.setEnabled(True) self.ui.actionDuplicateSession.setEnabled(False) self.ui.actionDuplicateSession_2.setEnabled(False) self.ui.actionSaveTemplateSession.setEnabled(False) self.ui.actionSaveTemplateSession_2.setEnabled(False) self.ui.actionReturnToAPreviousState.setEnabled(False) self.ui.actionAddApplication.setEnabled(False) self.ui.actionAddExecutable.setEnabled(False) self.ui.actionOpenSessionFolder.setEnabled(True) self.ui.actionSessionNotes.setEnabled(False) return close_or_off = bool( server_status in ( ray.ServerStatus.CLOSE, ray.ServerStatus.WAIT_USER, ray.ServerStatus.OUT_SAVE, ray.ServerStatus.OUT_SNAPSHOT, ray.ServerStatus.OFF)) ready = bool(server_status == ray.ServerStatus.READY) self.ui.actionSaveSession.setEnabled(ready) self.ui.actionCloseSession.setEnabled(ready) self.ui.actionAbortSession.setEnabled( not bool(server_status in (ray.ServerStatus.CLOSE, ray.ServerStatus.OFF))) self.ui.actionDuplicateSession.setEnabled(not close_or_off) self.ui.actionDuplicateSession_2.setEnabled(not close_or_off) self.ui.actionReturnToAPreviousState.setEnabled(not close_or_off) self.ui.actionRenameSession.setEnabled(ready) self.ui.actionRenameSession_2.setEnabled(ready) self.ui.actionSaveTemplateSession.setEnabled(not close_or_off) self.ui.actionSaveTemplateSession_2.setEnabled(not close_or_off) self.ui.actionAddApplication.setEnabled(not close_or_off) self.ui.actionAddExecutable.setEnabled(not close_or_off) self.ui.toolButtonFavorites.setEnabled( bool(self.session.favorite_list and not close_or_off)) self._favorites_menu.setEnabled( bool(self.session.favorite_list and not close_or_off)) self.ui.actionOpenSessionFolder.setEnabled( bool(server_status != ray.ServerStatus.OFF)) self.ui.actionSessionNotes.setEnabled( bool(server_status != ray.ServerStatus.OFF)) self.ui.stackedWidgetSessionName.set_editable( ready and self.session.is_renameable) self.ui.trashButton.setEnabled(bool(self.session.trashed_clients) and not close_or_off) self._systray_menu_add.setEnabled(not close_or_off) if (CommandLineArgs.under_nsm and not CommandLineArgs.out_daemon and ready and self.session.is_renameable): self.ui.stackedWidgetSessionName.set_on_edit() if self.server_copying: self.ui.actionSaveSession.setEnabled(False) self.ui.actionCloseSession.setEnabled(False) if CommandLineArgs.under_nsm: self.ui.actionNewSession.setEnabled(False) self.ui.actionOpenSession.setEnabled(False) self.ui.actionDuplicateSession.setEnabled(False) self.ui.actionCloseSession.setEnabled(False) self.ui.actionAbortSession.setEnabled(False) self.ui.menuRecentSessions.setEnabled(False) if server_status == ray.ServerStatus.OFF: if self.terminate_request: self.daemon_manager.stop() if server_status == ray.ServerStatus.WAIT_USER: if not RS.is_hidden(RS.HD_WaitCloseUser): dialog = child_dialogs.WaitingCloseUserDialog(self) dialog.exec() def _make_all_dialogs_reappear(self): ok = QMessageBox.question( self, _translate('hidden_dialogs', 'Make reappear dialog windows'), _translate('hidden_dialogs', 'Do you want to make reappear all dialogs you wanted to hide ?')) if not ok: return RS.reset_hiddens() def _build_systray_menu(self): is_shown = self._systray.isVisible() self._systray.hide() self._systray_menu.clear() self._systray_menu_add.clear() del self._systray_menu del self._systray_menu_add self._systray_menu = QMenu() self._systray_menu_add = QMenu( _translate('menu', 'Add'), self._systray_menu) self._systray_menu_add.addMenu(self._favorites_menu) self._systray_menu_add.addAction(self.ui.actionAddApplication) self._systray_menu_add.addAction(self.ui.actionAddExecutable) self._systray_menu_add.setIcon(QIcon.fromTheme('list-add')) self._systray_menu_add.setEnabled( self.session.server_status not in (ray.ServerStatus.OFF, ray.ServerStatus.CLOSE, ray.ServerStatus.WAIT_USER, ray.ServerStatus.OUT_SAVE, ray.ServerStatus.OUT_SNAPSHOT)) if self._reversed_systray_menu: self._systray_menu.addAction(self.ui.actionQuit) self._systray_menu.addSeparator() self._systray_menu.addAction(self.ui.actionSystemTrayIconOptions) self._systray_menu.addSeparator() self._systray_menu.addMenu(self.ui.menuRecentSessions) self._systray_menu.addAction(self.ui.actionOpenSession) self._systray_menu.addAction(self.ui.actionNewSession) self._systray_menu.addSeparator() self._systray_menu.addAction(self.ui.actionAbortSession) self._systray_menu.addAction(self.ui.actionCloseSession) self._systray_menu.addMenu(self._systray_menu_add) self._systray_menu.addAction(self.ui.actionSaveSession) else: self._systray_menu.addAction(self.ui.actionSaveSession) self._systray_menu.addMenu(self._systray_menu_add) self._systray_menu.addAction(self.ui.actionCloseSession) self._systray_menu.addAction(self.ui.actionAbortSession) self._systray_menu.addSeparator() self._systray_menu.addAction(self.ui.actionNewSession) self._systray_menu.addAction(self.ui.actionOpenSession) self._systray_menu.addMenu(self.ui.menuRecentSessions) self._systray_menu.addSeparator() self._systray_menu.addAction(self.ui.actionSystemTrayIconOptions) self._systray_menu.addSeparator() self._systray_menu.addAction(self.ui.actionQuit) self._systray.setContextMenu(self._systray_menu) if is_shown: self._systray.show() def _systray_activated(self): wayland = bool(ray.get_window_manager() == ray.WindowManager.WAYLAND) if self.isMinimized(): if self.hidden_maximized: self.showMaximized() else: self.showNormal() if not wayland: self.activateWindow() elif self.isHidden(): self.show() if not wayland: self.activateWindow() elif self.isActiveWindow(): self.hide() elif wayland: self.hide() else: self.activateWindow() ###FUNCTIONS RELATED TO SIGNALS FROM OSC SERVER####### def toggle_scene_full_screen(self): visible_maximized = 0x1 visible_menubar = 0x2 if self._fullscreen_patchbay: self.ui.toolBar.setVisible(True) if self._were_visible_before_fullscreen & visible_menubar: self.ui.menuBar.setVisible(True) if self._were_visible_before_fullscreen & visible_maximized: self.showNormal() self.showMaximized() else: self.showNormal() if self._geom_before_fullscreen is not None: self.setGeometry(self._geom_before_fullscreen) self.ui.splitterMainVsCanvas.setSizes( self._splitter_pos_before_fullscreen) self._fullscreen_patchbay = False else: self._were_visible_before_fullscreen = \ visible_maximized * int(self.isMaximized()) \ + visible_menubar * int(self.ui.menuBar.isVisible()) self._geom_before_fullscreen = self.geometry() self.ui.menuBar.setVisible(False) self.ui.toolBar.setVisible(False) self._splitter_pos_before_fullscreen = \ self.ui.splitterMainVsCanvas.sizes() self.ui.splitterMainVsCanvas.setSizes([0, 100]) self._fullscreen_patchbay = True self.showFullScreen() def add_patchbay_tools(self, tools_widget, canvas_menu): self._canvas_tools_action = self.ui.toolBar.addWidget(tools_widget) self._canvas_menu = self.ui.menuBar.addMenu(canvas_menu) def create_client_widget(self, client): return self.ui.listWidget.create_client_widget(client) def re_create_list_widget(self): # this function shouldn't exist, # it is a workaround for a bug with python-qt. # (when reorder widgets sometimes one widget is totally hidden # until user resize the window) # It has to be modified when ui_raysession is modified. self.ui.listWidget.clear() self.ui.verticalLayout.removeWidget(self.ui.listWidget) del self.ui.listWidget self.ui.listWidget = list_widget_clients.ListWidgetClients( self.ui.frameCurrentSession) self.ui.listWidget.setAcceptDrops(True) self.ui.listWidget.setStyleSheet("QFrame{border:none}") self.ui.listWidget.setDragEnabled(True) self.ui.listWidget.setDragDropMode(QAbstractItemView.InternalMove) self.ui.listWidget.setSelectionMode(QAbstractItemView.SingleSelection) self.ui.listWidget.setUniformItemSizes(False) self.ui.listWidget.setBatchSize(80) self.ui.listWidget.setObjectName("listWidget") self.ui.listWidget.set_session(self.session) self.ui.verticalLayout.addWidget(self.ui.listWidget) def canvas_callback(self, action: int, value1: int, value2: int, value_str: str): self.session.signaler.canvas_callback.emit( action, value1, value2, value_str) def set_nsm_locked(self, nsm_locked: bool): self.ui.actionNewSession.setEnabled(not nsm_locked) self.ui.actionOpenSession.setEnabled(not nsm_locked) self.ui.actionDuplicateSession.setEnabled(not nsm_locked) self.ui.actionCloseSession.setEnabled(not nsm_locked) self.ui.actionAbortSession.setEnabled(not nsm_locked) self.ui.toolBar.setVisible(True) self.ui.toolButtonNoRole.setVisible(nsm_locked) self.ui.toolButtonAbortSession.setVisible(not nsm_locked) self.ui.closeButton.setVisible(not nsm_locked) self.ui.toolButtonControl2.setVisible(nsm_locked) self.ui.stackedWidgetSessionName.set_editable( nsm_locked and not CommandLineArgs.out_daemon) self.ui.actionRenameSession.setEnabled( nsm_locked and not CommandLineArgs.out_daemon) self.ui.actionRenameSession_2.setEnabled( nsm_locked and not CommandLineArgs.out_daemon) frame_style_sheet = "SessionFrame{border-radius:4px;" if nsm_locked and CommandLineArgs.out_daemon: frame_style_sheet += "background-color: rgba(100, 181, 100, 35)}" elif nsm_locked: frame_style_sheet += "background-color: rgba(100, 100, 181, 35)}" else: frame_style_sheet += "background-color: rgba(127, 127, 127, 35)}" self.ui.frameCurrentSession.setStyleSheet(frame_style_sheet) def set_daemon_options(self, options): self.ui.actionBookmarkSessionFolder.setChecked( bool(options & ray.Option.BOOKMARK_SESSION)) self.ui.actionDesktopsMemory.setChecked( bool(options & ray.Option.DESKTOPS_MEMORY)) self.ui.actionAutoSnapshot.setChecked( bool(options & ray.Option.SNAPSHOTS)) self.ui.actionSessionScripts.setChecked( bool(options & ray.Option.SESSION_SCRIPTS)) self.ui.actionRememberOptionalGuiStates.setChecked( bool(options & ray.Option.GUI_STATES)) has_wmctrl = bool(options & ray.Option.HAS_WMCTRL) self.ui.actionDesktopsMemory.setEnabled(has_wmctrl) if has_wmctrl: self.ui.actionDesktopsMemory.setText( _translate('actions', 'Desktops Memory')) has_git = bool(options & ray.Option.HAS_GIT) self.ui.actionAutoSnapshot.setEnabled(has_git) self.ui.actionReturnToAPreviousState.setVisible(has_git) self.ui.toolButtonSnapshots.setVisible(has_git) if has_git: self.ui.actionAutoSnapshot.setText( _translate('actions', 'Auto Snapshot at Save')) self.has_git = has_git def donate(self, display_no_again=False): dialog = child_dialogs.DonationsDialog(self, display_no_again) dialog.exec() def edit_notes(self, close=False): icon_str = 'notes' if close: if self.session.notes: icon_str = 'notes-nonempty' if self.notes_dialog is not None and self.notes_dialog.isVisible(): self.notes_dialog.close() else: if self.notes_dialog is None: self.notes_dialog = child_dialogs.SessionNotesDialog(self) self.notes_dialog.show() icon_str = 'notes-editing' self.ui.actionSessionNotes.setIcon(RayIcon(icon_str, is_dark_theme(self))) def stop_client(self, client_id): client = self.session.get_client(client_id) if not client: return if client.check_last_save: if (client.no_save_level or (client.protocol == ray.Protocol.RAY_HACK and not client.ray_hack.saveable())): dialog = child_dialogs.StopClientNoSaveDialog(self, client_id) dialog.exec() if not dialog.result(): return elif client.status == ray.ClientStatus.READY: if client.has_dirty: if client.dirty_state: dialog = child_dialogs.StopClientDialog(self, client_id) dialog.exec() if not dialog.result(): return # last save (or start) more than 60 seconds ago elif (time.time() - client.last_save) >= 60: dialog = child_dialogs.StopClientDialog(self, client_id) dialog.exec() if not dialog.result(): return self.to_daemon('/ray/client/stop', client_id) def remove_client(self, client_id: str): self.ui.listWidget.remove_client_widget(client_id) def abort_copy_client(self, client_id: str): if not self.server_copying: return client = self.session.get_client(client_id) if not client or client.status not in ( ray.ClientStatus.COPY, ray.ClientStatus.PRECOPY): return dialog = child_dialogs.AbortClientCopyDialog(self, client_id) dialog.exec() if not dialog.result(): return self.to_daemon('/ray/server/abort_copy') def client_status_changed(self, client_id, status): # launch/stop flashing status if 'open' for client in self.session.client_list: if client.status == ray.ClientStatus.OPEN: if not self._timer_flicker_open.isActive(): self._timer_flicker_open.start() break else: self._timer_flicker_open.stop() # launch/stop timer_raisewin if keep focus if self._keep_focus: for client in self.session.client_list: if client.status == ray.ClientStatus.OPEN: if not self._timer_raisewin.isActive(): self._timer_raisewin.start() break else: self._timer_raisewin.stop() if status == ray.ClientStatus.READY: self._raise_window() def print_message(self, message): self.ui.textEditMessages.appendPlainText( time.strftime("%H:%M:%S") + ' ' + message) def rename_session(self, session_name, session_path): if session_name: self.setWindowTitle('%s - %s' % (ray.APP_TITLE, session_name)) self.ui.stackedWidgetSessionName.set_text(session_name) if self.notes_dialog is not None: self.notes_dialog.update_session() else: self.setWindowTitle(ray.APP_TITLE) self.ui.stackedWidgetSessionName.set_text( _translate('main view', 'No Session Loaded')) if self.notes_dialog is not None: self.notes_dialog.hide() self.update_recent_sessions_menu() def set_session_name_editable(self, set_edit: bool): self.ui.stackedWidgetSessionName.set_editable(set_edit) def update_recent_sessions_menu(self): self.ui.menuRecentSessions.clear() for sess in self.session.recent_sessions: sess_action = self.ui.menuRecentSessions.addAction(sess) if sess == self.session.get_short_path(): # disable running session sess_action.setEnabled(False) sess_action.setData(sess) sess_action.triggered.connect(self.launch_recent_session) self.ui.menuRecentSessions.setEnabled(bool(self.session.recent_sessions)) self._build_systray_menu() # here we start the startup dialog # FIXME - not a good place if (not RS.is_hidden(RS.HD_StartupRecentSessions) and time.time() - self._startup_time < 5 and self.session.recent_sessions and self.session.server_status == ray.ServerStatus.OFF): # ahah, dirty way to prevent a dialog once again self._startup_time -= 5 dialog = child_dialogs.StartupDialog(self) dialog.exec() if dialog.result(): self.to_daemon('/ray/server/open_session', dialog.get_selected_session()) elif dialog.get_clicked_action() == dialog.ACTION_NEW: self._create_new_session() elif dialog.get_clicked_action() == dialog.ACTION_OPEN: self._open_session() if dialog.not_again_value(): RS.set_hidden(RS.HD_StartupRecentSessions) def error_message(self, message: str): error_dialog = child_dialogs.ErrorDialog(self, message) error_dialog.exec() def opening_nsm_session(self): if RS.is_hidden(RS.HD_OpenNsmSession): return dialog = child_dialogs.OpenNsmSessionInfoDialog(self) dialog.exec() def trash_add(self, trashed_client): act_x_trashed = self._trash_menu.addAction( get_app_icon(trashed_client.icon, self), trashed_client.prettier_name()) act_x_trashed.setData(trashed_client.client_id) act_x_trashed.triggered.connect(self.show_client_trash_dialog) self.ui.trashButton.setEnabled( bool(not self.session.server_status in ( ray.ServerStatus.OFF, ray.ServerStatus.OUT_SAVE, ray.ServerStatus.WAIT_USER, ray.ServerStatus.OUT_SNAPSHOT, ray.ServerStatus.CLOSE))) return act_x_trashed def trash_remove(self, menu_action): self._trash_menu.removeAction(menu_action) if not self.session.trashed_clients: self.ui.trashButton.setEnabled(False) def trash_clear(self): self._trash_menu.clear() self.ui.trashButton.setEnabled(False) @pyqtSlot() def launch_recent_session(self): try: session_name = str(self.sender().data()) except BaseException: return self.to_daemon('/ray/server/open_session', session_name) @pyqtSlot() def show_client_trash_dialog(self): try: client_id = str(self.sender().data()) except BaseException: return for trashed_client in self.session.trashed_clients: if trashed_client.client_id == client_id: break else: return dialog = child_dialogs.ClientTrashDialog(self, trashed_client) dialog.exec() if not dialog.result(): return self.to_daemon('/ray/trashed_client/restore', client_id) @pyqtSlot() def launch_favorite(self): template_name, factory = self.sender().data() self.to_daemon('/ray/session/add_client_template', int(factory), template_name) def toggle_patchbay_filters_bar(self): if not self.ui.graphicsView.isVisible(): return self.ui.framePatchbayFilters.setVisible( not self.ui.framePatchbayFilters.isVisible()) def set_patchbay_filter_text(self, text: str): ''' used by client widget to find patchbay boxes ''' self.ui.framePatchbayFilters.setVisible(True) self.ui.framePatchbayFilters.set_filter_text(text) def update_favorites_menu(self): self._favorites_menu.clear() enable = bool( self.session.favorite_list and not self.session.server_status in ( ray.ServerStatus.OFF, ray.ServerStatus.CLOSE, ray.ServerStatus.OUT_SAVE, ray.ServerStatus.OUT_SNAPSHOT)) self.ui.toolButtonFavorites.setEnabled(enable) for favorite in self.session.favorite_list: act_app = self._favorites_menu.addAction( get_app_icon(favorite.icon, self), favorite.name) act_app.setData([favorite.name, favorite.factory]) act_app.triggered.connect(self.launch_favorite) self._favorites_menu.setEnabled( bool(enable and self.session.favorite_list)) self._build_systray_menu() def show_script_info(self, text): if self._script_info_dialog and self._script_info_dialog.should_be_removed(): del self._script_info_dialog self._script_info_dialog = None if not self._script_info_dialog: self._script_info_dialog = child_dialogs.ScriptInfoDialog(self) self._script_info_dialog.set_info_label(text) self._script_info_dialog.show() def hide_script_info_dialog(self): if self._script_info_dialog: self._script_info_dialog.close() del self._script_info_dialog self._script_info_dialog = None def show_script_user_action_dialog(self, text: str): if self._script_action_dialog: self._script_action_dialog.close() del self._script_action_dialog self.to_daemon( '/error', '/ray/gui/script_user_action', ray.Err.NOT_NOW, 'another script_user_action take place') self._script_action_dialog = child_dialogs.ScriptUserActionDialog(self) self._script_action_dialog.set_main_text(text) self._script_action_dialog.show() def hide_script_user_action_dialog(self): if self._script_action_dialog: self._script_action_dialog.close() del self._script_action_dialog self._script_action_dialog = None def daemon_crash(self): QMessageBox.critical( self, _translate('errors', "daemon crash!"), _translate('errors', "ray-daemon crashed, sorry !")) QApplication.quit() def save_window_settings(self, patchbay_mode=UI_PATCHBAY_UNDEF): if self.isFullScreen(): return with_patchbay = False if patchbay_mode == UI_PATCHBAY_UNDEF: with_patchbay = self.ui.actionShowJackPatchbay.isChecked() elif patchbay_mode == UI_PATCHBAY_SHOWN: with_patchbay = True geom_path = 'MainWindow/geometry' if with_patchbay: geom_path = 'MainWindow/patchbay_geometry' RS.settings.setValue( 'MainWindow/splitter_canvas_sizes', self.ui.splitterMainVsCanvas.sizes()) RS.settings.setValue(geom_path, self.saveGeometry()) RS.settings.setValue('MainWindow/WindowState', self.saveState()) RS.settings.setValue( 'MainWindow/ShowMenuBar', self.ui.menuBar.isVisible()) RS.settings.setValue("MainWindow/show_patchbay", self.ui.actionShowJackPatchbay.isChecked()) RS.settings.setValue("MainWindow/splitter_messages", self.ui.splitterSessionVsMessages.sizes()) RS.settings.sync() # Reimplemented Qt Functions def closeEvent(self, event): self.save_window_settings() self.hidden_maximized = self.isMaximized() if self._systray.isVisible() and self.session.is_running(): if not RS.is_hidden(RS.HD_SystrayClose): dialog = child_dialogs.SystrayCloseDialog(self) dialog.exec() if not dialog.result(): event.ignore() return if dialog.not_again(): RS.set_hidden(RS.HD_SystrayClose) self.hide() return if self._quit_app(): QMainWindow.closeEvent(self, event) else: event.ignore() def leaveEvent(self, event): if self.isActiveWindow(): self.mouse_is_inside = False QDialog.leaveEvent(self, event) def enterEvent(self, event): self.mouse_is_inside = True QDialog.enterEvent(self, event) def showEvent(self, event): if CommandLineArgs.under_nsm: if self.session.nsm_child is not None: self.session.nsm_child.send_gui_state(True) QMainWindow.showEvent(self, event) def hideEvent(self, event): self.hidden_maximized = self.isMaximized() if CommandLineArgs.under_nsm: if self.session.nsm_child is not None: self.session.nsm_child.send_gui_state(False) QMainWindow.hideEvent(self, event) def resizeEvent(self, event): if self._fullscreen_patchbay and not self.isFullScreen(): self.toggle_scene_full_screen() QMainWindow.resizeEvent(self, event) new_button = self.ui.toolBar.widgetForAction(self.ui.actionNewSession) open_button = self.ui.toolBar.widgetForAction(self.ui.actionOpenSession) if self.width() > 410: for button in (new_button, open_button): button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) elif self.width() > 310: new_button.setToolButtonStyle(Qt.ToolButtonIconOnly) open_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) else: new_button.setToolButtonStyle(Qt.ToolButtonIconOnly) open_button.setToolButtonStyle(Qt.ToolButtonIconOnly) RaySession-0.12.2/src/gui/nsm_child.py000066400000000000000000000101431417052567600175740ustar00rootroot00000000000000 import ray import nsm_client from gui_tools import CommandLineArgs, _translate from gui_server_thread import GuiServerThread class NsmChild: def __init__(self, session): self.session = session self.nsm_signaler = nsm_client.NSMSignaler() self.nsm_signaler.server_sends_open.connect(self._open) self.nsm_signaler.server_sends_save.connect(self._save) self.nsm_signaler.show_optional_gui.connect(self._show_optional_gui) self.nsm_signaler.hide_optional_gui.connect(self._hide_optional_gui) self.wait_for_open = False self.wait_for_save = False self.project_path = '' serverNSM = nsm_client.NSMThread('raysession_child', self.nsm_signaler, CommandLineArgs.NSM_URL, CommandLineArgs.debug) serverNSM.start() self.session.signaler.daemon_announce_ok.connect( self._announce_to_parent) self.session.signaler.server_status_changed.connect( self._server_status_changed) def _announce_to_parent(self): server_nsm = nsm_client.NSMThread.instance() if server_nsm: server_nsm.announce(_translate('child_session', 'Child Session'), ':switch:optional-gui:', 'raysession') def _server_status_changed(self, server_status: int): if server_status == ray.ServerStatus.READY: server_nsm = nsm_client.NSMThread.instance() if not server_nsm: return if self.wait_for_open: server_nsm.openReply() self.wait_for_open = False elif self.wait_for_save: server_nsm.saveReply() self.wait_for_save = False def _open(self, project_path: str, session_name: str, jack_client_name: str): self.wait_for_open = True self.project_path = project_path server = GuiServerThread.instance() if server: server.open_session(project_path, 0) self.send_gui_state(self.session.main_win.isVisible()) def _save(self): if self.session.main_win: self.session.main_win.save_window_settings() self.wait_for_save = True server = GuiServerThread.instance() if server: server.save_session() def _show_optional_gui(self): if self.session.main_win: self.session.main_win.show() def _hide_optional_gui(self): if self.session.main_win: self.session.main_win.hide() def send_gui_state(self, state: bool): serverNSM = nsm_client.NSMThread.instance() if serverNSM: serverNSM.sendGuiState(state) class NsmChildOutside(NsmChild): def __init__(self, session): NsmChild.__init__(self, session) self.wait_for_close = False def _announce_to_parent(self): server_nsm = nsm_client.NSMThread.instance() if server_nsm: server_nsm.announce( _translate('network_session', 'Network Session'), ':switch:optional-gui:ray-network:', ray.RAYNET_BIN) server_nsm.sendToDaemon( '/nsm/client/network_properties', self.session.daemon_manager.url, self.session.daemon_manager.session_root) self.session.main_win.hide() def _save(self): server_nsm = nsm_client.NSMThread.instance() if server_nsm: server_nsm.sendToDaemon( '/nsm/client/network_properties', self.session.daemon_manager.url, self.session.daemon_manager.session_root) NsmChild._save(self) def _open(self, project_path: str, session_name: str, jack_client_name: str): self.wait_for_open = True #Here project_path is used for template if needed template_name = jack_client_name server = GuiServerThread.instance() if server: server.open_session(project_path, 0, template_name) self.send_gui_state(self.session.main_win.isVisible()) RaySession-0.12.2/src/gui/nsm_client.py000077700000000000000000000000001417052567600241512../shared/nsm_client.pyustar00rootroot00000000000000RaySession-0.12.2/src/gui/open_session_dialog.py000066400000000000000000001151641417052567600216700ustar00rootroot00000000000000 import os import shutil import time from PyQt5.QtWidgets import (QApplication, QTreeWidget, QTreeWidgetItem, QDialogButtonBox, QMenu, QInputDialog, QMessageBox) from PyQt5.QtGui import QIcon, QColor, QCursor from PyQt5.QtCore import Qt, QTimer, QDateTime, QSize, QLocale, QPoint import child_dialogs import ray from gui_tools import CommandLineArgs, RS, RayIcon, is_dark_theme, basename from child_dialogs import ChildDialog from client_properties_dialog import ClientPropertiesDialog from snapshots_dialog import ( Snapshot, SnapGroup, GROUP_MAIN) import ui.open_session _translate = QApplication.translate COLUMN_NAME = 0 COLUMN_NOTES = 1 COLUMN_SCRIPTS = 2 COLUMN_DATE = 3 PENDING_ACTION_NONE = 0 PENDING_ACTION_RENAME = 1 PENDING_ACTION_DUPLICATE = 2 PENDING_ACTION_TEMPLATE = 3 CORNER_HIDDEN = 0 CORNER_LISTING = 1 CORNER_COPY = 2 CORNER_NOTIFICATION = 3 DATA_SIZE = Qt.UserRole + 1 class SessionItem(QTreeWidgetItem): def __init__(self, l_list, is_session=False): QTreeWidgetItem.__init__(self, l_list) self.is_session = is_session self.setTextAlignment(3, Qt.AlignRight | Qt.AlignVCenter) def __lt__(self, other): if self.childCount() and not other.childCount(): return True if other.childCount() and not self.childCount(): return False if OpenSessionDialog.sort_by_date: self_date_int = self.data(COLUMN_DATE, Qt.UserRole) other_date_int = other.data(COLUMN_DATE, Qt.UserRole) if self_date_int is None: if other_date_int is None: return bool(self.text(COLUMN_NAME).lower() < other.text(COLUMN_NAME).lower()) return False if other_date_int is None: return True return self_date_int > other_date_int return bool(self.text(COLUMN_NAME).lower() < other.text(COLUMN_NAME).lower()) def show_conditionnaly(self, string: str)->bool: show = bool( string.lower() in self.data(COLUMN_NAME, Qt.UserRole).lower()) n = 0 for i in range(self.childCount()): if self.child(i).show_conditionnaly(string.lower()): n += 1 if n: show = True self.setExpanded(bool(n and string)) self.setHidden(not show) return show def find_item_with(self, string): if self.data(COLUMN_NAME, Qt.UserRole) == string: return self item = None for i in range(self.childCount()): item = self.child(i).find_item_with(string) if item: break return item def set_notes_icon(self, icon): self.setIcon(COLUMN_NOTES, icon) def set_scripted(self, script_flags:int, for_child=False): if script_flags == ray.ScriptFile.PREVENT: self.setText(COLUMN_SCRIPTS, "") else: if for_child: self.setText(COLUMN_SCRIPTS, "^_") else: self.setText(COLUMN_SCRIPTS, ">_") for i in range(self.childCount()): item = self.child(i) item.set_scripted(script_flags, for_child=True) def set_modified_date(self, date_int:int): self.setData(COLUMN_DATE, Qt.UserRole, date_int) date = QDateTime.fromSecsSinceEpoch(date_int) date_string = date.toString("dd/MM/yy hh:mm") if QLocale.system().country() == QLocale.UnitedStates: date_string = date.toString("MM/dd/yy hh:mm") self.setText(COLUMN_DATE, date_string) def add_modified_date(self, path:str, date_int:int): self_path = self.data(COLUMN_NAME, Qt.UserRole) if not self_path: return if path == self_path: self.set_modified_date(date_int) return if path.startswith(self_path + '/'): current_data_date = self.data(COLUMN_DATE, Qt.UserRole) if current_data_date is None: current_data_date = 0 if date_int > current_data_date: self.set_modified_date(date_int) for i in range(self.childCount()): child_item = self.child(i) child_item.add_modified_date(path, date_int) def set_locked(self, locked:bool): if locked: self.setFlags(self.flags() & ~Qt.ItemIsEnabled) else: self.setFlags(self.flags() | Qt.ItemIsEnabled) class SessionFolder: name = "" path = "" is_session = False def __init__(self, name): self.name = name self.subfolders = [] self.item = None def set_path(self, path): self.path = path def make_item(self): self.item = SessionItem([self.name, "", "", ""], self.is_session) self.item.setData(COLUMN_NAME, Qt.UserRole, self.path) if self.subfolders: self.item.setIcon(COLUMN_NAME, QIcon.fromTheme('folder')) if not self.is_session: self.item.setFlags(self.item.flags() & ~Qt.ItemIsSelectable) for folder in self.subfolders: sub_item = folder.make_item() self.item.addChild(sub_item) return self.item def sort_childrens(self): if self.item is None: return self.item.sortChildren(COLUMN_NAME, Qt.AscendingOrder) for folder in self.subfolders: folder.sort_childrens() def find_item_with(self, sess_name:str): if self.item is None: return None return self.item.find_item_with(sess_name) class SaveSessionTemplateDialog(child_dialogs.SaveTemplateSessionDialog): def __init__(self, parent): child_dialogs.SaveTemplateSessionDialog.__init__(self, parent) self._server_will_accept = True def _server_status_changed(self, server_status): # server will always accept, whatever the status pass def set_original_session_name(self, session_name:str): self.ui.labelLabel.setText(session_name) class DuplicateDialog(child_dialogs.NewSessionDialog): def __init__(self, parent): child_dialogs.NewSessionDialog.__init__( self, parent, duplicate_window=True) self._server_will_accept = True self.ui.toolButtonFolder.setEnabled(False) self.ui.toolButtonFolder.setVisible(False) self._original_session_name = '' def _server_status_changed(self, server_status): # server will always accept, whatever the status pass def _add_sessions_to_list(self, session_names: list): child_dialogs.NewSessionDialog._add_sessions_to_list(self, session_names) if not session_names: subfolder, sep, after = self._original_session_name.rpartition('/') self.ui.lineEdit.setText(subfolder + sep) def set_original_session_name(self, session_name:str): self._original_session_name = session_name self.ui.labelOriginalSessionName.setText(session_name) class OpenSessionDialog(ChildDialog): sort_by_date = False @classmethod def set_sort_by_date(cls, sort_by_date:bool): cls.sort_by_date = sort_by_date def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.open_session.Ui_DialogOpenSession() self.ui.setupUi(self) self._pending_action = PENDING_ACTION_NONE self._session_renaming = ('', '') self._session_duplicating = ('', '') self._session_templating = ('', '') self._listing_timer_progress_n = 0 self._listing_timer_progress = QTimer() self._listing_timer_progress.setInterval(50) self._listing_timer_progress.timeout.connect(self._listing_timer_progress_timeout) self._listing_timer_progress.start() self._progress_inverted = False self.session_menu = QMenu() self.action_duplicate = self.session_menu.addAction( QIcon.fromTheme('duplicate'), _translate('session_menu', 'Duplicate session')) self.action_save_as_template = self.session_menu.addAction( QIcon.fromTheme('template'), _translate('session_menu', 'Save session as template')) self.action_rename = self.session_menu.addAction( QIcon.fromTheme('edit-rename'), _translate('session_menu', 'Rename session')) self.action_remove = self.session_menu.addAction( QIcon.fromTheme('remove'), _translate('session_menu', 'Remove session')) dark = is_dark_theme(self) self.action_duplicate.setIcon( RayIcon('xml-node-duplicate', dark)) self.action_save_as_template.setIcon( RayIcon('document-save-as-template', dark)) self.action_rename.triggered.connect(self._ask_for_session_rename) self.action_duplicate.triggered.connect(self._ask_for_session_duplicate) self.action_save_as_template.triggered.connect( self._ask_for_session_save_as_template) self.action_remove.triggered.connect(self._ask_for_session_remove) self.ui.toolButtonSessionMenu.setMenu(self.session_menu) self.ui.toolButtonFolderPreview.clicked.connect( self._open_preview_folder) self.ui.splitterMain.setSizes([240, 800]) self.ui.stackedWidgetSessionName.set_text('') self.ui.previewFrame.setEnabled(False) self.ui.tabWidget.tabBar().setExpanding(True) self.ui.toolButtonFolder.clicked.connect(self._change_root_folder) self.ui.splitterMain.splitterMoved.connect( self._splitter_moved) self.ui.stackedWidgetSessionName.name_changed.connect( self._session_name_changed) self.ui.sessionList.currentItemChanged.connect( self._current_item_changed) self.ui.sessionList.setFocus(Qt.OtherFocusReason) self.ui.sessionList.itemDoubleClicked.connect(self._go_if_any) self.ui.sessionList.itemClicked.connect(self._deploy_item) self.ui.sessionList.customContextMenuRequested.connect( self._show_context_menu) self.ui.filterBar.textEdited.connect(self._update_filtered_list) self.ui.filterBar.key_event.connect(self._up_down_pressed) self.ui.listWidgetPreview.properties_request.connect( self._show_client_properties) self.ui.listWidgetPreview.add_to_session_request.connect( self._add_client_to_current_session) self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.ui.currentSessionsFolder.setText(CommandLineArgs.session_root) self.ui.checkBoxShowDates.stateChanged.connect( self._set_full_sessions_view) self.ui.pushButtonCancelProgress.clicked.connect( self._cancel_copy_clicked) self.signaler.add_sessions_to_list.connect(self._add_sessions) self.signaler.root_changed.connect(self._root_changed) self.signaler.session_preview_update.connect( self._session_preview_update) self.signaler.session_details.connect( self._update_session_details) self.signaler.scripted_dir.connect( self._scripted_dir) self.signaler.parrallel_copy_state.connect( self._parrallel_copy_state) self.signaler.parrallel_copy_progress.connect( self._parrallel_copy_progress) self.signaler.parrallel_copy_aborted.connect( self._parrallel_copy_aborted) self.signaler.other_session_renamed.connect( self._session_renamed_by_server) self.signaler.other_session_duplicated.connect( self._session_duplicated_by_server) self.signaler.other_session_templated.connect( self._session_templated_by_server) self.to_daemon('/ray/server/list_sessions', 0) self.ui.groupBoxProgress.setVisible(False) if not self.daemon_manager.is_local: self.ui.toolButtonFolder.setVisible(False) self.ui.currentSessionsFolder.setVisible(False) self.ui.labelSessionsFolder.setVisible(False) self._server_will_accept = False self._has_selection = False self._last_mouse_click = 0 self._last_session_item = None self._server_status_changed(self.session.server_status) self._set_preview_scripted(False) self.folders = [] self.all_items = [] self.ui.filterBar.setFocus(Qt.OtherFocusReason) # snapshots related self.main_snap_group = SnapGroup() self._full_view = True self._set_full_sessions_view(False) self._current_parrallel_copy_id = 0 self._corner_mode = CORNER_HIDDEN self._set_corner_group(CORNER_HIDDEN) self.ui.checkBoxSaveCurrentSession.setVisible( self.session.server_status == ray.ServerStatus.READY) self.ui.listWidgetPreview.server_status_changed( self.session.server_status) self._last_selected_session = '' self._listing_sessions = False def _set_full_sessions_view(self, full_view:bool): self.ui.sessionList.setHeaderHidden(not full_view) if full_view: self.ui.sessionList.setColumnCount(4) else: self.ui.sessionList.setColumnCount(3) self._full_view = full_view self._resize_session_names_column() OpenSessionDialog.set_sort_by_date(full_view) root_item = self.ui.sessionList.invisibleRootItem() root_item.sortChildren(COLUMN_NAME, Qt.AscendingOrder) for folder in self.folders: folder.sort_childrens() def _server_status_changed(self, server_status): self.ui.toolButtonFolder.setEnabled( bool(server_status in (ray.ServerStatus.OFF, ray.ServerStatus.READY, ray.ServerStatus.CLOSE))) self._server_will_accept = bool( server_status in ( ray.ServerStatus.OFF, ray.ServerStatus.READY) and not self.server_copying) if server_status != ray.ServerStatus.OFF: if self._root_folder_file_dialog is not None: self._root_folder_file_dialog.reject() self._root_folder_message_box.reject() self.ui.checkBoxSaveCurrentSession.setVisible( server_status == ray.ServerStatus.READY) self.ui.listWidgetPreview.server_status_changed(server_status) self._prevent_ok() def _listing_timer_progress_timeout(self): # server is listing sessions if self._listing_timer_progress_n >= 10: # 10 x 50ms = 500 ms # display groupBoxProgress only if listing takes at least 500ms # to prevent flircks self._set_corner_group(CORNER_LISTING) self.ui.progressBar.setValue(self._listing_timer_progress_n) if self._listing_timer_progress_n >= 100: self._listing_timer_progress_n = 0 self._progress_inverted = not self._progress_inverted self.ui.progressBar.setInvertedAppearance( self._progress_inverted) self._listing_timer_progress_n += 5 def _root_changed(self, session_root): self.ui.currentSessionsFolder.setText(session_root) self.ui.sessionList.clear() self.folders.clear() self.to_daemon('/ray/server/list_sessions', 0) def _add_sessions(self, session_names, out_of_listing=False): if not self._listing_sessions and not out_of_listing: # in case session server is listing sessions # but they are already listed. # Check which one is selected and clear all of them. item = self.ui.sessionList.currentItem() if item is not None: self._last_selected_session = item.data(COLUMN_NAME, Qt.UserRole) self.folders.clear() self.ui.sessionList.clear() if not session_names: # there are no session_names here if session listing # is finished. self._listing_sessions = False self._listing_timer_progress.stop() height = self.ui.groupBoxProgress.size().height() self._set_corner_group(CORNER_HIDDEN) root_item = self.ui.sessionList.invisibleRootItem() sess_item = None if self._last_selected_session: for folder in self.folders: item = folder.find_item_with(self._last_selected_session) if item is not None: self.ui.sessionList.setCurrentItem(item) self.ui.sessionList.scrollToItem(item) break else: self._last_selected_session = '' if not self._last_selected_session: for sess in self.session.recent_sessions: if sess == self.session.get_short_path(): continue for i in range(root_item.childCount()): item = root_item.child(i) sess_item = item.find_item_with(sess) if sess_item is not None: break if sess_item is not None: self.ui.sessionList.setCurrentItem(sess_item) self.ui.sessionList.scrollToItem(sess_item) break QTimer.singleShot(20, self._resize_session_names_column) return for session_name in session_names: folder_div = session_name.split('/') folders = self.folders #folder_path_list = [] for i in range(len(folder_div)): f = folder_div[i] for g in folders: if g.name == f: if i + 1 == len(folder_div): g.set_path(session_name) g.is_session = True folders = g.subfolders break else: new_folder = SessionFolder(f) if i + 1 == len(folder_div): new_folder.set_path(session_name) new_folder.is_session = True else: new_folder.set_path('/'.join(folder_div[:i+1])) folders.append(new_folder) folders = new_folder.subfolders if not out_of_listing: self._listing_sessions = True self.ui.sessionList.clear() for folder in self.folders: item = folder.make_item() self.ui.sessionList.addTopLevelItem(item) self.ui.sessionList.sortByColumn(COLUMN_NAME, Qt.AscendingOrder) def _update_filtered_list(self, filt): filter_text = self.ui.filterBar.displayText() root_item = self.ui.sessionList.invisibleRootItem() ## hide all non matching items for i in range(root_item.childCount()): root_item.child(i).show_conditionnaly(filter_text) # if selected item not in list, then select the first visible if (not self.ui.sessionList.currentItem() or self.ui.sessionList.currentItem().isHidden()): for i in range(root_item.childCount()): item = root_item.child(i) if not item.isHidden(): self.ui.sessionList.setCurrentItem(item) break if (not self.ui.sessionList.currentItem() or self.ui.sessionList.currentItem().isHidden()): self.ui.filterBar.setStyleSheet( "QLineEdit { background-color: red}") self.ui.sessionList.setCurrentItem(None) else: self.ui.filterBar.setStyleSheet("") self.ui.sessionList.scrollTo(self.ui.sessionList.currentIndex()) def _up_down_pressed(self, event): start_item = self.ui.sessionList.currentItem() QTreeWidget.keyPressEvent(self.ui.sessionList, event) if not start_item: return current_item = self.ui.sessionList.currentItem() if current_item == start_item: return ex_item = current_item while not current_item.flags() & Qt.ItemIsSelectable: ex_item = current_item QTreeWidget.keyPressEvent(self.ui.sessionList, event) current_item = self.ui.sessionList.currentItem() if current_item == ex_item: self.ui.sessionList.setCurrentItem(start_item) return def _current_item_changed(self, item, previous_item): self._has_selection = bool(item and item.data(COLUMN_NAME, Qt.UserRole)) self.ui.listWidgetPreview.clear() self.ui.treeWidgetSnapshots.clear() self.ui.labelSessionSize.setText('') if item is not None and item.is_session: session_full_name = item.data(COLUMN_NAME, Qt.UserRole) self.ui.stackedWidgetSessionName.set_text(basename(session_full_name)) self.ui.previewFrame.setEnabled(True) if session_full_name: self.to_daemon('/ray/server/get_session_preview', session_full_name) if item.text(COLUMN_SCRIPTS): self._set_preview_scripted(True) else: self._set_preview_scripted(False) else: self.ui.stackedWidgetSessionName.set_text('') self.ui.previewFrame.setEnabled(False) self._set_preview_scripted(False) if item is not None: self._last_current_item = item self._prevent_ok() def _set_preview_scripted(self, scripted:bool): if scripted: self.ui.labelPreviewScript.setText('>_') self.ui.labelPreviewScript.setToolTip( _translate('open_session', 'This session is scripted')) self.ui.labelPreviewScript.setStyleSheet( 'QLabel{color:green;background-color:black}') else: self.ui.labelPreviewScript.setText('') self.ui.labelPreviewScript.setToolTip('') self.ui.labelPreviewScript.setStyleSheet('') def _prevent_ok(self): self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(self._server_will_accept and self._has_selection)) def _show_context_menu(self): item = self.ui.sessionList.currentItem() if item is None: return if not item.is_session: return x = QCursor.pos().x() rect = self.ui.sessionList.visualItemRect(item) y = self.ui.sessionList.mapToGlobal(rect.bottomLeft()).y() self.session_menu.exec(QPoint(x, y+1)) def _set_pending_action(self, action:int): self._pending_action = action self._update_session_menu() def _open_preview_folder(self): item = self.ui.sessionList.currentItem() if item is None: return session_name = item.data(COLUMN_NAME, Qt.UserRole) self.to_daemon('/ray/server/open_file_manager_at', os.path.join(CommandLineArgs.session_root, session_name)) def _set_corner_group(self, corner_mode:int): self._corner_mode = corner_mode self.ui.groupBoxProgress.setVisible(corner_mode != CORNER_HIDDEN) self.ui.pushButtonCancelProgress.setVisible(corner_mode != CORNER_LISTING) if corner_mode == CORNER_LISTING: self.ui.labelProgress.setText( _translate('open_session', 'Listing sessions')) elif corner_mode == CORNER_COPY: self.ui.pushButtonCancelProgress.setText( _translate('open_session', 'Cancel')) self.ui.labelProgress.setText( _translate('open_session', 'Session copy')) self.ui.progressBar.setValue(0) elif corner_mode == CORNER_NOTIFICATION: self.ui.pushButtonCancelProgress.setText( _translate('open_session', 'Ok')) self.ui.labelProgress.setText( _translate('open_session', 'Session saved as template')) self.ui.progressBar.setValue(100) def _ask_for_session_rename(self): if not self.ui.previewFrame.isEnabled(): return self.ui.stackedWidgetSessionName.toggle_edit() def _ask_for_session_duplicate(self): item = self.ui.sessionList.currentItem() if item is None: return old_session_name = item.data(COLUMN_NAME, Qt.UserRole) if self._pending_action: return dialog = DuplicateDialog(self) dialog.set_original_session_name(old_session_name) dialog.exec() if not dialog.result(): return new_session_name = dialog.get_session_short_path() self._set_pending_action(PENDING_ACTION_DUPLICATE) self._session_duplicating = (old_session_name, new_session_name) self.to_daemon('/ray/session/duplicate_only', old_session_name, new_session_name, CommandLineArgs.session_root) def _ask_for_session_save_as_template(self): item = self.ui.sessionList.currentItem() if item is None: return if self._pending_action: return session_name = item.data(COLUMN_NAME, Qt.UserRole) dialog = SaveSessionTemplateDialog(self) dialog.set_original_session_name(session_name) dialog.exec() if not dialog.result(): return template_name = dialog.get_template_name() self._set_pending_action(PENDING_ACTION_TEMPLATE) self._session_templating = (session_name, template_name) self.to_daemon('/ray/server/save_session_template', session_name, template_name) def _ask_for_session_remove(self): # we won't call the server to remove a session # because it would enable a very dangerous OSC path. # we will remove it directly in the GUI process and thread if CommandLineArgs.out_daemon: return # do not allow to remove from GUI a too big session # totally arbitrary choice : 95.37 Mb if self.session.preview_size >= 100000000: return item = self.ui.sessionList.currentItem() if item is None: return session_name = item.data(COLUMN_NAME, Qt.UserRole) full_path = os.path.join(CommandLineArgs.session_root, session_name) if not os.path.isdir(full_path): return ret = QMessageBox.critical( self, _translate('open_session', 'Remove session'), _translate('open_session', '

Are you really sure to want to remove the following session:

' + '

%s

' + '

This action is irreversible.') % session_name, QMessageBox.No | QMessageBox.Yes, QMessageBox.No) if ret != QMessageBox.Yes: return try: shutil.rmtree(full_path) except: # TODO return parent = item.parent() if parent is None: parent = self.ui.sessionList.invisibleRootItem() parent.removeChild(item) def _session_name_changed(self, new_name:str): item = self.ui.sessionList.currentItem() if item is None: return old_name = item.data(COLUMN_NAME, Qt.UserRole) # prevent accidental renaming to same name if basename(old_name) == new_name: return if self._pending_action: return self._set_pending_action(PENDING_ACTION_RENAME) self._session_renaming = (old_name, new_name) self.to_daemon('/ray/server/rename_session', old_name, new_name) def _parrallel_copy_state(self, session_id:int, state:int): if state and self._current_parrallel_copy_id: return self._current_parrallel_copy_id = session_id if state else 0 if not state: self._set_corner_group(CORNER_HIDDEN) def _parrallel_copy_progress(self, session_id:int, progress:float): if session_id != self._current_parrallel_copy_id: return self._set_corner_group(CORNER_COPY) self.ui.progressBar.setValue(int(progress * 100)) def _parrallel_copy_aborted(self): self._set_corner_group(CORNER_HIDDEN) self._set_pending_action(PENDING_ACTION_NONE) def _cancel_copy_clicked(self): if not self._current_parrallel_copy_id: if self._corner_mode == CORNER_NOTIFICATION: self._set_corner_group(CORNER_HIDDEN) return self.to_daemon('/ray/server/abort_parrallel_copy', self._current_parrallel_copy_id) def _session_renamed_by_server(self): old_name, new_name = self._session_renaming self._session_renaming = ('', '') current_name = '' item = self.ui.sessionList.currentItem() if item is not None: current_name = item.data(COLUMN_NAME, Qt.UserRole) new_long_name = new_name if '/' in old_name: new_long_name = old_name.rpartition('/')[0] + '/' + new_name if current_name != old_name: # should rarely happens because rename session is very fast # in case session has been renamed but is not selected anymore for i in range(self.ui.sessionList.topLevelItemCount()): item = self.ui.sessionList.topLevelItem(i) session_item = item.find_item_with(old_name) if session_item is not None: session_item.setData(COLUMN_NAME, Qt.UserRole, new_long_name) session_item.setText(COLUMN_DATE, new_name) break return if item is None: return item.setData(COLUMN_NAME, Qt.UserRole, new_long_name) item.setText(COLUMN_NAME, new_name) self.ui.stackedWidgetSessionName.set_text(new_name) self._set_pending_action(PENDING_ACTION_NONE) def _session_duplicated_by_server(self): old_name, new_name = self._session_duplicating self._session_duplicating = ('', '') self._set_pending_action(PENDING_ACTION_NONE) self._add_sessions([new_name], out_of_listing=True) for folder in self.folders: item = folder.find_item_with(new_name) if item is not None: self.ui.sessionList.setCurrentItem(item) filter_text = self.ui.filterBar.text() if filter_text.lower() in new_name.lower(): self._update_filtered_list('') else: self.ui.filterBar.setText('') parent_item = item.parent() while parent_item is not None: parent_item.setExpanded(True) parent_item = parent_item.parent() self.ui.sessionList.scrollToItem(item) break self._set_corner_group(CORNER_HIDDEN) def _session_templated_by_server(self): session_name, template_name = self._session_templating self._session_templating = ('', '') if self._pending_action == PENDING_ACTION_TEMPLATE: self._set_corner_group(CORNER_NOTIFICATION) self._set_pending_action(PENDING_ACTION_NONE) def _deploy_item(self, item, column): if column == COLUMN_NOTES and not item.icon(COLUMN_NOTES).isNull(): # set preview tab to 'Notes' tab if user clicked on a notes icon self.ui.tabWidget.setCurrentIndex(1) if not item.childCount(): return if time.time() - self._last_mouse_click > 0.35: item.setExpanded(not item.isExpanded()) self._last_mouse_click = time.time() def _go_if_any(self, item, column): if item.childCount(): return if (self._server_will_accept and self._has_selection and self.ui.sessionList.currentItem().data( COLUMN_NAME, Qt.UserRole)): self.accept() def _session_preview_update(self): self.ui.plainTextEditNotes.setPlainText(self.session.preview_notes) for pv_client in self.session.preview_client_list: client_slot = self.ui.listWidgetPreview.create_client_widget(pv_client) client_slot.set_launched( pv_client.client_id in self.session.preview_started_clients) self.main_snap_group.snapshots.clear() self._add_snapshots(self.session.preview_snapshots) locale = QLocale() self.ui.labelSessionSize.setText( locale.formattedDataSize(self.session.preview_size)) # store size in item item = self.ui.sessionList.currentItem() if item is not None: item.setData(COLUMN_NAME, DATA_SIZE, self.session.preview_size) self._set_preview_scripted( bool(item.text(COLUMN_SCRIPTS))) else: self._set_preview_scripted(False) self._update_session_menu() def _update_session_menu(self): item = self.ui.sessionList.currentItem() if item is None: self.session_menu.setEnabled(False) return self.session_menu.setEnabled(True) session_size = item.data(COLUMN_NAME, DATA_SIZE) allow_remove = False remove_title = _translate('session_menu', 'Remove session') if session_size is not None: if session_size >= 100000000: remove_title = _translate('session_menu', 'Remove session (too big)') else: allow_remove = True self.action_remove.setText(remove_title) ok = not bool(self._pending_action) self.action_duplicate.setEnabled(ok) self.action_rename.setEnabled(ok) self.action_save_as_template.setEnabled(ok) self.action_remove.setEnabled(ok and allow_remove) def _add_snapshots(self, snaptexts): if not snaptexts and not self.main_snap_group.snapshots: # Snapshot list finished without any snapshot #self._no_snapshot_found() return for snaptext in snaptexts: if not snaptext: continue snapshot = Snapshot.new_from_snaptext(snaptext) self.main_snap_group.add(snapshot) self.main_snap_group.sort() self.ui.treeWidgetSnapshots.clear() for snapshot in self.main_snap_group.snapshots: item = snapshot.make_item(GROUP_MAIN) self.ui.treeWidgetSnapshots.addTopLevelItem(item) #self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.ui.treeWidgetSnapshots.clearSelection() def _update_session_details(self, session_name:str, has_notes:int, modified:int, locked:int): for i in range(self.ui.sessionList.topLevelItemCount()): item = self.ui.sessionList.topLevelItem(i) session_item = item.find_item_with(session_name) if session_item is not None: if has_notes: session_item.set_notes_icon( RayIcon('notes', is_dark_theme(self))) # we add directly date to top item # this way folder also read the last date item.add_modified_date(session_name, modified) session_item.set_locked(bool(locked)) break def _scripted_dir(self, dir_name, script_flags): if dir_name == '': # means that all the session root directory is scripted for i in range(self.ui.sessionList.topLevelItemCount()): item = self.ui.sessionList.topLevelItem(i) item.set_scripted(script_flags) return for i in range(self.ui.sessionList.topLevelItemCount()): item = self.ui.sessionList.topLevelItem(i) scripted_item = item.find_item_with(dir_name) if scripted_item is not None: scripted_item.set_scripted(script_flags) def _resize_session_names_column(self): self.ui.sessionList.setColumnWidth(COLUMN_NOTES, 20) self.ui.sessionList.setColumnWidth(COLUMN_SCRIPTS, 20) scroll_bar = self.ui.sessionList.verticalScrollBar() width = 20 if self._full_view: self.ui.sessionList.setColumnWidth(COLUMN_DATE, 105) width = self.ui.sessionList.width() - 150 if scroll_bar.isVisible(): width -= scroll_bar.width() width = max(width, 20) else: width = self.ui.sessionList.width() - 45 if scroll_bar.isVisible(): width -= scroll_bar.width() width = max(width, 40) self.ui.sessionList.setColumnWidth(COLUMN_NAME, width) def _show_client_properties(self, client_id:str): for pv_client in self.session.preview_client_list: if pv_client.client_id == client_id: properties_dialog = ClientPropertiesDialog.create( self, pv_client) properties_dialog.update_contents() properties_dialog.lock_widgets() properties_dialog.show() break def _add_client_to_current_session(self, client_id:str): item = self.ui.sessionList.currentItem() if item is None: return session_name = item.data(COLUMN_NAME, Qt.UserRole) self.to_daemon('/ray/session/add_other_session_client', session_name, client_id) self.reject() def _splitter_moved(self, pos:int, index:int): self._resize_session_names_column() def resizeEvent(self, event): ChildDialog.resizeEvent(self, event) self._resize_session_names_column() def closeEvent(self, event): self._cancel_copy_clicked() ChildDialog.closeEvent(self, event) def get_selected_session(self)->str: if self.ui.sessionList.currentItem(): return self.ui.sessionList.currentItem().data( COLUMN_NAME, Qt.UserRole) def want_to_save_previous(self)->bool: if self.ui.checkBoxSaveCurrentSession.isHidden(): return True return self.ui.checkBoxSaveCurrentSession.isChecked() RaySession-0.12.2/src/gui/patchbay_manager.py000066400000000000000000002275551417052567600211420ustar00rootroot00000000000000 import json import os import sys from PyQt5.QtGui import QCursor, QIcon, QGuiApplication from PyQt5.QtWidgets import QMenu, QAction, QLabel, QMessageBox from PyQt5.QtCore import pyqtSlot, QTimer, QPoint import ray from gui_tools import RS from patchcanvas import patchcanvas from gui_server_thread import GuiServerThread from patchbay_tools import PatchbayToolsWidget, CanvasMenu, CanvasPortInfoDialog import canvas_options # Port Type PORT_TYPE_NULL = 0 PORT_TYPE_AUDIO = 1 PORT_TYPE_MIDI = 2 # Port Mode PORT_MODE_NULL = 0 PORT_MODE_INPUT = 1 PORT_MODE_OUTPUT = 2 # Port Flags PORT_IS_INPUT = 0x01 PORT_IS_OUTPUT = 0x02 PORT_IS_PHYSICAL = 0x04 PORT_CAN_MONITOR = 0x08 PORT_IS_TERMINAL = 0x10 PORT_IS_CONTROL_VOLTAGE = 0x100 # Group Position Flags GROUP_CONTEXT_AUDIO = 0x01 GROUP_CONTEXT_MIDI = 0x02 GROUP_SPLITTED = 0x04 GROUP_WRAPPED_INPUT = 0x10 GROUP_WRAPPED_OUTPUT = 0x20 GROUP_HAS_BEEN_SPLITTED = 0x40 # Portgroup Origin PORTGROUP_FROM_DETECTION = 0 PORTGROUP_FROM_METADATA = 1 PORTGROUP_FROM_USER = 2 # Meta data (taken from pyjacklib) _JACK_METADATA_PREFIX = "http://jackaudio.org/metadata/" JACK_METADATA_CONNECTED = _JACK_METADATA_PREFIX + "connected" JACK_METADATA_EVENT_TYPES = _JACK_METADATA_PREFIX + "event-types" JACK_METADATA_HARDWARE = _JACK_METADATA_PREFIX + "hardware" JACK_METADATA_ICON_LARGE = _JACK_METADATA_PREFIX + "icon-large" JACK_METADATA_ICON_NAME = _JACK_METADATA_PREFIX + "icon-name" JACK_METADATA_ICON_SMALL = _JACK_METADATA_PREFIX + "icon-small" JACK_METADATA_ORDER = _JACK_METADATA_PREFIX + "order" JACK_METADATA_PORT_GROUP = _JACK_METADATA_PREFIX + "port-group" JACK_METADATA_PRETTY_NAME = _JACK_METADATA_PREFIX + "pretty-name" JACK_METADATA_SIGNAL_TYPE = _JACK_METADATA_PREFIX + "signal-type" _translate = QGuiApplication.translate class Connection: def __init__(self, connection_id: int, port_out, port_in): self.connection_id = connection_id self.port_out = port_out self.port_in = port_in self.in_canvas = False def port_type(self)->int: return self.port_out.type def add_to_canvas(self): if self.in_canvas: return if not PatchbayManager.port_types_view & self.port_type(): return self.in_canvas = True patchcanvas.connectPorts( self.connection_id, self.port_out.group_id, self.port_out.port_id, self.port_in.group_id, self.port_in.port_id, fast=PatchbayManager.optimized_operation) def remove_from_canvas(self): if not self.in_canvas: return patchcanvas.disconnectPorts( self.connection_id, fast=PatchbayManager.optimized_operation) self.in_canvas = False def semi_hide(self, yesno: bool): if not self.in_canvas: return patchcanvas.semi_hide_connection( self.connection_id, yesno) def set_in_front(self): if not self.in_canvas: return patchcanvas.set_connection_in_front(self.connection_id) class Port: display_name = '' group_id = -1 portgroup_id = 0 prevent_stereo = False last_digit_to_add = '' in_canvas = False order = None uuid = 0 # will contains the real JACK uuid # given by JACK metadatas pretty_name = '' mdata_portgroup = '' def __init__(self, port_id: int, name: str, port_type: int, flags: int, uuid: int): self.port_id = port_id self.full_name = name self.type = port_type self.flags = flags self.uuid = uuid def mode(self): if self.flags & PORT_IS_OUTPUT: return PORT_MODE_OUTPUT elif self.flags & PORT_IS_INPUT: return PORT_MODE_INPUT else: return PORT_MODE_NULL def short_name(self)->str: if self.full_name.startswith('a2j:'): long_name = self.full_name.partition(':')[2] if ': ' in long_name: # normal case for a2j return long_name.partition(': ')[2] if self.full_name.startswith('Midi-Bridge:'): # supress 'Midi-Bridge:' at port name begginning long_name = self.full_name.partition(':')[2] if ') ' in long_name: # normal case, name is after ') ' return long_name.partition(') ')[2] if ': ' in long_name: # pipewire jack.filter_name = True # Midi-bridge names starts with 'MidiBridge:ClientName:' return long_name.partition(': ')[2] return self.full_name.partition(':')[2] def add_the_last_digit(self): self.display_name += ' ' + self.last_digit_to_add self.last_digit_to_add = '' self.rename_in_canvas() def add_to_canvas(self): if self.in_canvas: return if not PatchbayManager.port_types_view & self.type: return port_mode = PORT_MODE_NULL if self.flags & PORT_IS_INPUT: port_mode = PORT_MODE_INPUT elif self.flags & PORT_IS_OUTPUT: port_mode = PORT_MODE_OUTPUT else: return display_name = self.display_name if self.pretty_name: display_name = self.pretty_name if not PatchbayManager.use_graceful_names: display_name = self.short_name() is_alternate = False if self.flags & PORT_IS_CONTROL_VOLTAGE: is_alternate = True if (self.type == PORT_TYPE_MIDI and self.full_name.startswith(('a2j:', 'Midi-Bridge:'))): for group in PatchbayManager.groups: if group.group_id == self.group_id: is_alternate = True break self.in_canvas = True patchcanvas.addPort( self.group_id, self.port_id, display_name, port_mode, self.type, is_alternate, fast=PatchbayManager.optimized_operation) def remove_from_canvas(self): if not self.in_canvas: return patchcanvas.removePort(self.group_id, self.port_id, fast=PatchbayManager.optimized_operation) self.in_canvas = False def rename_in_canvas(self): if not self.in_canvas: return display_name = self.display_name if self.pretty_name: display_name = self.pretty_name if not PatchbayManager.use_graceful_names: display_name = self.short_name() patchcanvas.renamePort( self.group_id, self.port_id, display_name, fast=PatchbayManager.optimized_operation) def __lt__(self, other): if self.type != other.type: return (self.type < other.type) if (self.flags & PORT_IS_CONTROL_VOLTAGE != other.flags & PORT_IS_CONTROL_VOLTAGE): return not bool(self.flags & PORT_IS_CONTROL_VOLTAGE) if (self.full_name.startswith('a2j:') != other.full_name.startswith('a2j:')): return not self.full_name.startswith('a2j:') if self.mode() != other.mode(): return (self.mode() < other.mode()) if self.order is None and other.order is None: return self.port_id < other.port_id if self.order is None: return False if other.order is None: return True return bool(self.order < other.order) class Portgroup: # Portgroup is a stereo pair of ports # but could be a group of more ports def __init__(self, group_id: int, portgroup_id: int, port_mode: int, ports: tuple): self.group_id = group_id self.portgroup_id = portgroup_id self.port_mode = port_mode self.ports = tuple(ports) self.mdata_portgroup = '' self.above_metadatas = False self.in_canvas = False for port in self.ports: port.portgroup_id = portgroup_id def port_type(self): if not self.ports: return PORT_TYPE_NULL return self.ports[0].type def update_ports_in_canvas(self): for port in self.ports: port.rename_in_canvas() def sort_ports(self): port_list = list(self.ports) port_list.sort() self.ports = tuple(port_list) def add_to_canvas(self): if self.in_canvas: return if not PatchbayManager.port_types_view & self.port_type(): return if len(self.ports) < 2: return for port in self.ports: if not port.in_canvas: return port_mode = self.ports[0].mode() port_type = self.ports[0].type self.in_canvas = True port_id_list = [port.port_id for port in self.ports] port_id_list = tuple(port_id_list) patchcanvas.addPortGroup(self.group_id, self.portgroup_id, self.port_mode, port_type, port_id_list, fast=PatchbayManager.optimized_operation) def remove_from_canvas(self): if not self.in_canvas: return patchcanvas.removePortGroup(self.group_id, self.portgroup_id, fast=PatchbayManager.optimized_operation) self.in_canvas = False class Group: def __init__(self, group_id: int, name: str, group_position): self.group_id = group_id self.name = name self.display_name = name self.ports = [] self.portgroups = [] self.ports_to_rename_queue = [] self._is_hardware = False self.client_icon = '' self.a2j_group = False self.in_canvas = False self.current_position = group_position self.uuid = 0 self.has_gui = False self.gui_visible = False self._timer_port_order = QTimer() self._timer_port_order.setInterval(20) self._timer_port_order.setSingleShot(True) self._timer_port_order.timeout.connect(self.sort_ports_in_canvas) self._timer_ports_rename = QTimer() self._timer_ports_rename.setInterval(20) self._timer_ports_rename.setSingleShot(True) self._timer_ports_rename.timeout.connect(self.rename_waiting_ports) def update_ports_in_canvas(self): for port in self.ports: port.rename_in_canvas() def add_to_canvas(self, split=patchcanvas.SPLIT_UNDEF): if self.in_canvas: return icon_type = patchcanvas.ICON_APPLICATION icon_name = "" icon_name = self.name.partition('.')[0].lower() do_split = bool(self.current_position.flags & GROUP_SPLITTED) split = patchcanvas.SPLIT_YES if do_split else patchcanvas.SPLIT_NO if self._is_hardware: icon_type = patchcanvas.ICON_HARDWARE if self.a2j_group or self.display_name == "Midi-Bridge": icon_name = "a2j" if self.client_icon: icon_type = patchcanvas.ICON_CLIENT icon_name = self.client_icon if (self.name.startswith("PulseAudio ") and not self.client_icon): if "sink" in self.name.lower(): icon_type = patchcanvas.ICON_INTERNAL icon_name = "audio-volume-medium.svg" elif "source" in self.name.lower(): icon_type = patchcanvas.ICON_INTERNAL icon_name = "audio-input-microphone.svg" elif (self.name.endswith(" Monitor") and not self.client_icon): icon_type = patchcanvas.ICON_INTERNAL icon_name = "audio-volume-medium.svg" self.in_canvas = True gpos = self.current_position self.display_name = self.display_name.replace('.0/', '/') self.display_name = self.display_name.replace('_', ' ') display_name = self.name if PatchbayManager.use_graceful_names: display_name = self.display_name patchcanvas.addGroup( self.group_id, display_name, split, icon_type, icon_name, fast=PatchbayManager.optimized_operation, null_xy=gpos.null_xy, in_xy=gpos.in_xy, out_xy=gpos.out_xy) if do_split: gpos.flags |= GROUP_HAS_BEEN_SPLITTED patchcanvas.wrapGroupBox( self.group_id, PORT_MODE_INPUT, bool(gpos.flags & GROUP_WRAPPED_INPUT), animate=False) patchcanvas.wrapGroupBox( self.group_id, PORT_MODE_OUTPUT, bool(gpos.flags & GROUP_WRAPPED_OUTPUT), animate=False) else: patchcanvas.wrapGroupBox( self.group_id, PORT_MODE_NULL, bool(gpos.flags & GROUP_WRAPPED_INPUT and gpos.flags & GROUP_WRAPPED_OUTPUT), animate=False) if self.has_gui: patchcanvas.set_optional_gui_state(self.group_id, self.gui_visible) def remove_from_canvas(self): if not self.in_canvas: return patchcanvas.removeGroup(self.group_id, fast=PatchbayManager.optimized_operation) self.in_canvas = False def redraw_in_canvas(self): if not self.in_canvas: return patchcanvas.redrawGroup(self.group_id) def update_name_in_canvas(self): if not self.in_canvas: return display_name = self.name if PatchbayManager.use_graceful_names: display_name = self.display_name patchcanvas.renameGroup(self.group_id, display_name) def semi_hide(self, yesno: bool): if not self.in_canvas: return patchcanvas.semi_hide_group(self.group_id, yesno) def set_in_front(self): if not self.in_canvas: return patchcanvas.set_group_in_front(self.group_id) def get_number_of_boxes(self)->int: if not self.in_canvas: return 0 return patchcanvas.get_number_of_boxes(self.group_id) def select_filtered_box(self, n_select=0): if not self.in_canvas: return patchcanvas.select_filtered_group_box(self.group_id, n_select) def set_optional_gui_state(self, visible: bool): self.has_gui = True self.gui_visible = visible if not self.in_canvas: return patchcanvas.set_optional_gui_state(self.group_id, visible) def remove_all_ports(self): if self.in_canvas: for portgroup in self.portgroups: portgroup.remove_from_canvas() for port in self.ports: port.remove_from_canvas() self.portgroups.clear() self.ports.clear() def add_port(self, port): port_full_name = port.full_name port.group_id = self.group_id if (port_full_name.startswith('a2j:') and not port.flags & PORT_IS_PHYSICAL): port_full_name = port_full_name.partition(':')[2] port.display_name = port_full_name.partition(':')[2] if not self.ports: # we are adding the first port of the group if port.flags & PORT_IS_PHYSICAL: self._is_hardware = True if not self.current_position.fully_set: if self._is_hardware: self.current_position.flags |= GROUP_SPLITTED self.current_position.fully_set = True self.save_current_position() self.ports.append(port) def remove_port(self, port): if port in self.ports: self.ports.remove(port) def remove_portgroup(self, portgroup): if portgroup in self.portgroups: portgroup.remove_from_canvas() for port in portgroup.ports: port.portgroup_id = 0 self.portgroups.remove(portgroup) def portgroup_memory_added(self, portgroup_mem): if portgroup_mem.group_name != self.name: return remove_list = [] # first remove any existing portgroup with one of the porgroup_mem ports for portgroup in self.portgroups: if (portgroup.port_mode != portgroup_mem.port_mode or portgroup.port_type() != portgroup_mem.port_type): continue for port in portgroup.ports: if port.short_name() in portgroup_mem.port_names: remove_list.append(portgroup) for portgroup in remove_list: self.remove_portgroup(portgroup) # add a portgroup if all needed ports are present and consecutive port_list = [] for port in self.ports: if (port.mode != portgroup_mem.port_mode or port.type != portgroup_mem.port_type): continue if port.short_name() == portgroup_mem.port_names[len(port_list)]: port_list.append(port) if len(port_list) == len(portgroup_mem.port_names): # all ports are presents, create the portgroup portgroup = PatchbayManager.new_portgroup( self.group_id, port.mode(), port_list) self.portgroups.append(portgroup) portgroup.add_to_canvas() break elif port_list: # here it is a port breaking the consecutivity of the portgroup break def save_current_position(self): PatchbayManager.send_to_daemon( '/ray/server/patchbay/save_group_position', *self.current_position.spread()) def set_group_position(self, group_position): ex_gpos_flags = self.current_position.flags self.current_position = group_position gpos = self.current_position if not self.in_canvas: return patchcanvas.moveGroupBoxes( self.group_id, gpos.null_xy, gpos.in_xy, gpos.out_xy) if (gpos.flags & GROUP_SPLITTED and not ex_gpos_flags & GROUP_SPLITTED): patchcanvas.splitGroup(self.group_id) patchcanvas.wrapGroupBox(self.group_id, PORT_MODE_INPUT, bool(gpos.flags & GROUP_WRAPPED_INPUT)) patchcanvas.wrapGroupBox(self.group_id, PORT_MODE_OUTPUT, bool(gpos.flags & GROUP_WRAPPED_OUTPUT)) if (ex_gpos_flags & GROUP_SPLITTED and not gpos.flags & GROUP_SPLITTED): patchcanvas.animateBeforeJoin(self.group_id) def wrap_box(self, port_mode: int, yesno: bool): wrap_flag = GROUP_WRAPPED_OUTPUT | GROUP_WRAPPED_INPUT if port_mode == PORT_MODE_INPUT: wrap_flag = GROUP_WRAPPED_INPUT elif port_mode == PORT_MODE_OUTPUT: wrap_flag = GROUP_WRAPPED_OUTPUT if yesno: self.current_position.flags |= wrap_flag else: self.current_position.flags &= ~wrap_flag self.save_current_position() if not self.in_canvas: return patchcanvas.wrapGroupBox(self.group_id, port_mode, yesno) def set_client_icon(self, icon_name:str): self.client_icon = icon_name if self.in_canvas: patchcanvas.setGroupIcon( self.group_id, patchcanvas.ICON_CLIENT, icon_name) def get_pretty_client(self): for client_name in ('firewire_pcm', 'a2j', 'Hydrogen', 'ardour', 'Ardour', 'Qtractor', 'SooperLooper', 'sooperlooper', 'Luppp', 'seq64', 'calfjackhost', 'rakarrack-plus', 'seq192', 'Non-Mixer', 'jack_mixer'): if self.name == client_name: return client_name if self.name.startswith(client_name + '.'): return client_name name = self.name.partition('/')[0] if name == client_name: return client_name if name.startswith(client_name + '_'): if name.replace(client_name + '_', '', 1).isdigit(): return client_name if ' (' in name and name.endswith(')'): name = name.partition(' (')[0] if name == client_name: return client_name if name.startswith(client_name + '_'): if name.replace(client_name + '_', '', 1).isdigit(): return client_name return '' def graceful_port(self, port): def split_end_digits(name: str)->tuple: num = '' while name and name[-1].isdigit(): num = name[-1] + num name = name[:-1] if num.startswith('0') and num not in ('0', '09'): num = num[1:] return (name, num) def cut_end(name: str, *ends: str)->str: for end in ends: if name.endswith(end): return name.rsplit(end)[0] return name client_name = self.get_pretty_client() if (not client_name and port.full_name.startswith(('a2j:', 'Midi-Bridge:')) and port.flags & PORT_IS_PHYSICAL): client_name = 'a2j' display_name = port.short_name() s_display_name = display_name if client_name == 'firewire_pcm': if '(' in display_name and ')' in display_name: after_para = display_name.partition('(')[2] display_name = after_para.rpartition(')')[0] display_name, num = split_end_digits(display_name) if num: if display_name.endswith(':'): display_name = display_name[:-1] display_name += ' ' + num else: display_name = display_name.partition('_')[2] display_name = cut_end(display_name, '_in', '_out') display_name = display_name.replace(':', ' ') display_name, num = split_end_digits(display_name) display_name = display_name + num elif client_name == 'Hydrogen': if display_name.startswith('Track_'): display_name = display_name.replace('Track_', '', 1) num, udsc, name = display_name.partition('_') if num.isdigit(): display_name = num + ' ' + name if display_name.endswith('_Main_L'): display_name = display_name.replace('_Main_L', ' L', 1) elif display_name.endswith('_Main_R'): display_name = display_name.replace('_Main_R', ' R', 1) elif client_name == 'a2j': display_name, num = split_end_digits(display_name) if num: if display_name.endswith(' MIDI '): display_name = cut_end(display_name, ' MIDI ') if num == '1': port.last_digit_to_add = '1' else: display_name += ' ' + num elif display_name.endswith(' Port-'): display_name = cut_end(display_name, ' Port-') if num == '0': port.last_digit_to_add = '0' else: display_name += ' ' + num elif client_name in ('ardour', 'Ardour'): for pt in ('audio', 'midi'): if display_name == "physical_%s_input_monitor_enable" % pt: display_name = "physical monitor" break else: display_name, num = split_end_digits(display_name) if num: display_name = cut_end(display_name, '/audio_out ', '/audio_in ', '/midi_out ', '/midi_in ') if num == '1': port.last_digit_to_add = '1' else: display_name += ' ' + num elif client_name == 'Qtractor': display_name, num = split_end_digits(display_name) if num: display_name = cut_end(display_name, '/in_', '/out_') if num == '1': port.last_digit_to_add = '1' else: display_name += ' ' + num elif client_name == 'Non-Mixer': display_name, num = split_end_digits(display_name) if num: display_name = cut_end(display_name, '/in-', '/out-') if num == '1': port.last_digit_to_add = '1' else: display_name += ' ' + num elif client_name == 'jack_mixer': prefix, out, side = display_name.rpartition(' Out') if out and side in (' L', ' R', ''): display_name = prefix + side elif client_name in ('SooperLooper', 'sooperlooper'): display_name, num = split_end_digits(display_name) if num: display_name = cut_end(display_name, '_in_', '_out_') if num == '1': port.last_digit_to_add = '1' else: display_name += ' ' + num elif client_name == 'Luppp': if display_name.endswith('\n'): display_name = display_name[:-1] display_name = display_name.replace('_', ' ') elif client_name == 'seq64': display_name = display_name.replace('seq64 midi ', '', 1) elif client_name == 'seq192': display_name = display_name.replace('seq192 ', '', 1) elif client_name == 'calfjackhost': display_name, num = split_end_digits(display_name) if num: display_name = cut_end(display_name, ' Out #', ' In #') display_name += " " + num elif client_name == 'rakarrack-plus': if display_name.startswith('rakarrack-plus '): display_name = display_name.replace('rakarrack-plus ', '', 1) display_name = display_name.replace('_', ' ') elif not client_name: display_name = display_name.replace('_', ' ') if display_name.lower().endswith(('-left', ' left')): display_name = display_name[:-5] + ' L' elif display_name.lower().endswith(('-right', ' right')): display_name = display_name[:-6] + ' R' elif display_name.lower() == 'left in': display_name = 'In L' elif display_name.lower() == 'right in': display_name = 'In R' elif display_name.lower() == 'left out': display_name = 'Out L' elif display_name.lower() == 'right out': display_name = 'Out R' if display_name.startswith('Audio'): display_name = display_name.replace('Audio ', '') # reduce graceful name for pipewire Midi-Bridge with # option jack.filter_name = true if (port.full_name.startswith('Midi-Bridge') and display_name.startswith(('capture_', 'playback_'))): display_name = display_name.partition('_')[2] port.display_name = display_name if display_name else s_display_name def add_portgroup(self, portgroup): self.portgroups.append(portgroup) def change_port_types_view(self, port_types_view: int): # first add group to canvas if not already self.add_to_canvas() for portgroup in self.portgroups: if not port_types_view & portgroup.port_type(): portgroup.remove_from_canvas() for port in self.ports: if not port_types_view & port.type: port.remove_from_canvas() for port in self.ports: if port_types_view & port.type: port.add_to_canvas() for portgroup in self.portgroups: if port_types_view & portgroup.port_type(): portgroup.add_to_canvas() # remove group from canvas if no visible ports for port in self.ports: if port.in_canvas: break else: self.remove_from_canvas() def stereo_detection(self, port): if port.type != PORT_TYPE_AUDIO: return if port.flags & PORT_IS_CONTROL_VOLTAGE: return # find the last port with same type and mode in the group for other_port in reversed(self.ports): if other_port == port: continue if (other_port.type == port.type and other_port.mode() == port.mode() and not other_port.flags & PORT_IS_CONTROL_VOLTAGE and not other_port.portgroup_id and not other_port.prevent_stereo): for portgroup_mem in PatchbayManager.portgroups_memory: if (portgroup_mem.group_name == self.name and portgroup_mem.port_mode == other_port.mode() and portgroup_mem.port_type == other_port.type and other_port.short_name() in portgroup_mem.port_names): # other_port (left) is in a remembered portgroup # prevent stereo detection return break else: return may_match_list = [] port_name = port.full_name.replace(self.name + ':', '', 1) other_port_name = other_port.full_name.replace(self.name + ':', '', 1) if port.flags & PORT_IS_PHYSICAL: # force stereo detection for system ports # it forces it for firewire long and strange names may_match_list.append(other_port_name) elif port_name[-1].isdigit(): # Port ends with digit base_port = port_name[:-1] in_num = port_name[-1] while base_port[-1].isdigit(): in_num = base_port[-1] + in_num base_port = base_port[:-1] # if Port ends with Ldigits or Rdigits if base_port.endswith('R'): may_match_list.append(base_port[:-1] + 'L' + in_num) else: may_match_list.append(base_port + str(int(in_num) -1)) if int(in_num) in (1, 2): if base_port.endswith((' ', ('_'))): may_match_list.append(base_port[:-1]) else: may_match_list.append(base_port) else: # Port ends with non digit if port_name.endswith('R'): may_match_list.append(port_name[:-1] + 'L') if len(port_name) >= 2: if port_name[-2] == ' ': may_match_list.append(port_name[:-2]) else: may_match_list.append(port_name[:-1]) elif port_name.endswith('right'): may_match_list.append(port_name[:-5] + 'left') elif port_name.endswith('Right'): may_match_list.append(port_name[:-5] + 'Left') elif port_name.endswith('(Right)'): may_match_list.append(port_name[:-7] + '(Left)') elif port_name.endswith('.r'): may_match_list.append(port_name[:-2] + '.l') elif port_name.endswith('_r'): may_match_list.append(port_name[:-2] + '_l') elif port_name.endswith('_r\n'): may_match_list.append(port_name[:-3] + '_l\n') for x in ('out', 'Out', 'output', 'Output', 'in', 'In', 'input', 'Input', 'audio input', 'audio output'): if port_name.endswith('R ' + x): may_match_list.append('L ' + x) elif port_name.endswith('right ' + x): may_match_list.append('left ' + x) elif port_name.endswith('Right ' + x): may_match_list.append('Left ' + x) if other_port_name in may_match_list: return other_port def check_for_portgroup_on_last_port(self): if not self.ports: return last_port = self.ports[-1] last_port_name = last_port.short_name() # check in the saved portgroups if we need to make a portgroup # or prevent stereo detection for portgroup_mem in PatchbayManager.portgroups_memory: if (portgroup_mem.group_name == self.name and portgroup_mem.port_type == last_port.type and portgroup_mem.port_mode == last_port.mode() and last_port_name == portgroup_mem.port_names[-1]): if (len(portgroup_mem.port_names) == 1 or portgroup_mem.port_names.index(last_port_name) + 1 != len(portgroup_mem.port_names)): return port_list = [] for port in self.ports: if (port.type == last_port.type and port.mode() == last_port.mode()): if (port.short_name() == portgroup_mem.port_names[len(port_list)]): port_list.append(port) if len(port_list) == len(portgroup_mem.port_names): portgroup = PatchbayManager.new_portgroup( self.group_id, port.mode(), port_list) self.portgroups.append(portgroup) for port in port_list: if not port.in_canvas: break else: portgroup.add_to_canvas() elif port_list: return # detect left audio port if it is a right one other_port = self.stereo_detection(last_port) if other_port is not None: portgroup = PatchbayManager.new_portgroup( self.group_id, last_port.mode(), (other_port, last_port)) self.add_portgroup(portgroup) if self.in_canvas: portgroup.add_to_canvas() def check_for_display_name_on_last_port(self): if not self.ports: return last_port = self.ports[-1] last_digit = last_port.full_name[-1] if last_digit not in ('1', '2'): return for port in reversed(self.ports): if (port.type == last_port.type and port.mode() == last_port.mode() and port is not last_port): if (port.full_name[:-1] == last_port.full_name[:-1] and ((port.last_digit_to_add == '0' and last_digit == '1')) or (port.last_digit_to_add == '1' and last_digit == '2')): port.add_the_last_digit() break def sort_ports_in_canvas(self): PatchbayManager.optimize_operation(True) conn_list = [] for conn in PatchbayManager.connections: for port in self.ports: if (port in (conn.port_out, conn.port_in) and conn not in conn_list): conn_list.append(conn) for connection in conn_list: connection.remove_from_canvas() for portgroup in self.portgroups: portgroup.remove_from_canvas() for port in self.ports: port.remove_from_canvas() self.ports.sort() # search and remove existing portgroups with non consecutive ports portgroups_to_remove = [] for portgroup in self.portgroups: search_index = 0 previous_port = None seems_ok = False for port in self.ports: if not seems_ok and port is portgroup.ports[search_index]: if (port.mdata_portgroup != portgroup.mdata_portgroup and not portgroup.above_metadatas): portgroups_to_remove.append(portgroup) break if (not portgroup.above_metadatas and not search_index and previous_port is not None and previous_port.mdata_portgroup and previous_port.mdata_portgroup == port.mdata_portgroup): # previous port had the same portgroup metadata # that this port. we need to remove this portgroup. portgroups_to_remove.append(portgroup) break search_index += 1 if search_index == len(portgroup.ports): # all ports of portgroup are consecutive # but still exists the risk that metadatas says # that the portgroup has now more ports seems_ok = True if (portgroup.above_metadatas or not portgroup.mdata_portgroup): break elif search_index: if (seems_ok and (port.mdata_portgroup != previous_port.mdata_portgroup or port.type != portgroup.port_type() or port.mode() != portgroup.port_mode)): # port after the portgroup has not to make # the portgroup higher. We keep this portgroup break # this port breaks portgroup ports consecutivity. # note that ports have been just sorted by type and mode # so no risk that this port is falsely breaking portgroup portgroups_to_remove.append(portgroup) break previous_port = port else: if not seems_ok: portgroups_to_remove.append(portgroup) for portgroup in portgroups_to_remove: self.remove_portgroup(portgroup) # add missing portgroups aboving metadatas from portgroup memory for portgroup_mem in PatchbayManager.portgroups_memory: if not portgroup_mem.above_metadatas: continue if portgroup_mem.group_name != self.name: continue founded_ports = [] for port in self.ports: if (not port.portgroup_id and port.type == portgroup_mem.port_type and port.mode() == portgroup_mem.port_mode and port.short_name() == portgroup_mem.port_names[len(founded_ports)]): founded_ports.append(port) if len(founded_ports) == len(portgroup_mem.port_names): new_portgroup = PatchbayManager.new_portgroup( self.group_id, port.mode(), founded_ports) self.portgroups.append(new_portgroup) break elif founded_ports: break # detect and add portgroups given from metadatas portgroups_mdata = [] # list of dicts for port in self.ports: if port.mdata_portgroup: pg_mdata = None if portgroups_mdata: pg_mdata = portgroups_mdata[-1] if not port.portgroup_id: if (pg_mdata is not None and pg_mdata['pg_name'] == port.mdata_portgroup and pg_mdata['port_type'] == port.type and pg_mdata['port_mode'] == port.mode()): pg_mdata['ports'].append(port) else: portgroups_mdata.append( {'pg_name': port.mdata_portgroup, 'port_type': port.type, 'port_mode': port.mode(), 'ports':[port]}) for pg_mdata in portgroups_mdata: if len(pg_mdata['ports']) < 2: continue new_portgroup = PatchbayManager.new_portgroup( self.group_id, pg_mdata['port_mode'], pg_mdata['ports']) new_portgroup.mdata_portgroup = pg_mdata['pg_name'] self.portgroups.append(new_portgroup) # add missing portgroups from portgroup memory for portgroup_mem in PatchbayManager.portgroups_memory: if portgroup_mem.above_metadatas: continue if portgroup_mem.group_name != self.name: continue founded_ports = [] for port in self.ports: if (not port.portgroup_id and port.type == portgroup_mem.port_type and port.mode() == portgroup_mem.port_mode and port.short_name() == portgroup_mem.port_names[len(founded_ports)]): founded_ports.append(port) if len(founded_ports) == len(portgroup_mem.port_names): new_portgroup = PatchbayManager.new_portgroup( self.group_id, port.mode(), founded_ports) self.portgroups.append(new_portgroup) break elif founded_ports: break # ok for re-adding all items to canvas for port in self.ports: port.add_to_canvas() for portgroup in self.portgroups: portgroup.add_to_canvas() for connection in conn_list: connection.add_to_canvas() PatchbayManager.optimize_operation(False) self.redraw_in_canvas() def rename_waiting_ports(self): PatchbayManager.optimize_operation(True) for port_rename_dict in self.ports_to_rename_queue: port = port_rename_dict['port'] port.full_name = port_rename_dict['new_name'] self.graceful_port(port) port.rename_in_canvas() PatchbayManager.optimize_operation(False) self.redraw_in_canvas() self.ports_to_rename_queue.clear() def sort_ports_later(self): self._timer_port_order.start() def rename_port_later(self, port, new_name): self.ports_to_rename_queue.append( {'port': port, 'new_name': new_name}) self._timer_ports_rename.start() class PatchbayManager: use_graceful_names = True port_types_view = PORT_TYPE_AUDIO + PORT_TYPE_MIDI optimized_operation = False groups = [] connections = [] group_positions = [] portgroups_memory = [] _next_portgroup_id = 1 def __init__(self, session): self.session = session self.tools_widget = PatchbayToolsWidget() self.tools_widget.buffer_size_change_order.connect( self.change_buffersize) self._next_group_id = 0 self._next_port_id = 0 self._next_connection_id = 0 self.set_graceful_names(RS.settings.value( 'Canvas/use_graceful_names', True, type=bool)) self.group_a2j_hw = RS.settings.value( 'Canvas/group_a2j_ports', True, type=bool) self._wait_join_group_ids = [] self.join_animation_connected = False def finish_init(self): self.canvas_menu = CanvasMenu(self) self.options_dialog = canvas_options.CanvasOptionsDialog( self.session.main_win) self.options_dialog.gracious_names_checked.connect( self.set_graceful_names) self.options_dialog.a2j_grouped_checked.connect( self.set_a2j_grouped) self.options_dialog.group_shadows_checked.connect( self.set_group_shadows) self.options_dialog.theme_changed.connect( self.change_theme) self.options_dialog.elastic_checked.connect( self.set_elastic_canvas) self.options_dialog.prevent_overlap_checked.connect( self.set_prevent_overlap) self.options_dialog.max_port_width_changed.connect( patchcanvas.set_max_port_width) @staticmethod def send_to_patchbay_daemon(*args): server = GuiServerThread.instance() if not server: return if server.patchbay_addr is None: return server.send(server.patchbay_addr, *args) @staticmethod def send_to_daemon(*args): server = GuiServerThread.instance() if not server: return server.to_daemon(*args) @classmethod def set_use_graceful_names(cls, yesno: bool): cls.use_graceful_names = yesno @classmethod def optimize_operation(cls, yesno: bool): cls.optimized_operation = yesno if (patchcanvas.canvas is not None and patchcanvas.canvas.scene is not None): patchcanvas.canvas.scene.prevent_box_move = yesno patchcanvas.canvas.scene.loading_items = yesno @classmethod def new_portgroup(cls, group_id: int, port_mode: int, ports: tuple): portgroup = Portgroup(group_id, cls._next_portgroup_id, port_mode, ports) cls._next_portgroup_id += 1 return portgroup def canvas_callbacks(self, action, value1, value2, value_str): if action == patchcanvas.ACTION_GROUP_INFO: pass elif action == patchcanvas.ACTION_GROUP_RENAME: pass elif action == patchcanvas.ACTION_GROUP_SPLIT: group_id = value1 for group in self.groups: if group.group_id == group_id: on_place = not bool( group.current_position.flags & GROUP_HAS_BEEN_SPLITTED) patchcanvas.splitGroup(group_id, on_place=on_place) group.current_position.flags |= GROUP_SPLITTED group.current_position.flags |= GROUP_HAS_BEEN_SPLITTED group.save_current_position() break elif action == patchcanvas.ACTION_GROUP_JOIN: group_id = value1 patchcanvas.animateBeforeJoin(group_id) elif action == patchcanvas.ACTION_GROUP_JOINED: group_id = value1 for group in self.groups: if group.group_id == group_id: group.current_position.flags &= ~GROUP_SPLITTED group.save_current_position() break elif action == patchcanvas.ACTION_GROUP_MOVE: group_id = value1 port_mode = value2 x_y_str = value_str str_x, colon, str_y = x_y_str.partition(':') x = int(str_x) y = int(str_y) for group in self.groups: if group.group_id == group_id: gpos = group.current_position if port_mode == PORT_MODE_NULL: gpos.null_xy = (x, y) elif port_mode == PORT_MODE_INPUT: gpos.in_xy = (x, y) elif port_mode == PORT_MODE_OUTPUT: gpos.out_xy = (x, y) group.save_current_position() break elif action == patchcanvas.ACTION_GROUP_WRAP: group_id = value1 splitted_mode = value2 yesno = bool(value_str == 'True') for group in self.groups: if group.group_id == group_id: group.wrap_box(splitted_mode, yesno) break elif action == patchcanvas.ACTION_PORTGROUP_ADD: g_id, p_mode, p_type, p_id1, p_id2 = [ int(i) for i in value_str.split(":")] port_list = [] above_metadatas = False for port_id in p_id1, p_id2: port = self.get_port_from_id(g_id, port_id) if port.mdata_portgroup: above_metadatas = True port_list.append(port) portgroup = self.new_portgroup(g_id, p_mode, port_list) for group in self.groups: if group.group_id == g_id: group.add_portgroup(portgroup) new_portgroup_mem = ray.PortGroupMemory.new_from( group.name, portgroup.port_type(), portgroup.port_mode, int(above_metadatas), *[port.short_name() for port in port_list]) self.add_portgroup_memory(new_portgroup_mem) self.send_to_daemon( '/ray/server/patchbay/save_portgroup', *new_portgroup_mem.spread()) break portgroup.add_to_canvas() elif action == patchcanvas.ACTION_PORTGROUP_REMOVE: group_id = value1 portgroup_id = value2 for group in self.groups: if group.group_id == group_id: for portgroup in group.portgroups: if portgroup.portgroup_id == portgroup_id: for port in portgroup.ports: # save a fake portgroup with one port only # it will be considered as a forced mono port # (no stereo detection) above_metadatas = bool(port.mdata_portgroup) new_portgroup_mem = ray.PortGroupMemory.new_from( group.name, portgroup.port_type(), portgroup.port_mode, int(above_metadatas), port.short_name()) self.add_portgroup_memory(new_portgroup_mem) self.send_to_daemon( '/ray/server/patchbay/save_portgroup', *new_portgroup_mem.spread()) portgroup.remove_from_canvas() group.portgroups.remove(portgroup) break break elif action == patchcanvas.ACTION_PORT_INFO: group_id = value1 port_id = value2 port = self.get_port_from_id(group_id, port_id) if port is None: return dialog = CanvasPortInfoDialog(self.session.main_win) dialog.set_port(port) dialog.show() elif action == patchcanvas.ACTION_PORT_RENAME: pass elif action == patchcanvas.ACTION_PORTS_CONNECT: g_out, p_out, g_in, p_in = [int(i) for i in value_str.split(":")] port_out = self.get_port_from_id(g_out, p_out) port_in = self.get_port_from_id(g_in, p_in) if port_out is None or port_in is None: return self.send_to_patchbay_daemon( '/ray/patchbay/connect', port_out.full_name, port_in.full_name) elif action == patchcanvas.ACTION_PORTS_DISCONNECT: connection_id = value1 for connection in self.connections: if connection.connection_id == connection_id: self.send_to_patchbay_daemon( '/ray/patchbay/disconnect', connection.port_out.full_name, connection.port_in.full_name) break elif action == patchcanvas.ACTION_BG_RIGHT_CLICK: x, y = value1, value2 self.canvas_menu.exec(QPoint(x, y)) elif action == patchcanvas.ACTION_DOUBLE_CLICK: self.toggle_full_screen() elif action == patchcanvas.ACTION_CLIENT_SHOW_GUI: group_id, int_visible = value1, value2 for group in self.groups: if group.group_id == group_id: for client in self.session.client_list: if client.can_be_own_jack_client(group.name): show = 'show' if int_visible else 'hide' self.send_to_daemon( '/ray/client/%s_optional_gui' % show, client.client_id) break break def show_options_dialog(self): self.options_dialog.move(QCursor.pos()) self.options_dialog.show() def set_graceful_names(self, yesno: int): if self.use_graceful_names != yesno: self.toggle_graceful_names() def set_a2j_grouped(self, yesno: int): if self.group_a2j_hw != bool(yesno): self.group_a2j_hw = bool(yesno) self.refresh() def set_group_shadows(self, yesno: int): if yesno: patchcanvas.options.eyecandy = patchcanvas.EYECANDY_SMALL else: patchcanvas.options.eyecandy = patchcanvas.EYECANDY_NONE self.refresh() def change_theme(self, index:int): idx = 0 if index == 0: idx = 0 elif index == 1: idx = 1 elif index == 2: idx = 2 patchcanvas.changeTheme(idx) theme_name = patchcanvas.getThemeName(idx) RS.settings.setValue('Canvas/theme', theme_name) def set_elastic_canvas(self, yesno: int): patchcanvas.setElastic(yesno) def set_prevent_overlap(self, yesno: int): patchcanvas.set_prevent_overlap(yesno) def toggle_graceful_names(self): PatchbayManager.set_use_graceful_names(not self.use_graceful_names) PatchbayManager.optimize_operation(True) for group in self.groups: group.update_ports_in_canvas() group.update_name_in_canvas() PatchbayManager.optimize_operation(False) patchcanvas.redrawAllGroups() def toggle_full_screen(self): self.session.main_win.toggle_scene_full_screen() def refresh(self): self.clear_all() self.send_to_patchbay_daemon('/ray/patchbay/refresh') def get_port_from_name(self, port_name: str): for group in self.groups: for port in group.ports: if port.full_name == port_name: return port def get_port_from_uuid(self, uuid:int): for group in self.groups: for port in group.ports: if port.uuid == uuid: return port def get_port_from_id(self, group_id: int, port_id: int): for group in self.groups: if group.group_id == group_id: for port in group.ports: if port.port_id == port_id: return port break def get_group_position(self, group_name): for gpos in self.group_positions: if (gpos.port_types_view == self.port_types_view and gpos.group_name == group_name): return gpos # prevent move to a new position in case of port_types_view change # if there is no remembered position for this group in new view for group in self.groups: if group.name == group_name: # copy the group_position gpos = ray.GroupPosition.new_from( *group.current_position.spread()) gpos.port_types_view = self.port_types_view self.group_positions.append(gpos) return gpos # group position doesn't already exists, create one gpos = ray.GroupPosition() gpos.fully_set = False gpos.port_types_view = self.port_types_view gpos.group_name = group_name gpos.null_xy, gpos.in_xy, gpos.out_xy = \ patchcanvas.CanvasGetNewGroupPositions() self.group_positions.append(gpos) self.send_to_daemon( '/ray/server/patchbay/save_group_position', *gpos.spread()) return gpos def add_portgroup_memory(self, portgroup_mem): remove_list = [] for pg_mem in self.portgroups_memory: if pg_mem.has_a_common_port_with(portgroup_mem): remove_list.append(pg_mem) for pg_mem in remove_list: self.portgroups_memory.remove(pg_mem) self.portgroups_memory.append(portgroup_mem) def clear_all(self): self.optimize_operation(True) for connection in self.connections: connection.remove_from_canvas() for group in self.groups: group.remove_all_ports() group.remove_from_canvas() self.optimize_operation(False) self.connections.clear() self.groups.clear() patchcanvas.canvas.scene.clear() self._next_group_id = 0 self._next_port_id = 0 self._next_portgroup_id = 1 self._next_connection_id = 0 def change_port_types_view(self, port_types_view: int): if port_types_view == self.port_types_view: return self.port_types_view = port_types_view # Prevent visual update at each canvas item creation # because we may create a lot of ports here self.optimize_operation(True) for connection in self.connections: if (connection.in_canvas and not port_types_view & connection.port_type()): connection.remove_from_canvas() for group in self.groups: in_canvas = group.in_canvas group.change_port_types_view(port_types_view) gpos = self.get_group_position(group.name) group.set_group_position(gpos) for connection in self.connections: if (not connection.in_canvas and port_types_view & connection.port_type()): connection.add_to_canvas() self.optimize_operation(False) patchcanvas.redrawAllGroups() self.session.signaler.port_types_view_changed.emit( self.port_types_view) def get_json_contents_from_path(self, file_path: str)->dict: if not os.path.exists(file_path): return {} if not os.access(file_path, os.R_OK): return {} try: file = open(file_path, 'r') except IOError: return {} try: new_dict = json.load(file) except ImportError: return {} file.close() return new_dict def client_name_and_uuid(self, client_name: str, uuid: int): for group in self.groups: if group.name == client_name: group.uuid = uuid break def add_port(self, name: str, port_type: int, flags: int, uuid: int): port = Port(self._next_port_id, name, port_type, flags, uuid) self._next_port_id += 1 full_port_name = name group_name, colon, port_name = full_port_name.partition(':') a2j_group = False group_is_new = False if (full_port_name.startswith(('a2j:', 'Midi-Bridge:')) and (not self.group_a2j_hw or not port.flags & PORT_IS_PHYSICAL)): group_name, colon, port_name = port_name.partition(':') if full_port_name.startswith('a2j:'): group_name = group_name.rpartition(' [')[0] # fix a2j wrongly substitute '.' with space for client in self.session.client_list: if (client.status != ray.ClientStatus.STOPPED and '.' in client.jack_client_name and (client.jack_client_name.replace('.', ' ', 1) == group_name)): group_name = group_name.replace(' ', '.' , 1) break if port.flags & PORT_IS_PHYSICAL: a2j_group = True for group in self.groups: if group.name == group_name: break else: # port is an non existing group, create the group gpos = self.get_group_position(group_name) group = Group(self._next_group_id, group_name, gpos) group.a2j_group = a2j_group for client in self.session.client_list: if client.can_be_own_jack_client(group_name): group.set_client_icon(client.icon) # in case of long jack naming (ClientName.ClientId) # do not display ClientName if we have the icon if (client.icon and client.jack_client_name.endswith('.' + client.client_id) and group.name.startswith(client.jack_client_name)): group.display_name = group.display_name.partition('.')[2] if client.has_gui: group.set_optional_gui_state(client.gui_state) break self._next_group_id += 1 self.groups.append(group) group_is_new = True group.add_port(port) group.graceful_port(port) if group_is_new and self.port_types_view & port_type: gpos = self.get_group_position(group_name) group.set_group_position(gpos) group.add_to_canvas() if self.port_types_view & port_type: group.add_to_canvas() port.add_to_canvas() group.check_for_portgroup_on_last_port() group.check_for_display_name_on_last_port() def remove_port(self, name: str): port = self.get_port_from_name(name) if port is None: return for group in self.groups: if group.group_id == port.group_id: # remove portgroup first if port is in a portgroup if port.portgroup_id: for portgroup in group.portgroups: if portgroup.portgroup_id == port.portgroup_id: group.portgroups.remove(portgroup) portgroup.remove_from_canvas() break group.remove_port(port) port.remove_from_canvas() if not group.ports: group.remove_from_canvas() self.groups.remove(group) break def rename_port(self, name: str, new_name: str): port = self.get_port_from_name(name) if port is None: sys.stderr.write( "RaySession:PatchbayManager::rename_port" + "\"%s\" to \"%s\", port doesn't exists\n" % (name, new_name)) return group_name = name.partition(':')[0] new_group_name = new_name.partition(':')[0] # In case a port rename implies another group for the port if group_name != new_group_name: for group in self.groups: if group.name == group_name: group.remove_port(port) if not group.ports: self.groups.remove(group) break port.remove_from_canvas() port.full_name = new_name for group in self.groups: if group.name == new_group_name: group.add_port(port) break else: # copy the group_position to not move the group # because group has been renamed orig_gpos = self.get_group_position(group_name) gpos = ray.GroupPosition.new_from(*orig_gpos.spread()) gpos.group_name = new_group_name group = Group(self._next_group_id, new_group_name, gpos) self._next_group_id += 1 group.add_port(port) if self.port_types_view & port.type: group.add_to_canvas() if self.port_types_view & port.type: port.add_to_canvas() return for group in self.groups: if group.group_id == port.group_id: # because many ports may be renamed quicky # It is prefferable to rename all theses ports together. # It prevents too much widget update in canvas, # renames now could also prevent to find stereo detected portgroups # if one of the two ports has been renamed and not the other one. group.rename_port_later(port, new_name) break def optional_gui_state_changed(self, client_id: str, visible: bool): for client in self.session.client_list: if client.client_id == client_id: for group in self.groups: if client.can_be_own_jack_client(group.name): group.set_optional_gui_state(visible) break def metadata_update(self, uuid: int, key: str, value: str): if key == JACK_METADATA_ORDER: port = self.get_port_from_uuid(uuid) if port is None: return try: port_order = int(value) except: sys.stderr.write( "RaySession:PatchbayManager::JACK_METADATA_ORDER " + "value is not an int (%i,%s)\n" % (uuid, value)) return port.order = port_order # we may receive this message as many times as there are ports. # So, canvas redraw will be done 20ms after the last message. if not self.optimized_operation: for group in self.groups: if group.group_id == port.group_id: group.sort_ports_later() break elif key == JACK_METADATA_PRETTY_NAME: port = self.get_port_from_uuid(uuid) if port is None: return port.pretty_name = value port.rename_in_canvas() elif key == JACK_METADATA_PORT_GROUP: port = self.get_port_from_uuid(uuid) if port is None: return port.mdata_portgroup = value if not self.optimized_operation: for group in self.groups: if group.group_id == port.group_id: group.sort_ports_later() break elif key == JACK_METADATA_ICON_NAME: for group in self.groups: if group.uuid == uuid: group.set_client_icon(value) def add_connection(self, port_out_name: str, port_in_name: str): port_out = self.get_port_from_name(port_out_name) port_in = self.get_port_from_name(port_in_name) if port_out is None or port_in is None: return for connection in self.connections: if (connection.port_out == port_out and connection.port_in == port_in): return connection = Connection(self._next_connection_id, port_out, port_in) self._next_connection_id += 1 self.connections.append(connection) if connection.port_type() & self.port_types_view: connection.add_to_canvas() def remove_connection(self, port_out_name: str, port_in_name: str): port_out = self.get_port_from_name(port_out_name) port_in = self.get_port_from_name(port_in_name) if port_out is None or port_in is None: return for connection in self.connections: if (connection.port_out == port_out and connection.port_in == port_in): self.connections.remove(connection) connection.remove_from_canvas() break def update_group_position(self, *args): # remember group position and move boxes if needed gpos = ray.GroupPosition.new_from(*args) for group_position in self.group_positions: if (group_position.port_types_view == gpos.port_types_view and group_position.group_name == gpos.group_name): group_position.update(*args) else: self.group_positions.append(gpos) if gpos.port_types_view == self.port_types_view: for group in self.groups: if group.name == gpos.group_name: group.set_group_position(gpos) break def update_portgroup(self, *args): portgroup_mem = ray.PortGroupMemory.new_from(*args) self.add_portgroup_memory(portgroup_mem) for group in self.groups: if group.name == portgroup_mem.group_name: group.portgroup_memory_added(portgroup_mem) break def disannounce(self): self.send_to_patchbay_daemon('/ray/patchbay/gui_disannounce') self.clear_all() def server_started(self): self.tools_widget.set_jack_running(True) def server_stopped(self): self.tools_widget.set_jack_running(False) self.clear_all() def server_lose(self): self.tools_widget.set_jack_running(False) self.clear_all() ret = QMessageBox.critical( self.session.main_win, _translate('patchbay', "JACK server lose"), _translate('patchbay', "JACK server seems to be totally busy... ;(")) def set_dsp_load(self, dsp_load: int): self.tools_widget.set_dsp_load(dsp_load) def add_xrun(self): self.tools_widget.add_xrun() def change_buffersize(self, buffer_size): self.send_to_patchbay_daemon('/ray/patchbay/set_buffer_size', buffer_size) def filter_groups(self, text: str, n_select=0)->int: ''' semi hides groups not matching with text and return number of matching boxes ''' opac_grp_ids = set() opac_conn_ids = set() if text.startswith(('cl:', 'client:')): client_ids = text.rpartition(':')[2].split(' ') jack_client_names = [] for client in self.session.client_list: if (client.status != ray.ClientStatus.STOPPED and client.client_id in client_ids): jack_client_names.append(client.jack_client_name) if not client.jack_client_name.endswith('.' + client.client_id): jack_client_names.append(client.jack_client_name + '.0') for group in self.groups: opac = False for jack_client_name in jack_client_names: if (group.name == jack_client_name or group.name.startswith(jack_client_name + '/') or (group.name.startswith(jack_client_name + ' (') and ')' in group.name)): break else: opac = True opac_grp_ids.add(group.group_id) group.semi_hide(opac) else: for group in self.groups: opac = bool(text.lower() not in group.name.lower() and text.lower() not in group.display_name.lower()) if opac: opac_grp_ids.add(group.group_id) group.semi_hide(opac) for conn in self.connections: opac_conn = bool( conn.port_out.group_id in opac_grp_ids and conn.port_in.group_id in opac_grp_ids) conn.semi_hide(opac_conn) if opac_conn: opac_conn_ids.add(conn.connection_id) for group in self.groups: if group.group_id in opac_grp_ids: group.set_in_front() for conn in self.connections: if conn.connection_id in opac_conn_ids: conn.set_in_front() for conn in self.connections: if conn.connection_id not in opac_conn_ids: conn.set_in_front() n_boxes = 0 for group in self.groups: if group.group_id not in opac_grp_ids: group.set_in_front() n_grp_boxes = group.get_number_of_boxes() if n_select > n_boxes and n_select <= n_boxes + n_grp_boxes: group.select_filtered_box(n_select - n_boxes) n_boxes += n_grp_boxes return n_boxes def set_semi_hide_opacity(self, opacity: float): patchcanvas.set_semi_hide_opacity(opacity) def buffer_size_changed(self, buffer_size): self.tools_widget.set_buffer_size(buffer_size) def sample_rate_changed(self, samplerate): self.tools_widget.set_samplerate(samplerate) def receive_big_packets(self, state: int): self.optimize_operation(not bool(state)) if state: patchcanvas.redrawAllGroups() def fast_temp_file_memory(self, temp_path): ''' receives a .json file path from daemon with groups positions and portgroups remembered from user. ''' canvas_data = self.get_json_contents_from_path(temp_path) if not canvas_data: sys.stderr.write( "RaySession::Failed to load tmp file %s to get canvas positions\n" % temp_path) return for key in canvas_data.keys(): if key == 'group_positions': for gpos_dict in canvas_data[key]: gpos = ray.GroupPosition() gpos.write_from_dict(gpos_dict) self.update_group_position(*gpos.spread()) elif key == 'portgroups': for pg_dict in canvas_data[key]: portgroup_mem = ray.PortGroupMemory() portgroup_mem.write_from_dict(pg_dict) self.update_portgroup(*portgroup_mem.spread()) os.remove(temp_path) def fast_temp_file_running(self, temp_path): ''' receives a .json file path from patchbay daemon with all ports, connections and jack metadatas''' patchbay_data = self.get_json_contents_from_path(temp_path) if not patchbay_data: sys.stderr.write( "RaySession::Failed to load tmp file %s to get JACK ports\n" % temp_path) return # optimize_operation allow to not redraw group at each port added. # however, if there is no group position # (i.e. if there is no config at all), it is prefferable to # know where finish the group boxes before to add another one. if self.group_positions: self.optimize_operation(True) for key in patchbay_data.keys(): if key == 'ports': for p in patchbay_data[key]: self.add_port(p.get('name'), p.get('type'), p.get('flags'), p.get('uuid')) elif key == 'clients': for cnu in patchbay_data[key]: self.client_name_and_uuid(cnu.get('name'), cnu.get('uuid')) elif key == 'connections': for c in patchbay_data[key]: self.add_connection(c.get('port_out_name'), c.get('port_in_name')) elif key == 'metadatas': for m in patchbay_data[key]: self.metadata_update( m.get('uuid'), m.get('key'), m.get('value')) for group in self.groups: group.sort_ports_in_canvas() self.optimize_operation(False) patchcanvas.redrawAllGroups() os.remove(temp_path) def patchbay_announce(self, jack_running: int, samplerate: int, buffer_size: int): self.tools_widget.set_samplerate(samplerate) self.tools_widget.set_buffer_size(buffer_size) self.tools_widget.set_jack_running(jack_running) self.session.main_win.add_patchbay_tools( self.tools_widget, self.canvas_menu) RaySession-0.12.2/src/gui/patchbay_tools.py000066400000000000000000000312341417052567600206530ustar00rootroot00000000000000 import os from PyQt5.QtCore import pyqtSignal, QTimer, QLocale, QUrl, Qt from PyQt5.QtGui import QIcon, QDesktopServices from PyQt5.QtWidgets import QWidget, QComboBox, QMenu, QApplication, QDialog import patchcanvas from gui_tools import is_dark_theme, get_code_root import ui.canvas_port_info import ui.patchbay_tools import ui.canvas_port_info GROUP_CONTEXT_AUDIO = 0x01 GROUP_CONTEXT_MIDI = 0x02 # Port Type PORT_TYPE_NULL = 0 PORT_TYPE_AUDIO = 1 PORT_TYPE_MIDI = 2 # Port Flags PORT_IS_INPUT = 0x01 PORT_IS_OUTPUT = 0x02 PORT_IS_PHYSICAL = 0x04 PORT_CAN_MONITOR = 0x08 PORT_IS_TERMINAL = 0x10 PORT_IS_CONTROL_VOLTAGE = 0x100 _translate = QApplication.translate class PatchbayToolsWidget(QWidget): buffer_size_change_order = pyqtSignal(int) def __init__(self): QWidget.__init__(self) self.ui = ui.patchbay_tools.Ui_Form() self.ui.setupUi(self) if is_dark_theme(self): self.ui.sliderZoom.setStyleSheet( self.ui.sliderZoom.styleSheet().replace('/breeze/', '/breeze-dark/')) self._waiting_buffer_change = False self._buffer_change_from_osc = False self.ui.sliderZoom.valueChanged.connect(self.set_zoom) self.ui.pushButtonXruns.clicked.connect( self.reset_xruns) self.ui.comboBoxBuffer.currentIndexChanged.connect( self.change_buffersize) self.buffer_sizes = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192] for size in self.buffer_sizes: self.ui.comboBoxBuffer.addItem(str(size), size) self.current_buffer_size = self.ui.comboBoxBuffer.currentData() self.xruns_counter = 0 def zoom_changed_from_canvas(self, ratio): self.ui.sliderZoom.set_percent(ratio * 100) def set_zoom(self, value): percent = self.ui.sliderZoom.zoom_percent() patchcanvas.canvas.scene.zoom_ratio(percent) def set_samplerate(self, samplerate: int): str_sr = str(samplerate) str_samplerate = str_sr if len(str_sr) > 3: str_samplerate = str_sr[:-3] + ' ' + str_sr[-3:] self.ui.labelSamplerate.setText(str_samplerate) def set_buffer_size(self, buffer_size: int): self._waiting_buffer_change = False self.ui.comboBoxBuffer.setEnabled(True) if self.ui.comboBoxBuffer.currentData() == buffer_size: return self._buffer_change_from_osc = True index = self.ui.comboBoxBuffer.findData(buffer_size) # manage exotic buffer sizes # findData returns -1 if buffer_size is not in combo box values if index < 0: index = 0 for size in self.buffer_sizes: if size > buffer_size: break index += 1 self.buffer_sizes.insert(index, buffer_size) self.ui.comboBoxBuffer.insertItem( index, str(buffer_size), buffer_size) self.ui.comboBoxBuffer.setCurrentIndex(index) self.current_buffer_size = buffer_size def update_xruns(self): self.ui.pushButtonXruns.setText("%i Xruns" % self.xruns_counter) def add_xrun(self): self.xruns_counter += 1 self.update_xruns() def reset_xruns(self): self.xruns_counter = 0 self.update_xruns() def set_dsp_load(self, dsp_load: int): self.ui.progressBarDsp.setValue(dsp_load) def change_buffersize(self, index: int): # prevent loop of buffer size change if self._buffer_change_from_osc: # change_buffersize not called by user # but ensure next time it could be self._buffer_change_from_osc = False return self.ui.comboBoxBuffer.setEnabled(False) self._waiting_buffer_change = True self.buffer_size_change_order.emit( self.ui.comboBoxBuffer.currentData()) # only in the case no set_buffer_size message come back QTimer.singleShot(10000, self.re_enable_buffer_combobox) def re_enable_buffer_combobox(self): if self._waiting_buffer_change: self.set_buffer_size(self.current_buffer_size) def set_jack_running(self, yesno: bool): for widget in ( self.ui.sliderZoom, self.ui.labelSamplerate, self.ui.labelSamplerateUnits, self.ui.labelBuffer, self.ui.comboBoxBuffer, self.ui.pushButtonXruns, self.ui.progressBarDsp, self.ui.lineSep1, self.ui.lineSep2, self.ui.lineSep3): widget.setVisible(yesno) self.ui.labelJackNotStarted.setVisible(not yesno) if yesno: patchcanvas.canvas.scene.scaleChanged.connect( self.zoom_changed_from_canvas) self.ui.sliderZoom.zoom_fit_asked.connect( patchcanvas.canvas.scene.zoom_fit) class CanvasMenu(QMenu): def __init__(self, patchbay_manager): QMenu.__init__(self, _translate('patchbay', 'Patchbay')) self.patchbay_manager = patchbay_manager # fix wrong menu position with Wayland, # see https://community.kde.org/Guidelines_and_HOWTOs/Wayland_Porting_Notes self.winId() main_win = self.patchbay_manager.session.main_win main_win.winId() parent_window_handle = main_win.windowHandle() if not parent_window_handle: native_parent_widget = main_win.nativeParentWidget() if native_parent_widget: parent_window_handle = native_parent_widget.windowHandle() self.windowHandle().setTransientParent(parent_window_handle) self.patchbay_manager.session.signaler.port_types_view_changed.connect( self._port_types_view_changed) self.action_fullscreen = self.addAction( _translate('patchbay', "Toggle Full Screen")) self.action_fullscreen.setIcon(QIcon.fromTheme('view-fullscreen')) self.action_fullscreen.triggered.connect( patchbay_manager.toggle_full_screen) port_types_view = patchbay_manager.port_types_view & ( GROUP_CONTEXT_AUDIO | GROUP_CONTEXT_MIDI) self.action_find_box = self.addAction( _translate('patchbay', "Find a box...\tCtrl+F")) self.action_find_box.setIcon(QIcon.fromTheme('edit-find')) self.action_find_box.triggered.connect( main_win.toggle_patchbay_filters_bar) self.port_types_menu = QMenu(_translate('patchbay', 'Type filter'), self) self.port_types_menu.setIcon(QIcon.fromTheme('view-filter')) self.action_audio_midi = self.port_types_menu.addAction( _translate('patchbay', 'Audio + Midi')) self.action_audio_midi.setCheckable(True) self.action_audio_midi.setChecked( bool(port_types_view == (GROUP_CONTEXT_AUDIO | GROUP_CONTEXT_MIDI))) self.action_audio_midi.triggered.connect( self.port_types_view_audio_midi_choice) self.action_audio = self.port_types_menu.addAction( _translate('patchbay', 'Audio only')) self.action_audio.setCheckable(True) self.action_audio.setChecked(port_types_view == GROUP_CONTEXT_AUDIO) self.action_audio.triggered.connect( self.port_types_view_audio_choice) self.action_midi = self.port_types_menu.addAction( _translate('patchbay', 'MIDI only')) self.action_midi.setCheckable(True) self.action_midi.setChecked(port_types_view == GROUP_CONTEXT_MIDI) self.action_midi.triggered.connect( self.port_types_view_midi_choice) self.addMenu(self.port_types_menu) self.zoom_menu = QMenu(_translate('patchbay', 'Zoom'), self) self.zoom_menu.setIcon(QIcon.fromTheme('zoom')) self.autofit = self.zoom_menu.addAction( _translate('patchbay', 'auto-fit')) self.autofit.setIcon(QIcon.fromTheme('zoom-select-fit')) self.autofit.setShortcut('Home') self.autofit.triggered.connect(patchcanvas.canvas.scene.zoom_fit) self.zoom_in = self.zoom_menu.addAction( _translate('patchbay', 'Zoom +')) self.zoom_in.setIcon(QIcon.fromTheme('zoom-in')) self.zoom_in.setShortcut('Ctrl++') self.zoom_in.triggered.connect(patchcanvas.canvas.scene.zoom_in) self.zoom_out = self.zoom_menu.addAction( _translate('patchbay', 'Zoom -')) self.zoom_out.setIcon(QIcon.fromTheme('zoom-out')) self.zoom_out.setShortcut('Ctrl+-') self.zoom_out.triggered.connect(patchcanvas.canvas.scene.zoom_out) self.zoom_orig = self.zoom_menu.addAction( _translate('patchbay', 'Zoom 100%')) self.zoom_orig.setIcon(QIcon.fromTheme('zoom')) self.zoom_orig.setShortcut('Ctrl+1') self.zoom_orig.triggered.connect(patchcanvas.canvas.scene.zoom_reset) self.addMenu(self.zoom_menu) self.action_refresh = self.addAction( _translate('patchbay', "Refresh the canvas")) self.action_refresh.setIcon(QIcon.fromTheme('view-refresh')) self.action_refresh.triggered.connect(patchbay_manager.refresh) self.action_manual = self.addAction( _translate('patchbay', "Patchbay manual")) self.action_manual.setIcon(QIcon.fromTheme('system-help')) self.action_manual.triggered.connect(self.internal_manual) self.action_options = self.addAction( _translate('patchbay', "Canvas options")) self.action_options.setIcon(QIcon.fromTheme("configure")) self.action_options.triggered.connect( patchbay_manager.show_options_dialog) def _port_types_view_changed(self, port_types_view: int): self.action_audio_midi.setChecked( port_types_view == GROUP_CONTEXT_AUDIO | GROUP_CONTEXT_MIDI) self.action_audio.setChecked( port_types_view == GROUP_CONTEXT_AUDIO) self.action_midi.setChecked( port_types_view == GROUP_CONTEXT_MIDI) def port_types_view_audio_midi_choice(self): self.patchbay_manager.change_port_types_view( GROUP_CONTEXT_AUDIO | GROUP_CONTEXT_MIDI) def port_types_view_audio_choice(self): self.patchbay_manager.change_port_types_view( GROUP_CONTEXT_AUDIO) def port_types_view_midi_choice(self): self.patchbay_manager.change_port_types_view( GROUP_CONTEXT_MIDI) def internal_manual(self): short_locale = 'en' manual_dir = "%s/manual" % get_code_root() locale_str = QLocale.system().name() if (len(locale_str) > 2 and '_' in locale_str and os.path.isfile( "%s/%s/manual.html" % (manual_dir, locale_str[:2]))): short_locale = locale_str[:2] url = QUrl("file://%s/%s/manual.html#patchbay" % (manual_dir, short_locale)) QDesktopServices.openUrl(url) class CanvasPortInfoDialog(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.ui = ui.canvas_port_info.Ui_Dialog() self.ui.setupUi(self) self._port = None self.ui.toolButtonRefresh.clicked.connect( self.update_contents) def set_port(self, port): self._port = port self.update_contents() def update_contents(self): if self._port is None: return port_type_str = _translate('patchbay', "Audio") if self._port.type == PORT_TYPE_MIDI: port_type_str = _translate('patchbay', "MIDI") flags_list = [] dict_flag_str = { PORT_IS_INPUT: _translate('patchbay', 'Input'), PORT_IS_OUTPUT: _translate('patchbay', 'Output'), PORT_IS_PHYSICAL: _translate('patchbay', 'Physical'), PORT_CAN_MONITOR: _translate('patchbay', 'Monitor'), PORT_IS_TERMINAL: _translate('patchbay', 'Terminal'), PORT_IS_CONTROL_VOLTAGE: _translate('patchbay', 'Control Voltage')} for key in dict_flag_str.keys(): if self._port.flags & key: flags_list.append(dict_flag_str[key]) port_flags_str = ' | '.join(flags_list) self.ui.lineEditFullPortName.setText(self._port.full_name) self.ui.lineEditUuid.setText(str(self._port.uuid)) self.ui.labelPortType.setText(port_type_str) self.ui.labelPortFlags.setText(port_flags_str) self.ui.labelPrettyName.setText(self._port.pretty_name) self.ui.labelPortOrder.setText(str(self._port.order)) self.ui.labelPortGroup.setText(self._port.mdata_portgroup) self.ui.groupBoxMetadatas.setVisible(bool( self._port.pretty_name or self._port.order is not None or self._port.mdata_portgroup)) RaySession-0.12.2/src/gui/patchcanvas/000077500000000000000000000000001417052567600175565ustar00rootroot00000000000000RaySession-0.12.2/src/gui/patchcanvas/__init__.py000066400000000000000000000233531417052567600216750ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from PyQt5.QtCore import QPointF, QRectF from PyQt5.QtWidgets import QGraphicsItem # ------------------------------------------------------------------------------------------------------------ # Imports (Theme) from .theme import getDefaultThemeName # ------------------------------------------------------------------------------------------------------------ # Maximum Id for a plugin, treated as invalid/zero if above this value MAX_PLUGIN_ID_ALLOWED = 0x7FF # Port Mode PORT_MODE_NULL = 0 PORT_MODE_INPUT = 1 PORT_MODE_OUTPUT = 2 # Port Type PORT_TYPE_NULL = 0 PORT_TYPE_AUDIO_JACK = 1 PORT_TYPE_MIDI_JACK = 2 PORT_TYPE_MIDI_ALSA = 3 PORT_TYPE_PARAMETER = 4 # Callback Action ACTION_GROUP_INFO = 0 # group_id, N, N ACTION_GROUP_RENAME = 1 # group_id, N, N ACTION_GROUP_SPLIT = 2 # group_id, N, N ACTION_GROUP_JOIN = 3 # group_id, N, N ACTION_GROUP_JOINED = 4 # group_id, N, N ACTION_GROUP_MOVE = 5 # group_id, in_or_out, "x:y" ACTION_GROUP_WRAP = 6 # group_id, folded, N ACTION_PORTGROUP_ADD = 7 # N, N, "gId:pgId:pMode:pType:portId1:portId2" ACTION_PORTGROUP_REMOVE = 8 # group_id, portgrp_id, N ACTION_PORT_INFO = 9 # group_id, port_id, N ACTION_PORT_RENAME = 10 # group_id, port_id, N ACTION_PORTS_CONNECT = 11 # N, N, "outG:outP:inG:inP" ACTION_PORTS_DISCONNECT = 12 # conn_id, N, N ACTION_PLUGIN_CLONE = 13 # plugin_id, N, N ACTION_PLUGIN_EDIT = 14 # plugin_id, N, N ACTION_PLUGIN_RENAME = 15 # plugin_id, N, N ACTION_PLUGIN_REPLACE = 16 # plugin_id, N, N ACTION_PLUGIN_REMOVE = 17 # plugin_id, N, N ACTION_PLUGIN_SHOW_UI = 18 # plugin_id, N, N ACTION_BG_RIGHT_CLICK = 19 # N, N, N ACTION_DOUBLE_CLICK = 20 # N, N, N ACTION_INLINE_DISPLAY = 21 # plugin_id, N, N ACTION_CLIENT_SHOW_GUI = 22 # group_id, visible, N # Icon ICON_APPLICATION = 0 ICON_HARDWARE = 1 ICON_DISTRHO = 2 ICON_FILE = 3 ICON_PLUGIN = 4 ICON_LADISH_ROOM = 5 ICON_CLIENT = 6 ICON_INTERNAL = 7 # Split Option SPLIT_UNDEF = 0 SPLIT_NO = 1 SPLIT_YES = 2 # Antialiasing Option ANTIALIASING_NONE = 0 ANTIALIASING_SMALL = 1 ANTIALIASING_FULL = 2 # Eye-Candy Option EYECANDY_NONE = 0 EYECANDY_SMALL = 1 EYECANDY_FULL = 2 # For Repulsive boxes DIRECTION_NONE = 0 DIRECTION_LEFT = 1 DIRECTION_RIGHT = 2 DIRECTION_UP = 3 DIRECTION_DOWN = 4 # ------------------------------------------------------------------------------------------------------------ # object types CanvasBoxType = QGraphicsItem.UserType + 1 CanvasIconType = QGraphicsItem.UserType + 2 CanvasPortType = QGraphicsItem.UserType + 3 CanvasPortGroupType = QGraphicsItem.UserType + 4 CanvasLineType = QGraphicsItem.UserType + 5 CanvasBezierLineType = QGraphicsItem.UserType + 6 CanvasLineMovType = QGraphicsItem.UserType + 7 CanvasBezierLineMovType = QGraphicsItem.UserType + 8 CanvasRubberbandType = QGraphicsItem.UserType + 9 # ------------------------------------------------------------------------------------------------------------ # Canvas options class options_t(object): __slots__ = [ 'theme_name', 'auto_hide_groups', 'auto_select_items', 'use_bezier_lines', 'antialiasing', 'eyecandy', 'inline_displays', 'elastic', 'prevent_overlap', 'max_port_width' ] # Canvas features class features_t(object): __slots__ = [ 'group_info', 'group_rename', 'port_info', 'port_rename', 'handle_group_pos' ] # Main Canvas object class Canvas(object): def __init__(self): self.qobject = None self.settings = None self.theme = None self.initiated = False self.group_list = [] self.port_list = [] self.portgrp_list = [] self.connection_list = [] self.animation_list = [] self.clipboard = [] self.clipboard_cut = True self.group_plugin_map = {} self.callback = self.callback self.debug = False self.scene = None self.last_z_value = 0 self.last_connection_id = 0 self.initial_pos = QPointF(0, 0) self.size_rect = QRectF() self.is_line_mov = False self.semi_hide_opacity = 0.17 def callback(self, action, value1, value2, value_str): print("Canvas::callback({}, {}, {}, {})".format( action, value1, value2, value_str)) # ------------------------------------------------------------------------------------------------------------ # object lists class group_dict_t(object): __slots__ = [ 'group_id', 'group_name', 'split', 'icon_type', 'icon_name', 'plugin_id', 'plugin_ui', 'plugin_inline', 'null_pos', 'in_pos', 'out_pos', 'handle_client_gui', 'gui_visible', 'widgets' ] class port_dict_t(object): __slots__ = [ 'group_id', 'port_id', 'port_name', 'port_mode', 'port_type', 'portgrp_id', 'is_alternate', 'widget' ] def is_connectable_to(self, other)->bool: if self.port_type != other.port_type: return False if self.port_mode == other.port_mode: return False class portgrp_dict_t(object): __slots__ = [ 'portgrp_id', 'group_id', 'port_mode', 'port_type', 'port_id_list', 'widget' ] class connection_dict_t(object): __slots__ = [ 'connection_id', 'group_in_id', 'port_in_id', 'group_out_id', 'port_out_id', 'widget' ] class clipboard_element_dict_t: __slots__ = [ 'port_type', 'port_mode', 'group_id', 'port_id', 'group_port_ids'] class animation_dict_t(object): __slots__ = [ 'animation', 'item' ] # ------------------------------------------------------------------------------------------------------------ # Internal functions def bool2str(check): return "True" if check else "False" def port_mode2str(port_mode): if port_mode == PORT_MODE_NULL: return "PORT_MODE_NULL" elif port_mode == PORT_MODE_INPUT: return "PORT_MODE_INPUT" elif port_mode == PORT_MODE_OUTPUT: return "PORT_MODE_OUTPUT" else: return "PORT_MODE_???" def port_type2str(port_type): if port_type == PORT_TYPE_NULL: return "PORT_TYPE_NULL" elif port_type == PORT_TYPE_AUDIO_JACK: return "PORT_TYPE_AUDIO_JACK" elif port_type == PORT_TYPE_MIDI_JACK: return "PORT_TYPE_MIDI_JACK" elif port_type == PORT_TYPE_MIDI_ALSA: return "PORT_TYPE_MIDI_ALSA" elif port_type == PORT_TYPE_PARAMETER: return "PORT_TYPE_MIDI_PARAMETER" else: return "PORT_TYPE_???" def icon2str(icon): if icon == ICON_APPLICATION: return "ICON_APPLICATION" elif icon == ICON_HARDWARE: return "ICON_HARDWARE" elif icon == ICON_DISTRHO: return "ICON_DISTRHO" elif icon == ICON_FILE: return "ICON_FILE" elif icon == ICON_PLUGIN: return "ICON_PLUGIN" elif icon == ICON_LADISH_ROOM: return "ICON_LADISH_ROOM" else: return "ICON_???" def split2str(split): if split == SPLIT_UNDEF: return "SPLIT_UNDEF" elif split == SPLIT_NO: return "SPLIT_NO" elif split == SPLIT_YES: return "SPLIT_YES" else: return "SPLIT_???" # ------------------------------------------------------------------------------------------------------------ # Global objects canvas = Canvas() options = options_t() options.theme_name = getDefaultThemeName() options.auto_hide_groups = False options.auto_select_items = False options.use_bezier_lines = True options.antialiasing = ANTIALIASING_SMALL options.eyecandy = EYECANDY_SMALL options.inline_displays = False options.elastic = True options.prevent_overlap = True options.max_port_width = 160 features = features_t() features.group_info = False features.group_rename = False features.port_info = False features.port_rename = False features.handle_group_pos = False # PatchCanvas API def setOptions(new_options): if canvas.initiated: return options.theme_name = new_options.theme_name options.auto_hide_groups = new_options.auto_hide_groups options.auto_select_items = new_options.auto_select_items options.use_bezier_lines = new_options.use_bezier_lines options.antialiasing = new_options.antialiasing options.eyecandy = new_options.eyecandy options.inline_displays = new_options.inline_displays options.elastic = new_options.elastic options.prevent_overlap = new_options.prevent_overlap options.max_port_width = new_options.max_port_width def setFeatures(new_features): if canvas.initiated: return features.group_info = new_features.group_info features.group_rename = new_features.group_rename features.port_info = new_features.port_info features.port_rename = new_features.port_rename features.handle_group_pos = new_features.handle_group_pos RaySession-0.12.2/src/gui/patchcanvas/canvasbezierline.py000066400000000000000000000222561417052567600234630ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from math import log, sqrt from PyQt5.QtCore import Qt, QPointF from PyQt5.QtGui import QColor, QLinearGradient, QPainter, QPainterPath, QPen from PyQt5.QtWidgets import QGraphicsPathItem # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, options, CanvasBezierLineType, ACTION_PORTS_DISCONNECT, EYECANDY_FULL, PORT_MODE_OUTPUT, PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_MIDI_JACK, PORT_TYPE_PARAMETER, ) from .utils import CanvasGetPortGroupPosition from .canvasportglow import CanvasPortGlow # ------------------------------------------------------------------------------------------------------------ class CanvasBezierLine(QGraphicsPathItem): def __init__(self, item1, item2, parent): QGraphicsPathItem.__init__(self) self.setParentItem(parent) self.item1 = item1 self.item2 = item2 self.m_locked = False self.m_lineSelected = False self.m_ready_to_disc = False self.m_is_semi_hidden = False self.setBrush(QColor(0, 0, 0, 0)) self.setGraphicsEffect(None) self.updateLinePos() def isReadyToDisc(self): return self.m_ready_to_disc def setReadyToDisc(self, yesno): self.m_ready_to_disc = yesno def isLocked(self): return self.m_locked def setLocked(self, yesno): self.m_locked = yesno def isLineSelected(self): return self.m_lineSelected def setLineSelected(self, yesno): if self.m_locked: return if yesno != self.m_lineSelected and options.eyecandy == EYECANDY_FULL: if yesno: self.setGraphicsEffect(CanvasPortGlow(self.item1.getPortType(), self.toGraphicsObject())) else: self.setGraphicsEffect(None) self.m_lineSelected = yesno self.updateLineGradient() def triggerDisconnect(self): for connection in canvas.connection_list: if (connection.port_out_id == self.item1.getPortId() and connection.port_in_id == self.item2.getPortId()): canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, "") break def semi_hide(self, yesno: bool): self.m_is_semi_hidden = yesno self.updateLineGradient() def updateLinePos(self): if self.item1.getPortMode() == PORT_MODE_OUTPUT: item1_x = self.item1.scenePos().x() + self.item1.getPortWidth() + 12 port_pos_1, portgrp_len_1 = self.item1.getPortGroupPosition() phi = 0.75 if portgrp_len_1 > 2 else 0.62 if portgrp_len_1 > 1: first_old_y = canvas.theme.port_height * phi last_old_y = canvas.theme.port_height * (portgrp_len_1 - phi) delta = (last_old_y - first_old_y) / (portgrp_len_1 -1) old_y1 = first_old_y + (port_pos_1 * delta) - (canvas.theme.port_height * port_pos_1) if not self.item1.isVisible(): # item is hidden port when its box is folded old_y1 = canvas.theme.port_height - old_y1 else: old_y1 = canvas.theme.port_height / 2 item1_y = self.item1.scenePos().y() + old_y1 item2_x = self.item2.scenePos().x() port_pos_2, portgrp_len_2 = self.item2.getPortGroupPosition() phi = 0.75 if portgrp_len_1 > 2 else 0.62 if portgrp_len_2 > 1: first_old_y = canvas.theme.port_height * phi last_old_y = canvas.theme.port_height * (portgrp_len_2 - phi) delta = (last_old_y - first_old_y) / (portgrp_len_2 -1) old_y2 = first_old_y + (port_pos_2 * delta) - (canvas.theme.port_height * port_pos_2) if not self.item2.isVisible(): old_y2 = canvas.theme.port_height - old_y2 else: old_y2 = canvas.theme.port_height / 2 item2_y = self.item2.scenePos().y() + old_y2 mid_x = abs(item1_x - item2_x) / 2 diffxy = abs(item1_y - item2_y) - abs(item1_x - item2_x) if diffxy > 0: mid_x += diffxy if diffxy > 0 or item1_x > item2_x: mid_x = min(mid_x, 200) item1_new_x = item1_x + mid_x item2_new_x = item2_x - mid_x path = QPainterPath(QPointF(item1_x, item1_y)) path.cubicTo(item1_new_x, item1_y, item2_new_x, item2_y, item2_x, item2_y) self.setPath(path) self.m_lineSelected = False self.updateLineGradient() def type(self): return CanvasBezierLineType def updateLineGradient(self): pos_top = self.boundingRect().top() pos_bot = self.boundingRect().bottom() if self.item2.scenePos().y() >= self.item1.scenePos().y(): pos1 = 0 pos2 = 1 else: pos1 = 1 pos2 = 0 port_type1 = self.item1.getPortType() port_type2 = self.item2.getPortType() port_gradient = QLinearGradient(0, pos_top, 0, pos_bot) #if port_type1 == PORT_TYPE_AUDIO_JACK: #port_gradient.setColorAt(pos1, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack) #elif port_type1 == PORT_TYPE_MIDI_JACK: #port_gradient.setColorAt(pos1, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack) #elif port_type1 == PORT_TYPE_MIDI_ALSA: #port_gradient.setColorAt(pos1, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa) #elif port_type1 == PORT_TYPE_PARAMETER: #port_gradient.setColorAt(pos1, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter) #if port_type2 == PORT_TYPE_AUDIO_JACK: #port_gradient.setColorAt(pos2, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack) #elif port_type2 == PORT_TYPE_MIDI_JACK: #port_gradient.setColorAt(pos2, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack) #elif port_type2 == PORT_TYPE_MIDI_ALSA: #port_gradient.setColorAt(pos2, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa) #elif port_type2 == PORT_TYPE_PARAMETER: #port_gradient.setColorAt(pos2, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter) base_color = canvas.theme.line_audio_jack if self.m_lineSelected: base_color = canvas.theme.line_audio_jack_sel if port_type1 == PORT_TYPE_MIDI_JACK: base_color = canvas.theme.port_midi_jack_bg if self.m_lineSelected: base_color = canvas.theme.port_midi_jack_bg_sel if self.m_is_semi_hidden: base_color = QColor(int(base_color.red() * canvas.semi_hide_opacity + 0.5), int(base_color.green() * canvas.semi_hide_opacity + 0.5), int(base_color.blue() * canvas.semi_hide_opacity + 0.5)) if self.m_ready_to_disc: port_gradient.setColorAt(pos1, QColor(34, 34, 34)) port_gradient.setColorAt(pos2, QColor(34, 34, 34)) self.setPen(QPen(port_gradient, 2, Qt.DotLine)) else: port_gradient.setColorAt(0, base_color.lighter(130)) port_gradient.setColorAt(0.5, base_color.darker(130)) port_gradient.setColorAt(1, base_color.lighter(130)) self.setPen(QPen(port_gradient, 1.750001, Qt.SolidLine, Qt.FlatCap)) def paint(self, painter, option, widget): if canvas.scene.loading_items: return painter.save() painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing)) pen = self.pen() cosm_pen = QPen(pen) cosm_pen.setCosmetic(True) cosm_pen.setWidthF(1.00001) QGraphicsPathItem.paint(self, painter, option, widget) painter.setPen(cosm_pen) painter.setBrush(Qt.NoBrush) painter.setOpacity(0.2) painter.drawPath(self.path()) painter.restore() # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvasbezierlinemov.py000066400000000000000000000177151417052567600242110ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from PyQt5.QtCore import qWarning, Qt, QPointF from PyQt5.QtGui import QPainter, QPainterPath, QPen from PyQt5.QtWidgets import QGraphicsPathItem # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, options, port_mode2str, port_type2str, CanvasBezierLineMovType, CanvasPortType, CanvasPortGroupType, PORT_MODE_INPUT, PORT_MODE_OUTPUT, PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_MIDI_JACK, PORT_TYPE_PARAMETER, ) # ------------------------------------------------------------------------------------------------------------ class CanvasBezierLineMov(QGraphicsPathItem): def __init__(self, port_mode, port_type, port_posinportgrp, portgrp_lenght, parent): QGraphicsPathItem.__init__(self) self.setParentItem(parent) self.m_port_mode = port_mode self.m_port_type = port_type self.m_port_posinportgrp = port_posinportgrp self.m_port_posinportgrp_to = port_posinportgrp self.m_portgrp_lenght = portgrp_lenght self.m_portgrp_lenght_to = portgrp_lenght self.m_ready_to_disc = False # Port position doesn't change while moving around line self.p_itemX = self.scenePos().x() self.p_itemY = self.scenePos().y() self.p_width = parent.getPortWidth() if self.m_port_type not in (PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_PARAMETER): qWarning("PatchCanvas::CanvasBezierLineMov(%s, %s, %s) - invalid port type" % (port_mode2str(self.m_port_mode), port_type2str(self.m_port_type), self.parentItem())) def setReadyToDisc(self, yesno): self.m_ready_to_disc = yesno def toggleReadyToDisc(self): self.m_ready_to_disc = not bool(self.m_ready_to_disc) def setDestinationPortGroupPosition(self, port_pos, portgrp_len): self.m_port_posinportgrp_to = port_pos self.m_portgrp_lenght_to = portgrp_len def updateLinePos(self, scenePos): if self.m_ready_to_disc: if self.m_port_type == PORT_TYPE_AUDIO_JACK: pen = QPen(canvas.theme.line_audio_jack_sel, 2, Qt.DotLine) elif self.m_port_type == PORT_TYPE_MIDI_JACK: pen = QPen(canvas.theme.line_midi_jack_sel, 2, Qt.DotLine) elif self.m_port_type == PORT_TYPE_MIDI_ALSA: pen = QPen(canvas.theme.line_midi_alsa_sel, 2, Qt.DotLine) elif self.m_port_type == PORT_TYPE_PARAMETER: pen = QPen(canvas.theme.line_parameter_sel, 2, Qt.DotLine) else: pen = QPen(Qt.black) else: if self.m_port_type == PORT_TYPE_AUDIO_JACK: pen = QPen(canvas.theme.line_audio_jack_sel, 2) elif self.m_port_type == PORT_TYPE_MIDI_JACK: pen = QPen(canvas.theme.line_midi_jack_sel, 2) elif self.m_port_type == PORT_TYPE_MIDI_ALSA: pen = QPen(canvas.theme.line_midi_alsa_sel, 2) elif self.m_port_type == PORT_TYPE_PARAMETER: pen = QPen(canvas.theme.line_parameter_sel, 2) else: pen = QPen(Qt.black) pen.setCapStyle(Qt.FlatCap) pen.setWidthF(pen.widthF() + 0.00001) self.setPen(pen) phi = 0.75 if self.m_portgrp_lenght > 2 else 0.62 phito = 0.75 if self.m_portgrp_lenght_to > 2 else 0.62 if self.parentItem().type() == CanvasPortType: if self.m_portgrp_lenght > 1: first_old_y = canvas.theme.port_height * phi last_old_y = canvas.theme.port_height * (self.m_portgrp_lenght - phi) delta = (last_old_y - first_old_y) / (self.m_portgrp_lenght -1) old_y = first_old_y + (self.m_port_posinportgrp * delta) \ - canvas.theme.port_height * self.m_port_posinportgrp else: old_y = canvas.theme.port_height / 2 if self.m_portgrp_lenght_to == 1: new_y = 0 else: first_new_y = canvas.theme.port_height * phito last_new_y = canvas.theme.port_height * (self.m_portgrp_lenght_to - phito) delta = (last_new_y - first_new_y) / (self.m_portgrp_lenght_to -1) new_y1 = first_new_y + (self.m_port_posinportgrp_to * delta) new_y = new_y1 - ( (last_new_y - first_new_y) / 2 ) \ - canvas.theme.port_height * phito elif self.parentItem().type() == CanvasPortGroupType: first_old_y = canvas.theme.port_height * phi last_old_y = canvas.theme.port_height * (self.m_portgrp_lenght - phi) delta = (last_old_y - first_old_y) / (self.m_portgrp_lenght -1) old_y = first_old_y + (self.m_port_posinportgrp * delta) if self.m_portgrp_lenght_to == 1: new_y = 0 elif (self.m_port_posinportgrp_to == self.m_port_posinportgrp and self.m_portgrp_lenght == self.m_portgrp_lenght_to): new_y = old_y - ( (last_old_y - first_old_y) / 2 ) \ - (canvas.theme.port_height * phi) else: first_new_y = canvas.theme.port_height * phito last_new_y = canvas.theme.port_height * (self.m_portgrp_lenght_to - phito) delta = (last_new_y - first_new_y) / (self.m_portgrp_lenght_to -1) new_y1 = first_new_y + (self.m_port_posinportgrp_to * delta) new_y = new_y1 - ( (last_new_y - first_new_y) / 2 ) \ - (canvas.theme.port_height * phito) final_x = scenePos.x() - self.p_itemX final_y = scenePos.y() - self.p_itemY + new_y if self.m_port_mode == PORT_MODE_OUTPUT: old_x = self.p_width + 12 mid_x = abs(final_x - old_x) / 2 new_x1 = old_x + mid_x new_x2 = final_x - mid_x diffxy = abs(final_y - old_y) - abs(final_x - old_x) if diffxy > 0: new_x1 += abs(diffxy) new_x2 -= abs(diffxy) elif self.m_port_mode == PORT_MODE_INPUT: old_x = 0 mid_x = abs(final_x - old_x) / 2 new_x1 = old_x - mid_x new_x2 = final_x + mid_x diffxy = abs(final_y - old_y) - abs(final_x - old_x) if diffxy > 0: new_x1 -= abs(diffxy) new_x2 += abs(diffxy) else: return path = QPainterPath(QPointF(old_x, old_y)) path.cubicTo(new_x1, old_y, new_x2, final_y, final_x, final_y) self.setPath(path) def type(self): return CanvasBezierLineMovType def paint(self, painter, option, widget): painter.save() painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing)) QGraphicsPathItem.paint(self, painter, option, widget) painter.restore() # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvasbox.py000066400000000000000000002257611417052567600221310ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) import math import sys import time from sip import voidptr from struct import pack from PyQt5.QtCore import (qCritical, Qt, QPoint, QPointF, QRectF, QTimer, pyqtSignal, QMarginsF, QTimer) from PyQt5.QtGui import (QCursor, QFont, QFontMetrics, QImage, QLinearGradient, QPainter, QPen, QPolygonF, QColor, QIcon, QPixmap) from PyQt5.QtWidgets import QGraphicsItem, QMenu, QApplication # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, features, options, port_dict_t, CanvasBoxType, ANTIALIASING_FULL, ACTION_PLUGIN_EDIT, ACTION_PLUGIN_SHOW_UI, ACTION_PLUGIN_CLONE, ACTION_PLUGIN_REMOVE, ACTION_PLUGIN_RENAME, ACTION_PLUGIN_REPLACE, ACTION_GROUP_INFO, ACTION_GROUP_JOIN, ACTION_GROUP_SPLIT, ACTION_GROUP_RENAME, ACTION_GROUP_MOVE, ACTION_GROUP_WRAP, ACTION_PORTS_DISCONNECT, ACTION_INLINE_DISPLAY, ACTION_CLIENT_SHOW_GUI, EYECANDY_FULL, PORT_MODE_NULL, PORT_MODE_INPUT, PORT_MODE_OUTPUT, PORT_TYPE_NULL, PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_MIDI_JACK, PORT_TYPE_PARAMETER, MAX_PLUGIN_ID_ALLOWED, ICON_HARDWARE, ICON_INTERNAL, ICON_CLIENT, DIRECTION_DOWN ) from .canvasboxshadow import CanvasBoxShadow from .canvasicon import CanvasSvgIcon, CanvasIconPixmap from .canvasport import CanvasPort from .canvasportgroup import CanvasPortGroup from .theme import Theme from .utils import (CanvasItemFX, CanvasGetFullPortName, CanvasGetPortConnectionList, CanvasGetPortGroupName, CanvasGetPortGroupPosition, CanvasGetPortPrintName, CanvasCallback, CanvasConnectionConcerns, CanvasGetIcon, is_dark_theme) _translate = QApplication.translate UNWRAP_BUTTON_NONE = 0 UNWRAP_BUTTON_LEFT = 1 UNWRAP_BUTTON_CENTER = 2 UNWRAP_BUTTON_RIGHT = 3 # ------------------------------------------------------------------------------------------------------------ class cb_line_t(object): def __init__(self, line, connection_id): self.line = line self.connection_id = connection_id class TitleLine: text = '' size = 0 x = 0 y = 0 is_little = False def __init__(self, text: str, little=False): self.text = text self.is_little = little self.x = 0 self.y = 0 self.font = QFont() self.font.setFamily(canvas.theme.box_font_name) self.font.setPixelSize(canvas.theme.box_font_size) if not little: self.font.setWeight(QFont.Bold) self.size = QFontMetrics(self.font).width(text) def reduce_pixel(self, reduce): self.font.setPixelSize(canvas.theme.box_font_size - reduce) self.size = QFontMetrics(self.font).width(self.text) # ------------------------------------------------------------------------------------------------------------ class CanvasBox(QGraphicsItem): INLINE_DISPLAY_DISABLED = 0 INLINE_DISPLAY_ENABLED = 1 INLINE_DISPLAY_CACHED = 2 def __init__(self, group_id: int, group_name: str, icon_type: int, icon_name: str, parent=None): QGraphicsItem.__init__(self) self.setParentItem(parent) # Save Variables, useful for later self.m_group_id = group_id self.m_group_name = group_name self.m_icon_type = icon_type self._title_lines = [TitleLine(group_name)] # plugin Id, < 0 if invalid self.m_plugin_id = -1 self.m_plugin_ui = False self.m_plugin_inline = self.INLINE_DISPLAY_DISABLED # Base Variables self.p_width = 50 self.p_width_in = 0 self.p_width_out = 0 self.p_height = canvas.theme.box_header_height + canvas.theme.box_header_spacing + 1 self.p_ex_width = self.p_width self.p_ex_height = self.p_height self.p_header_height = canvas.theme.box_header_height self.p_ex_scene_pos = self.scenePos() self.m_last_pos = QPointF() self.m_splitted = False self.m_splitted_mode = PORT_MODE_NULL self.m_current_port_mode = PORT_MODE_NULL # depends of present ports self.m_cursor_moving = False self.m_forced_split = False self.m_mouse_down = False self.m_inline_data = None self.m_inline_image = None self.m_inline_scaling = 1.0 self.m_port_list_ids = [] self.m_connection_lines = [] # Set Font self.m_font_name = QFont() self.m_font_name.setFamily(canvas.theme.box_font_name) self.m_font_name.setPixelSize(canvas.theme.box_font_size) self.m_font_name.setWeight(canvas.theme.box_font_state) self.m_font_italic = QFont() self.m_font_italic.setFamily(canvas.theme.box_font_name) self.m_font_italic.setPixelSize(canvas.theme.box_font_size) self.m_font_italic.setWeight(canvas.theme.box_font_state) #self.m_font_italic.setItalic(True) self.m_font_italic.setBold(False) self.m_font_port = QFont() self.m_font_port.setFamily(canvas.theme.port_font_name) self.m_font_port.setPixelSize(canvas.theme.port_font_size) self.m_font_port.setWeight(canvas.theme.port_font_state) self._is_hardware = bool(icon_type == ICON_HARDWARE) self._hw_polygon = QPolygonF() self._icon_name = icon_name self._wrapped = False self._wrapping = False self._unwrapping = False self._wrapping_ratio = 1.0 self.p_unwrap_triangle_pos = UNWRAP_BUTTON_NONE self._ensuring_visible = False # Icon if canvas.theme.box_use_icon: if icon_type in (ICON_HARDWARE, ICON_INTERNAL): port_mode = PORT_MODE_NULL if self.m_splitted: port_mode = self.m_splitted_mode self.top_icon = CanvasSvgIcon( icon_type, icon_name, port_mode, self) else: self.top_icon = CanvasIconPixmap(icon_type, icon_name, self) if self.top_icon.is_null(): top_icon = self.top_icon self.top_icon = None del top_icon else: self.top_icon = None # Shadow self.shadow = None # FIXME FX on top of graphic items make them lose high-dpi # See https://bugreports.qt.io/browse/QTBUG-65035 if options.eyecandy and canvas.scene.getDevicePixelRatioF() == 1.0: self.shadow = CanvasBoxShadow(self.toGraphicsObject()) self.shadow.setFakeParent(self) self.setGraphicsEffect(self.shadow) # Final touches self.setFlags(QGraphicsItem.ItemIsFocusable | QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable) # Wait for at least 1 port if options.auto_hide_groups: self.setVisible(False) if options.auto_select_items: self.setAcceptHoverEvents(True) self.m_is_semi_hidden = False self.m_can_handle_gui = False # used for optional-gui switch self.m_gui_visible = False self.updatePositions() canvas.scene.addItem(self) QTimer.singleShot(0, self.fixPos) def getGroupId(self): return self.m_group_id def getGroupName(self): return self.m_group_name def isSplitted(self): return self.m_splitted def getSplittedMode(self): return self.m_splitted_mode def getPortCount(self): return len(self.m_port_list_ids) def getPortList(self): return self.m_port_list_ids def get_current_port_mode(self): return self.m_current_port_mode def redrawInlineDisplay(self): if self.m_plugin_inline == self.INLINE_DISPLAY_CACHED: self.m_plugin_inline = self.INLINE_DISPLAY_ENABLED self.update() def removeAsPlugin(self): #del self.m_inline_image #self.m_inline_data = None #self.m_inline_image = None #self.m_inline_scaling = 1.0 self.m_plugin_id = -1 self.m_plugin_ui = False #self.m_plugin_inline = self.INLINE_DISPLAY_DISABLED def setAsPlugin(self, plugin_id, hasUI, hasInlineDisplay): if hasInlineDisplay and not options.inline_displays: hasInlineDisplay = False if not hasInlineDisplay: del self.m_inline_image self.m_inline_data = None self.m_inline_image = None self.m_inline_scaling = 1.0 self.m_plugin_id = plugin_id self.m_plugin_ui = hasUI self.m_plugin_inline = self.INLINE_DISPLAY_ENABLED if hasInlineDisplay else self.INLINE_DISPLAY_DISABLED self.update() def setIcon(self, icon_type, icon_name): if icon_type == ICON_HARDWARE: self.removeIconFromScene() port_mode = PORT_MODE_NULL if self.m_splitted: port_mode = self.m_splitted_mode self.top_icon = CanvasSvgIcon(icon_type, icon_name, port_mode, self) return if self.top_icon is not None: self.top_icon.setIcon(icon_type, icon_name, self.m_group_name) else: self.top_icon = CanvasIconPixmap(icon_type, icon_name, self) self.updatePositions() def has_top_icon(self)->bool: if self.top_icon is None: return False return not self.top_icon.is_null() def set_optional_gui_state(self, visible: bool): self.m_can_handle_gui = True self.m_gui_visible = visible def setSplit(self, split, mode=PORT_MODE_NULL): self.m_splitted = split self.m_splitted_mode = mode self.m_current_port_mode = mode if self._is_hardware: self.setIcon(ICON_HARDWARE, self._icon_name) def splitTitle(self, n_lines=True)->tuple: title, slash, subtitle = self.m_group_name.partition('/') if self.m_icon_type == ICON_CLIENT and subtitle: # if there is a subtitle, title is not bold when subtitle is. # so title is 'little' title_lines = [TitleLine(title, little=True)] if n_lines >= 3: title_lines += [TitleLine(subtt) for subtt in self.split_in_two(subtitle, 2) if subtt] else: title_lines.append(TitleLine(subtitle)) else: if n_lines >= 2: title_lines = [ TitleLine(tt) for tt in self.split_in_two(self.m_group_name, n_lines) if tt] else: title_lines= [TitleLine(self.m_group_name)] if len(title_lines) >= 4: for title_line in title_lines: title_line.reduce_pixel(2) return tuple(title_lines) def setGroupName(self, group_name): self.m_group_name = group_name self.updatePositions() def setShadowOpacity(self, opacity): if self.shadow: self.shadow.setOpacity(opacity) def addPortFromGroup(self, port_id, port_mode, port_type, port_name, is_alternate): if len(self.m_port_list_ids) == 0: if options.auto_hide_groups: if options.eyecandy == EYECANDY_FULL: CanvasItemFX(self, True, False) self.setVisible(True) new_widget = CanvasPort(self.m_group_id, port_id, port_name, port_mode, port_type, is_alternate, self) if self._wrapped: new_widget.setVisible(False) self.m_port_list_ids.append(port_id) return new_widget def removePortFromGroup(self, port_id): if port_id in self.m_port_list_ids: self.m_port_list_ids.remove(port_id) else: qCritical("PatchCanvas::CanvasBox.removePort(%i) - unable to find port to remove" % port_id) return if len(self.m_port_list_ids) > 0: self.updatePositions() elif self.isVisible(): if options.auto_hide_groups: if options.eyecandy == EYECANDY_FULL: CanvasItemFX(self, False, False) else: self.setVisible(False) def addPortGroupFromGroup(self, portgrp_id, port_mode, port_type, port_id_list): new_widget = CanvasPortGroup(self.m_group_id, portgrp_id, port_mode, port_type, port_id_list, self) if self._wrapped: new_widget.setVisible(False) return new_widget def addLineFromGroup(self, line, connection_id): new_cbline = cb_line_t(line, connection_id) self.m_connection_lines.append(new_cbline) def removeLineFromGroup(self, connection_id): for connection in self.m_connection_lines: if connection.connection_id == connection_id: self.m_connection_lines.remove(connection) return qCritical("PatchCanvas::CanvasBox.removeLineFromGroup(%i) - unable to find line to remove" % connection_id) def checkItemPos(self): if not canvas.size_rect.isNull(): pos = self.scenePos() if not (canvas.size_rect.contains(pos) and canvas.size_rect.contains(pos + QPointF(self.p_width, self.p_height))): if pos.x() < canvas.size_rect.x(): self.setPos(canvas.size_rect.x(), pos.y()) elif pos.x() + self.p_width > canvas.size_rect.width(): self.setPos(canvas.size_rect.width() - self.p_width, pos.y()) pos = self.scenePos() if pos.y() < canvas.size_rect.y(): self.setPos(pos.x(), canvas.size_rect.y()) elif pos.y() + self.p_height > canvas.size_rect.height(): self.setPos(pos.x(), canvas.size_rect.height() - self.p_height) def removeIconFromScene(self): if self.top_icon is None: return item = self.top_icon self.top_icon = None canvas.scene.removeItem(item) del item def animate_wrapping(self, ratio: float): # we expose wrapping ratio only for prettier animation # say self._wrapping_ratio = ratio would also works fine if self._wrapping: self._wrapping_ratio = ratio ** 0.25 else: self._wrapping_ratio = ratio ** 4 if ratio == 1.00: # counter is terminated if self._unwrapping: self.hide_ports_for_wrap(False) self._wrapping = False self._unwrapping = False self.updatePositions() def hide_ports_for_wrap(self, hide: bool): for portgrp in canvas.portgrp_list: if portgrp.group_id == self.m_group_id: if (self.m_splitted and self.m_splitted_mode != portgrp.port_mode): continue if portgrp.widget is not None: portgrp.widget.setVisible(not hide) for port in canvas.port_list: if port.group_id == self.m_group_id: if (self.m_splitted and self.m_splitted_mode != port.port_mode): continue if port.widget is not None: port.widget.setVisible(not hide) def is_wrapped(self)->bool: return self._wrapped def set_wrapped(self, yesno: bool, animate=True): if yesno == self._wrapped: return self._wrapped = yesno if yesno: self.hide_ports_for_wrap(True) if not animate: return self._wrapping = yesno self._unwrapping = not yesno canvas.scene.add_box_to_animation_wrapping(self, yesno) hws = canvas.theme.hardware_rack_width if yesno: new_bounding_rect = QRectF(0, 0, self.p_width, self.p_wrapped_height) if self._is_hardware: new_bounding_rect = QRectF(- hws, - hws, self.p_width + 2 * hws, self.p_wrapped_height + 2 * hws) canvas.scene.bring_neighbors_and_deplace_boxes(self, new_bounding_rect) else: new_bounding_rect = QRectF(0, 0, self.p_width, self.p_unwrapped_height) if self._is_hardware: new_bounding_rect = QRectF(- hws, - hws , self.p_width + 2 * hws, self.p_unwrapped_height + 2 * hws) canvas.scene.deplace_boxes_from_repulsers( [self], new_scene_rect=new_bounding_rect.translated(self.pos()), wanted_direction=DIRECTION_DOWN) def get_string_size(self, string: str)->int: return QFontMetrics(self.m_font_name).width(string) @staticmethod def split_in_two(string: str, n_lines=2)->tuple: sep_indexes = [] last_was_digit = False for sep in (' ', '-', '_', 'capital'): for i in range(len(string)): c = string[i] if sep == 'capital': if c.upper() == c: if not c.isdigit() or not last_was_digit: sep_indexes.append(i) last_was_digit = c.isdigit() elif c == sep: sep_indexes.append(i) if sep_indexes: break if not sep_indexes: # no available separator in given text return_list = [string] + ['' for n in range(1, n_lines)] return tuple(return_list) if len(sep_indexes) + 1 <= n_lines: return_list = [] last_index = 0 for sep_index in sep_indexes: return_list.append(string[last_index:sep_index]) last_index = sep_index if sep == ' ': last_index += 1 return_list.append(string[last_index:]) return_list += ['' for n in range(n_lines - len(sep_indexes) - 1)] return tuple(return_list) best_indexes = [0] string_rest = string string_list = [] for i in range(n_lines, 1, -1): target = best_indexes[-1] + int(len(string_rest)/i) best_index = 0 best_dif = len(string) for s in sep_indexes: if s <= best_indexes[-1]: continue dif = abs(target - s) if dif < best_dif: best_index = s best_dif = dif else: break if sep == ' ': string_rest = string[best_index+1:] else: string_rest = string[best_index:] best_indexes.append(best_index) best_indexes = best_indexes[1:] last_index = 0 return_list = [] for i in best_indexes: return_list.append(string[last_index:i]) last_index = i if sep == ' ': last_index += 1 return_list.append(string[last_index:]) return tuple(return_list) def updatePositions(self, even_animated=False): if canvas.scene.loading_items: return if (not even_animated and self in [b['widget'] for b in canvas.scene.move_boxes]): # do not change box disposition while box is moved by animation # updatePositions will be called when animation is finished return self.prepareGeometryChange() # Get Port List port_list = [] self.m_current_port_mode = PORT_MODE_NULL for port in canvas.port_list: if port.group_id == self.m_group_id and port.port_id in self.m_port_list_ids: port_list.append(port) # used to know present port modes (INPUT or OUTPUT) self.m_current_port_mode |= port.port_mode max_in_width = max_out_width = 0 port_spacing = canvas.theme.port_height + canvas.theme.port_spacing # Get Max Box Width, vertical ports re-positioning port_types = [PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_PARAMETER] last_in_type = last_out_type = PORT_TYPE_NULL last_in_alter = last_out_alter = False last_in_pos = last_out_pos = (canvas.theme.box_header_height + canvas.theme.box_header_spacing) final_last_in_pos = final_last_out_pos = last_in_pos wrapped_port_pos = last_in_pos last_of_portgrp = True align_port_types = True port_types_aligner = [] # check if we can align port types # eg, align first midi input to first midi output for port_type in port_types: aligner_item = [] for alternate in (False, True): n_ins = 0 n_outs = 0 for port in port_list: if (port.port_type == port_type and port.is_alternate == alternate): if port.port_mode == PORT_MODE_INPUT: n_ins += 1 elif port.port_mode == PORT_MODE_OUTPUT: n_outs += 1 port_types_aligner.append((n_ins, n_outs)) winner = PORT_MODE_NULL for n_ins, n_outs in port_types_aligner: if ((winner == PORT_MODE_INPUT and n_outs > n_ins) or (winner == PORT_MODE_OUTPUT and n_ins > n_outs)): align_port_types = False break if n_ins > n_outs: winner = PORT_MODE_INPUT elif n_outs > n_ins: winner = PORT_MODE_OUTPUT # ports Y positioning, and get width informations for port_type in port_types: for alternate in (False, True): for port in port_list: if (port.port_type != port_type or port.is_alternate != alternate): continue ## uncomment this block to enable ## inputs and outputs in down order ## to win space in some cases #last_in_pos = last_out_pos = max(last_in_pos, last_out_pos) port_pos, pg_len = CanvasGetPortGroupPosition( self.m_group_id, port.port_id, port.portgrp_id) first_of_portgrp = bool(port_pos == 0) last_of_portgrp = bool(port_pos + 1 == pg_len) size = 0 max_pwidth = options.max_port_width if port.portgrp_id: for portgrp in canvas.portgrp_list: if not (portgrp.group_id == self.m_group_id and portgrp.portgrp_id == port.portgrp_id): continue if port.port_id == portgrp.port_id_list[0]: portgrp_name = CanvasGetPortGroupName( self.m_group_id, portgrp.port_id_list) if portgrp_name: portgrp.widget.set_print_name( portgrp_name, max_pwidth - canvas.theme.port_in_portgrp_width - 5) else: portgrp.widget.set_print_name('', 0) port.widget.set_print_name( CanvasGetPortPrintName( self.m_group_id, port.port_id, port.portgrp_id), int(max_pwidth/2)) if portgrp.widget.get_text_width() + 5 > max_pwidth - port.widget.get_text_width(): portgrp.widget.reduce_print_name(max_pwidth - port.widget.get_text_width() - 5) size = portgrp.widget.get_text_width() \ + max(port.widget.get_text_width() + 6, canvas.theme.port_in_portgrp_width) break else: port.widget.set_print_name(port.port_name, max_pwidth) size = max(port.widget.get_text_width(), 20) if port.port_mode == PORT_MODE_INPUT: max_in_width = max(max_in_width, size) if (port.port_type != last_in_type or port.is_alternate != last_in_alter): if last_in_type != PORT_TYPE_NULL: last_in_pos += canvas.theme.port_spacingT last_in_type = port.port_type last_in_alter = port.is_alternate if self._wrapping: port.widget.setY(last_in_pos - (last_in_pos - wrapped_port_pos) * self._wrapping_ratio) elif self._unwrapping: port.widget.setY(wrapped_port_pos + (last_in_pos - wrapped_port_pos) * self._wrapping_ratio) elif self._wrapped: port.widget.setY(wrapped_port_pos) else: port.widget.setY(last_in_pos) if port.portgrp_id and first_of_portgrp: for portgrp in canvas.portgrp_list: if (portgrp.group_id == self.m_group_id and portgrp.portgrp_id == port.portgrp_id): if portgrp.widget is not None: if self._wrapped: portgrp.widget.setY(wrapped_port_pos) else: portgrp.widget.setY(last_in_pos) break if last_of_portgrp: last_in_pos += port_spacing else: last_in_pos += canvas.theme.port_height elif port.port_mode == PORT_MODE_OUTPUT: max_out_width = max(max_out_width, size) if (port.port_type != last_out_type or port.is_alternate != last_out_alter): if last_out_type != PORT_TYPE_NULL: last_out_pos += canvas.theme.port_spacingT last_out_type = port.port_type last_out_alter = port.is_alternate if self._wrapping: port.widget.setY(last_out_pos - (last_out_pos - wrapped_port_pos) * self._wrapping_ratio) elif self._unwrapping: port.widget.setY(wrapped_port_pos + (last_out_pos - wrapped_port_pos) * self._wrapping_ratio) elif self._wrapped: port.widget.setY(wrapped_port_pos) else: port.widget.setY(last_out_pos) if port.portgrp_id and first_of_portgrp: for portgrp in canvas.portgrp_list: if (portgrp.group_id == self.m_group_id and portgrp.portgrp_id == port.portgrp_id): if portgrp.widget is not None: if self._wrapped: portgrp.widget.setY(wrapped_port_pos) else: portgrp.widget.setY(last_out_pos) break if last_of_portgrp: last_out_pos += port_spacing else: last_out_pos += canvas.theme.port_height final_last_in_pos = last_in_pos final_last_out_pos = last_out_pos if align_port_types: # align port types horizontally if last_in_pos > last_out_pos: last_out_type = last_in_type last_out_alter = last_in_alter else: last_in_type = last_out_type last_in_alter = last_out_alter last_in_pos = last_out_pos = max(last_in_pos, last_out_pos) self.p_width = 30 if self.m_plugin_inline != self.INLINE_DISPLAY_DISABLED: self.p_width = 100 self.p_width += max_in_width + max_out_width #self.p_width += max(max_in_width, max_out_width) self.p_width_in = max_in_width self.p_width_out = max_out_width # Check Text Name size title_template = {"title_width": 0, "header_width": 0} all_title_templates = [title_template.copy() for i in range(5)] for i in range(1, 5): max_title_size = 0 title_lines = self.splitTitle(i) for title_line in title_lines: max_title_size = max(max_title_size, title_line.size) all_title_templates[i] header_width = max_title_size if self.has_top_icon(): header_width += 37 else: header_width += 16 header_width = max(200 if self.m_plugin_inline != self.INLINE_DISPLAY_DISABLED else 50, header_width) new_title_template = title_template.copy() new_title_template['title_width'] = max_title_size new_title_template['header_width'] = header_width all_title_templates[i] = new_title_template if header_width < self.p_width: break more_height = 0 lines_choice = 1 if all_title_templates[1]['header_width'] <= self.p_width: # One line title is shorter than the box, choose it lines_choice = 1 elif all_title_templates[2]['header_width'] <= self.p_width: # Two lines title is shorter than the box, choose it lines_choice = 2 else: more_height = 14 area_2 = all_title_templates[2]['header_width'] * max(last_in_pos, last_out_pos) area_3 = max(self.p_width, all_title_templates[3]['header_width']) \ * (max(last_in_pos, last_out_pos) + more_height) if area_2 <= area_3: # Box area is smaller with 2 lines titles than with 3 lines title # choose 2 lines title lines_choice = 2 more_height = 0 elif all_title_templates[3]['header_width'] <= self.p_width: # 3 lines title is shorter than the box, choose it lines_choice = 3 else: area_4 = max(self.p_width, all_title_templates[4]['header_width']) \ * (max(last_in_pos, last_out_pos) + more_height) if area_3 - area_4 >= 5000: lines_choice = 4 else: lines_choice = 3 self._title_lines = self.splitTitle(lines_choice) #more_width_for_gui = 0 #if self.m_can_handle_gui: #more_width_for_gui = 2 self.p_width = max(self.p_width, all_title_templates[lines_choice]['header_width']) max_title_size = all_title_templates[lines_choice]['title_width'] if more_height: # down ports for port in port_list: port.widget.setY(port.widget.y() + more_height) # down portgroups for portgrp in canvas.portgrp_list: if (portgrp.group_id == self.m_group_id and self.m_current_port_mode & portgrp.port_mode): if portgrp.widget is not None: portgrp.widget.setY(portgrp.widget.y() + more_height) last_in_pos += more_height last_out_pos += more_height # Horizontal ports re-positioning inX = canvas.theme.port_offset outX = self.p_width - max_out_width - canvas.theme.port_offset - 12 # Horizontal ports not in portgroup re-positioning for port in port_list: if port.portgrp_id: continue if port.port_mode == PORT_MODE_INPUT: port.widget.setX(inX) port.widget.setPortWidth(max_in_width) elif port.port_mode == PORT_MODE_OUTPUT: port.widget.setX(outX) port.widget.setPortWidth(max_out_width) # Horizontal portgroups and ports in portgroup re-positioning for portgrp in canvas.portgrp_list: if (portgrp.group_id != self.m_group_id or not self.m_current_port_mode & portgrp.port_mode): continue if portgrp.widget is not None: if portgrp.port_mode == PORT_MODE_INPUT: portgrp.widget.setPortGroupWidth(max_in_width) portgrp.widget.setX(canvas.theme.port_offset +1) elif portgrp.port_mode == PORT_MODE_OUTPUT: portgrp.widget.setPortGroupWidth(max_out_width) portgrp.widget.setX(outX) max_port_in_pg_width = canvas.theme.port_in_portgrp_width for port in canvas.port_list: if (port.group_id == self.m_group_id and port.port_id in portgrp.port_id_list and port.widget is not None): port_print_width = port.widget.get_text_width() # change port in portgroup width only if # portgrp will have a name # to ensure that portgroup widget is large enough if portgrp_name: max_port_in_pg_width = max(max_port_in_pg_width, port_print_width + 4) out_in_portgrpX = (self.p_width - canvas.theme.port_offset - 12 - max_port_in_pg_width) portgrp.widget.set_ports_width(max_port_in_pg_width) for port in canvas.port_list: if (port.group_id == self.m_group_id and port.port_id in portgrp.port_id_list and port.widget is not None): port.widget.setPortWidth(max_port_in_pg_width) if port.port_mode == PORT_MODE_INPUT: port.widget.setX(inX) elif port.port_mode == PORT_MODE_OUTPUT: port.widget.setX(out_in_portgrpX) # wrapped/unwrapped sizes normal_height = max(last_in_pos, last_out_pos) wrapped_height = wrapped_port_pos + canvas.theme.port_height if len(self._title_lines) >= 3: wrapped_height += 14 self.p_header_height = canvas.theme.box_header_height + 14 else: self.p_header_height = canvas.theme.box_header_height if self._wrapping: self.p_height = normal_height \ - (normal_height - wrapped_height) \ * self._wrapping_ratio elif self._unwrapping: self.p_height = wrapped_height \ + (normal_height - wrapped_height) \ * self._wrapping_ratio elif self._wrapped: self.p_height = wrapped_height else: self.p_height = max(last_in_pos, last_out_pos) self.p_unwrap_triangle_pos = UNWRAP_BUTTON_NONE if self.p_height >= 100: if final_last_out_pos > final_last_in_pos: self.p_unwrap_triangle_pos = UNWRAP_BUTTON_LEFT elif final_last_in_pos > final_last_out_pos: self.p_unwrap_triangle_pos = UNWRAP_BUTTON_RIGHT else: self.p_unwrap_triangle_pos = UNWRAP_BUTTON_CENTER down_height = max(canvas.theme.port_spacing, canvas.theme.port_spacingT) \ - canvas.theme.port_spacing \ + canvas.theme.box_pen.widthF() self.p_wrapped_height = wrapped_height + down_height self.p_unwrapped_height = normal_height + down_height self.p_height += down_height if self.has_top_icon(): self.top_icon.align_at((self.p_width - max_title_size - 29)/2) #if self.m_can_handle_gui: #self.top_icon.y_offset = 6 if (self.p_width != self.p_ex_width or self.p_height != self.p_ex_height or self.scenePos() != self.p_ex_scene_pos): canvas.scene.resize_the_scene() self.p_ex_width = self.p_width self.p_ex_height = self.p_height self.p_ex_scene_pos = self.scenePos() self.repaintLines(forced=True) if not (self._wrapping or self._unwrapping) and self.isVisible(): canvas.scene.deplace_boxes_from_repulsers([self]) self.update() def repaintLines(self, forced=False): if forced or self.pos() != self.m_last_pos: for connection in self.m_connection_lines: connection.line.updateLinePos() self.m_last_pos = self.pos() def resetLinesZValue(self): for connection in canvas.connection_list: if (connection.port_out_id in self.m_port_list_ids and connection.port_in_id in self.m_port_list_ids): z_value = canvas.last_z_value else: z_value = canvas.last_z_value - 1 connection.widget.setZValue(z_value) def _get_adjacent_boxes(self): item_list = [self] for item in item_list: rect = item.boundingRect() rect.translate(item.pos()) rect.adjust(0, -5, 0, 5) for litem in canvas.scene.items(rect): if (litem.type() == CanvasBoxType and litem not in item_list): item_list.append(litem) return item_list def semi_hide(self, yesno: bool): self.m_is_semi_hidden = yesno if yesno: self.setOpacity(canvas.semi_hide_opacity) else: self.setOpacity(1.0) def update_opacity(self): if not self.m_is_semi_hidden: return self.setOpacity(canvas.semi_hide_opacity) def type(self): return CanvasBoxType def contextMenuEvent(self, event): if canvas.is_line_mov: return event.accept() menu = QMenu() dark = '' if is_dark_theme(menu): dark = '-dark' # Disconnect menu stuff discMenu = QMenu(_translate('patchbay', "Disconnect"), menu) discMenu.setIcon( QIcon(QPixmap(':scalable/breeze%s/lines-disconnector' % dark))) conn_list_ids = [] disconnect_list = [] # will contains disconnect_element dicts for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, self.m_group_id, self.m_port_list_ids): conn_list_ids.append(connection.connection_id) other_group_id = connection.group_in_id group_port_mode = PORT_MODE_INPUT if self.m_splitted: if self.m_splitted_mode == PORT_MODE_INPUT: other_group_id = connection.group_out_id group_port_mode = PORT_MODE_OUTPUT else: if other_group_id == self.m_group_id: other_group_id = connection.group_out_id group_port_mode = PORT_MODE_OUTPUT for disconnect_element in disconnect_list: if disconnect_element['group_id'] == other_group_id: if group_port_mode == PORT_MODE_INPUT: disconnect_element['connection_in_ids'].append( connection.connection_id) else: disconnect_element['connection_out_ids'].append( connection.connection_id) break else: disconnect_element = {'group_id': other_group_id, 'connection_in_ids': [], 'connection_out_ids': []} if group_port_mode == PORT_MODE_INPUT: disconnect_element['connection_in_ids'].append( connection.connection_id) else: disconnect_element['connection_out_ids'].append( connection.connection_id) disconnect_list.append(disconnect_element) if disconnect_list: for disconnect_element in disconnect_list: for group in canvas.group_list: if group.group_id == disconnect_element['group_id']: if (group.split and disconnect_element['connection_in_ids'] and disconnect_element['connection_out_ids']): ins_label = " (inputs)" outs_label = " (outputs)" if group.icon_type == ICON_HARDWARE: ins_label = " (playbacks)" outs_label = " (captures)" act_x_disc1 = discMenu.addAction( group.group_name + outs_label) act_x_disc1.setIcon(CanvasGetIcon( group.icon_type, group.icon_name, PORT_MODE_OUTPUT)) act_x_disc1.setData( disconnect_element['connection_out_ids']) act_x_disc1.triggered.connect( canvas.qobject.PortContextMenuDisconnect) act_x_disc2 = discMenu.addAction( group.group_name + ins_label) act_x_disc2.setIcon(CanvasGetIcon( group.icon_type, group.icon_name, PORT_MODE_INPUT)) act_x_disc2.setData( disconnect_element['connection_in_ids']) act_x_disc2.triggered.connect( canvas.qobject.PortContextMenuDisconnect) else: port_mode = PORT_MODE_NULL if not disconnect_element['connection_in_ids']: port_mode = PORT_MODE_OUTPUT elif not disconnect_element['connection_out_ids']: port_mode = PORT_MODE_INPUT act_x_disc = discMenu.addAction(group.group_name) icon = CanvasGetIcon( group.icon_type, group.icon_name, port_mode) act_x_disc.setIcon(icon) act_x_disc.setData( disconnect_element['connection_out_ids'] + disconnect_element['connection_in_ids']) act_x_disc.triggered.connect( canvas.qobject.PortContextMenuDisconnect) break else: act_x_disc = discMenu.addAction("No connections") act_x_disc.setEnabled(False) menu.addMenu(discMenu) act_x_disc_all = menu.addAction( _translate('patchbay', "Disconnect &All")) act_x_disc_all.setIcon( QIcon(QPixmap(':scalable/breeze%s/lines-disconnector' % dark))) act_x_sep1 = menu.addSeparator() act_x_info = menu.addAction(_translate('patchbay', "Info")) act_x_rename = menu.addAction(_translate('patchbay', "Rename")) act_x_sep2 = menu.addSeparator() split_join_name = _translate('patchbay', "Split") split_join_icon = QIcon.fromTheme('split') if self.m_splitted: split_join_name = _translate('patchbay', "Join") split_join_icon = QIcon.fromTheme('join') act_x_split_join = menu.addAction(split_join_name) act_x_split_join.setIcon(split_join_icon) wrap_title = _translate('patchbay', 'Wrap') wrap_icon = QIcon.fromTheme('pan-up-symbolic') if self._wrapped: wrap_title = _translate('patchbay', 'Unwrap') wrap_icon = QIcon.fromTheme('pan-down-symbolic') act_x_wrap = menu.addAction(wrap_title) act_x_wrap.setIcon(wrap_icon) act_x_sep3 = menu.addSeparator() if not features.group_info: act_x_info.setVisible(False) if not features.group_rename: act_x_rename.setVisible(False) if not (features.group_info and features.group_rename): act_x_sep1.setVisible(False) if self.m_plugin_id >= 0 and self.m_plugin_id <= MAX_PLUGIN_ID_ALLOWED: menu.addSeparator() act_p_edit = menu.addAction("Edit") act_p_ui = menu.addAction("Show Custom UI") menu.addSeparator() act_p_clone = menu.addAction("Clone") act_p_rename = menu.addAction("Rename...") act_p_replace = menu.addAction("Replace...") act_p_remove = menu.addAction("Remove") if not self.m_plugin_ui: act_p_ui.setVisible(False) else: act_p_edit = act_p_ui = None act_p_clone = act_p_rename = None act_p_replace = act_p_remove = None haveIns = haveOuts = False for port in canvas.port_list: if port.group_id == self.m_group_id and port.port_id in self.m_port_list_ids: if port.port_mode == PORT_MODE_INPUT: haveIns = True elif port.port_mode == PORT_MODE_OUTPUT: haveOuts = True if not (self.m_splitted or bool(haveIns and haveOuts)): act_x_sep2.setVisible(False) act_x_split_join.setVisible(False) act_selected = menu.exec_(event.screenPos()) if act_selected is None: pass elif act_selected == act_x_disc_all: for conn_id in conn_list_ids: canvas.callback(ACTION_PORTS_DISCONNECT, conn_id, 0, "") elif act_selected == act_x_info: canvas.callback(ACTION_GROUP_INFO, self.m_group_id, 0, "") elif act_selected == act_x_rename: canvas.callback(ACTION_GROUP_RENAME, self.m_group_id, 0, "") elif act_selected == act_x_split_join: if self.m_splitted: canvas.callback(ACTION_GROUP_JOIN, self.m_group_id, 0, "") else: canvas.callback(ACTION_GROUP_SPLIT, self.m_group_id, 0, "") elif act_selected == act_p_edit: canvas.callback(ACTION_PLUGIN_EDIT, self.m_plugin_id, 0, "") elif act_selected == act_p_ui: canvas.callback(ACTION_PLUGIN_SHOW_UI, self.m_plugin_id, 0, "") elif act_selected == act_p_clone: canvas.callback(ACTION_PLUGIN_CLONE, self.m_plugin_id, 0, "") elif act_selected == act_p_rename: canvas.callback(ACTION_PLUGIN_RENAME, self.m_plugin_id, 0, "") elif act_selected == act_p_replace: canvas.callback(ACTION_PLUGIN_REPLACE, self.m_plugin_id, 0, "") elif act_selected == act_p_remove: canvas.callback(ACTION_PLUGIN_REMOVE, self.m_plugin_id, 0, "") elif act_selected == act_x_wrap: canvas.callback(ACTION_GROUP_WRAP, self.m_group_id, self.m_splitted_mode, str(not self._wrapped)) def keyPressEvent(self, event): if self.m_plugin_id >= 0 and event.key() == Qt.Key_Delete: event.accept() canvas.callback(ACTION_PLUGIN_REMOVE, self.m_plugin_id, 0, "") return QGraphicsItem.keyPressEvent(self, event) def hoverEnterEvent(self, event): if options.auto_select_items: if len(canvas.scene.selectedItems()) > 0: canvas.scene.clearSelection() self.setSelected(True) QGraphicsItem.hoverEnterEvent(self, event) def mouseDoubleClickEvent(self, event): if self.m_can_handle_gui: canvas.callback( ACTION_CLIENT_SHOW_GUI, self.m_group_id, int(not(self.m_gui_visible)), '') if self.m_plugin_id >= 0: event.accept() canvas.callback( ACTION_PLUGIN_SHOW_UI if self.m_plugin_ui else ACTION_PLUGIN_EDIT, self.m_plugin_id, 0, "") return QGraphicsItem.mouseDoubleClickEvent(self, event) def mousePressEvent(self, event): canvas.last_z_value += 1 self.setZValue(canvas.last_z_value) self.resetLinesZValue() self.m_cursor_moving = False if event.button() == Qt.RightButton: event.accept() canvas.scene.clearSelection() self.setSelected(True) self.m_mouse_down = False return elif event.button() == Qt.LeftButton: if QApplication.keyboardModifiers() & Qt.ShiftModifier: boxes = self._get_adjacent_boxes() for box in boxes: box.setSelected(True) return if self.sceneBoundingRect().contains(event.scenePos()): if self._wrapped: # unwrap the box if event is one of the triangles zones ypos = canvas.theme.box_header_height if len(self._title_lines) >= 3: ypos += 14 triangle_rect_out = QRectF( 0, ypos, 24, ypos + canvas.theme.port_spacing) triangle_rect_in = QRectF( self.p_width - 24, ypos, 24, ypos + canvas.theme.port_spacing) mode = PORT_MODE_INPUT wrap = False for trirect in triangle_rect_out, triangle_rect_in: trirect.translate(self.scenePos()) if (self.m_current_port_mode & mode and trirect.contains(event.scenePos())): wrap = True break mode = PORT_MODE_OUTPUT if wrap: CanvasCallback( ACTION_GROUP_WRAP, self.m_group_id, self.m_splitted_mode, 'False') return elif self.p_unwrap_triangle_pos: trirect = QRectF(0, self.p_height - 16, 16, 16) if self.p_unwrap_triangle_pos == UNWRAP_BUTTON_CENTER: trirect = QRectF(self.p_width_in + 8, self.p_height - 16, 16, 16) elif self.p_unwrap_triangle_pos == UNWRAP_BUTTON_RIGHT: trirect = QRectF(self.p_width - 16, self.p_height -16, 16, 16) trirect.translate(self.scenePos()) if trirect.contains(event.scenePos()): CanvasCallback( ACTION_GROUP_WRAP, self.m_group_id, self.m_splitted_mode, 'True') event.ignore() return self.m_mouse_down = True else: # FIXME: Check if still valid: Fix a weird Qt behaviour with right-click mouseMove self.m_mouse_down = False event.ignore() return else: self.m_mouse_down = False QGraphicsItem.mousePressEvent(self, event) def mouseMoveEvent(self, event): if canvas.scene.resizing_scene: # QGraphicsScene.setSceneRect calls this method # and resize_the_scene can be called from this method # So, here we avoid a RecursionError return if self.m_mouse_down: if not self.m_cursor_moving: self.setCursor(QCursor(Qt.SizeAllCursor)) self.m_cursor_moving = True canvas.scene.fix_temporary_scroll_bars() QGraphicsItem.mouseMoveEvent(self, event) self.repaintLines() canvas.scene.resize_the_scene() return QGraphicsItem.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): if self.m_cursor_moving: self.unsetCursor() self.repaintLines(forced=True) canvas.scene.reset_scroll_bars() self.fixPosAfterMove() # get all selected boxes repulsers = [] for group in canvas.group_list: for widget in group.widgets: if widget is not None and widget.isSelected(): repulsers.append(widget) canvas.scene.deplace_boxes_from_repulsers(repulsers) QTimer.singleShot(0, canvas.scene.update) self.m_mouse_down = False if (QApplication.keyboardModifiers() & Qt.ShiftModifier and not self.m_cursor_moving): return self.m_cursor_moving = False QGraphicsItem.mouseReleaseEvent(self, event) def fixPos(self): self.setX(round(self.x())) self.setY(round(self.y())) def send_move_callback(self): x_y_str = "%i:%i" % (round(self.x()), round(self.y())) CanvasCallback(ACTION_GROUP_MOVE, self.m_group_id, self.m_splitted_mode, x_y_str) for group in canvas.group_list: if group.group_id == self.m_group_id: pos = QPoint(round(self.x()), round(self.y())) if self.m_splitted_mode == PORT_MODE_NULL: group.null_pos = pos elif self.m_splitted_mode == PORT_MODE_INPUT: group.in_pos = pos elif self.m_splitted_mode == PORT_MODE_OUTPUT: group.out_pos = pos break def fixPosAfterMove(self): for item in canvas.scene.selectedItems(): if item.type() == CanvasBoxType: item.fixPos() item.send_move_callback() def boundingRect(self): hws = canvas.theme.hardware_rack_width if self._is_hardware: return QRectF(- hws, - hws, self.p_width + 2 * hws, self.p_height + 2 * hws) return QRectF(0, 0, self.p_width, self.p_height) def paint(self, painter, option, widget): if canvas.scene.loading_items: return painter.save() painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing == ANTIALIASING_FULL)) # Draw rectangle pen = QPen(canvas.theme.box_pen_sel if self.isSelected() else canvas.theme.box_pen) pen.setWidthF(pen.widthF() + 0.00001) painter.setPen(pen) brush = painter.brush() pen_width = pen.widthF() lineHinting = pen_width / 2 if self._is_hardware: d = canvas.theme.hardware_rack_width hw_gradient = QLinearGradient(-d, -d, self.p_width +d, self.p_height +d) hw_gradient.setColorAt(0, QColor(60, 60, 43)) hw_gradient.setColorAt(0.5, QColor(40, 40, 24)) hw_gradient.setColorAt(1, QColor(60, 60, 43)) painter.setBrush(hw_gradient) painter.setPen(QPen(QColor(30, 30, 30), 1)) if self.m_current_port_mode != PORT_MODE_INPUT + PORT_MODE_OUTPUT: hardware_poly = QPolygonF() if self.m_current_port_mode == PORT_MODE_INPUT: hardware_poly += QPointF(- lineHinting, - lineHinting) hardware_poly += QPointF(- lineHinting, 34) hardware_poly += QPointF(-d /2.0, 34) hardware_poly += QPointF(-d, 34 - d / 2.0) hardware_poly += QPointF(-d, -d / 2.0) hardware_poly += QPointF(-d / 2.0, -d) hardware_poly += QPointF(self.p_width + d/2.0, -d) hardware_poly += QPointF(self.p_width + d, -d / 2.0) hardware_poly += QPointF(self.p_width + d, self.p_height + d/2.0) hardware_poly += QPointF(self.p_width + d/2.0, self.p_height + d) hardware_poly += QPointF(-d/2.0, self.p_height +d) hardware_poly += QPointF(-d, self.p_height +d/2.0) hardware_poly += QPointF(-d, self.p_height -3 + d/2.0) hardware_poly += QPointF(-d/2.0, self.p_height -3) hardware_poly += QPointF(- lineHinting, self.p_height -3) hardware_poly += QPointF(- lineHinting, self.p_height + lineHinting) hardware_poly += QPointF(self.p_width + lineHinting, self.p_height + lineHinting) hardware_poly += QPointF(self.p_width + lineHinting, - lineHinting) else: hardware_poly += QPointF(self.p_width + lineHinting, - lineHinting) hardware_poly += QPointF(self.p_width + lineHinting, 34) hardware_poly += QPointF(self.p_width + d/2.0, 34) hardware_poly += QPointF(self.p_width + d, 34 - d/2.0) hardware_poly += QPointF(self.p_width +d, -d / 2.0) hardware_poly += QPointF(self.p_width + d/2.0, -d) hardware_poly += QPointF(-d / 2.0, -d) hardware_poly += QPointF(-d, -d/2.0) hardware_poly += QPointF(-d, self.p_height + d/2.0) hardware_poly += QPointF(-d/2.0, self.p_height + d) hardware_poly += QPointF(self.p_width + d/2.0, self.p_height + d) hardware_poly += QPointF(self.p_width + d, self.p_height + d/2.0) hardware_poly += QPointF(self.p_width +d, self.p_height -3 + d/2.0) hardware_poly += QPointF(self.p_width + d/2, self.p_height -3) hardware_poly += QPointF(self.p_width + lineHinting, self.p_height -3) hardware_poly += QPointF(self.p_width + lineHinting, self.p_height + lineHinting) hardware_poly += QPointF(-lineHinting, self.p_height + lineHinting) hardware_poly += QPointF(-lineHinting, -lineHinting) painter.drawPolygon(hardware_poly) else: hw_poly_top = QPolygonF() hw_poly_top += QPointF(-lineHinting, -lineHinting) hw_poly_top += QPointF(-lineHinting, 34) hw_poly_top += QPointF(-d /2.0, 34) hw_poly_top += QPointF(-d, 34 - d / 2.0) hw_poly_top += QPointF(-d, -d / 2.0) hw_poly_top += QPointF(-d / 2.0, -d) hw_poly_top += QPointF(self.p_width + d/2.0, -d) hw_poly_top += QPointF(self.p_width + d, -d / 2.0) hw_poly_top += QPointF(self.p_width + d, 34 - d/2) hw_poly_top += QPointF(self.p_width+ d/2, 34) hw_poly_top += QPointF(self.p_width + lineHinting, 34) hw_poly_top += QPointF(self.p_width + lineHinting, -lineHinting) painter.drawPolygon(hw_poly_top) hw_poly_bt = QPolygonF() hw_poly_bt += QPointF(-lineHinting, self.p_height + lineHinting) hw_poly_bt += QPointF(-lineHinting, self.p_height -3) hw_poly_bt += QPointF(-d/2, self.p_height -3) hw_poly_bt += QPointF(-d, self.p_height -3 + d/2) hw_poly_bt += QPointF(-d, self.p_height + d/2) hw_poly_bt += QPointF(-d/2, self.p_height + d) hw_poly_bt += QPointF(self.p_width + d/2, self.p_height + d) hw_poly_bt += QPointF(self.p_width +d, self.p_height + d/2) hw_poly_bt += QPointF(self.p_width +d, self.p_height -3 + d/2) hw_poly_bt += QPointF(self.p_width +d/2, self.p_height -3) hw_poly_bt += QPointF(self.p_width + lineHinting, self.p_height -3) hw_poly_bt += QPointF(self.p_width + lineHinting, self.p_height + lineHinting) painter.drawPolygon(hw_poly_bt) pen = QPen(canvas.theme.box_pen_sel if self.isSelected() else canvas.theme.box_pen) pen.setWidthF(pen.widthF() + 0.00001) painter.setPen(pen) painter.setBrush(brush) rect = QRectF(0, 0, self.p_width, self.p_height) if canvas.theme.box_bg_type == Theme.THEME_BG_GRADIENT: max_size = max(self.p_height, self.p_width) box_gradient = QLinearGradient(0, 0, max_size, max_size) color_main = canvas.theme.box_bg_1 color_alter = canvas.theme.box_bg_2 gradient_size = 50 if True or self._is_hardware: box_gradient = QLinearGradient(0, 0, max_size, max_size) color_main = QColor(20, 20, 20) color_alter = QColor(26, 24, 21) gradient_size = 20 box_gradient.setColorAt(0, color_main) tot = int(max_size / gradient_size) for i in range(tot): if i % 2 == 0: box_gradient.setColorAt((i/tot) ** 0.7, color_main) else: box_gradient.setColorAt((i/tot) ** 0.7, color_alter) painter.setBrush(box_gradient) else: painter.setBrush(canvas.theme.box_bg_1) rect.adjust(lineHinting, lineHinting, -lineHinting, -lineHinting) painter.drawRect(rect) # Draw plugin inline display if supported self.paintInlineDisplay(painter) # Draw toggle GUI client button if self.m_can_handle_gui: header_rect = QRectF(3, 3, self.p_width - 6, self.p_header_height - 6) header_rect.adjust(lineHinting * 2, lineHinting * 2, -2 * lineHinting, -2 * lineHinting) painter.setBrush(QColor(255, 240, 180, 10)) painter.setPen(Qt.NoPen) if self.m_gui_visible: header_color = QColor(255, 240, 180, 45) painter.setPen(Qt.NoPen) painter.setBrush(header_color) painter.drawRect(header_rect) if not self.m_gui_visible: painter.setPen(QPen((QColor(255, 240, 180, 25)), 1.000001)) painter.drawLine( QPointF(4.5, self.p_header_height - 3.5), QPointF(self.p_width - 3.5, self.p_header_height - 3.5)) elif self.m_group_name.endswith(' Monitor'): bor_gradient = QLinearGradient(0, 0, self.p_height, self.p_height) color_main = QColor(70, 70, 70) color_alter = QColor(45, 45, 45) tot = int(self.p_height / 20) for i in range(tot): if i % 2 == 0: bor_gradient.setColorAt(i/tot, color_main) else: bor_gradient.setColorAt(i/tot, color_alter) painter.setBrush(bor_gradient) painter.setPen(Qt.NoPen) border_rect = QRectF(0, 0, 11, self.p_height) border_rect.adjust(lineHinting * 2, lineHinting * 2, -2 * lineHinting, -2 * lineHinting) top_pol = QPolygonF() top_pol += QPointF(11 - 2 * lineHinting, lineHinting * 2) top_pol += QPointF(11 - 2 * lineHinting + 13, lineHinting * 2) top_pol += QPointF(11 - 2 * lineHinting, 13 + lineHinting * 2) band_mon_larger = 9 triangle_mon_size_top = 7 triangle_mon_size_bottom = 0 if self.p_height >= 100 or self._wrapping or self._unwrapping: triangle_mon_size_bottom = 13 bml = band_mon_larger tms_top = triangle_mon_size_top tms_bot = triangle_mon_size_bottom mon_poly = QPolygonF() mon_poly += QPointF(pen_width, pen_width) mon_poly += QPointF(pen_width + bml + tms_top, pen_width) mon_poly += QPointF(pen_width + bml, pen_width + tms_top) mon_poly += QPointF(pen_width + bml, self.p_height - tms_bot - pen_width) mon_poly += QPointF(pen_width + bml + tms_bot, self.p_height - pen_width) mon_poly += QPointF(pen_width, self.p_height - pen_width) painter.drawPolygon(mon_poly) # Draw pixmap header rect.setHeight(canvas.theme.box_header_height) if canvas.theme.box_header_pixmap: painter.setPen(Qt.NoPen) painter.setBrush(canvas.theme.box_bg_2) # outline rect.adjust(lineHinting, lineHinting, -lineHinting, -lineHinting) painter.drawRect(rect) rect.adjust(1, 1, -1, 0) painter.drawTiledPixmap(rect, canvas.theme.box_header_pixmap, rect.topLeft()) # Draw text title_x_pos = 8 if self.has_top_icon(): title_x_pos += 25 for title_line in self._title_lines: title_line.x = title_x_pos title_line.y = canvas.theme.box_text_ypos if len(self._title_lines) >= 2: if self._title_lines[0].is_little: self._title_lines[0].y -= 7 self._title_lines[1].y += 9 if len(self._title_lines) >= 3: self._title_lines[2].y += 24 else: if len(self._title_lines) == 4: self._title_lines[0].y -= 9 self._title_lines[1].y += 2 self._title_lines[2].y += 13 self._title_lines[3].y += 24 else: self._title_lines[0].y -= 6 self._title_lines[1].y += 9 if len(self._title_lines) >= 3: self._title_lines[2].y += 24 max_title_size = 0 for title_line in self._title_lines: max_title_size = max(max_title_size, title_line.size) # may draw horizontal lines around title # and set x on title lines painter.setPen(QPen(QColor(255, 192, 0, 80), 1)) if self.has_top_icon(): title_x_pos = 29 + (self.p_width - 29 - max_title_size) / 2 if title_x_pos > 43: painter.drawLine(5, 16, int(title_x_pos -29 -5), 16) painter.drawLine( int(title_x_pos + max_title_size + 5), 16, int(self.p_width -5), 16) for title_line in self._title_lines: title_line.x = title_x_pos else: left_xpos = self.p_width right_xpos = 0 for title_line in self._title_lines: title_line.x = (self.p_width - title_line.size) / 2 left_xpos = min(left_xpos, title_line.x) right_xpos = max(right_xpos, title_line.x + title_line.size) if left_xpos > 10: painter.drawLine(5, 16, int(left_xpos - 5), 16) painter.drawLine(int(right_xpos + 5), 16, int(self.p_width - 5), 16) if self._is_hardware: painter.setPen(canvas.theme.box_text_hw) elif self.isSelected(): painter.setPen(canvas.theme.box_text_sel) else: painter.setPen(canvas.theme.box_text) # draw title lines for title_line in self._title_lines: painter.setFont(title_line.font) global_opacity = canvas.semi_hide_opacity if self.m_is_semi_hidden else 1.0 painter.setOpacity(global_opacity) if title_line.is_little: painter.setOpacity(0.5 * global_opacity) if (title_line == self._title_lines[-1] and self.m_group_name.endswith(' Monitor')): # Title line endswith " Monitor" # Draw "Monitor" in yellow # but keep the rest in white pre_text = title_line.text.rpartition(' Monitor')[0] painter.drawText( int(title_line.x + 0.5), int(title_line.y + 0.5), pre_text) x_pos = title_line.x if pre_text: x_pos += QFontMetrics(title_line.font).width(pre_text) x_pos += QFontMetrics(title_line.font).width(' ') painter.setPen(QPen(QColor(190, 158, 0), 0)) painter.drawText(int(x_pos + 0.5), int(title_line.y + 0.5), 'Monitor') else: painter.drawText( int(title_line.x + 0.5), int(title_line.y + 0.5), title_line.text) # draw (un)wrapper triangles painter.setPen(canvas.theme.box_pen) painter.setBrush(QColor(255, 192, 0, 80)) if self._is_hardware: painter.setPen(canvas.theme.box_pen_hw) painter.setBrush(QColor(255, 192, 0, 60)) if self._wrapped: for port_mode in PORT_MODE_INPUT, PORT_MODE_OUTPUT: if self.m_current_port_mode & port_mode: side = 6 x = 6 ypos = canvas.theme.box_header_height if len(self._title_lines) >= 3: ypos += 14 if port_mode == PORT_MODE_OUTPUT: x = self.p_width - (x + 2 * side) triangle = QPolygonF() triangle += QPointF(x, ypos + 2) triangle += QPointF(x + 2 * side, ypos + 2) triangle += QPointF(x + side, ypos + side + 2) painter.drawPolygon(triangle) elif self.p_unwrap_triangle_pos == UNWRAP_BUTTON_LEFT: side = 6 x = 4 ypos = self.p_height - 6 triangle = QPolygonF() triangle += QPointF(x, ypos + 2) triangle += QPointF(x + 2 * side, ypos + 2) triangle += QPointF(x + side, ypos -side + 2) painter.drawPolygon(triangle) elif self.p_unwrap_triangle_pos == UNWRAP_BUTTON_RIGHT: side = 6 x = self.p_width - 2 * side - 4 ypos = self.p_height - 6 triangle = QPolygonF() triangle += QPointF(x, ypos + 2) triangle += QPointF(x + 2 * side, ypos + 2) triangle += QPointF(x + side, ypos -side + 2) painter.drawPolygon(triangle) elif self.p_unwrap_triangle_pos == UNWRAP_BUTTON_CENTER: side = 7 x = self.p_width_in + 8 ypos = self.p_height - 3 + 0.5 triangle = QPolygonF() triangle += QPointF(x, ypos + 2) triangle += QPointF(x + 2 * side, ypos + 2) triangle += QPointF(x + side, ypos -side + 2) painter.drawPolygon(triangle) self.repaintLines() painter.restore() def paintInlineDisplay(self, painter): if self.m_plugin_inline == self.INLINE_DISPLAY_DISABLED: return if not options.inline_displays: return inwidth = self.p_width - self.p_width_in - self.p_width_out - 16 inheight = self.p_height - canvas.theme.box_header_height - canvas.theme.box_header_spacing - canvas.theme.port_spacing - 3 scaling = canvas.scene.getScaleFactor() * canvas.scene.getDevicePixelRatioF() if self.m_plugin_id >= 0 and self.m_plugin_id <= MAX_PLUGIN_ID_ALLOWED and ( self.m_plugin_inline == self.INLINE_DISPLAY_ENABLED or self.m_inline_scaling != scaling): size = "%i:%i" % (int(inwidth*scaling), int(inheight*scaling)) data = canvas.callback(ACTION_INLINE_DISPLAY, self.m_plugin_id, 0, size) if data is None: return # invalidate old image first del self.m_inline_image self.m_inline_data = pack("%iB" % (data['height'] * data['stride']), *data['data']) self.m_inline_image = QImage(voidptr(self.m_inline_data), data['width'], data['height'], data['stride'], QImage.Format_ARGB32) self.m_inline_scaling = scaling self.m_plugin_inline = self.INLINE_DISPLAY_CACHED if self.m_inline_image is None: sys.stderr.write("ERROR: inline display image is None for\n", self.m_plugin_id, self.m_group_name) return swidth = self.m_inline_image.width() / scaling sheight = self.m_inline_image.height() / scaling srcx = int(self.p_width_in + (self.p_width - self.p_width_in - self.p_width_out) / 2 - swidth / 2) srcy = int(canvas.theme.box_header_height + canvas.theme.box_header_spacing + 1 + (inheight - sheight) / 2) painter.drawImage(QRectF(srcx, srcy, swidth, sheight), self.m_inline_image) # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvasboxshadow.py000066400000000000000000000036711417052567600233310ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QGraphicsDropShadowEffect # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import canvas # ------------------------------------------------------------------------------------------------------------ class CanvasBoxShadow(QGraphicsDropShadowEffect): def __init__(self, parent): QGraphicsDropShadowEffect.__init__(self, parent) self.m_fakeParent = None self.setBlurRadius(20) self.setColor(canvas.theme.box_shadow) self.setOffset(0, 0) def setFakeParent(self, fakeParent): self.m_fakeParent = fakeParent def setOpacity(self, opacity): color = QColor(canvas.theme.box_shadow) color.setAlphaF(opacity) self.setColor(color) def draw(self, painter): if self.m_fakeParent: self.m_fakeParent.repaintLines() QGraphicsDropShadowEffect.draw(self, painter) # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvasfadeanimation.py000066400000000000000000000051021417052567600241210ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from PyQt5.QtCore import QAbstractAnimation # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import canvas, CanvasBoxType # ------------------------------------------------------------------------------------------------------------ class CanvasFadeAnimation(QAbstractAnimation): def __init__(self, item, show): QAbstractAnimation.__init__(self) self.m_show = show self.m_duration = 0 self.m_item = item def item(self): return self.m_item def forceStop(self): self.blockSignals(True) self.stop() def setDuration(self, time): if self.m_item.opacity() == 0 and not self.m_show: self.m_duration = 0 else: self.m_item.show() self.m_duration = time def duration(self): return self.m_duration def updateCurrentTime(self, time): if self.m_duration == 0: return if self.m_show: value = float(time) / self.m_duration else: value = 1.0 - (float(time) / self.m_duration) try: self.m_item.setOpacity(value) except RuntimeError: print("CanvasFadeAnimation::updateCurrentTime() - failed to animate canvas item, already destroyed?") self.forceStop() canvas.animation_list.remove(self) return if self.m_item.type() == CanvasBoxType: self.m_item.setShadowOpacity(value) def updateDirection(self, direction): pass def updateState(self, oldState, newState): pass # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvasicon.py000066400000000000000000000200201417052567600222460ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) import os from PyQt5.QtCore import qCritical, QRectF, QFile from PyQt5.QtGui import QPainter, QPalette, QIcon, QPixmap from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer from PyQt5.QtWidgets import QGraphicsColorizeEffect, QGraphicsPixmapItem # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, icon2str, CanvasIconType, ICON_APPLICATION, ICON_HARDWARE, ICON_DISTRHO, ICON_FILE, ICON_PLUGIN, ICON_LADISH_ROOM, ICON_CLIENT, ICON_INTERNAL, PORT_MODE_INPUT, PORT_MODE_OUTPUT ) # ------------------------------------------------------------------------------------------------------------ def getAppIcon(icon_name): #dark = bool( #widget.palette().brush( #2, QPalette.WindowText).color().lightness() > 128) icon = QIcon.fromTheme(icon_name) if icon.isNull(): for ext in ('svg', 'svgz', 'png'): filename = ":app_icons/%s.%s" % (icon_name, ext) #darkname = ":app_icons/dark/%s.%s" % (icon_name, ext) #if dark and QFile.exists(darkname): #filename = darkname if QFile.exists(filename): del icon icon = QIcon() icon.addFile(filename) break if icon.isNull(): for path in ('/usr/local', '/usr', '%s/.local' % os.getenv('HOME')): for ext in ('png', 'svg', 'svgz', 'xpm'): filename = "%s/share/pixmaps/%s.%s" % (path, icon_name, ext) if QFile.exists(filename): del icon icon = QIcon() icon.addFile(filename) break return icon class CanvasIconPixmap(QGraphicsPixmapItem): def __init__(self, icon_type, icon_name, parent): QGraphicsPixmapItem.__init__(self) self.setParentItem(parent) self.p_size = QRectF(0.0, 0.0, 24.0, 24.0) self.icon = None self.x_offset = 4 self.y_offset = 4 if icon_type in (ICON_CLIENT, ICON_APPLICATION): self.setIcon(icon_type, icon_name) def setIcon(self, icon, name): self.icon = getAppIcon(name) if not self.icon.isNull(): pixmap = self.icon.pixmap(24, 24) self.setPixmap(pixmap) self.setOffset(4.0, 4.0) def update_zoom(self, scale: float): if self.icon is None or scale <= 0.0: return pixmap = self.icon.pixmap(int(0.5 + 24 * scale), int(0.5 + 24 * scale)) self.setPixmap(pixmap) self.setScale(1.0 / scale) self.setOffset(float(self.x_offset * scale), float(self.y_offset * scale)) def is_null(self)->bool: if self.icon is None: return True return self.icon.isNull() def align_at(self, x_pos: int): self.x_offset = x_pos self.setOffset(float(self.x_offset), self.y_offset) def align_right(self, width: int): self.x_offset = width - 28 self.setOffset(float(self.x_offset), self.y_offset) def type(self): return CanvasIconType class CanvasSvgIcon(QGraphicsSvgItem): def __init__(self, icon_type, name, port_mode, parent): QGraphicsSvgItem.__init__(self) self.setParentItem(parent) self.m_renderer = None self.p_size = QRectF(4, 4, 24, 24) self.m_colorFX = QGraphicsColorizeEffect(self) self.m_colorFX.setColor(canvas.theme.box_text.color()) #self.setGraphicsEffect(self.m_colorFX) self.setIcon(icon_type, name, port_mode) def setIcon(self, icon, name, port_mode): name = name.lower() icon_path = "" if icon == ICON_APPLICATION: self.p_size = QRectF(3, 2, 19, 18) if "audacious" in name: icon_path = ":/scalable/pb_audacious.svg" self.p_size = QRectF(5, 4, 16, 16) elif "clementine" in name: icon_path = ":/scalable/pb_clementine.svg" self.p_size = QRectF(5, 4, 16, 16) elif "distrho" in name: icon_path = ":/scalable/pb_distrho.svg" self.p_size = QRectF(5, 4, 16, 16) elif "jamin" in name: icon_path = ":/scalable/pb_jamin.svg" self.p_size = QRectF(5, 3, 16, 16) elif "mplayer" in name: icon_path = ":/scalable/pb_mplayer.svg" self.p_size = QRectF(5, 4, 16, 16) elif "vlc" in name: icon_path = ":/scalable/pb_vlc.svg" self.p_size = QRectF(5, 3, 16, 16) else: icon_path = ":/scalable/pb_generic.svg" self.p_size = QRectF(4, 4, 24, 24) elif icon == ICON_HARDWARE: if name == "a2j": icon_path = ":/scalable/DIN-5.svg" self.p_size = QRectF(4, 4, 24, 24) else: if port_mode & PORT_MODE_INPUT: icon_path = ":/scalable/audio-headphones.svg" elif port_mode & PORT_MODE_OUTPUT: icon_path = ":/scalable/microphone.svg" else: icon_path = ":/scalable/pb_hardware.svg" self.p_size = QRectF(4, 4, 24, 24) elif icon == ICON_DISTRHO: icon_path = ":/scalable/pb_distrho.svg" self.p_size = QRectF(5, 4, 16, 16) elif icon == ICON_FILE: icon_path = ":/scalable/pb_file.svg" self.p_size = QRectF(5, 4, 16, 16) elif icon == ICON_PLUGIN: icon_path = ":/scalable/pb_plugin.svg" self.p_size = QRectF(5, 4, 16, 16) elif icon == ICON_LADISH_ROOM: # TODO - make a unique ladish-room icon icon_path = ":/scalable/pb_hardware.svg" self.p_size = QRectF(5, 2, 16, 16) elif icon == ICON_INTERNAL: icon_path = ":/scalable/" + name self.p_size = QRectF(4, 4, 24, 24) else: self.p_size = QRectF(0, 0, 0, 0) qCritical("PatchCanvas::CanvasIcon.setIcon(%s, %s) - unsupported icon requested" % ( icon2str(icon), name.encode())) return self.m_renderer = QSvgRenderer(icon_path, canvas.scene) self.setSharedRenderer(self.m_renderer) self.update() def update_zoom(self, scale: float): pass def type(self): return CanvasIconType def is_null(self)->bool: return False def align_at(self, x_pos: int): self.p_size = QRectF(x_pos, 4, 24, 24) def align_right(self, width: int): self.p_size = QRectF(width - 28, 4, 24, 24) def boundingRect(self): return self.p_size def paint(self, painter, option, widget): if not self.m_renderer: QGraphicsSvgItem.paint(self, painter, option, widget) return painter.save() painter.setRenderHint(QPainter.Antialiasing, False) painter.setRenderHint(QPainter.TextAntialiasing, False) self.m_renderer.render(painter, self.p_size) painter.restore() # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvasline.py000066400000000000000000000156301417052567600222600ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from PyQt5.QtCore import Qt, QLineF from PyQt5.QtGui import QLinearGradient, QPainter, QPen from PyQt5.QtWidgets import QGraphicsLineItem # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, options, CanvasLineType, ACTION_PORTS_DISCONNECT, EYECANDY_FULL, PORT_MODE_OUTPUT, PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_MIDI_JACK, PORT_TYPE_PARAMETER, ) from .canvasportglow import CanvasPortGlow # ------------------------------------------------------------------------------------------------------------ class CanvasLine(QGraphicsLineItem): def __init__(self, item1, item2, parent): QGraphicsLineItem.__init__(self) self.setParentItem(parent) self.item1 = item1 self.item2 = item2 self.m_locked = False self.m_lineSelected = False self.setGraphicsEffect(None) self.updateLinePos() def isLocked(self): return self.m_locked def setLocked(self, yesno): self.m_locked = yesno def isLineSelected(self): return self.m_lineSelected def setLineSelected(self, yesno): if self.m_locked: return if yesno != self.m_lineSelected and options.eyecandy == EYECANDY_FULL: if yesno: self.setGraphicsEffect(CanvasPortGlow(self.item1.getPortType(), self.toGraphicsObject())) else: self.setGraphicsEffect(None) self.m_lineSelected = yesno self.updateLineGradient() def triggerDisconnect(self): for connection in canvas.connection_list: if (connection.port_out_id == self.item1.getPortId() and connection.port_in_id == self.item2.getPortId()): canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, "") break def updateLinePos(self): if self.item1.getPortMode() == PORT_MODE_OUTPUT: port_pos_1, portgrp_len_1 = self.item1.getPortGroupPosition() if portgrp_len_1 > 2: phi = 0.75 else: phi = 0.62 if portgrp_len_1 > 1: first_old_y = canvas.theme.port_height * phi last_old_y = canvas.theme.port_height * (portgrp_len_1 - phi) delta = (last_old_y - first_old_y) / (portgrp_len_1 -1) Y1 = first_old_y + (port_pos_1 * delta) - (canvas.theme.port_height * port_pos_1) else: Y1 = canvas.theme.port_height / 2 port_pos_2, portgrp_len_2 = self.item2.getPortGroupPosition() if portgrp_len_2 > 2: phi = 0.75 else: phi = 0.62 if portgrp_len_2 > 1: first_old_y = canvas.theme.port_height * phi last_old_y = canvas.theme.port_height * (portgrp_len_2 - phi) delta = (last_old_y - first_old_y) / (portgrp_len_2 -1) Y2 = first_old_y + (port_pos_2 * delta) - (canvas.theme.port_height * port_pos_2) else: Y2 = canvas.theme.port_height / 2 line = QLineF(self.item1.scenePos().x() + self.item1.getPortWidth() + 12, self.item1.scenePos().y() + Y1, self.item2.scenePos().x(), self.item2.scenePos().y() + Y2) self.setLine(line) self.m_lineSelected = False self.updateLineGradient() def type(self): return CanvasLineType def updateLineGradient(self): pos_top = self.boundingRect().top() pos_bot = self.boundingRect().bottom() if self.item2.scenePos().y() >= self.item1.scenePos().y(): pos1 = 0 pos2 = 1 else: pos1 = 1 pos2 = 0 port_type1 = self.item1.getPortType() port_type2 = self.item2.getPortType() port_gradient = QLinearGradient(0, pos_top, 0, pos_bot) if port_type1 == PORT_TYPE_AUDIO_JACK: port_gradient.setColorAt(pos1, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack) elif port_type1 == PORT_TYPE_MIDI_JACK: port_gradient.setColorAt(pos1, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack) elif port_type1 == PORT_TYPE_MIDI_ALSA: port_gradient.setColorAt(pos1, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa) elif port_type1 == PORT_TYPE_PARAMETER: port_gradient.setColorAt(pos1, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter) if port_type2 == PORT_TYPE_AUDIO_JACK: port_gradient.setColorAt(pos2, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack) elif port_type2 == PORT_TYPE_MIDI_JACK: port_gradient.setColorAt(pos2, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack) elif port_type2 == PORT_TYPE_MIDI_ALSA: port_gradient.setColorAt(pos2, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa) elif port_type2 == PORT_TYPE_PARAMETER: port_gradient.setColorAt(pos2, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter) self.setPen(QPen(port_gradient, 2.00001, Qt.SolidLine, Qt.RoundCap)) def paint(self, painter, option, widget): painter.save() painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing)) pen = self.pen() cosm_pen = QPen(pen) cosm_pen.setCosmetic(True) cosm_pen.setWidthF(1.00001) QGraphicsLineItem.paint(self, painter, option, widget) painter.setPen(cosm_pen) painter.setBrush(Qt.NoBrush) painter.setOpacity(0.2) painter.drawLine(self.line()) painter.restore() # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvaslinemov.py000066400000000000000000000124111417052567600227740ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from PyQt5.QtCore import qWarning, Qt, QLineF from PyQt5.QtGui import QPainter, QPen from PyQt5.QtWidgets import QGraphicsLineItem # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, options, port_mode2str, port_type2str, CanvasLineMovType, CanvasPortType, CanvasPortGroupType, PORT_MODE_INPUT, PORT_MODE_OUTPUT, PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_MIDI_JACK, PORT_TYPE_PARAMETER, ) # ------------------------------------------------------------------------------------------------------------ class CanvasLineMov(QGraphicsLineItem): def __init__(self, port_mode, port_type, port_pos, portgrp_len, parent): QGraphicsLineItem.__init__(self) self.setParentItem(parent) self.m_port_mode = port_mode self.m_port_type = port_type self.m_port_pos_from = port_pos self.m_port_pos_dest = port_pos self.m_portgrp_len_from = portgrp_len self.m_portgrp_len_dest = portgrp_len # Port position doesn't change while moving around line self.p_lineX = self.scenePos().x() self.p_lineY = self.scenePos().y() self.p_width = parent.getPortWidth() if port_type == PORT_TYPE_AUDIO_JACK: pen = QPen(canvas.theme.line_audio_jack, 2) elif port_type == PORT_TYPE_MIDI_JACK: pen = QPen(canvas.theme.line_midi_jack, 2) elif port_type == PORT_TYPE_MIDI_ALSA: pen = QPen(canvas.theme.line_midi_alsa, 2) elif port_type == PORT_TYPE_PARAMETER: pen = QPen(canvas.theme.line_parameter, 2) else: qWarning("PatchCanvas::CanvasLineMov(%s, %s, %s) - invalid port type" % (port_mode2str(port_mode), port_type2str(port_type), parent)) pen = QPen(Qt.black) pen.setCapStyle(Qt.RoundCap) pen.setWidthF(pen.widthF() + 0.00001) self.setPen(pen) def setDestinationPortGroupPosition(self, port_pos, portgrp_len): self.m_port_pos_dest = port_pos self.m_portgrp_len_dest = portgrp_len def updateLinePos(self, scenePos): phi = 0.75 if self.m_portgrp_len_from > 2 else 0.62 phito = 0.75 if self.m_portgrp_len_dest > 2 else 0.62 item_pos = [0, 0] if self.m_port_mode == PORT_MODE_INPUT: item_pos[0] = 0 elif self.m_port_mode == PORT_MODE_OUTPUT: item_pos[0] = self.p_width + 12 else: return if self.parentItem().type() == CanvasPortType: if self.m_portgrp_len_from > 1: first_old_y = canvas.theme.port_height * phi last_old_y = canvas.theme.port_height * (self.m_portgrp_len_from - phi) delta = (last_old_y - first_old_y) / (self.m_portgrp_len_from -1) item_pos[1] = first_old_y + (self.m_port_pos_from * delta) \ - (canvas.theme.port_height * self.m_port_pos_from) else: item_pos[1] = float(canvas.theme.port_height)/2 elif self.parentItem().type() == CanvasPortGroupType: first_old_y = canvas.theme.port_height * phi last_old_y = canvas.theme.port_height * (self.m_portgrp_len_from - phi) delta = (last_old_y - first_old_y) / (self.m_portgrp_len_from -1) item_pos[1] = first_old_y + (self.m_port_pos_from * delta) if self.m_portgrp_len_dest == 1: mouse_y_offset = 0 else: first_new_y = canvas.theme.port_height * phito last_new_y = canvas.theme.port_height * (self.m_portgrp_len_dest - phito) delta = (last_new_y - first_new_y) / (self.m_portgrp_len_dest -1) new_y1 = first_new_y + (self.m_port_pos_dest * delta) mouse_y_offset = new_y1 - ( (last_new_y - first_new_y) / 2 ) - (canvas.theme.port_height * phito) line = QLineF(item_pos[0], item_pos[1], scenePos.x() - self.p_lineX, scenePos.y() - self.p_lineY + mouse_y_offset) self.setLine(line) def type(self): return CanvasLineMovType def paint(self, painter, option, widget): painter.save() painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing)) QGraphicsLineItem.paint(self, painter, option, widget) painter.restore() # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvasport.py000066400000000000000000001120601417052567600223100ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from math import floor import time from PyQt5.QtCore import qCritical, Qt, QLineF, QPointF, QRectF, QTimer, QSizeF from PyQt5.QtGui import ( QCursor, QFont, QFontMetrics, QPainter, QPainterPath, QPen, QPolygonF, QLinearGradient, QColor, QRadialGradient, QIcon) from PyQt5.QtWidgets import ( QGraphicsItem, QMenu, QCheckBox, QWidgetAction, QGraphicsEllipseItem, QApplication) # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, features, options, port_mode2str, port_type2str, CanvasPortType, CanvasPortGroupType, ANTIALIASING_FULL, ACTION_PORTGROUP_ADD, ACTION_PORT_INFO, ACTION_PORT_RENAME, ACTION_PORTS_CONNECT, ACTION_PORTS_DISCONNECT, PORT_MODE_INPUT, PORT_MODE_OUTPUT, PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_MIDI_JACK, PORT_TYPE_PARAMETER, ) from .canvasbezierlinemov import CanvasBezierLineMov from .canvaslinemov import CanvasLineMov from .theme import Theme from .connect_menu import MainPortContextMenu from .utils import ( CanvasGetFullPortName, CanvasGetPortGroupPortList, CanvasGetPortConnectionList, CanvasGetPortGroupName, CanvasGetPortGroupPosition, CanvasGetPortPrintName, CanvasConnectionMatches, CanvasConnectionConcerns, CanvasGetGroupIcon, CanvasConnectPorts, CanvasCallback) # ------------------------------------------------------------------------------------------------------------ _translate = QApplication.translate class CanvasPort(QGraphicsItem): def __init__(self, group_id, port_id, port_name, port_mode, port_type, is_alternate, parent): QGraphicsItem.__init__(self) self.setParentItem(parent) # Save Variables, useful for later self.m_group_id = group_id self.m_port_id = port_id self.m_port_mode = port_mode self.m_port_type = port_type self.m_port_name = port_name self.m_portgrp_id = 0 self.m_is_alternate = is_alternate self.m_print_name = port_name self.m_print_name_right = '' self.m_name_truncked = False self.m_trunck_sep = '⠿' # Base Variables self.m_port_width = 15 self.m_port_height = canvas.theme.port_height self.m_port_font = QFont() self.m_port_font.setFamily(canvas.theme.port_font_name) self.m_port_font.setPixelSize(canvas.theme.port_font_size) self.m_port_font.setWeight(canvas.theme.port_font_state) # needed for line mov self.m_line_mov_list = [] self.m_last_rclick_item = None self.m_r_click_time = 0 self.m_dotcon_list = [] self.m_hover_item = None self.m_mouse_down = False self.m_cursor_moving = False self.m_has_connections = False self.setFlags(QGraphicsItem.ItemIsSelectable) if options.auto_select_items: self.setAcceptHoverEvents(True) def getGroupId(self): return self.m_group_id def getPortId(self): return self.m_port_id def getPortMode(self): return self.m_port_mode def getPortType(self): return self.m_port_type def isAlternate(self): return self.m_is_alternate def getPortName(self): return self.m_port_name def getPortGroupId(self): return self.m_portgrp_id def is_connectable_to(self, other, accept_same_port_mode=False)->bool: if self.m_port_type != other.getPortType(): return False if not accept_same_port_mode: if self.m_port_mode == other.getPortMode(): return False if self.m_port_type == PORT_TYPE_AUDIO_JACK: if other.getPortMode() == self.m_port_mode: return bool(self.isAlternate() == other.isAlternate()) # absolutely forbidden to connect an output CV port # to an input audio port. # It could destroy material. if self.m_port_mode == PORT_MODE_OUTPUT: if self.isAlternate(): return other.isAlternate() return True if self.m_port_mode == PORT_MODE_INPUT: if self.isAlternate(): return True return not other.isAlternate() return True def getFullPortName(self): return "%s:%s" % (self.parentItem().getGroupName(), self.m_port_name) def getPortWidth(self): return self.m_port_width def getPortHeight(self): return self.m_port_height def getPortGroupPosition(self): return CanvasGetPortGroupPosition(self.m_group_id, self.m_port_id, self.m_portgrp_id) def setPortGroupId(self, portgrp_id): self.m_portgrp_id = portgrp_id def setPortName(self, port_name): # if (QFontMetrics(self.m_port_font).width(port_name) # < QFontMetrics(self.m_port_font).width(self.m_port_name)): # QTimer.singleShot(0, canvas.scene.update) self.m_port_name = port_name # self.update() def get_width_for_text(self, text: str): return QFontMetrics(self.m_port_font).width(text) def reduce_print_text(self, print_text: str): pass def setPortWidth(self, port_width): #if port_width < self.m_port_width: #QTimer.singleShot(0, canvas.scene.update) self.m_port_width = port_width #self.update() def set_print_name(self, print_name:str, width_limited: int): self.m_print_name = print_name self.m_name_truncked = False if width_limited: sizer = QFontMetrics(self.m_port_font) if sizer.width(self.m_print_name) > width_limited: name_len = len(self.m_print_name) middle = int(name_len / 2) left_text = self.m_print_name[:middle] middle_text = self.m_trunck_sep right_text = self.m_print_name[middle + 1:] left_size = sizer.width(left_text) middle_size = sizer.width(middle_text) right_size = sizer.width(right_text) while left_size + middle_size + right_size > width_limited: if left_size > right_size: left_text = left_text[:-1] left_size = sizer.width(left_text) else: right_text = right_text[1:] right_size = sizer.width(right_text) if not (left_text or right_text): break self.m_print_name = left_text self.m_print_name_right = right_text self.m_name_truncked = True def get_text_width(self): sizer = QFontMetrics(self.m_port_font) if self.m_name_truncked: return (sizer.width(self.m_print_name) + sizer.width(self.m_trunck_sep) + sizer.width(self.m_print_name_right)) return sizer.width(self.m_print_name) def resetLineMovPositions(self): for i in range(len(self.m_line_mov_list)): line_mov = self.m_line_mov_list[i] if i < 1: line_mov.setDestinationPortGroupPosition(i, 1) else: item = line_mov canvas.scene.removeItem(item) del item self.m_line_mov_list = self.m_line_mov_list[:1] def resetDotLines(self): for connection in self.m_dotcon_list: if connection.widget.isReadyToDisc(): connection.widget.setReadyToDisc(False) connection.widget.updateLineGradient() for line_mov in self.m_line_mov_list: line_mov.setReadyToDisc(False) self.m_dotcon_list.clear() def SetAsStereo(self, port_id): port_id_list = [] for port in canvas.port_list: if port.port_id in (self.m_port_id, port_id): port_id_list.append(port.port_id) data = "%i:%i:%i:%i:%i" % (self.m_group_id, self.m_port_mode, self.m_port_type, port_id_list[0], port_id_list[1]) CanvasCallback(ACTION_PORTGROUP_ADD, 0, 0, data) def set_paint_attributes(self, print_name:str, port_width:int): pass def connectToHover(self): if self.m_hover_item: hover_port_id_list = [] if self.m_hover_item.type() == CanvasPortType: hover_port_id_list = [ self.m_hover_item.getPortId() ] elif self.m_hover_item.type() == CanvasPortGroupType: hover_port_id_list = self.m_hover_item.getPortsList() hover_group_id = self.m_hover_item.getGroupId() con_list = [] ports_connected_list = [] # cut and paste connections directly by attempt to connect # one port to another with same type and mode if self.m_hover_item.getPortMode() == self.m_port_mode: for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, self.m_group_id, [self.m_port_id]): canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, '') con_group_id = connection.group_out_id con_port_id = connection.port_out_id if self.m_port_mode == PORT_MODE_OUTPUT: con_group_id = connection.group_in_id con_port_id = connection.port_in_id for hover_port_id in hover_port_id_list: CanvasConnectPorts(con_group_id, con_port_id, hover_group_id, hover_port_id) return # FIXME clean this big if stuff for hover_port_id in hover_port_id_list: for connection in canvas.connection_list: if CanvasConnectionMatches(connection, self.m_group_id, [self.m_port_id], hover_group_id, [hover_port_id]): con_list.append(connection) ports_connected_list.append(hover_port_id) if len(con_list) == len(hover_port_id_list): for connection in con_list: canvas.callback( ACTION_PORTS_DISCONNECT, connection.connection_id, 0, "") else: for porthover_id in hover_port_id_list: if not porthover_id in ports_connected_list: if self.m_port_mode == PORT_MODE_OUTPUT: conn = "%i:%i:%i:%i" % ( self.m_group_id, self.m_port_id, hover_group_id, porthover_id) else: conn = "%i:%i:%i:%i" % ( hover_group_id, porthover_id, self.m_group_id, self.m_port_id) canvas.callback(ACTION_PORTS_CONNECT, '', '', conn) def type(self): return CanvasPortType def hoverEnterEvent(self, event): if options.auto_select_items: self.setSelected(True) QGraphicsItem.hoverEnterEvent(self, event) def hoverLeaveEvent(self, event): if options.auto_select_items: self.setSelected(False) QGraphicsItem.hoverLeaveEvent(self, event) def mousePressEvent(self, event): if canvas.scene.get_zoom_scale() <= 0.4: # prefer move box if zoom is too low event.ignore() return if event.button() == Qt.LeftButton: self.m_hover_item = None self.m_mouse_down = True self.m_cursor_moving = False for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, self.m_group_id, [self.m_port_id]): self.m_has_connections = True break else: self.m_has_connections = False elif event.button() == Qt.RightButton: if canvas.is_line_mov: if self.m_hover_item: self.m_r_click_time = time.time() self.connectToHover() self.m_last_rclick_item = self.m_hover_item for line_mov in self.m_line_mov_list: line_mov.toggleReadyToDisc() line_mov.updateLinePos(event.scenePos()) for connection in self.m_dotcon_list: if connection in canvas.connection_list: connection.widget.setReadyToDisc(True) connection.widget.updateLineGradient() QGraphicsItem.mousePressEvent(self, event) def mouseMoveEvent(self, event): if not self.m_mouse_down: QGraphicsItem.mouseMoveEvent(self, event) return event.accept() if not self.m_cursor_moving: self.setCursor(QCursor(Qt.CrossCursor)) self.m_cursor_moving = True for connection in canvas.connection_list: if CanvasConnectionConcerns(connection, self.m_group_id, [self.m_port_id]): connection.widget.setLocked(True) if not self.m_line_mov_list: if options.use_bezier_lines: line_mov = CanvasBezierLineMov(self.m_port_mode, self.m_port_type, 0, 1, self) else: line_mov = CanvasLineMov(self.m_port_mode, self.m_port_type, 0, 1, self) self.m_line_mov_list.append(line_mov) line_mov.setZValue(canvas.last_z_value) canvas.last_z_value += 1 canvas.is_line_mov = True self.m_last_rclick_item = None self.parentItem().setZValue(canvas.last_z_value) item = None items = canvas.scene.items(event.scenePos(), Qt.ContainsItemShape, Qt.AscendingOrder) for _, itemx in enumerate(items): if not itemx.type() in (CanvasPortType, CanvasPortGroupType): continue if itemx == self: continue if (item is None or itemx.parentItem().zValue() > item.parentItem().zValue()): item = itemx if self.m_hover_item and self.m_hover_item != item: self.m_hover_item.setSelected(False) if (item is not None and item.getPortType() == self.m_port_type and item.getPortMode() == self.m_port_mode): # check if item can cut/paste connections item_valid = False if self.m_has_connections: if item.type() == CanvasPortType: for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, item.getGroupId(), [item.getPortId()]): break else: item_valid = True if not item_valid: item = None if item is not None and not self.is_connectable_to( item, accept_same_port_mode=True): # prevent connection from an out CV port to a non CV port input # because it is very dangerous for monitoring pass elif (item is not None and item.getPortType() == self.m_port_type): item.setSelected(True) if item == self.m_hover_item: pass elif item.type() == CanvasPortGroupType: self.m_hover_item = item self.resetLineMovPositions() self.resetDotLines() if len(self.m_line_mov_list) <= 1: # make original line going to first port of the hover portgrp for line_mov in self.m_line_mov_list: line_mov.setDestinationPortGroupPosition( 0, self.m_hover_item.getPortLength()) port_pos, portgrp_len = CanvasGetPortGroupPosition( self.m_group_id, self.m_port_id, self.m_portgrp_id) # create one line for each port of the hover portgrp for i in range(1, self.m_hover_item.getPortLength()): if options.use_bezier_lines: line_mov = CanvasBezierLineMov( self.m_port_mode, self.m_port_type, port_pos, portgrp_len, self) else: line_mov = CanvasLineMov( self.m_port_mode, self.m_port_type, port_pos, portgrp_len, self) line_mov.setDestinationPortGroupPosition( i, self.m_hover_item.getPortLength()) self.m_line_mov_list.append(line_mov) for connection in canvas.connection_list: if CanvasConnectionMatches( connection, self.m_group_id, [self.m_port_id], self.m_hover_item.getGroupId(), self.m_hover_item.getPortsList()): self.m_dotcon_list.append(connection) if (len(self.m_dotcon_list) == len(self.m_hover_item.getPortsList())): for connection in self.m_dotcon_list: connection.widget.setReadyToDisc(True) connection.widget.updateLineGradient() for line_mov in self.m_line_mov_list: line_mov.setReadyToDisc(True) elif item.type() == CanvasPortType: self.m_hover_item = item self.resetLineMovPositions() self.resetDotLines() if item.getPortMode() == self.m_port_mode: # situation of cut and paste existing connections for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, self.m_group_id, [self.m_port_id]): connection.widget.setReadyToDisc(True) connection.widget.updateLineGradient() self.m_dotcon_list.append(connection) for line_mov in self.m_line_mov_list: line_mov.setReadyToDisc(True) else: for connection in canvas.connection_list: if CanvasConnectionMatches( connection, self.m_group_id, [self.m_port_id], self.m_hover_item.getGroupId(), [self.m_hover_item.getPortId()]): for line_mov in self.m_line_mov_list: line_mov.setReadyToDisc(True) connection.widget.setReadyToDisc(True) connection.widget.updateLineGradient() self.m_dotcon_list.append(connection) elif connection.widget.isReadyToDisc(): connection.widget.setReadyToDisc(False) connection.widget.updateLineGradient() else: self.m_hover_item = None self.resetLineMovPositions() self.resetDotLines() self.m_last_rclick_item = None for line_mov in self.m_line_mov_list: line_mov.updateLinePos(event.scenePos()) return event.accept() QGraphicsItem.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): if event.button() != Qt.LeftButton: QGraphicsItem.mouseReleaseEvent(self, event) return if self.m_mouse_down: if self.m_line_mov_list: for line_mov in self.m_line_mov_list: item = line_mov canvas.scene.removeItem(item) del item self.m_line_mov_list.clear() for connection in canvas.connection_list: if CanvasConnectionConcerns(connection, self.m_group_id, [self.m_port_id]): connection.widget.setLocked(False) if self.m_hover_item: if (self.m_last_rclick_item != self.m_hover_item and time.time() > self.m_r_click_time + 0.3): self.connectToHover() canvas.scene.clearSelection() if self.m_last_rclick_item: canvas.scene.clearSelection() if self.m_cursor_moving: self.unsetCursor() self.m_hover_item = None self.m_mouse_down = False self.m_cursor_moving = False canvas.is_line_mov = False QGraphicsItem.mouseReleaseEvent(self, event) def contextMenuEvent(self, event): if canvas.scene.get_zoom_scale() <= 0.4: # prefer move box if zoom is too low event.ignore() return if canvas.is_line_mov: return event.accept() canvas.scene.clearSelection() self.setSelected(True) menu = MainPortContextMenu(self.m_group_id, self.m_port_id) act_x_sep_1 = menu.addSeparator() if (self.m_port_type == PORT_TYPE_AUDIO_JACK and not self.m_is_alternate and not self.m_portgrp_id): StereoMenu = QMenu(_translate('patchbay', "Set as Stereo with"), menu) menu.addMenu(StereoMenu) # get list of available mono ports settables as stereo with port port_cousin_list = [] for port in canvas.port_list: if (port.port_type == PORT_TYPE_AUDIO_JACK and port.group_id == self.m_group_id and port.port_mode == self.m_port_mode and not port.is_alternate): port_cousin_list.append(port.port_id) selfport_index = port_cousin_list.index(self.m_port_id) stereo_able_ids_list = [] if selfport_index > 0: stereo_able_ids_list.append(port_cousin_list[selfport_index -1]) if selfport_index < len(port_cousin_list) -1: stereo_able_ids_list.append(port_cousin_list[selfport_index +1]) at_least_one = False for port in canvas.port_list: if port.port_id in stereo_able_ids_list and not port.portgrp_id: act_x_setasstereo = StereoMenu.addAction(port.port_name) act_x_setasstereo.setData([self, port.port_id]) act_x_setasstereo.triggered.connect(canvas.qobject.SetasStereoWith) at_least_one = True if not at_least_one: act_x_setasstereo = StereoMenu.addAction('no available mono port') act_x_setasstereo.setEnabled(False) act_x_info = menu.addAction(_translate('patchbay', "Get &Info")) act_x_info.setIcon(QIcon.fromTheme('dialog-information')) act_x_rename = menu.addAction(_translate('patchbay', "&Rename")) if not features.port_info: act_x_info.setVisible(False) if not features.port_rename: act_x_rename.setVisible(False) if not (features.port_info and features.port_rename): act_x_sep_1.setVisible(False) act_selected = menu.exec_(event.screenPos()) if act_selected == act_x_info: canvas.callback(ACTION_PORT_INFO, self.m_group_id, self.m_port_id, "") elif act_selected == act_x_rename: canvas.callback(ACTION_PORT_RENAME, self.m_group_id, self.m_port_id, "") def setPortSelected(self, yesno): for connection in canvas.connection_list: if CanvasConnectionConcerns(connection, self.m_group_id, [self.m_port_id]): connection.widget.setLineSelected(yesno) def itemChange(self, change, value): if change == QGraphicsItem.ItemSelectedHasChanged: self.setPortSelected(value) return QGraphicsItem.itemChange(self, change, value) def triggerDisconnect(self, conn_list=None): if not conn_list: conn_list = CanvasGetPortConnectionList(self.m_group_id, self.m_port_id) for conn_id, group_id, port_id in conn_list: canvas.callback(ACTION_PORTS_DISCONNECT, conn_id, 0, "") def boundingRect(self): if self.m_portgrp_id: if self.m_port_mode == PORT_MODE_INPUT: return QRectF(0, 0, self.m_port_width, self.m_port_height) else: return QRectF(12, 0, self.m_port_width, self.m_port_height) else: return QRectF(0, 0, self.m_port_width + 12, self.m_port_height) def paint(self, painter, option, widget): if canvas.scene.loading_items: return painter.save() painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing == ANTIALIASING_FULL)) selected = self.isSelected() theme = canvas.theme if self.m_port_type == PORT_TYPE_AUDIO_JACK: if self.m_is_alternate: poly_color = theme.port_cv_jack_bg_sel if selected else theme.port_cv_jack_bg poly_pen = theme.port_cv_jack_pen_sel if selected else theme.port_cv_jack_pen else: poly_color = theme.port_audio_jack_bg_sel if selected else theme.port_audio_jack_bg poly_pen = theme.port_audio_jack_pen_sel if selected else theme.port_audio_jack_pen text_pen = theme.port_audio_jack_text_sel if selected else theme.port_audio_jack_text conn_pen = QPen(theme.port_audio_jack_pen_sel) elif self.m_port_type == PORT_TYPE_MIDI_JACK: poly_color = theme.port_midi_jack_bg_sel if selected else theme.port_midi_jack_bg poly_pen = theme.port_midi_jack_pen_sel if selected else theme.port_midi_jack_pen text_pen = theme.port_midi_jack_text_sel if selected else theme.port_midi_jack_text conn_pen = QPen(theme.port_midi_jack_pen_sel) elif self.m_port_type == PORT_TYPE_MIDI_ALSA: poly_color = theme.port_midi_alsa_bg_sel if selected else theme.port_midi_alsa_bg poly_pen = theme.port_midi_alsa_pen_sel if selected else theme.port_midi_alsa_pen text_pen = theme.port_midi_alsa_text_sel if selected else theme.port_midi_alsa_text conn_pen = QPen(theme.port_midi_alsa_pen_sel) elif self.m_port_type == PORT_TYPE_PARAMETER: poly_color = theme.port_parameter_bg_sel if selected else theme.port_parameter_bg poly_pen = theme.port_parameter_pen_sel if selected else theme.port_parameter_pen text_pen = theme.port_parameter_text_sel if selected else theme.port_parameter_text conn_pen = QPen(theme.port_parameter_pen_sel) else: qCritical("PatchCanvas::CanvasPort.paint() - invalid port type '%s'" % port_type2str(self.m_port_type)) return # To prevent quality worsening poly_pen = QPen(poly_pen) poly_pen.setWidthF(poly_pen.widthF() + 0.00001) lineHinting = poly_pen.widthF() / 2 poly_locx = [0, 0, 0, 0, 0, 0] poly_corner_xhinting = ((float(canvas.theme.port_height)/2) % floor(float(canvas.theme.port_height)/2)) if poly_corner_xhinting == 0: poly_corner_xhinting = 0.5 * (1 - 7 / (float(canvas.theme.port_height)/2)) is_cv_port = bool(self.m_port_type == PORT_TYPE_AUDIO_JACK and self.m_is_alternate) if self.m_port_mode == PORT_MODE_INPUT: text_pos = QPointF(3, canvas.theme.port_text_ypos) if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON and not is_cv_port: poly_locx[0] = lineHinting poly_locx[1] = self.m_port_width + 5 - lineHinting poly_locx[2] = self.m_port_width + 12 - poly_corner_xhinting poly_locx[3] = self.m_port_width + 5 - lineHinting poly_locx[4] = lineHinting poly_locx[5] = self.m_port_width elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE or is_cv_port: poly_locx[0] = lineHinting poly_locx[1] = self.m_port_width + 5 - lineHinting poly_locx[2] = self.m_port_width + 5 - lineHinting poly_locx[3] = self.m_port_width + 5 - lineHinting poly_locx[4] = lineHinting poly_locx[5] = self.m_port_width else: qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode) return elif self.m_port_mode == PORT_MODE_OUTPUT: text_pos = QPointF(9, canvas.theme.port_text_ypos) if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON and not is_cv_port: poly_locx[0] = self.m_port_width + 12 - lineHinting poly_locx[1] = 7 + lineHinting poly_locx[2] = 0 + poly_corner_xhinting poly_locx[3] = 7 + lineHinting poly_locx[4] = self.m_port_width + 12 - lineHinting poly_locx[5] = 12 - lineHinting elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE or is_cv_port: poly_locx[0] = self.m_port_width + 12 - lineHinting poly_locx[1] = 5 + lineHinting poly_locx[2] = 5 + lineHinting poly_locx[3] = 5 + lineHinting poly_locx[4] = self.m_port_width + 12 - lineHinting poly_locx[5] = 12 - lineHinting else: qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode) return else: qCritical("PatchCanvas::CanvasPort.paint() - invalid port mode '%s'" % port_mode2str(self.m_port_mode)) return polygon = QPolygonF() if self.m_portgrp_id: first_of_portgrp = False last_of_portgrp = False # look in portgroup if port is the first, # the last, or not. for portgrp in canvas.portgrp_list: if portgrp.portgrp_id == self.m_portgrp_id: if self.m_port_id == portgrp.port_id_list[0]: first_of_portgrp = True if self.m_port_id == portgrp.port_id_list[-1]: last_of_portgrp = True break if first_of_portgrp: polygon += QPointF(poly_locx[0] , lineHinting) polygon += QPointF(poly_locx[5] , lineHinting) else: polygon += QPointF(poly_locx[0] , 0) polygon += QPointF(poly_locx[5] , 0) if last_of_portgrp: polygon += QPointF(poly_locx[5], canvas.theme.port_height - lineHinting) polygon += QPointF(poly_locx[0], canvas.theme.port_height - lineHinting) else: polygon += QPointF(poly_locx[5], canvas.theme.port_height) polygon += QPointF(poly_locx[0], canvas.theme.port_height) else: polygon += QPointF(poly_locx[0], lineHinting) polygon += QPointF(poly_locx[1], lineHinting) polygon += QPointF(poly_locx[2], float(canvas.theme.port_height)/2) polygon += QPointF(poly_locx[3], canvas.theme.port_height - lineHinting) polygon += QPointF(poly_locx[4], canvas.theme.port_height - lineHinting) polygon += QPointF(poly_locx[0], lineHinting) if canvas.theme.port_bg_pixmap: portRect = polygon.boundingRect().adjusted( -lineHinting+1, -lineHinting+1, lineHinting-1, lineHinting-1) portPos = portRect.topLeft() painter.drawTiledPixmap( portRect, canvas.theme.port_bg_pixmap, portPos) else: port_gradient = QLinearGradient(0, 0, 0, self.m_port_height) dark_color = poly_color.darker(112) light_color = poly_color.lighter(111) if poly_color.lightness() > 127: port_gradient.setColorAt(0, dark_color) port_gradient.setColorAt(0.5, light_color) port_gradient.setColorAt(1, dark_color) else: port_gradient.setColorAt(0, light_color) port_gradient.setColorAt(0.5, dark_color) port_gradient.setColorAt(1, light_color) painter.setBrush(port_gradient) painter.setPen(poly_pen) painter.drawPolygon(polygon) if self.m_is_alternate and not self.m_portgrp_id: if is_cv_port: poly_pen.setWidthF(2.000001) painter.setPen(poly_pen) y_line = canvas.theme.port_height / 2.0 if self.m_port_mode == PORT_MODE_OUTPUT: painter.drawLine( QPointF(0.0, y_line), QPointF(float(poly_locx[1]), y_line)) elif self.m_port_mode == PORT_MODE_INPUT: painter.drawLine( QPointF(self.m_port_width + 5.0, y_line), QPointF(self.m_port_width + 12.0, y_line)) else: # draw the little circle for a2j (or MidiBridge) port poly_pen.setWidthF(1.000001) painter.setBrush(canvas.theme.box_bg_1) ellipse_x = poly_locx[1] if self.m_port_mode == PORT_MODE_OUTPUT: ellipse_x -= 2 elif self.m_port_mode == PORT_MODE_INPUT: ellipse_x += 2 painter.drawEllipse( QPointF(ellipse_x, canvas.theme.port_height / 2.0), 2, 2) painter.setPen(text_pen) painter.setFont(self.m_port_font) sizer = QFontMetrics(self.m_port_font) sep_width = sizer.width(self.m_trunck_sep) if self.m_portgrp_id: print_name_size = self.get_text_width() if self.m_port_mode == PORT_MODE_OUTPUT: text_pos = QPointF(self.m_port_width + 9 - print_name_size, canvas.theme.port_text_ypos) if print_name_size > (self.m_port_width - 4): painter.setPen(QPen(port_gradient, 3)) painter.drawLine( QPointF(float(poly_locx[5]), 3.0), QPointF(float(poly_locx[5]), canvas.theme.port_height - 3.0)) painter.setPen(text_pen) painter.setFont(self.m_port_font) painter.drawText(text_pos, self.m_print_name) if self.m_name_truncked: sep_x = text_pos.x() + sizer.width(self.m_print_name) painter.drawText(QPointF(sep_x + sep_width, text_pos.y()), self.m_print_name_right) painter.setPen(poly_pen) painter.drawText(QPointF(sep_x, text_pos.y() + 1), self.m_trunck_sep) if canvas.theme.idx == Theme.THEME_OOSTUDIO and canvas.theme.port_bg_pixmap: painter.setPen(Qt.NoPen) painter.setBrush(conn_pen.brush()) if self.m_port_mode == PORT_MODE_INPUT: connRect = QRectF(portRect.topLeft(), QSizeF(2, portRect.height())) else: connRect = QRectF(QPointF(portRect.right()-2, portRect.top()), QSizeF(2, portRect.height())) painter.drawRect(connRect) painter.restore() # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvasportglow.py000066400000000000000000000037541417052567600232120ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from PyQt5.QtWidgets import QGraphicsDropShadowEffect # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_MIDI_JACK, PORT_TYPE_PARAMETER, ) # ------------------------------------------------------------------------------------------------------------ class CanvasPortGlow(QGraphicsDropShadowEffect): def __init__(self, port_type, parent): QGraphicsDropShadowEffect.__init__(self, parent) self.setBlurRadius(12) self.setOffset(0, 0) if port_type == PORT_TYPE_AUDIO_JACK: self.setColor(canvas.theme.line_audio_jack_glow) elif port_type == PORT_TYPE_MIDI_JACK: self.setColor(canvas.theme.line_midi_jack_glow) elif port_type == PORT_TYPE_MIDI_ALSA: self.setColor(canvas.theme.line_midi_alsa_glow) elif port_type == PORT_TYPE_PARAMETER: self.setColor(canvas.theme.line_parameter_glow) # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/canvasportgroup.py000066400000000000000000001024711417052567600233720ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from math import floor import time from PyQt5.QtCore import qCritical, Qt, QLineF, QPointF, QRectF, QTimer from PyQt5.QtGui import (QCursor, QFont, QFontMetrics, QPainter, QPainterPath, QPen, QPolygonF, QLinearGradient, QColor) from PyQt5.QtWidgets import QGraphicsItem, QMenu, QApplication # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, features, options, port_mode2str, port_type2str, CanvasPortType, CanvasPortGroupType, ANTIALIASING_FULL, ACTION_PORTGROUP_REMOVE, ACTION_PORT_INFO, ACTION_PORT_RENAME, ACTION_PORTS_CONNECT, ACTION_PORTS_DISCONNECT, PORT_MODE_INPUT, PORT_MODE_OUTPUT, PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_ALSA, PORT_TYPE_MIDI_JACK, PORT_TYPE_PARAMETER, ) from .canvasbezierlinemov import CanvasBezierLineMov from .canvaslinemov import CanvasLineMov from .theme import Theme from .connect_menu import MainPortContextMenu from .utils import (CanvasGetFullPortName, CanvasGetPortConnectionList, CanvasGetPortGroupPosition, CanvasGetPortPrintName, CanvasGetPortGroupName, CanvasGetPortGroupFullName, CanvasConnectionMatches, CanvasConnectionConcerns, CanvasCallback, CanvasConnectPorts) # ------------------------------------------------------------------------------------------------------------ _translate = QApplication.translate class CanvasPortGroup(QGraphicsItem): def __init__(self, group_id, portgrp_id, port_mode, port_type, port_id_list, parent): QGraphicsItem.__init__(self) self.setParentItem(parent) # Save Variables, useful for later self.m_portgrp_id = portgrp_id self.m_port_mode = port_mode self.m_port_type = port_type self.m_port_id_list = port_id_list self.m_group_id = group_id # Base Variables self.m_portgrp_width = 15 self.m_portgrp_height = canvas.theme.port_height self.m_portgrp_font = QFont() self.m_portgrp_font.setFamily(canvas.theme.port_font_name) self.m_portgrp_font.setPixelSize(canvas.theme.port_font_size) self.m_portgrp_font.setWeight(canvas.theme.port_font_state) self.m_ports_width = canvas.theme.port_in_portgrp_width self.m_print_name = '' self.m_normal_print_name = '' # same as m_print_name but not reduced self.m_print_name_right = '' self.m_name_truncked = False self.m_trunck_sep = '⠿' self.m_line_mov_list = [] self.m_dotcon_list = [] self.m_last_rclick_item = None self.m_r_click_time = 0 self.m_hover_item = None self.m_has_connections = False self.m_mouse_down = False self.m_cursor_moving = False self.setFlags(QGraphicsItem.ItemIsSelectable) def getPortGroupId(self): return self.m_portgrp_id def getPortMode(self): return self.m_port_mode def getPortType(self): return self.m_port_type def isAlternate(self): return False def is_connectable_to(self, other, accept_same_port_mode=False)->bool: if self.m_port_type != other.getPortType(): return False if not accept_same_port_mode: if self.m_port_mode == other.getPortMode(): return False if self.m_port_type == PORT_TYPE_AUDIO_JACK: if other.getPortMode() == self.m_port_mode: return bool(self.isAlternate() == other.isAlternate()) # absolutely forbidden to connect an output CV port # to an input audio port. # It could destroy material. if self.m_port_mode == PORT_MODE_OUTPUT: if self.isAlternate(): return other.isAlternate() return True if self.m_port_mode == PORT_MODE_INPUT: if self.isAlternate(): return True return not other.isAlternate() return True def getGroupId(self): return self.m_group_id def getPortWidth(self): return self.m_portgrp_width def getPortGroupWidth(self): return self.m_portgrp_width def getPortGroupHeight(self): return self.m_port_height def getPortsList(self): return self.m_port_id_list def getPortLength(self): return len(self.m_port_id_list) def type(self): return CanvasPortGroupType def setPortGroupWidth(self, portgrp_width): #if portgrp_width < self.m_portgrp_width: #QTimer.singleShot(0, canvas.scene.update) self.m_portgrp_width = portgrp_width #self.update() def set_ports_width(self, ports_width:int): self.m_ports_width = ports_width def set_print_name(self, print_name:str, width_limited: int): self.m_print_name = print_name self.m_normal_print_name = print_name self.m_name_truncked = False if width_limited: sizer = QFontMetrics(self.m_portgrp_font) if sizer.width(self.m_print_name) > width_limited: name_len = len(self.m_print_name) middle = int(name_len / 2) left_text = self.m_print_name[:middle] middle_text = self.m_trunck_sep right_text = self.m_print_name[middle + 1:] left_size = sizer.width(left_text) middle_size = sizer.width(middle_text) right_size = sizer.width(right_text) while left_size + middle_size + right_size > width_limited: if left_size > right_size: left_text = left_text[:-1] left_size = sizer.width(left_text) else: right_text = right_text[1:] right_size = sizer.width(right_text) if not (left_text or right_text): break self.m_print_name = left_text self.m_print_name_right = right_text self.m_name_truncked = True def reduce_print_name(self, width_limited:int): self.set_print_name(self.m_normal_print_name, width_limited) def get_text_width(self): sizer = QFontMetrics(self.m_portgrp_font) if self.m_name_truncked: return (sizer.width(self.m_print_name) + sizer.width(self.m_trunck_sep) + sizer.width(self.m_print_name_right)) return sizer.width(self.m_print_name) def resetDotLines(self): for connection in self.m_dotcon_list: if connection.widget.isReadyToDisc(): connection.widget.setReadyToDisc(False) connection.widget.updateLineGradient() for line_mov in self.m_line_mov_list: line_mov.setReadyToDisc(False) self.m_dotcon_list.clear() def SplitToMonos(self): CanvasCallback(ACTION_PORTGROUP_REMOVE, self.m_group_id, self.m_portgrp_id, "") def ConnectToHover(self): if self.m_hover_item: if self.m_hover_item.type() == CanvasPortType: hover_port_id_list = [self.m_hover_item.getPortId()] elif self.m_hover_item.type() == CanvasPortGroupType: hover_port_id_list = self.m_hover_item.getPortsList() if not hover_port_id_list: return hover_group_id = self.m_hover_item.getGroupId() con_list = [] ports_connected_list = [] maxportgrp = max(len(self.m_port_id_list), len(hover_port_id_list)) if self.m_hover_item.getPortMode() == self.m_port_mode: for i in range(len(self.m_port_id_list)): for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, self.m_group_id, [self.m_port_id_list[i]]): canvas.callback( ACTION_PORTS_DISCONNECT, connection.connection_id, 0, '') for j in range(len(hover_port_id_list)): if len(hover_port_id_list) >= len(self.m_port_id_list): if j % len(self.m_port_id_list) != i: continue else: if i % len(hover_port_id_list) != j: continue if self.m_port_mode == PORT_MODE_OUTPUT: canvas.callback( ACTION_PORTS_CONNECT, 0, 0, "%i:%i:%i:%i" % ( hover_group_id, hover_port_id_list[j], connection.group_in_id, connection.port_in_id)) else: canvas.callback( ACTION_PORTS_CONNECT, 0, 0, "%i:%i:%i:%i" % ( connection.group_out_id, connection.port_out_id, hover_group_id, hover_port_id_list[j])) return for i in range(len(self.m_port_id_list)): port_id = self.m_port_id_list[i] for j in range(len(hover_port_id_list)): hover_port_id = hover_port_id_list[j] for connection in canvas.connection_list: if CanvasConnectionMatches(connection, self.m_group_id, [port_id], hover_group_id, [hover_port_id]): if (i % len(hover_port_id_list) == j % len(self.m_port_id_list)): con_list.append(connection) ports_connected_list.append( [port_id, hover_port_id]) else: canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, "") if len(con_list) == maxportgrp: for connection in con_list: canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, "") else: for i in range(len(self.m_port_id_list)): port_id = self.m_port_id_list[i] for j in range(len(hover_port_id_list)): hover_port_id = hover_port_id_list[j] if (i % len(hover_port_id_list) == j % len(self.m_port_id_list)): if not [port_id, hover_port_id] in ports_connected_list: if self.m_port_mode == PORT_MODE_OUTPUT: conn = "%i:%i:%i:%i" % ( self.m_group_id, port_id, hover_group_id, hover_port_id) else: conn = "%i:%i:%i:%i" % ( hover_group_id, hover_port_id, self.m_group_id, port_id) canvas.callback(ACTION_PORTS_CONNECT, 0, 0, conn) def resetLineMovPositions(self): for i in range(len(self.m_line_mov_list)): line_mov = self.m_line_mov_list[i] if i < self.getPortLength(): line_mov.setDestinationPortGroupPosition(i, self.getPortLength()) else: item = line_mov canvas.scene.removeItem(item) del item while len(self.m_line_mov_list) < self.getPortLength(): if options.use_bezier_lines: line_mov = CanvasBezierLineMov(self.m_port_mode, self.m_port_type, len(self.m_line_mov_list), self.getPortLength(), self) else: line_mov = CanvasLineMov(self.m_port_mode, self.m_port_type, len(self.m_line_mov_list), self.getPortLength(), self) self.m_line_mov_list.append(line_mov) self.m_line_mov_list = self.m_line_mov_list[:self.getPortLength()] def hoverEnterEvent(self, event): if options.auto_select_items: self.setSelected(True) QGraphicsItem.hoverEnterEvent(self, event) def hoverLeaveEvent(self, event): if options.auto_select_items: self.setSelected(False) QGraphicsItem.hoverLeaveEvent(self, event) def mousePressEvent(self, event): if canvas.scene.get_zoom_scale() <= 0.4: # prefer move box if zoom is too low event.ignore() return if event.button() == Qt.LeftButton: self.m_hover_item = None self.m_mouse_down = True self.m_cursor_moving = False for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, self.m_group_id, self.m_port_id_list): self.m_has_connections = True break else: self.m_has_connections = False elif event.button() == Qt.RightButton: if canvas.is_line_mov: if self.m_hover_item: self.ConnectToHover() self.m_last_rclick_item = self.m_hover_item self.m_r_click_time = time.time() for line_mov in self.m_line_mov_list: line_mov.toggleReadyToDisc() line_mov.updateLinePos(event.scenePos()) QGraphicsItem.mousePressEvent(self, event) def mouseMoveEvent(self, event): if not self.m_mouse_down: QGraphicsItem.mouseMoveEvent(self, event) return if not self.m_cursor_moving: self.setCursor(QCursor(Qt.CrossCursor)) self.m_cursor_moving = True for connection in canvas.connection_list: if CanvasConnectionConcerns(connection, self.m_group_id, self.m_port_id_list): connection.widget.setLocked(True) if not self.m_line_mov_list: self.m_last_rclick_item = None canvas.last_z_value += 1 self.setZValue(canvas.last_z_value) canvas.last_z_value += 1 for port in canvas.port_list: if (port.group_id == self.m_group_id and port.port_id in self.m_port_id_list): port.widget.setZValue(canvas.last_z_value) for i in range(len(self.m_port_id_list)): if options.use_bezier_lines: line_mov = CanvasBezierLineMov(self.m_port_mode, self.m_port_type, i, len(self.m_port_id_list), self) else: line_mov = CanvasLineMov(self.m_port_mode, self.m_port_type, i, len(self.m_port_id_list), self) self.m_line_mov_list.append(line_mov) canvas.is_line_mov = True canvas.last_z_value += 1 self.parentItem().setZValue(canvas.last_z_value) item = None items = canvas.scene.items(event.scenePos(), Qt.ContainsItemShape, Qt.AscendingOrder) for i in range(len(items)): if items[i].type() in (CanvasPortType, CanvasPortGroupType): if items[i] != self: if not item: item = items[i] elif (items[i].parentItem().zValue() > item.parentItem().zValue()): item = items[i] if self.m_hover_item and self.m_hover_item != item: self.m_hover_item.setSelected(False) # if item has same port mode # verify we can use it for cut and paste connections if (item is not None and item.getPortType() == self.m_port_type and item.getPortMode() == self.m_port_mode): item_valid = False if (self.m_has_connections and item.type() == CanvasPortGroupType and len(item.getPortsList()) == len(self.m_port_id_list)): for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, item.getGroupId(), item.getPortsList()): break else: item_valid = True if not item_valid: item = None if item is not None and not self.is_connectable_to( item, accept_same_port_mode=True): # prevent connection from an out CV port to a non CV port input # because it is very dangerous for monitoring pass elif (item is not None and self.m_hover_item != item and item.getPortType() == self.m_port_type): item.setSelected(True) if item == self.m_hover_item: # prevent unneeded operations pass elif item.type() == CanvasPortType: self.m_hover_item = item self.resetDotLines() self.resetLineMovPositions() for line_mov in self.m_line_mov_list: line_mov.setDestinationPortGroupPosition(0, 1) self.m_dotcon_list.clear() for connection in canvas.connection_list: if CanvasConnectionMatches( connection, self.m_group_id, self.m_port_id_list, self.m_hover_item.getGroupId(), [self.m_hover_item.getPortId()]): self.m_dotcon_list.append(connection) if len(self.m_dotcon_list) == len(self.m_port_id_list): for connection in self.m_dotcon_list: connection.widget.setReadyToDisc(True) connection.widget.updateLineGradient() for line_mov in self.m_line_mov_list: line_mov.setReadyToDisc(True) elif item.type() == CanvasPortGroupType: self.m_hover_item = item self.resetDotLines() self.resetLineMovPositions() if item.getPortMode() == self.m_port_mode: for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, self.m_group_id, self.m_port_id_list): connection.widget.setReadyToDisc(True) connection.widget.updateLineGradient() self.m_dotcon_list.append(connection) for line_mov in self.m_line_mov_list: line_mov.setReadyToDisc(True) else: if (self.m_hover_item.getPortLength() <= len(self.m_line_mov_list)): for i in range(len(self.m_line_mov_list)): line_mov = self.m_line_mov_list[i] line_mov.setDestinationPortGroupPosition( i % self.m_hover_item.getPortLength(), self.m_hover_item.getPortLength()) else: start_n_linemov = len(self.m_line_mov_list) for i in range(self.m_hover_item.getPortLength()): if i < start_n_linemov: line_mov = self.m_line_mov_list[i] line_mov.setDestinationPortGroupPosition( i, self.m_hover_item.getPortLength()) else: port_posinportgrp = i % len(self.m_port_id_list) if options.use_bezier_lines: line_mov = CanvasBezierLineMov( self.m_port_mode, self.m_port_type, port_posinportgrp, self.m_hover_item.getPortLength(), self) else: line_mov = CanvasLineMov( self.m_port_mode, self.m_port_type, port_posinportgrp, self.m_hover_item.getPortLength(), self) line_mov.setDestinationPortGroupPosition( i, self.m_hover_item.getPortLength()) self.m_line_mov_list.append(line_mov) self.m_dotcon_list.clear() symetric_con_list = [] for portself_id in self.m_port_id_list: for porthover_id in self.m_hover_item.getPortsList(): for connection in canvas.connection_list: if CanvasConnectionMatches( connection, self.m_group_id, [portself_id], self.m_hover_item.getGroupId(), [porthover_id]): if (self.m_port_id_list.index(portself_id) % len(self.m_hover_item.getPortsList()) == (self.m_hover_item.getPortsList().index(porthover_id) % len(self.m_port_id_list))): self.m_dotcon_list.append(connection) symetric_con_list.append(connection) else: self.m_dotcon_list.append(connection) connection.widget.setReadyToDisc(True) connection.widget.updateLineGradient() biggest_list = self.m_hover_item.getPortsList() if (len(self.m_port_id_list) >= len(self.m_hover_item.getPortsList())): biggest_list = self.m_port_id_list if len(symetric_con_list) == len(biggest_list): for connection in self.m_dotcon_list: connection.widget.setReadyToDisc(True) connection.widget.updateLineGradient() for line_mov in self.m_line_mov_list: line_mov.setReadyToDisc(True) else: if item != self.m_hover_item: self.m_hover_item = None self.m_last_rclick_item = None self.resetDotLines() self.resetLineMovPositions() for line_mov in self.m_line_mov_list: line_mov.updateLinePos(event.scenePos()) return event.accept() QGraphicsItem.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: if self.m_mouse_down: for line_mov in self.m_line_mov_list: item = line_mov canvas.scene.removeItem(item) del item self.m_line_mov_list.clear() for connection in canvas.connection_list: if CanvasConnectionConcerns(connection, self.m_group_id, self.m_port_id_list): connection.widget.setLocked(False) if self.m_hover_item: if (self.m_last_rclick_item != self.m_hover_item and time.time() > self.m_r_click_time + 0.3): self.ConnectToHover() canvas.scene.clearSelection() elif self.m_last_rclick_item: canvas.scene.clearSelection() if self.m_cursor_moving: self.setCursor(QCursor(Qt.ArrowCursor)) self.m_hover_item = None self.m_mouse_down = False self.m_cursor_moving = False canvas.is_line_mov = False QGraphicsItem.mouseReleaseEvent(self, event) def contextMenuEvent(self, event): if canvas.scene.get_zoom_scale() <= 0.4: # prefer move box if zoom is too low event.ignore() return if canvas.is_line_mov: return canvas.scene.clearSelection() self.setSelected(True) menu = MainPortContextMenu(self.m_group_id, 0, self.m_portgrp_id) act_x_setasmono = menu.addAction( _translate('patchbay', "Split to Monos")) act_selected = menu.exec_(event.screenPos()) if act_selected == act_x_setasmono: self.SplitToMonos() event.accept() def setPortGroupSelected(self, yesno): for connection in canvas.connection_list: if CanvasConnectionConcerns(connection, self.m_group_id, self.m_port_id_list): connection.widget.setLineSelected(yesno) def itemChange(self, change, value): if change == QGraphicsItem.ItemSelectedHasChanged: self.setPortGroupSelected(value) return QGraphicsItem.itemChange(self, change, value) def boundingRect(self): self.m_portgrp_width = self.getPortGroupWidth() if self.m_port_mode == PORT_MODE_INPUT: return QRectF(canvas.theme.port_in_portgrp_width, 0, self.m_portgrp_width + 12 - canvas.theme.port_in_portgrp_width, canvas.theme.port_height * len(self.m_port_id_list)) else: return QRectF(0, 0, self.m_portgrp_width + 12 - canvas.theme.port_in_portgrp_width, canvas.theme.port_height * len(self.m_port_id_list)) def paint(self, painter, option, widget): if canvas.scene.loading_items: return painter.save() painter.setRenderHint( QPainter.Antialiasing, bool(options.antialiasing == ANTIALIASING_FULL)) lineHinting = canvas.theme.port_audio_jack_pen.widthF() / 2 poly_locx = [0, 0, 0, 0, 0] poly_corner_xhinting = ( float(canvas.theme.port_height)/2) % floor(float(canvas.theme.port_height)/2) if poly_corner_xhinting == 0: poly_corner_xhinting = 0.5 * (1 - 7 / (float(canvas.theme.port_height)/2)) if self.m_port_mode == PORT_MODE_INPUT: port_width = canvas.theme.port_in_portgrp_width for port in canvas.port_list: if port.port_id in self.m_port_id_list: port_print_name = CanvasGetPortPrintName( port.group_id, port.port_id, self.m_portgrp_id) port_in_p_width = QFontMetrics(self.m_portgrp_font).width(port_print_name) + 3 port_width = max(port_width, port_in_p_width) text_pos = QPointF( self.m_ports_width + 3, canvas.theme.port_text_ypos + (canvas.theme.port_height * (len(self.m_port_id_list) -1)/2)) if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON: poly_locx[0] = self.m_ports_width - lineHinting poly_locx[1] = self.m_portgrp_width + 3 + lineHinting poly_locx[2] = self.m_portgrp_width + 10 + lineHinting poly_locx[3] = self.m_portgrp_width + 3 + lineHinting poly_locx[4] = self.m_ports_width - lineHinting elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE: poly_locx[0] = self.m_ports_width - lineHinting poly_locx[1] = self.m_portgrp_width + 5 + lineHinting poly_locx[2] = self.m_portgrp_width + 5 + lineHinting poly_locx[3] = self.m_portgrp_width + 5 + lineHinting poly_locx[4] = self.m_ports_width - lineHinting else: qCritical("PatchCanvas::CanvasPortGroup.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode) return elif self.m_port_mode == PORT_MODE_OUTPUT: text_pos = QPointF(9, canvas.theme.port_text_ypos \ + (canvas.theme.port_height * (len(self.m_port_id_list) -1)/2)) if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON: poly_locx[0] = self.m_portgrp_width + 12 \ - self.m_ports_width - lineHinting poly_locx[1] = 7 + lineHinting poly_locx[2] = 0 + lineHinting poly_locx[3] = 7 + lineHinting poly_locx[4] = self.m_portgrp_width + 12 - self.m_ports_width - lineHinting elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE: poly_locx[0] = self.m_portgrp_width + 12 - self.m_ports_width - lineHinting poly_locx[1] = 5 + lineHinting poly_locx[2] = 5 + lineHinting poly_locx[3] = 5 + lineHinting poly_locx[4] = self.m_portgrp_width + 12 - self.m_ports_width - lineHinting else: qCritical( "PatchCanvas::CanvasPortGroup.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode) return else: qCritical("PatchCanvas::CanvasPortGroup.paint() - invalid port mode '%s'" % port_mode2str(self.m_port_mode)) return poly_pen = canvas.theme.portgrp_audio_jack_pen_sel if self.isSelected() else canvas.theme.portgrp_audio_jack_pen text_pen = canvas.theme.port_audio_jack_text_sel if self.isSelected() else canvas.theme.port_audio_jack_text color = canvas.theme.portgrp_audio_jack_bg_sel if self.isSelected() else canvas.theme.portgrp_audio_jack_bg light_color = color.lighter(108) dark_color = color.darker(109) portgrp_gradient = QLinearGradient(0, 0, 0, self.m_portgrp_height * 2) portgrp_gradient.setColorAt(0, dark_color) portgrp_gradient.setColorAt(0.5, light_color) portgrp_gradient.setColorAt(1, dark_color) polygon = QPolygonF() polygon += QPointF(poly_locx[0], lineHinting) polygon += QPointF(poly_locx[1], lineHinting) polygon += QPointF(poly_locx[2], float(canvas.theme.port_height / 2) ) polygon += QPointF(poly_locx[2], float(canvas.theme.port_height * (len(self.m_port_id_list) - 1/2)) ) polygon += QPointF(poly_locx[3], canvas.theme.port_height * len(self.m_port_id_list) - lineHinting) polygon += QPointF(poly_locx[4], canvas.theme.port_height * len(self.m_port_id_list) - lineHinting) if canvas.theme.port_bg_pixmap: portRect = polygon.boundingRect() portPos = portRect.topLeft() painter.drawTiledPixmap(portRect, canvas.theme.port_bg_pixmap, portPos) else: painter.setBrush(portgrp_gradient) painter.setPen(poly_pen) painter.drawPolygon(polygon) painter.setPen(text_pen) painter.setFont(self.m_portgrp_font) painter.drawText(text_pos, self.m_print_name) if self.m_name_truncked: sizer = QFontMetrics(self.m_portgrp_font) sep_x = text_pos.x() + sizer.width(self.m_print_name) sep_width = sizer.width(self.m_trunck_sep) painter.drawText(QPointF(sep_x + sep_width, text_pos.y()), self.m_print_name_right) painter.setPen(poly_pen) painter.drawText(QPointF(sep_x, text_pos.y() + 1), self.m_trunck_sep) painter.restore() RaySession-0.12.2/src/gui/patchcanvas/connect_menu.py000066400000000000000000000754301417052567600226160ustar00rootroot00000000000000 from PyQt5.QtCore import pyqtSlot, QCoreApplication, Qt from PyQt5.QtWidgets import QWidgetAction, QMenu, QCheckBox, QAction from PyQt5.QtGui import QIcon, QPixmap, QPalette from . import ( canvas, clipboard_element_dict_t, ACTION_PORTS_CONNECT, ACTION_PORTS_DISCONNECT, PORT_TYPE_NULL, PORT_TYPE_AUDIO_JACK, PORT_TYPE_MIDI_JACK, PORT_MODE_NULL, PORT_MODE_OUTPUT, PORT_MODE_INPUT) from .utils import( CanvasCallback, CanvasConnectionMatches, CanvasConnectionConcerns, CanvasGetGroupIcon, CanvasGetFullPortName, CanvasGetPortConnectionList, CanvasConnectPorts, CanvasGetPortGroupFullName, CanvasGetPortGroupPortList, CanvasConnectPortGroups, CanvasPortGroupConnectionState, is_dark_theme) _translate = QCoreApplication.translate DANGEROUS_NO_CARE = 0 DANGEROUS_NO = 1 DANGEROUS_YES = 2 class PortCheckBox(QCheckBox): def __init__(self, port_id: int, portgrp_id: int, port_name: str, port_type: int, parent): QCheckBox.__init__(self, port_name, parent) self.setTristate(True) self.setMinimumHeight(23) self.setMinimumWidth(100) border_color = canvas.theme.port_audio_jack_pen.color().name() sel_bg = canvas.theme.port_audio_jack_bg.name() sel_text_color = canvas.theme.port_audio_jack_text.color().name() if port_type == PORT_TYPE_MIDI_JACK: border_color = canvas.theme.port_midi_jack_pen.color().name() sel_bg = canvas.theme.port_midi_jack_bg.name() sel_text_color = canvas.theme.port_midi_jack_text.color().name() #self.setStyleSheet( #"""QCheckBox:hover{background-color: %s;color: %s} #QCheckBox::indicator:hover{background-color: #202020;color: white}""" % ( #sel_bg, sel_text_color)) self._parent = parent self._port_id = port_id self._portgrp_id = portgrp_id def nextCheckState(self): self._parent.connection_asked_from_box( self._port_id, self._portgrp_id, not self.isChecked()) class SubMenu(QMenu): def __init__(self, name: str, port_data, parent): QMenu.__init__(self, name, parent) self._port_data = port_data self._group_id = port_data._group_id self._port_id = port_data._port_id self._port_type = port_data._port_type self._port_mode = port_data._port_mode self._portgrp_id = port_data._portgrp_id self._is_alternate = port_data._is_alternate self._port_id_list = port_data._port_id_list class PortData: def __init__(self, group_id: int, port_id: int, port_type: int, port_mode: int, portgrp_id: int, is_alternate: bool): self._group_id = group_id self._port_id = port_id self._port_type = port_type self._port_mode = port_mode self._portgrp_id = portgrp_id self._is_alternate = is_alternate self._port_id_list = [port_id] if portgrp_id: self._port_id_list = CanvasGetPortGroupPortList(group_id, portgrp_id) class ConnectGroupMenu(SubMenu): def __init__(self, group_name: str, group_id: str, port_data, parent, dangerous_mode=DANGEROUS_NO_CARE): SubMenu.__init__(self, group_name, port_data, parent) self._parent = parent self._menu_group_id = group_id self.elements = [] self._last_portgrp_id = 0 for port in canvas.port_list: if (port.group_id == self._menu_group_id and port.port_type == self._port_type and port.port_mode != self._port_mode): if self._portgrp_id and port.portgrp_id: if port.portgrp_id != self._last_portgrp_id: for portgrp in canvas.portgrp_list: if (portgrp.group_id == port.group_id and portgrp.portgrp_id == port.portgrp_id): portgrp_full_name = CanvasGetPortGroupFullName( portgrp.group_id, portgrp.portgrp_id) portgrp_name = '‖ ' \ + portgrp_full_name.partition(':')[2] # all portgroups items will have -1 as port_id self.add_element(-1, port.portgrp_id, portgrp_name) break else: if (dangerous_mode == DANGEROUS_YES and self._is_alternate == port.is_alternate): continue if (dangerous_mode == DANGEROUS_NO and self._is_alternate != port.is_alternate): continue self.add_element(port.port_id, port.portgrp_id, port.port_name, port.is_alternate) def group_id(self)->int: return self._menu_group_id def add_element(self, port_id: int, portgrp_id: int, port_name: str, is_alternate=False): if self._port_type == PORT_TYPE_AUDIO_JACK and is_alternate: port_name = "CV| %s" % port_name check_box = PortCheckBox(port_id, portgrp_id, port_name, self._port_type, self) action = QWidgetAction(self._parent) action.setDefaultWidget(check_box) if not self._portgrp_id and portgrp_id != self._last_portgrp_id: self.addSeparator() self._last_portgrp_id = portgrp_id self.addAction(action) self.elements.append( {'port_id': port_id, 'portgrp_id': portgrp_id, 'action': action, 'check_box': check_box}) def remove_element(self, port_id: int, portgrp_id: int): for element in self.elements: if (element['port_id'] == port_id and element['portgrp_id'] == portgrp_id): self.removeAction(element['action']) self.elements.remove(element) break def check_element(self, port_id: int, portgrp_id: int, check_state: int): for element in self.elements: if (element['port_id'] == port_id and element['portgrp_id'] == portgrp_id): check_box = element['check_box'] check_box.setCheckState(check_state) break def connection_asked_from_box(self, port_id: int, portgrp_id: int, yesno: bool): self._parent.connection_asked_from_box(self._menu_group_id, port_id, portgrp_id, yesno) class DangerousMenu(SubMenu): def __init__(self, name, port_data, parent): SubMenu.__init__(self, name, port_data, parent) self.setIcon(QIcon.fromTheme('emblem-warning')) self.group_menus = [] self.connection_list = [] def add_group_menu(self, group_id: int, group_name: str): if len(group_name) > 15: if '/' in group_name: group_name = group_name.partition('/')[2] group_menu = ConnectGroupMenu(group_name, group_id, self._port_data, self, dangerous_mode=DANGEROUS_YES) group_icon = CanvasGetGroupIcon(group_id, self._port_mode) group_menu.setIcon(group_icon) self.group_menus.append(group_menu) self.addMenu(group_menu) def connection_asked_from_box(self, group_id: int, port_id: int, portgrp_id: int, yesno: bool): if yesno: if self._portgrp_id and portgrp_id: # in and out are portgroups CanvasConnectPortGroups(self._group_id, self._portgrp_id, group_id, portgrp_id) else: for self_port_id in self._port_id_list: CanvasConnectPorts(self._group_id, self_port_id, group_id, port_id) else: if self._portgrp_id and portgrp_id: CanvasConnectPortGroups(self._group_id, self._portgrp_id, group_id, portgrp_id, disconnect=True) else: for connection in canvas.connection_list: if CanvasConnectionMatches( connection, self._group_id, self._port_id_list, group_id, [port_id]): CanvasCallback( ACTION_PORTS_DISCONNECT, connection.connection_id, '', '') class ConnectMenu(SubMenu): def __init__(self, port_data, parent): SubMenu.__init__(self, _translate('patchbay', 'Connect'), port_data, parent) #canvas.qobject.port_added.connect(self.port_added_to_canvas) #canvas.qobject.port_removed.connect(self.port_removed_from_canvas) self.group_menus = [] self.connection_list = [] dangerous_name = '' if self._port_type == PORT_TYPE_AUDIO_JACK: if (self._port_mode == PORT_MODE_OUTPUT and self._is_alternate): dangerous_name = _translate( 'patchbay', 'Audio | DANGEROUS !!!') elif (self._port_mode == PORT_MODE_INPUT and not self._is_alternate): dangerous_name = _translate( 'patchbay', 'CV | DANGEROUS !!!') self.dangerous_submenu = DangerousMenu( dangerous_name, port_data, self) has_dangerous_global = False # add the needed groups (not the ports) for group in canvas.group_list: has_dangerous = False has_regular = False for port in canvas.port_list: if (port.group_id == group.group_id and port.port_type == self._port_type and port.port_mode != self._port_mode): if (self._port_type == PORT_TYPE_AUDIO_JACK and (self._port_mode == PORT_MODE_OUTPUT and self._is_alternate and not port.is_alternate) or (self._port_mode == PORT_MODE_INPUT and not self._is_alternate and port.is_alternate)): if not has_dangerous: self.dangerous_submenu.add_group_menu( group.group_id, group.group_name) has_dangerous = True has_dangerous_global = True else: if not has_regular: self.add_group_menu(group.group_id, group.group_name) has_regular = True if has_dangerous and has_regular: break if has_dangerous_global: self.addSeparator() self.addMenu(self.dangerous_submenu) def add_group_menu(self, group_id: int, group_name: str): if len(group_name) > 15: if '/' in group_name: group_name = group_name.partition('/')[2] dangerous = DANGEROUS_NO_CARE if (self._port_type == PORT_TYPE_AUDIO_JACK and (self._port_mode == PORT_MODE_OUTPUT and self._is_alternate) or (self._port_mode == PORT_MODE_INPUT and not self._is_alternate)): dangerous = DANGEROUS_NO group_menu = ConnectGroupMenu(group_name, group_id, self._port_data, self, dangerous_mode=dangerous) group_icon = CanvasGetGroupIcon(group_id, self._port_mode) group_menu.setIcon(group_icon) self.group_menus.append(group_menu) self.addMenu(group_menu) def connection_asked_from_box(self, group_id: int, port_id: int, portgrp_id: int, yesno: bool): if yesno: if self._portgrp_id and portgrp_id: # in and out are portgroups CanvasConnectPortGroups(self._group_id, self._portgrp_id, group_id, portgrp_id) else: for self_port_id in self._port_id_list: CanvasConnectPorts(self._group_id, self_port_id, group_id, port_id) else: if self._portgrp_id and portgrp_id: CanvasConnectPortGroups(self._group_id, self._portgrp_id, group_id, portgrp_id, disconnect=True) else: for connection in canvas.connection_list: if CanvasConnectionMatches( connection, self._group_id, self._port_id_list, group_id, [port_id]): CanvasCallback( ACTION_PORTS_DISCONNECT, connection.connection_id, '', '') # TODO was initially added the fact menu was updated # when port was added or removed # for portgroup it seems to be much complicated # user will just have to re-open the menu #def port_added_to_canvas(self, group_id: int, port_id: int): #for port in canvas.port_list: #if port.group_id == group_id and port.port_id == port_id: #if (port.port_type != self._port_type #or port.port_mode == self._port_mode): #continue #for group_menu in self.group_menus: #if group_menu.group_id() == port.group_id: #if (self._portgrp_id and port.portgrp_id #and group_menu.elements #and (group_menu.elements[-1]['portgrp_id'] #== port.portgrp_id)): #pass #else: #group_menu.add_element( #port.port_id, port.portgrp_id, #port.port_name) #break #else: #for group in canvas.group_list: #if group.group_id == port.group_id: #self.add_group_menu( #group.group_id, group.group_name) ## this group menu will see itself the port #break #break #def port_removed_from_canvas(self, group_id: int, port_id: int): #for group_menu in self.group_menus: #if group_menu.group_id() == group_id: #group_menu.remove_element(port_id, 0) #break class DisconnectMenu(SubMenu): def __init__(self, port_data, parent): SubMenu.__init__(self, _translate('patchbay', "Disconnect"), port_data, parent) self.elements = [] self._no_action_title = _translate('patchbay', 'No connections') self._no_action = self.addAction(self._no_action_title) self._no_action.setEnabled(False) @pyqtSlot() def apply_disconnection(self): action = self.sender() if action is None: return for element in self.elements: if element['action'] == action: for connection in canvas.connection_list: if CanvasConnectionMatches( connection, self._group_id, self._port_id_list, element['group_id'], element['port_id_list']): CanvasCallback( ACTION_PORTS_DISCONNECT, connection.connection_id, '', '') break def add_element(self, group_id: int, port_id_list: list, portgrp_id: int): if not port_id_list: return for element in self.elements: if (element['group_id'] == group_id and element['port_id_list'] == port_id_list): # element already exists return # display actions in the group_id and port_id order i = 0 following_action = None for element in self.elements: if (element['group_id'] > group_id or (element['group_id'] == group_id and element['port_id_list'][0] > port_id_list[-1])): following_action = element['action'] break i += 1 action_name = "" if self._portgrp_id and portgrp_id: action_name = '‖ ' action_name += CanvasGetPortGroupFullName(group_id, portgrp_id) else: action_name = CanvasGetFullPortName(group_id, port_id_list[0]) icon = CanvasGetGroupIcon(group_id, self._port_mode) action = QAction(action_name) action.setIcon(icon) action.triggered.connect(self.apply_disconnection) if following_action is None: self.addAction(action) else: self.insertAction(following_action, action) element = {'group_id': group_id, 'port_id_list': port_id_list, 'portgrp_id': portgrp_id, 'action': action} self.elements.insert(i, element) # remove "no connections" fake action if self._no_action is not None: self.removeAction(self._no_action) self._no_action = None def remove_element(self, group_id: int, port_id_list: int, portgrp_id: int): for element in self.elements: if (element['group_id'] == group_id and element['portgrp_id'] == portgrp_id and element['port_id_list'] == port_id_list): self.removeAction(element['action']) self.elements.remove(element) break else: return if not self.elements: self._no_action = self.addAction(self._no_action_title) self._no_action.setEnabled(False) class ClipboardMenu(SubMenu): def __init__(self, port_data, parent): SubMenu.__init__(self, _translate('patchbay', 'Clipboard'), port_data, parent) cut_action = self.addAction( _translate('patchbay', 'Cut connections')) cut_action.setIcon(QIcon.fromTheme('edit-cut')) cut_action.triggered.connect(self.cut_connections) copy_action = self.addAction( _translate('patchbay', 'Copy connections')) copy_action.setIcon(QIcon.fromTheme('edit-copy')) copy_action.triggered.connect(self.copy_connections) has_connection = False for self_port_id in self._port_id_list: con_list = CanvasGetPortConnectionList(self._group_id, self_port_id) if con_list: has_connection = True break if not con_list: cut_action.setEnabled(False) copy_action.setEnabled(False) for cb_element in canvas.clipboard: if (cb_element.port_type == self._port_type and cb_element.port_mode == self._port_mode and cb_element.port_id != self._port_id): paste_action = self.addAction( _translate('patchbay', 'Paste connections')) paste_action.setIcon(QIcon.fromTheme('edit-paste')) paste_action.triggered.connect(self.paste_connections) break def write_clipboard(self, cut: bool): canvas.clipboard.clear() canvas.clipboard_cut = cut for self_port_id in self._port_id_list: group_port_ids = [] for connection in canvas.connection_list: if self._port_mode == PORT_MODE_OUTPUT: if (connection.group_out_id == self._group_id and connection.port_out_id == self_port_id): group_port_ids.append((connection.group_in_id, connection.port_in_id)) elif self._port_mode == PORT_MODE_INPUT: if (connection.group_in_id == self._group_id and connection.port_in_id == self_port_id): group_port_ids.append((connection.group_out_id, connection.port_out_id)) element = clipboard_element_dict_t() element.group_id = self._group_id element.port_id = self_port_id element.port_type = self._port_type element.port_mode = self._port_mode element.group_port_ids = group_port_ids canvas.clipboard.append(element) def cut_connections(self): self.write_clipboard(True) def copy_connections(self): self.write_clipboard(False) def paste_connections(self): for i in range(len(self._port_id_list)): for j in range(len(canvas.clipboard)): if i % len(canvas.clipboard) != j % len(self._port_id_list): continue self_port_id = self._port_id_list[i] element = canvas.clipboard[j] if (element.port_type == self._port_type and element.port_mode == self._port_mode): for group_port_id in element.group_port_ids: group_id, port_id = group_port_id if canvas.clipboard_cut: # remove the original connection if still exists for connection in canvas.connection_list: if CanvasConnectionMatches( connection, element.group_id, [element.port_id], group_id, [port_id]): CanvasCallback( ACTION_PORTS_DISCONNECT, connection.connection_id, 0, '') break CanvasConnectPorts(self._group_id, self_port_id, group_id, port_id) break # once past, de-activate cut to prevent recut of connections # if they have been remade by user canvas.clipboard_cut = False class MainPortContextMenu(QMenu): def __init__(self, group_id: int, port_id: int, portgrp_id=0): QMenu.__init__(self) #self.setStyleSheet( #"""QMenu{background-color:#202020; border: 1px solid; #border-color: red; border-radius: 4px}; #QMenu::item{background-color:#999900}; #QMenu::item:selected{background-color: red}""") if portgrp_id: # menu is for a portgroup for portgrp in canvas.portgrp_list: if (portgrp.group_id == group_id and portgrp.portgrp_id == portgrp_id): port_type = portgrp.port_type port_mode = portgrp.port_mode is_alternate = False break else: return else: # menu is for a port for port in canvas.port_list: if port.group_id == group_id and port.port_id == port_id: port_type = port.port_type port_mode = port.port_mode is_alternate = port.is_alternate break else: return border_color = canvas.theme.port_audio_jack_pen.color().name() sel_bg = canvas.theme.port_audio_jack_bg.name() sel_text_color = canvas.theme.port_audio_jack_text.color().name() if port_type == PORT_TYPE_MIDI_JACK: border_color = canvas.theme.port_midi_jack_pen.color().name() sel_bg = canvas.theme.port_midi_jack_bg.name() sel_text_color = canvas.theme.port_midi_jack_text.color().name() style_str = """QMenu{background-color:#202020; border: 1px solid; border-color: %s; border-radius: 4px} QMenu::item{background-color: #202020;color: white} QMenu::item:disabled{color: #777777} QMenu::item:selected{background-color: %s; color:%s}""" % ( border_color, sel_bg, sel_text_color) #self.setStyleSheet(style_str) PortData.__init__(self, group_id, port_id, port_type, port_mode, portgrp_id, is_alternate) self.connection_list = [] canvas.qobject.connection_added.connect( self.connection_added_to_canvas) canvas.qobject.connection_removed.connect( self.connection_removed_from_canvas) port_data = PortData(group_id, port_id, port_type, port_mode, portgrp_id, is_alternate) dark = '' if is_dark_theme(self): dark = '-dark' self.connect_menu = ConnectMenu(port_data, self) self.connect_menu.setIcon( QIcon(QPixmap(':scalable/breeze%s/lines-connector' % dark))) self.addMenu(self.connect_menu) self.disconnect_menu = DisconnectMenu(port_data, self) self.disconnect_menu.setIcon( QIcon(QPixmap(':scalable/breeze%s/lines-disconnector' % dark))) self.addMenu(self.disconnect_menu) disconnect_all_action = self.addAction( _translate('patchbay', "Disconnect All")) disconnect_all_action.setIcon( QIcon(QPixmap(':scalable/breeze%s/lines-disconnector' % dark))) disconnect_all_action.triggered.connect(self.disconnect_all) self.clipboard_menu = ClipboardMenu(port_data, self) self.clipboard_menu.setIcon(QIcon.fromTheme('edit-paste')) self.addMenu(self.clipboard_menu) self.addSeparator() for connection in canvas.connection_list: if CanvasConnectionConcerns( connection, self._group_id, self._port_id_list): self.add_connection(connection) def get_port_attributes(self)->tuple: return (self._group_id, self._port_id, self._port_type, self._port_mode) def disconnect_all(self): for connection in self.connection_list: CanvasCallback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, '') def add_connection(self, connection): self.connection_list.append(connection) for port in canvas.port_list: if ((self._port_mode == PORT_MODE_OUTPUT and port.group_id == connection.group_in_id and port.port_id == connection.port_in_id) or (self._port_mode == PORT_MODE_INPUT and port.group_id == connection.group_out_id and port.port_id == connection.port_out_id)): group_id = port.group_id port_id = port.port_id portgrp_id = port.portgrp_id port_id_list = [port_id] if self._portgrp_id and portgrp_id: port_id = -1 port_id_list = CanvasGetPortGroupPortList( group_id, portgrp_id) con_state = CanvasPortGroupConnectionState( self._group_id, self._port_id_list, group_id, port_id_list) for group_menu in self.connect_menu.group_menus: if group_menu.group_id() == group_id: group_menu.check_element( port_id, portgrp_id, con_state) break for group_menu in self.connect_menu.dangerous_submenu.group_menus: if group_menu.group_id() == group_id: group_menu.check_element( port_id, portgrp_id, con_state) break self.disconnect_menu.add_element(group_id, port_id_list, portgrp_id) break def connection_added_to_canvas(self, connection_id: int): for connection in canvas.connection_list: if connection.connection_id == connection_id: if not CanvasConnectionConcerns( connection, self._group_id, self._port_id_list): return self.add_connection(connection) def connection_removed_from_canvas(self, connection_id: int): for connection in self.connection_list: if connection.connection_id == connection_id: for port in canvas.port_list: if ((self._port_mode == PORT_MODE_OUTPUT and port.group_id == connection.group_in_id and port.port_id == connection.port_in_id) or (self._port_mode == PORT_MODE_INPUT and port.group_id == connection.group_out_id and port.port_id == connection.port_out_id)): group_id = port.group_id port_id = port.port_id portgrp_id = port.portgrp_id if self._portgrp_id and portgrp_id: port_id = -1 port_id_list = CanvasGetPortGroupPortList( group_id, portgrp_id) else: port_id_list = [port_id] con_state = CanvasPortGroupConnectionState( self._group_id, self._port_id_list, group_id, port_id_list) for group_menu in self.connect_menu.group_menus: if group_menu.group_id() == group_id: group_menu.check_element( port_id, portgrp_id, con_state) break for group_menu in self.connect_menu.dangerous_submenu.group_menus: if group_menu.group_id() == group_id: group_menu.check_element( port_id, portgrp_id, con_state) break self.disconnect_menu.remove_element( group_id, port_id_list, portgrp_id) break self.connection_list.remove(connection) break RaySession-0.12.2/src/gui/patchcanvas/patchcanvas.py000066400000000000000000001372531417052567600224360ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from PyQt5.QtCore import (pyqtSlot, qCritical, qFatal, qWarning, QObject, QPoint, QPointF, QRectF, QSettings, QTimer, pyqtSignal) # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, features, options, group_dict_t, port_dict_t, portgrp_dict_t, connection_dict_t, bool2str, icon2str, split2str, port_mode2str, port_type2str, CanvasIconType, CanvasRubberbandType, ACTION_PORTS_DISCONNECT, EYECANDY_FULL, ICON_APPLICATION, ICON_HARDWARE, ICON_LADISH_ROOM, PORT_MODE_INPUT, PORT_MODE_OUTPUT, SPLIT_YES, SPLIT_NO, SPLIT_UNDEF, MAX_PLUGIN_ID_ALLOWED, ) from .canvasbox import CanvasBox from .canvasbezierline import CanvasBezierLine from .canvasline import CanvasLine from .theme import Theme, getDefaultTheme, getThemeName from .utils import (CanvasCallback, CanvasGetNewGroupPos, CanvasItemFX, CanvasRemoveItemFX, CanvasGetPortGroupPosition, CanvasGetNewGroupPositions) # FIXME from . import * from .scene import PatchScene # ------------------------------------------------------------------------------------------------------------ class CanvasObject(QObject): port_added = pyqtSignal(int, int) port_removed = pyqtSignal(int, int) connection_added = pyqtSignal(int) connection_removed = pyqtSignal(int) move_boxes_finished = pyqtSignal() zoom_changed = pyqtSignal(int) def __init__(self, parent=None): QObject.__init__(self, parent) self.groups_to_join = [] self.move_boxes_finished.connect(self.join_after_move) @pyqtSlot() def AnimationFinishedShow(self): animation = self.sender() if animation: animation.forceStop() canvas.animation_list.remove(animation) @pyqtSlot() def AnimationFinishedHide(self): animation = self.sender() if animation: animation.forceStop() canvas.animation_list.remove(animation) item = animation.item() if item: item.hide() @pyqtSlot() def AnimationFinishedDestroy(self): animation = self.sender() if animation: animation.forceStop() canvas.animation_list.remove(animation) item = animation.item() if item: CanvasRemoveItemFX(item) @pyqtSlot() def port_context_menu_connect(self): try: all_ids = list(self.sender().data()) except: return if len(all_ids) != 4: return group_out_id, port_out_id, group_in_id, port_in_id = all_ids CanvasCallback(ACTION_PORTS_CONNECT, '', '', ':'.join(all_ids)) @pyqtSlot() def PortContextMenuDisconnect(self): try: con_ids_list = list(self.sender().data()) except: return for connectionId in con_ids_list: if type(connectionId) != int: continue CanvasCallback(ACTION_PORTS_DISCONNECT, connectionId, 0, "") @pyqtSlot() def SetasStereoWith(self): try: all_data = self.sender().data() except: return port_widget = all_data[0] port_id = all_data[1] port_widget.SetAsStereo(port_id) def join_after_move(self): for group_id in self.groups_to_join: joinGroup(group_id) self.groups_to_join.clear() # ------------------------------------------------------------------------------------------------------------ def getStoredCanvasPosition(key, fallback_pos): try: return canvas.settings.value("CanvasPositions/" + key, fallback_pos, type=QPointF) except: return fallback_pos def getStoredCanvasSplit(group_name, fallback_split_mode): try: return canvas.settings.value("CanvasPositions/%s_SPLIT" % group_name, fallback_split_mode, type=int) except: return fallback_split_mode # ------------------------------------------------------------------------------------------------------------ def init(appName, scene, callback, debug=False): if debug: print("PatchCanvas::init(\"%s\", %s, %s, %s)" % (appName, scene, callback, bool2str(debug))) if canvas.initiated: qCritical("PatchCanvas::init() - already initiated") return if not callback: qFatal("PatchCanvas::init() - fatal error: callback not set") return canvas.callback = callback canvas.debug = debug canvas.scene = scene canvas.last_z_value = 0 canvas.last_connection_id = 0 canvas.initial_pos = QPointF(0, 0) canvas.size_rect = QRectF() if not canvas.qobject: canvas.qobject = CanvasObject() if not canvas.settings: canvas.settings = QSettings("falkTX", appName) if canvas.theme: del canvas.theme canvas.theme = None for i in range(Theme.THEME_MAX): this_theme_name = getThemeName(i) if this_theme_name == options.theme_name: canvas.theme = Theme(i) break if not canvas.theme: canvas.theme = Theme(getDefaultTheme()) canvas.scene.updateTheme() canvas.initiated = True def clear(): if canvas.debug: print("PatchCanvas::clear()") group_list_ids = [] port_list_ids = [] connection_list_ids = [] for group in canvas.group_list: group_list_ids.append(group.group_id) for port in canvas.port_list: port_list_ids.append((port.group_id, port.port_id)) for connection in canvas.connection_list: connection_list_ids.append(connection.connection_id) for idx in connection_list_ids: disconnectPorts(idx) for group_id, port_id in port_list_ids: removePort(group_id, port_id) for idx in group_list_ids: removeGroup(idx) canvas.last_z_value = 0 canvas.last_connection_id = 0 canvas.group_list = [] canvas.port_list = [] canvas.portgrp_list = [] canvas.connection_list = [] canvas.group_plugin_map = {} canvas.scene.clearSelection() animatedItems = [] for animation in canvas.animation_list: animatedItems.append(animation.item()) for item in canvas.scene.items(): if item.type() in (CanvasIconType, CanvasRubberbandType) or item in animatedItems: continue canvas.scene.removeItem(item) del item canvas.initiated = False QTimer.singleShot(0, canvas.scene.update) # ------------------------------------------------------------------------------------------------------------ def setInitialPos(x, y): if canvas.debug: print("PatchCanvas::setInitialPos(%i, %i)" % (x, y)) canvas.initial_pos.setX(x) canvas.initial_pos.setY(y) def setCanvasSize(x, y, width, height): if canvas.debug: print("PatchCanvas::setCanvasSize(%i, %i, %i, %i)" % (x, y, width, height)) canvas.size_rect.setX(x) canvas.size_rect.setY(y) canvas.size_rect.setWidth(width) canvas.size_rect.setHeight(height) canvas.scene.updateLimits() canvas.scene.fixScaleFactor() def addGroup(group_id, group_name, split=SPLIT_UNDEF, icon_type=ICON_APPLICATION, icon_name='', fast=False, null_xy=(0, 0), in_xy=(0, 0), out_xy=(0, 0), split_animated=False): if canvas.debug: print("PatchCanvas::addGroup(%i, %s, %s, %s)" % ( group_id, group_name.encode(), split2str(split), icon2str(icon_type))) for group in canvas.group_list: if group.group_id == group_id: qWarning("PatchCanvas::addGroup(%i, %s, %s, %s) - group already exists" % ( group_id, group_name.encode(), split2str(split), icon2str(icon_type))) return if split == SPLIT_UNDEF: isHardware = bool(icon_type == ICON_HARDWARE) if isHardware: split = SPLIT_YES group_box = CanvasBox(group_id, group_name, icon_type, icon_name) group_dict = group_dict_t() group_dict.group_id = group_id group_dict.group_name = group_name group_dict.split = bool(split == SPLIT_YES) group_dict.icon_type = icon_type group_dict.icon_name = icon_name group_dict.plugin_id = -1 group_dict.plugin_ui = False group_dict.plugin_inline = False group_dict.handle_client_gui = False group_dict.gui_visible = False group_dict.null_pos = QPoint(*null_xy) group_dict.in_pos = QPoint(*in_xy) group_dict.out_pos = QPoint(*out_xy) group_dict.widgets = [group_box, None] if split == SPLIT_YES: group_box.setSplit(True, PORT_MODE_OUTPUT) if features.handle_group_pos: new_pos = getStoredCanvasPosition(group_name + "_OUTPUT", CanvasGetNewGroupPos(False)) canvas.scene.add_box_to_animation(group_box, new_pos.x(), new_pos.y()) else: if split_animated: group_box.setPos(group_dict.null_pos) else: group_box.setPos(group_dict.out_pos) group_sbox = CanvasBox(group_id, group_name, icon_type, icon_name) group_sbox.setSplit(True, PORT_MODE_INPUT) group_dict.widgets[1] = group_sbox if features.handle_group_pos: new_pos = getStoredCanvasPosition(group_name + "_INPUT", CanvasGetNewGroupPos(True)) canvas.scene.add_box_to_animation(group_sbox, new_pos.x(), new_pos.y()) else: if split_animated: group_sbox.setPos(group_dict.null_pos) else: group_sbox.setPos(group_dict.in_pos) canvas.last_z_value += 1 group_sbox.setZValue(canvas.last_z_value) if options.eyecandy == EYECANDY_FULL and not options.auto_hide_groups: CanvasItemFX(group_sbox, True, False) else: group_box.setSplit(False) if features.handle_group_pos: group_box.setPos(getStoredCanvasPosition(group_name, CanvasGetNewGroupPos(False))) else: # Special ladish fake-split groups #horizontal = bool(icon_type in (ICON_HARDWARE, ICON_LADISH_ROOM)) group_box.setPos(group_dict.null_pos) canvas.last_z_value += 1 group_box.setZValue(canvas.last_z_value) canvas.group_list.append(group_dict) if options.eyecandy == EYECANDY_FULL and not options.auto_hide_groups: CanvasItemFX(group_box, True, False) return if fast: return if split_animated: for box in group_dict.widgets: if box is not None: if box.getSplittedMode() == PORT_MODE_OUTPUT: canvas.scene.add_box_to_animation( box, group_dict.out_pos.x(), group_dict.out_pos.y()) elif box.getSplittedMode() == PORT_MODE_INPUT: canvas.scene.add_box_to_animation( box, group_dict.in_pos.x(), group_dict.in_pos.y()) QTimer.singleShot(0, canvas.scene.update) def removeGroup(group_id, save_positions=True, fast=False): if canvas.debug: print("PatchCanvas::removeGroup(%i)" % group_id) for group in canvas.group_list: if group.group_id == group_id: item = group.widgets[0] group_name = group.group_name if group.split: s_item = group.widgets[1] if features.handle_group_pos and save_positions: canvas.settings.setValue("CanvasPositions/%s_OUTPUT" % group_name, item.pos()) canvas.settings.setValue("CanvasPositions/%s_INPUT" % group_name, s_item.pos()) canvas.settings.setValue("CanvasPositions/%s_SPLIT" % group_name, SPLIT_YES) if options.eyecandy == EYECANDY_FULL: CanvasItemFX(s_item, False, True) else: s_item.removeIconFromScene() canvas.scene.removeItem(s_item) del s_item else: if features.handle_group_pos and save_positions: canvas.settings.setValue("CanvasPositions/%s" % group_name, item.pos()) canvas.settings.setValue("CanvasPositions/%s_SPLIT" % group_name, SPLIT_NO) if options.eyecandy == EYECANDY_FULL: CanvasItemFX(item, False, True) else: item.removeIconFromScene() canvas.scene.removeItem(item) del item canvas.group_list.remove(group) canvas.group_plugin_map.pop(group.plugin_id, None) if fast: return QTimer.singleShot(0, canvas.scene.update) QTimer.singleShot(0, canvas.scene.resize_the_scene) return qCritical("PatchCanvas::removeGroup(%i) - unable to find group to remove" % group_id) def renameGroup(group_id, new_group_name): if canvas.debug: print("PatchCanvas::renameGroup(%i, %s)" % (group_id, new_group_name.encode())) for group in canvas.group_list: if group.group_id == group_id: group.group_name = new_group_name group.widgets[0].setGroupName(new_group_name) if group.split and group.widgets[1]: group.widgets[1].setGroupName(new_group_name) QTimer.singleShot(0, canvas.scene.update) return qCritical("PatchCanvas::renameGroup(%i, %s) - unable to find group to rename" % (group_id, new_group_name.encode())) def splitGroup(group_id, on_place=False): if canvas.debug: print("PatchCanvas::splitGroup(%i)" % group_id) item = None group_name = "" group_icon_type = ICON_APPLICATION group_icon_name = "" group_null_pos = QPoint(0, 0) group_in_pos = QPoint(0, 0) group_out_pos = QPoint(0, 0) plugin_id = -1 plugin_ui = False plugin_inline = False handle_client_gui = False gui_visible = False portgrps_data = [] ports_data = [] conns_data = [] # Step 1 - Store all Item data for group in canvas.group_list: if group.group_id == group_id: if group.split: qCritical("PatchCanvas::splitGroup(%i) - group is already split" % group_id) return item = group.widgets[0] group_name = group.group_name group_icon_type = group.icon_type group_icon_name = group.icon_name group_null_pos = group.null_pos group_in_pos = group.in_pos group_out_pos = group.out_pos plugin_id = group.plugin_id plugin_ui = group.plugin_ui plugin_inline = group.plugin_inline handle_client_gui = group.handle_client_gui gui_visible = group.gui_visible if on_place and item is not None: pos = item.pos() rect = item.boundingRect() y = int(pos.y()) x = int(pos.x()) group_in_pos = QPoint(x - int(rect.width() / 2), y) group_out_pos = QPoint(x + int(rect.width() / 2), y) break if not item: qCritical("PatchCanvas::splitGroup(%i) - unable to find group to split" % group_id) return wrap = item.is_wrapped() for portgrp in canvas.portgrp_list: if portgrp.group_id == group_id: portgrp_dict = portgrp_dict_t() portgrp_dict.group_id = portgrp.group_id portgrp_dict.portgrp_id = portgrp.portgrp_id portgrp_dict.port_type = portgrp.port_type portgrp_dict.port_mode = portgrp.port_mode portgrp_dict.port_id_list = portgrp.port_id_list portgrp_dict.widget = None portgrps_data.append(portgrp_dict) for port in canvas.port_list: if port.group_id == group_id: port_dict = port_dict_t() port_dict.group_id = port.group_id port_dict.port_id = port.port_id port_dict.port_name = port.port_name port_dict.port_mode = port.port_mode port_dict.port_type = port.port_type port_dict.portgrp_id = 0 port_dict.is_alternate = port.is_alternate port_dict.widget = None ports_data.append(port_dict) for connection in canvas.connection_list: if (connection.group_out_id == group_id or connection.group_in_id == group_id): connection_dict = connection_dict_t() connection_dict.connection_id = connection.connection_id connection_dict.group_in_id = connection.group_in_id connection_dict.port_in_id = connection.port_in_id connection_dict.group_out_id = connection.group_out_id connection_dict.port_out_id = connection.port_out_id connection_dict.widget = None conns_data.append(connection_dict) # Step 2 - Remove Item and Children for conn in conns_data: disconnectPorts(conn.connection_id, fast=True) for portgrp in portgrps_data: if portgrp.group_id == group_id: removePortGroup(group_id, portgrp.portgrp_id, fast=True) for port in ports_data: if port.group_id == group_id: removePort(group_id, port.port_id, fast=True) removeGroup(group_id) # Step 3 - Re-create Item, now split addGroup(group_id, group_name, SPLIT_YES, group_icon_type, group_icon_name, null_xy=(group_null_pos.x(), group_null_pos.y()), in_xy=(group_in_pos.x(), group_in_pos.y()), out_xy=(group_out_pos.x(), group_out_pos.y()), split_animated=True) if handle_client_gui: set_optional_gui_state(group_id, gui_visible) if plugin_id >= 0: setGroupAsPlugin(group_id, plugin_id, plugin_ui, plugin_inline) for port in ports_data: addPort(group_id, port.port_id, port.port_name, port.port_mode, port.port_type, port.is_alternate, fast=True) for portgrp in portgrps_data: addPortGroup(group_id, portgrp.portgrp_id, portgrp.port_mode, portgrp.port_type, portgrp.port_id_list, fast=True) for conn in conns_data: connectPorts(conn.connection_id, conn.group_out_id, conn.port_out_id, conn.group_in_id, conn.port_in_id, fast=True) for group in canvas.group_list: if group.group_id == group_id: for box in group.widgets: if box is not None: box.set_wrapped(wrap, animate=False) box.updatePositions(even_animated=True) QTimer.singleShot(0, canvas.scene.update) def joinGroup(group_id): if canvas.debug: print("PatchCanvas::joinGroup(%i)" % group_id) item = None s_item = None group_name = "" group_icon_type = ICON_APPLICATION group_icon_name = "" group_null_pos = QPoint(0, 0) group_in_pos = QPoint(0, 0) group_out_pos = QPoint(0, 0) plugin_id = -1 plugin_ui = False plugin_inline = False handle_client_gui = False gui_visible = False portgrps_data = [] ports_data = [] conns_data = [] # Step 1 - Store all Item data for group in canvas.group_list: if group.group_id == group_id: if not group.split: qCritical("PatchCanvas::joinGroup(%i) - group is not split" % group_id) return item = group.widgets[0] s_item = group.widgets[1] group_name = group.group_name group_icon_type = group.icon_type group_icon_name = group.icon_name group_null_pos = group.null_pos group_in_pos = group.in_pos group_out_pos = group.out_pos plugin_id = group.plugin_id plugin_ui = group.plugin_ui plugin_inline = group.plugin_inline handle_client_gui = group.handle_client_gui gui_visible = group.gui_visible break # FIXME if not (item and s_item): qCritical("PatchCanvas::joinGroup(%i) - unable to find groups to join" % group_id) return wrap = item.is_wrapped() and s_item.is_wrapped() for portgrp in canvas.portgrp_list: if portgrp.group_id == group_id: portgrp_dict = portgrp_dict_t() portgrp_dict.group_id = portgrp.group_id portgrp_dict.portgrp_id = portgrp.portgrp_id portgrp_dict.port_type = portgrp.port_type portgrp_dict.port_mode = portgrp.port_mode portgrp_dict.port_id_list = portgrp.port_id_list portgrp_dict.widget = None portgrps_data.append(portgrp_dict) for port in canvas.port_list: if port.group_id == group_id: port_dict = port_dict_t() port_dict.group_id = port.group_id port_dict.port_id = port.port_id port_dict.port_name = port.port_name port_dict.port_mode = port.port_mode port_dict.port_type = port.port_type port_dict.portgrp_id = port.portgrp_id port_dict.is_alternate = port.is_alternate port_dict.widget = None ports_data.append(port_dict) for connection in canvas.connection_list: if (connection.group_out_id == group_id or connection.group_in_id == group_id): connection_dict = connection_dict_t() connection_dict.connection_id = connection.connection_id connection_dict.group_in_id = connection.group_in_id connection_dict.port_in_id = connection.port_in_id connection_dict.group_out_id = connection.group_out_id connection_dict.port_out_id = connection.port_out_id connection_dict.widget = None conns_data.append(connection_dict) # Step 2 - Remove Item and Children for conn in conns_data: disconnectPorts(conn.connection_id, fast=True) for portgrp in portgrps_data: removePortGroup(group_id, portgrp.portgrp_id, fast=True) for port in ports_data: removePort(group_id, port.port_id, fast=True) removeGroup(group_id, save_positions=False) # Step 3 - Re-create Item, now together addGroup(group_id, group_name, SPLIT_NO, group_icon_type, group_icon_name, null_xy=(group_null_pos.x(), group_null_pos.y()), in_xy=(group_in_pos.x(), group_in_pos.y()), out_xy=(group_out_pos.x(), group_out_pos.y())) if handle_client_gui: set_optional_gui_state(group_id, gui_visible) if plugin_id >= 0: setGroupAsPlugin(group_id, plugin_id, plugin_ui, plugin_inline) for port in ports_data: addPort(group_id, port.port_id, port.port_name, port.port_mode, port.port_type, port.is_alternate, fast=True) for portgrp in portgrps_data: addPortGroup(group_id, portgrp.portgrp_id, portgrp.port_mode, portgrp.port_type, portgrp.port_id_list, fast=True) for conn in conns_data: connectPorts(conn.connection_id, conn.group_out_id, conn.port_out_id, conn.group_in_id, conn.port_in_id, fast=True) for group in canvas.group_list: if group.group_id == group_id: for box in group.widgets: if box is not None: box.set_wrapped(wrap, animate=False) box.updatePositions() canvas.callback(ACTION_GROUP_JOINED, group_id, 0, '') QTimer.singleShot(0, canvas.scene.update) def redrawAllGroups(): for group in canvas.group_list: for box in group.widgets: if box is not None: box.updatePositions() if canvas.scene is None: return QTimer.singleShot(0, canvas.scene.update) def redrawGroup(group_id: int): for group in canvas.group_list: if group.group_id == group_id: for box in group.widgets: if box is not None: box.updatePositions() break QTimer.singleShot(0, canvas.scene.update) def animateBeforeJoin(group_id: int): canvas.qobject.groups_to_join.append(group_id) for group in canvas.group_list: if group.group_id == group_id: for widget in group.widgets: canvas.scene.add_box_to_animation( widget, group.null_pos.x(), group.null_pos.y()) break def moveGroupBoxes(group_id: int, null_xy: tuple, in_xy: tuple, out_xy: tuple, animate=True): for group in canvas.group_list: if group.group_id == group_id: break else: return group.null_pos = QPoint(*null_xy) group.in_pos = QPoint(*in_xy) group.out_pos = QPoint(*out_xy) if group.split: for port_mode in (PORT_MODE_OUTPUT, PORT_MODE_INPUT): box = group.widgets[0] xy = out_xy pos = group.out_pos if port_mode == PORT_MODE_INPUT: box = group.widgets[1] xy = in_xy pos = group.in_pos if box is None: continue box_pos = box.pos() if int(box_pos.x()) == xy[0] and int(box_pos.y()) == xy[1]: continue canvas.scene.add_box_to_animation( box, xy[0], xy[1], force_anim=animate) else: box = group.widgets[0] if box is None: return box_pos = box.pos() if int(box_pos.x()) == null_xy[0] and int(box_pos.y()) == null_xy[1]: return canvas.scene.add_box_to_animation(box, null_xy[0], null_xy[1], force_anim=animate) def wrapGroupBox(group_id: int, port_mode: int, yesno: bool, animate=True): for group in canvas.group_list: if group.group_id == group_id: for box in group.widgets: if (box is not None and box.getSplittedMode() == port_mode): box.set_wrapped(yesno, animate=animate) # ------------------------------------------------------------------------------------------------------------ def getGroupPos(group_id, port_mode=PORT_MODE_OUTPUT): if canvas.debug: print("PatchCanvas::getGroupPos(%i, %s)" % (group_id, port_mode2str(port_mode))) for group in canvas.group_list: if group.group_id == group_id: return group.widgets[1 if (group.split and port_mode == PORT_MODE_INPUT) else 0].pos() qCritical("PatchCanvas::getGroupPos(%i, %s) - unable to find group" % (group_id, port_mode2str(port_mode))) return QPointF(0, 0) def restoreGroupPositions(dataList): if canvas.debug: print("PatchCanvas::restoreGroupPositions(...)") mapping = {} for group in canvas.group_list: mapping[group.group_name] = group for data in dataList: name = data['name'] group = mapping.get(name, None) if group is None: continue group.widgets[0].setPos(data['pos1x'], data['pos1y']) if group.split and group.widgets[1]: group.widgets[1].setPos(data['pos2x'], data['pos2y']) def setGroupPos(group_id, group_pos_x, group_pos_y): setGroupPosFull(group_id, group_pos_x, group_pos_y, group_pos_x, group_pos_y) def setGroupPosFull(group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group_pos_y_i): if canvas.debug: print("PatchCanvas::setGroupPos(%i, %i, %i, %i, %i)" % ( group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group_pos_y_i)) for group in canvas.group_list: if group.group_id == group_id: group.widgets[0].setPos(group_pos_x_o, group_pos_y_o) if group.split and group.widgets[1]: group.widgets[1].setPos(group_pos_x_i, group_pos_y_i) QTimer.singleShot(0, canvas.scene.update) return qCritical("PatchCanvas::setGroupPos(%i, %i, %i, %i, %i) - unable to find group to reposition" % ( group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group_pos_y_i)) # ------------------------------------------------------------------------------------------------------------ def setGroupIcon(group_id, icon_type: int, icon_name: str): if canvas.debug: print("PatchCanvas::setGroupIcon(%i, %s)" % (group_id, icon2str(icon_type))) for group in canvas.group_list: if group.group_id == group_id: group.icon_type = icon_type for widget in group.widgets: if widget is not None: widget.setIcon(icon_type, icon_name) QTimer.singleShot(0, canvas.scene.update) return qCritical("PatchCanvas::setGroupIcon(%i, %s) - unable to find group to change icon" % (group_id, icon2str(icon_type))) def setGroupAsPlugin(group_id, plugin_id, hasUI, hasInlineDisplay): if canvas.debug: print("PatchCanvas::setGroupAsPlugin(%i, %i, %s, %s)" % ( group_id, plugin_id, bool2str(hasUI), bool2str(hasInlineDisplay))) for group in canvas.group_list: if group.group_id == group_id: group.plugin_id = plugin_id group.plugin_ui = hasUI group.plugin_inline = hasInlineDisplay group.widgets[0].setAsPlugin(plugin_id, hasUI, hasInlineDisplay) if group.split and group.widgets[1]: group.widgets[1].setAsPlugin(plugin_id, hasUI, hasInlineDisplay) canvas.group_plugin_map[plugin_id] = group return qCritical("PatchCanvas::setGroupAsPlugin(%i, %i, %s, %s) - unable to find group to set as plugin" % ( group_id, plugin_id, bool2str(hasUI), bool2str(hasInlineDisplay))) # ------------------------------------------------------------------------------------------------------------ def addPort(group_id, port_id, port_name, port_mode, port_type, is_alternate=False, fast=False): if canvas.debug: print("PatchCanvas::addPort(%i, %i, %s, %s, %s, %s)" % ( group_id, port_id, port_name.encode(), port_mode2str(port_mode), port_type2str(port_type), bool2str(is_alternate))) for port in canvas.port_list: if port.group_id == group_id and port.port_id == port_id: qWarning("PatchCanvas::addPort(%i, %i, %s, %s, %s) - port already exists" % ( group_id, port_id, port_name.encode(), port_mode2str(port_mode), port_type2str(port_type))) return box_widget = None port_widget = None for group in canvas.group_list: if group.group_id == group_id: if group.split and group.widgets[0].getSplittedMode() != port_mode and group.widgets[1]: n = 1 else: n = 0 box_widget = group.widgets[n] port_widget = box_widget.addPortFromGroup( port_id, port_mode, port_type, port_name, is_alternate) break if not (box_widget and port_widget): qCritical("PatchCanvas::addPort(%i, %i, %s, %s, %s) - Unable to find parent group" % ( group_id, port_id, port_name.encode(), port_mode2str(port_mode), port_type2str(port_type))) return port_dict = port_dict_t() port_dict.group_id = group_id port_dict.port_id = port_id port_dict.port_name = port_name port_dict.port_mode = port_mode port_dict.port_type = port_type port_dict.portgrp_id = 0 port_dict.is_alternate = is_alternate port_dict.widget = port_widget canvas.port_list.append(port_dict) canvas.last_z_value += 1 port_widget.setZValue(canvas.last_z_value) canvas.qobject.port_added.emit(port_dict.group_id, port_dict.port_id) if fast: return box_widget.updatePositions() if options.eyecandy == EYECANDY_FULL: CanvasItemFX(port_widget, True, False) return QTimer.singleShot(0, canvas.scene.update) def removePort(group_id, port_id, fast=False): if canvas.debug: print("PatchCanvas::removePort(%i, %i)" % (group_id, port_id)) for port in canvas.port_list: if port.group_id == group_id and port.port_id == port_id: if port.portgrp_id: qCritical("PatchCanvas::removePort(%i, %i) - Port is in portgroup %i, remove it before !" % ( group_id, port_id, port.portgrp_id)) return item = port.widget if item is not None: item.parentItem().removePortFromGroup(port_id) canvas.scene.removeItem(item) del item canvas.port_list.remove(port) canvas.qobject.port_removed.emit(group_id, port_id) if fast: return QTimer.singleShot(0, canvas.scene.update) return qCritical("PatchCanvas::removePort(%i, %i) - Unable to find port to remove" % (group_id, port_id)) def renamePort(group_id, port_id, new_port_name, fast=False): if canvas.debug: print("PatchCanvas::renamePort(%i, %i, %s)" % (group_id, port_id, new_port_name)) for port in canvas.port_list: if port.group_id == group_id and port.port_id == port_id: if new_port_name != port.port_name: port.port_name = new_port_name port.widget.setPortName(new_port_name) if fast: return port.widget.parentItem().updatePositions() QTimer.singleShot(0, canvas.scene.update) return qCritical("PatchCanvas::renamePort(%i, %i, %s) - Unable to find port to rename" % ( group_id, port_id, new_port_name.encode())) def addPortGroup(group_id, portgrp_id, port_mode, port_type, port_id_list, fast=False): if canvas.debug: print("PatchCanvas::addPortGroup(%i, %i)" % (group_id, portgrp_id)) for portgrp in canvas.portgrp_list: if portgrp.group_id == group_id and portgrp.portgrp_id == portgrp_id: qWarning("PatchCanvas::addPortGroup(%i, %i) - portgroup already exists" % ( group_id, portgrp_id)) return portgrp_dict = portgrp_dict_t() portgrp_dict.group_id = group_id portgrp_dict.portgrp_id = portgrp_id portgrp_dict.port_mode = port_mode portgrp_dict.port_type = port_type portgrp_dict.port_id_list = tuple(port_id_list) portgrp_dict.widget = None i = 0 # check that port ids are present and groupable in this group for port in canvas.port_list: if (port.group_id == group_id and port.port_type == port_type and port.port_mode == port_mode): if port.port_id == port_id_list[i]: if port.portgrp_id: qWarning("PatchCanvas::addPortGroup(%i, %i, %s) - port id %i is already in portgroup %i" % (group_id, portgrp_id, str(port_id_list), port.port_id, port.portgrp_id)) return i += 1 if i == len(port_id_list): # everything seems ok for this portgroup, stop the check break elif i > 0: qWarning("PatchCanvas::addPortGroup(%i, %i, %s) - port ids are not consecutive" % ( group_id, portgrp_id, str(port_id_list))) return else: qWarning("PatchCanvas::addPortGroup(%i, %i, %s) - not enought ports with port_id_list" % ( group_id, portgrp_id, str(port_id_list))) return # modify ports impacted by portgroup for port in canvas.port_list: if (port.group_id == group_id and port.port_id in port_id_list): port.portgrp_id = portgrp_id if port.widget is not None: port.widget.setPortGroupId(portgrp_id) canvas.portgrp_list.append(portgrp_dict) # add portgroup widget and refresh the view for group in canvas.group_list: if group.group_id == group_id: for box in group.widgets: if box is None: continue if (not box.isSplitted() or box.getSplittedMode() == port_mode): portgrp_dict.widget = box.addPortGroupFromGroup( portgrp_id, port_mode, port_type, port_id_list) if not fast: box.updatePositions() break def removePortGroup(group_id, portgrp_id, fast=False): if canvas.debug: print("PatchCanvas::removePortGroup(%i, %i)" % (group_id, portgrp_id)) box_widget = None for portgrp in canvas.portgrp_list: if (portgrp.group_id == group_id and portgrp.portgrp_id == portgrp_id): # set portgrp_id to the concerned ports for port in canvas.port_list: if (port.group_id == group_id and port.portgrp_id == portgrp_id): port.portgrp_id = 0 if port.widget is not None: port.widget.setPortGroupId(0) box_widget = port.widget.parentItem() if portgrp.widget is not None: item = portgrp.widget canvas.scene.removeItem(item) del item portgrp.widget = None break else: qCritical("PatchCanvas::removePortGroup(%i, %i) - Unable to find portgrp to remove" % ( group_id, portgrp_id)) return canvas.portgrp_list.remove(portgrp) if fast: return if box_widget is not None: box_widget.updatePositions() QTimer.singleShot(0, canvas.scene.update) def connectPorts(connection_id, group_out_id, port_out_id, group_in_id, port_in_id, fast=False): if canvas.debug: print("PatchCanvas::connectPorts(%i, %i, %i, %i, %i)" % ( connection_id, group_out_id, port_out_id, group_in_id, port_in_id)) port_out = None port_in = None port_out_parent = None port_in_parent = None for port in canvas.port_list: if port.group_id == group_out_id and port.port_id == port_out_id: port_out = port.widget if port_out is not None: port_out_parent = port_out.parentItem() elif port.group_id == group_in_id and port.port_id == port_in_id: port_in = port.widget if port_in is not None: port_in_parent = port_in.parentItem() # FIXME if not (port_out and port_in and port_out_parent and port_in_parent): qCritical("PatchCanvas::connectPorts(%i, %i, %i, %i, %i) - unable to find ports to connect" % ( connection_id, group_out_id, port_out_id, group_in_id, port_in_id)) return connection_dict = connection_dict_t() connection_dict.connection_id = connection_id connection_dict.group_in_id = group_in_id connection_dict.port_in_id = port_in_id connection_dict.group_out_id = group_out_id connection_dict.port_out_id = port_out_id if options.use_bezier_lines: connection_dict.widget = CanvasBezierLine(port_out, port_in, None) else: connection_dict.widget = CanvasLine(port_out, port_in, None) canvas.scene.addItem(connection_dict.widget) port_out_parent.addLineFromGroup(connection_dict.widget, connection_id) port_in_parent.addLineFromGroup(connection_dict.widget, connection_id) canvas.last_z_value += 1 port_out_parent.setZValue(canvas.last_z_value) port_in_parent.setZValue(canvas.last_z_value) canvas.last_z_value += 1 connection_dict.widget.setZValue(canvas.last_z_value) canvas.connection_list.append(connection_dict) canvas.qobject.connection_added.emit(connection_id) if fast: return if options.eyecandy == EYECANDY_FULL: item = connection_dict.widget CanvasItemFX(item, True, False) return QTimer.singleShot(0, canvas.scene.update) def disconnectPorts(connection_id, fast=False): if canvas.debug: print("PatchCanvas::disconnectPorts(%i)" % connection_id) line = None item1 = None item2 = None group1id = port1id = 0 group2id = port2id = 0 for connection in canvas.connection_list: if connection.connection_id == connection_id: group1id = connection.group_out_id group2id = connection.group_in_id port1id = connection.port_out_id port2id = connection.port_in_id line = connection.widget canvas.connection_list.remove(connection) break canvas.qobject.connection_removed.emit(connection_id) if not line: qCritical("PatchCanvas::disconnectPorts(%i) - unable to find connection ports" % connection_id) return for port in canvas.port_list: if port.group_id == group1id and port.port_id == port1id: item1 = port.widget break if not item1: qCritical("PatchCanvas::disconnectPorts(%i) - unable to find output port" % connection_id) return for port in canvas.port_list: if port.group_id == group2id and port.port_id == port2id: item2 = port.widget break if not item2: qCritical("PatchCanvas::disconnectPorts(%i) - unable to find input port" % connection_id) return item1.parentItem().removeLineFromGroup(connection_id) item2.parentItem().removeLineFromGroup(connection_id) if options.eyecandy == EYECANDY_FULL and not fast: CanvasItemFX(line, False, True) return canvas.scene.removeItem(line) del line if fast: return QTimer.singleShot(0, canvas.scene.update) # ------------------------------------------------------------------------------------------------------------ def arrange(): if canvas.debug: print("PatchCanvas::arrange()") def changeTheme(idx: int): canvas.theme.setTheme(idx) canvas.scene.updateTheme() for group in canvas.group_list: for widget in group.widgets: if widget is not None: widget.repaintLines(forced=True) widget.update() QTimer.singleShot(0, canvas.scene.update) # ------------------------------------------------------------------------------------------------------------ def updateZValues(): if canvas.debug: print("PatchCanvas::updateZValues()") for group in canvas.group_list: group.widgets[0].resetLinesZValue() if group.split and group.widgets[1]: group.widgets[1].resetLinesZValue() # ------------------------------------------------------------------------------------------------------------ def redrawPluginGroup(plugin_id): group = canvas.group_plugin_map.get(plugin_id, None) if group is None: #qCritical("PatchCanvas::redrawPluginGroup(%i) - unable to find group" % plugin_id) return group.widgets[0].redrawInlineDisplay() if group.split and group.widgets[1]: group.widgets[1].redrawInlineDisplay() def handlePluginRemoved(plugin_id): if canvas.debug: print("PatchCanvas::handlePluginRemoved(%i)" % plugin_id) group = canvas.group_plugin_map.pop(plugin_id, None) if group is not None: group.plugin_id = -1 group.plugin_ui = False group.plugin_inline = False group.widgets[0].removeAsPlugin() if group.split and group.widgets[1]: group.widgets[1].removeAsPlugin() for group in canvas.group_list: if group.plugin_id < plugin_id or group.plugin_id > MAX_PLUGIN_ID_ALLOWED: continue group.plugin_id -= 1 group.widgets[0].m_plugin_id -= 1 if group.split and group.widgets[1]: group.widgets[1].m_plugin_id -= 1 canvas.group_plugin_map[plugin_id] = group def handleAllPluginsRemoved(): if canvas.debug: print("PatchCanvas::handleAllPluginsRemoved()") canvas.group_plugin_map = {} for group in canvas.group_list: if group.plugin_id < 0: continue if group.plugin_id > MAX_PLUGIN_ID_ALLOWED: continue group.plugin_id = -1 group.plugin_ui = False group.plugin_inline = False group.widgets[0].removeAsPlugin() if group.split and group.widgets[1]: group.widgets[1].removeAsPlugin() def setElastic(yesno: bool): canvas.scene.set_elastic(yesno) def set_prevent_overlap(yesno: bool): canvas.scene.set_prevent_overlap(yesno) if yesno: redrawAllGroups() def set_max_port_width(width: int): options.max_port_width = width redrawAllGroups() def semi_hide_group(group_id: int, yesno:bool): for group in canvas.group_list: if group.group_id == group_id: for widget in group.widgets: if widget is not None: widget.semi_hide(yesno) break def semi_hide_connection(connection_id: int, yesno:bool): for connection in canvas.connection_list: if connection.connection_id == connection_id: if connection.widget is not None: connection.widget.semi_hide(yesno) break def set_group_in_front(group_id: int): canvas.last_z_value += 1 for group in canvas.group_list: if group.group_id == group_id: for widget in group.widgets: if widget is not None: widget.setZValue(canvas.last_z_value) break def set_connection_in_front(connection_id: int): canvas.last_z_value += 1 for conn in canvas.connection_list: if conn.connection_id == connection_id: if conn.widget is not None: conn.widget.setZValue(canvas.last_z_value) break def select_filtered_group_box(group_id: int, n_select = 1): for group in canvas.group_list: if group.group_id == group_id: n_widget = 1 for widget in group.widgets: if widget is not None and widget.isVisible(): if n_select == n_widget: canvas.scene.clearSelection() widget.setSelected(True) canvas.scene.center_view_on(widget) break n_widget += 1 break def get_number_of_boxes(group_id: int)->int: n = 0 for group in canvas.group_list: if group.group_id == group_id: for widget in group.widgets: if widget is not None and widget.isVisible(): n += 1 break return n def set_semi_hide_opacity(opacity: float): canvas.semi_hide_opacity = opacity for group in canvas.group_list: for widget in group.widgets: if widget is not None: widget.update_opacity() for conn in canvas.connection_list: if conn.widget is not None: conn.widget.updateLineGradient() def set_optional_gui_state(group_id: int, visible: bool): for group in canvas.group_list: if group.group_id == group_id: group.handle_client_gui = True group.gui_visible = visible for widget in group.widgets: if widget is not None: widget.set_optional_gui_state(visible) break canvas.scene.update() # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/scene.py000066400000000000000000001157031417052567600212340ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from math import floor import time from PyQt5.QtCore import (QT_VERSION, pyqtSignal, pyqtSlot, qFatal, Qt, QPoint, QPointF, QRectF, QTimer, QSizeF, QMarginsF) from PyQt5.QtGui import QCursor, QPixmap, QPolygonF, QLinearGradient, QColor from PyQt5.QtWidgets import (QGraphicsRectItem, QGraphicsScene, QGraphicsView, QApplication) # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import ( canvas, options, CanvasBoxType, CanvasIconType, CanvasPortType, CanvasPortGroupType, CanvasLineType, CanvasBezierLineType, CanvasRubberbandType, ACTION_BG_RIGHT_CLICK, ACTION_DOUBLE_CLICK, MAX_PLUGIN_ID_ALLOWED, PORT_MODE_INPUT, PORT_MODE_OUTPUT, DIRECTION_NONE, DIRECTION_LEFT, DIRECTION_RIGHT, DIRECTION_UP, DIRECTION_DOWN ) from .canvasbox import CanvasBox # ------------------------------------------------------------------------------------------------------------ class RubberbandRect(QGraphicsRectItem): def __init__(self, scene): QGraphicsRectItem.__init__(self, QRectF(0, 0, 0, 0)) self.setZValue(-1) self.hide() scene.addItem(self) def type(self): return CanvasRubberbandType # ------------------------------------------------------------------------------------------------------------ class PatchScene(QGraphicsScene): scaleChanged = pyqtSignal(float) sceneGroupMoved = pyqtSignal(int, int, QPointF) pluginSelected = pyqtSignal(list) def __init__(self, parent, view): QGraphicsScene.__init__(self, parent) #self.setItemIndexMethod(QGraphicsScene.NoIndex) self.m_scale_area = False self.m_mouse_down_init = False self.m_mouse_rubberband = False self.m_mid_button_down = False self.m_pointer_border = QRectF(0.0, 0.0, 1.0, 1.0) self.m_scale_min = 0.1 self.m_scale_max = 4.0 self.scales = (0.1, 0.25, 0.4, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 4.0) self.m_rubberband = RubberbandRect(self) self.m_rubberband_selection = False self.m_rubberband_orig_point = QPointF(0, 0) self.m_view = view if not self.m_view: qFatal("PatchCanvas::PatchScene() - invalid view") self.curCut = None self.curZoomArea = None self._move_timer_start_at = 0 self._move_timer_interval = 20 # 20 ms step animation (50 Hz) self.move_boxes = [] self.wrapping_boxes = [] self.move_box_timer = QTimer() self.move_box_timer.setInterval(self._move_timer_interval) self.move_box_timer.timeout.connect(self.move_boxes_animation) self.move_box_n = 0 self.move_box_n_max = 16 # 16 animations steps (20ms * 16 = 320ms) self.elastic_scene = True self.resizing_scene = False self.selectionChanged.connect(self.slot_selectionChanged) self._prevent_overlap = True self.loading_items = False def clear(self): # reimplement Qt function and fix missing rubberband after clear QGraphicsScene.clear(self) self.m_rubberband = RubberbandRect(self) self.updateTheme() def getDevicePixelRatioF(self): if QT_VERSION < 0x50600: return 1.0 return self.m_view.devicePixelRatioF() def getScaleFactor(self): return self.m_view.transform().m11() def fixScaleFactor(self, transform=None): fix, set_view = False, False if not transform: set_view = True view = self.m_view transform = view.transform() scale = transform.m11() if scale > self.m_scale_max: fix = True transform.reset() transform.scale(self.m_scale_max, self.m_scale_max) elif scale < self.m_scale_min: fix = True transform.reset() transform.scale(self.m_scale_min, self.m_scale_min) if set_view: if fix: view.setTransform(transform) self.scaleChanged.emit(transform.m11()) return fix def fix_temporary_scroll_bars(self): if self.m_view is None: return if self.m_view.horizontalScrollBar().isVisible(): self.m_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) else: self.m_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) if self.m_view.verticalScrollBar().isVisible(): self.m_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) else: self.m_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) def reset_scroll_bars(self): self.m_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.m_view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) def move_boxes_animation(self): # animation is nice but not the priority # do not ensure all steps are played # but just move the box where it has to go self.move_box_n = int((time.time() - self._move_timer_start_at) / (self._move_timer_interval * 0.001)) self.move_box_n = min(self.move_box_n, self.move_box_n_max) for box_dict in self.move_boxes: if box_dict['widget'] is not None: total_n = self.move_box_n_max - box_dict['n_start'] n = self.move_box_n - box_dict['n_start'] x = box_dict['from_x'] \ + (box_dict['to_x'] - box_dict['from_x']) \ * ((n/total_n) ** 0.6) y = box_dict['from_y'] \ + (box_dict['to_y'] - box_dict['from_y']) \ * ((n/total_n) ** 0.6) box_dict['widget'].setPos(x, y) for wrap_dict in self.wrapping_boxes: if wrap_dict['widget'] is not None: if self.move_box_n == self.move_box_n_max: wrap_dict['widget'].animate_wrapping(1.00) else: wrap_dict['widget'].animate_wrapping( float(self.move_box_n / self.move_box_n_max)) self.resize_the_scene() if self.move_box_n >= self.move_box_n_max: self.move_box_n = 0 self.move_box_timer.stop() move_box_widgets = [b['widget'] for b in self.move_boxes] self.move_boxes.clear() self.wrapping_boxes.clear() QTimer.singleShot(0, self.update) for box_dict in self.move_boxes: if box_dict['widget'] is not None: QTimer.singleShot(0, box_dict['widget'].repaintLines) for box in move_box_widgets: if box is not None: box.updatePositions() box.send_move_callback() canvas.qobject.move_boxes_finished.emit() elif self.move_box_n % 5 == 4: self.update() def add_box_to_animation(self, box_widget, to_x: int, to_y: int, force_anim=True): for box_dict in self.move_boxes: if box_dict['widget'] == box_widget: break else: if not force_anim: # if box is not in a current animation # and force_anim is False, # then box position is directly changed if box_widget is not None: box_widget.setPos(int(to_x), int(to_y)) return box_dict = {'widget': box_widget} self.move_boxes.append(box_dict) box_dict['from_x'] = box_widget.pos().x() box_dict['from_y'] = box_widget.pos().y() box_dict['to_x'] = int(to_x) box_dict['to_y'] = int(to_y) box_dict['n_start'] = self.move_box_n if not self.move_box_timer.isActive(): self._move_timer_start_at = time.time() self.move_box_timer.start() def add_box_to_animation_wrapping(self, box_widget, wrap: bool): for wrap_dict in self.wrapping_boxes: if wrap_dict['widget'] == box_widget: wrap_dict['wrap'] = wrap break else: self.wrapping_boxes.append({'widget': box_widget, 'wrap': wrap}) if not self.move_box_timer.isActive(): self._move_timer_start_at = time.time() self.move_box_timer.start() def deplace_boxes_from_repulsers(self, repulser_boxes: list, wanted_direction=DIRECTION_NONE, new_scene_rect=None): if not options.prevent_overlap: return box_spacing = canvas.theme.box_spacing box_spacing_hor = canvas.theme.box_spacing_hor magnet = canvas.theme.magnet def get_direction(fixed_rect, moving_rect, parent_directions=[])->int: if (moving_rect.top() <= fixed_rect.center().y() <= moving_rect.bottom() or fixed_rect.top() <= moving_rect.center().y() <= fixed_rect.bottom()): if (fixed_rect.right() < moving_rect.center().x() and fixed_rect.center().x() < moving_rect.left()): if DIRECTION_LEFT in parent_directions: return DIRECTION_LEFT return DIRECTION_RIGHT if (fixed_rect.left() > moving_rect.center().x() and fixed_rect.center().x() > moving_rect.right()): if DIRECTION_RIGHT in parent_directions: return DIRECTION_RIGHT return DIRECTION_LEFT if fixed_rect.center().y() <= moving_rect.center().y(): if DIRECTION_UP in parent_directions: return DIRECTION_UP return DIRECTION_DOWN if DIRECTION_DOWN in parent_directions: return DIRECTION_DOWN return DIRECTION_UP def repulse(direction: int, fixed, moving, fixed_port_mode: int, moving_port_mode: int): ''' returns a qrect to be placed at side of fixed_rect where fixed_rect is an already determinated futur place for a box ''' if isinstance(fixed, CanvasBox): fixed_rect = fixed.boundingRect().translated(fixed.pos()) else: fixed_rect = fixed if isinstance(moving, CanvasBox): rect = moving.boundingRect().translated(moving.pos()) else: rect = moving assert direction in (DIRECTION_DOWN, DIRECTION_LEFT, DIRECTION_UP, DIRECTION_RIGHT) x = rect.left() y = rect.top() if direction in (DIRECTION_LEFT, DIRECTION_RIGHT): spacing = box_spacing if direction == DIRECTION_LEFT: if (fixed_port_mode & PORT_MODE_INPUT or moving_port_mode & PORT_MODE_OUTPUT): spacing = box_spacing_hor x = fixed_rect.left() - spacing - rect.width() if x < 0: x -= 1.0 x = float(int(x)) else: if (fixed_port_mode & PORT_MODE_OUTPUT or moving_port_mode & PORT_MODE_INPUT): spacing = box_spacing_hor x = fixed_rect.right() + spacing if x < 0: x -= 1.0 x = float(int(x + 0.99)) top_diff = abs(fixed_rect.top() - rect.top()) bottom_diff = abs(fixed_rect.bottom() - rect.bottom()) if bottom_diff > top_diff and top_diff <= magnet: y = fixed_rect.top() elif bottom_diff <= magnet: y = fixed_rect.bottom() - rect.height() elif direction in (DIRECTION_UP, DIRECTION_DOWN): if direction == DIRECTION_UP: y = fixed_rect.top() - box_spacing - rect.height() if y < 0: y -= 1.0 y = float(int(y)) else: y = fixed_rect.bottom() + box_spacing if y < 0: y -= 1.0 y = float(int(y + 0.99)) left_diff = abs(fixed_rect.left() - rect.left()) right_diff = abs(fixed_rect.right() - rect.right()) if right_diff > left_diff and left_diff <= magnet: x = fixed_rect.left() elif right_diff <= magnet: x = fixed_rect.right() - rect.width() return QRectF(x, y, rect.width(), rect.height()) def rect_has_to_move_from( repulser_rect, rect, repulser_port_mode: int, rect_port_mode: int)->bool: left_spacing = right_spacing = box_spacing if (repulser_port_mode & PORT_MODE_INPUT or rect_port_mode & PORT_MODE_OUTPUT): left_spacing = box_spacing_hor if (repulser_port_mode & PORT_MODE_OUTPUT or rect_port_mode & PORT_MODE_INPUT): right_spacing = box_spacing_hor large_repulser_rect = repulser_rect.adjusted( - left_spacing, - box_spacing, right_spacing, box_spacing) return rect.intersects(large_repulser_rect) to_move_boxes = [] repulsers = [] wanted_directions = [wanted_direction] for box in repulser_boxes: srect = box.boundingRect() if new_scene_rect is not None: srect = new_scene_rect else: # if box is already moving, consider its end position for box_dict in self.move_boxes: if box_dict['widget'] == box: srect.translate(QPoint(box_dict['to_x'], box_dict['to_y'])) break else: srect.translate(box.pos()) repulser = {'rect': srect, 'item': box} repulsers.append(repulser) items_to_move = [] for group in canvas.group_list: for widget in group.widgets: if (widget is None or widget in repulser_boxes or widget in [b['item'] for b in to_move_boxes] or widget in [b['widget'] for b in self.move_boxes]): continue irect = widget.boundingRect() irect.translate(widget.pos()) if rect_has_to_move_from( repulser['rect'], irect, repulser['item'].get_current_port_mode(), widget.get_current_port_mode()): items_to_move.append({'item': widget, 'rect': irect}) for box_dict in self.move_boxes: if (box_dict['widget'] in repulser_boxes or box_dict['widget'] in [b['item'] for b in to_move_boxes]): continue widget = box_dict['widget'] irect = widget.boundingRect() irect.translate(QPoint(box_dict['to_x'], box_dict['to_y'])) if rect_has_to_move_from( repulser['rect'], irect, repulser['item'].get_current_port_mode(), widget.get_current_port_mode()): items_to_move.append({'item': widget, 'rect': irect}) for item_to_move in items_to_move: item = item_to_move['item'] irect = item_to_move['rect'] # evaluate in which direction should go the box direction = get_direction(srect, irect, wanted_directions) to_move_box = { 'directions': [direction], 'pos': 0, 'item': item, 'repulser': repulser} # stock a position only for sorting reason if direction == DIRECTION_RIGHT: to_move_box['pos'] = irect.left() elif direction == DIRECTION_LEFT: to_move_box['pos'] = - irect.right() elif direction == DIRECTION_DOWN: to_move_box['pos'] = irect.top() elif direction == DIRECTION_UP: to_move_box['pos'] = - irect.bottom() to_move_boxes.append(to_move_box) # sort the list of dicts to_move_boxes = sorted(to_move_boxes, key = lambda d: d['pos']) to_move_boxes = sorted(to_move_boxes, key = lambda d: d['directions']) # the to_move_boxes list is dynamic # elements can be added to the list while iteration for to_move_box in to_move_boxes: item = to_move_box['item'] repulser = to_move_box['repulser'] ref_rect = repulser['rect'] irect = item.boundingRect().translated(item.pos()) directions = to_move_box['directions'].copy() new_direction = get_direction(repulser['rect'], irect, directions) directions.append(new_direction) # calculate the new position of the box repulsed by its repulser new_rect = repulse(new_direction, repulser['rect'], item, repulser['item'].m_current_port_mode, item.m_current_port_mode) active_repulsers = [] # while there is a repulser rect at new box position # move the future box position while True: # list just here to prevent infinite loop # we save the repulsers that already have moved the rect for repulser in repulsers: if rect_has_to_move_from( repulser['rect'], new_rect, repulser['item'].get_current_port_mode(), item.get_current_port_mode()): if repulser in active_repulsers: continue active_repulsers.append(repulser) new_direction = get_direction( repulser['rect'], new_rect, directions) new_rect = repulse( new_direction, repulser['rect'], new_rect, repulser['item'].m_current_port_mode, item.m_current_port_mode) directions.append(new_direction) break else: break # Now we know where the box will be definitely positioned # So, this is now a repulser for other boxes repulser = {'rect': new_rect, 'item': item} repulsers.append(repulser) # check which existing boxes exists at the new place of the box # and add them to this to_move_boxes iteration adding_list = [] for group in canvas.group_list: for widget in group.widgets: if (widget is None or widget in repulser_boxes or widget in [b['item'] for b in to_move_boxes] or widget in [b['widget'] for b in self.move_boxes]): continue mirect = widget.boundingRect().translated(widget.pos()) if rect_has_to_move_from( new_rect, mirect, to_move_box['item'].get_current_port_mode(), widget.get_current_port_mode()): adding_list.append( {'directions': directions, 'pos': mirect.right(), 'item': widget, 'repulser': repulser}) for box_dict in self.move_boxes: mitem = box_dict['widget'] if (mitem in repulser_boxes or mitem in [b['item'] for b in to_move_boxes]): continue rect = mitem.boundingRect() rect.translate(QPoint(box_dict['to_x'], box_dict['to_y'])) if rect_has_to_move_from( new_rect, rect, to_move_box['item'].get_current_port_mode(), mitem.get_current_port_mode()): adding_list.append( {'directions': directions, 'pos': 0, 'item': box_dict['widget'], 'repulser': repulser}) for to_move_box in adding_list: to_move_boxes.append(to_move_box) # now we decide where the box is moved pos_offset = item.boundingRect().topLeft() to_send_rect = new_rect.translated(- pos_offset) self.add_box_to_animation( item, to_send_rect.left(), to_send_rect.top()) def bring_neighbors_and_deplace_boxes(self, box_widget, new_scene_rect): neighbors = [box_widget] limit_top = box_widget.pos().y() for neighbor in neighbors: srect = neighbor.boundingRect() for move_box in self.move_boxes: if move_box['widget'] == neighbor: srect.translate(QPointF(move_box['to_x'], move_box['to_y'])) break else: srect.translate(neighbor.pos()) for item in self.items( srect.adjusted( 0, 0, 0, canvas.theme.box_spacing + 1)): if item not in neighbors and item.type() == CanvasBoxType: nrect = item.boundingRect().translated(item.pos()) if nrect.top() >= limit_top: neighbors.append(item) neighbors.remove(box_widget) less_y = box_widget.boundingRect().height() - new_scene_rect.height() repulser_boxes = [] for neighbor in neighbors: self.add_box_to_animation( neighbor, neighbor.pos().x(), neighbor.pos().y() - less_y) repulser_boxes.append(neighbor) repulser_boxes.append(box_widget) self.deplace_boxes_from_repulsers(repulser_boxes, wanted_direction=DIRECTION_UP) def center_view_on(self, widget): self.m_view.centerOn(widget) def removeItem(self, item): for child_item in item.childItems(): QGraphicsScene.removeItem(self, child_item) QGraphicsScene.removeItem(self, item) def updateLimits(self): w0 = canvas.size_rect.width() h0 = canvas.size_rect.height() w1 = self.m_view.width() h1 = self.m_view.height() self.m_scale_min = w1/w0 if w0/h0 > w1/h1 else h1/h0 def updateTheme(self): self.setBackgroundBrush(canvas.theme.canvas_bg) self.m_rubberband.setPen(canvas.theme.rubberband_pen) self.m_rubberband.setBrush(canvas.theme.rubberband_brush) cur_color = "black" if canvas.theme.canvas_bg.blackF() < 0.5 else "white" self.curCut = QCursor(QPixmap(":/cursors/cut-"+cur_color+".png"), 1, 1) self.curZoomArea = QCursor(QPixmap(":/cursors/zoom-area-"+cur_color+".png"), 8, 7) def get_new_scene_rect(self): first_pass = True for group in canvas.group_list: for widget in group.widgets: if widget is None or not widget.isVisible(): continue item_rect = widget.boundingRect().translated(widget.scenePos()) item_rect = item_rect.marginsAdded(QMarginsF(50, 20, 50, 20)) if first_pass: full_rect = item_rect else: full_rect = full_rect.united(item_rect) first_pass = False if not first_pass: return full_rect return QRectF() def resize_the_scene(self): if not options.elastic: return scene_rect = self.get_new_scene_rect() if not scene_rect.isNull(): self.resizing_scene = True self.setSceneRect(scene_rect) self.resizing_scene = False def set_elastic(self, yesno: bool): options.elastic = True self.resize_the_scene() options.elastic = yesno if not yesno: # resize the scene to a null QRectF to auto set sceneRect # always growing with items self.setSceneRect(QRectF()) # add a fake item with the current canvas scene size # (calculated with items), and remove it. fake_item = QGraphicsRectItem(self.get_new_scene_rect()) self.addItem(fake_item) self.update() self.removeItem(fake_item) def set_prevent_overlap(self, yesno: bool): options.prevent_overlap = yesno def zoom_ratio(self, percent: float): ratio = percent / 100.0 transform = self.m_view.transform() transform.reset() transform.scale(ratio, ratio) self.m_view.setTransform(transform) for group in canvas.group_list: for widget in group.widgets: if widget and widget.top_icon: widget.top_icon.update_zoom(ratio) def zoom_fit(self): min_x = min_y = max_x = max_y = None first_value = True items_list = self.items() if len(items_list) > 0: for item in items_list: if item and item.isVisible() and item.type() == CanvasBoxType: pos = item.scenePos() rect = item.boundingRect() x = pos.x() + rect.left() y = pos.y() + rect.top() if first_value: first_value = False min_x, min_y = x, y max_x = x + rect.width() max_y = y + rect.height() else: min_x = min(min_x, x) min_y = min(min_y, y) max_x = max(max_x, x + rect.width()) max_y = max(max_y, y + rect.height()) if not first_value: self.m_view.fitInView(min_x, min_y, abs(max_x - min_x), abs(max_y - min_y), Qt.KeepAspectRatio) self.fixScaleFactor() if self.m_view: self.scaleChanged.emit(self.m_view.transform().m11()) def zoom_in(self): view = self.m_view transform = view.transform() if transform.m11() < self.m_scale_max: transform.scale(1.2, 1.2) if transform.m11() > self.m_scale_max: transform.reset() transform.scale(self.m_scale_max, self.m_scale_max) view.setTransform(transform) self.scaleChanged.emit(transform.m11()) def zoom_out(self): view = self.m_view transform = view.transform() if transform.m11() > self.m_scale_min: transform.scale(0.833333333333333, 0.833333333333333) if transform.m11() < self.m_scale_min: transform.reset() transform.scale(self.m_scale_min, self.m_scale_min) view.setTransform(transform) self.scaleChanged.emit(transform.m11()) def zoom_reset(self): self.m_view.resetTransform() self.scaleChanged.emit(1.0) @pyqtSlot() def slot_selectionChanged(self): items_list = self.selectedItems() if len(items_list) == 0: self.pluginSelected.emit([]) return plugin_list = [] for item in items_list: if item and item.isVisible(): group_item = None if item.type() == CanvasBoxType: group_item = item elif item.type() == CanvasPortType: group_item = item.parentItem() #elif item.type() in (CanvasLineType, CanvasBezierLineType, CanvasLineMovType, CanvasBezierLineMovType): #plugin_list = [] #break if group_item is not None and group_item.m_plugin_id >= 0: plugin_id = group_item.m_plugin_id if plugin_id > MAX_PLUGIN_ID_ALLOWED: plugin_id = 0 plugin_list.append(plugin_id) self.pluginSelected.emit(plugin_list) def triggerRubberbandScale(self): self.m_scale_area = True if self.curZoomArea: self.m_view.viewport().setCursor(self.curZoomArea) def send_zoom_to_zoom_widget(self): if not self.m_view: return canvas.qobject.zoom_changed.emit(self.m_view.transform().m11() * 100) def get_zoom_scale(self): return self.m_view.transform().m11() def keyPressEvent(self, event): if not self.m_view: event.ignore() return if event.key() == Qt.Key_Control: if self.m_mid_button_down: self.startConnectionCut() elif event.key() == Qt.Key_Home: event.accept() self.zoom_fit() return elif QApplication.keyboardModifiers() & Qt.ControlModifier: if event.key() == Qt.Key_Plus: event.accept() self.zoom_in() return if event.key() == Qt.Key_Minus: event.accept() self.zoom_out() return if event.key() == Qt.Key_1: event.accept() self.zoom_reset() return QGraphicsScene.keyPressEvent(self, event) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Control: # Connection cut mode off if self.m_mid_button_down: self.m_view.viewport().unsetCursor() QGraphicsScene.keyReleaseEvent(self, event) def startConnectionCut(self): if self.curCut: self.m_view.viewport().setCursor(self.curCut) def zoom_wheel(self, delta): transform = self.m_view.transform() scale = transform.m11() if ((delta > 0 and scale < self.m_scale_max) or (delta < 0 and scale > self.m_scale_min)): # prevent too large unzoom if delta < 0: rect = self.sceneRect() top_left_vw = self.m_view.mapFromScene(rect.topLeft()) bottom_right_vw = self.m_view.mapFromScene(rect.bottomRight()) if (top_left_vw.x() > self.m_view.width() / 4 and top_left_vw.y() > self.m_view.height() / 4): return # Apply scale factor = 1.4142135623730951 ** (delta / 240.0) transform.scale(factor, factor) self.fixScaleFactor(transform) self.m_view.setTransform(transform) self.scaleChanged.emit(transform.m11()) # Update box icons especially when they are not scalable # eg. coming from theme for group in canvas.group_list: for widget in group.widgets: if widget and widget.top_icon: widget.top_icon.update_zoom(scale * factor) def mouseDoubleClickEvent(self, event): if event.button() == Qt.LeftButton: # parse items under mouse to prevent ACTION_DOUBLE_CLICK # if mouse is on a box items = self.items( event.scenePos(), Qt.ContainsItemShape, Qt.AscendingOrder) for item in items: if item.type() == CanvasBoxType: break else: canvas.callback(ACTION_DOUBLE_CLICK, 0, 0, "") return QGraphicsScene.mouseDoubleClickEvent(self, event) def mousePressEvent(self, event): self.m_mouse_down_init = ( (event.button() == Qt.LeftButton) or ((event.button() == Qt.RightButton) and QApplication.keyboardModifiers() & Qt.ControlModifier)) self.m_mouse_rubberband = False if (event.button() == Qt.MidButton and QApplication.keyboardModifiers() & Qt.ControlModifier): self.m_mid_button_down = True self.startConnectionCut() pos = event.scenePos() self.m_pointer_border.moveTo(floor(pos.x()), floor(pos.y())) items = self.items(self.m_pointer_border) for item in items: if item and item.type() in (CanvasLineType, CanvasBezierLineType, CanvasPortType): item.triggerDisconnect() QGraphicsScene.mousePressEvent(self, event) def mouseMoveEvent(self, event): if self.m_mouse_down_init: self.m_mouse_down_init = False topmost = self.itemAt(event.scenePos(), self.m_view.transform()) self.m_mouse_rubberband = not ( topmost and topmost.type() in (CanvasBoxType, CanvasIconType, CanvasPortType, CanvasPortGroupType)) if self.m_mouse_rubberband: event.accept() pos = event.scenePos() pos_x = pos.x() pos_y = pos.y() if not self.m_rubberband_selection: self.m_rubberband.show() self.m_rubberband_selection = True self.m_rubberband_orig_point = pos rubberband_orig_point = self.m_rubberband_orig_point x = min(pos_x, rubberband_orig_point.x()) y = min(pos_y, rubberband_orig_point.y()) lineHinting = canvas.theme.rubberband_pen.widthF() / 2 self.m_rubberband.setRect(x+lineHinting, y+lineHinting, abs(pos_x - rubberband_orig_point.x()), abs(pos_y - rubberband_orig_point.y())) return if (self.m_mid_button_down and QApplication.keyboardModifiers() & Qt.ControlModifier): trail = QPolygonF([event.scenePos(), event.lastScenePos(), event.scenePos()]) items = self.items(trail) for item in items: if item and item.type() in (CanvasLineType, CanvasBezierLineType): item.triggerDisconnect() QGraphicsScene.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): if self.m_scale_area and not self.m_rubberband_selection: self.m_scale_area = False self.m_view.viewport().unsetCursor() if self.m_rubberband_selection: if self.m_scale_area: self.m_scale_area = False self.m_view.viewport().unsetCursor() rect = self.m_rubberband.rect() self.m_view.fitInView(rect.x(), rect.y(), rect.width(), rect.height(), Qt.KeepAspectRatio) self.fixScaleFactor() else: items_list = self.items() for item in items_list: if item and item.isVisible() and item.type() == CanvasBoxType: item_rect = item.sceneBoundingRect() item_top_left = QPointF(item_rect.x(), item_rect.y()) item_bottom_right = QPointF(item_rect.x() + item_rect.width(), item_rect.y() + item_rect.height()) if self.m_rubberband.contains(item_top_left) and self.m_rubberband.contains(item_bottom_right): item.setSelected(True) self.m_rubberband.hide() self.m_rubberband.setRect(0, 0, 0, 0) self.m_rubberband_selection = False else: items_list = self.selectedItems() for item in items_list: if item and item.isVisible() and item.type() == CanvasBoxType: item.checkItemPos() self.sceneGroupMoved.emit(item.getGroupId(), item.getSplittedMode(), item.scenePos()) if len(items_list) > 1: self.update() self.m_mouse_down_init = False self.m_mouse_rubberband = False if event.button() == Qt.MidButton: event.accept() self.m_mid_button_down = False # Connection cut mode off if QApplication.keyboardModifiers() & Qt.ControlModifier: self.m_view.viewport().unsetCursor() return QGraphicsScene.mouseReleaseEvent(self, event) def wheelEvent(self, event): if not self.m_view: event.ignore() return if QApplication.keyboardModifiers() & Qt.ControlModifier: event.accept() self.zoom_wheel(event.delta()) return QGraphicsScene.wheelEvent(self, event) def contextMenuEvent(self, event): if QApplication.keyboardModifiers() & Qt.ControlModifier: event.accept() self.triggerRubberbandScale() return if len(self.selectedItems()) == 0: event.accept() x, y = event.screenPos().x(), event.screenPos().y() canvas.callback(ACTION_BG_RIGHT_CLICK, x, y, "") return QGraphicsScene.contextMenuEvent(self, event) # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/theme.py000066400000000000000000000765351417052567600212520ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas Themes # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from PyQt5.QtCore import Qt from PyQt5.QtGui import QColor, QFont, QPen, QPixmap # ------------------------------------------------------------------------------------------------------------ class Theme(object): # enum PortType THEME_PORT_SQUARE = 0 THEME_PORT_POLYGON = 1 # enum List THEME_SILVER_GOLD = 0 THEME_BLACK_GOLD = 1 THEME_MODERN_DARK = 2 THEME_MODERN_DARK_TINY = 3 THEME_MODERN_LIGHT = 4 THEME_CLASSIC_DARK = 5 THEME_OOSTUDIO = 6 THEME_MAX = 7 # enum BackgroundType THEME_BG_SOLID = 0 THEME_BG_GRADIENT = 1 def __init__(self, idx): object.__init__(self) self.idx = idx # don't manage different themes anymore with different sizes anymore # only color schemes and pen widths self.box_header_pixmap = None self.box_header_height = 36 self.box_header_spacing = 0 self.box_text_ypos = 20 self.box_text_hw = QPen(QColor(180, 180, 180), 0) self.box_pen_hw = QPen(QColor(56, 57, 58), 1, Qt.SolidLine) self.box_bg_type = self.THEME_BG_GRADIENT self.box_use_icon = True self.port_text_ypos = 12 self.port_bg_pixmap = None self.port_mode = self.THEME_PORT_POLYGON self.port_in_portgrp_width = 19 self.port_height = 16 self.port_offset = 0 self.port_spacing = 2 self.port_spacingT = 2 self.box_spacing = 4 self.box_spacing_hor = 24 self.magnet = 12 self.hardware_rack_width = 5 self.setTheme(idx) def setTheme(self, idx): if idx == self.THEME_SILVER_GOLD: # Canvas self.canvas_bg = QColor(0, 0, 0) # Boxes self.box_pen = QPen(QColor(76, 77, 78), 1, Qt.SolidLine) self.box_pen_sel = QPen(QColor(206, 207, 208), 1, Qt.DashLine) self.box_bg_1 = QColor(32, 34, 35) self.box_bg_2 = QColor(38, 40, 41) self.box_shadow = QColor(89, 89, 89, 180) self.box_text = QPen(QColor(240, 240, 240), 0) self.box_text_sel = self.box_text self.box_font_name = "Deja Vu Sans" self.box_font_size = 11 self.box_font_state = QFont.Bold # Ports self.port_text = QPen(QColor(48, 32, 0)) self.port_font_name = "Deja Vu Sans" self.port_font_size = 11 self.port_font_state = QFont.Normal self.port_audio_jack_pen = QPen(QColor(143, 119, 0), 1.4) self.port_audio_jack_pen_sel = self.port_audio_jack_pen self.port_midi_jack_pen = QPen(QColor(43, 23, 9), 1) self.port_midi_jack_pen_sel = self.port_midi_jack_pen self.port_midi_alsa_pen = QPen(QColor(93, 141, 46), 1) self.port_midi_alsa_pen_sel = QPen(QColor(93 + 30, 141 + 30, 46 + 30), 1) self.port_parameter_pen = QPen(QColor(137, 76, 43), 1) self.port_parameter_pen_sel = QPen(QColor(137 + 30, 76 + 30, 43 + 30), 1) self.port_cv_jack_pen = self.port_audio_jack_pen self.port_cv_jack_pen_sel = self.port_audio_jack_pen_sel self.port_audio_jack_bg = QColor(165, 165, 165) self.port_audio_jack_bg_sel = QColor(198, 161, 80) self.port_midi_jack_bg = QColor(77, 42, 16) self.port_midi_jack_bg_sel = QColor(160, 86, 33) self.port_midi_alsa_bg = QColor(64, 112, 18) self.port_midi_alsa_bg_sel = QColor(64 + 50, 112 + 50, 18 + 50) self.port_parameter_bg = QColor(101, 47, 16) self.port_parameter_bg_sel = QColor(101 + 50, 47 + 50, 16 + 50) self.port_cv_jack_bg = QColor(220, 220, 220) self.port_cv_jack_bg_sel = QColor(198, 161, 80) self.portgrp_audio_jack_pen = QPen(QColor(143, 119, 0), 1.4) self.portgrp_audio_jack_pen_sel = self.portgrp_audio_jack_pen self.portgrp_audio_jack_bg = QColor(185, 185, 185) self.portgrp_audio_jack_bg_sel = QColor(209, 170, 86) self.port_audio_jack_text = self.port_text self.port_audio_jack_text_sel = self.port_text self.port_midi_jack_text = QPen(QColor(255, 255, 150), 0) self.port_midi_jack_text_sel = self.port_midi_jack_text self.port_midi_alsa_text = self.port_text self.port_midi_alsa_text_sel = self.port_text self.port_parameter_text = self.port_text self.port_parameter_text_sel = self.port_text # Lines self.line_audio_jack = QColor(100, 100, 100) self.line_audio_jack_sel = QColor(198, 161, 80) self.line_audio_jack_glow = QColor(100, 100, 200) self.line_midi_jack = QColor(77, 42, 16) self.line_midi_jack_sel = QColor(160, 86, 33) self.line_midi_jack_glow = QColor(200, 100, 100) self.line_midi_alsa = QColor(93, 141, 46) self.line_midi_alsa_sel = QColor(93 + 90, 141 + 90, 46 + 90) self.line_midi_alsa_glow = QColor(100, 200, 100) self.line_parameter = QColor(137, 76, 43) self.line_parameter_sel = QColor(137 + 90, 76 + 90, 43 + 90) self.line_parameter_glow = QColor(166, 133, 133) self.rubberband_pen = QPen(QColor(206, 207, 208), 1, Qt.SolidLine) self.rubberband_brush = QColor(76, 77, 78, 100) if idx == self.THEME_BLACK_GOLD: # Canvas self.canvas_bg = QColor(0, 0, 0) # Boxes self.box_pen = QPen(QColor(76, 77, 78), 1, Qt.SolidLine) self.box_pen_sel = QPen(QColor(206, 207, 208), 1, Qt.DashLine) self.box_bg_1 = QColor(32, 34, 35) self.box_bg_2 = QColor(38, 40, 41) self.box_shadow = QColor(89, 89, 89, 180) self.box_text = QPen(QColor(210, 210, 210), 0) self.box_text_sel = self.box_text self.box_font_name = "Deja Vu Sans" self.box_font_size = 11 self.box_font_state = QFont.Bold # Ports self.port_text = QPen(QColor(200, 200, 200)) self.port_font_name = "Deja Vu Sans" self.port_font_size = 11 self.port_font_state = QFont.Normal self.port_audio_jack_pen = QPen(QColor(100, 81, 0), 1.0) self.port_audio_jack_pen_sel = self.port_audio_jack_pen self.port_midi_jack_pen = QPen(QColor(43, 23, 9), 1) self.port_midi_jack_pen_sel = self.port_midi_jack_pen self.port_midi_alsa_pen = QPen(QColor(93, 141, 46), 1) self.port_midi_alsa_pen_sel = QPen(QColor(93 + 30, 141 + 30, 46 + 30), 1) self.port_parameter_pen = QPen(QColor(137, 76, 43), 1) self.port_parameter_pen_sel = QPen(QColor(137 + 30, 76 + 30, 43 + 30), 1) self.port_cv_jack_pen = self.port_audio_jack_pen self.port_cv_jack_pen_sel = self.port_audio_jack_pen_sel self.port_audio_jack_bg = QColor(40, 40, 48) self.port_audio_jack_bg_sel = QColor(198, 161, 80) #self.port_audio_jack_bg_sel = QColor(60, 60, 72) self.port_midi_jack_bg = QColor(77, 42, 16) self.port_midi_jack_bg_sel = QColor(160, 86, 33) self.port_midi_alsa_bg = QColor(64, 112, 18) self.port_midi_alsa_bg_sel = QColor(64 + 50, 112 + 50, 18 + 50) self.port_parameter_bg = QColor(101, 47, 16) self.port_parameter_bg_sel = QColor(101 + 50, 47 + 50, 16 + 50) self.port_cv_jack_bg = QColor(20, 20, 25) self.port_cv_jack_bg_sel = QColor(198, 161, 80) self.portgrp_audio_jack_pen = QPen(QColor(100, 81, 0), 1.0) self.portgrp_audio_jack_pen_sel = self.portgrp_audio_jack_pen self.portgrp_audio_jack_bg = QColor(25, 25, 30) self.portgrp_audio_jack_bg_sel = QColor(209, 170, 86) #self.portgrp_audio_jack_bg_sel = QColor(60, 60, 72) self.port_audio_jack_text = self.port_text self.port_audio_jack_text_sel = QPen(QColor(0, 0, 0)) #self.port_audio_jack_text_sel = self.port_text self.port_midi_jack_text = QPen(QColor(255, 255, 150), 0) self.port_midi_jack_text_sel = self.port_midi_jack_text self.port_midi_alsa_text = self.port_text self.port_midi_alsa_text_sel = self.port_text self.port_parameter_text = self.port_text self.port_parameter_text_sel = self.port_text # Lines self.line_audio_jack = QColor(60, 60, 72) #self.line_audio_jack = QColor(80, 80, 96) #self.line_audio_jack_sel = QColor(100, 81, 0) self.line_audio_jack_sel = QColor(118, 118, 141) self.line_audio_jack_glow = QColor(100, 100, 200) self.line_midi_jack = QColor(77, 42, 16) self.line_midi_jack_sel = QColor(160, 86, 33) self.line_midi_jack_glow = QColor(200, 100, 100) self.line_midi_alsa = QColor(93, 141, 46) self.line_midi_alsa_sel = QColor(93 + 90, 141 + 90, 46 + 90) self.line_midi_alsa_glow = QColor(100, 200, 100) self.line_parameter = QColor(137, 76, 43) self.line_parameter_sel = QColor(137 + 90, 76 + 90, 43 + 90) self.line_parameter_glow = QColor(166, 133, 133) self.rubberband_pen = QPen(QColor(206, 207, 208), 1, Qt.SolidLine) self.rubberband_brush = QColor(76, 77, 78, 100) elif idx == self.THEME_MODERN_DARK: # Canvas self.canvas_bg = QColor(0, 0, 0) # Boxes self.box_pen = QPen(QColor(76, 77, 78), 1, Qt.SolidLine) self.box_pen_sel = QPen(QColor(206, 207, 208), 1, Qt.DashLine) self.box_bg_1 = QColor(32, 34, 35) self.box_bg_2 = QColor(38, 40, 41) self.box_shadow = QColor(89, 89, 89, 180) self.box_text = QPen(QColor(240, 240, 240), 0) self.box_text_sel = self.box_text self.box_font_name = "Deja Vu Sans" self.box_font_size = 11 self.box_font_state = QFont.Bold self.box_bg_type = self.THEME_BG_GRADIENT self.box_use_icon = True # Ports self.port_text = QPen(QColor(250, 250, 250), 0) self.port_font_name = "Deja Vu Sans" self.port_font_size = 11 self.port_font_state = QFont.Normal self.port_audio_jack_pen = QPen(QColor(63, 90, 126), 1) self.port_audio_jack_pen_sel = QPen(QColor(63 + 30, 90 + 30, 126 + 30), 1) self.port_midi_jack_pen = QPen(QColor(159, 44, 42), 1) self.port_midi_jack_pen_sel = QPen(QColor(159 + 30, 44 + 30, 42 + 30), 1) self.port_midi_alsa_pen = QPen(QColor(93, 141, 46), 1) self.port_midi_alsa_pen_sel = QPen(QColor(93 + 30, 141 + 30, 46 + 30), 1) self.port_parameter_pen = QPen(QColor(137, 76, 43), 1) self.port_parameter_pen_sel = QPen(QColor(137 + 30, 76 + 30, 43 + 30), 1) self.port_cv_jack_pen = self.port_audio_jack_pen self.port_cv_jack_pen_sel = self.port_audio_jack_pen_sel self.port_audio_jack_bg = QColor(35, 61, 99) self.port_audio_jack_bg_sel = QColor(35 + 50, 61 + 50, 99 + 50) self.port_midi_jack_bg = QColor(120, 15, 16) self.port_midi_jack_bg_sel = QColor(120 + 50, 15 + 50, 16 + 50) self.port_midi_alsa_bg = QColor(64, 112, 18) self.port_midi_alsa_bg_sel = QColor(64 + 50, 112 + 50, 18 + 50) self.port_parameter_bg = QColor(101, 47, 16) self.port_parameter_bg_sel = QColor(101 + 50, 47 + 50, 16 + 50) self.port_cv_jack_bg = QColor(18, 32, 50) self.port_cv_jack_bg_sel = self.port_audio_jack_bg_sel self.portgrp_audio_jack_pen = QPen(QColor(63, 90, 126), 1) self.portgrp_audio_jack_pen_sel = QPen(QColor(63 + 30, 90 + 30, 126 + 30), 1) self.portgrp_audio_jack_bg = QColor(26, 45, 71) self.portgrp_audio_jack_bg_sel = QColor(27 + 50, 47 + 50, 75 + 50) self.port_audio_jack_text = self.port_text self.port_audio_jack_text_sel = self.port_text self.port_midi_jack_text = self.port_text self.port_midi_jack_text_sel = self.port_text self.port_midi_alsa_text = self.port_text self.port_midi_alsa_text_sel = self.port_text self.port_parameter_text = self.port_text self.port_parameter_text_sel = self.port_text # Lines self.line_audio_jack = QColor(63, 90, 126) self.line_audio_jack_sel = QColor(63 + 90, 90 + 90, 126 + 90) self.line_audio_jack_glow = QColor(100, 100, 200) self.line_midi_jack = QColor(159, 44, 42) self.line_midi_jack_sel = QColor(159 + 90, 44 + 90, 42 + 90) self.line_midi_jack_glow = QColor(200, 100, 100) self.line_midi_alsa = QColor(93, 141, 46) self.line_midi_alsa_sel = QColor(93 + 90, 141 + 90, 46 + 90) self.line_midi_alsa_glow = QColor(100, 200, 100) self.line_parameter = QColor(137, 76, 43) self.line_parameter_sel = QColor(137 + 90, 76 + 90, 43 + 90) self.line_parameter_glow = QColor(166, 133, 133) self.rubberband_pen = QPen(QColor(206, 207, 208), 1, Qt.SolidLine) self.rubberband_brush = QColor(76, 77, 78, 100) elif idx == self.THEME_MODERN_DARK_TINY: # Canvas self.canvas_bg = QColor(0, 0, 0) # Boxes self.box_pen = QPen(QColor(76, 77, 78), 1, Qt.SolidLine) self.box_pen_sel = QPen(QColor(206, 207, 208), 1, Qt.DashLine) self.box_bg_1 = QColor(32, 34, 35) self.box_bg_2 = QColor(43, 47, 48) self.box_shadow = QColor(89, 89, 89, 180) self.box_header_pixmap = None self.box_header_height = 14 self.box_header_spacing = 0 self.box_text = QPen(QColor(240, 240, 240), 0) self.box_text_sel = self.box_text self.box_text_ypos = 10 self.box_font_name = "Deja Vu Sans" self.box_font_size = 10 self.box_font_state = QFont.Bold self.box_bg_type = self.THEME_BG_GRADIENT self.box_use_icon = False # Ports self.port_text = QPen(QColor(250, 250, 250), 0) self.port_text_ypos = 9 self.port_bg_pixmap = None self.port_font_name = "Deja Vu Sans" self.port_font_size = 9 self.port_font_state = QFont.Normal self.port_mode = self.THEME_PORT_POLYGON self.port_audio_jack_pen = QPen(QColor(63, 90, 126), 1) self.port_audio_jack_pen_sel = QPen(QColor(63 + 30, 90 + 30, 126 + 30), 1) self.port_midi_jack_pen = QPen(QColor(159, 44, 42), 1) self.port_midi_jack_pen_sel = QPen(QColor(159 + 30, 44 + 30, 42 + 30), 1) self.port_midi_alsa_pen = QPen(QColor(93, 141, 46), 1) self.port_midi_alsa_pen_sel = QPen(QColor(93 + 30, 141 + 30, 46 + 30), 1) self.port_parameter_pen = QPen(QColor(137, 76, 43), 1) self.port_parameter_pen_sel = QPen(QColor(137 + 30, 76 + 30, 43 + 30), 1) self.port_audio_jack_bg = QColor(35, 61, 99) self.port_audio_jack_bg_sel = QColor(35 + 50, 61 + 50, 99 + 50) self.port_midi_jack_bg = QColor(120, 15, 16) self.port_midi_jack_bg_sel = QColor(120 + 50, 15 + 50, 16 + 50) self.port_midi_alsa_bg = QColor(64, 112, 18) self.port_midi_alsa_bg_sel = QColor(64 + 50, 112 + 50, 18 + 50) self.port_parameter_bg = QColor(101, 47, 16) self.port_parameter_bg_sel = QColor(101 + 50, 47 + 50, 16 + 50) self.portgrp_audio_jack_pen = QPen(QColor(63, 90, 126), 1) self.portgrp_audio_jack_pen_sel = QPen(QColor(63 + 30, 90 + 30, 126 + 30), 1) self.portgrp_audio_jack_bg = QColor(27, 47, 75) self.portgrp_audio_jack_bg_sel = QColor(27 + 50, 47 + 50, 75 + 50) self.port_audio_jack_text = self.port_text self.port_audio_jack_text_sel = self.port_text self.port_midi_jack_text = self.port_text self.port_midi_jack_text_sel = self.port_text self.port_midi_alsa_text = self.port_text self.port_midi_alsa_text_sel = self.port_text self.port_parameter_text = self.port_text self.port_parameter_text_sel = self.port_text self.port_in_portgrp_width = 15 self.port_height = 12 self.port_offset = 0 self.port_spacing = 1 self.port_spacingT = 1 # Lines self.line_audio_jack = QColor(63, 90, 126) self.line_audio_jack_sel = QColor(63 + 90, 90 + 90, 126 + 90) self.line_audio_jack_glow = QColor(100, 100, 200) self.line_midi_jack = QColor(159, 44, 42) self.line_midi_jack_sel = QColor(159 + 90, 44 + 90, 42 + 90) self.line_midi_jack_glow = QColor(200, 100, 100) self.line_midi_alsa = QColor(93, 141, 46) self.line_midi_alsa_sel = QColor(93 + 90, 141 + 90, 46 + 90) self.line_midi_alsa_glow = QColor(100, 200, 100) self.line_parameter = QColor(137, 76, 43) self.line_parameter_sel = QColor(137 + 90, 76 + 90, 43 + 90) self.line_parameter_glow = QColor(166, 133, 133) self.rubberband_pen = QPen(QColor(206, 207, 208), 1, Qt.SolidLine) self.rubberband_brush = QColor(76, 77, 78, 100) elif idx == self.THEME_MODERN_LIGHT: # Canvas self.canvas_bg = QColor(248, 249, 250) # Boxes self.box_pen = QPen(QColor(176, 177, 178), 1, Qt.SolidLine) self.box_pen_sel = QPen(QColor(1, 2, 3), 2, Qt.DashLine) self.box_bg_1 = QColor(250, 250, 250) self.box_bg_2 = QColor(200, 200, 200) self.box_shadow = QColor(1, 1, 1, 100) self.box_header_pixmap = None self.box_header_height = 24 self.box_header_spacing = 0 self.box_text = QPen(QColor(1, 1, 1), 0) self.box_text_sel = self.box_text self.box_text_ypos = 16 self.box_font_name = "Ubuntu" self.box_font_size = 11 self.box_font_state = QFont.Bold self.box_bg_type = self.THEME_BG_GRADIENT self.box_use_icon = True # Ports self.port_text = QPen(QColor(255, 255, 255), 1) self.port_text_ypos = 12 self.port_bg_pixmap = None self.port_font_name = "Ubuntu" self.port_font_size = 11 self.port_font_state = QFont.Bold self.port_mode = self.THEME_PORT_POLYGON self.port_audio_jack_pen = QPen(QColor(103, 130, 166), 2) self.port_audio_jack_pen_sel = QPen(QColor(103 + 136, 190 + 130, 226 + 130), 1) self.port_midi_jack_pen = QPen(QColor(159, 44, 42), 1) self.port_midi_jack_pen_sel = QPen(QColor(90 + 30, 44 + 30, 42 + 30), 1) self.port_midi_alsa_pen = QPen(QColor(93, 141, 46), 1) self.port_midi_alsa_pen_sel = QPen(QColor(93 + 30, 141 + 30, 46 + 30), 1) self.port_parameter_pen = QPen(QColor(137, 76, 43), 1) self.port_parameter_pen_sel = QPen(QColor(137 + 30, 76 + 30, 43 + 30), 1) self.port_audio_jack_bg = QColor(0, 0, 180) self.port_audio_jack_bg_sel = QColor(135 + 150, 161 + 150, 199 + 150) self.port_midi_jack_bg = QColor(130, 15, 16) self.port_midi_jack_bg_sel = QColor(90 + 30, 15 + 50, 16 + 50) self.port_midi_alsa_bg = QColor(64, 112, 18) self.port_midi_alsa_bg_sel = QColor(64 + 50, 112 + 50, 18 + 50) self.port_parameter_bg = QColor(101, 47, 16) self.port_parameter_bg_sel = QColor(101 + 50, 47 + 50, 16 + 50) self.portgrp_audio_jack_pen = QPen(QColor(103, 130, 166), 2) self.portgrp_audio_jack_pen_sel = QPen(QColor(103 + 136, 190 + 130, 226 + 130), 1) self.portgrp_audio_jack_bg = QColor(0, 0, 120) self.portgrp_audio_jack_bg_sel = QColor(0 + 150, 0 + 150, 120 + 150) self.port_audio_jack_text = self.port_text self.port_audio_jack_text_sel = self.port_text self.port_midi_jack_text = self.port_text self.port_midi_jack_text_sel = self.port_text self.port_midi_alsa_text = self.port_text self.port_midi_alsa_text_sel = self.port_text self.port_parameter_text = self.port_text self.port_parameter_text_sel = self.port_text self.port_in_portgrp_width = 18 self.port_height = 16 self.port_offset = 0 self.port_spacing = 2 self.port_spacingT = 2 # Lines self.line_audio_jack = QColor(63, 90, 126) self.line_audio_jack_sel = QColor(63 + 63, 90 + 90, 126 + 90) self.line_audio_jack_glow = QColor(100, 100, 200) self.line_midi_jack = QColor(159, 44, 42) self.line_midi_jack_sel = QColor(159 + 44, 44 + 90, 42 + 90) self.line_midi_jack_glow = QColor(200, 100, 100) self.line_midi_alsa = QColor(93, 141, 46) self.line_midi_alsa_sel = QColor(93 + 90, 141 + 90, 46 + 90) self.line_midi_alsa_glow = QColor(100, 200, 100) self.line_parameter = QColor(137, 43, 43) self.line_parameter_sel = QColor(137 + 90, 76 + 90, 43 + 90) self.line_parameter_glow = QColor(166, 133, 133) self.rubberband_pen = QPen(QColor(206, 207, 208), 1, Qt.SolidLine) self.rubberband_brush = QColor(76, 77, 78, 100) elif idx == self.THEME_CLASSIC_DARK: # Canvas self.canvas_bg = QColor(0, 0, 0) # Boxes self.box_pen = QPen(QColor(147 - 70, 151 - 70, 143 - 70), 2, Qt.SolidLine) self.box_pen_sel = QPen(QColor(147, 151, 143), 2, Qt.DashLine) self.box_bg_1 = QColor(30, 34, 36) self.box_bg_2 = QColor(30, 34, 36) self.box_shadow = QColor(89, 89, 89, 180) self.box_header_pixmap = None self.box_header_height = 19 self.box_header_spacing = 0 self.box_text = QPen(QColor(255, 255, 255), 0) self.box_text_sel = self.box_text self.box_text_ypos = 12 self.box_font_name = "Sans" self.box_font_size = 12 self.box_font_state = QFont.Normal self.box_bg_type = self.THEME_BG_GRADIENT self.box_use_icon = False # Ports self.port_text = QPen(QColor(250, 250, 250), 0) self.port_text_ypos = 11 self.port_bg_pixmap = None self.port_font_name = "Sans" self.port_font_size = 11 self.port_font_state = QFont.Normal self.port_mode = self.THEME_PORT_SQUARE self.port_audio_jack_pen = QPen(QColor(35, 61, 99), Qt.NoPen, 0) self.port_audio_jack_pen_sel = QPen(QColor(255, 0, 0), Qt.NoPen, 0) self.port_midi_jack_pen = QPen(QColor(120, 15, 16), Qt.NoPen, 0) self.port_midi_jack_pen_sel = QPen(QColor(255, 0, 0), Qt.NoPen, 0) self.port_midi_alsa_pen = QPen(QColor(63, 112, 19), Qt.NoPen, 0) self.port_midi_alsa_pen_sel = QPen(QColor(255, 0, 0), Qt.NoPen, 0) self.port_parameter_pen = QPen(QColor(101, 47, 17), Qt.NoPen, 0) self.port_parameter_pen_sel = QPen(QColor(255, 0, 0), Qt.NoPen, 0) self.port_audio_jack_bg = QColor(35, 61, 99) self.port_audio_jack_bg_sel = QColor(255, 0, 0) self.port_midi_jack_bg = QColor(120, 15, 16) self.port_midi_jack_bg_sel = QColor(255, 0, 0) self.port_midi_alsa_bg = QColor(63, 112, 19) self.port_midi_alsa_bg_sel = QColor(255, 0, 0) self.port_parameter_bg = QColor(101, 47, 17) self.port_parameter_bg_sel = QColor(255, 0, 0) self.portgrp_audio_jack_pen = QPen(QColor(35, 61, 99), 0) self.portgrp_audio_jack_pen_sel = QPen(QColor(255, 0, 0), 0) self.portgrp_audio_jack_bg = QColor(27, 47, 75) self.portgrp_audio_jack_bg_sel = QColor(255, 0, 0) self.port_audio_jack_text = self.port_text self.port_audio_jack_text_sel = self.port_text self.port_midi_jack_text = self.port_text self.port_midi_jack_text_sel = self.port_text self.port_midi_alsa_text = self.port_text self.port_midi_alsa_text_sel = self.port_text self.port_parameter_text = self.port_text self.port_parameter_text_sel = self.port_text self.port_in_portgrp_width = 18 self.port_height = 14 self.port_offset = 0 self.port_spacing = 1 self.port_spacingT = 0 # Lines self.line_audio_jack = QColor(53, 78, 116) self.line_audio_jack_sel = QColor(255, 0, 0) self.line_audio_jack_glow = QColor(255, 0, 0) self.line_midi_jack = QColor(139, 32, 32) self.line_midi_jack_sel = QColor(255, 0, 0) self.line_midi_jack_glow = QColor(255, 0, 0) self.line_midi_alsa = QColor(81, 130, 36) self.line_midi_alsa_sel = QColor(255, 0, 0) self.line_midi_alsa_glow = QColor(255, 0, 0) self.line_parameter = QColor(120, 65, 33) self.line_parameter_sel = QColor(255, 0, 0) self.line_parameter_glow = QColor(255, 0, 0) self.rubberband_pen = QPen(QColor(147, 151, 143), 2, Qt.SolidLine) self.rubberband_brush = QColor(35, 61, 99, 100) elif idx == self.THEME_OOSTUDIO: # Canvas self.canvas_bg = QColor(11, 11, 11) # Boxes self.box_pen = QPen(QColor(76, 77, 78), 1, Qt.SolidLine) self.box_pen_sel = QPen(QColor(189, 122, 214), 1, Qt.DashLine) self.box_bg_1 = QColor(46, 46, 46) self.box_bg_2 = QColor(23, 23, 23) self.box_shadow = QColor(89, 89, 89, 180) self.box_header_pixmap = QPixmap(":/bitmaps/canvas/frame_node_header.png") self.box_header_height = 22 self.box_header_spacing = 6 self.box_text = QPen(QColor(144, 144, 144), 0) self.box_text_sel = QPen(QColor(189, 122, 214), 0) self.box_text_ypos = 16 self.box_font_name = "Deja Vu Sans" self.box_font_size = 11 self.box_font_state = QFont.Bold self.box_bg_type = self.THEME_BG_SOLID self.box_use_icon = False # Ports normalPortBG = QColor(46, 46, 46) selPortBG = QColor(23, 23, 23) self.port_text = QPen(QColor(155, 155, 155), 0) self.port_text_ypos = 14 self.port_bg_pixmap = QPixmap(":/bitmaps/canvas/frame_port_bg.png") self.port_font_name = "Deja Vu Sans" self.port_font_size = 11 self.port_font_state = QFont.Normal self.port_mode = self.THEME_PORT_SQUARE self.port_audio_jack_pen = QPen(selPortBG, 2) self.port_audio_jack_pen_sel = QPen(QColor(1, 230, 238), 1) self.port_midi_jack_pen = QPen(selPortBG, 2) self.port_midi_jack_pen_sel = QPen(QColor(252, 118, 118), 1) self.port_midi_alsa_pen = QPen(selPortBG, 2) self.port_midi_alsa_pen_sel = QPen(QColor(129, 244, 118), 0) self.port_parameter_pen = QPen(selPortBG, 2) self.port_parameter_pen_sel = QPen(QColor(137, 76, 43), 1) self.port_audio_jack_bg = normalPortBG self.port_audio_jack_bg_sel = selPortBG self.port_midi_jack_bg = normalPortBG self.port_midi_jack_bg_sel = selPortBG self.port_midi_alsa_bg = normalPortBG self.port_midi_alsa_bg_sel = selPortBG self.port_parameter_bg = normalPortBG self.port_parameter_bg_sel = selPortBG self.portgrp_audio_jack_pen = QPen(selPortBG, 2) self.portgrp_audio_jack_pen_sel = QPen(QColor(1, 230, 238), 1) self.portgrp_audio_jack_bg = normalPortBG self.portgrp_audio_jack_bg_sel = selPortBG self.port_audio_jack_text = self.port_text self.port_audio_jack_text_sel = self.port_audio_jack_pen_sel self.port_midi_jack_text = self.port_text self.port_midi_jack_text_sel = self.port_midi_jack_pen_sel self.port_midi_alsa_text = self.port_text self.port_midi_alsa_text_sel = self.port_midi_alsa_pen_sel self.port_parameter_text = self.port_text self.port_parameter_text_sel = self.port_parameter_pen_sel # missing, ports 2 self.port_in_portgrp_width = 18 self.port_height = 21 self.port_offset = 1 self.port_spacing = 3 self.port_spacingT = 0 # Lines self.line_audio_jack = QColor(64, 64, 64) self.line_audio_jack_sel = QColor(1, 230, 238) self.line_audio_jack_glow = QColor(100, 200, 100) self.line_midi_jack = QColor(64, 64, 64) self.line_midi_jack_sel = QColor(252, 118, 118) self.line_midi_jack_glow = QColor(200, 100, 100) self.line_midi_alsa = QColor(64, 64, 64) self.line_midi_alsa_sel = QColor(129, 244, 118) self.line_midi_alsa_glow = QColor(100, 200, 100) self.line_parameter = QColor(64, 64, 64) self.line_parameter_sel = QColor(137+90, 76+90, 43+90) self.line_parameter_glow = QColor(166, 133, 133) self.rubberband_pen = QPen(QColor(1, 230, 238), 2, Qt.SolidLine) self.rubberband_brush = QColor(90, 90, 90, 100) # ------------------------------------------------------------------------------------------------------------ def getDefaultTheme(): return Theme.THEME_BLACK_GOLD def getThemeName(idx): if idx == Theme.THEME_BLACK_GOLD: return "Black Gold" if idx == Theme.THEME_SILVER_GOLD: return "Silver Gold" if idx == Theme.THEME_MODERN_DARK: return "Modern Dark" if idx == Theme.THEME_MODERN_DARK_TINY: return "Modern Dark (Tiny)" if idx == Theme.THEME_MODERN_LIGHT: return "Modern Light" if idx == Theme.THEME_CLASSIC_DARK: return "Classic Dark" if idx == Theme.THEME_OOSTUDIO: return "OpenOctave Studio" return "" def getDefaultThemeName(): return "Silver Gold" # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/patchcanvas/utils.py000066400000000000000000000501001417052567600212640ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # PatchBay Canvas engine using QGraphicsView/Scene # Copyright (C) 2010-2019 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) import sys from PyQt5.QtCore import qCritical, QPointF, QTimer, QFile from PyQt5.QtGui import QIcon, QPalette # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) from . import (bool2str, canvas, CanvasBoxType, ICON_APPLICATION, ICON_CLIENT, ICON_HARDWARE, ICON_INTERNAL, PORT_MODE_NULL, PORT_MODE_INPUT, PORT_MODE_OUTPUT, ACTION_PORTS_CONNECT, ACTION_PORTS_DISCONNECT) from .canvasfadeanimation import CanvasFadeAnimation # ------------------------------------------------------------------------------------------------------------ def CanvasGetNewGroupPositions()->tuple: def get_middle_empty_positions(scene_rect)->tuple: if scene_rect.isNull(): return ((0, 200)) needed_x = 120 needed_y = 120 margin_x = 50 margin_y = 10 x = scene_rect.center().x() - needed_y / 2 y = scene_rect.top() + 20 y_list = [] min_top = scene_rect.bottom() max_bottom = scene_rect.top() for group in canvas.group_list: for widget in group.widgets: if widget is None: continue box_rect = widget.sceneBoundingRect() min_top = min(min_top, box_rect.top()) max_bottom = max(max_bottom, box_rect.bottom()) if box_rect.left() - needed_x <= x <= box_rect.right() + margin_x: y_list.append( (box_rect.top(), box_rect.bottom(), box_rect.left())) if not y_list: return (int(x), int(y)) y_list.sort() available_segments = [[min_top, max_bottom, x]] for box_top, box_bottom, box_left in y_list: for segment in available_segments: seg_top, seg_bottom, seg_left = segment if box_bottom <= seg_top or box_top >= seg_bottom: continue if box_top <= seg_top and box_bottom >= seg_bottom: available_segments.remove(segment) break if box_top > seg_top: segment[1] = box_top if box_bottom < seg_bottom: available_segments.insert( available_segments.index(segment) + 1, [box_bottom, seg_bottom, box_left]) break segment[0] = box_bottom if not available_segments: return (int(x), int(max_bottom + margin_y)) available_segments.sort() for seg_top, seg_bottom, seg_left in available_segments: if seg_bottom - seg_top >= 200: y = seg_top + margin_y x = seg_left break else: y = max_bottom + margin_y return (int(x), int(y)) rect = canvas.scene.get_new_scene_rect() if rect.isNull(): return ((200, 0), (400, 0), (0, 0)) y = rect.bottom() return (get_middle_empty_positions(rect), (400, int(y)), (0, int(y))) def CanvasGetNewGroupPos(horizontal): if canvas.debug: print("PatchCanvas::CanvasGetNewGroupPos(%s)" % bool2str(horizontal)) new_pos = QPointF(canvas.initial_pos) items = canvas.scene.items() break_loop = False while not break_loop: break_for = False for i, item in enumerate(items): if item and item.type() == CanvasBoxType: if item.sceneBoundingRect().contains(new_pos): if horizontal: new_pos += QPointF(item.boundingRect().width() + 15, 0) else: new_pos += QPointF(0, item.boundingRect().height() + 15) break_for = True break if i >= len(items) - 1 and not break_for: break_loop = True return new_pos def CanvasGetFullPortName(group_id, port_id): if canvas.debug: print("PatchCanvas::CanvasGetFullPortName(%i, %i)" % (group_id, port_id)) for port in canvas.port_list: if port.group_id == group_id and port.port_id == port_id: group_id = port.group_id for group in canvas.group_list: if group.group_id == group_id: return group.group_name + ":" + port.port_name break qCritical("PatchCanvas::CanvasGetFullPortName(%i, %i) - unable to find port" % (group_id, port_id)) return "" def CanvasGetPortConnectionList(group_id, port_id): if canvas.debug: print("PatchCanvas::CanvasGetPortConnectionList(%i, %i)" % (group_id, port_id)) conn_list = [] for connection in canvas.connection_list: if (connection.group_out_id == group_id and connection.port_out_id == port_id): conn_list.append((connection.connection_id, connection.group_in_id, connection.port_in_id)) elif (connection.group_in_id == group_id and connection.port_in_id == port_id): conn_list.append((connection.connection_id, connection.group_out_id, connection.port_out_id)) return conn_list def CanvasGetPortGroupPosition(group_id: int, port_id: int, portgrp_id: int)->tuple: if portgrp_id <= 0: return (0, 1) for portgrp in canvas.portgrp_list: if (portgrp.group_id == group_id and portgrp.portgrp_id == portgrp_id): for i in range(len(portgrp.port_id_list)): if port_id == portgrp.port_id_list[i]: return (i, len(portgrp.port_id_list)) return (0, 1) def CanvasGetPortGroupName(group_id: int, ports_ids_list: list)->str: # accept portgrp_id instead of ports_ids_list as second argument if isinstance(ports_ids_list, int): for portgrp in canvas.portgrp_list: if (portgrp.group_id == group_id and portgrp.portgrp_id == ports_ids_list): ports_ids_list = portgrp.port_id_list break ports_names = [] for port in canvas.port_list: if port.group_id == group_id and port.port_id in ports_ids_list: ports_names.append(port.port_name) if len(ports_names) < 2: return '' portgrp_name_ends = (' ', '_', '.', '-', '#', ':', 'out', 'in', 'Out', 'In', 'Output', 'Input', 'output', 'input') # set portgrp name portgrp_name = '' for c in ports_names[0]: for eachname in ports_names: if not eachname.startswith(portgrp_name + c): break else: portgrp_name += c # reduce portgrp name until it ends with one of the characters # in portgrp_name_ends if not portgrp_name.endswith((' AUX', '_AUX')): check = False while not check: for x in portgrp_name_ends: if portgrp_name.endswith(x): check = True break if len(portgrp_name) == 0 or portgrp_name in ports_names: check = True if not check: portgrp_name = portgrp_name[:-1] return portgrp_name def CanvasGetPortPrintName(group_id, port_id, portgrp_id): for portgrp in canvas.portgrp_list: if (portgrp.group_id == group_id and portgrp.portgrp_id == portgrp_id): portgrp_name = CanvasGetPortGroupName( group_id, portgrp.port_id_list) for port in canvas.port_list: if port.group_id == group_id and port.port_id == port_id: return port.port_name.replace(portgrp_name, '', 1) def CanvasGetPortGroupPortList(group_id: int, portgrp_id: int)->list: for portgrp in canvas.portgrp_list: if (portgrp.group_id == group_id and portgrp.portgrp_id == portgrp_id): return portgrp.port_id_list return [] def CanvasGetPortGroupFullName(group_id, portgrp_id): for portgrp in canvas.portgrp_list: if (portgrp.group_id == group_id and portgrp.portgrp_id == portgrp_id): group_name = "" for group in canvas.group_list: if group.group_id == group_id: group_name = group.group_name break else: return "" endofname = '' for port_id in portgrp.port_id_list: endofname += "%s/" % CanvasGetPortPrintName(group_id, port_id, portgrp.portgrp_id) portgrp_name = CanvasGetPortGroupName(group_id, portgrp.port_id_list) return "%s:%s %s" % (group_name, portgrp_name, endofname[:-1]) return "" def CanvasConnectionMatches(connection, group_id_1: int, port_ids_list_1: list, group_id_2: int, port_ids_list_2: list)->bool: if (connection.group_in_id == group_id_1 and connection.port_in_id in port_ids_list_1 and connection.group_out_id == group_id_2 and connection.port_out_id in port_ids_list_2): return True elif (connection.group_in_id == group_id_2 and connection.port_in_id in port_ids_list_2 and connection.group_out_id == group_id_1 and connection.port_out_id in port_ids_list_1): return True else: return False def CanvasConnectionConcerns(connection, group_id: int, port_ids_list: list)->bool: if (connection.group_in_id == group_id and connection.port_in_id in port_ids_list): return True elif (connection.group_out_id == group_id and connection.port_out_id in port_ids_list): return True else: return False def CanvasGetGroupIcon(group_id: int, port_mode: int): # port_mode is here reversed group_port_mode = PORT_MODE_INPUT if port_mode == PORT_MODE_INPUT: group_port_mode = PORT_MODE_OUTPUT for group in canvas.group_list: if group.group_id == group_id: if not group.split: group_port_mode = PORT_MODE_NULL return CanvasGetIcon( group.icon_type, group.icon_name, group_port_mode) return QIcon() def CanvasGetIcon(icon_type: int, icon_name: str, port_mode: int): if icon_type in (ICON_CLIENT, ICON_APPLICATION): icon = QIcon.fromTheme(icon_name) if icon.isNull(): for ext in ('svg', 'svgz', 'png'): filename = ":app_icons/%s.%s" % (icon_name, ext) if QFile.exists(filename): del icon icon = QIcon() icon.addFile(filename) break return icon icon = QIcon() if icon_type == ICON_HARDWARE: icon_file = ":/scalable/pb_hardware.svg" if icon_name == "a2j": icon_file = ":/scalable/DIN-5.svg" elif port_mode == PORT_MODE_INPUT: icon_file = ":/scalable/audio-headphones.svg" elif port_mode == PORT_MODE_OUTPUT: icon_file = ":/scalable/microphone.svg" icon.addFile(icon_file) elif icon_type == ICON_INTERNAL: icon.addFile(":/scalable/%s" % icon_name) return icon def CanvasConnectPorts(group_id_1: int, port_id_1: int, group_id_2: int, port_id_2:int): one_is_out = True for port in canvas.port_list: if port.group_id == group_id_1 and port.port_id == port_id_1: if port.port_mode != PORT_MODE_OUTPUT: one_is_out = False break elif port.group_id == group_id_2 and port.port_id == port_id_2: if port.port_mode == PORT_MODE_OUTPUT: one_is_out = False break else: sys.stderr.write( "PatchCanvas::CanvasConnectPorts, port not found %i:%i and %i:%i\n" % (group_id_1, port_id_1, group_id_2, port_id_2)) return string_to_send = "%i:%i:%i:%i" % (group_id_2, port_id_2, group_id_1, port_id_1) if one_is_out: string_to_send = "%i:%i:%i:%i" % (group_id_1, port_id_1, group_id_2, port_id_2) canvas.callback(ACTION_PORTS_CONNECT, 0, 0, string_to_send) def CanvasPortGroupConnectionState(group_id_1: int, port_id_list_1: list, group_id_2: int, port_id_list_2: list)->int: # returns # 0 if no connection # 1 if connection is irregular # 2 if connection is correct group_out_id = 0 group_in_id = 0 out_port_id_list = [] in_port_id_list = [] for port in canvas.port_list: if (port.group_id == group_id_1 and port.port_id in port_id_list_1): if port.port_mode == PORT_MODE_OUTPUT: out_port_id_list = port_id_list_1 group_out_id = group_id_1 else: in_port_id_list = port_id_list_1 group_in_id = group_id_1 elif (port.group_id == group_id_2 and port.port_id in port_id_list_2): if port.port_mode == PORT_MODE_OUTPUT: out_port_id_list = port_id_list_2 group_out_id = group_id_2 else: in_port_id_list = port_id_list_2 group_in_id = group_id_2 if not (out_port_id_list and in_port_id_list): return 0 has_connection = False miss_connection = False for out_index in range(len(out_port_id_list)): for in_index in range(len(in_port_id_list)): if (out_index % len(in_port_id_list) == in_index % len(out_port_id_list)): for connection in canvas.connection_list: if (connection.group_out_id == group_out_id and connection.port_out_id == out_port_id_list[out_index] and connection.group_in_id == group_in_id and connection.port_in_id == in_port_id_list[in_index]): has_connection = True break else: miss_connection = True else: for connection in canvas.connection_list: if (connection.group_out_id == group_out_id and connection.port_out_id == out_port_id_list[out_index] and connection.group_in_id == group_in_id and connection.port_in_id == in_port_id_list[in_index]): # irregular connection exists # we are sure connection is irregular return 1 if has_connection: if miss_connection: return 1 else: return 2 else: return 0 def CanvasConnectPortGroups(group_id_1: int, portgrp_id_1: int, group_id_2: int, portgrp_id_2: int, disconnect=False): group_out_id = 0 group_in_id = 0 out_port_id_list = [] in_port_id_list = [] for portgrp in canvas.portgrp_list: if (portgrp.group_id == group_id_1 and portgrp.portgrp_id == portgrp_id_1): if portgrp.port_mode == PORT_MODE_OUTPUT: group_out_id = group_id_1 out_port_id_list = portgrp.port_id_list else: group_in_id = group_id_1 in_port_id_list = portgrp.port_id_list elif (portgrp.group_id == group_id_2 and portgrp.portgrp_id == portgrp_id_2): if portgrp.port_mode == PORT_MODE_OUTPUT: group_out_id = group_id_2 out_port_id_list = portgrp.port_id_list else: group_in_id = group_id_2 in_port_id_list = portgrp.port_id_list if not (out_port_id_list and in_port_id_list): sys.stderr.write( "PatchCanvas::CanvasConnectPortGroups, empty port id list\n") return connected_indexes = [] # disconnect irregular connections for connection in canvas.connection_list: if (connection.group_out_id == group_out_id and connection.port_out_id in out_port_id_list and connection.group_in_id == group_in_id and connection.port_in_id in in_port_id_list): out_index = out_port_id_list.index(connection.port_out_id) in_index = in_port_id_list.index(connection.port_in_id) if (out_index % len(in_port_id_list) == in_index % len(out_port_id_list) and not disconnect): # remember this connection already exists # and has not to be remade connected_indexes.append((out_index, in_index)) else: canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, '') if disconnect: return # finally connect the ports for out_index in range(len(out_port_id_list)): for in_index in range(len(in_port_id_list)): if (out_index % len(in_port_id_list) == in_index % len(out_port_id_list) and (out_index, in_index) not in connected_indexes): canvas.callback( ACTION_PORTS_CONNECT, 0, 0, "%i:%i:%i:%i" % ( group_out_id, out_port_id_list[out_index], group_in_id, in_port_id_list[in_index])) def CanvasCallback(action, value1, value2, value_str): if canvas.debug: sys.stderr.write("PatchCanvas::CanvasCallback(%i, %i, %i, %s)\n" % (action, value1, value2, value_str.encode())) canvas.callback(action, value1, value2, value_str) def CanvasItemFX(item, show, destroy): if canvas.debug: print("PatchCanvas::CanvasItemFX(%s, %s, %s)" % (item, bool2str(show), bool2str(destroy))) # Check if the item already has an animation for animation in canvas.animation_list: if animation.item() == item: animation.forceStop() canvas.animation_list.remove(animation) del animation break animation = CanvasFadeAnimation(item, show) animation.setDuration(750 if show else 500) if show: animation.finished.connect(canvas.qobject.AnimationFinishedShow) else: if destroy: animation.finished.connect(canvas.qobject.AnimationFinishedDestroy) else: animation.finished.connect(canvas.qobject.AnimationFinishedHide) canvas.animation_list.append(animation) animation.start() def CanvasRemoveItemFX(item): if canvas.debug: print("PatchCanvas::CanvasRemoveItemFX(%s)" % item) if item.type() == CanvasBoxType: item.removeIconFromScene() canvas.scene.removeItem(item) del item QTimer.singleShot(0, canvas.scene.update) def is_dark_theme(widget)->bool: return bool( widget.palette().brush(QPalette.Active, QPalette.WindowText).color().lightness() > 128) # ------------------------------------------------------------------------------------------------------------ RaySession-0.12.2/src/gui/ray.py000077700000000000000000000000001417052567600212512../shared/ray.pyustar00rootroot00000000000000RaySession-0.12.2/src/gui/raysession.py000077500000000000000000000055011417052567600200400ustar00rootroot00000000000000#!/usr/bin/python3 -u #libs import signal import sys from PyQt5.QtWidgets import QApplication from PyQt5.QtGui import QIcon, QFontDatabase from PyQt5.QtCore import QLocale, QTranslator, QTimer, QLibraryInfo #local imports from gui_tools import ArgParser, CommandLineArgs, init_gui_tools, get_code_root from gui_server_thread import GuiServerThread from gui_session import SignaledSession import ray import resources_rc def signal_handler(sig, frame): if sig in (signal.SIGINT, signal.SIGTERM): if session.daemon_manager.launched_before: if (CommandLineArgs.under_nsm and session.server_status != ray.ServerStatus.OFF): session.main_win.terminate_request = True l_server = GuiServerThread.instance() if l_server: l_server.abort_session() else: session.daemon_manager.stop() return session.main_win.terminate_request = True session.daemon_manager.stop() if __name__ == '__main__': # set Qt Application app = QApplication(sys.argv) app.setApplicationName(ray.APP_TITLE) app.setApplicationVersion(ray.VERSION) app.setOrganizationName(ray.APP_TITLE) app.setWindowIcon(QIcon(':/scalable/%s.svg' % ray.APP_TITLE.lower())) app.setQuitOnLastWindowClosed(False) app.setDesktopFileName(ray.APP_TITLE.lower()) # with some themes (GNOME fedora 34) # QGroupBox are not really visible app.setStyleSheet("QGroupBox{background-color: #15888888}") ### Translation process locale = QLocale.system().name() app_translator = QTranslator() if app_translator.load(QLocale(), ray.APP_TITLE.lower(), '_', "%s/locale" % get_code_root()): app.installTranslator(app_translator) sys_translator = QTranslator() path_sys_translations = QLibraryInfo.location(QLibraryInfo.TranslationsPath) if sys_translator.load(QLocale(), 'qt', '_', path_sys_translations): app.installTranslator(sys_translator) QFontDatabase.addApplicationFont(":/fonts/Ubuntu-R.ttf") QFontDatabase.addApplicationFont(":fonts/Ubuntu-C.ttf") # get arguments parser = ArgParser() init_gui_tools() # Add raysession/src/bin to $PATH # to can use raysession after make, whitout install ray.add_self_bin_to_path() #connect signals signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) #needed for signals SIGINT, SIGTERM timer = QTimer() timer.start(200) timer.timeout.connect(lambda: None) #build session server = GuiServerThread() session = SignaledSession() app.exec() # TODO find something better, sometimes program never ends without. #time.sleep(0.002) server.stop() session.quit() del session del app RaySession-0.12.2/src/gui/snapshots_dialog.py000066400000000000000000000366211417052567600212060ustar00rootroot00000000000000from PyQt5.QtCore import Qt, QDateTime, QDate from PyQt5.QtWidgets import QDialogButtonBox, QTreeWidgetItem from child_dialogs import ChildDialog from gui_tools import _translate, RS import ui.list_snapshots import ui.snapshot_name import ui.snapshots_info GROUP_ELEMENT = 0 GROUP_DAY = 1 GROUP_MONTH = 2 GROUP_YEAR = 3 GROUP_MAIN = 4 class Snapshot: valid = False text = '' sub_type = GROUP_ELEMENT item = None before_rewind_to = '' date_time = None rewind_date_time = None session_name = "" label = '' rewind_label = '' ref = '' def __init__(self, date_time): self.date_time = date_time def __lt__(self, other): if not other.is_valid(): return True if not self.is_valid(): return False return self.date_time < other.date_time @staticmethod def new_from_snaptext(snaptext:str): time_str_full, line_change, rw_time_str_full_sess = \ snaptext.partition('\n') rw_time_str_full, line_change, session_name = \ rw_time_str_full_sess.partition('\n') time_str, two_points, label = time_str_full.partition(':') rw_time_str, two_points, rw_label = rw_time_str_full.partition(':') utc_date_time = QDateTime.fromString(time_str, 'yyyy_M_d_h_m_s') utc_rw_date_time = QDateTime.fromString(rw_time_str, 'yyyy_M_d_h_m_s') utc_date_time.setTimeSpec(Qt.OffsetFromUTC) utc_rw_date_time.setTimeSpec(Qt.OffsetFromUTC) date_time = None rw_date_time = None if utc_date_time.isValid(): date_time = utc_date_time.toLocalTime() if utc_rw_date_time.isValid(): rw_date_time = utc_rw_date_time.toLocalTime() snapshot = Snapshot(date_time) snapshot.text = snaptext snapshot.label = label snapshot.rewind_date_time = rw_date_time snapshot.rewind_label = rw_label snapshot.session_name = session_name return snapshot def year(self): return self.date_time.date().year() def month(self): return self.date_time.date().month() def day(self): return self.date_time.date().day() def is_valid(self): if not self.date_time: return False return self.date_time.isValid() def is_today(self): if not self.date_time: return False return bool(self.date_time.date() == QDate.currentDate()) def is_yesterday(self): if not self.date_time: return False return bool(self.date_time.date() == QDate.currentDate().addDays(-1)) def can_take(self, other): return False def add(self, other): pass def common_group(self, other): if not (self.is_valid() and other.is_valid()): return GROUP_MAIN common_group = GROUP_MAIN if self.year() == other.year(): common_group = GROUP_YEAR if self.month() == other.month(): common_group = GROUP_MONTH if self.day() == other.day(): common_group = GROUP_DAY if common_group <= self.sub_type: return self.sub_type +1 return common_group def make_item(self, sub_type): if self.is_today(): day_string = _translate('snapshots', 'Today') elif self.is_yesterday(): day_string = _translate('snapshots', 'Yesterday') elif self.is_valid(): day_string = self.date_time.toString('dddd d MMMM yyyy') if not self.is_valid(): display_text = self.text else: display_text = _translate('snapshots', "%s at %s") % ( day_string, self.date_time.toString('HH:mm')) if sub_type in (GROUP_YEAR, GROUP_MONTH): if not self.is_today() or self.is_yesterday(): day_string = self.date_time.toString('dddd d MMMM') display_text = _translate('snapshots', "%s at %s") % ( day_string, self.date_time.toString('HH:mm')) elif sub_type == GROUP_DAY: display_text = _translate('snapshots', "at %s") \ % self.date_time.toString('HH:mm') if self.rewind_date_time: display_text += '\n' display_text += _translate('snapshots', "before rewind to ") if self.rewind_label: display_text += self.rewind_label elif self.rewind_date_time.date() == self.date_time.date(): display_text += self.rewind_date_time.toString('hh:mm') elif (self.rewind_date_time.date().year() == self.date_time.date().year()): display_text += self.rewind_date_time.toString('d MMM hh:mm') else: display_text += self.rewind_date_time.toString('d MMM yyyy hh:mm') elif self.session_name: display_text += "\nsession name: %s" % self.session_name if self.label: display_text += "\n%s" % self.label item = QTreeWidgetItem([display_text]) item.setData(0, Qt.UserRole, self.text) return item class SnapGroup(Snapshot): def __init__(self, date_time=None, sub_type=GROUP_MAIN): Snapshot.__init__(self, date_time) self.sub_type = sub_type self.valid = True self.snapshots = [] def can_take(self, other): if self.sub_type <= other.sub_type: return False if self.sub_type == GROUP_MAIN: return True if self.year() != other.year(): return False if self.sub_type == GROUP_YEAR: return True if self.month() != other.month(): return False if self.sub_type == GROUP_MONTH: return True if self.day() != other.day(): return False return True def add(self, new_snapshot): if not new_snapshot.is_valid(): self.snapshots.append(new_snapshot) return if self.sub_type <= 1: # If this group (self) is a day group, just add this snapshot self.snapshots.append(new_snapshot) return for snapshot in self.snapshots: if snapshot.can_take(new_snapshot): # if a snapgroup can take this snapshot, # just add this snapshot to this snapgroup. snapshot.add(new_snapshot) return smallest_cg = self.sub_type # find the smallest common group with any other for snapshot in self.snapshots: common_group = snapshot.common_group(new_snapshot) if common_group < smallest_cg: smallest_cg = common_group # check if there are snaps not common # with the smallest common group find above (smallest_cg) for snapshot in self.snapshots: common_group = snapshot.common_group(new_snapshot) if common_group != smallest_cg: break else: # There is no snap outside of smallest_cg # but there are maybe others snapshots to group together cg_final = 0 compare_snap = Snapshot(None) for cg in (GROUP_DAY, GROUP_MONTH, GROUP_YEAR): if cg_final: break if cg >= smallest_cg: continue # compare all existing snapshots with all others for i in range(len(self.snapshots)): if cg_final: break compare_snap = self.snapshots[i] if compare_snap.sub_type >= cg: continue for j in range(len(self.snapshots)): if j <= i: # prevent compare to itself or already compared continue snapshot = self.snapshots[j] if snapshot.sub_type >= cg: continue if (snapshot.common_group(compare_snap) == cg and snapshot.common_group(new_snapshot) > cg): cg_final = cg break if cg_final: snap_group = SnapGroup(compare_snap.date_time, cg_final) self.add_group(snap_group) self.snapshots.append(new_snapshot) return # create group and add to this all snaps which have to. snap_group = SnapGroup(new_snapshot.date_time, smallest_cg) snap_group.add(new_snapshot) self.add_group(snap_group) def add_group(self, snap_group): to_rem = [] for i in range(len(self.snapshots)): snapshot = self.snapshots[i] if snap_group.can_take(snapshot): snap_group.add(snapshot) to_rem.append(i) to_rem.reverse() for i in to_rem: self.snapshots.__delitem__(i) self.snapshots.append(snap_group) def sort(self): for snapshot in self.snapshots: if snapshot.sub_type: snapshot.sort() self.snapshots.sort() self.snapshots.reverse() def make_item(self, sub_type=GROUP_MAIN): display_text = '' if self.sub_type == GROUP_MAIN: return None if not self.date_time: display_text = self.text elif self.sub_type == GROUP_YEAR: display_text = self.date_time.toString('yyyy') elif self.sub_type == GROUP_MONTH: display_text = self.date_time.toString('MMMM yyyy') elif self.sub_type == GROUP_DAY: display_text = self.date_time.toString('dddd d MMMM yyyy') if self.is_today(): display_text = _translate('snapshots', 'Today') elif self.is_yesterday(): display_text = _translate('snapshots', 'Yesterday') item = QTreeWidgetItem([display_text]) for snapshot in self.snapshots: sub_item = snapshot.make_item(self.sub_type) item.addChild(sub_item) # set this group item not selectable item.setFlags(item.flags() & ~Qt.ItemIsSelectable) return item class TakeSnapshotDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.snapshot_name.Ui_Dialog() self.ui.setupUi(self) self.ui.lineEdit.textChanged.connect(self._text_changed) self.ui.pushButtonSave.setEnabled(False) self.ui.pushButtonSnapshot.setEnabled(False) self._save_asked = False self.ui.pushButtonSave.clicked.connect(self._accept_with_save) def _text_changed(self, text): self.ui.pushButtonSave.setEnabled(bool(text)) self.ui.pushButtonSnapshot.setEnabled(bool(text)) def _accept_with_save(self): self._save_asked = True self.accept() def get_snapshot_name(self): return self.ui.lineEdit.text() def save_asked(self): return self._save_asked class SnapshotsDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.list_snapshots.Ui_Dialog() self.ui.setupUi(self) self._original_label = self.ui.label.text() self.signaler.reply_auto_snapshot.connect( self.ui.checkBoxAutoSnapshot.setChecked) self.signaler.snapshots_found.connect(self._add_snapshots) self.snapshots = [] self.main_snap_group = SnapGroup() self.ui.snapshotsList.setHeaderHidden(True) self.ui.snapshotsList.currentItemChanged.connect( self._current_item_changed) self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) def _current_item_changed(self, current, previous): self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(current and current.data(0, Qt.UserRole))) def _add_snapshots(self, snaptexts): if not snaptexts and not self.main_snap_group.snapshots: # Snapshot list finished without any snapshot self._no_snapshot_found() return for snaptext in snaptexts: if not snaptext: continue snapshot = Snapshot.new_from_snaptext(snaptext) self.main_snap_group.add(snapshot) self.main_snap_group.sort() self.ui.snapshotsList.clear() for snapshot in self.main_snap_group.snapshots: item = snapshot.make_item(GROUP_MAIN) self.ui.snapshotsList.addTopLevelItem(item) self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.ui.snapshotsList.clearSelection() def _no_snapshot_found(self): pass def get_selected_snapshot(self): item = self.ui.snapshotsList.currentItem() full_str = item.data(0, Qt.UserRole) snapshot_ref = full_str.partition('\n')[0].partition(':')[0] return snapshot_ref def showEvent(self, event): ChildDialog.showEvent(self, event) if RS.is_hidden(RS.HD_SnapshotsInfo): return info_dialog = SnapshotsInfoDialog(self) info_dialog.exec() if info_dialog.has_to_be_hidden_next_time(): RS.set_hidden(RS.HD_SnapshotsInfo) class SnapshotsInfoDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.snapshots_info.Ui_Dialog() self.ui.setupUi(self) def has_to_be_hidden_next_time(self): return self.ui.checkBox.isChecked() class SessionSnapshotsDialog(SnapshotsDialog): def __init__(self, parent): SnapshotsDialog.__init__(self, parent) self.ui.pushButtonSnapshotNow.clicked.connect(self._take_snapshot) self.to_daemon('/ray/session/list_snapshots') self.ui.checkBoxAutoSnapshot.stateChanged.connect( self._set_auto_snapshot) def _take_snapshot(self): dialog = TakeSnapshotDialog(self) dialog.exec() if dialog.result(): snapshot_label = dialog.get_snapshot_name() with_save = dialog.save_asked() self.to_daemon('/ray/session/take_snapshot', snapshot_label, int(with_save)) self.ui.snapshotsList.setVisible(True) self.ui.label.setText(self._original_label) def _set_auto_snapshot(self, bool_snapshot): self.to_daemon('/ray/session/set_auto_snapshot', int(bool_snapshot)) def _no_snapshot_found(self): self.ui.label.setText( _translate('snapshots', "This session does not contains any snapshot.")) self.ui.snapshotsList.setVisible(False) class ClientSnapshotsDialog(SnapshotsDialog): def __init__(self, parent, client): SnapshotsDialog.__init__(self, parent) self.ui.pushButtonSnapshotNow.hide() self.ui.checkBoxAutoSnapshot.hide() self.client = client self.to_daemon('/ray/client/list_snapshots', client.client_id) self.resize(0, 0) def _no_snapshot_found(self): self.ui.label.setText( _translate('snapshots', 'There is no existing snapshot for this client.')) self.ui.snapshotsList.setVisible(False) RaySession-0.12.2/src/gui/surclassed_widgets.py000066400000000000000000000376441417052567600215510ustar00rootroot00000000000000from PyQt5.QtWidgets import ( QLineEdit, QStackedWidget, QLabel, QToolButton, QFrame, QGraphicsView, QSplitter, QSplitterHandle, QSlider, QToolTip, QApplication, QProgressBar, QDialogButtonBox, QPushButton) from PyQt5.QtGui import (QFont, QFontDatabase, QFontMetrics, QPalette, QIcon, QCursor, QMouseEvent) from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QPoint, QPointF, QRectF, QSizeF import time import ray from gui_tools import is_dark_theme class RayHackButton(QToolButton): order_hack_visibility = pyqtSignal(bool) def __init__(self, parent): QToolButton.__init__(self, parent) basecolor = self.palette().base().color().name() textcolor = self.palette().buttonText().color().name() textdbcolor = self.palette().brush( QPalette.Disabled, QPalette.WindowText).color().name() style = "QToolButton{border-radius: 2px ;border-left: 1px solid " \ + "qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 " \ + textcolor + ", stop:0.35 " + basecolor + ", stop:0.75 " \ + basecolor + ", stop:1 " + textcolor + ")" \ + ";border-right: 1px solid " \ + "qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 " \ + textcolor + ", stop:0.25 " + basecolor + ", stop:0.75 " \ + basecolor + ", stop:1 " + textcolor + ")" \ + ";border-top: 1px solid " + textcolor \ + ";border-bottom : 1px solid " + textcolor \ + "; background-color: " + basecolor + "; font-size: 11px" + "}"\ + "QToolButton::checked{background-color: " \ + "qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 " \ + textcolor + ", stop:0.25 " + basecolor + ", stop:0.85 " \ + basecolor + ", stop:1 " + textcolor + ")" \ + "; margin-top: 0px; margin-left: 0px " + "}" \ + "QToolButton::disabled{;border-left: 1px solid " \ + "qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 " \ + textdbcolor + ", stop:0.25 " + basecolor + ", stop:0.75 " \ + basecolor + ", stop:1 " + textdbcolor + ")" \ + ";border-right: 1px solid " \ + "qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 " \ + textdbcolor + ", stop:0.25 " + basecolor + ", stop:0.75 " \ + basecolor + ", stop:1 " + textdbcolor + ")" \ + ";border-top: 1px solid " + textdbcolor \ + ";border-bottom : 1px solid " + textdbcolor \ + "; background-color: " + basecolor + "}" self.setStyleSheet(style) def mousePressEvent(self, event): self.order_hack_visibility.emit(not self.isChecked()) # and not toggle button, the client will emit a gui state that will # toggle this button class OpenSessionFilterBar(QLineEdit): up_down_pressed = pyqtSignal(int) key_event = pyqtSignal(object) def __init__(self, parent): QLineEdit.__init__(self) def keyPressEvent(self, event): if event.key() in (Qt.Key_Up, Qt.Key_Down): self.up_down_pressed.emit(event.key()) self.key_event.emit(event) QLineEdit.keyPressEvent(self, event) class CustomLineEdit(QLineEdit): def __init__(self, parent): QLineEdit.__init__(self) self.parent = parent def mouseDoubleClickEvent(self, event): self.parent.mouseDoubleClickEvent(event) def keyPressEvent(self, event): if event.key() in (Qt.Key_Enter, Qt.Key_Return): self.parent.name_changed.emit(self.text()) self.parent.setCurrentIndex(0) return QLineEdit.keyPressEvent(self, event) class SessionFrame(QFrame): frame_resized = pyqtSignal() def __init__(self, parent): QFrame.__init__(self) def resizeEvent(self, event): QFrame.resizeEvent(self, event) self.frame_resized.emit() class StackedSessionName(QStackedWidget): name_changed = pyqtSignal(str) def __init__(self, parent): QStackedWidget.__init__(self) self._is_editable = True self._label_widget = QLabel() self._label_widget.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self._label_widget.setStyleSheet("QLabel {font-weight : bold}") self._line_edit_widget = CustomLineEdit(self) self._line_edit_widget.setAlignment(Qt.AlignHCenter) self.addWidget(self._label_widget) self.addWidget(self._line_edit_widget) self.setCurrentIndex(0) def mouseDoubleClickEvent(self, event): if self.currentIndex() == 1: self.setCurrentIndex(0) self.name_changed.emit(self._line_edit_widget.text()) return if self.currentIndex() == 0 and self._is_editable: self.setCurrentIndex(1) self._line_edit_widget.setText(self._label_widget.text()) self._line_edit_widget.selectAll() return QStackedWidget.mouseDoubleClickEvent(self, event) def set_editable(self, yesno: bool): self._is_editable = yesno if not yesno: self.setCurrentIndex(0) def set_text(self, text: str): self._label_widget.setText(text) self._line_edit_widget.setText(text) self.setCurrentIndex(0) def toggle_edit(self): if not self._is_editable: self.setCurrentIndex(0) return if self.currentIndex() == 0: self.setCurrentIndex(1) self._line_edit_widget.setFocus(Qt.OtherFocusReason) else: self.setCurrentIndex(0) def set_on_edit(self): if not self._is_editable: return self.setCurrentIndex(1) class StatusBar(QLineEdit): status_pressed = pyqtSignal() def __init__(self, parent): QLineEdit.__init__(self) self._next_texts = [] self._timer = QTimer() self._timer.setInterval(350) self._timer.timeout.connect(self._show_next_text) self._ubuntu_font = QFont( QFontDatabase.applicationFontFamilies(0)[0], 8) self._ubuntu_font_cond = QFont( QFontDatabase.applicationFontFamilies(1)[0], 8) self._ubuntu_font.setBold(True) self._ubuntu_font_cond.setBold(True) self._basecolor = self.palette().base().color().name() self._bluecolor = self.palette().highlight().color().name() self._last_status_time = 0.0 # ui_client_slot.py will display "stopped" status. # we need to not stay on this status text # especially at client switch because widget is recreated. self._first_text_done = False def _show_next_text(self): if self._next_texts: if len(self._next_texts) >= 4: interval = int(1000 / len(self._next_texts)) self._timer.setInterval(interval) elif len(self._next_texts) == 3: self._timer.setInterval(350) self.setText(self._next_texts.pop(0), True) else: self._timer.stop() def _set_font_for_text(self, text): if QFontMetrics(self._ubuntu_font).width(text) >= (self.width() - 16): self.setFont(self._ubuntu_font_cond) else: self.setFont(self._ubuntu_font) def setText(self, text, from_timer=False): self._last_status_time = time.time() if not self._first_text_done: self._set_font_for_text(text) QLineEdit.setText(self, text) self._first_text_done = True return if text and not from_timer: if self._timer.isActive(): self._next_texts.append(text) return self._timer.start() if not text: self._next_texts.clear() self._set_font_for_text(text) self.setStyleSheet('') QLineEdit.setText(self, text) def set_progress(self, progress: float): if not 0.0 <= progress <= 1.0: return # no progress display in the first second if time.time() - self._last_status_time < 1.0: return pre_progress = progress - 0.03 if pre_progress < 0: pre_progress = 0 style = "QLineEdit{background-color: " \ + "qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0," \ + "stop:0 %s, stop:%f %s, stop:%f %s, stop:1 %s)}" \ % (self._bluecolor, pre_progress, self._bluecolor, progress, self._basecolor, self._basecolor) self.setStyleSheet(style) def mousePressEvent(self, event): self.status_pressed.emit() class StatusBarNegativ(StatusBar): def __init__(self, parent): StatusBar.__init__(self, parent) class FakeToolButton(QToolButton): def __init__(self, parent): QToolButton.__init__(self, parent) self.setStyleSheet("QToolButton{border:none}") def mousePressEvent(self, event): self.parent().mousePressEvent(event) class FavoriteToolButton(QToolButton): def __init__(self, parent): QToolButton.__init__(self, parent) self._template_name = "" self._template_icon = "" self._factory = True self._state = False self._favicon_not = QIcon(':scalable/breeze/draw-star.svg') self._favicon_yes = QIcon(':scalable/breeze/star-yellow.svg') self.session = None self.setIcon(self._favicon_not) def set_dark_theme(self): self._favicon_not = QIcon(':scalable/breeze-dark/draw-star.svg') if not self._state: self.setIcon(self._favicon_not) def set_session(self, session): self.session = session def set_template(self, template_name: str, template_icon: str, factory: bool): self._template_name = template_name self._template_icon = template_icon self._factory = factory def set_as_favorite(self, yesno: bool): self._state = yesno self.setIcon(self._favicon_yes if yesno else self._favicon_not) def mouseReleaseEvent(self, event): QToolButton.mouseReleaseEvent(self, event) if self.session is None: return if self._state: self.session.remove_favorite(self._template_name, self._factory) else: self.session.add_favorite( self._template_name, self._template_icon, self._factory) # taken from carla (falktx) class DraggableGraphicsView(QGraphicsView): def __init__(self, parent): QGraphicsView.__init__(self, parent) self._panning = False try: self._middle_button = Qt.MiddleButton except: self._middle_button = Qt.MidButton def mousePressEvent(self, event): if (event.button() == self._middle_button and not QApplication.keyboardModifiers() & Qt.ControlModifier): self._panning = True self.setDragMode(QGraphicsView.ScrollHandDrag) event = QMouseEvent(event.type(), event.pos(), Qt.LeftButton, Qt.LeftButton, event.modifiers()) QGraphicsView.mousePressEvent(self, event) def mouseReleaseEvent(self, event): QGraphicsView.mouseReleaseEvent(self, event) if not self._panning: return self._panning = False self.setDragMode(QGraphicsView.NoDrag) self.setCursor(QCursor(Qt.ArrowCursor)) class CanvasSplitterHandle(QSplitterHandle): def __init__(self, parent): QSplitterHandle.__init__(self, Qt.Horizontal, parent) self._default_cursor = self.cursor() self._active = True def set_active(self, yesno: bool): self._active = yesno if yesno: self.setCursor(self._default_cursor) else: self.unsetCursor() def mouseMoveEvent(self, event): if not self._active: return QSplitterHandle.mouseMoveEvent(self, event) class CanvasSplitter(QSplitter): def __init__(self, parent): QSplitter.__init__(self, parent) def set_active(self, yesno: bool): handle = self.handle(1) if handle: handle.set_active(yesno) def createHandle(self): return CanvasSplitterHandle(self) class ZoomSlider(QSlider): zoom_fit_asked = pyqtSignal() def __init__(self, parent): QSlider.__init__(self, parent) @staticmethod def map_float_to(x, min_a, max_a, min_b, max_b): if max_a == min_a: return min_b return min_b + ((x - min_a) / (max_a - min_a)) * (max_b - min_b) def _show_tool_tip(self): win = QApplication.activeWindow() if win and win.isFullScreen(): return string = " Zoom: %i%% " % int(self.zoom_percent()) QToolTip.showText(self.mapToGlobal(QPoint(0, 12)), string) def zoom_percent(self)->int: percent = 100.0 if self.value() <= 500: percent = self.map_float_to(self.value(), 0, 500, 20, 100) else: percent = self.map_float_to(self.value(), 500, 1000, 100, 300) return percent def set_percent(self, percent: float): if 99.99999 < percent < 100.00001: self.setValue(500) elif percent < 100: self.setValue(int(self.map_float_to(percent, 20, 100, 0, 500))) else: self.setValue(int(self.map_float_to(percent, 100, 300, 500, 1000))) self._show_tool_tip() def mouseDoubleClickEvent(self, event): self.zoom_fit_asked.emit() def contextMenuEvent(self, event): self.setValue(500) self._show_tool_tip() def wheelEvent(self, event): direction = 1 if event.angleDelta().y() > 0 else -1 if QApplication.keyboardModifiers() & Qt.ControlModifier: self.set_percent(self.zoom_percent() + direction) else: self.set_percent(self.zoom_percent() + direction * 5) #QSlider.wheelEvent(self, event) self._show_tool_tip() def mouseMoveEvent(self, event): QSlider.mouseMoveEvent(self, event) self._show_tool_tip() class ProgressBarDsp(QProgressBar): def __init__(self, parent): QProgressBar.__init__(self) def setValue(self, value): color_border = "rgba(%i%%, %i%%, 0, 55%%)" % (value, 100 - value) color_center = "rgba(%i%%, %i%%, 0, 45%%)" % (value, 100 - value) self.setStyleSheet( "QProgressBar:chunk{background-color: " + "qlineargradient(x1:0, y1:0, x2:0, y1:1, " + "stop:0 " + color_border + ',' + "stop:0.5 " + color_center + ',' + "stop:1 " + color_border + ',' + ')}') QProgressBar.setValue(self, value) class StartupDialogButtonBox(QDialogButtonBox): key_event = pyqtSignal(object) def __init__(self, parent): QDialogButtonBox.__init__(self, parent) def keyPressEvent(self, event): if event.key in (Qt.Key_Up, Qt.Key_Down): self.key_event.emit(event) return QDialogButtonBox.keyPressEvent(self, event) class StartupDialogPushButtonNew(QPushButton): focus_on_list = pyqtSignal() focus_on_open = pyqtSignal() def __init__(self, parent): QPushButton.__init__(self, parent) def keyPressEvent(self, event): if event.key() in (Qt.Key_Down, Qt.Key_Up): self.focus_on_open.emit() return if event.key() in (Qt.Key_Left, Qt.Key_Right): self.focus_on_list.emit() return QPushButton.keyPressEvent(self, event) class StartupDialogPushButtonOpen(StartupDialogPushButtonNew): focus_on_new = pyqtSignal() def __init__(self, parent): StartupDialogPushButtonNew.__init__(self, parent) def keyPressEvent(self, event): if event.key() in (Qt.Key_Down, Qt.Key_Up): self.focus_on_new.emit() return StartupDialogPushButtonNew.keyPressEvent(self, event) class PreviewFrame(QFrame): def __init__(self, parent): QFrame.__init__(self, parent) RaySession-0.12.2/src/gui/utility_scripts.py000066400000000000000000000242151417052567600211130ustar00rootroot00000000000000 import os import shutil import sys from PyQt5.QtWidgets import (QApplication, QFileDialog, QMessageBox, QPushButton, QDialogButtonBox) from PyQt5.QtGui import QIcon from PyQt5.QtCore import QProcess, QProcessEnvironment, Qt import ray from gui_tools import CommandLineArgs, RS from open_session_dialog import OpenSessionDialog from child_dialogs import ChildDialog import ui.ardour_convert import ui.hydro_rh_nsm import ui.ray_to_nsm _translate = QApplication.translate class ArdourConversionDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.ardour_convert.Ui_Dialog() self.ui.setupUi(self) def not_again_value(self)->bool: return self.ui.checkBoxNotAgain.isChecked() class HydrogenRhNsmDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.hydro_rh_nsm.Ui_Dialog() self.ui.setupUi(self) self.ui.checkBoxCurrentSession.stateChanged.connect( self._current_session_check) self._check_boxes = (self.ui.checkBoxAllSessions, self.ui.checkBoxClientTemplates, self.ui.checkBoxSessionTemplates) for check_box in self._check_boxes: check_box.stateChanged.connect(self._one_state_changed) if self.session.server_status != ray.ServerStatus.READY: self.ui.checkBoxCurrentSession.setEnabled(False) def _current_session_check(self, state:bool): for check_box in self._check_boxes: check_box.setEnabled(not state) def _one_state_changed(self): for check_box in self._check_boxes: if check_box.isChecked(): break else: for check_box in self._check_boxes: check_box.setChecked(True) def get_check_arguments(self)->list: args = [] if self.ui.checkBoxCurrentSession.isChecked(): return args if self.ui.checkBoxAllSessions.isChecked(): args.append('sessions') if self.ui.checkBoxClientTemplates.isChecked(): args.append('client_templates') if self.ui.checkBoxSessionTemplates.isChecked(): args.append('session_templates') return args def rename_for_other_app(self, name:str): self.ui.label.setText(self.ui.label.text().replace('Hydrogen', name)) class RayToNsmDialog(ChildDialog): def __init__(self, parent): ChildDialog.__init__(self, parent) self.ui = ui.ray_to_nsm.Ui_Dialog() self.ui.setupUi(self) self.choose_current_session = False #self.choose_session choose_button = self.ui.buttonBox.addButton( _translate('utilities', 'Choose a session'), QDialogButtonBox.AcceptRole) choose_button.setIcon(QIcon.fromTheme('folder-open')) this_session_button = self.ui.buttonBox.addButton( _translate('utilities', 'Convert the current session'), QDialogButtonBox.AcceptRole) if not self.session.path: this_session_button.setVisible(False) this_session_button.clicked.connect( self._set_on_choose_current_session) def _set_on_choose_current_session(self): self.choose_current_session = True def get_check_arguments(self)->list: if self.ui.checkBoxJackPatch.isChecked(): return ['--replace-jackpatch'] return [''] class UtilityScriptLauncher: def __init__(self, main_win, session): self.daemon_manager = session.daemon_manager self.main_win = main_win self._process = QProcess() def _which_terminal(self, title='')->list: """ returns the most appropriate terminal executable with its arguments """ terminals = ['gnome-terminal', 'mate-terminal', 'xfce4-terminal', 'xterm', 'konsole', 'lxterminal', 'rxvt'] current_desktop = os.getenv('XDG_CURRENT_DESKTOP') terminal = '' # make prior most appropriate terminal if current_desktop == 'GNOME': pass elif current_desktop == 'KDE': terminals.remove('konsole') terminals.insert(0, 'konsole') elif current_desktop == 'MATE': terminals.remove('mate-terminal') terminals.insert(0, 'mate-terminal') elif current_desktop == 'XFCE': terminals.remove('xfce4-terminal') terminals.insert(0, 'xfce4-terminal') terminals.insert(0, 'xfce-terminal') elif current_desktop == 'LXDE': terminals.remove('lxterminal') terminals.insert(0, 'lxterminal') # search executable for terminals for term in terminals: if shutil.which(term): terminal = term break else: return [] if terminal == 'gnome-terminal': return [terminal, '--hide-menubar', '--'] if terminal == 'konsole': if title: return [terminal, '--hide-tabbar', '--hide-menubar', '-p', "tabtitle=%s" % title, '-e'] return [terminal, '--hide-tabbar', '--hide-menubar', '-e'] if terminal == 'mate-terminal': if title: return [terminal, '--hide-menubar', '--title', title, '--'] return [terminal, '--hide-menubar', '--'] if terminal == 'xfce4-terminal': if title: return [terminal, '--hide-menubar', '--hide-toolbar', '-T', title, '-e'] return [terminal, '--hide-menubar', '--hide-toolbar', '-e'] return [terminal, '-e'] def _get_scripts_path(self)->str: code_root = os.path.dirname( os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) return os.path.join(code_root, 'utility-scripts') def _start_process(self, script_name, terminal_title, *args): if not self.daemon_manager.is_local or CommandLineArgs.under_nsm: # utility scripts are not available if daemon is not # on the same machine, or if current session is a subsession return if self._process.state(): QMessageBox.critical( self.main_win, _translate('utilities', 'Other script running'), _translate('utilities', "An utility script is already running,\n" "please close its terminal and start again !")) return process_env = QProcessEnvironment.systemEnvironment() process_env.insert( 'RAY_CONTROL_PORT', str(self.daemon_manager.get_port())) self._process.setProcessEnvironment(process_env) terminal_args = self._which_terminal(terminal_title) if not terminal_args: return full_script_path = os.path.join(self._get_scripts_path(), script_name) terminal = terminal_args.pop(0) self._process.setProgram(terminal) self._process.setArguments( terminal_args + ["utility_script_keeper.sh", full_script_path] + list(args)) self._process.start() def convert_ardour_to_session(self): script_name = 'ardour_from_external_to_session.sh' terminal_title = _translate('utilities', 'Convert Ardour session to Ray') if not RS.is_hidden(RS.HD_ArdourConversion): dialog = ArdourConversionDialog(self.main_win) dialog.exec() if not dialog.result(): return if dialog.not_again_value(): RS.set_hidden(RS.HD_ArdourConversion) ardour_session , filter = QFileDialog.getOpenFileName( self.main_win, _translate('utilities', "Choose an Ardour session to convert..."), os.getenv('HOME'), _translate('utilities', "Ardour sessions (*.ardour)")) if not ardour_session: return executable = "ardour" if not shutil.which(executable): for i in range(9, 5, -1): if shutil.which("ardour%i" % i): executable = "ardour%i" % i break if shutil.which("Ardour%i" % i): executable = "Ardour%i" % i break args = ["--executable", executable, ardour_session] self._start_process(script_name, terminal_title, *args) def convert_ray_hack_to_nsm_hydrogen(self): script_name = 'all_ray_hack_to_nsm_hydrogen.sh' terminal_title = _translate('utilities', 'Hydrogen Ray-Hack->NSM') dialog = HydrogenRhNsmDialog(self.main_win) dialog.exec() if not dialog.result(): return args = dialog.get_check_arguments() self._start_process(script_name, terminal_title, *args) def convert_ray_hack_to_nsm_jack_mixer(self): script_name = 'all_ray_hack_to_nsm_jack_mixer.sh' terminal_title = _translate('utilities', 'Jack Mixer Ray-Hack->NSM') dialog = HydrogenRhNsmDialog(self.main_win) dialog.rename_for_other_app('Jack Mixer') dialog.exec() if not dialog.result(): return args = dialog.get_check_arguments() self._start_process(script_name, terminal_title, *args) def convert_to_nsm_file_format(self): script_name = 'session_ray_to_nsm.sh' terminal_title = _translate('utilities', 'Session to NSM file format') dialog = RayToNsmDialog(self.main_win) dialog.exec() if not dialog.result(): return args = dialog.get_check_arguments() if not dialog.choose_current_session: open_dialog = OpenSessionDialog(self.main_win) open_dialog.setWindowTitle( _translate('utilities', 'Choose a session to convert to NSM')) open_dialog.exec() if not open_dialog.result(): return args.append(open_dialog.get_selected_session()) self._start_process(script_name, terminal_title, *args) RaySession-0.12.2/src/jack_config_script/000077500000000000000000000000001417052567600203205ustar00rootroot00000000000000RaySession-0.12.2/src/jack_config_script/get_diff.sh000066400000000000000000000007321417052567600224250ustar00rootroot00000000000000#!/bin/bash source shared.sh || exit 0 ray_operation=load # read current and session parameters, and diff between them current_parameters=$(get_current_parameters for_load) if [ -n "$1" ];then # keep parameters of a (multi-lines) argument wanted_parameters="$1" elif [ -f "$session_jack_file" ];then # keep parameters from session file wanted_parameters=$(cat "$session_jack_file") else exit 0 fi make_diff_parameters echo "$diff_parameters" exit 0 RaySession-0.12.2/src/jack_config_script/jack_checker_daemon.py000077500000000000000000000113021417052567600246110ustar00rootroot00000000000000#!/usr/bin/python3 -u import os import sys import time try: import dbus import dbus.mainloop.glib from gi.repository import GLib except: sys.stderr.write('python3-dbus is missing !\n') sys.exit(1) state_file_path = '/tmp/RaySession/jack_current_parameters' name_base = 'org.jackaudio' control_interface_name = name_base + '.JackControl' configure_interface_name = name_base + '.Configure' patchbay_interface_name = name_base + '.JackPatchbay' service_name = name_base + '.service' last_file_write = 0.0 def dbus_signal_receiver(*args, **kwds): global last_file_write # dbus signal for something else than JACK, do nothing if not kwds['interface'].startswith('org.jackaudio.'): return if not kwds['member'] in ('ServerStarted', 'ServerStopped', 'PortAppeared'): return if kwds['member'] == 'PortAppeared': # file already saved in last 3s if time.time() - last_file_write < 3: return # PortAppeared doesn't concerns a physical port, do nothing if not args[5] & 0x4: return jack_status = 1 if kwds['member'] == 'ServerStopped': jack_status = 0 write_the_file(jack_started=jack_status) def write_the_file(at_start=False, jack_started=-1): global last_file_write output_string = "daemon_pid:%i\n" % os.getpid() # Check if JACK is started, start output_string store if jack_started == -1: jack_started = control_iface.IsStarted() output_string += "jack_started:%s\n" % str(jack_started) output_string += "reliable_infos:%i\n" \ % int(not bool(at_start and jack_started)) params = configure_iface.GetParametersInfo(['engine']) for param in params: isset, default, value = configure_iface.GetParameterValue( ['engine', param[1]]) if isset: output_string += '/engine/%s:%s\n' % (param[1], value) params = configure_iface.GetParametersInfo(['driver']) for param in params: isset, default, value = configure_iface.GetParameterValue( ['driver', param[1]]) if isset: output_string += '/driver/%s:%s\n' % (param[1], value) is_leaf, internals = configure_iface.ReadContainer(['internals']) for internal in internals: params = configure_iface.GetParametersInfo( ['internals', internal]) for param in params: isset, default, value = configure_iface.GetParameterValue( ['internals', internal, param[1]]) if isset: output_string += '/internals/%s/%s:%s\n' % ( internal, param[1], value) state_dir = os.path.dirname(state_file_path) if not os.path.exists(state_dir): os.makedirs(state_dir) # give read/write access to all users os.chmod(state_dir, 0o777) file = open(state_file_path, 'w') file.write(output_string) file.close() last_file_write = time.time() if __name__ == '__main__': if os.path.exists(state_file_path): file = open(state_file_path, 'r') file_contents = file.read() file.close() jack_checker_pid = 0 for line in file_contents.split('\n'): if line.startswith('daemon_pid:'): pid_str = line.replace('daemon_pid:', '', 1) if pid_str.isdigit(): jack_checker_pid = int(pid_str) break if os.path.isdir('/proc/%i' % jack_checker_pid): # this daemon is already running, just exit sys.stderr.write('jack checker daemon already running\n') sys.exit() else: os.remove(state_file_path) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) loop = GLib.MainLoop() bus = dbus.SessionBus() controller = bus.get_object(service_name, "/org/jackaudio/Controller") control_iface = dbus.Interface(controller, control_interface_name) configure_iface = dbus.Interface(controller, configure_interface_name) patchbay_iface = dbus.Interface(controller, patchbay_interface_name) bus.add_signal_receiver(dbus_signal_receiver, destination_keyword="dest", path_keyword="path", member_keyword="member", interface_keyword="interface", sender_keyword="sender") if len(sys.argv) >= 2 and sys.argv[1] in ('-f', '--force-reliable'): write_the_file() else: write_the_file(at_start=True) loop.run() sys.exit() RaySession-0.12.2/src/jack_config_script/jack_parameters.py000077500000000000000000000143561417052567600240410ustar00rootroot00000000000000#!/usr/bin/python3 -u import sys try: import dbus except: sys.stderr.write('python3-dbus is missing !\n') sys.exit(1) name_base = 'org.jackaudio' control_interface_name = name_base + '.JackControl' configure_interface_name = name_base + '.Configure' patchbay_interface_name = name_base + '.JackPatchbay' service_name = name_base + '.service' def convert_str_to_dbustype(value, dbus_type): try: dbus_type = str(dbus_type) if dbus_type == 'b': return bool(value in ('1', 'true', 'True')) if dbus_type == 'u': return dbus.UInt32(value) if dbus_type == 'i': return int(value) if dbus_type == 'y': return value.encode() if dbus_type == 's': return value return None except: return None def get_jack_parameters(): # Check if JACK is started, start output_string store jack_started = control_iface.IsStarted() output_string = "jack_started:%s\n" % str(jack_started) params = configure_iface.GetParametersInfo(['engine']) for param in params: isset, default, value = configure_iface.GetParameterValue( ['engine', param[1]]) if isset: output_string += '/engine/%s:%s\n' % (param[1], value) params = configure_iface.GetParametersInfo(['driver']) for param in params: isset, default, value = configure_iface.GetParameterValue( ['driver', param[1]]) if isset: output_string += '/driver/%s:%s\n' % (param[1], value) is_leaf, internals = configure_iface.ReadContainer(['internals']) for internal in internals: params = configure_iface.GetParametersInfo(['internals', internal]) for param in params: isset, default, value = configure_iface.GetParameterValue( ['internals', internal, param[1]]) if isset: output_string += '/internals/%s/%s:%s\n' % ( internal, param[1], value) if output_string: return output_string return '\n' def set_jack_parameters(contents): all_input_parameters = {} for line in contents.split('\n'): if line.startswith(('/engine/', '/driver/', '/internals/')): param, colon, value = line.partition(':') all_input_parameters[param] = value params = configure_iface.GetParametersInfo(['engine']) for param in params: isset, default, value = configure_iface.GetParameterValue( ['engine', param[1]]) full_param = '/engine/%s' % param[1] if full_param in all_input_parameters: if str(value) != all_input_parameters[full_param]: dbus_value = convert_str_to_dbustype( all_input_parameters[full_param], param[0]) if dbus_value is not None: configure_iface.SetParameterValue( ['engine', param[1]], dbus_value) params = configure_iface.GetParametersInfo(['driver']) for param in params: isset, default, value = configure_iface.GetParameterValue( ['driver', param[1]]) full_param = '/driver/%s' % param[1] if full_param in all_input_parameters: if str(value) != all_input_parameters[full_param]: dbus_value = convert_str_to_dbustype( all_input_parameters[full_param], param[0]) if dbus_value is not None: configure_iface.SetParameterValue( ['driver', param[1]], dbus_value) is_leaf, internals = configure_iface.ReadContainer(['internals']) for internal in internals: params = configure_iface.GetParametersInfo(['internals', internal]) for param in params: isset, default, value = configure_iface.GetParameterValue( ['internals', internal, param[1]]) full_param = '/internals/%s/%s' % (internal, param[1]) if full_param in all_input_parameters: if str(value) != all_input_parameters[full_param]: dbus_value = convert_str_to_dbustype( all_input_parameters[full_param], param[0]) if dbus_value is not None: configure_iface.SetParameterValue( ['internals', internal, param[1]], dbus_value) if __name__ == '__main__': try: bus = dbus.SessionBus() controller = bus.get_object(service_name, "/org/jackaudio/Controller") control_iface = dbus.Interface(controller, control_interface_name) configure_iface = dbus.Interface(controller, configure_interface_name) patchbay_iface = dbus.Interface(controller, patchbay_interface_name) except: sys.stderr.write('Impossible to connect to JACK dbus\n') sys.exit(1) if len(sys.argv) >= 2: if sys.argv[1] == '--diff': if len(sys.argv) >= 4: try: file1 = open(sys.argv[2], 'r') contents1 = file1.read() file1.close() file2 = open(sys.argv[3], 'r') contents2 = file2.read() file2.close() except: sys.stderr.write("unable to read file %s or %s\n" % ( sys.argv[2], sys.argv[3])) sys.exit(1) output = diff(contents1, contents2) sys.stdout.write(output) sys.exit(0) else: sys.stderr.write('not enough arguments\n') sys.exit(1) try: file = open(sys.argv[1], 'r') contents = file.read() file.close() except: sys.stderr.write("unable to read file %s\n" % sys.argv[1]) sys.exit(1) sys.exit(set_jack_parameters(contents)) else: output_string = get_jack_parameters() sys.stdout.write(output_string) RaySession-0.12.2/src/jack_config_script/load_config.sh000077500000000000000000000047711417052567600231340ustar00rootroot00000000000000#!/bin/bash ############ SCRIPT START ############# # exit 0 means load session after script # else the session open will be cancelled source shared.sh || exit 0 ray_operation=load # read current and session parameters, and diff between them current_parameters=$(get_current_parameters for_load) [ -f "$session_jack_file" ] && wanted_parameters=$(cat "$session_jack_file") make_diff_parameters [[ "$(current_value_of jack_started)" == 1 ]] && jack_was_started=true || jack_was_started=false # save the current configuration to can restore it (only if we are not in a switch situation) $RAY_SWITCHING_SESSION || echo "$current_parameters" > "$backup_jack_conf" # no reliable JACK infos because JACK was started before the checker script if $RAY_JACK_RELIABILITY_CHECK && [[ "$(current_value_of reliable_infos)" == 0 ]];then if has_different_value hostname;then $jack_was_started && stop_jack has_different_value /driver/rate && set_samplerate start_jack $jack_was_started && reconfigure_pulseaudio as_it_just_was else check_device $jack_was_started && stop_jack set_jack_parameters start_jack if [ -f "$session_jack_file" ];then reconfigure_pulseaudio else reconfigure_pulseaudio as_it_just_was fi fi exit 0 fi # JACK should not be started, continue normal way even if JACK is started [[ "$(wanted_value_of jack_started)" == 0 ]] && exit 0 # Session uses another samplerate than the current one, re-start JACK and go if has_different_value /driver/rate;then if has_different_value hostname;then $jack_was_started && stop_jack set_samplerate start_jack $jack_was_started && reconfigure_pulseaudio as_it_just_was else check_device $jack_was_started && stop_jack set_jack_parameters start_jack reconfigure_pulseaudio fi exit 0 fi # Session last open was on another machine, continue normal way if has_different_value hostname;then $jack_was_started || start_jack exit 0 fi # no jack parameters differences, set only parameters if jack is stopped if [ -z "$(echo "$diff_parameters"|grep -e ^/engine/ -e ^/driver/ -e ^/internals/)" ];then if ! $jack_was_started;then check_device set_jack_parameters start_jack fi reconfigure_pulseaudio else check_device $jack_was_started && stop_jack set_jack_parameters start_jack reconfigure_pulseaudio fi exit 0 RaySession-0.12.2/src/jack_config_script/locale.sh000066400000000000000000000073011417052567600221140ustar00rootroot00000000000000#!/bin/bash case "$LANG" in en_*) tr_script_info_loadanyway(){ echo "

To open this session anyway,
" echo "de-activate session scripts.

" } tr_start_jack_failed_load(){ echo "

Failed to start JACK." echo "Session open cancelled !

" tr_script_info_loadanyway } tr_start_jack_failed_close(){ echo "

Failed to start JACK." echo "Your previous configuration can't be restored.

" } tr_device_not_connected_load(){ echo "

Device $1 is not connected !" echo "Session open cancelled.

" tr_script_info_loadanyway } tr_device_not_connected_close(){ echo "

Device $1 is not connected !" echo "Your previous configuration can't be restored.

" } tr_waiting_jack_infos="Waiting for JACK infos..." tr_starting_jack="Starting JACK" tr_stopping_clients="Stopping clients" tr_stopping_jack="Stopping JACK" tr_reconfigure_pulseaudio="Reconfigure PulseAudio" ;; fr_*) tr_script_info_loadanyway(){ echo "

Pour ouvrir cette session malgré tout,
" echo "désactivez les scripts de session.

" } tr_start_jack_failed_load(){ echo "

Échec du démarrage de JACK." echo "L'ouverture de la session est abandonnée.

" tr_script_info_loadanyway } tr_start_jack_failed_close(){ echo "

Échec du démarrage de JACK." echo "Votre ancienne configuration n'a pas pu être restaurée.

" } tr_device_not_connected_load(){ echo "

L'interface $1 n'est pas connectée !
" echo "L'ouverture de la session est abandonnée.

" tr_script_info_loadanyway } tr_device_not_connected_close(){ echo "L'interface $1 n'est pas connectée !" echo "Votre ancienne configuration n'a pas pu être restaurée." } tr_waiting_jack_infos="Attente des infos de JACK..." tr_starting_jack="Démarrage de JACK" tr_stopping_clients="Arrêt des clients" tr_stopping_jack="Arrêt de JACK" tr_reconfigure_pulseaudio="Reconfiguration de PulseAudio" ;; * ) tr_script_info_loadanyway(){ echo "

To open this session anyway,
" echo "de-activate session scripts.

" } tr_start_jack_failed_load(){ echo "

Failed to start JACK." echo "Session open cancelled !

" tr_script_info_loadanyway } tr_start_jack_failed_close(){ echo "

Failed to start JACK." echo "Your previous configuration can't be restored.

" } tr_device_not_connected_load(){ echo "

Device $1 is not connected !" echo "Session open cancelled.

" tr_script_info_loadanyway } tr_device_not_connected_close(){ echo "

Device $1 is not connected !" echo "Your previous configuration can't be restored.

" } tr_waiting_jack_infos="Waiting for JACK infos..." tr_starting_jack="Starting JACK" tr_stopping_clients="Stopping clients" tr_stopping_jack="Stopping JACK" tr_reconfigure_pulseaudio="Reconfigure PulseAudio" ;; esac RaySession-0.12.2/src/jack_config_script/pulse2jack_tool.py000077500000000000000000000260361417052567600240040ustar00rootroot00000000000000#!/usr/bin/python3 import os import shlex import shutil import subprocess import sys import tempfile TMP_PA_CONTENTS = """ .fail ### Automatically restore the volume of streams and devices load-module module-device-restore load-module module-stream-restore load-module module-card-restore ### Load unix protocol load-module module-native-protocol-unix ### Automatically restore the default sink/source when changed by the user ### during runtime ### NOTE: This should be loaded as early as possible so that subsequent modules ### that look up the default sink/source get the right value load-module module-default-device-restore ### Automatically move streams to the default sink if the sink they are ### connected to dies, similar for sources load-module module-rescue-streams ### Make sure we always have a sink around, even if it is a null sink. load-module module-always-sink """ PULSE_CONFIG_DIR = os.path.join(os.getenv('HOME'), '.pulse') if os.getenv('PULSE_CONFIG_DIR'): PULSE_CONFIG_DIR = os.getenv('PULSE_CONFIG_DIR') class Bridge: module_id = '0' type = 'source' name = '' channels = '' connected = 'yes' existing = False number_in_file = '' def __init__(self, bridge_type, name, channels, connected): if bridge_type.lower() == 'sink': self.type = 'sink' self.name = name if channels.isdigit() and int(channels) > 0: self.channels = channels if connected.lower() in ('false', 'no'): self.connected = 'no' def is_same_as(self, other)->bool: return bool(self.type == other.type and self.name == other.name and self.channels == other.channels and self.connected == other.connected) def set_module_id(self, module_id: str): self.module_id = module_id def set_value_with_key(self, key: str, value: str): if key == 'name': self.name = value elif key == 'channels': if value.isdigit() and int(value) >= 1: self.channels = value elif key == 'connect': self.connected = value def get_load_module_string(self)->str: string = "load-module module-jack-%s" % self.type if self.channels: string += " channels=%s" % self.channels if self.connected: string += " connected=%s" % self.connected if self.name: string += " client_name=\"%s\"" % self.name.replace('"', '\\"') return string def get_save_string(self)->str: str_base = "pulseaudio_%s%s" % (self.type, self.number_in_file) save_list = [] if self.name: save_list.append("%s_name:%s" % (str_base, self.name)) if self.channels: save_list.append("%s_channels:%s" % (str_base, self.channels)) if self.connected: save_list.append("%s_connect:%s" % (str_base, self.connected)) return '\n'.join(save_list) def rewrite_config_file(file_path: str, keys: dict): if not os.access(file_path, os.W_OK): sys.stderr.write("Impossible to write %s\n" % file_path) return contents = "" if os.path.isfile(file_path) and os.access(file_path, os.R_OK): file = open(file_path, 'r') contents = file.read() file.close() out_lines = [] if contents: for line in contents.split('\n'): for key in keys: if line.startswith("%s =" % key): break else: out_lines.append(line) for key in keys: out_lines.append("%s = %s" % (key, keys[key])) file = open(file_path, 'w') file.write('\n'.join(out_lines)) file.close() def init_pulse_config_files(): client_keys = {"autospawn": "no"} daemon_keys = {"default-sample-format": "float32le", "realtime-scheduling": "yes", "rlimit-rttime": "-1", "exit-idle-time": "-1"} rewrite_config_file("%s/client.conf" % PULSE_CONFIG_DIR, client_keys) rewrite_config_file("%s/daemon.conf" % PULSE_CONFIG_DIR, daemon_keys) def start_pulseaudio(): """Starts pulseaudio with custom properties""" tmp_pa = tempfile.NamedTemporaryFile(mode='w+t') tmp_pa.writelines(TMP_PA_CONTENTS) tmp_pa.seek(0) process = subprocess.run(["pulseaudio", "--daemonize", "--high-priority", "--realtime", "--exit-idle-time=-1", "--file=%s" % tmp_pa.name, "-n"]) if process.returncode: sys.stdout.write("Failed to initialize PulseAudio!\n") else: sys.stdout.write("Initiated PulseAudio successfully!\n") def get_wanted_bridges_from_str(input_parameters: str)->list: bridges = [] for line in input_parameters.split('\n'): key, colon, value = line.partition(':') if not key.startswith('pulseaudio_'): continue key = key.replace('pulseaudio_', '', 1) if not key.startswith(('sink', 'source')): continue bridge_type = 'sink' if key.startswith('source'): bridge_type = 'source' key = key.replace(bridge_type, '', 1) number_in_file, underscore, subkey = key.partition('_') if not number_in_file: number_in_file = '0' elif number_in_file == 's': # ensure backward compatibility with pulse_audio_sinks # and pulse_audio_sources keys subkey = 'channels' number_in_file = '0' if value == '0': continue if not number_in_file.isdigit(): continue if not subkey in ('name', 'channels', 'connect'): continue for bridge in bridges: if (bridge.type == bridge_type and bridge.number_in_file == number_in_file): bridge.set_value_with_key(subkey, value) break else: bridge = Bridge(bridge_type, '', '', '') bridge.number_in_file = number_in_file bridge.set_value_with_key(subkey, value) bridges.append(bridge) return bridges def pactl_contents_to_bridge_list(pactl_contents: str)->list: """Converts the contents of `pactl list modules short` to a list of Bridge class elements""" modules = [] # parse the pactl list for line in pactl_contents.split('\n'): elements = line.split('\t') if len(elements) < 3: continue module_number, module_name, *rest = elements arguments_line = '\t'.join(rest) if module_name not in ('module-jack-sink', 'module-jack-source'): # not a pulseaudio JACK bridge module, no interest here continue module_type = module_name.replace('module-jack-', '') arguments = shlex.split(arguments_line) client_name = "" channels = "" connected = "yes" for argument in arguments: if argument.startswith('client_name='): client_name = argument.partition('=')[2] elif argument.startswith('channels='): channels = argument.partition('=')[2] elif argument.startswith('connect='): connected = argument.partition('=')[2] module = Bridge(module_type, client_name, channels, connected) module.set_module_id(module_number) modules.append(module) return modules def get_existing_modules()->list: """reads loaded pulseaudio modules and returns them in a list of Bridges""" # will raise FileNotFoundError if pactl is missing # or subprocess.CalledProcessError if pulseaudio is not running pactl_contents = subprocess.check_output( ['pactl', 'list', 'modules', 'short']).decode() return pactl_contents_to_bridge_list(pactl_contents) def get_save_string(existing_modules: list)->str: save_string = '' n_sink = 1 n_source = 1 for bridge in existing_modules: if bridge.type == 'sink': if n_sink > 1: bridge.number_in_file = str(n_sink) n_sink += 1 elif bridge.type == 'source': if n_source > 1: bridge.number_in_file = str(n_source) n_source += 1 return '\n'.join([b.get_save_string() for b in existing_modules]) def unload_and_load_modules(wanted_modules, existing_modules): """Unload unwanted PulseAudio JACK modules and load wanted modules, skipping theses one already bridged""" # disconnect unwanted modules for module in existing_modules: for bridge in wanted_modules: if bridge.is_same_as(module): bridge.existing = True sys.stderr.write( 'keep module-jack-%s "%s" because it is already running\n' % (module.type, module.name)) break else: sys.stderr.write('unload module-jack-%s "%s"\n' % (module.type, module.name)) subprocess.run(['pactl', 'unload-module', module.module_id]) has_source = False has_sink = False # connect new bridges for bridge in wanted_modules: if bridge.type == 'source': has_source = True else: has_sink = True if bridge.existing: continue sys.stderr.write( 'Adding module-jack-%s "%s"\n' % (bridge.type, bridge.name)) process_args = ['pactl', 'load-module', 'module-jack-%s' % bridge.type] if bridge.channels: process_args.append('channels="%s"' % bridge.channels) if bridge.name: process_args.append('client_name="%s"' % bridge.name.replace('"', '\\"')) if bridge.connected: process_args.append('connect="%s"' % bridge.connected) subprocess.run(process_args, stdout=subprocess.DEVNULL) if has_source: subprocess.run(['pactl', 'set-default-source', 'jack_in']) if has_sink: subprocess.run(['pactl', 'set-default-sink', 'jack_out']) if __name__ == '__main__': if len(sys.argv) < 2: sys.stderr.write('argument required.\n') sys.exit(1) # init the pulse config files if needed init_pulse_config_files() if not shutil.which('pactl'): sys.stderr.write( 'pactl is missing, please install pulseaudio !\n') sys.exit(1) pactl_prc = subprocess.run( ['pactl', 'list', 'modules', 'short'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) pactl_contents = pactl_prc.stdout.decode() existing_modules = pactl_contents_to_bridge_list(pactl_contents) if sys.argv[1] == '--save': if pactl_prc.returncode: sys.exit() sys.stdout.write(get_save_string(existing_modules)) sys.stdout.write('\n') sys.exit() else: wanted_modules = get_wanted_bridges_from_str(sys.argv[1]) if pactl_prc.returncode: start_pulseaudio(wanted_modules) else: unload_and_load_modules(wanted_modules, existing_modules) RaySession-0.12.2/src/jack_config_script/putback_config.sh000077500000000000000000000021201417052567600236300ustar00rootroot00000000000000#!/bin/bash # cd "$(dirname "`readlink -f "$(realpath "$0")"`")" source shared.sh if ! [ -f "$backup_jack_conf" ];then echo "No backup jack config file '$backup_jack_conf'" >/dev/stderr exit 0 fi ray_operation=close current_parameters=$(get_current_parameters) wanted_parameters=$(cat "$backup_jack_conf") rm "$backup_jack_conf" rm "$tmp_pulse_file" make_diff_parameters [[ "$(current_value_of jack_started)" == 1 ]] && jack_was_started=true || jack_was_started=false # reset the backup jack parameters in all cases check_device set_jack_parameters if has_different_value jack_started;then if ! $jack_was_started;then start_jack reconfigure_pulseaudio else stop_jack fi exit 0 fi # just leave if jack is not started and should not be $jack_was_started || exit 0 # no jack parameters differences if [ -z "$(echo "$diff_parameters"|grep -e ^/engine/ -e ^/driver/ -e ^/internals/)" ];then reconfigure_pulseaudio exit 0 fi # JACK is started and should be, but not with the same parameters stop_jack start_jack reconfigure_pulseaudio exit 0 RaySession-0.12.2/src/jack_config_script/reconfigure-pulse2jack.sh000077500000000000000000000203201417052567600252250ustar00rootroot00000000000000#!/bin/bash # Script to bridge/start pulseaudio into JACK mode # highly inspired (plagiarism) from cadence-pulse2jack from falktx [ ! -d ~/.pulse ] && mkdir -p ~/.pulse if [ ! -f ~/.pulse/client.conf ]; then echo "autospawn = no" > ~/.pulse/client.conf else if (! cat ~/.pulse/client.conf | grep "autospawn = no" > /dev/null); then sed -i '/autospawn =/d' ~/.pulse/client.conf echo "autospawn = no" >> ~/.pulse/client.conf fi fi if [ ! -f ~/.pulse/daemon.conf ]; then echo "default-sample-format = float32le" > ~/.pulse/daemon.conf echo "realtime-scheduling = yes" >> ~/.pulse/daemon.conf echo "rlimit-rttime = -1" >> ~/.pulse/daemon.conf echo "exit-idle-time = -1" >> ~/.pulse/daemon.conf else if (! cat ~/.pulse/daemon.conf | grep "default-sample-format = float32le" > /dev/null); then sed -i '/default-sample-format = /d' ~/.pulse/daemon.conf echo "default-sample-format = float32le" >> ~/.pulse/daemon.conf fi if (! cat ~/.pulse/daemon.conf | grep "realtime-scheduling = yes" > /dev/null); then sed -i '/realtime-scheduling = /d' ~/.pulse/daemon.conf echo "realtime-scheduling = yes" >> ~/.pulse/daemon.conf fi if (! cat ~/.pulse/daemon.conf | grep "rlimit-rttime = -1" > /dev/null); then sed -i '/rlimit-rttime =/d' ~/.pulse/daemon.conf echo "rlimit-rttime = -1" >> ~/.pulse/daemon.conf fi if (! cat ~/.pulse/daemon.conf | grep "exit-idle-time = -1" > /dev/null); then sed -i '/exit-idle-time =/d' ~/.pulse/daemon.conf echo "exit-idle-time = -1" >> ~/.pulse/daemon.conf fi fi IsPulseAudioRunning() { PROCESS=`ps -u "$USER" | grep " pulseaudio"$` [ -n "$PROCESS" ] } StartBridged() { #write pulseaudio config file in a tmp file pa_file=$(mktemp --suffix .pa) echo .fail > $pa_file ### Automatically restore the volume of streams and devices echo load-module module-device-restore >> $pa_file echo load-module module-stream-restore >> $pa_file echo load-module module-card-restore >> $pa_file ### Load Jack modules [ $wanted_capture_ports != 0 ] && echo load-module module-jack-source $str_capture >> $pa_file [ $wanted_playback_ports != 0 ] && echo load-module module-jack-sink $str_playback >> $pa_file ### Load unix protocol echo load-module module-native-protocol-unix >> $pa_file ### Automatically restore the default sink/source when changed by the user ### during runtime ### NOTE: This should be loaded as early as possible so that subsequent modules ### that look up the default sink/source get the right value echo load-module module-default-device-restore >> $pa_file ### Automatically move streams to the default sink if the sink they are ### connected to dies, similar for sources echo load-module module-rescue-streams >> $pa_file ### Make sure we always have a sink around, even if it is a null sink. echo load-module module-always-sink >> $pa_file ### Make Jack default [ $wanted_capture_ports != 0 ] && echo set-default-source jack_in >> $pa_file [ $wanted_playback_ports != 0 ] && echo set-default-sink jack_out >> $pa_file if (`pulseaudio --daemonize --high-priority --realtime --exit-idle-time=-1 --file=$pa_file -n`); then echo "Initiated PulseAudio successfully!" else echo "Failed to initialize PulseAudio!" fi } killReStart() { pulseaudio -k && StartBridged exit } JackNotRunning() { echo "JACK seems not running, start JACK before bridge PulseAudio" exit 1 } # ---------------------------------------------- wanted_capture_ports=0 # -1 means default wanted_playback_ports=0 # -1 means default arg_is_for="" for arg in "$@";do case "$arg" in -h|--h|--help) echo "usage: $0 [command] -p Playback only with default number of channels -p Number of playback channels -c Capture only with default number of channels -c Number of capture channels -h, --help Show this help menu --dummy Don't do anything, just create the needed files NOTE: When runned with no arguments, $(basename "$0") will activate PulseAudio with both playback and record modes with default number of channels. " exit ;; --dummy) exit ;; -c|--capture) arg_is_for="capture" wanted_capture_ports=-1 # -1 means default, if no (correct) argument is given. ;; -p|--play|--playback) arg_is_for="playback" wanted_playback_ports=-1 ;; * ) case "$arg_is_for" in "capture") [ "$arg" -ge 0 ] 2>/dev/null && wanted_capture_ports="$arg" ;; "playback") [ "$arg" -ge 0 ] 2>/dev/null && wanted_playback_ports="$arg" ;; esac ;; esac done if [ $wanted_capture_ports == 0 ] && [ $wanted_playback_ports == 0 ];then IsPulseAudioRunning || exit 0 fi str_capture="channels=$wanted_capture_ports" #used for pulseaudio commands str_playback="channels=$wanted_playback_ports" ## [ $wanted_capture_ports == -1 ] && str_capture="" # -1 means default, no command channels=n [ $wanted_playback_ports == -1 ] && str_playback="" ## # ---------------------------------------------- if (IsPulseAudioRunning); then { #count all Jack Audio Physical ports all_jack_lsp=$(jack_lsp -p -t) || JackNotRunning output_physical_lines=$(echo "$all_jack_lsp"|grep -n "output,physical,"|cut -d':' -f1) input_physical_lines=$( echo "$all_jack_lsp"|grep -n "input,physical," |cut -d':' -f1) audio_lines=$(echo "$all_jack_lsp" |grep -n " audio"|cut -d':' -f1) capture_physical_ports=0 playback_physical_ports=0 for out_phy_line in $output_physical_lines;do if echo "$audio_lines"|grep -q $(($out_phy_line + 1));then ((capture_physical_ports++)) fi done for in_phy_line in $input_physical_lines;do if echo "$audio_lines"|grep -q $(($in_phy_line + 1));then ((playback_physical_ports++)) fi done #count PulseAudio jack ports current_playback_ports=$(echo "$all_jack_lsp"|grep ^"PulseAudio JACK Sink:" |wc -l) current_capture_ports=$( echo "$all_jack_lsp"|grep ^"PulseAudio JACK Source:"|wc -l) #if number of pulseaudio ports equal to physical ports, consider pulseaudio module is running the default mode (no channels=n) [ $current_capture_ports == $capture_physical_ports ] && current_capture_ports=-1 [ $current_playback_ports == $playback_physical_ports ] && current_playback_ports=-1 [ $wanted_capture_ports == $capture_physical_ports ] && wanted_capture_ports=-1 [ $wanted_playback_ports == $playback_physical_ports ] && wanted_playback_ports=-1 if [ $wanted_capture_ports == $current_capture_ports ] && [ $wanted_playback_ports == $current_playback_ports ];then echo "PulseAudio is already started and bridged to Jack with $current_capture_ports inputs and $current_playback_ports outputs, nothing to do !" exit fi if [ $current_capture_ports != $wanted_capture_ports ];then if [ $current_capture_ports != 0 ];then echo "unload PulseAudio JACK Source" pactl unload-module module-jack-source > /dev/null || killReStart fi if [ $wanted_capture_ports != 0 ];then echo "load PulseAudio JACK Source $str_capture" pactl load-module module-jack-source $str_capture > /dev/null pacmd set-default-source jack_in > /dev/null fi fi if [ $current_playback_ports != $wanted_playback_ports ];then if [ $current_playback_ports != 0 ];then echo "unload PulseAudio JACK Sink" pactl unload-module module-jack-sink > /dev/null || killReStart fi if [ $wanted_playback_ports != 0 ];then echo "load PulseAudio JACK Sink $str_playback" pactl load-module module-jack-sink $str_playback > /dev/null pactl set-default-sink jack_out > /dev/null fi fi } else { StartBridged } fi RaySession-0.12.2/src/jack_config_script/save_config.sh000077500000000000000000000001721417052567600231420ustar00rootroot00000000000000#!/bin/bash source shared.sh || exit 0 contents=$(get_current_parameters) echo "$contents" > "$session_jack_file" exit 0 RaySession-0.12.2/src/jack_config_script/script_starter.sh000077500000000000000000000025441417052567600237340ustar00rootroot00000000000000#!/bin/bash true_or_false(){ if [ -n "$1" ];then [[ "${1,,}" != false ]] && echo true || echo false elif [ -n "$2" ];then echo "$2" else echo false fi } operation="$1" shift if [ -z "$RAY_SESSION_PATH" ];then possible_sesspath="$1" if [ -n "$possible_sesspath" ];then RAY_SESSION_PATH="$possible_sesspath" fi fi if [ -z "$RAY_SESSION_PATH" ];then case "$operation" in load|save) echo "this script has to be used by ray session scripts or this way : $0 operation [SESSION_PATH] where operation can be 'load', 'save', 'putback','get_diff' or 'set_jack_parameters'" >/dev/stderr exit 1 ;; esac fi [ -z "$RAY_SWITCHING_SESSION" ] && RAY_SWITCHING_SESSION=false RAY_MANAGE_PULSEAUDIO=$(true_or_false "$RAY_MANAGE_PULSEAUDIO" true) RAY_JACK_RELIABILITY_CHECK=$(true_or_false "$RAY_JACK_RELIABILITY_CHECK" true) RAY_HOSTNAME_SENSIBLE=$(true_or_false "$RAY_HOSTNAME_SENSIBLE" true) cd "$(dirname "`readlink -f "$(realpath "$0")"`")" case "$operation" in load ) source ./load_config.sh ;; save ) source ./save_config.sh ;; putback ) source ./putback_config.sh ;; get_diff ) source ./get_diff.sh ;; set_jack_parameters ) source ./set_jack_parameters.sh ;; esac exit 0 RaySession-0.12.2/src/jack_config_script/set_jack_parameters.sh000066400000000000000000000001231417052567600246560ustar00rootroot00000000000000#!/bin/bash source shared.sh || exit 0 wanted_parameters="$1" set_jack_parameters RaySession-0.12.2/src/jack_config_script/shared.sh000066400000000000000000000143331417052567600221260ustar00rootroot00000000000000#!/bin/bash has_pulse_jack(){ # check if pulseaudio-module-jack is quite long (> 100ms on a correct machine) # So this state is stored in a tmp file. if [ -f "$tmp_pulse_file" ];then [[ "$(cat "$tmp_pulse_file")" == 0 ]] && return 0 || return 1 fi which pulseaudio >/dev/null && pulseaudio --dump-modules|grep -q ^module-jack- return_code=$? echo $return_code > "$tmp_pulse_file" return $return_code } get_current_parameters(){ $RAY_HOSTNAME_SENSIBLE && echo "hostname:$(hostname)" parameters_path="$tmp_dir/jack_current_parameters" if [ -f "$parameters_path" ];then daemon_pid=$(cat "$parameters_path"|grep ^daemon_pid:|cut -d':' -f2) [ -d "/proc/$daemon_pid" ] || rm "$parameters_path" fi if [ ! -f "$parameters_path" ];then # start the jack parameters checker daemon ./jack_checker_daemon.py &>/dev/null & for ((i=0; i<=50; i++));do sleep 0.1 [ -f "$parameters_path" ] && break [ "$i" == 2 ] && ray_control script_info "$tr_waiting_jack_infos" >/dev/null done ray_control hide_script_info >/dev/null fi if [ -f "$parameters_path" ];then jack_parameters=$(cat "$parameters_path") if [[ "$1" == for_load ]];then echo "$jack_parameters"|grep -v ^"daemon_pid:" else echo "$jack_parameters"|grep -v -e ^"daemon_pid:" -e ^"reliable_infos:" fi fi has_pulse_jack && ./pulse2jack_tool.py --save } make_diff_parameters(){ IFS=$'\n' diff_parameters="" for line in $wanted_parameters;do param="${line%%:*}" value="${line#*:}" current_line=$(echo "$current_parameters"|grep ^"${param}:") current_value="${current_line#*:}" [[ "$value" != "$current_value" ]] && diff_parameters+="$param " done unset IFS } set_jack_parameters(){ parameters_files=$(mktemp) echo "$wanted_parameters" > "$parameters_files" ./jack_parameters.py "$parameters_files" rm "$parameters_files" } start_jack(){ ray_control script_info "$tr_starting_jack" jack_control start &>/dev/null if ! jack_control status &>/dev/null;then ray_control script_info "$(tr_start_jack_failed_${ray_operation})" # session load is aborted, and script_info dialog will not be hidden exit 1 fi } stop_jack(){ if $RAY_SWITCHING_SESSION;then ray_control script_info "$tr_stopping_clients" ray_control clear_clients fi ray_control script_info "$tr_stopping_jack" jack_control stop &>/dev/null } set_samplerate(){ jack_control dps rate "$(current_value_of /driver/rate)" } check_alsa_device(){ full_device="$1" [[ "$full_device" == none ]] && full_device="" [ -z "$full_device" ] && return 0 # device is not set, should work in most cases device_and_index=${full_device#*:} device=${device_and_index%,*} index=${device_and_index##*,} command=aplay [[ "$2" == capture ]] && command=arecord if [[ "$device_and_index" =~ ',' ]];then LANG=C LC_ALL=C $command -l|grep -q ^"card .: ${device} \[.*\], device ${index}: " elif [[ "$device_and_index" =~ ^[0-9]+$ ]];then LANG=C LC_ALL=C $command -l|grep -q ^"card ${index}: " else LANG=C LC_ALL=C $command -l|grep -q ^"card .: ${device} \[" fi return_code=$? unset full_device device_and_index device index command return $return_code } check_device(){ case "$(wanted_value_of /engine/driver)" in alsa ) if [[ "$(wanted_value_of /driver/duplex)" == "1" ]];then pb_device=$(wanted_value_of /driver/playback) if ! check_alsa_device "$pb_device";then ray_control script_info "$(tr_device_not_connected_${ray_operation} "$pb_device")" exit 1 fi cp_device="$(wanted_value_of /driver/capture)" if ! check_alsa_device "$cp_device" capture;then ray_control script_info "$(tr_device_not_connected_${ray_operation} "$cp_device")" exit 1 fi else pb_device="$(wanted_value_of /driver/device)" if ! check_alsa_device "$pb_device";then ray_control script_info "$(tr_device_not_connected_${ray_operation} "$pb_device")" exit 1 fi fi ;; net ) check_url=$(wanted_value_of /driver/multicast-ip) if [[ -n "$check_url" ]] && ! ping -c 1 "$check_url" &>/dev/null;then ray_control script_info "$(tr_device_not_connected_${ray_operation} "$check_url")" exit 1 fi ;; * ) true ;; esac } reconfigure_pulseaudio(){ $RAY_MANAGE_PULSEAUDIO || return has_pulse_jack || return current_pulse_vars=$(echo "$current_parameters"|grep ^pulseaudio_) wanted_pulse_vars=$(echo "$wanted_parameters"|grep ^pulseaudio_) [[ "$1" == "as_it_just_was" ]] && as_it_just_was=true || as_it_just_was=false if ! $as_it_just_was && [[ "$wanted_pulse_vars" == "$current_pulse_vars" ]];then unset wanted_pulse_vars unset current_pulse_vars return fi ray_control script_info "$tr_reconfigure_pulseaudio" $as_it_just_was && pulse_vars="$current_pulse_vars" || pulse_vars="$wanted_pulse_vars" ./pulse2jack_tool.py "$pulse_vars" unset wanted_pulse_vars unset current_pulse_vars unset pulse_vars } wanted_value_of(){ line=$(echo "$wanted_parameters"|grep ^"$1:"|head -n 1) echo "${line#*:}" } current_value_of(){ line=$(echo "$current_parameters"|grep ^"$1:"|head -n 1) echo "${line#*:}" } has_different_value(){ if ! $RAY_HOSTNAME_SENSIBLE;then [[ "$1" == hostname ]] && return 1 fi echo "$diff_parameters"|grep -q ^"$1"$ } source locale.sh session_jack_file="$RAY_SESSION_PATH/jack_parameters" tmp_dir=/tmp/RaySession [ -d "$tmp_dir" ] || mkdir -p "$tmp_dir" backup_jack_conf="$tmp_dir/jack_backup_parameters" tmp_pulse_file="$tmp_dir/has_pulse_jack" RaySession-0.12.2/src/jack_patchbay_to_osc/000077500000000000000000000000001417052567600206305ustar00rootroot00000000000000RaySession-0.12.2/src/jack_patchbay_to_osc/jacklib/000077500000000000000000000000001417052567600222275ustar00rootroot00000000000000RaySession-0.12.2/src/jack_patchbay_to_osc/jacklib/__init__.py000066400000000000000000000001221417052567600243330ustar00rootroot00000000000000from .version import __version__ # noqa from .api import * # noqa RaySession-0.12.2/src/jack_patchbay_to_osc/jacklib/api.py000066400000000000000000001622031417052567600233560ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # JACK ctypes definitions for usage in Python applications # Copyright (C) 2010-2020 Filipe Coelho # 2016-2021 Christopher Arndt # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the COPYING file # ------------------------------------------------------------------------------------------------- # Imports (Global) from __future__ import absolute_import, print_function, unicode_literals from ctypes import (ARRAY, CFUNCTYPE, POINTER, Structure, byref, c_char_p, c_double, c_float, c_int, c_int32, c_size_t, c_uint8, c_uint32, c_uint64, c_ulong, c_void_p, cdll, pointer) from collections import namedtuple from sys import platform # ------------------------------------------------------------------------------------------------- # Load JACK shared library try: if platform == "darwin": jlib = cdll.LoadLibrary("libjack.dylib") elif platform in ("win32", "win64", "cygwin"): jlib = cdll.LoadLibrary("libjack.dll") else: jlib = cdll.LoadLibrary("libjack.so.0") except OSError: jlib = None raise ImportError("JACK is not available in this system") # ------------------------------------------------------------------------------------------------- # JACK2 test try: if jlib.jack_get_version_string: JACK2 = True else: JACK2 = False except AttributeError: JACK2 = False # ------------------------------------------------------------------------------------------------- # Pre-Types c_enum = c_int c_uchar = c_uint8 class _jack_port(Structure): _fields_ = [] class _jack_client(Structure): _fields_ = [] # ------------------------------------------------------------------------------------------------- # Defines ENCODING = "utf-8" JACK_MAX_FRAMES = 4294967295 JACK_LOAD_INIT_LIMIT = 1024 JACK_DEFAULT_AUDIO_TYPE = "32 bit float mono audio" JACK_DEFAULT_MIDI_TYPE = "8 bit raw midi" JACK_UUID_SIZE = 36 JACK_UUID_STRING_SIZE = JACK_UUID_SIZE + 1 JACK_UUID_EMPTY_INITIALIZER = 0 # Meta data _JACK_METADATA_PREFIX = "http://jackaudio.org/metadata/" JACK_METADATA_CONNECTED = _JACK_METADATA_PREFIX + "connected" JACK_METADATA_EVENT_TYPES = _JACK_METADATA_PREFIX + "event-types" JACK_METADATA_HARDWARE = _JACK_METADATA_PREFIX + "hardware" JACK_METADATA_ICON_LARGE = _JACK_METADATA_PREFIX + "icon-large" JACK_METADATA_ICON_NAME = _JACK_METADATA_PREFIX + "icon-name" JACK_METADATA_ICON_SMALL = _JACK_METADATA_PREFIX + "icon-small" JACK_METADATA_ORDER = _JACK_METADATA_PREFIX + "order" JACK_METADATA_PORT_GROUP = _JACK_METADATA_PREFIX + "port-group" JACK_METADATA_PRETTY_NAME = _JACK_METADATA_PREFIX + "pretty-name" JACK_METADATA_SIGNAL_TYPE = _JACK_METADATA_PREFIX + "signal-type" # ------------------------------------------------------------------------------------------------- # Helper functions def _e(s, encoding=ENCODING): if encoding: return s.encode(encoding) return s def _d(s, encoding=ENCODING): if encoding: return s.decode(encoding) return s # ------------------------------------------------------------------------------------------------- # Types jack_client_t = _jack_client jack_default_audio_sample_t = c_float jack_midi_data_t = c_uchar jack_nframes_t = c_uint32 jack_port_id_t = c_uint32 jack_port_t = _jack_port jack_time_t = c_uint64 jack_unique_t = c_uint64 jack_uuid_t = c_uint64 jack_options_t = c_enum # JackOptions jack_status_t = c_enum # JackStatus jack_transport_state_t = c_enum # JackTransportState jack_position_bits_t = c_enum # JackPositionBits jack_session_event_type_t = c_enum # JackSessionEventType jack_session_flags_t = c_enum # JackSessionFlags jack_custom_change_t = c_enum # JackCustomChange jack_latency_callback_mode_t = c_enum # JackLatencyCallbackMode jack_property_change_t = c_enum # JacKPropertyChange # JACK2 only: jack_port_type_id_t = c_uint32 # enum JackOptions JackNullOption = 0x00 JackNoStartServer = 0x01 JackUseExactName = 0x02 JackServerName = 0x04 JackLoadName = 0x08 JackLoadInit = 0x10 JackSessionID = 0x20 JackOpenOptions = JackSessionID | JackServerName | JackNoStartServer | JackUseExactName JackLoadOptions = JackLoadInit | JackLoadName | JackUseExactName # enum JackStatus JackFailure = 0x01 JackInvalidOption = 0x02 JackNameNotUnique = 0x04 JackServerStarted = 0x08 JackServerFailed = 0x10 JackServerError = 0x20 JackNoSuchClient = 0x40 JackLoadFailure = 0x80 JackInitFailure = 0x100 JackShmFailure = 0x200 JackVersionError = 0x400 JackBackendError = 0x800 JackClientZombie = 0x1000 # enum JackLatencyCallbackMode JackCaptureLatency = 0 JackPlaybackLatency = 1 # enum JackPortFlags JackPortIsInput = 0x1 JackPortIsOutput = 0x2 JackPortIsPhysical = 0x4 JackPortCanMonitor = 0x8 JackPortIsTerminal = 0x10 JackPortIsControlVoltage = 0x100 # enum JackTransportState JackTransportStopped = 0 JackTransportRolling = 1 JackTransportLooping = 2 JackTransportStarting = 3 # JACK2 only: JackTransportNetStarting = 4 # enum JackPositionBits JackPositionBBT = 0x10 JackPositionTimecode = 0x20 JackBBTFrameOffset = 0x40 JackAudioVideoRatio = 0x80 JackVideoFrameOffset = 0x100 JACK_POSITION_MASK = (JackPositionBBT | JackPositionTimecode | JackBBTFrameOffset | JackAudioVideoRatio | JackVideoFrameOffset) # enum JackSessionEventType JackSessionSave = 1 JackSessionSaveAndQuit = 2 JackSessionSaveTemplate = 3 # enum JackSessionFlags JackSessionSaveError = 0x01 JackSessionNeedTerminal = 0x02 # enum JackCustomChange JackCustomRemoved = 0 JackCustomAdded = 1 JackCustomReplaced = 2 # enum JackPropertyChange PropertyCreated = 0 PropertyChanged = 1 PropertyDeleted = 2 # ------------------------------------------------------------------------------------------------- # Structs class jack_midi_event_t(Structure): _fields_ = [ ("time", jack_nframes_t), ("size", c_size_t), ("buffer", POINTER(jack_midi_data_t)) ] class jack_latency_range_t(Structure): _fields_ = [ ("min", jack_nframes_t), ("max", jack_nframes_t) ] class jack_position_t(Structure): _fields_ = [ ("unique_1", jack_unique_t), ("usecs", jack_time_t), ("frame_rate", jack_nframes_t), ("frame", jack_nframes_t), ("valid", jack_position_bits_t), ("bar", c_int32), ("beat", c_int32), ("tick", c_int32), ("bar_start_tick", c_double), ("beats_per_bar", c_float), ("beat_type", c_float), ("ticks_per_beat", c_double), ("beats_per_minute", c_double), ("frame_time", c_double), ("next_time", c_double), ("bbt_offset", jack_nframes_t), ("audio_frames_per_video_frame", c_float), ("video_offset", jack_nframes_t), ("padding", ARRAY(c_int32, 7)), ("unique_2", jack_unique_t) ] class jack_session_event_t(Structure): _fields_ = [ ("type", jack_session_event_type_t), ("session_dir", c_char_p), ("client_uuid", c_char_p), ("command_line", c_char_p), ("flags", jack_session_flags_t), ("future", c_uint32) ] class jack_session_command_t(Structure): _fields_ = [ ("uuid", c_char_p), ("client_name", c_char_p), ("command", c_char_p), ("flags", jack_session_flags_t) ] class jack_property_t(Structure): _fields_ = [ ('key', c_char_p), ('data', c_char_p), ('type', c_char_p) ] class jack_description_t(Structure): _fields_ = [ ('subject', jack_uuid_t), ('property_cnt', c_uint32), ('properties', POINTER(jack_property_t)), ('property_size', c_uint32) ] # ------------------------------------------------------------------------------------------------- # Callbacks JackLatencyCallback = CFUNCTYPE(None, jack_latency_callback_mode_t, c_void_p) JackProcessCallback = CFUNCTYPE(c_int, jack_nframes_t, c_void_p) JackThreadCallback = CFUNCTYPE(c_void_p, c_void_p) JackThreadInitCallback = CFUNCTYPE(None, c_void_p) JackGraphOrderCallback = CFUNCTYPE(c_int, c_void_p) JackXRunCallback = CFUNCTYPE(c_int, c_void_p) JackBufferSizeCallback = CFUNCTYPE(c_int, jack_nframes_t, c_void_p) JackSampleRateCallback = CFUNCTYPE(c_int, jack_nframes_t, c_void_p) JackPortRegistrationCallback = CFUNCTYPE(None, jack_port_id_t, c_int, c_void_p) JackClientRegistrationCallback = CFUNCTYPE(None, c_char_p, c_int, c_void_p) # JACK2 only: JackClientRenameCallback = CFUNCTYPE(c_int, c_char_p, c_char_p, c_void_p) JackPortConnectCallback = CFUNCTYPE(None, jack_port_id_t, jack_port_id_t, c_int, c_void_p) # JACK2 only: JackPortRenameCallback = CFUNCTYPE(None, jack_port_id_t, c_char_p, c_char_p, c_void_p) JackFreewheelCallback = CFUNCTYPE(None, c_int, c_void_p) JackShutdownCallback = CFUNCTYPE(None, c_void_p) JackInfoShutdownCallback = CFUNCTYPE(None, jack_status_t, c_char_p, c_void_p) JackSyncCallback = CFUNCTYPE(c_int, jack_transport_state_t, POINTER(jack_position_t), c_void_p) JackTimebaseCallback = CFUNCTYPE(None, jack_transport_state_t, jack_nframes_t, POINTER(jack_position_t), c_int, c_void_p) JackSessionCallback = CFUNCTYPE(None, POINTER(jack_session_event_t), c_void_p) JackCustomDataAppearanceCallback = CFUNCTYPE(None, c_char_p, c_char_p, jack_custom_change_t, c_void_p) JackPropertyChangeCallback = CFUNCTYPE(None, jack_uuid_t, c_char_p, jack_property_change_t, c_void_p) JackErrorCallback = CFUNCTYPE(None, c_char_p) # ------------------------------------------------------------------------------------------------- # Functions try: jlib.jack_get_version_string.argtypes = None jlib.jack_get_version_string.restype = c_char_p except AttributeError: jlib.jack_get_version_string = None try: jlib.jack_client_open.argtypes = [c_char_p, jack_options_t, POINTER(jack_status_t), c_char_p] jlib.jack_client_open.restype = POINTER(jack_client_t) except AttributeError: jlib.jack_client_open = None try: jlib.jack_client_rename.argtypes = [POINTER(jack_client_t), c_char_p] jlib.jack_client_rename.restype = c_char_p except AttributeError: jlib.jack_client_rename = None try: jlib.jack_client_close.argtypes = [POINTER(jack_client_t)] jlib.jack_client_close.restype = c_int except AttributeError: jlib.jack_client_close = None try: jlib.jack_client_name_size.argtypes = None jlib.jack_client_name_size.restype = c_int except AttributeError: jlib.jack_client_name_size = None try: jlib.jack_get_client_name.argtypes = [POINTER(jack_client_t)] jlib.jack_get_client_name.restype = c_char_p except AttributeError: jlib.jack_get_client_name = None try: jlib.jack_activate.argtypes = [POINTER(jack_client_t)] jlib.jack_activate.restype = c_int except AttributeError: jlib.jack_activate = None try: jlib.jack_deactivate.argtypes = [POINTER(jack_client_t)] jlib.jack_deactivate.restype = c_int except AttributeError: jlib.jack_deactivate = None try: jlib.jack_get_client_pid.argtypes = [c_char_p] jlib.jack_get_client_pid.restype = c_int except AttributeError: jlib.jack_get_client_pid = None try: jlib.jack_is_realtime.argtypes = [POINTER(jack_client_t)] jlib.jack_is_realtime.restype = c_int except AttributeError: jlib.jack_is_realtime = None # JACK2 only: def get_version_string(): if jlib.jack_get_version_string: return jlib.jack_get_version_string() return None def client_open(client_name, options, status, uuid=""): if jlib.jack_client_open: return jlib.jack_client_open(_e(client_name), options, status, _e(uuid) if uuid else None) return None def client_rename(client, new_name): if jlib.jack_client_rename: return jlib.jack_client_rename(client, _e(new_name)) return None def client_close(client): if jlib.jack_client_close: return jlib.jack_client_close(client) return -1 def client_name_size(): if jlib.jack_client_name_size: return jlib.jack_client_name_size() return 0 def get_client_name(client): if jlib.jack_get_client_name: return jlib.jack_get_client_name(client) return None def activate(client): if jlib.jack_activate: return jlib.jack_activate(client) return -1 def deactivate(client): if jlib.jack_deactivate: return jlib.jack_deactivate(client) return -1 # JACK2 only: def get_client_pid(name): if jlib.jack_get_client_pid: return jlib.jack_get_client_pid(_e(name)) return 0 def is_realtime(client): if jlib.jack_is_realtime: return jlib.jack_is_realtime(client) return 0 # ------------------------------------------------------------------------------------------------- # Non-Callback API _thread_callback = None try: jlib.jack_cycle_wait.argtypes = [POINTER(jack_client_t)] jlib.jack_cycle_wait.restype = jack_nframes_t except AttributeError: jlib.jack_cycle_wait = None try: jlib.jack_cycle_signal.argtypes = [POINTER(jack_client_t), c_int] jlib.jack_cycle_signal.restype = None except AttributeError: jlib.jack_cycle_signal = None try: jlib.jack_set_process_thread.argtypes = [POINTER(jack_client_t), JackThreadCallback, c_void_p] jlib.jack_set_process_thread.restype = c_int except AttributeError: jlib.jack_set_process_thread = None def cycle_wait(client): if jlib.jack_cycle_wait: return jlib.jack_cycle_wait(client) return 0 def cycle_signal(client, status): if jlib.jack_cycle_signal: jlib.jack_cycle_signal(client, status) def set_process_thread(client, thread_callback, arg): if jlib.jack_set_process_thread: global _thread_callback _thread_callback = JackThreadCallback(thread_callback) return jlib.jack_set_process_thread(client, _thread_callback, arg) return -1 # ------------------------------------------------------------------------------------------------- # Client Callbacks _thread_init_callback = _shutdown_callback = _info_shutdown_callback = None _process_callback = _freewheel_callback = _bufsize_callback = _srate_callback = None _client_registration_callback = _client_rename_callback = None _port_registration_callback = _port_connect_callback = _port_rename_callback = None _graph_callback = _xrun_callback = _latency_callback = None _property_change_callback = None try: jlib.jack_set_thread_init_callback.argtypes = [ POINTER(jack_client_t), JackThreadInitCallback, c_void_p ] jlib.jack_set_thread_init_callback.restype = c_int except AttributeError: jlib.jack_set_thread_init_callback = None try: jlib.jack_on_shutdown.argtypes = [POINTER(jack_client_t), JackShutdownCallback, c_void_p] jlib.jack_on_shutdown.restype = None except AttributeError: jlib.jack_on_shutdown = None try: jlib.jack_on_info_shutdown.argtypes = [ POINTER(jack_client_t), JackInfoShutdownCallback, c_void_p ] jlib.jack_on_info_shutdown.restype = None except AttributeError: jlib.jack_on_info_shutdown = None try: jlib.jack_set_process_callback.argtypes = [ POINTER(jack_client_t), JackProcessCallback, c_void_p ] jlib.jack_set_process_callback.restype = c_int except AttributeError: jlib.jack_set_process_callback = None try: jlib.jack_set_freewheel_callback.argtypes = [ POINTER(jack_client_t), JackFreewheelCallback, c_void_p ] jlib.jack_set_freewheel_callback.restype = c_int except AttributeError: jlib.jack_set_freewheel_callback = None try: jlib.jack_set_buffer_size_callback.argtypes = [ POINTER(jack_client_t), JackBufferSizeCallback, c_void_p ] jlib.jack_set_buffer_size_callback.restype = c_int except AttributeError: jlib.jack_set_buffer_size_callback = None try: jlib.jack_set_sample_rate_callback.argtypes = [ POINTER(jack_client_t), JackSampleRateCallback, c_void_p ] jlib.jack_set_sample_rate_callback.restype = c_int except AttributeError: jlib.jack_set_sample_rate_callback = None try: jlib.jack_set_client_registration_callback.argtypes = [ POINTER(jack_client_t), JackClientRegistrationCallback, c_void_p ] jlib.jack_set_client_registration_callback.restype = c_int except AttributeError: jlib.jack_set_client_registration_callback = None try: jlib.jack_set_client_rename_callback.argtypes = [ POINTER(jack_client_t), JackClientRenameCallback, c_void_p ] jlib.jack_set_client_rename_callback.restype = c_int except AttributeError: jlib.jack_set_client_rename_callback = None try: jlib.jack_set_port_registration_callback.argtypes = [ POINTER(jack_client_t), JackPortRegistrationCallback, c_void_p ] jlib.jack_set_port_registration_callback.restype = c_int except AttributeError: jlib.jack_set_port_registration_callback = None try: jlib.jack_set_port_connect_callback.argtypes = [ POINTER(jack_client_t), JackPortConnectCallback, c_void_p ] jlib.jack_set_port_connect_callback.restype = c_int except AttributeError: jlib.jack_set_port_connect_callback = None try: jlib.jack_set_port_rename_callback.argtypes = [ POINTER(jack_client_t), JackPortRenameCallback, c_void_p ] jlib.jack_set_port_rename_callback.restype = c_int except AttributeError: jlib.jack_set_port_rename_callback = None try: jlib.jack_set_graph_order_callback.argtypes = [ POINTER(jack_client_t), JackGraphOrderCallback, c_void_p ] jlib.jack_set_graph_order_callback.restype = c_int except AttributeError: jlib.jack_set_graph_order_callback = None try: jlib.jack_set_xrun_callback.argtypes = [POINTER(jack_client_t), JackXRunCallback, c_void_p] jlib.jack_set_xrun_callback.restype = c_int except AttributeError: jlib.jack_set_xrun_callback = None try: jlib.jack_set_latency_callback.argtypes = [ POINTER(jack_client_t), JackLatencyCallback, c_void_p ] jlib.jack_set_latency_callback.restype = c_int except AttributeError: jlib.jack_set_latency_callback = None def set_thread_init_callback(client, thread_init_callback, arg): if jlib.jack_set_thread_init_callback: global _thread_init_callback _thread_init_callback = JackThreadInitCallback(thread_init_callback) return jlib.jack_set_thread_init_callback(client, _thread_init_callback, arg) return -1 def on_shutdown(client, shutdown_callback, arg): if jlib.jack_on_shutdown: global _shutdown_callback _shutdown_callback = JackShutdownCallback(shutdown_callback) jlib.jack_on_shutdown(client, _shutdown_callback, arg) def on_info_shutdown(client, info_shutdown_callback, arg): if jlib.jack_on_info_shutdown: global _info_shutdown_callback _info_shutdown_callback = JackInfoShutdownCallback(info_shutdown_callback) jlib.jack_on_info_shutdown(client, _info_shutdown_callback, arg) def set_process_callback(client, process_callback, arg): if jlib.jack_set_process_callback: global _process_callback _process_callback = JackProcessCallback(process_callback) return jlib.jack_set_process_callback(client, _process_callback, arg) return -1 def set_freewheel_callback(client, freewheel_callback, arg): if jlib.jack_set_freewheel_callback: global _freewheel_callback _freewheel_callback = JackFreewheelCallback(freewheel_callback) return jlib.jack_set_freewheel_callback(client, _freewheel_callback, arg) return -1 def set_buffer_size_callback(client, bufsize_callback, arg): if jlib.jack_set_buffer_size_callback: global _bufsize_callback _bufsize_callback = JackBufferSizeCallback(bufsize_callback) return jlib.jack_set_buffer_size_callback(client, _bufsize_callback, arg) return -1 def set_sample_rate_callback(client, srate_callback, arg): if jlib.jack_set_sample_rate_callback: global _srate_callback _srate_callback = JackSampleRateCallback(srate_callback) return jlib.jack_set_sample_rate_callback(client, _srate_callback, arg) return -1 def set_client_registration_callback(client, client_registration_callback, arg): if jlib.jack_set_client_registration_callback: global _client_registration_callback _client_registration_callback = JackClientRegistrationCallback(client_registration_callback) return jlib.jack_set_client_registration_callback(client, _client_registration_callback, arg) return -1 # JACK2 only: def set_client_rename_callback(client, client_rename_callback, arg): if jlib.jack_set_client_rename_callback: global _client_rename_callback _client_rename_callback = JackClientRenameCallback(client_rename_callback) return jlib.jack_set_client_rename_callback(client, _client_rename_callback, arg) return -1 def set_port_registration_callback(client, port_registration_callback, arg): if jlib.jack_set_port_registration_callback: global _port_registration_callback _port_registration_callback = JackPortRegistrationCallback(port_registration_callback) return jlib.jack_set_port_registration_callback(client, _port_registration_callback, arg) return -1 def set_port_connect_callback(client, connect_callback, arg): if jlib.jack_set_port_connect_callback: global _port_connect_callback _port_connect_callback = JackPortConnectCallback(connect_callback) return jlib.jack_set_port_connect_callback(client, _port_connect_callback, arg) return -1 # JACK2 only: def set_port_rename_callback(client, rename_callback, arg): if jlib.jack_set_port_rename_callback: global _port_rename_callback _port_rename_callback = JackPortRenameCallback(rename_callback) return jlib.jack_set_port_rename_callback(client, _port_rename_callback, arg) return -1 def set_graph_order_callback(client, graph_callback, arg): if jlib.jack_set_graph_order_callback: global _graph_callback _graph_callback = JackGraphOrderCallback(graph_callback) return jlib.jack_set_graph_order_callback(client, _graph_callback, arg) return -1 def set_xrun_callback(client, xrun_callback, arg): if jlib.jack_set_xrun_callback: global _xrun_callback _xrun_callback = JackXRunCallback(xrun_callback) return jlib.jack_set_xrun_callback(client, _xrun_callback, arg) return -1 def set_latency_callback(client, latency_callback, arg): if jlib.jack_set_latency_callback: global _latency_callback _latency_callback = JackLatencyCallback(latency_callback) return jlib.jack_set_latency_callback(client, _latency_callback, arg) return -1 # ------------------------------------------------------------------------------------------------- # Server Control jlib.jack_set_freewheel.argtypes = [POINTER(jack_client_t), c_int] jlib.jack_set_freewheel.restype = c_int jlib.jack_set_buffer_size.argtypes = [POINTER(jack_client_t), jack_nframes_t] jlib.jack_set_buffer_size.restype = c_int jlib.jack_get_sample_rate.argtypes = [POINTER(jack_client_t)] jlib.jack_get_sample_rate.restype = jack_nframes_t jlib.jack_get_buffer_size.argtypes = [POINTER(jack_client_t)] jlib.jack_get_buffer_size.restype = jack_nframes_t jlib.jack_engine_takeover_timebase.argtypes = [POINTER(jack_client_t)] jlib.jack_engine_takeover_timebase.restype = c_int jlib.jack_cpu_load.argtypes = [POINTER(jack_client_t)] jlib.jack_cpu_load.restype = c_float def set_freewheel(client, onoff): return jlib.jack_set_freewheel(client, onoff) def set_buffer_size(client, nframes): return jlib.jack_set_buffer_size(client, nframes) def get_sample_rate(client): return jlib.jack_get_sample_rate(client) def get_buffer_size(client): return jlib.jack_get_buffer_size(client) def engine_takeover_timebase(client): return jlib.jack_engine_takeover_timebase(client) def cpu_load(client): return jlib.jack_cpu_load(client) # ------------------------------------------------------------------------------------------------- # Port Functions jlib.jack_port_register.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p, c_ulong, c_ulong] jlib.jack_port_register.restype = POINTER(jack_port_t) jlib.jack_port_unregister.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jlib.jack_port_unregister.restype = c_int jlib.jack_port_get_buffer.argtypes = [POINTER(jack_port_t), jack_nframes_t] jlib.jack_port_get_buffer.restype = c_void_p jlib.jack_port_name.argtypes = [POINTER(jack_port_t)] jlib.jack_port_name.restype = c_char_p jlib.jack_port_short_name.argtypes = [POINTER(jack_port_t)] jlib.jack_port_short_name.restype = c_char_p jlib.jack_port_flags.argtypes = [POINTER(jack_port_t)] jlib.jack_port_flags.restype = c_int jlib.jack_port_type.argtypes = [POINTER(jack_port_t)] jlib.jack_port_type.restype = c_char_p if JACK2: jlib.jack_port_type_id.argtypes = [POINTER(jack_port_t)] jlib.jack_port_type_id.restype = jack_port_type_id_t jlib.jack_port_is_mine.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jlib.jack_port_is_mine.restype = c_int jlib.jack_port_connected.argtypes = [POINTER(jack_port_t)] jlib.jack_port_connected.restype = c_int jlib.jack_port_connected_to.argtypes = [POINTER(jack_port_t), c_char_p] jlib.jack_port_connected_to.restype = c_int jlib.jack_port_get_connections.argtypes = [POINTER(jack_port_t)] jlib.jack_port_get_connections.restype = POINTER(c_char_p) jlib.jack_port_get_all_connections.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jlib.jack_port_get_all_connections.restype = POINTER(c_char_p) jlib.jack_port_tie.argtypes = [POINTER(jack_port_t), POINTER(jack_port_t)] jlib.jack_port_tie.restype = c_int jlib.jack_port_untie.argtypes = [POINTER(jack_port_t)] jlib.jack_port_untie.restype = c_int jlib.jack_port_set_name.argtypes = [POINTER(jack_port_t), c_char_p] jlib.jack_port_set_name.restype = c_int jlib.jack_port_set_alias.argtypes = [POINTER(jack_port_t), c_char_p] jlib.jack_port_set_alias.restype = c_int jlib.jack_port_unset_alias.argtypes = [POINTER(jack_port_t), c_char_p] jlib.jack_port_unset_alias.restype = c_int jlib.jack_port_get_aliases.argtypes = [POINTER(jack_port_t), POINTER(ARRAY(c_char_p, 2))] jlib.jack_port_get_aliases.restype = c_int jlib.jack_port_request_monitor.argtypes = [POINTER(jack_port_t), c_int] jlib.jack_port_request_monitor.restype = c_int jlib.jack_port_request_monitor_by_name.argtypes = [POINTER(jack_client_t), c_char_p, c_int] jlib.jack_port_request_monitor_by_name.restype = c_int jlib.jack_port_ensure_monitor.argtypes = [POINTER(jack_port_t), c_int] jlib.jack_port_ensure_monitor.restype = c_int jlib.jack_port_monitoring_input.argtypes = [POINTER(jack_port_t)] jlib.jack_port_monitoring_input.restype = c_int jlib.jack_connect.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p] jlib.jack_connect.restype = c_int jlib.jack_disconnect.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p] jlib.jack_disconnect.restype = c_int jlib.jack_port_disconnect.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jlib.jack_port_disconnect.restype = c_int jlib.jack_port_name_size.argtypes = None jlib.jack_port_name_size.restype = c_int jlib.jack_port_type_size.argtypes = None jlib.jack_port_type_size.restype = c_int try: jlib.jack_port_uuid.argtypes = [POINTER(jack_port_t)] jlib.jack_port_uuid.restype = jack_uuid_t except AttributeError: jlib.jack_port_uuid = None try: jlib.jack_port_type_get_buffer_size.argtypes = [POINTER(jack_client_t), c_char_p] jlib.jack_port_type_get_buffer_size.restype = c_size_t except AttributeError: jlib.jack_port_type_get_buffer_size = None def port_register(client, port_name, port_type, flags, buffer_size): return jlib.jack_port_register(client, _e(port_name), _e(port_type), flags, buffer_size) def port_unregister(client, port): return jlib.jack_port_unregister(client, port) def port_get_buffer(port, nframes): return jlib.jack_port_get_buffer(port, nframes) def port_name(port): return _d(jlib.jack_port_name(port)) def port_short_name(port): return _d(jlib.jack_port_short_name(port)) def port_flags(port): return jlib.jack_port_flags(port) def port_type(port): return _d(jlib.jack_port_type(port)) # JACK2 only: def port_type_id(port): return jlib.jack_port_type_id(port) def port_is_mine(client, port): return jlib.jack_port_is_mine(client, port) def port_connected(port): return jlib.jack_port_connected(port) def port_connected_to(port, port_name): return jlib.jack_port_connected_to(port, _e(port_name)) def port_get_connections(port): ports = jlib.jack_port_get_connections(port) if not ports: return for port_name in ports: if port_name is None: break yield _d(port_name) def port_get_all_connections(client, port): ports = jlib.jack_port_get_all_connections(client, port) if not ports: return for port_name in ports: if port_name is None: break yield _d(port_name) def port_tie(src, dst): return jlib.jack_port_tie(src, dst) def port_untie(port): return jlib.jack_port_untie(port) def port_set_name(port, port_name): return jlib.jack_port_set_name(port, _e(port_name)) def port_set_alias(port, alias): return jlib.jack_port_set_alias(port, _e(alias)) def port_unset_alias(port, alias): return jlib.jack_port_unset_alias(port, _e(alias)) def port_get_aliases(port): # NOTE - this function has no 2nd argument in jacklib # Instead, aliases will be passed in return value, in form of (int ret, str alias1, str alias2) name_size = port_name_size() alias_type = c_char_p * 2 aliases = alias_type(b" " * name_size, b" " * name_size) ret = jlib.jack_port_get_aliases(port, pointer(aliases)) return ret, _d(aliases[0]), _d(aliases[1]) def port_request_monitor(port, onoff): return jlib.jack_port_request_monitor(port, onoff) def port_request_monitor_by_name(client, port_name, onoff): return jlib.jack_port_request_monitor_by_name(client, _e(port_name), onoff) def port_ensure_monitor(port, onoff): return jlib.jack_port_ensure_monitor(port, onoff) def port_monitoring_input(port): return jlib.jack_port_monitoring_input(port) def connect(client, source_port, destination_port): return jlib.jack_connect(client, _e(source_port), _e(destination_port)) def disconnect(client, source_port, destination_port): return jlib.jack_disconnect(client, _e(source_port), _e(destination_port)) def port_disconnect(client, port): return jlib.jack_port_disconnect(client, port) def port_name_size(): return jlib.jack_port_name_size() def port_type_size(): return jlib.jack_port_type_size() def port_type_get_buffer_size(client, port_type): if jlib.jack_port_type_get_buffer_size: return jlib.jack_port_type_get_buffer_size(client, _e(port_type)) return 0 def port_uuid(port): if jlib.jack_port_uuid: return jlib.jack_port_uuid(port) return -1 # ------------------------------------------------------------------------------------------------- # Latency Functions jlib.jack_port_set_latency.argtypes = [POINTER(jack_port_t), jack_nframes_t] jlib.jack_port_set_latency.restype = None try: jlib.jack_port_get_latency_range.argtypes = [ POINTER(jack_port_t), jack_latency_callback_mode_t, POINTER(jack_latency_range_t) ] jlib.jack_port_get_latency_range.restype = None except AttributeError: jlib.jack_port_get_latency_range = None try: jlib.jack_port_set_latency_range.argtypes = [ POINTER(jack_port_t), jack_latency_callback_mode_t, POINTER(jack_latency_range_t) ] jlib.jack_port_set_latency_range.restype = None except AttributeError: jlib.jack_port_set_latency_range = None jlib.jack_recompute_total_latencies.argtypes = [POINTER(jack_client_t)] jlib.jack_recompute_total_latencies.restype = c_int jlib.jack_port_get_latency.argtypes = [POINTER(jack_port_t)] jlib.jack_port_get_latency.restype = jack_nframes_t jlib.jack_port_get_total_latency.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jlib.jack_port_get_total_latency.restype = jack_nframes_t jlib.jack_recompute_total_latency.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jlib.jack_recompute_total_latency.restype = c_int def port_set_latency(port, nframes): jlib.jack_port_set_latency(port, nframes) def port_get_latency_range(port, mode, range_): if jlib.jack_port_get_latency_range: jlib.jack_port_get_latency_range(port, mode, range_) def port_set_latency_range(port, mode, range_): if jlib.jack_port_set_latency_range: jlib.jack_port_set_latency_range(port, mode, range_) def recompute_total_latencies(): return jlib.jack_recompute_total_latencies() def port_get_latency(port): return jlib.jack_port_get_latency(port) def port_get_total_latency(client, port): return jlib.jack_port_get_total_latency(client, port) def recompute_total_latency(client, port): return jlib.jack_recompute_total_latency(client, port) # ------------------------------------------------------------------------------------------------- # Port Searching jlib.jack_get_ports.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p, c_ulong] jlib.jack_get_ports.restype = POINTER(c_char_p) jlib.jack_port_by_name.argtypes = [POINTER(jack_client_t), c_char_p] jlib.jack_port_by_name.restype = POINTER(jack_port_t) jlib.jack_port_by_id.argtypes = [POINTER(jack_client_t), jack_port_id_t] jlib.jack_port_by_id.restype = POINTER(jack_port_t) def get_ports(client, port_name_pattern=None, type_name_pattern=None, flags=0): return jlib.jack_get_ports(client, _e(port_name_pattern or ''), _e(type_name_pattern or ''), flags) def port_by_name(client, port_name): return jlib.jack_port_by_name(client, _e(port_name)) def port_by_id(client, port_id): return jlib.jack_port_by_id(client, port_id) # ------------------------------------------------------------------------------------------------- # Time Functions jlib.jack_frames_since_cycle_start.argtypes = [POINTER(jack_client_t)] jlib.jack_frames_since_cycle_start.restype = jack_nframes_t jlib.jack_frame_time.argtypes = [POINTER(jack_client_t)] jlib.jack_frame_time.restype = jack_nframes_t jlib.jack_last_frame_time.argtypes = [POINTER(jack_client_t)] jlib.jack_last_frame_time.restype = jack_nframes_t try: # JACK_OPTIONAL_WEAK_EXPORT jlib.jack_get_cycle_times.argtypes = [ POINTER(jack_client_t), POINTER(jack_nframes_t), POINTER(jack_time_t), POINTER(jack_time_t), POINTER(c_float) ] jlib.jack_get_cycle_times.restype = c_int except AttributeError: jlib.jack_get_cycle_times = None jlib.jack_frames_to_time.argtypes = [POINTER(jack_client_t), jack_nframes_t] jlib.jack_frames_to_time.restype = jack_time_t jlib.jack_time_to_frames.argtypes = [POINTER(jack_client_t), jack_time_t] jlib.jack_time_to_frames.restype = jack_nframes_t jlib.jack_get_time.argtypes = None jlib.jack_get_time.restype = jack_time_t def frames_since_cycle_start(client): return jlib.jack_frames_since_cycle_start(client) def frame_time(client): return jlib.jack_frame_time(client) def last_frame_time(client): return jlib.jack_last_frame_time(client) def get_cycle_times(client, current_frames, current_usecs, next_usecs, period_usecs): # JACK_OPTIONAL_WEAK_EXPORT if jlib.jack_frames_to_time: return jlib.jack_get_cycle_times(client, current_frames, current_usecs, next_usecs, period_usecs) return -1 def frames_to_time(client, nframes): return jlib.jack_frames_to_time(client, nframes) def time_to_frames(client, time): return jlib.jack_time_to_frames(client, time) def get_time(): return jlib.jack_get_time() # ------------------------------------------------------------------------------------------------- # Error Output # TODO # ------------------------------------------------------------------------------------------------- # Misc _error_callback = None jlib.jack_free.argtypes = [c_void_p] jlib.jack_free.restype = None try: jlib.jack_set_error_function.argtypes = [JackErrorCallback] jlib.jack_set_error_function.restype = None except AttributeError: jlib.jack_set_error_function = None def set_error_function(error_callback): global _error_callback if jlib.jack_set_error_function: _error_callback = JackErrorCallback(error_callback) jlib.jack_set_error_function(_error_callback) def free(ptr): return jlib.jack_free(ptr) # ------------------------------------------------------------------------------------------------- # Transport _sync_callback = _timebase_callback = None jlib.jack_release_timebase.argtypes = [POINTER(jack_client_t)] jlib.jack_release_timebase.restype = c_int jlib.jack_set_sync_callback.argtypes = [POINTER(jack_client_t), JackSyncCallback, c_void_p] jlib.jack_set_sync_callback.restype = c_int jlib.jack_set_sync_timeout.argtypes = [POINTER(jack_client_t), jack_time_t] jlib.jack_set_sync_timeout.restype = c_int jlib.jack_set_timebase_callback.argtypes = [ POINTER(jack_client_t), c_int, JackTimebaseCallback, c_void_p ] jlib.jack_set_timebase_callback.restype = c_int jlib.jack_transport_locate.argtypes = [POINTER(jack_client_t), jack_nframes_t] jlib.jack_transport_locate.restype = c_int jlib.jack_transport_query.argtypes = [POINTER(jack_client_t), POINTER(jack_position_t)] jlib.jack_transport_query.restype = jack_transport_state_t jlib.jack_get_current_transport_frame.argtypes = [POINTER(jack_client_t)] jlib.jack_get_current_transport_frame.restype = jack_nframes_t jlib.jack_transport_reposition.argtypes = [POINTER(jack_client_t), POINTER(jack_position_t)] jlib.jack_transport_reposition.restype = c_int jlib.jack_transport_start.argtypes = [POINTER(jack_client_t)] jlib.jack_transport_start.restype = None jlib.jack_transport_stop.argtypes = [POINTER(jack_client_t)] jlib.jack_transport_stop.restype = None def release_timebase(client): return jlib.jack_release_timebase(client) def set_sync_callback(client, sync_callback, arg): global _sync_callback _sync_callback = JackSyncCallback(sync_callback) return jlib.jack_set_sync_callback(client, _sync_callback, arg) def set_sync_timeout(client, timeout): return jlib.jack_set_sync_timeout(client, timeout) def set_timebase_callback(client, conditional, timebase_callback, arg): global _timebase_callback _timebase_callback = JackTimebaseCallback(timebase_callback) return jlib.jack_set_timebase_callback(client, conditional, _timebase_callback, arg) def transport_locate(client, frame): return jlib.jack_transport_locate(client, frame) def transport_query(client, pos): return jlib.jack_transport_query(client, pos) def get_current_transport_frame(client): return jlib.jack_get_current_transport_frame(client) def transport_reposition(client, pos): return jlib.jack_transport_reposition(client, pos) def transport_start(client): return jlib.jack_transport_start(client) def transport_stop(client): return jlib.jack_transport_stop(client) # ------------------------------------------------------------------------------------------------- # MIDI jlib.jack_midi_get_event_count.argtypes = [c_void_p] jlib.jack_midi_get_event_count.restype = jack_nframes_t jlib.jack_midi_event_get.argtypes = [POINTER(jack_midi_event_t), c_void_p, c_uint32] jlib.jack_midi_event_get.restype = c_int jlib.jack_midi_clear_buffer.argtypes = [c_void_p] jlib.jack_midi_clear_buffer.restype = None jlib.jack_midi_max_event_size.argtypes = [c_void_p] jlib.jack_midi_max_event_size.restype = c_size_t jlib.jack_midi_event_reserve.argtypes = [c_void_p, jack_nframes_t, c_size_t] jlib.jack_midi_event_reserve.restype = POINTER(jack_midi_data_t) jlib.jack_midi_event_write.argtypes = [ c_void_p, jack_nframes_t, POINTER(jack_midi_data_t), c_size_t ] jlib.jack_midi_event_write.restype = c_int jlib.jack_midi_get_lost_event_count.argtypes = [c_void_p] jlib.jack_midi_get_lost_event_count.restype = c_uint32 def midi_get_event_count(port_buffer): return jlib.jack_midi_get_event_count(port_buffer) def midi_event_get(event, port_buffer, event_index): return jlib.jack_midi_event_get(event, port_buffer, event_index) def midi_clear_buffer(port_buffer): return jlib.jack_midi_clear_buffer(port_buffer) def midi_max_event_size(port_buffer): return jlib.jack_midi_max_event_size(port_buffer) def midi_event_reserve(port_buffer, time, data_size): return jlib.jack_midi_event_reserve(port_buffer, time, data_size) def midi_event_write(port_buffer, time, data, data_size): return jlib.jack_midi_event_write(port_buffer, time, data, data_size) def midi_get_lost_event_count(port_buffer): return jlib.jack_midi_get_lost_event_count(port_buffer) # ------------------------------------------------------------------------------------------------- # Session _session_callback = None try: jlib.jack_set_session_callback.argtypes = [ POINTER(jack_client_t), JackSessionCallback, c_void_p ] jlib.jack_set_session_callback.restype = c_int except AttributeError: jlib.jack_set_session_callback = None try: jlib.jack_session_reply.argtypes = [POINTER(jack_client_t), POINTER(jack_session_event_t)] jlib.jack_session_reply.restype = c_int except AttributeError: jlib.jack_session_reply = None try: jlib.jack_session_event_free.argtypes = [POINTER(jack_session_event_t)] jlib.jack_session_event_free.restype = None except AttributeError: jlib.jack_session_event_free = None try: jlib.jack_client_get_uuid.argtypes = [POINTER(jack_client_t)] jlib.jack_client_get_uuid.restype = c_char_p except AttributeError: jlib.jack_client_get_uuid = None try: jlib.jack_session_notify.argtypes = [ POINTER(jack_client_t), c_char_p, jack_session_event_type_t, c_char_p ] jlib.jack_session_notify.restype = POINTER(jack_session_command_t) except AttributeError: jlib.jack_session_notify = None try: jlib.jack_session_commands_free.argtypes = [POINTER(jack_session_command_t)] jlib.jack_session_commands_free.restype = None except AttributeError: jlib.jack_session_commands_free = None try: jlib.jack_get_uuid_for_client_name.argtypes = [POINTER(jack_client_t), c_char_p] jlib.jack_get_uuid_for_client_name.restype = c_char_p except AttributeError: jlib.jack_get_uuid_for_client_name = None try: jlib.jack_get_client_name_by_uuid.argtypes = [POINTER(jack_client_t), c_char_p] jlib.jack_get_client_name_by_uuid.restype = c_char_p except AttributeError: jlib.jack_get_client_name_by_uuid = None try: jlib.jack_reserve_client_name.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p] jlib.jack_reserve_client_name.restype = c_int except AttributeError: jlib.jack_reserve_client_name = None try: jlib.jack_client_has_session_callback.argtypes = [POINTER(jack_client_t), c_char_p] jlib.jack_client_has_session_callback.restype = c_int except AttributeError: jlib.jack_client_has_session_callback = None try: jlib.jack_uuid_parse.argtypes = [c_char_p, POINTER(jack_uuid_t)] jlib.jack_uuid_parse.restype = c_int except AttributeError: jlib.jack_uuid_parse = None try: jlib.jack_uuid_unparse.argtypes = [jack_uuid_t, c_char_p] jlib.jack_uuid_unparse.restype = None except AttributeError: jlib.jack_uuid_unparse = None def set_session_callback(client, session_callback, arg): if jlib.jack_set_session_callback: global _session_callback _session_callback = JackSessionCallback(session_callback) return jlib.jack_set_session_callback(client, _session_callback, arg) return -1 def session_reply(client, event): if jlib.jack_session_reply: return jlib.jack_session_reply(client, event) return -1 def session_event_free(event): if jlib.jack_session_event_free: jlib.jack_session_event_free(event) def client_get_uuid(client): if jlib.jack_client_get_uuid: return _d(jlib.jack_client_get_uuid(client)) return None def session_notify(client, target, type_, path): if jlib.jack_session_notify: return jlib.jack_session_notify(client, _e(target), type_, _e(path)) return jack_session_command_t() def session_commands_free(cmds): if jlib.jack_session_commands_free: jlib.jack_session_commands_free(cmds) def get_uuid_for_client_name(client, client_name): if jlib.jack_get_uuid_for_client_name: return jlib.jack_get_uuid_for_client_name(client, _e(client_name)) return None def get_client_name_by_uuid(client, client_uuid): if jlib.jack_get_client_name_by_uuid: return jlib.jack_get_client_name_by_uuid(client, _e(client_uuid)) return None def reserve_client_name(client, name, uuid): if jlib.jack_reserve_client_name: return jlib.jack_reserve_client_name(client, _e(name), _e(uuid)) return -1 def client_has_session_callback(client, client_name): if jlib.jack_client_has_session_callback: return jlib.jack_client_has_session_callback(client, _e(client_name)) return -1 def uuid_parse(uuid_cstr): if jlib.jack_uuid_parse and uuid_cstr is not None: uuid = jack_uuid_t() res = jlib.jack_uuid_parse(uuid_cstr, byref(uuid)) return uuid if res != -1 else None return -1 def uuid_unparse(uuid, encoding=ENCODING): if jlib.jack_uuid_unparse: uuid_str = c_char_p(b" " * JACK_UUID_STRING_SIZE) jlib.jack_uuid_unparse(uuid, uuid_str) return _d(uuid_str.value, encoding) return "" # ------------------------------------------------------------------------------------------------- # Custom _custom_appearance_callback = None try: jlib.jack_custom_publish_data.argtypes = [POINTER(jack_client_t), c_char_p, c_void_p, c_size_t] jlib.jack_custom_publish_data.restype = c_int except AttributeError: jlib.jack_custom_publish_data = None try: jlib.jack_custom_get_data.argtypes = [ POINTER(jack_client_t), c_char_p, c_char_p, POINTER(c_void_p), POINTER(c_size_t) ] jlib.jack_custom_get_data.restype = c_int except AttributeError: jlib.jack_custom_get_data = None try: jlib.jack_custom_unpublish_data.argtypes = [POINTER(jack_client_t), c_char_p] jlib.jack_custom_unpublish_data.restype = c_int except AttributeError: jlib.jack_custom_unpublish_data = None try: jlib.jack_custom_get_keys.argtypes = [POINTER(jack_client_t), c_char_p] jlib.jack_custom_get_keys.restype = POINTER(c_char_p) except AttributeError: jlib.jack_custom_get_keys = None try: jlib.jack_custom_set_data_appearance_callback.argtypes = [ POINTER(jack_client_t), JackCustomDataAppearanceCallback, c_void_p ] jlib.jack_custom_set_data_appearance_callback.restype = c_int except AttributeError: jlib.jack_custom_set_data_appearance_callback = None def custom_publish_data(client, key, data, size): if jlib.jack_custom_publish_data: return jlib.jack_custom_publish_data(client, _e(key), data, size) return -1 def custom_get_data(client, client_name, key): # NOTE - this function has no extra arguments in jacklib # Instead, data and size will be passed in return value # in form of (int ret, void* data, size_t size) if jlib.jack_custom_get_data: data = c_void_p(0) size = c_size_t(0) ret = jlib.jack_custom_get_data(client, _e(client_name), _e(key), pointer(data), pointer(size)) return ret, data, size return -1, None, 0 def custom_unpublish_data(client, key): if jlib.jack_custom_unpublish_data: return jlib.jack_custom_unpublish_data(client, _e(key)) return -1 def custom_get_keys(client, client_name): if jlib.jack_custom_get_keys: return jlib.jack_custom_get_keys(client, _e(client_name)) return None def custom_set_data_appearance_callback(client, custom_callback, arg): if jlib.jack_custom_set_data_appearance_callback: global _custom_appearance_callback _custom_appearance_callback = JackCustomDataAppearanceCallback(custom_callback) return jlib.jack_custom_set_data_appearance_callback(client, _custom_appearance_callback, arg) return -1 # ------------------------------------------------------------------------------------------------- # Meta data Property = namedtuple('Property', ('key', 'value', 'type')) try: jlib.jack_free_description.argtypes = [POINTER(jack_description_t), c_int] jlib.jack_free_description.restype = None jlib.jack_get_all_properties.argtypes = [POINTER(POINTER(jack_description_t))] jlib.jack_get_all_properties.restype = c_int jlib.jack_get_properties.argtypes = [jack_uuid_t, POINTER(jack_description_t)] jlib.jack_get_properties.restype = c_int jlib.jack_get_property.argtypes = [jack_uuid_t, c_char_p, POINTER(c_char_p), POINTER(c_char_p)] jlib.jack_get_property.restype = c_int jlib.jack_remove_all_properties.argtypes = [POINTER(jack_client_t)] jlib.jack_remove_all_properties.restype = c_int jlib.jack_remove_properties.argtypess = [POINTER(jack_client_t), POINTER(jack_uuid_t)] jlib.jack_remove_properties.restype = c_int jlib.jack_remove_property.argtypes = [POINTER(jack_client_t), POINTER(jack_uuid_t), c_char_p] jlib.jack_remove_property.restype = c_int jlib.jack_set_property.argtypes = [ POINTER(jack_client_t), jack_uuid_t, c_char_p, c_char_p, c_char_p ] jlib.jack_set_property.restype = c_int jlib.jack_set_property_change_callback.argtypes = [ POINTER(jack_client_t), JackPropertyChangeCallback, c_void_p ] jlib.jack_set_property_change_callback.restype = c_int except AttributeError: jlib.jack_free_description = None jlib.jack_get_properties = None jlib.jack_get_property = None jlib.jack_remove_all_properties = None jlib.jack_remove_properties = None jlib.jack_remove_property = None jlib.jack_set_property = None jlib.jack_set_property_change_callback = None def free_description(description, free_description_itself=0): jlib.jack_free_description(description, free_description_itself) def _decode_property(prop, encoding=ENCODING): key, value, type_ = prop.key, prop.data, prop.type decode_value = True try: key = _d(key, encoding) except UnicodeDecodeError: pass if type_: try: type_ = _d(type_, encoding) except UnicodeDecodeError: pass else: decode_value = type_.startswith('text/') if decode_value: try: value = _d(value, encoding) except UnicodeDecodeError: pass return Property(key, value, type_) def get_all_properties(encoding=ENCODING): descriptions = POINTER(jack_description_t)() ret = jlib.jack_get_all_properties(byref(descriptions)) results = {} if ret != -1: for p_idx in range(ret): description = descriptions[p_idx] if description.property_cnt: results[description.subject] = [ _decode_property(description.properties[p_idx], encoding) for p_idx in range(description.property_cnt) ] jlib.jack_free_description(description, 0) free(descriptions) return results def get_properties(subject, encoding=ENCODING): description = jack_description_t() ret = jlib.jack_get_properties(subject, byref(description)) results = [] if ret != -1: for p_idx in range(description.property_cnt): results.append(_decode_property(description.properties[p_idx], encoding)) jlib.jack_free_description(byref(description), 0) return results def get_client_properties(client, client_uuid, encoding=ENCODING): if isinstance(client_uuid, str): client_uuid = get_uuid_for_client_name(client, client_uuid) return get_properties(uuid_parse(client_uuid), encoding) def get_port_properties(client, port, encoding=ENCODING): if not isinstance(port, POINTER(jack_port_t)): port = port_by_name(client, port) return get_properties(port_uuid(port), encoding) def get_property(subject, key, encoding=ENCODING): # FIXME: how to handle non-null terminated data in value? # We wouldn't know the length of the data in the value buffer. # This seems to be an oversight in the JACK meta data API. value_c = c_char_p() type_c = c_char_p() ret = jlib.jack_get_property(subject, _e(key), byref(value_c), byref(type_c)) value = value_c.value if ret != -1: decode_value = True if type_c: try: type_ = _d(type_c.value, encoding) except UnicodeDecodeError: # If type can't be decoded, we assume it's neither a mimetype # nor a URI, so we don't know how to interpret it and won't use # it to decide whether to decode the property value. type_ = type_c.value else: decode_value = type_.startswith('text/') free(type_c) else: type_ = None if decode_value: try: value = _d(value_c.value, encoding) except UnicodeDecodeError: pass free(value_c) return Property(key, value, type_) def get_client_property(client, client_uuid, key, encoding=ENCODING): if isinstance(client_uuid, str): client_uuid = get_uuid_for_client_name(client, client_uuid) return get_property(uuid_parse(client_uuid), key, encoding) def get_port_property(client, port, key, encoding=ENCODING): if not isinstance(port, POINTER(jack_port_t)): port = port_by_name(client, port) return get_property(port_uuid(port), key, encoding) def get_port_pretty_name(client, port, encoding=ENCODING): prop = get_port_property(client, port, JACK_METADATA_PRETTY_NAME, encoding) return prop.value if prop else None def remove_all_properties(client): return jlib.jack_remove_property(client) def remove_properties(client, subject): return jlib.jack_remove_property(client, subject) def remove_client_properties(client, client_uuid): if isinstance(client_uuid, str): client_uuid = get_uuid_for_client_name(client, client_uuid) return remove_properties(client, uuid_parse(client_uuid)) def remove_port_properties(client, port): if not isinstance(port, POINTER(jack_port_t)): port = port_by_name(client, port) return remove_properties(client, port_uuid(port)) def remove_property(client, subject, key, encoding=ENCODING): return jlib.jack_remove_property(client, subject, _e(key, encoding)) def remove_client_property(client, client_uuid, key, encoding=ENCODING): if isinstance(client_uuid, str): client_uuid = get_uuid_for_client_name(client, client_uuid) return remove_property(client, uuid_parse(client_uuid), key, encoding) def remove_port_property(client, port, key, encoding=ENCODING): if not isinstance(port, POINTER(jack_port_t)): port = port_by_name(client, port) return remove_property(client, port_uuid(port), key, encoding) def set_property(client, subject, key, value, type=None, encoding=ENCODING): if value is not None and encoding: value = _e(value, encoding) if type is not None and encoding: type = _e(type, encoding) return jlib.jack_set_property(client, subject, _e(key, encoding), value, type) def set_client_property(client, client_uuid, key, value, type=None, encoding=ENCODING): if isinstance(client_uuid, str): client_uuid = get_uuid_for_client_name(client, client_uuid) uuid = uuid_parse(client_uuid) return set_property(client, uuid, key, value, type, encoding) if uuid != -1 else -1 def set_port_property(client, port, key, value, type=None, encoding=ENCODING): if not isinstance(port, POINTER(jack_port_t)): port = port_by_name(client, port) uuid = port_uuid(port) return set_property(client, uuid, key, value, type, encoding) if uuid != -1 else -1 def set_port_pretty_name(client, port, value, encoding=ENCODING): return set_port_property(client, port, JACK_METADATA_PRETTY_NAME, value, 'text/plain', encoding) def set_property_change_callback(client, callback, arg=None): if jlib.jack_set_property_change_callback: global _property_change_callback _property_change_callback = JackPropertyChangeCallback(callback) return jlib.jack_set_property_change_callback(client, _property_change_callback, arg) return -1 RaySession-0.12.2/src/jack_patchbay_to_osc/jacklib/helpers.py000066400000000000000000000104771417052567600242540ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Helper functions for extra jacklib functionality # Copyright (C) 2012-2013 Filipe Coelho # 2016-2021 Christopher Arndt # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the COPYING file # ------------------------------------------------------------------------------------------------- # Try Import jacklib from __future__ import absolute_import, print_function, unicode_literals from . import api as jacklib # ------------------------------------------------------------------------------------------------- # Get JACK error status as string def get_jack_status_error_string(cStatus): status = cStatus.value if status == 0x0: return "" errorString = [] if status == jacklib.JackFailure: # Only include this generic message if no other error status is set errorString.append("Overall operation failed") if status & jacklib.JackInvalidOption: errorString.append("The operation contained an invalid or unsupported option") if status & jacklib.JackNameNotUnique: errorString.append("The desired client name was not unique") if status & jacklib.JackServerStarted: errorString.append("The JACK server was started as a result of this operation") if status & jacklib.JackServerFailed: errorString.append("Unable to connect to the JACK server") if status & jacklib.JackServerError: errorString.append("Communication error with the JACK server") if status & jacklib.JackNoSuchClient: errorString.append("Requested client does not exist") if status & jacklib.JackLoadFailure: errorString.append("Unable to load internal client") if status & jacklib.JackInitFailure: errorString.append("Unable to initialize client") if status & jacklib.JackShmFailure: errorString.append("Unable to access shared memory") if status & jacklib.JackVersionError: errorString.append("Client's protocol version does not match") if status & jacklib.JackBackendError: errorString.append("Backend Error") if status & jacklib.JackClientZombie: errorString.append("Client is being shutdown against its will") return ";\n".join(errorString) + "." # ------------------------------------------------------------------------------------------------- # Convert C char** -> Python list def c_char_p_p_to_list(c_char_p_p, encoding=jacklib.ENCODING, errors='ignore'): i = 0 retList = [] if not c_char_p_p: return retList while True: new_char_p = c_char_p_p[i] if not new_char_p: break retList.append(new_char_p.decode(encoding=encoding, errors=errors)) i += 1 jacklib.free(c_char_p_p) return retList # ------------------------------------------------------------------------------------------------- # Convert C void* -> string def voidptr2str(void_p): char_p = jacklib.cast(void_p, jacklib.c_char_p) string = str(char_p.value, encoding="utf-8") return string # ------------------------------------------------------------------------------------------------- # Convert C void* -> jack_default_audio_sample_t* def translate_audio_port_buffer(void_p): return jacklib.cast(void_p, jacklib.POINTER(jacklib.jack_default_audio_sample_t)) # ------------------------------------------------------------------------------------------------- # Convert a JACK midi buffer into a python variable-size list def translate_midi_event_buffer(void_p, size): if not void_p: return () elif size == 1: return (void_p[0],) elif size == 2: return (void_p[0], void_p[1]) elif size == 3: return (void_p[0], void_p[1], void_p[2]) elif size == 4: return (void_p[0], void_p[1], void_p[2], void_p[3]) else: return () RaySession-0.12.2/src/jack_patchbay_to_osc/jacklib/version.py000066400000000000000000000000261417052567600242640ustar00rootroot00000000000000__version__ = "0.1.0" RaySession-0.12.2/src/jack_patchbay_to_osc/osc_server.py000066400000000000000000000327001417052567600233560ustar00rootroot00000000000000 import sys import time #import pickle import tempfile import socket import json import subprocess from liblo import Server, Address, make_method import jacklib ### Code copied from shared/ray.py ### we don't import ray.py here, because this executable is Qt free ### TODO : make a miniray.py with only Qt free code class Machine192: ip = '' read_done = False @staticmethod def read()->str: try: ips = subprocess.check_output( ['ip', 'route', 'get', '1']).decode() ip_line = ips.partition('\n')[0] ip_end = ip_line.rpartition('src ')[2] ip = ip_end.partition(' ')[0] except BaseException: try: ips = subprocess.check_output(['hostname', '-I']).decode() ip = ips.split(' ')[0] except BaseException: return '' if ip.count('.') != 3: return '' return ip @classmethod def get(cls)->str: if cls.read_done: return cls.ip cls.ip = cls.read() cls.read_done = True return cls.ip def areOnSameMachine(url1, url2): if url1 == url2: return True try: address1 = Address(url1) address2 = Address(url2) except BaseException: return False if address1.hostname == address2.hostname: return True try: if (socket.gethostbyname(address1.hostname) in ('127.0.0.1', '127.0.1.1') and socket.gethostbyname(address2.hostname) in ('127.0.0.1', '127.0.1.1')): return True if socket.gethostbyaddr( address1.hostname) == socket.gethostbyaddr( address2.hostname): return True except BaseException: try: ip = Machine192.get() if ip not in (address1.hostname, address2.hostname): return False try: if socket.gethostbyname( address1.hostname) in ( '127.0.0.1', '127.0.1.1'): if address2.hostname == ip: return True except BaseException: if socket.gethostbyname( address2.hostname) in ( '127.0.0.1', '127.0.1.1'): if address1.hostname == ip: return True except BaseException: return False return False return False class OscJackPatch(Server): slow_wait_time = 0.020 slow_wait_num = 50 def __init__(self, main_object): Server.__init__(self) self.add_method('/ray/patchbay/add_gui', 's', self._ray_patchbay_add_gui) self.add_method('/ray/patchbay/gui_disannounce', '', self._ray_patchbay_gui_disannounce) self.add_method('ray/patchbay/port/set_alias', 'sis', self._ray_patchbay_port_set_alias) self.add_method('/ray/patchbay/connect', 'ss', self._ray_patchbay_connect) self.add_method('/ray/patchbay/disconnect', 'ss', self._ray_patchbay_disconnect) self.add_method('/ray/patchbay/set_buffer_size', 'i', self._ray_patchbay_set_buffersize) self.add_method('/ray/patchbay/refresh', '', self._ray_patchbay_refresh) self.add_method('/ray/patchbay/set_metadata', 'hss', self._ray_patchbay_set_metadata) self.main_object = main_object self.jack_client = main_object.jack_client self.port_list = main_object.port_list self.connection_list = main_object.connection_list self.metadata_list = main_object.metadata_list self.client_list = main_object.client_list self.gui_list = [] self._tmp_gui_url = '' self._terminate = False def set_tmp_gui_url(self, gui_url): self._tmp_gui_url = gui_url def set_jack_client(self, jack_client): self.jack_client = jack_client def _ray_patchbay_add_gui(self, path, args, types, src_addr): self.add_gui(args[0]) def _ray_patchbay_gui_disannounce(self, path, args, types, src_addr): for gui_addr in self.gui_list: if gui_addr.url == src_addr.url: # possible because we break the loop self.gui_list.remove(gui_addr) break if not self.gui_list: # no more GUI connected, no reason to exists anymore self._terminate = True def _ray_patchbay_port_set_alias(self, path, args, types, src_addr): port_name, alias_num, alias = args for port in self.port_list: if port.name == port_name: # TODO # better would be to use jacklib.port_set_alias(port, alias) # but this is very confuse # 2 aliases possibles, but only one arg to this method (after port). if alias_num == 1: port.alias_1 = alias elif alias_num == 2: port.alias_2 = alias break def _ray_patchbay_connect(self, path, args): port_out_name, port_in_name = args #connect here jacklib.connect(self.jack_client, port_out_name, port_in_name) def _ray_patchbay_disconnect(self, path, args): port_out_name, port_in_name = args #disconnect here jacklib.disconnect(self.jack_client, port_out_name, port_in_name) def _ray_patchbay_set_buffersize(self, path, args): buffer_size = args[0] self.main_object.set_buffer_size(buffer_size) def _ray_patchbay_refresh(self, path, args): self.main_object.refresh() def _ray_patchbay_set_metadata(self, path, args): uuid, key, value = args self.main_object.set_metadata(uuid, key, value) def send_gui(self, *args): for gui_addr in self.gui_list: self.send(gui_addr, *args) def multi_send(self, src_addr_list, *args): for src_addr in src_addr_list: self.send(src_addr, *args) def send_local_data(self, src_addr_list): # at invitation, if gui is on the same machine # it's prefferable to save all data in /tmp # Indeed, to prevent OSC packet loses # this daemon will send a lot of OSC messages not too fast # so here, it is faster, and prevent OSC saturation. # json format (and not binary with pickle) is choosen # this way, code language of the GUI is not a blocker patchbay_data = {'ports': [], 'connections': [], 'metadatas': [], 'clients': []} for port in self.port_list: port_dict = {'name': port.name, 'type': port.type, 'flags': port.flags, 'uuid': port.uuid} patchbay_data['ports'].append(port_dict) for connection in self.connection_list: conn_dict = {'port_out_name': connection[0], 'port_in_name': connection[1]} patchbay_data['connections'].append(conn_dict) for metadata in self.metadata_list: patchbay_data['metadatas'].append(metadata) for client_dict in self.client_list: patchbay_data['clients'].append(client_dict) for src_addr in src_addr_list: # tmp file is deleted by the gui itself once read # so there is one tmp file per local GUI file = tempfile.NamedTemporaryFile(delete=False, mode='w+') json.dump(patchbay_data, file) file.close() self.send(src_addr, '/ray/gui/patchbay/fast_temp_file_running', file.name) def send_distant_data(self, src_addr_list): # we need to slow the long process of messages sends # to prevent loss packets self.multi_send(src_addr_list, '/ray/gui/patchbay/big_packets', 0) n = 0 increment = len(src_addr_list) for port in self.port_list: self.multi_send(src_addr_list, '/ray/gui/patchbay/port_added', port.name, port.type, port.flags, port.uuid) n += increment if n % self.slow_wait_num < increment: self.multi_send(src_addr_list, '/ray/gui/patchbay/big_packets', 1) time.sleep(self.slow_wait_time) self.multi_send(src_addr_list, '/ray/gui/patchbay/big_packets', 0) for connection in self.connection_list: self.multi_send(src_addr_list, '/ray/gui/patchbay/connection_added', connection[0], connection[1]) n += increment if n % self.slow_wait_num < increment: self.multi_send(src_addr_list, '/ray/gui/patchbay/big_packets', 1) time.sleep(self.slow_wait_time) self.multi_send(src_addr_list, '/ray/gui/patchbay/big_packets', 0) for metadata in self.metadata_list: self.multi_send(src_addr_list, '/ray/gui/patchbay/metadata_updated', metadata['uuid'], metadata['key'], metadata['value']) n += increment if n % self.slow_wait_num < increment: self.multi_send(src_addr_list, '/ray/gui/patchbay/big_packets', 1) time.sleep(self.slow_wait_time) self.multi_send(src_addr_list, '/ray/gui/patchbay/big_packets', 0) self.multi_send(src_addr_list, '/ray/gui/patchbay/big_packets', 1) def add_gui(self, gui_url): gui_addr = Address(gui_url) if gui_addr is None: return self.send(gui_addr, '/ray/gui/patchbay/announce', int(self.main_object.jack_running), self.main_object.samplerate, self.main_object.buffer_size) self.send(gui_addr, '/ray/gui/patchbay/dsp_load', self.main_object.last_sent_dsp_load) if areOnSameMachine(gui_url, self.url): self.send_local_data([gui_addr]) else: self.send_distant_data([gui_addr]) self.gui_list.append(gui_addr) def server_restarted(self): self.send_gui('/ray/gui/patchbay/server_started') self.send_samplerate() self.send_buffersize() local_guis = [] distant_guis = [] for gui_addr in self.gui_list: if areOnSameMachine(self.url, gui_addr.url): local_guis.append(gui_addr) else: distant_guis.append(gui_addr) if local_guis: self.send_local_data(local_guis) if distant_guis: self.send_distant_data(distant_guis) def client_name_and_uuid(self, client_name: str, uuid: int): self.send_gui('/ray/gui/patchbay/client_name_and_uuid', client_name, uuid) def port_added(self, port): self.send_gui('/ray/gui/patchbay/port_added', port.name, port.type, port.flags, port.uuid) def port_renamed(self, port, ex_name): self.send_gui('/ray/gui/patchbay/port_renamed', ex_name, port.name) def port_removed(self, port): self.send_gui('/ray/gui/patchbay/port_removed', port.name) def metadata_updated(self, uuid: int, key: str, value: str): self.send_gui('/ray/gui/patchbay/metadata_updated', uuid, key, value) def port_order_changed(self, port): if port.order is None: return self.send_gui('/ray/gui/patchbay/port_order_changed', port.name, port.order) def connection_added(self, connection): self.send_gui('/ray/gui/patchbay/connection_added', connection[0], connection[1]) def connection_removed(self, connection): self.send_gui('/ray/gui/patchbay/connection_removed', connection[0], connection[1]) def server_stopped(self): # here server is JACK (in future maybe pipewire) self.send_gui('/ray/gui/patchbay/server_stopped') def send_dsp_load(self, dsp_load: int): self.send_gui('/ray/gui/patchbay/dsp_load', dsp_load) def send_one_xrun(self): self.send_gui('/ray/gui/patchbay/add_xrun') def send_buffersize(self): self.send_gui('/ray/gui/patchbay/buffer_size', self.main_object.buffer_size) def send_samplerate(self): self.send_gui('/ray/gui/patchbay/sample_rate', self.main_object.samplerate) def is_terminate(self): return self._terminate def send_server_lose(self): self.send_gui('/ray/gui/patchbay/server_lose') # In the case server is not responding # and gui has not yet been added to gui_list # but gui url stocked in self._tmp_gui_url if not self.gui_list and self._tmp_gui_url: try: addr = Address(self._tmp_gui_url) except: return self.send(addr, '/ray/gui/patchbay/server_lose') RaySession-0.12.2/src/jack_patchbay_to_osc/ray-jackpatch_to_osc.py000077500000000000000000000411761417052567600253050ustar00rootroot00000000000000#!/usr/bin/python3 -u import os import signal import sys import warnings import osc_server import threading import time import jacklib from jacklib.helpers import c_char_p_p_to_list, voidptr2str PORT_TYPE_NULL = 0 PORT_TYPE_AUDIO = 1 PORT_TYPE_MIDI = 2 EXISTENCE_PATH = '/tmp/RaySession/patchbay_daemons/' # Define a context manager to suppress stdout and stderr. class suppress_stdout_stderr(object): ''' A context manager for doing a "deep suppression" of stdout and stderr in Python, i.e. will suppress all print, even if the print originates in a compiled C/Fortran sub-function. This will not suppress raised exceptions, since exceptions are printed to stderr just before a script exits, and after the context manager has exited (at least, I think that is why it lets exceptions through). ''' def __init__(self): # Open a pair of null files self.null_fds = [os.open(os.devnull,os.O_RDWR) for x in range(2)] # Save the actual stdout (1) and stderr (2) file descriptors. self.save_fds = [os.dup(1), os.dup(2)] def __enter__(self): # Assign the null pointers to stdout and stderr. os.dup2(self.null_fds[0],1) os.dup2(self.null_fds[1],2) def __exit__(self, *_): # Re-assign the real stdout/stderr back to (1) and (2) os.dup2(self.save_fds[0],1) os.dup2(self.save_fds[1],2) # Close all file descriptors for fd in self.null_fds + self.save_fds: os.close(fd) class JackPort: id = 0 name = '' type = PORT_TYPE_NULL flags = 0 alias_1 = '' alias_2 = '' order = None uuid = 0 def __init__(self, port_name:str, jack_client, port_ptr=None): # In some cases, port could has just been renamed # then, jacklib.port_by_name fail. # that is why, port_ptr can be sent as argument here self.name = port_name if port_ptr is None: port_ptr = jacklib.port_by_name(jack_client, port_name) self.flags = jacklib.port_flags(port_ptr) self.uuid = jacklib.port_uuid(port_ptr) port_type_str = jacklib.port_type(port_ptr) if port_type_str == jacklib.JACK_DEFAULT_AUDIO_TYPE: self.type = PORT_TYPE_AUDIO elif port_type_str == jacklib.JACK_DEFAULT_MIDI_TYPE: self.type = PORT_TYPE_MIDI order_prop = jacklib.get_property(self.uuid, jacklib.JACK_METADATA_ORDER) ret, alias_1, alias_2 = jacklib.port_get_aliases(port_ptr) if ret: self.alias_1 = alias_1 self.alias_2 = alias_2 def __lt__(self, other): return self.uuid < other.uuid class MainObject: port_list = [] connection_list = [] metadata_list = [] client_list = [] # list of dicts {'name': client_name, 'uuid': client_uuid} client_names_queue = [] jack_running = False osc_server = None terminate = False jack_client = None samplerate = 48000 buffer_size = 1024 def __init__(self, daemon_port: str, gui_url: str): self._daemon_port = daemon_port self.last_sent_dsp_load = 0 self.max_dsp_since_last_sent = 0.00 self._waiting_jack_client_open = True self.osc_server = osc_server.OscJackPatch(self) self.osc_server.set_tmp_gui_url(gui_url) self.write_existence_file() self.start_jack_client() @staticmethod def get_metadata_value_str(prop)->str: value = prop.value if type(value) == bytes: return value.decode() elif type(value) == str: return value else: try: value = str(value) except: return '' return value def write_existence_file(self): if not os.path.isdir(EXISTENCE_PATH): os.makedirs(EXISTENCE_PATH) try: file = open(EXISTENCE_PATH + self._daemon_port, 'w') except PermissionError: sys.stderr.write( 'ray-patchbay_to_osc: Error, no permission for existence file\n') sys.exit(1) contents = 'pid:%i\n' % os.getpid() contents += 'port:%i\n' % self.osc_server.port file.write(contents) file.close() def remove_existence_file(self): if not os.path.exists(EXISTENCE_PATH + self._daemon_port): return try: os.remove(EXISTENCE_PATH + self._daemon_port) except PermissionError: sys.stderr.write( 'ray-patchbay_to_osc: Error, unable to remove %s\n' % EXISTENCE_PATH + self._daemon_port) @classmethod def signal_handler(cls, sig: int, frame): if sig in (signal.SIGINT, signal.SIGTERM): cls.terminate = True def eat_client_names_queue(self): while self.client_names_queue: client_name = self.client_names_queue.pop(0) b_uuid = jacklib.get_uuid_for_client_name(self.jack_client, client_name) # convert bytes uuid to int uuid = 0 if isinstance(b_uuid, bytes): str_uuid = b_uuid.decode() if str_uuid.isdigit(): uuid = int(str_uuid) if not uuid: continue for client_dict in self.client_list: if client_dict['name'] == client_name: client_dict['uuid'] = uuid break else: self.client_list.append({'name': client_name, 'uuid': uuid}) def add_gui(self, gui_url: str): self.osc_server.add_gui(gui_url) def check_jack_client_responding(self): for i in range(25): # JACK has 5s to answer time.sleep(0.200) if not self._waiting_jack_client_open: break else: # server never answer self.osc_server.send_server_lose() self.remove_existence_file() # JACK is not responding at all # probably it is started but totally bugged # finally kill this program from system os.kill(os.getpid(), signal.SIGKILL) def refresh(self): if self.jack_running: self.get_all_ports_and_connections() self.osc_server.server_restarted() def remember_dsp_load(self): self.max_dsp_since_last_sent = max( self.max_dsp_since_last_sent, jacklib.cpu_load(self.jack_client)) def send_dsp_load(self): current_dsp = int(self.max_dsp_since_last_sent + 0.5) if current_dsp != self.last_sent_dsp_load: self.osc_server.send_dsp_load(current_dsp) self.last_sent_dsp_load = current_dsp self.max_dsp_since_last_sent = 0.00 def start_loop(self): n = 0 while True: self.osc_server.recv(50) if self.is_terminate(): break if self.jack_running: if n % 4 == 0: self.remember_dsp_load() if n % 20 == 0: self.send_dsp_load() self.eat_client_names_queue() else: if n % 10 == 0: self.start_jack_client() n += 1 def exit(self): if self.jack_running: jacklib.deactivate(self.jack_client) jacklib.client_close(self.jack_client) self.remove_existence_file() del self.osc_server def start_jack_client(self): self._waiting_jack_client_open = True # Sometimes JACK never registers the client # and never answers. This thread will allow to exit # if JACK didn't answer 5 seconds after register ask jack_waiter_thread = threading.Thread( target=self.check_jack_client_responding) jack_waiter_thread.start() #time.sleep(20) with suppress_stdout_stderr(): self.jack_client = jacklib.client_open( "ray-patch_to_osc", jacklib.JackNoStartServer | jacklib.JackSessionID, None) self._waiting_jack_client_open = False jack_waiter_thread.join() if self.jack_client: self.jack_running = True self.set_registrations() self.get_all_ports_and_connections() self.osc_server.set_jack_client(self.jack_client) self.samplerate = jacklib.get_sample_rate(self.jack_client) self.buffer_size = jacklib.get_buffer_size(self.jack_client) self.osc_server.server_restarted() else: self.jack_running = False def is_terminate(self)->bool: if self.terminate or self.osc_server.is_terminate(): return True return False def set_registrations(self): if not self.jack_client: return jacklib.set_client_registration_callback( self.jack_client, self.jack_client_registration_callback, None) jacklib.set_port_registration_callback( self.jack_client, self.jack_port_registration_callback, None) jacklib.set_port_connect_callback( self.jack_client, self.jack_port_connect_callback, None) jacklib.set_port_rename_callback( self.jack_client, self.jack_port_rename_callback, None) jacklib.set_xrun_callback( self.jack_client, self.jack_xrun_callback, None) jacklib.set_buffer_size_callback( self.jack_client, self.jack_buffer_size_callback, None) jacklib.set_sample_rate_callback( self.jack_client, self.jack_sample_rate_callback, None) jacklib.set_property_change_callback( self.jack_client, self.jack_properties_change_callback, None) jacklib.on_shutdown( self.jack_client, self.jack_shutdown_callback, None) jacklib.activate(self.jack_client) def get_all_ports_and_connections(self): self.port_list.clear() self.connection_list.clear() self.metadata_list.clear() #get all currents Jack ports and connections port_name_list = c_char_p_p_to_list( jacklib.get_ports(self.jack_client, "", "", 0)) client_names = [] for port_name in port_name_list: port_ptr = jacklib.port_by_name(self.jack_client, port_name) jport = JackPort(port_name, self.jack_client) self.port_list.append(jport) client_name = port_name.partition(':')[0] if not client_name in client_names: client_names.append(client_name) # get port metadatas for key in (jacklib.JACK_METADATA_CONNECTED, jacklib.JACK_METADATA_ORDER, jacklib.JACK_METADATA_PORT_GROUP, jacklib.JACK_METADATA_PRETTY_NAME): prop = jacklib.get_property(jport.uuid, key) if prop is None: continue value = self.get_metadata_value_str(prop) self.metadata_list.append( {'uuid': jport.uuid, 'key': key, 'value': value}) if jport.flags & jacklib.JackPortIsInput: continue port_ptr = jacklib.port_by_name(self.jack_client, jport.name) # this port is output, list its connections port_connection_names = tuple( jacklib.port_get_all_connections(self.jack_client, port_ptr)) for port_con_name in port_connection_names: self.connection_list.append((jport.name, port_con_name)) for client_name in client_names: uuid = jacklib.get_uuid_for_client_name(self.jack_client, client_name) if not uuid: continue self.client_list.append({'name': client_name, 'uuid': int(uuid)}) #self.port_list.sort() def jack_shutdown_callback(self, arg=None)->int: self.jack_running = False self.port_list.clear() self.connection_list.clear() self.osc_server.server_stopped() return 0 def jack_xrun_callback(self, arg=None)->int: self.osc_server.send_one_xrun() return 0 def jack_sample_rate_callback(self, samplerate, arg=None)->int: self.samplerate = samplerate self.osc_server.send_samplerate() return 0 def jack_buffer_size_callback(self, buffer_size, arg=None)->int: self.buffer_size = buffer_size self.osc_server.send_buffersize() return 0 def jack_client_registration_callback(self, client_name: bytes, register: int, arg=None)->int: client_name = client_name.decode() self.client_names_queue.append(client_name) return 0 def jack_port_registration_callback(self, port_id: int, register: bool, arg=None)->int: if not self.jack_client: return 0 port_ptr = jacklib.port_by_id(self.jack_client, port_id) port_name = jacklib.port_name(port_ptr) if register: jport = JackPort(port_name, self.jack_client, port_ptr) self.port_list.append(jport) self.osc_server.port_added(jport) else: for jport in self.port_list: if jport.name == port_name: self.port_list.remove(jport) self.osc_server.port_removed(jport) break return 0 def jack_port_rename_callback(self, port_id: int, old_name: str, new_name: str, arg=None)->int: for jport in self.port_list: if jport.name == str(old_name.decode()): ex_name = jport.name jport.name = str(new_name.decode()) self.osc_server.port_renamed(jport, ex_name) break return 0 def jack_port_connect_callback(self, port_id_A: int, port_id_B: int, connect_yesno: bool, arg=None)->int: #if not self.jack_client: #return 0 port_ptr_A = jacklib.port_by_id(self.jack_client, port_id_A) port_ptr_B = jacklib.port_by_id(self.jack_client, port_id_B) port_str_A = jacklib.port_name(port_ptr_A) port_str_B = jacklib.port_name(port_ptr_B) connection = (port_str_A, port_str_B) if connect_yesno: self.connection_list.append(connection) self.osc_server.connection_added(connection) elif connection in self.connection_list: self.connection_list.remove(connection) self.osc_server.connection_removed(connection) return 0 def jack_properties_change_callback(self, uuid: int, name: bytes, type_: int, arg=None)->int: if name is not None: name = name.decode() value = '' if name and type_ != jacklib.PropertyDeleted: prop = jacklib.get_property(uuid, name) if prop is None: return 0 value = self.get_metadata_value_str(prop) for metadata in self.metadata_list: if metadata['uuid'] == uuid and metadata['key'] == name: metadata['value'] = value break else: self.metadata_list.append( {'uuid': uuid, 'key': name, 'value': value}) self.osc_server.metadata_updated(uuid, name, value) return 0 def set_buffer_size(self, buffer_size: int): jacklib.set_buffer_size(self.jack_client, buffer_size) def set_metadata(self, uuid: int, key: str, value: str): jacklib.set_property(uuid, key, value, 'text/plain', jacklib.ENCODING) def main_process(): args = sys.argv.copy() daemon_port = '' gui_url = '' if args: this_exec = args.pop(0) if args: daemon_port = args.pop(0) if args: gui_url = args[0] main_object = MainObject(daemon_port, gui_url) for gui_url in args: main_object.add_gui(gui_url) main_object.start_loop() main_object.exit() if __name__ == '__main__': # prevent deprecation warnings python messages warnings.filterwarnings("ignore", category=DeprecationWarning) signal.signal(signal.SIGINT, MainObject.signal_handler) signal.signal(signal.SIGTERM, MainObject.signal_handler) main_process() RaySession-0.12.2/src/shared/000077500000000000000000000000001417052567600157455ustar00rootroot00000000000000RaySession-0.12.2/src/shared/jacklib.py000066400000000000000000001331771417052567600177320ustar00rootroot00000000000000 # JACK ctypes definitions for usage in python applications # Copyright (C) 2010-2013 Filipe Coelho # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a full copy of the GNU General Public License see the COPYING file # ------------------------------------------------------------------------------------------------------------ # Imports (Global) from ctypes import ( cdll, c_int, c_uint8, c_uint32, c_uint64, c_int32, Structure, c_float, c_size_t, POINTER, c_double, c_float, ARRAY, c_char_p, CFUNCTYPE, c_void_p, c_ulong, pointer) from sys import platform # ------------------------------------------------------------------------------------------------------------ # Load JACK shared library try: if platform == "darwin": jacklib = cdll.LoadLibrary("libjack.dylib") elif platform in ("win32", "win64", "cygwin"): jacklib = cdll.LoadLibrary("libjack.dll") else: jacklib = cdll.LoadLibrary("libjack.so.0") except: jacklib = None raise ImportError("JACK is not available in this system") # ------------------------------------------------------------------------------------------------------------ # JACK2 test try: if jacklib.jack_get_version_string: JACK2 = True else: JACK2 = False except: JACK2 = False # ------------------------------------------------------------------------------------------------------------ # Pre-Types c_enum = c_int c_uchar = c_uint8 class _jack_port(Structure): _fields_ = [] class _jack_client(Structure): _fields_ = [] # ------------------------------------------------------------------------------------------------------------ # Defines JACK_MAX_FRAMES = 4294967295 JACK_LOAD_INIT_LIMIT = 1024 JACK_DEFAULT_AUDIO_TYPE = "32 bit float mono audio" JACK_DEFAULT_MIDI_TYPE = "8 bit raw midi" # ------------------------------------------------------------------------------------------------------------ # Types jack_nframes_t = c_uint32 jack_port_id_t = c_uint32 jack_time_t = c_uint64 jack_unique_t = c_uint64 jack_midi_data_t = c_uchar jack_default_audio_sample_t = c_float jack_options_t = c_enum # JackOptions jack_status_t = c_enum # JackStatus jack_transport_state_t = c_enum # JackTransportState jack_position_bits_t = c_enum # JackPositionBits jack_session_event_type_t = c_enum # JackSessionEventType jack_session_flags_t = c_enum # JackSessionFlags jack_custom_change_t = c_enum # JackCustomChange jack_latency_callback_mode_t = c_enum # JackLatencyCallbackMode jack_port_t = _jack_port jack_client_t = _jack_client jack_port_type_id_t = c_uint32 # JACK2 only # enum JackOptions JackNullOption = 0x00 JackNoStartServer = 0x01 JackUseExactName = 0x02 JackServerName = 0x04 JackLoadName = 0x08 JackLoadInit = 0x10 JackSessionID = 0x20 JackOpenOptions = JackSessionID|JackServerName|JackNoStartServer|JackUseExactName JackLoadOptions = JackLoadInit|JackLoadName|JackUseExactName # enum JackStatus JackFailure = 0x01 JackInvalidOption = 0x02 JackNameNotUnique = 0x04 JackServerStarted = 0x08 JackServerFailed = 0x10 JackServerError = 0x20 JackNoSuchClient = 0x40 JackLoadFailure = 0x80 JackInitFailure = 0x100 JackShmFailure = 0x200 JackVersionError = 0x400 JackBackendError = 0x800 JackClientZombie = 0x1000 # enum JackLatencyCallbackMode JackCaptureLatency = 0 JackPlaybackLatency = 1 # enum JackPortFlags JackPortIsInput = 0x1 JackPortIsOutput = 0x2 JackPortIsPhysical = 0x4 JackPortCanMonitor = 0x8 JackPortIsTerminal = 0x10 JackPortIsControlVoltage = 0x100 # enum JackTransportState JackTransportStopped = 0 JackTransportRolling = 1 JackTransportLooping = 2 JackTransportStarting = 3 JackTransportNetStarting = 4 # JACK2 only # enum JackPositionBits JackPositionBBT = 0x10 JackPositionTimecode = 0x20 JackBBTFrameOffset = 0x40 JackAudioVideoRatio = 0x80 JackVideoFrameOffset = 0x100 JACK_POSITION_MASK = JackPositionBBT|JackPositionTimecode|JackBBTFrameOffset|JackAudioVideoRatio|JackVideoFrameOffset # enum JackSessionEventType JackSessionSave = 1 JackSessionSaveAndQuit = 2 JackSessionSaveTemplate = 3 # enum JackSessionFlags JackSessionSaveError = 0x01 JackSessionNeedTerminal = 0x02 # enum JackCustomChange JackCustomRemoved = 0 JackCustomAdded = 1 JackCustomReplaced = 2 # ------------------------------------------------------------------------------------------------------------ # Structs class jack_midi_event_t(Structure): _fields_ = [ ("time", jack_nframes_t), ("size", c_size_t), ("buffer", POINTER(jack_midi_data_t)) ] class jack_latency_range_t(Structure): _fields_ = [ ("min", jack_nframes_t), ("max", jack_nframes_t) ] class jack_position_t(Structure): _fields_ = [ ("unique_1", jack_unique_t), ("usecs", jack_time_t), ("frame_rate", jack_nframes_t), ("frame", jack_nframes_t), ("valid", jack_position_bits_t), ("bar", c_int32), ("beat", c_int32), ("tick", c_int32), ("bar_start_tick", c_double), ("beats_per_bar", c_float), ("beat_type", c_float), ("ticks_per_beat", c_double), ("beats_per_minute", c_double), ("frame_time", c_double), ("next_time", c_double), ("bbt_offset", jack_nframes_t), ("audio_frames_per_video_frame", c_float), ("video_offset", jack_nframes_t), ("padding", ARRAY(c_int32, 7)), ("unique_2", jack_unique_t) ] class jack_session_event_t(Structure): _fields_ = [ ("type", jack_session_event_type_t), ("session_dir", c_char_p), ("client_uuid", c_char_p), ("command_line", c_char_p), ("flags", jack_session_flags_t), ("future", c_uint32) ] class jack_session_command_t(Structure): _fields_ = [ ("uuid", c_char_p), ("client_name", c_char_p), ("command", c_char_p), ("flags", jack_session_flags_t) ] # ------------------------------------------------------------------------------------------------------------ # Callbacks JackLatencyCallback = CFUNCTYPE(None, jack_latency_callback_mode_t, c_void_p) JackProcessCallback = CFUNCTYPE(c_int, jack_nframes_t, c_void_p) JackThreadCallback = CFUNCTYPE(c_void_p, c_void_p) JackThreadInitCallback = CFUNCTYPE(None, c_void_p) JackGraphOrderCallback = CFUNCTYPE(c_int, c_void_p) JackXRunCallback = CFUNCTYPE(c_int, c_void_p) JackBufferSizeCallback = CFUNCTYPE(c_int, jack_nframes_t, c_void_p) JackSampleRateCallback = CFUNCTYPE(c_int, jack_nframes_t, c_void_p) JackPortRegistrationCallback = CFUNCTYPE(None, jack_port_id_t, c_int, c_void_p) JackClientRegistrationCallback = CFUNCTYPE(None, c_char_p, c_int, c_void_p) JackClientRenameCallback = CFUNCTYPE(c_int, c_char_p, c_char_p, c_void_p) # JACK2 only JackPortConnectCallback = CFUNCTYPE(None, jack_port_id_t, jack_port_id_t, c_int, c_void_p) JackPortRenameCallback = CFUNCTYPE(c_int, jack_port_id_t, c_char_p, c_char_p, c_void_p) # JACK2 only JackFreewheelCallback = CFUNCTYPE(None, c_int, c_void_p) JackShutdownCallback = CFUNCTYPE(None, c_void_p) JackInfoShutdownCallback = CFUNCTYPE(None, jack_status_t, c_char_p, c_void_p) JackSyncCallback = CFUNCTYPE(c_int, jack_transport_state_t, POINTER(jack_position_t), c_void_p) JackTimebaseCallback = CFUNCTYPE(None, jack_transport_state_t, jack_nframes_t, POINTER(jack_position_t), c_int, c_void_p) JackSessionCallback = CFUNCTYPE(None, POINTER(jack_session_event_t), c_void_p) JackCustomDataAppearanceCallback = CFUNCTYPE(None, c_char_p, c_char_p, jack_custom_change_t, c_void_p) # ------------------------------------------------------------------------------------------------------------ # Functions try: jacklib.jack_get_version_string.argtypes = None jacklib.jack_get_version_string.restype = c_char_p except: jacklib.jack_get_version_string = None try: jacklib.jack_client_open.argtypes = [c_char_p, jack_options_t, POINTER(jack_status_t), c_char_p] jacklib.jack_client_open.restype = POINTER(jack_client_t) except: jacklib.jack_client_open = None try: jacklib.jack_client_rename.argtypes = [POINTER(jack_client_t), c_char_p] jacklib.jack_client_rename.restype = c_char_p except: jacklib.jack_client_rename = None try: jacklib.jack_client_close.argtypes = [POINTER(jack_client_t)] jacklib.jack_client_close.restype = c_int except: jacklib.jack_client_close = None try: jacklib.jack_client_name_size.argtypes = None jacklib.jack_client_name_size.restype = c_int except: jacklib.jack_client_name_size = None try: jacklib.jack_get_client_name.argtypes = [POINTER(jack_client_t)] jacklib.jack_get_client_name.restype = c_char_p except: jacklib.jack_get_client_name = None try: jacklib.jack_activate.argtypes = [POINTER(jack_client_t)] jacklib.jack_activate.restype = c_int except: jacklib.jack_activate = None try: jacklib.jack_deactivate.argtypes = [POINTER(jack_client_t)] jacklib.jack_deactivate.restype = c_int except: jacklib.jack_deactivate = None try: jacklib.jack_get_client_pid.argtypes = [c_char_p] jacklib.jack_get_client_pid.restype = c_int except: jacklib.jack_get_client_pid = None try: jacklib.jack_is_realtime.argtypes = [POINTER(jack_client_t)] jacklib.jack_is_realtime.restype = c_int except: jacklib.jack_is_realtime = None def get_version_string(): # JACK2 only if jacklib.jack_get_version_string: return jacklib.jack_get_version_string() return None def client_open(client_name, options, status, uuid=""): if jacklib.jack_client_open: return jacklib.jack_client_open(client_name.encode("utf-8"), options, status, uuid.encode("utf-8") if uuid else None) return None def client_rename(client, new_name): if jacklib.jack_client_rename: return jacklib.jack_client_rename(client, new_name.encode("utf-8")) return None def client_close(client): if jacklib.jack_client_close: return jacklib.jack_client_close(client) return -1 def client_name_size(): if jacklib.jack_client_name_size: return jacklib.jack_client_name_size() return 0 def get_client_name(client): if jacklib.jack_get_client_name: return jacklib.jack_get_client_name(client) return None def activate(client): if jacklib.jack_activate: return jacklib.jack_activate(client) return -1 def deactivate(client): if jacklib.jack_deactivate: return jacklib.jack_deactivate(client) return -1 def get_client_pid(name): # JACK2 only if jacklib.jack_get_client_pid: return jacklib.jack_get_client_pid(name.encode("utf-8")) return 0 def is_realtime(client): if jacklib.jack_is_realtime: return jacklib.jack_is_realtime(client) return 0 # ------------------------------------------------------------------------------------------------------------ # Non-Callback API global _thread_callback _thread_callback = None try: jacklib.jack_cycle_wait.argtypes = [POINTER(jack_client_t)] jacklib.jack_cycle_wait.restype = jack_nframes_t except: jacklib.jack_cycle_wait = None try: jacklib.jack_cycle_signal.argtypes = [POINTER(jack_client_t), c_int] jacklib.jack_cycle_signal.restype = None except: jacklib.jack_cycle_signal = None try: jacklib.jack_set_process_thread.argtypes = [POINTER(jack_client_t), JackThreadCallback, c_void_p] jacklib.jack_set_process_thread.restype = c_int except: jacklib.jack_set_process_thread = None def cycle_wait(client): if jacklib.jack_cycle_wait: return jacklib.jack_cycle_wait(client) return 0 def cycle_signal(client, status): if jacklib.jack_cycle_signal: jacklib.jack_cycle_signal(client, status) def set_process_thread(client, thread_callback, arg): if jacklib.jack_set_process_thread: global _thread_callback _thread_callback = JackThreadCallback(thread_callback) return jacklib.jack_set_process_thread(client, _thread_callback, arg) return -1 # ------------------------------------------------------------------------------------------------------------ # Client Callbacks global _thread_init_callback global _shutdown_callback global _info_shutdown_callback global _process_callback global _freewheel_callback global _bufsize_callback global _srate_callback global _client_registration_callback global _client_rename_callback global _port_registration_callback global _port_connect_callback global _port_rename_callback global _graph_callback global _xrun_callback global _latency_callback _thread_init_callback = _shutdown_callback = _info_shutdown_callback = None _process_callback = _freewheel_callback = _bufsize_callback = _srate_callback = None _client_registration_callback = _client_rename_callback = None _port_registration_callback = _port_connect_callback = _port_rename_callback = None _graph_callback = _xrun_callback = _latency_callback = None try: jacklib.jack_set_thread_init_callback.argtypes = [POINTER(jack_client_t), JackThreadInitCallback, c_void_p] jacklib.jack_set_thread_init_callback.restype = c_int except: jacklib.jack_set_thread_init_callback = None try: jacklib.jack_on_shutdown.argtypes = [POINTER(jack_client_t), JackShutdownCallback, c_void_p] jacklib.jack_on_shutdown.restype = None except: jacklib.jack_on_shutdown = None try: jacklib.jack_on_info_shutdown.argtypes = [POINTER(jack_client_t), JackInfoShutdownCallback, c_void_p] jacklib.jack_on_info_shutdown.restype = None except: jacklib.jack_on_info_shutdown = None try: jacklib.jack_set_process_callback.argtypes = [POINTER(jack_client_t), JackProcessCallback, c_void_p] jacklib.jack_set_process_callback.restype = c_int except: jacklib.jack_set_process_callback = None try: jacklib.jack_set_freewheel_callback.argtypes = [POINTER(jack_client_t), JackFreewheelCallback, c_void_p] jacklib.jack_set_freewheel_callback.restype = c_int except: jacklib.jack_set_freewheel_callback = None try: jacklib.jack_set_buffer_size_callback.argtypes = [POINTER(jack_client_t), JackBufferSizeCallback, c_void_p] jacklib.jack_set_buffer_size_callback.restype = c_int except: jacklib.jack_set_buffer_size_callback = None try: jacklib.jack_set_sample_rate_callback.argtypes = [POINTER(jack_client_t), JackSampleRateCallback, c_void_p] jacklib.jack_set_sample_rate_callback.restype = c_int except: jacklib.jack_set_sample_rate_callback = None try: jacklib.jack_set_client_registration_callback.argtypes = [POINTER(jack_client_t), JackClientRegistrationCallback, c_void_p] jacklib.jack_set_client_registration_callback.restype = c_int except: jacklib.jack_set_client_registration_callback = None try: jacklib.jack_set_client_rename_callback.argtypes = [POINTER(jack_client_t), JackClientRenameCallback, c_void_p] jacklib.jack_set_client_rename_callback.restype = c_int except: jacklib.jack_set_client_rename_callback = None try: jacklib.jack_set_port_registration_callback.argtypes = [POINTER(jack_client_t), JackPortRegistrationCallback, c_void_p] jacklib.jack_set_port_registration_callback.restype = c_int except: jacklib.jack_set_port_registration_callback = None try: jacklib.jack_set_port_connect_callback.argtypes = [POINTER(jack_client_t), JackPortConnectCallback, c_void_p] jacklib.jack_set_port_connect_callback.restype = c_int except: jacklib.jack_set_port_connect_callback = None try: jacklib.jack_set_port_rename_callback.argtypes = [POINTER(jack_client_t), JackPortRenameCallback, c_void_p] jacklib.jack_set_port_rename_callback.restype = c_int except: jacklib.jack_set_port_rename_callback = None try: jacklib.jack_set_graph_order_callback.argtypes = [POINTER(jack_client_t), JackGraphOrderCallback, c_void_p] jacklib.jack_set_graph_order_callback.restype = c_int except: jacklib.jack_set_graph_order_callback = None try: jacklib.jack_set_xrun_callback.argtypes = [POINTER(jack_client_t), JackXRunCallback, c_void_p] jacklib.jack_set_xrun_callback.restype = c_int except: jacklib.jack_set_xrun_callback = None try: jacklib.jack_set_latency_callback.argtypes = [POINTER(jack_client_t), JackLatencyCallback, c_void_p] jacklib.jack_set_latency_callback.restype = c_int except: jacklib.jack_set_latency_callback = None def set_thread_init_callback(client, thread_init_callback, arg): if jacklib.jack_set_thread_init_callback: global _thread_init_callback _thread_init_callback = JackThreadInitCallback(thread_init_callback) return jacklib.jack_set_thread_init_callback(client, _thread_init_callback, arg) return -1 def on_shutdown(client, shutdown_callback, arg): if jacklib.jack_on_shutdown: global _shutdown_callback _shutdown_callback = JackShutdownCallback(shutdown_callback) jacklib.jack_on_shutdown(client, _shutdown_callback, arg) def on_info_shutdown(client, info_shutdown_callback, arg): if jacklib.jack_on_info_shutdown: global _info_shutdown_callback _info_shutdown_callback = JackInfoShutdownCallback(info_shutdown_callback) jacklib.jack_on_info_shutdown(client, _info_shutdown_callback, arg) def set_process_callback(client, process_callback, arg): if jacklib.jack_set_process_callback: global _process_callback _process_callback = JackProcessCallback(process_callback) return jacklib.jack_set_process_callback(client, _process_callback, arg) return -1 def set_freewheel_callback(client, freewheel_callback, arg): if jacklib.jack_set_freewheel_callback: global _freewheel_callback _freewheel_callback = JackFreewheelCallback(freewheel_callback) return jacklib.jack_set_freewheel_callback(client, _freewheel_callback, arg) return -1 def set_buffer_size_callback(client, bufsize_callback, arg): if jacklib.jack_set_buffer_size_callback: global _bufsize_callback _bufsize_callback = JackBufferSizeCallback(bufsize_callback) return jacklib.jack_set_buffer_size_callback(client, _bufsize_callback, arg) return -1 def set_sample_rate_callback(client, srate_callback, arg): if jacklib.jack_set_sample_rate_callback: global _srate_callback _srate_callback = JackSampleRateCallback(srate_callback) return jacklib.jack_set_sample_rate_callback(client, _srate_callback, arg) return -1 def set_client_registration_callback(client, client_registration_callback, arg): if jacklib.jack_set_client_registration_callback: global _client_registration_callback _client_registration_callback = JackClientRegistrationCallback(client_registration_callback) return jacklib.jack_set_client_registration_callback(client, _client_registration_callback, arg) return -1 def set_client_rename_callback(client, client_rename_callback, arg): # JACK2 only if jacklib.jack_set_client_rename_callback: global _client_rename_callback _client_rename_callback = JackClientRenameCallback(client_rename_callback) return jacklib.jack_set_client_rename_callback(client, _client_rename_callback, arg) return -1 def set_port_registration_callback(client, port_registration_callback, arg): if jacklib.jack_set_port_registration_callback: global _port_registration_callback _port_registration_callback = JackPortRegistrationCallback(port_registration_callback) return jacklib.jack_set_port_registration_callback(client, _port_registration_callback, arg) return -1 def set_port_connect_callback(client, connect_callback, arg): if jacklib.jack_set_port_connect_callback: global _port_connect_callback _port_connect_callback = JackPortConnectCallback(connect_callback) return jacklib.jack_set_port_connect_callback(client, _port_connect_callback, arg) return -1 def set_port_rename_callback(client, rename_callback, arg): # JACK2 only if jacklib.jack_set_port_rename_callback: global _port_rename_callback _port_rename_callback = JackPortRenameCallback(rename_callback) return jacklib.jack_set_port_rename_callback(client, _port_rename_callback, arg) return -1 def set_graph_order_callback(client, graph_callback, arg): if jacklib.jack_set_graph_order_callback: global _graph_callback _graph_callback = JackGraphOrderCallback(graph_callback) return jacklib.jack_set_graph_order_callback(client, _graph_callback, arg) return -1 def set_xrun_callback(client, xrun_callback, arg): if jacklib.jack_set_xrun_callback: global _xrun_callback _xrun_callback = JackXRunCallback(xrun_callback) return jacklib.jack_set_xrun_callback(client, _xrun_callback, arg) return -1 def set_latency_callback(client, latency_callback, arg): if jacklib.jack_set_latency_callback: global _latency_callback _latency_callback = JackLatencyCallback(latency_callback) return jacklib.jack_set_latency_callback(client, _latency_callback, arg) return -1 # ------------------------------------------------------------------------------------------------------------ # Server Control jacklib.jack_set_freewheel.argtypes = [POINTER(jack_client_t), c_int] jacklib.jack_set_freewheel.restype = c_int jacklib.jack_set_buffer_size.argtypes = [POINTER(jack_client_t), jack_nframes_t] jacklib.jack_set_buffer_size.restype = c_int jacklib.jack_get_sample_rate.argtypes = [POINTER(jack_client_t)] jacklib.jack_get_sample_rate.restype = jack_nframes_t jacklib.jack_get_buffer_size.argtypes = [POINTER(jack_client_t)] jacklib.jack_get_buffer_size.restype = jack_nframes_t jacklib.jack_engine_takeover_timebase.argtypes = [POINTER(jack_client_t)] jacklib.jack_engine_takeover_timebase.restype = c_int jacklib.jack_cpu_load.argtypes = [POINTER(jack_client_t)] jacklib.jack_cpu_load.restype = c_float def set_freewheel(client, onoff): return jacklib.jack_set_freewheel(client, onoff) def set_buffer_size(client, nframes): return jacklib.jack_set_buffer_size(client, nframes) def get_sample_rate(client): return jacklib.jack_get_sample_rate(client) def get_buffer_size(client): return jacklib.jack_get_buffer_size(client) def engine_takeover_timebase(client): return jacklib.jack_engine_takeover_timebase(client) def cpu_load(client): return jacklib.jack_cpu_load(client) # ------------------------------------------------------------------------------------------------------------ # Port Functions jacklib.jack_port_register.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p, c_ulong, c_ulong] jacklib.jack_port_register.restype = POINTER(jack_port_t) jacklib.jack_port_unregister.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jacklib.jack_port_unregister.restype = c_int jacklib.jack_port_get_buffer.argtypes = [POINTER(jack_port_t), jack_nframes_t] jacklib.jack_port_get_buffer.restype = c_void_p jacklib.jack_port_name.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_name.restype = c_char_p jacklib.jack_port_short_name.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_short_name.restype = c_char_p jacklib.jack_port_flags.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_flags.restype = c_int jacklib.jack_port_type.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_type.restype = c_char_p if JACK2: jacklib.jack_port_type_id.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_type_id.restype = jack_port_type_id_t jacklib.jack_port_is_mine.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jacklib.jack_port_is_mine.restype = c_int jacklib.jack_port_connected.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_connected.restype = c_int jacklib.jack_port_connected_to.argtypes = [POINTER(jack_port_t), c_char_p] jacklib.jack_port_connected_to.restype = c_int jacklib.jack_port_get_connections.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_get_connections.restype = POINTER(c_char_p) jacklib.jack_port_get_all_connections.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jacklib.jack_port_get_all_connections.restype = POINTER(c_char_p) jacklib.jack_port_tie.argtypes = [POINTER(jack_port_t), POINTER(jack_port_t)] jacklib.jack_port_tie.restype = c_int jacklib.jack_port_untie.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_untie.restype = c_int jacklib.jack_port_set_name.argtypes = [POINTER(jack_port_t), c_char_p] jacklib.jack_port_set_name.restype = c_int jacklib.jack_port_set_alias.argtypes = [POINTER(jack_port_t), c_char_p] jacklib.jack_port_set_alias.restype = c_int jacklib.jack_port_unset_alias.argtypes = [POINTER(jack_port_t), c_char_p] jacklib.jack_port_unset_alias.restype = c_int jacklib.jack_port_get_aliases.argtypes = [POINTER(jack_port_t), POINTER(ARRAY(c_char_p, 2))] jacklib.jack_port_get_aliases.restype = c_int jacklib.jack_port_request_monitor.argtypes = [POINTER(jack_port_t), c_int] jacklib.jack_port_request_monitor.restype = c_int jacklib.jack_port_request_monitor_by_name.argtypes = [POINTER(jack_client_t), c_char_p, c_int] jacklib.jack_port_request_monitor_by_name.restype = c_int jacklib.jack_port_ensure_monitor.argtypes = [POINTER(jack_port_t), c_int] jacklib.jack_port_ensure_monitor.restype = c_int jacklib.jack_port_monitoring_input.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_monitoring_input.restype = c_int jacklib.jack_connect.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p] jacklib.jack_connect.restype = c_int jacklib.jack_disconnect.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p] jacklib.jack_disconnect.restype = c_int jacklib.jack_port_disconnect.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jacklib.jack_port_disconnect.restype = c_int jacklib.jack_port_name_size.argtypes = None jacklib.jack_port_name_size.restype = c_int jacklib.jack_port_type_size.argtypes = None jacklib.jack_port_type_size.restype = c_int try: jacklib.jack_port_type_get_buffer_size.argtypes = [POINTER(jack_client_t), c_char_p] jacklib.jack_port_type_get_buffer_size.restype = c_size_t except: jacklib.jack_port_type_get_buffer_size = None def port_register(client, port_name, port_type, flags, buffer_size): return jacklib.jack_port_register(client, port_name.encode("utf-8"), port_type.encode("utf-8"), flags, buffer_size) def port_unregister(client, port): return jacklib.jack_port_unregister(client, port) def port_get_buffer(port, nframes): return jacklib.jack_port_get_buffer(port, nframes) def port_name(port): return jacklib.jack_port_name(port) def port_short_name(port): return jacklib.jack_port_short_name(port) def port_flags(port): return jacklib.jack_port_flags(port) def port_type(port): return jacklib.jack_port_type(port) def port_type_id(port): # JACK2 only return jacklib.jack_port_type_id(port) def port_is_mine(client, port): return jacklib.jack_port_is_mine(client, port) def port_connected(port): return jacklib.jack_port_connected(port) def port_connected_to(port, port_name): return jacklib.jack_port_connected_to(port, port_name.encode("utf-8")) def port_get_connections(port): return jacklib.jack_port_get_connections(port) def port_get_all_connections(client, port): return jacklib.jack_port_get_all_connections(client, port) def port_tie(src, dst): return jacklib.jack_port_tie(src, dst) def port_untie(port): return jacklib.jack_port_untie(port) def port_set_name(port, port_name): return jacklib.jack_port_set_name(port, port_name.encode("utf-8")) def port_set_alias(port, alias): return jacklib.jack_port_set_alias(port, alias.encode("utf-8")) def port_unset_alias(port, alias): return jacklib.jack_port_unset_alias(port, alias.encode("utf-8")) def port_get_aliases(port): # NOTE - this function has no 2nd argument in jacklib # Instead, aliases will be passed in return value, in form of (int ret, str alias1, str alias2) name_size = port_name_size() alias_type = c_char_p * 2 aliases = alias_type(" ".encode("utf-8") * name_size, " ".encode("utf-8") * name_size) ret = jacklib.jack_port_get_aliases(port, pointer(aliases)) return (ret, str(aliases[0], encoding="utf-8"), str(aliases[1], encoding="utf-8")) def port_request_monitor(port, onoff): return jacklib.jack_port_request_monitor(port, onoff) def port_request_monitor_by_name(client, port_name, onoff): return jacklib.jack_port_request_monitor_by_name(client, port_name.encode("utf-8"), onoff) def port_ensure_monitor(port, onoff): return jacklib.jack_port_ensure_monitor(port, onoff) def port_monitoring_input(port): return jacklib.jack_port_monitoring_input(port) def connect(client, source_port, destination_port): return jacklib.jack_connect(client, source_port.encode("utf-8"), destination_port.encode("utf-8")) def disconnect(client, source_port, destination_port): return jacklib.jack_disconnect(client, source_port.encode("utf-8"), destination_port.encode("utf-8")) def port_disconnect(client, port): return jacklib.jack_port_disconnect(client, port) def port_name_size(): return jacklib.jack_port_name_size() def port_type_size(): return jacklib.jack_port_type_size() def port_type_get_buffer_size(client, port_type): if jacklib.jack_port_type_get_buffer_size: return jacklib.jack_port_type_get_buffer_size(client, port_type.encode("utf-8")) return 0 # ------------------------------------------------------------------------------------------------------------ # Latency Functions jacklib.jack_port_set_latency.argtypes = [POINTER(jack_port_t), jack_nframes_t] jacklib.jack_port_set_latency.restype = None try: jacklib.jack_port_get_latency_range.argtypes = [POINTER(jack_port_t), jack_latency_callback_mode_t, POINTER(jack_latency_range_t)] jacklib.jack_port_get_latency_range.restype = None except: jacklib.jack_port_get_latency_range = None try: jacklib.jack_port_set_latency_range.argtypes = [POINTER(jack_port_t), jack_latency_callback_mode_t, POINTER(jack_latency_range_t)] jacklib.jack_port_set_latency_range.restype = None except: jacklib.jack_port_set_latency_range = None jacklib.jack_recompute_total_latencies.argtypes = [POINTER(jack_client_t)] jacklib.jack_recompute_total_latencies.restype = c_int jacklib.jack_port_get_latency.argtypes = [POINTER(jack_port_t)] jacklib.jack_port_get_latency.restype = jack_nframes_t jacklib.jack_port_get_total_latency.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jacklib.jack_port_get_total_latency.restype = jack_nframes_t jacklib.jack_recompute_total_latency.argtypes = [POINTER(jack_client_t), POINTER(jack_port_t)] jacklib.jack_recompute_total_latency.restype = c_int def port_set_latency(port, nframes): jacklib.jack_port_set_latency(port, nframes) def port_get_latency_range(port, mode, range_): if jacklib.jack_port_get_latency_range: jacklib.jack_port_get_latency_range(port, mode, range_) def port_set_latency_range(port, mode, range_): if jacklib.jack_port_set_latency_range: jacklib.jack_port_set_latency_range(port, mode, range_) def recompute_total_latencies(): return jacklib.jack_recompute_total_latencies() def port_get_latency(port): return jacklib.jack_port_get_latency(port) def port_get_total_latency(client, port): return jacklib.jack_port_get_total_latency(client, port) def recompute_total_latency(client, port): return jacklib.jack_recompute_total_latency(client, port) # ------------------------------------------------------------------------------------------------------------ # Port Searching jacklib.jack_get_ports.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p, c_ulong] jacklib.jack_get_ports.restype = POINTER(c_char_p) jacklib.jack_port_by_name.argtypes = [POINTER(jack_client_t), c_char_p] jacklib.jack_port_by_name.restype = POINTER(jack_port_t) jacklib.jack_port_by_id.argtypes = [POINTER(jack_client_t), jack_port_id_t] jacklib.jack_port_by_id.restype = POINTER(jack_port_t) def get_ports(client, port_name_pattern, type_name_pattern, flags): return jacklib.jack_get_ports(client, port_name_pattern.encode("utf-8"), type_name_pattern.encode("utf-8"), flags) def port_by_name(client, port_name): return jacklib.jack_port_by_name(client, port_name.encode("utf-8")) def port_by_id(client, port_id): return jacklib.jack_port_by_id(client, port_id) # ------------------------------------------------------------------------------------------------------------ # Time Functions jacklib.jack_frames_since_cycle_start.argtypes = [POINTER(jack_client_t)] jacklib.jack_frames_since_cycle_start.restype = jack_nframes_t jacklib.jack_frame_time.argtypes = [POINTER(jack_client_t)] jacklib.jack_frame_time.restype = jack_nframes_t jacklib.jack_last_frame_time.argtypes = [POINTER(jack_client_t)] jacklib.jack_last_frame_time.restype = jack_nframes_t try: # JACK_OPTIONAL_WEAK_EXPORT jacklib.jack_get_cycle_times.argtypes = [POINTER(jack_client_t), POINTER(jack_nframes_t), POINTER(jack_time_t), POINTER(jack_time_t), POINTER(c_float)] jacklib.jack_get_cycle_times.restype = c_int except: jacklib.jack_get_cycle_times = None jacklib.jack_frames_to_time.argtypes = [POINTER(jack_client_t), jack_nframes_t] jacklib.jack_frames_to_time.restype = jack_time_t jacklib.jack_time_to_frames.argtypes = [POINTER(jack_client_t), jack_time_t] jacklib.jack_time_to_frames.restype = jack_nframes_t jacklib.jack_get_time.argtypes = None jacklib.jack_get_time.restype = jack_time_t def frames_since_cycle_start(client): return jacklib.jack_frames_since_cycle_start(client) def frame_time(client): return jacklib.jack_frame_time(client) def last_frame_time(client): return jacklib.jack_last_frame_time(client) def get_cycle_times(client, current_frames, current_usecs, next_usecs, period_usecs): # JACK_OPTIONAL_WEAK_EXPORT if jacklib.jack_frames_to_time: return jacklib.jack_get_cycle_times(client, current_frames, current_usecs, next_usecs, period_usecs) return -1 def frames_to_time(client, nframes): return jacklib.jack_frames_to_time(client, nframes) def time_to_frames(client, time): return jacklib.jack_time_to_frames(client, time) def get_time(): return jacklib.jack_get_time() # ------------------------------------------------------------------------------------------------------------ # Error Output # TODO # ------------------------------------------------------------------------------------------------------------ # Misc jacklib.jack_free.argtypes = [c_void_p] jacklib.jack_free.restype = None def free(ptr): return jacklib.jack_free(ptr) # ------------------------------------------------------------------------------------------------------------ # Transport global _sync_callback global _timebase_callback _sync_callback = _timebase_callback = None jacklib.jack_release_timebase.argtypes = [POINTER(jack_client_t)] jacklib.jack_release_timebase.restype = c_int jacklib.jack_set_sync_callback.argtypes = [POINTER(jack_client_t), JackSyncCallback, c_void_p] jacklib.jack_set_sync_callback.restype = c_int jacklib.jack_set_sync_timeout.argtypes = [POINTER(jack_client_t), jack_time_t] jacklib.jack_set_sync_timeout.restype = c_int jacklib.jack_set_timebase_callback.argtypes = [POINTER(jack_client_t), c_int, JackTimebaseCallback, c_void_p] jacklib.jack_set_timebase_callback.restype = c_int jacklib.jack_transport_locate.argtypes = [POINTER(jack_client_t), jack_nframes_t] jacklib.jack_transport_locate.restype = c_int jacklib.jack_transport_query.argtypes = [POINTER(jack_client_t), POINTER(jack_position_t)] jacklib.jack_transport_query.restype = jack_transport_state_t jacklib.jack_get_current_transport_frame.argtypes = [POINTER(jack_client_t)] jacklib.jack_get_current_transport_frame.restype = jack_nframes_t jacklib.jack_transport_reposition.argtypes = [POINTER(jack_client_t), POINTER(jack_position_t)] jacklib.jack_transport_reposition.restype = c_int jacklib.jack_transport_start.argtypes = [POINTER(jack_client_t)] jacklib.jack_transport_start.restype = None jacklib.jack_transport_stop.argtypes = [POINTER(jack_client_t)] jacklib.jack_transport_stop.restype = None def release_timebase(client): return jacklib.jack_release_timebase(client) def set_sync_callback(client, sync_callback, arg): global _sync_callback _sync_callback = JackSyncCallback(sync_callback) return jacklib.jack_set_sync_callback(client, _sync_callback, arg) def set_sync_timeout(client, timeout): return jacklib.jack_set_sync_timeout(client, timeout) def set_timebase_callback(client, conditional, timebase_callback, arg): global _timebase_callback _timebase_callback = JackTimebaseCallback(timebase_callback) return jacklib.jack_set_timebase_callback(client, conditional, _timebase_callback, arg) def transport_locate(client, frame): return jacklib.jack_transport_locate(client, frame) def transport_query(client, pos): return jacklib.jack_transport_query(client, pos) def get_current_transport_frame(client): return jacklib.jack_get_current_transport_frame(client) def transport_reposition(client, pos): return jacklib.jack_transport_reposition(client, pos) def transport_start(client): return jacklib.jack_transport_start(client) def transport_stop(client): return jacklib.jack_transport_stop(client) # ------------------------------------------------------------------------------------------------------------ # MIDI jacklib.jack_midi_get_event_count.argtypes = [c_void_p] jacklib.jack_midi_get_event_count.restype = jack_nframes_t jacklib.jack_midi_event_get.argtypes = [POINTER(jack_midi_event_t), c_void_p, c_uint32] jacklib.jack_midi_event_get.restype = c_int jacklib.jack_midi_clear_buffer.argtypes = [c_void_p] jacklib.jack_midi_clear_buffer.restype = None jacklib.jack_midi_max_event_size.argtypes = [c_void_p] jacklib.jack_midi_max_event_size.restype = c_size_t jacklib.jack_midi_event_reserve.argtypes = [c_void_p, jack_nframes_t, c_size_t] jacklib.jack_midi_event_reserve.restype = POINTER(jack_midi_data_t) jacklib.jack_midi_event_write.argtypes = [c_void_p, jack_nframes_t, POINTER(jack_midi_data_t), c_size_t] jacklib.jack_midi_event_write.restype = c_int jacklib.jack_midi_get_lost_event_count.argtypes = [c_void_p] jacklib.jack_midi_get_lost_event_count.restype = c_uint32 def midi_get_event_count(port_buffer): return jacklib.jack_midi_get_event_count(port_buffer) def midi_event_get(event, port_buffer, event_index): return jacklib.jack_midi_event_get(event, port_buffer, event_index) def midi_clear_buffer(port_buffer): return jacklib.jack_midi_clear_buffer(port_buffer) def midi_max_event_size(port_buffer): return jacklib.jack_midi_max_event_size(port_buffer) def midi_event_reserve(port_buffer, time, data_size): return jacklib.jack_midi_event_reserve(port_buffer, time, data_size) def midi_event_write(port_buffer, time, data, data_size): return jacklib.jack_midi_event_write(port_buffer, time, data, data_size) def midi_get_lost_event_count(port_buffer): return jacklib.jack_midi_get_lost_event_count(port_buffer) # ------------------------------------------------------------------------------------------------------------ # Session global _session_callback _session_callback = None try: jacklib.jack_set_session_callback.argtypes = [POINTER(jack_client_t), JackSessionCallback, c_void_p] jacklib.jack_set_session_callback.restype = c_int except: jacklib.jack_set_session_callback = None try: jacklib.jack_session_reply.argtypes = [POINTER(jack_client_t), POINTER(jack_session_event_t)] jacklib.jack_session_reply.restype = c_int except: jacklib.jack_session_reply = None try: jacklib.jack_session_event_free.argtypes = [POINTER(jack_session_event_t)] jacklib.jack_session_event_free.restype = None except: jacklib.jack_session_event_free = None try: jacklib.jack_client_get_uuid.argtypes = [POINTER(jack_client_t)] jacklib.jack_client_get_uuid.restype = c_char_p except: jacklib.jack_client_get_uuid = None try: jacklib.jack_session_notify.argtypes = [POINTER(jack_client_t), c_char_p, jack_session_event_type_t, c_char_p] jacklib.jack_session_notify.restype = POINTER(jack_session_command_t) except: jacklib.jack_session_notify = None try: jacklib.jack_session_commands_free.argtypes = [POINTER(jack_session_command_t)] jacklib.jack_session_commands_free.restype = None except: jacklib.jack_session_commands_free = None try: jacklib.jack_get_uuid_for_client_name.argtypes = [POINTER(jack_client_t), c_char_p] jacklib.jack_get_uuid_for_client_name.restype = c_char_p except: jacklib.jack_get_uuid_for_client_name = None try: jacklib.jack_get_client_name_by_uuid.argtypes = [POINTER(jack_client_t), c_char_p] jacklib.jack_get_client_name_by_uuid.restype = c_char_p except: jacklib.jack_get_client_name_by_uuid = None try: jacklib.jack_reserve_client_name.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p] jacklib.jack_reserve_client_name.restype = c_int except: jacklib.jack_reserve_client_name = None try: jacklib.jack_client_has_session_callback.argtypes = [POINTER(jack_client_t), c_char_p] jacklib.jack_client_has_session_callback.restype = c_int except: jacklib.jack_client_has_session_callback = None def set_session_callback(client, session_callback, arg): if jacklib.jack_set_session_callback: global _session_callback _session_callback = JackSessionCallback(session_callback) return jacklib.jack_set_session_callback(client, _session_callback, arg) return -1 def session_reply(client, event): if jacklib.jack_session_reply: return jacklib.jack_session_reply(client, event) return -1 def session_event_free(event): if jacklib.jack_session_event_free: jacklib.jack_session_event_free(event) def client_get_uuid(client): if jacklib.jack_client_get_uuid: return jacklib.jack_client_get_uuid(client) return None def session_notify(client, target, type_, path): if jacklib.jack_session_notify: return jacklib.jack_session_notify(client, target.encode("utf-8"), type_, path.encode("utf-8")) return jack_session_command_t() def session_commands_free(cmds): if jacklib.jack_session_commands_free: jacklib.jack_session_commands_free(cmds) def get_uuid_for_client_name(client, client_name): if jacklib.jack_get_uuid_for_client_name: return jacklib.jack_get_uuid_for_client_name(client, client_name.encode("utf-8")) return None def get_client_name_by_uuid(client, client_uuid): if jacklib.jack_get_client_name_by_uuid: return jacklib.jack_get_client_name_by_uuid(client, client_uuid.encode("utf-8")) return None def reserve_client_name(client, name, uuid): if jacklib.jack_reserve_client_name: return jacklib.jack_reserve_client_name(client, name.encode("utf-8"), uuid.encode("utf-8")) return -1 def client_has_session_callback(client, client_name): if jacklib.jack_client_has_session_callback: return jacklib.jack_client_has_session_callback(client, client_name.encode("utf-8")) return -1 # ------------------------------------------------------------------------------------------------------------ # Custom global _custom_appearance_callback _custom_appearance_callback = None try: jacklib.jack_custom_publish_data.argtypes = [POINTER(jack_client_t), c_char_p, c_void_p, c_size_t] jacklib.jack_custom_publish_data.restype = c_int except: jacklib.jack_custom_publish_data = None try: jacklib.jack_custom_get_data.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p, POINTER(c_void_p), POINTER(c_size_t)] jacklib.jack_custom_get_data.restype = c_int except: jacklib.jack_custom_get_data = None try: jacklib.jack_custom_unpublish_data.argtypes = [POINTER(jack_client_t), c_char_p] jacklib.jack_custom_unpublish_data.restype = c_int except: jacklib.jack_custom_unpublish_data = None try: jacklib.jack_custom_get_keys.argtypes = [POINTER(jack_client_t), c_char_p] jacklib.jack_custom_get_keys.restype = POINTER(c_char_p) except: jacklib.jack_custom_get_keys = None try: jacklib.jack_custom_set_data_appearance_callback.argtypes = [POINTER(jack_client_t), JackCustomDataAppearanceCallback, c_void_p] jacklib.jack_custom_set_data_appearance_callback.restype = c_int except: jacklib.jack_custom_set_data_appearance_callback = None def custom_publish_data(client, key, data, size): if jacklib.jack_custom_publish_data: return jacklib.jack_custom_publish_data(client, key.encode("utf-8"), data, size) return -1 def custom_get_data(client, client_name, key): # NOTE - this function has no extra arguments in jacklib # Instead, data and size will be passed in return value, in form of (int ret, void* data, size_t size) if jacklib.jack_custom_get_data: data = c_void_p(0) size = c_size_t(0) ret = jacklib.jack_custom_get_data(client, client_name.encode("utf-8"), key.encode("utf-8"), pointer(data), pointer(size)) return (ret, data, size) return (-1, None, 0) def custom_unpublish_data(client, key): if jacklib.jack_custom_unpublish_data: return jacklib.jack_custom_unpublish_data(client, key.encode("utf-8")) return -1 def custom_get_keys(client, client_name): if jacklib.jack_custom_get_keys: return jacklib.jack_custom_get_keys(client, client_name.encode("utf-8")) return None def custom_set_data_appearance_callback(client, custom_callback, arg): if jacklib.jack_custom_set_data_appearance_callback: global _custom_appearance_callback _custom_appearance_callback = JackCustomDataAppearanceCallback(custom_callback) return jacklib.jack_custom_set_data_appearance_callback(client, _custom_appearance_callback, arg) return -1 RaySession-0.12.2/src/shared/nsm_client.py000066400000000000000000000072351417052567600204610ustar00rootroot00000000000000# -*- coding: utf-8 -*- import os import sys from PyQt5.QtCore import QObject, pyqtSignal from liblo import ServerThread, make_method class NSMSignaler(QObject): server_sends_open = pyqtSignal(str, str, str) server_sends_save = pyqtSignal() session_is_loaded = pyqtSignal() show_optional_gui = pyqtSignal() hide_optional_gui = pyqtSignal() instance = None class NSMThread(ServerThread): def __init__(self, name, signaler, daemon_address, debug): ServerThread.__init__(self) self.name = name self.signaler = signaler self.daemon_address = daemon_address self.debug = debug self.server_capabilities = "" global instance instance = self @staticmethod def instance(): return instance @make_method('/reply', None) def serverReply(self, path, args): if args: reply_path = args[0] else: return if reply_path == '/nsm/server/announce': self.server_capabilities = args[3] @make_method('/nsm/client/open', 'sss') def nsmClientOpen(self, path, args): self.ifDebug( 'serverOSC::%s_receives %s, %s' % (self.name, path, str(args))) self.signaler.server_sends_open.emit(*args) @make_method('/nsm/client/save', '') def nsmClientSave(self, path, args): self.ifDebug( 'serverOSC::%s_receives %s, %s' % (self.name, path, str(args))) self.signaler.server_sends_save.emit() @make_method('/nsm/client/session_is_loaded', '') def nsmClientSessionIsLoaded(self, path, args): self.ifDebug( 'serverOSC::%s_receives %s, %s' % (self.name, path, str(args))) self.signaler.session_is_loaded.emit() @make_method('/nsm/client/show_optional_gui', '') def nsmClientShow_optional_gui(self, path, args): self.ifDebug( 'serverOSC::%s_receives %s, %s' % (self.name, path, str(args))) self.signaler.show_optional_gui.emit() @make_method('/nsm/client/hide_optional_gui', '') def nsmClientHide_optional_gui(self, path, args): self.ifDebug( 'serverOSC::%s_receives %s, %s' % (self.name, path, str(args))) self.signaler.hide_optional_gui.emit() @make_method('/nsm/client/monitor/client_state', 'si') def nsm_client_brother_client_state(self, path, args): pass @make_method('/nsm/client/monitor/client_event', 'ss') def nsm_client_monitor_event(self, path, args): pass def getServerCapabilities(self): return self.server_capabilities def ifDebug(self, string): if self.debug: sys.stderr.write("%s\n" % string) def sendToDaemon(self, *args): self.send(self.daemon_address, *args) def announce(self, client_name, capabilities, executable_path): major = 1 minor = 0 pid = os.getpid() self.sendToDaemon( '/nsm/server/announce', client_name, capabilities, executable_path, major, minor, pid) def openReply(self): self.sendToDaemon('/reply', '/nsm/client/open', 'Ready') def saveReply(self): self.sendToDaemon('/reply', '/nsm/client/save', 'Saved') def sendDirtyState(self, bool_dirty): if bool_dirty: self.sendToDaemon('/nsm/client/is_dirty') else: self.sendToDaemon('/nsm/client/is_clean') def sendGuiState(self, state): if state: self.sendToDaemon('/nsm/client/gui_is_shown') else: self.sendToDaemon('/nsm/client/gui_is_hidden') RaySession-0.12.2/src/shared/print_osc_messages.py000077500000000000000000000010701417052567600222070ustar00rootroot00000000000000#!/usr/bin/python3 import sys file = open(sys.argv[1], 'r') contents = file.read() all_lines = contents.split('\n') output = "" for line in all_lines: while line.startswith(' '): line = line.replace(' ', '') if line.startswith('@ray_method('): raym, par, qmessargs = line.partition('(') qmess, qargs = qmessargs.split(',') mess = qmess[1:-1] if qargs[1:-1] == 'None': args = 'strings' else: args = qargs[2:-2] output += "%s %s\n" % (mess, args) sys.stdout.write(output) RaySession-0.12.2/src/shared/ray.py000066400000000000000000000543771417052567600171320ustar00rootroot00000000000000 import argparse import liblo import os import shlex import socket import subprocess import sys from liblo import Server, Address from PyQt5.QtCore import QT_VERSION_STR, QFile from PyQt5.QtGui import QIcon, QPalette # get qt version in list of ints QT_VERSION = [] for strdigit in QT_VERSION_STR.split('.'): QT_VERSION.append(int(strdigit)) QT_VERSION = tuple(QT_VERSION) if QT_VERSION < (5, 6): sys.stderr.write( "WARNING: You are using a version of QT older than 5.6.\n" + "You won't be warned if a process can't be launch.\n") VERSION = "0.12.2" APP_TITLE = 'RaySession' DEFAULT_SESSION_ROOT = "%s/Ray Sessions" % os.getenv('HOME') SCRIPTS_DIR = 'ray-scripts' NOTES_PATH = 'ray-notes' FACTORY_SESSION_TEMPLATES = ( 'with_jack_patch', 'with_jack_config', 'scripted') RAYNET_BIN = 'ray-network' GIT_IGNORED_EXTENSIONS = ".wav .flac .ogg .mp3 .mp4 .avi .mkv .peak .m4a .pdf" GROUP_CONTEXT_AUDIO = 0x01 GROUP_CONTEXT_MIDI = 0x02 class PrefixMode: CUSTOM = 0 CLIENT_NAME = 1 SESSION_NAME = 2 class JackNaming: SHORT = 0 LONG = 1 class ClientStatus: STOPPED = 0 LAUNCH = 1 OPEN = 2 READY = 3 PRECOPY = 4 COPY = 5 SAVE = 6 SWITCH = 7 QUIT = 8 NOOP = 9 ERROR = 10 REMOVED = 11 UNDEF = 12 SCRIPT = 13 class ServerStatus: OFF = 0 NEW = 1 OPEN = 2 CLEAR = 3 SWITCH = 4 LAUNCH = 5 PRECOPY = 6 COPY = 7 READY = 8 SAVE = 9 CLOSE = 10 SNAPSHOT = 11 REWIND = 12 WAIT_USER = 13 OUT_SAVE = 14 OUT_SNAPSHOT = 15 SCRIPT = 16 class NSMMode: NO_NSM = 0 CHILD = 1 NETWORK = 2 class Protocol: NSM = 0 RAY_HACK = 1 RAY_NET = 2 class Option: NSM_LOCKED = 0x001 SAVE_FROM_CLIENT = 0x002 #DEPRECATED BOOKMARK_SESSION = 0x004 HAS_WMCTRL = 0x008 DESKTOPS_MEMORY = 0x010 HAS_GIT = 0x020 SNAPSHOTS = 0x040 SESSION_SCRIPTS = 0x080 GUI_STATES = 0x100 class Err: OK = 0 GENERAL_ERROR = -1 INCOMPATIBLE_API = -2 BLACKLISTED = -3 LAUNCH_FAILED = -4 NO_SUCH_FILE = -5 NO_SESSION_OPEN = -6 UNSAVED_CHANGES = -7 NOT_NOW = -8 BAD_PROJECT = -9 CREATE_FAILED = -10 SESSION_LOCKED = -11 OPERATION_PENDING = -12 COPY_RUNNING = -13 NET_ROOT_RUNNING = -14 SUBPROCESS_UNTERMINATED = -15 SUBPROCESS_CRASH = -16 SUBPROCESS_EXITCODE = -17 UNKNOWN_MESSAGE = -18 ABORT_ORDERED = -19 COPY_ABORTED = -20 SESSION_IN_SESSION_DIR = -21 # check control/osc_server.py in case of changes !!! class Command: NONE = 0 START = 1 OPEN = 2 SAVE = 3 STOP = 4 class WaitFor: NONE = 0 QUIT = 1 STOP_ONE = 2 ANNOUNCE = 3 REPLY = 4 DUPLICATE_START = 5 DUPLICATE_FINISH = 6 SCRIPT_QUIT = 7 class Template: NONE = 0 RENAME = 1 SESSION_SAVE = 2 SESSION_SAVE_NET = 3 SESSION_LOAD = 4 SESSION_LOAD_NET = 5 CLIENT_SAVE = 6 CLIENT_LOAD = 7 class SwitchState: NONE = 0 RESERVED = 1 NEEDED = 2 DONE = 3 class WindowManager: NONE = 0 X = 1 WAYLAND = 2 class Systray: OFF = 0 SESSION_ONLY = 1 ALWAYS = 2 class Favorite(): def __init__(self, name, icon, factory): self.name = name self.icon = icon self.factory = factory class ScriptFile: PREVENT = 0x0 PARENT = 0x1 LOAD = 0x2 SAVE = 0x4 CLOSE = 0x8 @classmethod def by_string(cls, action:str)->int: if action == 'load': return cls.LOAD if action == 'save': return cls.SAVE if action == 'close': return cls.CLOSE return cls.PREVENT debug = False def ifDebug(string): if debug: sys.stderr.write("%s\n" % string) def version_to_tuple(version_str): version_list = [] for c in version_str.split('.'): if not c.isdigit(): return () version_list.append(int(c)) return tuple(version_list) def add_self_bin_to_path(): # Add raysession/src/bin to $PATH to can use ray executables after make # Warning, will works only if link to this file is in RaySession/*/*/*.py this_path = os.path.realpath(os.path.dirname(os.path.realpath(__file__))) bin_path = "%s/bin" % os.path.dirname(this_path) if not os.environ['PATH'].startswith("%s:" % bin_path): os.environ['PATH'] = "%s:%s" % (bin_path, os.environ['PATH']) def get_list_in_settings(settings, path): # getting a QSettings value of list type seems to not works the same way # on all machines try: settings_list = settings.value(path, [], type=list) except BaseException: try: settings_list = settings.value(path, []) except BaseException: settings_list = [] return settings_list def is_git_taggable(string)->bool: ''' know if a string can be a git tag, not used currently ''' if not string: return False if string.startswith('/'): return False if string.endswith('/'): return False if string.endswith('.'): return False for forbidden in (' ', '~', '^', ':', '?', '*', '[', '..', '@{', '\\', '//', ','): if forbidden in string: return False if string == "@": return False return True def is_valid_full_path(path: str)->bool: if not path.startswith('/'): return False for forbidden in ('//', '/./', '/../'): if forbidden in path: return False if path.endswith(('/.', '/..')): return False return True def is_osc_port_free(port:int): try: testport = Server(port) except BaseException: return False del testport return True def get_free_osc_port(default=16187): ''' get a free OSC port for daemon, start from default ''' if default >= 65536: default = 16187 daemon_port = default used_port = True testport = None while used_port: try: testport = Server(daemon_port) used_port = False except BaseException: daemon_port += 1 used_port = True del testport return daemon_port def is_valid_osc_url(url:str): try: address = liblo.Address(url) return True except BaseException: return False def get_liblo_address(url): valid_url = False try: address = liblo.Address(url) valid_url = True except BaseException: valid_url = False msg = "%r is not a valid osc url" % url raise argparse.ArgumentTypeError(msg) if valid_url: try: liblo.send(address, '/ping') return address except BaseException: msg = "%r is an unknown osc url" % url raise argparse.ArgumentTypeError(msg) def get_liblo_address_from_port(port:int): try: port = int(port) except: msg = "%r port must be an int" % port raise argparse.ArgumentTypeError(msg) valid_port = False try: address = liblo.Address(port) valid_port = True except BaseException: valid_port = False msg = "%i is not a valid osc port" % port raise argparse.ArgumentTypeError(msg) if valid_port: try: liblo.send(address, '/ping') return address except BaseException: msg = "%i is an unknown osc port" % port raise argparse.ArgumentTypeError(msg) def are_same_osc_port(url1, url2): if url1 == url2: return True try: address1 = Address(url1) address2 = Address(url2) except BaseException: return False if address1.port != address2.port: return False if are_on_same_machine(url1, url2): return True return False def are_on_same_machine(url1, url2): if url1 == url2: return True try: address1 = Address(url1) address2 = Address(url2) except BaseException: return False if address1.hostname == address2.hostname: return True try: if (socket.gethostbyname(address1.hostname) in ('127.0.0.1', '127.0.1.1') and socket.gethostbyname(address2.hostname) in ('127.0.0.1', '127.0.1.1')): return True if socket.gethostbyaddr( address1.hostname) == socket.gethostbyaddr( address2.hostname): return True ip = Machine192.get() if ip not in (address1.hostname, address2.hostname): return False if (ip == socket.gethostbyname(address1.hostname) == socket.gethostbyname(address2.hostname)): # on some systems (as fedora), # socket.gethostbyname returns a 192.168.. url return True if (socket.gethostbyname(address1.hostname) in ('127.0.0.1', '127.0.1.1')): if address2.hostname == ip: return True if (socket.gethostbyname(address2.hostname) in ('127.0.0.1', '127.0.1.1')): if address1.hostname == ip: return True except BaseException: return False return False def get_net_url(port)->str: ip = Machine192.get() if not ip: return '' return "osc.udp://%s:%i/" % (ip, port) def shell_line_to_args(string:str)->list: try: args = shlex.split(string) except BaseException: return None return args def types_are_all_strings(types:str)->bool: for char in types: if char != 's': return False return True def are_they_all_strings(args:list)->bool: for arg in args: if not isinstance(arg, str): return False return True def get_window_manager(): if os.getenv('WAYLAND_DISPLAY'): return WindowManager.WAYLAND if os.getenv('DISPLAY'): return WindowManager.X return WindowManager.NONE def get_full_path(root, session_name): spath = "%s%s%s" % (root, os.sep, session_name) if session_name.startswith(os.sep): spath = session_name if spath.endswith(os.sep): spath = spath[:-1] return spath def protocol_to_str(protocol: int)->str: if protocol == Protocol.RAY_HACK: return "Ray-Hack" if protocol == Protocol.RAY_NET: return "Ray-Net" return "NSM" def protocol_from_str(protocol_str: str)->int: if protocol_str.lower() in ('ray_hack', 'ray-hack'): return Protocol.RAY_HACK elif protocol_str.lower() in ('ray_net', 'ray-net'): return Protocol.RAY_NET return Protocol.NSM class Machine192: ip = '' read_done = False @staticmethod def read()->str: try: ips = subprocess.check_output( ['ip', 'route', 'get', '1']).decode() ip_line = ips.partition('\n')[0] ip_end = ip_line.rpartition('src ')[2] ip = ip_end.partition(' ')[0] except BaseException: try: ips = subprocess.check_output(['hostname', '-I']).decode() ip = ips.split(' ')[0] except BaseException: return '' if ip.count('.') != 3: return '' return ip @classmethod def get(cls)->str: if cls.read_done: return cls.ip cls.ip = cls.read() cls.read_done = True return cls.ip class ClientData: client_id = '' protocol = Protocol.NSM executable_path = '' arguments = '' pre_env = '' name = '' prefix_mode = PrefixMode.SESSION_NAME custom_prefix = '' desktop_file = '' label = '' description = '' icon = '' capabilities = '' check_last_save = True ignored_extensions = GIT_IGNORED_EXTENSIONS template_origin = '' jack_client_name = '' jack_naming = 0 ray_hack = None ray_net = None @staticmethod def sisi(): return 'sissssissssssisssi' @staticmethod def new_from(*args): client_data = ClientData() client_data.update(*args) return client_data @staticmethod def spread_client(client)->tuple: return (client.client_id, client.protocol, client.executable_path, client.arguments, client.pre_env, client.name, client.prefix_mode, client.custom_prefix, client.desktop_file, client.label, client.description, client.icon, client.capabilities, int(client.check_last_save), client.ignored_extensions, client.template_origin, client.jack_client_name, client.jack_naming) def gui_init(self, client_id, protocol): self.client_id = client_id self.protocol = protocol def set_ray_hack(self, ray_hack): self.ray_hack = ray_hack def set_ray_net(self, ray_net): self.ray_net = ray_net def update(self, client_id, protocol, executable, arguments, pre_env, name, prefix_mode, custom_prefix, desktop_file, label, description, icon, capabilities, check_last_save, ignored_extensions, template_origin, jack_client_name, jack_naming, secure=False): self.executable_path = str(executable) self.arguments = str(arguments) self.pre_env = str(pre_env) self.desktop_file = str(desktop_file) self.label = str(label) self.description = str(description) self.icon = str(icon) self.check_last_save = bool(check_last_save) self.ignored_extensions = str(ignored_extensions) self.template_origin = template_origin self.jack_naming = jack_naming if secure: return self.client_id = str(client_id) self.protocol = int(protocol) if name: self.name = str(name) else: self.name = os.path.basename(self.executable_path) self.prefix_mode = int(prefix_mode) if self.prefix_mode == PrefixMode.CUSTOM: if custom_prefix: self.custom_prefix = str(custom_prefix) else: self.prefix_mode = PrefixMode.SESSION_NAME self.capabilities = str(capabilities) self.jack_client_name = jack_client_name def update_secure(self, *args): self.update(*args, secure=True) def spread(self)->tuple: return ClientData.spread_client(self) def prettier_name(self)->str: if self.label: return self.label if (self.protocol != Protocol.RAY_HACK and self.name): return self.name return self.executable_path class RayHack: config_file = "" save_sig = 0 stop_sig = 15 wait_win = False no_save_level = 0 useless_str = '' useless_int = 0 @staticmethod def sisi(): # the first 's' is for client_id, not stocked in RayHack return 'siiiisi' @staticmethod def new_from(*args): ray_hack = RayHack() ray_hack.update(*args) return ray_hack def saveable(self)->bool: return bool(self.config_file and self.save_sig) def noSaveLevel(self)->int: if self.config_file and self.save_sig == 0: return self.no_save_level return 0 def update(self, config_file, save_sig, stop_sig, wait_win, no_save_level, useless_str, useless_int): self.config_file = str(config_file) self.save_sig = int(save_sig) self.stop_sig = int(stop_sig) self.wait_win = bool(wait_win) self.no_save_level = int(no_save_level) def spread(self)->tuple: return (self.config_file, self.save_sig, self.stop_sig, int(self.wait_win), self.no_save_level, self.useless_str, self.useless_int) class RayNet: daemon_url = '' session_root = '' session_template = '' duplicate_state = -1 running_daemon_url = '' running_session_root ='' @staticmethod def sisi(): return 'sss' @staticmethod def new_from(*args): ray_net = RayNet() ray_net.update(*args) return ray_net def update(self, daemon_url, session_root, session_template): self.daemon_url = daemon_url self.session_root = session_root self.session_template = session_template def spread(self)->tuple: return (self.daemon_url, self.session_root, self.session_template) class GroupPosition: port_types_view = GROUP_CONTEXT_AUDIO | GROUP_CONTEXT_MIDI group_name = '' null_zone = '' in_zone = '' out_zone = '' null_xy = (0, 0) in_xy = (0, 0) out_xy = (0, 0) flags = 0 fully_set = True @staticmethod def get_attributes(): return ('port_types_view', 'group_name', 'null_zone', 'in_zone', 'out_zone', 'null_xy', 'in_xy', 'out_xy', 'flags') @staticmethod def sisi(): return 'issssiiiiiii' @staticmethod def new_from(*args): group_position = GroupPosition() group_position.update(*args) return group_position def write_from_dict(self, input_dict: dict): for attr in input_dict: if not attr in self.get_attributes(): sys.stderr.write( 'group position has no attribute %s\n' % attr) continue value = input_dict[attr] attr_type = type(value) if attr in ('port_types_view', 'flags'): if attr_type != int: continue elif attr in ('group_name', 'null_zone', 'in_zone', 'out_zone'): if attr_type != str: continue elif attr in ('null_xy', 'in_xy', 'out_xy'): if attr_type not in (list, tuple): continue value = tuple(value) self.__setattr__(attr, value) def is_same(self, other)->bool: if (self.port_types_view == other.port_types_view and self.group_name == other.group_name): return True return False def update(self, port_types_view: int, group_name: str, null_zone: str, in_zone: str, out_zone: str, null_x: int, null_y: int, in_x: int, in_y: int, out_x: int, out_y: int, flags: int): for string in (group_name, null_zone, in_zone, out_zone): if type(string) != str: return for digit in (port_types_view, null_x, null_y, in_x, in_y, out_x, out_y, flags): if type(digit) == int: continue if type(digit) != str: return if (digit.isdigit() or (digit.startswith('-') and digit.replace('-', '', 1).isdigit())): continue else: return self.port_types_view = port_types_view self.group_name = group_name self.null_zone = null_zone self.in_zone = in_zone self.out_zone = out_zone self.null_xy = (int(null_x), int(null_y)) self.in_xy = (int(in_x), int(in_y)) self.out_xy = (int(out_x), int(out_y)) self.flags = int(flags) def spread(self)->tuple: return (self.port_types_view, self.group_name, self.null_zone, self.in_zone, self.out_zone, self.null_xy[0], self.null_xy[1], self.in_xy[0], self.in_xy[1], self.out_xy[0], self.out_xy[1], self.flags) def to_dict(self)->dict: new_dict = {} for attr in self.__dir__(): if attr in self.get_attributes(): new_dict[attr] = self.__getattribute__(attr) return new_dict def get_str_value(self, attr: str)->str: if attr not in self.get_attributes(): return '' return str(self.__getattribute__(attr)) class PortGroupMemory: group_name = '' port_type = 0 port_mode = 0 port_names = [] above_metadatas = False @staticmethod def get_attributes(): return ('group_name', 'port_type', 'port_mode', 'above_metadatas', 'port_names') @staticmethod def new_from(*args): portgrp_memory = PortGroupMemory() portgrp_memory.update(*args) return portgrp_memory def write_from_dict(self, input_dict: dict): for attr in input_dict: if not attr in self.get_attributes(): sys.stderr.write( 'PortGroupMemory has no attribute %s\n' % attr) continue value = input_dict[attr] attr_type = type(value) if value == 'group_name' and attr_type != str: continue if value in ('port_type', 'port_mode') and attr_type != int: continue if value == 'above_metadatas' and attr_type != bool: continue if value == 'port_names' and attr_type not in (tuple, list): continue self.__setattr__(attr, value) def update(self, group_name: str, port_type: int, port_mode: int, above_metadatas: int, *port_names): self.group_name = group_name self.port_type = port_type self.port_mode = port_mode self.above_metadatas = bool(above_metadatas) self.port_names = port_names def spread(self)->tuple: return (self.group_name, self.port_type, self.port_mode, int(self.above_metadatas), *self.port_names) def to_dict(self)->dict: new_dict = {} for attr in self.__dir__(): if attr in self.get_attributes(): new_dict[attr] = self.__getattribute__(attr) return new_dict def has_a_common_port_with(self, other)->bool: if (self.port_type != other.port_type or self.port_mode != other.port_mode or self.group_name != other.group_name): return False for port_name in self.port_names: if port_name in other.port_names: return True return False RaySession-0.12.2/utility-scripts/000077500000000000000000000000001417052567600171005ustar00rootroot00000000000000RaySession-0.12.2/utility-scripts/all_ray_hack_to_nsm_hydrogen.sh000077500000000000000000000122521417052567600253300ustar00rootroot00000000000000#!/bin/bash hydro_rh_to_nsm(){ # variables 'session' and 'client_id' have to be set # session must be open # current directory must be in session path folder="${session##*/}.$client_id" current_hsong_file="$folder/${session##*/}.h2song" if ! [ -f "$current_hsong_file" ];then echo "$current_hsong_file doesn't exists, skip" return 1 fi # here rename h2song file to match with how hydrogen works with NSM if ! mv "$folder/${session##*/}.h2song" "$folder/${session##*/}.$client_id.h2song";then echo " impossible to rename h2song file, skip" return 1 fi # trash and remove hydrogen Ray-Hack client ray_control client $client_id trash ray_control trashed_client $client_id remove_keep_files # add the new hydrogen NSM client ray_control add_executable $executable client_id:$client_id not_start } # check what to do with arguments convert_current_session=false convert_sessions=false convert_client_templates=false convert_session_templates=false for arg in "$@";do [[ "$arg" == sessions ]] && convert_sessions=true [[ "$arg" == client_templates ]] && convert_client_templates=true [[ "$arg" == session_templates ]] && convert_session_templates=true done if ! ($convert_sessions || $convert_client_templates || $convert_session_templates);then convert_current_session=true fi executable=hydrogen config_file="\$RAY_SESSION_NAME.h2song" arguments="-n -s \"\$CONFIG_FILE\"" list_filters[0]="executable:$executable" list_filters[1]="protocol:Ray-Hack" list_filters[2]="prefix_mode:2" list_filters[3]="config_file:$config_file" list_filters[4]="arguments:$arguments" # check if hydrogen factory template uses NSM hydro_nsm_templates=$(ray_control list_factory_client_templates executable:$executable protocol:NSM) if [ -z "$hydro_nsm_templates" ];then echo "Your current $executable version seems to be too old to have correct NSM support." exit 1 fi # better to not use session_scripts and bookmark options # for performance and security # during the execution of this script reput_session_scripts=false reput_bookmarks=false if ! $convert_current_session;then # no need to unset session_scripts and bookmarks # if we only work in the current session # because, in this case, session will not be saved or closed ray_control has_option session_scripts && reput_session_scripts=true ray_control has_option bookmark_session_folder && reput_bookmarks=true ray_control set_options not_session_scripts not_bookmark_session_folder fi if $convert_current_session;then echo "proceed in the current session" session=$(ray_control get_session_path) if [ -z "$session" ];then echo "no arguments, no running session, nothing to do !" exit 1 fi clients=$(ray_control list_clients "${list_filters[@]}") if [ -z "$clients" ];then echo "no matching client in the current session, nothing to do !" exit 1 fi cd "$session" for client_id in $clients;do echo " client:$client_id" ray_control client $client_id stop hydro_rh_to_nsm done fi if $convert_sessions;then echo "proceed in all sessions" IFS=$'\n' for session in $(ray_control list_sessions);do unset IFS ray_control open_session_off "$session" 2>/dev/null clients=$(ray_control list_clients "${list_filters[@]}") if [ -z "$clients" ];then ray_control abort 2>/dev/null continue fi echo "treating session:$session" cd "$(ray_control get_session_path)" echo cd $PWD for client_id in $clients;do echo " client:$client_id" hydro_rh_to_nsm done done ray_control close fi if $convert_client_templates;then echo "proceed in all client templates" IFS=$'\n' for template in $(ray_control list_user_client_templates "${list_filters[@]}");do unset IFS session=$(mktemp -u) ray_control open_session_off "$session" cd "$session" client_id=$(ray_control add_user_client_template "$template" not_start) hydro_rh_to_nsm ray_control client $client_id save_as_template "$template" ray_control abort done fi if $convert_session_templates;then echo "proceed in all session templates" IFS=$'\n' for session_template in $(ray_control list_session_templates);do session=$(mktemp -u) ray_control open_session_off "$session" cd "$session" echo cd $PWD clients=$(ray_control list_clients "${list_filters[@]}") if [ -z "$clients" ];then ray_control abort 2>/dev/null continue fi echo " treating session template:$session" for client_id in $clients;do echo " client:$client_id" hydro_rh_to_nsm done # save the session and update the template ray_control save ray_control save_as_template "$session_template" ray_control abort done fi $reput_session_scripts && ray_control set_options session_scripts $reput_bookmarks && ray_control set_options bookmark_session_folder RaySession-0.12.2/utility-scripts/all_ray_hack_to_nsm_jack_mixer.sh000077500000000000000000000123061417052567600256250ustar00rootroot00000000000000#!/bin/bash jack_mixer_rh_to_nsm(){ # variables 'session' and 'client_id' have to be set # session must be open # current directory must be in session path folder="${session##*/}.$client_id" current_xml_file="$folder/${session##*/}.xml" if ! [ -f "$current_xml_file" ];then echo "$current_xml_file doesn't exists, skip" return 1 fi # here move .xml jack_mixer conf file to match with how jack_mixer works with NSM if ! mv "$current_xml_file" "${session##*/}.$client_id.xml";then echo " impossible to move $current_xml_file file, skip" return 1 fi # trash and remove jack_mixer Ray-Hack client ray_control client $client_id trash ray_control trashed_client $client_id remove_keep_files # add the new jack_mixer NSM client ray_control add_executable $executable client_id:$client_id not_start } # check what to do with arguments convert_current_session=false convert_sessions=false convert_client_templates=false convert_session_templates=false for arg in "$@";do [[ "$arg" == sessions ]] && convert_sessions=true [[ "$arg" == client_templates ]] && convert_client_templates=true [[ "$arg" == session_templates ]] && convert_session_templates=true done if ! ($convert_sessions || $convert_client_templates || $convert_session_templates);then convert_current_session=true fi executable=jack_mixer config_file="\$RAY_SESSION_NAME.xml" arguments="-c \"\$CONFIG_FILE\"" list_filters[0]="executable:$executable" list_filters[1]="protocol:Ray-Hack" list_filters[2]="prefix_mode:2" list_filters[3]="config_file:$config_file" list_filters[4]="arguments:$arguments" # check if jack_mixer factory template uses NSM jack_mixer_nsm_templates=$(ray_control list_factory_client_templates executable:$executable protocol:NSM) if [ -z "$jack_mixer_nsm_templates" ];then echo "Your current $executable version seems to be too old to have correct NSM support." exit 1 fi # better to not use session_scripts and bookmark options # for performance and security # during the execution of this script reput_session_scripts=false reput_bookmarks=false if ! $convert_current_session;then # no need to unset session_scripts and bookmarks # if we only work in the current session # because, in this case, session will not be saved or closed ray_control has_option session_scripts && reput_session_scripts=true ray_control has_option bookmark_session_folder && reput_bookmarks=true ray_control set_options not_session_scripts not_bookmark_session_folder fi if $convert_current_session;then echo "proceed in the current session" session=$(ray_control get_session_path) if [ -z "$session" ];then echo "no arguments, no running session, nothing to do !" exit 1 fi clients=$(ray_control list_clients "${list_filters[@]}") if [ -z "$clients" ];then echo "no matching client in the current session, nothing to do !" exit 1 fi cd "$session" for client_id in $clients;do echo " client:$client_id" ray_control client $client_id stop jack_mixer_rh_to_nsm done fi if $convert_sessions;then echo "proceed in all sessions" IFS=$'\n' for session in $(ray_control list_sessions);do unset IFS ray_control open_session_off "$session" 2>/dev/null clients=$(ray_control list_clients "${list_filters[@]}") if [ -z "$clients" ];then ray_control abort 2>/dev/null continue fi echo "treating session:$session" cd "$(ray_control get_session_path)" echo cd $PWD for client_id in $clients;do echo " client:$client_id" jack_mixer_rh_to_nsm done done ray_control close fi if $convert_client_templates;then echo "proceed in all client templates" IFS=$'\n' for template in $(ray_control list_user_client_templates "${list_filters[@]}");do unset IFS session=$(mktemp -u) ray_control open_session_off "$session" cd "$session" client_id=$(ray_control add_user_client_template "$template" not_start) jack_mixer_rh_to_nsm ray_control client $client_id save_as_template "$template" ray_control abort done fi if $convert_session_templates;then echo "proceed in all session templates" IFS=$'\n' for session_template in $(ray_control list_session_templates);do session=$(mktemp -u) ray_control open_session_off "$session" cd "$session" echo cd $PWD clients=$(ray_control list_clients "${list_filters[@]}") if [ -z "$clients" ];then ray_control abort 2>/dev/null continue fi echo " treating session template:$session" for client_id in $clients;do echo " client:$client_id" jack_mixer_rh_to_nsm done # save the session and update the template ray_control save ray_control save_as_template "$session_template" ray_control abort done fi $reput_session_scripts && ray_control set_options session_scripts $reput_bookmarks && ray_control set_options bookmark_session_folder RaySession-0.12.2/utility-scripts/ardour5to6ray.sh000077500000000000000000000024401417052567600221650ustar00rootroot00000000000000#!/bin/bash # This script can be used to transform all ardour5 executables to ardour6 # in all sessions. # If you want to use it for other executables, # just change old_executable and new_executable values old_executable=ardour5 new_executable=ardour6 if ! which ray_control >/dev/null;then echo "ray_control is missing, abort." exit 1 fi all_sessions=`ray_control list_sessions` ns=`echo "$all_sessions"|wc -l` #number of sessions if [ -z "$all_sessions" ];then echo "No sessions...quit." exit 0 fi # parse all sessions for ((i=1; i<=$ns; i++));do session=`echo "$all_sessions"|sed -n ${i}p` # open session ('off' means -> without launching any client) if ! ray_control open_session_off "$session";then echo "failed to open session: $session" continue fi echo "treating session: $session" # parse all proxy clients of the session for client_id in `ray_control list_clients "executable:$old_executable"`;do # change executable from old_executable to new_executable if ray_control client $client_id set_properties "executable:$new_executable";then echo " done for $client_id." else echo " abort for client $client_id. Impossible to change its executable." fi done done RaySession-0.12.2/utility-scripts/ardour_from_external_to_session.sh000077500000000000000000000064201417052567600261270ustar00rootroot00000000000000#!/bin/bash # pass as argument to this script a *.ardour session file or an ardour session dir # if it has been made with ardour not launched from RaySession. # It will create (or load) a RaySession session with the same name # and move (or copy) the ardour session files to the new RaySession session executable=ardour if [[ "$1" == "--executable" ]];then shift executable="$1" shift fi current_session=false if [[ "$1" == "--current-session" ]];then shift current_session=true session_path=$(ray_control get_session_path) if [ -z "$session_path" ];then echo "option --current-session without running Ray session, abort." exit 7 fi fi if [ -f "$1" ] && [[ "$1" =~ ".ardour"$ ]];then # argument is a file and an ardour session ardour_session_dir=`dirname "$1"` ardour_session_name=`basename "$ardour_session_dir"` if ! [ -f "$ardour_session_dir/$ardour_session_name.ardour" ];then # argument is not the main ardour snapshot of the session # moves it to be the main if ! mv "$1" "$ardour_session_dir/$ardour_session_name.ardour";then echo "$1 is not the main snapshot of the session, and it can't be moved to. abort." exit 6 fi fi else ardour_session_dir="$1" [ -z "$1" ] && ardour_session_dir="$PWD" ardour_session_name=`basename "$ardour_session_dir"` if ! [ -f "$ardour_session_dir/$ardour_session_name.ardour" ];then echo "$ardour_session_dir/$ardour_session_name.ardour doesn't exists." echo "It means it is probably not an ardour session. abort." exit 1 fi fi if ! $current_session;then if ! ray_control start;then echo "can not start ray_control. abort." exit 2 fi ray_root=`ray_control get_root` if ! ray_control open_session_off "$ardour_session_name";then echo "impossible to load $ardour_session_name with RaySession. abort." exit 3 fi ray_control add_factory_client_template "JACK Connections" session_path="$ray_root/$ardour_session_name" fi if $current_session;then client_id=`ray_control add_executable $executable "prefix:$ardour_session_name" not_start` else client_id=`ray_control add_executable $executable not_start` fi if [ -z "$client_id" ];then echo "impossible to add $executable to session $ardour_session_name. abort." exit 4 fi echo "client_id:$client_id" # check if we move or copy the ardour session folder # if session is on the same partition than RaySession root folder -> move, else copy move_or_copy=mv [[ `stat -c '%d' "$ardour_session_dir"` == `stat -c '%d' "$ray_root"` ]] || move_or_copy="cp -R -v" new_ardour_session_dir="$session_path/$ardour_session_name.$client_id" if [[ "$move_or_copy" == mv ]];then echo -n "moving " else echo -n "copying " fi echo "$ardour_session_dir to $new_ardour_session_dir" $move_or_copy "$ardour_session_dir" "$new_ardour_session_dir" if ! mv "$new_ardour_session_dir/interchange/$ardour_session_name" \ "$new_ardour_session_dir/interchange/$ardour_session_name.$client_id";then # file copy/move failed. abort ray_control client $client_id trash exit 5 fi echo "Done. Open RaySession if not done and start the ardour client to start the ardour session." exit 0 RaySession-0.12.2/utility-scripts/connections_nsm_adapter.py000077500000000000000000000102621417052567600243550ustar00rootroot00000000000000#!/usr/bin/python3 import xml.etree.ElementTree as ET import sys READ_OFF = 0 READ_FILE_PATH = 1 READ_OLD_NAME = 2 READ_NEW_NAME = 3 READ_BIG_VAR = 4 def get_new_port_name(port:str, old_group:str, new_group:str)->str: if port.startswith((old_group + ':', old_group + '/')): return port.replace(old_group, new_group, 1) if port.startswith((old_group + '.0/', old_group + '.0:')): return port.replace(old_group + '.0', new_group, 1) return '' def main_process(): input_file_path = '' read_mode = READ_FILE_PATH all_groups = [] new_group = {'old_name': '', 'new_name': ''} for arg in sys.argv[1:]: if read_mode == READ_FILE_PATH: input_file_path = arg read_mode = READ_OFF elif arg == '-g': read_mode = READ_OLD_NAME elif read_mode == READ_OLD_NAME: new_group['old_name'] = arg read_mode = READ_NEW_NAME elif read_mode == READ_NEW_NAME: new_group['new_name'] = arg all_groups.append(new_group) new_group = {'old_name': '', 'new_name': ''} read_mode = READ_OFF elif arg.startswith('old_name:'): read_mode = READ_BIG_VAR for line in arg.splitlines(): if line.startswith('old_name:'): new_group['old_name'] = line.replace('old_name:', '', 1) elif line.startswith('new_name:'): new_group['new_name'] = line.replace('new_name:', '', 1) all_groups.append(new_group) new_group = {'old_name': '', 'new_name': ''} read_mode = READ_OFF if not input_file_path: sys.stderr.write('no input file, nothing to do.\n') sys.exit(1) if read_mode != READ_OFF: sys.stderr.write('malformed arguments\n') sys.exit(1) try: tree = ET.parse(input_file_path) except: sys.stderr.write('fail to parse %s as a XML file\n' % input_file_path) sys.exit(1) jackpatch_lines = [] new_connections = [] root = tree.getroot() if root.tag != "RAY-JACKPATCH": sys.stderr.write('xml file %s is not a RAY-JACKPATCH file\n' % input_file_path) sys.exit(1) for child in root: if child.tag != "connection": continue port_from = '' port_to = '' for key in child.attrib.keys(): if key == 'from': port_from = child.attrib[key] elif key == 'to': port_to = child.attrib[key] if port_from and port_to: break else: continue jackpatch_lines.append("%s |> %s" % (port_from, port_to)) new_port_from = '' new_port_to = '' for group in all_groups: # get_new_port_name returns an empty string # if port may not belong to old group if not new_port_from: new_port_from = get_new_port_name( port_from, group['old_name'], group['new_name']) if not new_port_to: new_port_to = get_new_port_name( port_to, group['old_name'], group['new_name']) if new_port_from and new_port_to: break if new_port_from: if new_port_to: jackpatch_lines.append("%s |> %s" % (new_port_from, new_port_to)) new_connections.append({'from': new_port_from, 'to': new_port_to}) jackpatch_lines.append("%s |> %s" % (new_port_from, port_to)) new_connections.append({'from': new_port_from, 'to': port_to}) if new_port_to: jackpatch_lines.append("%s |> %s" % (port_from, new_port_to)) new_connections.append({'from': port_from, 'to': new_port_to}) for con in new_connections: new_conn_xml = ET.SubElement(root, 'connection') new_conn_xml.attrib['from'] = con['from'] new_conn_xml.attrib['to'] = con['to'] print('\n'.join(jackpatch_lines)) tree.write(input_file_path) if __name__ == '__main__': main_process() RaySession-0.12.2/utility-scripts/hydro_from_proxy_to_nsm.sh000077500000000000000000000073611417052567600244360ustar00rootroot00000000000000#!/bin/bash # This script can be used to transform all hydrogen clients launched via proxy # to clients launching directly hydrogen # it applies this change to all sessions. # This script works for Hydrogen but could not works for any client # It depends on the way the client saves its files under NSM (in a folder..) executable=hydrogen if ! which ray_control >/dev/null;then echo "ray_control is missing, abort." exit 1 fi all_sessions=`ray_control list_sessions` ns=`echo "$all_sessions"|wc -l` #number of sessions if [ -z "$all_sessions" ];then echo "No sessions...quit." exit 0 fi # parse all sessions for ((i=1; i<=$ns; i++));do session=`echo "$all_sessions"|sed -n ${i}p` # open session ('off' means -> without launching any client) if ! ray_control open_session_off "$session";then echo "failed to open session: $session" continue fi session_name=$(ray_control get_session_name) echo "treating session: $session" # parse all proxy clients of the session for client_id in `ray_control list_clients "executable:ray-proxy"`;do proxy_properties=`ray_control client $client_id get_proxy_properties` if ! echo "$proxy_properties"|grep ^"executable:$executable"$ >/dev/null;then # executable in the proxy is not hydrogen, skip it. echo " skipping client $client_id" continue fi client_files=`ray_control client $client_id list_files` if [ -z "$client_files" ] || [ -z "$proxy_properties" ];then # No client files or error asking ray_control, skip. echo " client untreated $client_id" continue fi if [ `echo "$client_files"|wc -l` != 1 ];then echo " client untreated $client_id" echo " A proxy should only contains one directory. and no more files." echo "$client_files" continue fi echo " treating client $client_id" # here config_file is the *.h2song file (hydrogen project). config_file=$(echo "$proxy_properties" |grep ^"config_file:" |sed 's/^config_file://' \ |sed "s/\$RAY_SESSION_NAME/$session_name/g" \ |sed "s/\${RAY_SESSION_NAME}/$session_name/g") proxy_dir="$client_files" full_config_file="$proxy_dir/$config_file" if ! [ -f "$full_config_file" ];then echo " file $full_config_file doesn't exists" continue fi config_file_short=`basename "$config_file"` extension="${config_file_short##*.}" # should be h2song here. config_file_base="${config_file_short%.*}" # the file name without .h2song # change executable from ray-proxy to hydrogen if ! ray_control client $client_id set_properties "executable:$executable";then echo " abort for client $client_id. Impossible to change its executable." continue fi # move *.h2song file to the wanted path if ! mv "$full_config_file" "$proxy_dir.$extension";then echo " Impossible to move $full_config_file to $proxydir.$extension. abort" # move didn't work, so reset client executable to ray-proxy ray_control client $client_id set_properties "executable:ray-proxy" continue fi # remove proxy directory if it only contains ray-proxy.xml if [[ `ls "$proxy_dir"` == 'ray-proxy.xml' ]];then rm -R "$proxy_dir" else echo " $proxy_dir has not been removed because it still contains other files" fi done done RaySession-0.12.2/utility-scripts/rayproxy_to_rayhack.sh000077500000000000000000000103231417052567600235370ustar00rootroot00000000000000#!/bin/bash print_help(){ echo "usage: $1 arguments where options can be --help print this help all_sessions convert ray-proxy clients to RayHack in all sessions all_templates convert all ray-proxy templates to Ray-Hack running_client CLIENT_ID convert running CLIENT_ID to ray_hack if it is a ray-proxy " } proxy_to_ray_hack(){ client_id="$1" echo " treating $client_id" c_project_path=$(ray_control client $client_id list_files) proxy_properties=$(ray_control client $client_id get_proxy_properties) # more than 1 path for this client, skip [[ $(echo "$c_project_path"|wc -l) == "1" ]] || continue # move the folder didn't work, skip if ! mv "$c_project_path" "${c_project_path}__bak";then echo "error while moving files, ignore it" continue fi echo "trash $client_id" ray_control client $client_id trash echo "remove_definitely $client_id" ray_control trashed_client $client_id remove_definitely normal_lines=$(ray_control client $client_id get_properties|grep -e ^label: -e ^description: -e ^icon: -e ^desktop_file:) exec_line=$(echo "$proxy_properties"|grep ^executable:) good_lines=$(echo "$proxy_properties"|grep -e ^arguments: -e ^no_save_level:) save_sig_line=$(echo "$proxy_properties"|grep ^save_signal:) stop_sig_line=$(echo "$proxy_properties"|grep ^stop_signal:) wait_win_line=$(echo "$proxy_properties"|grep ^wait_window:) config_file_line=$(echo "$proxy_properties"|grep ^config_file:) config_file="${config_file_line#*:}" if [ -z "$config_file" ] && [[ "${save_sig_line#*:}" != "0" ]];then config_file=anything fi # mmmh, on very old proxies, stop signal was always saved to SIGUSR1 stop_sig=${stop_sig_line#*:} [[ "$stop_sig" == "10" ]] && stop_sig=15 new_client_id=$(ray_control add_executable "${exec_line#*:}" ray_hack not_start client_id:${client_id}) if [ -n "$new_client_id" ];then echo "set properties of new client '$new_client_id'" ray_control client $new_client_id set_properties "$good_lines config_file:${config_file} save_sig:${save_sig_line#*:} stop_sig:$stop_sig wait_win:${wait_win_line#*:} $normal_lines" rm -R "$c_project_path" else echo "Add executable failed, sorry, no more client" fi mv "${c_project_path}__bak" "$c_project_path" } all_sessions(){ IFS=$'\n' for session in $(ray_control list_sessions);do echo "____" echo "session:"$session ray_control open_session_off "$session" || continue clients=$(ray_control list_clients executable:ray-proxy) for client_id in $clients;do proxy_to_ray_hack "$client_id" done done ray_control save } all_templates(){ ray_control open_session_off $(mktemp -u) IFS=$'\n' for client_template in $(ray_control list_user_client_templates);do echo " client_template:$client_template" client_id=$(ray_control add_user_client_template "$client_template" not_start) || continue echo " client_id:$client_id" if ray_control client $client_id get_properties|grep ^executable:ray-proxy;then echo " ray-proxy -> Ray-Hack" proxy_to_ray_hack $client_id echo " save as template $client_template" ray_control client $client_id save_as_template "$client_template" fi ray_control client $client_id trash ray_control trashed_client $client_id remove_definitely done } argument=$1 shift case $argument in all_sessions|all_templates) export RAY_CONTROL_PORT=$(ray_control start_new_hidden) $argument ray_control quit ;; running_client) client_id="$1" [ -z "$client_id" ] && print_help && exit 1 echo -n "session_path:" ray_control get_session_path || exit 1 if ! ray_control list_clients|grep ^$client_id$;then echo "no client with $client_id client_id" exit 1 fi ray_control client "$client_id" stop proxy_to_ray_hack "$client_id" ;; --help ) print_help ;; *) print_help exit 1 esac RaySession-0.12.2/utility-scripts/session_ray_to_nsm.sh000077500000000000000000000130541417052567600233570ustar00rootroot00000000000000#!/bin/bash get_property(){ # $properties must be set before line=$(echo "$properties"|grep -m 1 ^"$1:") echo "${line#*:}" } # read arguments replace_jackpatch=false if [[ "$1" == '--replace-jackpatch' ]];then replace_jackpatch=true shift fi # we need to know the script dir to launch the python script # that writes connections file bash_dir=`realpath "$(dirname "${BASH_SOURCE[0]}")"` # get the session to convert # if no argument, the current session is choose session="$1" if [ -z "$session" ];then session=$(ray_control get_session_path) if [ -z "$session" ];then echo "No session loaded, nothing to do" exit fi fi # better to not use session_scripts and bookmark options # for performance and security # during the execution of this script reput_session_scripts=false reput_bookmarks=false ray_control has_option session_scripts && reput_session_scripts=true ray_control has_option bookmark_session_folder && reput_bookmarks=true ray_control set_options not_session_scripts not_bookmark_session_folder # close and re-open the session # It prevents to have to save the session with clients off ray_control close ray_control open_session_off "$session" ray_control take_snapshot "Just before NSM conversion" cd "$(ray_control get_session_path)" # in bash, init empty vars is unneeded, that is true ;) nsm_file_contents='' connections_file_old='' connections_file_new='' group_replaces='' rayjackpatch_client_id='' # list clients and operate on them for client_id in $(ray_control list_clients);do # change the client prefix to change their working directory # and adapt it to the nsmd way: client_name.client_id ray_control client $client_id change_prefix client_name # read all needed client properties properties=$(ray_control client "$client_id" get_properties) executable=$(get_property executable) client_name=$(get_property name) protocol=$(get_property protocol) jack_naming=$(get_property jack_naming) jack_name=$(get_property jack_name) case $protocol in NSM) if [[ "$executable" == ray-jackpatch ]];then connections_file="$client_name.$client_id.xml" rayjackpatch_client_id="$client_id" continue fi nsm_file_contents+="$client_name:$executable:$client_id\n" ;; Ray-Hack) # we will adapt the Ray-Hack client with nsm-proxy arguments=$(get_property arguments|sed 's/$RAY_JACK_CLIENT_NAME/$NSM_CLIENT_ID/g') config_file=$(get_property config_file|sed "s/\$RAY_SESSION_NAME/${session_path##*/}/g") save_sig=$(get_property save_sig) stop_sig=$(get_property stop_sig) label=$(get_property label) # save the nsm-proxy config file contents proxy_contents="executable $executable arguments $arguments config file $config_file save signal $save_sig stop signal $stop_sig label $label " linkdir="NSM Proxy.$client_id" if [ -d "$linkdir" ] && [ -L "$linkdir" ] && [[ "$(readlink "$linkdir")" == "$client_name.$client_id" ]];then echo "$linkdir already linked, keep it" echo "$proxy_contents" > "NSM Proxy.$client_id/nsm-proxy.config" nsm_file_contents+="NSM Proxy:nsm-proxy:$client_id\n" # link the NSM Proxy new directory to the Ray-Hack client dir elif ln -s -r "$client_name.$client_id" "NSM Proxy.$client_id";then echo "$proxy_contents" > "NSM Proxy.$client_id/nsm-proxy.config" nsm_file_contents+="NSM Proxy:nsm-proxy:$client_id\n" else echo "impossible to link $client_name.$client_id to NSM Proxy.$client_id" fi ;; esac if [[ "$jack_naming" != 1 ]];then # the way to name JACK clients is different in RaySession and NSM # in NSM, long JACK naming is used, # JACK client is named this way: client_name.client_id # in RS, by default it is only: # client_name (+ _N) if client_id ends with digits ray_control client $client_id set_properties jack_naming:1 # a long string with jack client names will be sent as argument to # the python script which add new connections to the config file group_replaces+="old_name:$jack_name new_name:$client_name.$client_id " fi done jackpatch_id=nWASRAY if $replace_jackpatch and [ -n "$rayjackpatch_client_id" ];then # remove ray-jackpatch from session and replace it with jackpatch ray_control client $rayjackpatch_client_id trash ray_control add_executable jackpatch not_start client_id:$jackpatch_id prefix_mode:client_name fi if [ -n "$connections_file" ];then # get the connections as written by the NSM jackpatch # Note it will also update the ray-jackpatch file with new connections conns=`"$bash_dir/connections_nsm_adapter.py" "$connections_file" "$group_replaces"` if $replace_jackpatch;then # write the jackpatch connections file and add jackpatch to the NSM session echo "$conns" > JACKPatch.$jackpatch_id.jackpatch nsm_file_contents="JACKPatch:jackpatch:$jackpatch_id $nsm_file_contents" fi fi # save and close session # very important to save because client prefixes have been moved ray_control close # write the NSM session file echo -e "$nsm_file_contents" > session.nsm # reput options unset at the script start $reput_session_scripts && ray_control set_options session_scripts $reput_bookmarks && ray_control set_options bookmark_session_folder echo "Done."