pax_global_header00006660000000000000000000000064135123647530014523gustar00rootroot0000000000000052 comment=e77780e7524c0a97f25313b205837191bbe9712a uftrace-0.9.3/000077500000000000000000000000001351236475300131655ustar00rootroot00000000000000uftrace-0.9.3/.gitignore000066400000000000000000000006661351236475300151650ustar00rootroot00000000000000*.o *.op *.ot a.out ftrace uftrace ftrace.dir ftrace.dir.old ftrace.data ftrace.data.old uftrace.data uftrace.data.old !gdb/uftrace/*.py libmcount.so libmcount-*.so libcygprof.so libcygprof-nop.so gmon.out tests/t-* tests/arch/*/t-* tests/*.so check-deps/* !check-deps/*.c !check-deps/Makefile* FLAGS version.h .config .build/ GPATH GRTAGS GTAGS TAGS tags cscope.* *.pyc *.sw[opn] *.patch *.orig *.gcda *.gcno misc/demangler misc/symbols uftrace-0.9.3/.travis.yml000066400000000000000000000030031351236475300152720ustar00rootroot00000000000000language: c # Ubuntu 14.04 LTS dist: trusty sudo: required install: - sudo apt-get -qq update - sudo apt-get -y install libelf-dev libstdc++-4.8-dev pandoc script: ./configure && make env: global: # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created # via the "travis encrypt" command using the project repo's public key - secure: "zl83nEBIlkt3inI+jtGCDmrA3Lzdylf7Ez81soIPEWlirR2nZGfwhnHzfV8BCl+vaxaDIZYhHcHNF90Qt2WEOZ980WfXS0PPMslEWsL57N1oh2/5/dWHANL/+hlw11EiwtWNm6DEY4E2WyrCRinzxoVkH+UgKMV0cLPs5y5qMLd+/oqfDKD1eMp91GsEB+mzK7/qoS1H8TbubbyS3nFpUj9ZqsZwBGatL62vZYiTnaw+8M9BANFl/ctE9dchNNhKUYxwXMLKmE/ET7Ryk0Ikf1QojG0NI7xUyoZsVDifipYTWOIKJQWVxJwlyUE9QZsrYIVM/5qbeOlDKOwTtvOXW3joSlYrgNv5Bp3UJJAUxIrH5X45e1bi7TTiJ/KhT48+jTLtKp619PUuw23hlHKMK6p9niXcA/tNHCEnQTd8GuKOHV3ebAipeIBcuNTTmR4AnnzwB870UAFF9cS1YMAeW1wDXxO9w8CiwKnOlFRfko+YkC7H+DhuEn7Fg7nB6VoNCgCle5SUnTAbMIuH4TqlPI6ix9SHUU+jIWn+hS9Ck5vecGzvEglsOsiXsZ/dx3NzkEO35JFc4XhmCk9VQsOgJFgufC3vB2sG4cQML09PdbyPQ4XMuAgDB3EmjRwa6IiUuUuBqYqBSmZyhZOp3xBtAebg5MTz+fRQ+2ku/RM54gE=" before_install: - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- addons: coverity_scan: project: name: "namhyung/uftrace" description: "Build submitted via Travis CI" notification_email: namhyung@gmail.com build_command_prepend: "./configure; make clean" build_command: "make -j 4" branch_pattern: masteruftrace-0.9.3/CONTRIBUTING.md000066400000000000000000000061621351236475300154230ustar00rootroot00000000000000Contributing to uftrace ======================= Thanks for considering contribution to uftrace. You can git clone the uftrace source on the following address and send PR with your patch. But, before doing that, I recommend you to read this to follow the conventions. https://github.com/namhyung/uftrace Coding style ------------ The uftrace is written in C and mostly follows the coding style of the Linux kernel [1]. The only different is where to put the closing brace and start of subsequent block. I prefer to put it at a separate line for readability. For example: if (cond == A) { do_some_thing(); } else if (cond == B) { do_other_thing(); } Please note that the position of the "else if" line. For python programs (for tests or scripts), use 4 spaces to indent. [1] https://www.kernel.org/doc/Documentation/process/coding-style.rst Include subject word in message header -------------------------------------- Although uftrace has a small codebase, I believe it's a good convention to prefix your subject line with colon. This lets me and other developers more easily distinguish patches from other subject. $ git log --oneline --graph * fef4226 Merge branch 'misc-fix' |\ | * 54a4ef0 test: Fix to be able to call runtest.py directly | * 6bbe4a0 graph: Skip kernel functions outside of user | * a76c7cb kernel: Use real address for filter match |/ ... Signing your patch ------------------ The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: if you can certify the below: Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. then you just add a line saying Signed-off-by: Random J Developer using your real name (sorry, no pseudonyms or anonymous contributions.) uftrace-0.9.3/COPYING000066400000000000000000000432541351236475300142300ustar00rootroot00000000000000 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 How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 (at your option) 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. uftrace-0.9.3/INSTALL.md000066400000000000000000000147721351236475300146300ustar00rootroot00000000000000QUICK GUIDE =========== On Linux distros, following commands will build and install uftrace from source. $ sudo misc/install-deps.sh # optional for advanced features $ ./configure # --prefix can be used to change install dir $ make $ sudo make install For more information, please see below. GETTING THE SOURCE ================== The latest version of uftrace is available at Github. https://github.com/namhyung/uftrace DEPENDENCY ========== The uftrace is written in C and tried to minimize external dependencies. Currently, uftrace can be built without any external libraries. But in order to use more advanced features, it'd be better to install them like below. Firstly, please make sure `pkg-config` is installed in the system to properly detect the dependencies of uftrace. Otherwise, some packages may not be detected even if they are already installed and it disables some features of uftrace. Historically uftrace depended on the `libelf` from elfutils project for ELF file manipulation. While it's not mandatory anymore, we recommend you to install it for better handling of ELF binaries. Also `libdw` library is recommended to be installed in order to process DWARF debug information. The libdw itself depends on the `libelf`, so you can just install `libdw`. On debian based systems (like Ubuntu), `libdw-dev` package will provide required libraries/files. $ sudo apt-get install libdw-dev On redhat based systems (like Fedora, RHEL), it'll be `elfutils-devel`. $ sudo dnf install elfutils-devel It also uses libstdc++ library to demangle C++ symbols in full detail. But it's not mandatory as uftrace has its own demangler for shorter symbol name (it omits arguments, templates and so on). And ncursesw library is to implement text user interface (TUI) on console. The ncurses(w) library provides terminal handling routines so `uftrace tui` command is built on top of them. As it improves user experience of trace data analysis, you need to consider install it if you do things like `uftrace graph` or `uftrace report` frequently. Also it needs `pandoc` to build man pages from the markdown document. BUILD ===== To build uftrace, you need to install basic software development tools first - like gcc and make. And also you need to install dependent softwares, please see DEPENDENCY section for details. Once you installed required software(s), you can run `make` to build it. $ make It builds uftrace and resulting binary exists in the current directory. This is good for testing, but you'll want to install it for normal use. $ sudo make install It installs the uftrace under /usr/local by default, if you want install it to other location, you can set the `prefix` variable when invoking the configure before running make. (see below). $ ./configure --prefix=/usr $ make $ sudo make install The output of build looks like linux kernel style, users can see original build command lines with V=1 (like kernel). $ make V=1 CONFIGURATION ============= The uftrace implements own version of configure script to save user preferences. The config file (named `.config`) is created if not exist on build time with default options. User can set custom installation directories or build directory with this script. $ ./configure --help Usage: ./configure [] --help print this message --prefix= set install root dir as (default: /usr/local) --bindir= set executable install dir as (default: ${prefix}/bin) --libdir= set library install dir as (default: ${prefix}/lib) --mandir= set manual doc install dir as (default: ${prefix}/share/man) --objdir= set build dir as (default: ${PWD}) --sysconfdir= override the etc dir as --with-elfutils= search for elfutils in /include and /lib --without-libelf build without libelf (and libdw) (even if found on the system) --without-libdw build without libdw (even if found on the system) --without-libstdc++ build without libstdc++ (even if found on the system) --without-libpython build without libpython2.7 (even if found on the system) --without-libncurses build without libncursesw (even if found on the system) --without-perf build without perf event (even if available) --without-schedule build without scheduler event (even if available) -p preserve old setting Some influential environment variables: ARCH Target architecture e.g. arm, aarch64, or x86_64 CROSS_COMPILE Specify the compiler prefix during compilation e.g. CC is overridden by $(CROSS_COMPILE)gcc CFLAGS C compiler flags LDFLAGS linker flags Also you can set the target architecture and compiler options like CC, CFLAGS. It's also possible to disable some features depending on external libraries or system behaviors. For example --without-libpython option will make scripting feature disabled - `uftrace script` command will still exist but won't work. For cross compile, you may want to setup the toolchain something like below: $ export CROSS_COMPILE=/path/to/cross/toolchain/arm-unknown-linux-gnueabihf- $ ./configure ARCH=arm CFLAGS='--sysroot /path/to/sysroot' This assumes you already installed the cross-built `libelf` on the sysroot directory. Otherwise, you can also build it from source (please see below) or use it on a different path using `--with-elfutils=`. BUILD WITH ELFUTILS (libelf) ============================ It may be useful to manually compile libelf/libdw for uftrace build if the target system doesn't have them installed. `misc/install-elfutils.sh` provides a way to download and build libelf and libdw, which are libraries in elfutils. The below is the way to compile uftrace together with libelf/libdw. $ export CROSS_COMPILE=arm-linux-gnueabi- $ export ARCH=arm $ export CFLAGS="-march=armv7-a" $ ./misc/install-elfutils.sh --prefix=/path/to/install $ ./configure --prefix=/path/to/install --with-elfutils=/path/to/install $ make $ make install `misc/install-elfutils.sh` downloads and builds elfutils and install both libelf and libdw to prefix directory. The installed libelf and libdw can be found using `--with-elfutils` in `configure` script. uftrace-0.9.3/Makefile000066400000000000000000000350021351236475300146250ustar00rootroot00000000000000VERSION := 0.9.3 # Makefiles suck: This macro sets a default value of $(2) for the # variable named by $(1), unless the variable has been set by # environment or command line. This is necessary for CC and AR # because make sets default values, so the simpler ?= approach # won't work as expected. define allow-override $(if $(or $(findstring environment,$(origin $(1))),\ $(findstring command line,$(origin $(1)))),,\ $(eval $(1) = $(2))) endef # Allow setting CC and AR and LD, or setting CROSS_COMPILE as a prefix. $(call allow-override,CC,$(CROSS_COMPILE)gcc) $(call allow-override,AR,$(CROSS_COMPILE)ar) $(call allow-override,LD,$(CROSS_COMPILE)ld) uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/arm.*/arm/ ) ifeq ($(ARCH),x86_64) ifneq ($(findstring m32,$(CFLAGS)),) override ARCH := i386 endif endif prefix ?= /usr/local bindir = $(prefix)/bin libdir = $(prefix)/lib etcdir = $(prefix)/etc mandir = $(prefix)/share/man srcdir = $(CURDIR) # set objdir to $(O) by default (if any) ifeq ($(objdir),) ifneq ($(O),) objdir = $(O) else objdir = $(CURDIR) endif endif ifneq ($(wildcard $(objdir)/.config),) include $(objdir)/.config endif RM = rm -f INSTALL = install export ARCH CC AR LD RM srcdir objdir LDFLAGS COMMON_CFLAGS := -D_GNU_SOURCE $(CFLAGS) $(CPPFLAGS) COMMON_CFLAGS += -iquote $(srcdir) -iquote $(objdir) -iquote $(srcdir)/arch/$(ARCH) #CFLAGS-DEBUG = -g -D_GNU_SOURCE $(CFLAGS_$@) COMMON_LDFLAGS := -lrt -ldl -pthread -Wl,-z,noexecstack $(LDFLAGS) ifneq ($(elfdir),) COMMON_CFLAGS += -I$(elfdir)/include COMMON_LDFLAGS += -L$(elfdir)/lib endif COMMON_CFLAGS += -W -Wall -Wno-unused-parameter -Wno-missing-field-initializers # # Note that the plain CFLAGS and LDFLAGS can be changed # by config/Makefile later but *_*FLAGS can not. # UFTRACE_CFLAGS = $(COMMON_CFLAGS) $(CFLAGS_$@) $(CFLAGS_uftrace) DEMANGLER_CFLAGS = $(COMMON_CFLAGS) $(CFLAGS_$@) $(CFLAGS_demangler) SYMBOLS_CFLAGS = $(COMMON_CFLAGS) $(CFLAGS_$@) $(CFLAGS_symbols) TRACEEVENT_CFLAGS = $(COMMON_CFLAGS) $(CFLAGS_$@) $(CFLAGS_traceevent) LIB_CFLAGS = $(COMMON_CFLAGS) $(CFLAGS_$@) $(CFLAGS_lib) LIB_CFLAGS += -fPIC -fvisibility=hidden -fno-omit-frame-pointer TEST_CFLAGS = $(COMMON_CFLAGS) -DUNIT_TEST UFTRACE_LDFLAGS = $(COMMON_LDFLAGS) $(LDFLAGS_$@) $(LDFLAGS_uftrace) DEMANGLER_LDFLAGS = $(COMMON_LDFLAGS) $(LDFLAGS_$@) $(LDFLAGS_demangler) SYMBOLS_LDFLAGS = $(COMMON_LDFLAGS) $(LDFLAGS_$@) $(LDFLAGS_symbols) LIB_LDFLAGS = $(COMMON_LDFLAGS) $(LDFLAGS_$@) $(LDFLAGS_lib) -Wl,--no-undefined TEST_LDFLAGS = $(COMMON_LDFLAGS) -L$(objdir)/libtraceevent -ltraceevent ifeq ($(DEBUG), 1) COMMON_CFLAGS += -O0 -g else COMMON_CFLAGS += -O2 -g endif ifeq ($(TRACE), 1) UFTRACE_CFLAGS += -pg -fno-omit-frame-pointer DEMANGLER_CFLAGS += -pg -fno-omit-frame-pointer SYMBOLS_CFLAGS += -pg -fno-omit-frame-pointer TRACEEVENT_CFLAGS += -pg -fno-omit-frame-pointer TEST_CFLAGS += -pg -fno-omit-frame-pointer # cannot add -pg to LIB_CFLAGS because mcount() is not reentrant endif ifeq ($(COVERAGE), 1) COMMON_CFLAGS += -O0 -g --coverage -U_FORTIFY_SOURCE LIB_CFLAGS += -O0 -g --coverage -U_FORTIFY_SOURCE TEST_CFLAGS += -O0 -g --coverage -U_FORTIFY_SOURCE LIB_LDFLAGS += --coverage endif ifeq ($(ASAN), 1) UFTRACE_CFLAGS += -O0 -g -fsanitize=address -fsanitize=leak DEMANGLER_CFLAGS += -O0 -g -fsanitize=address -fsanitize=leak SYMBOLS_CFLAGS += -O0 -g -fsanitize=address -fsanitize=leak TRACEEVENT_CFLAGS += -O0 -g -fsanitize=address -fsanitize=leak TEST_CFLAGS += -O0 -g -fsanitize=address -fsanitize=leak endif export UFTRACE_CFLAGS LIB_CFLAGS TEST_CFLAGS TEST_LDFLAGS VERSION_GIT := $(shell git describe --tags 2> /dev/null || echo v$(VERSION)) all: ifneq ($(wildcard $(srcdir)/check-deps/check-tstamp),) include $(srcdir)/check-deps/Makefile.check endif include $(srcdir)/Makefile.include LIBMCOUNT_TARGETS := libmcount/libmcount.so libmcount/libmcount-fast.so LIBMCOUNT_TARGETS += libmcount/libmcount-single.so libmcount/libmcount-fast-single.so _TARGETS := uftrace libtraceevent/libtraceevent.a _TARGETS += $(LIBMCOUNT_TARGETS) libmcount/libmcount-nop.so _TARGETS += misc/demangler misc/symbols TARGETS := $(patsubst %,$(objdir)/%,$(_TARGETS)) UFTRACE_SRCS := $(srcdir)/uftrace.c $(wildcard $(srcdir)/cmds/*.c $(srcdir)/utils/*.c) UFTRACE_OBJS := $(patsubst $(srcdir)/%.c,$(objdir)/%.o,$(UFTRACE_SRCS)) UFTRACE_OBJS_VERSION := $(objdir)/cmds/script.o $(objdir)/cmds/tui.o UFTRACE_OBJS_VERSION += $(objdir)/cmds/dump.o $(objdir)/cmds/info.o DEMANGLER_SRCS := $(srcdir)/misc/demangler.c $(srcdir)/utils/demangle.c DEMANGLER_SRCS += $(srcdir)/utils/debug.c $(srcdir)/utils/utils.c DEMANGLER_OBJS := $(patsubst $(srcdir)/%.c,$(objdir)/%.o,$(DEMANGLER_SRCS)) SYMBOLS_SRCS := $(srcdir)/misc/symbols.c $(srcdir)/utils/session.c SYMBOLS_SRCS += $(srcdir)/utils/demangle.c $(srcdir)/utils/rbtree.c SYMBOLS_SRCS += $(srcdir)/utils/utils.c $(srcdir)/utils/debug.c SYMBOLS_SRCS += $(srcdir)/utils/filter.c $(srcdir)/utils/dwarf.c SYMBOLS_SRCS += $(srcdir)/utils/auto-args.c $(srcdir)/utils/regs.c SYMBOLS_SRCS += $(wildcard $(srcdir)/utils/symbol*.c) SYMBOLS_OBJS := $(patsubst $(srcdir)/%.c,$(objdir)/%.o,$(SYMBOLS_SRCS)) UFTRACE_ARCH_OBJS := $(objdir)/arch/$(ARCH)/uftrace.o UFTRACE_HDRS := $(filter-out $(srcdir)/version.h,$(wildcard $(srcdir)/*.h $(srcdir)/utils/*.h)) UFTRACE_HDRS += $(srcdir)/libmcount/mcount.h $(wildcard $(srcdir)/arch/$(ARCH)/*.h) LIBMCOUNT_SRCS := $(filter-out %-nop.c,$(wildcard $(srcdir)/libmcount/*.c)) LIBMCOUNT_OBJS := $(patsubst $(srcdir)/%.c,$(objdir)/%.op,$(LIBMCOUNT_SRCS)) LIBMCOUNT_FAST_OBJS := $(patsubst $(objdir)/%.op,$(objdir)/%-fast.op,$(LIBMCOUNT_OBJS)) LIBMCOUNT_SINGLE_OBJS := $(patsubst $(objdir)/%.op,$(objdir)/%-single.op,$(LIBMCOUNT_OBJS)) LIBMCOUNT_FAST_SINGLE_OBJS := $(patsubst $(objdir)/%.op,$(objdir)/%-fast-single.op,$(LIBMCOUNT_OBJS)) LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/debug.c $(srcdir)/utils/regs.c LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/rbtree.c $(srcdir)/utils/filter.c LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/demangle.c $(srcdir)/utils/utils.c LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/script.c $(srcdir)/utils/script-python.c LIBMCOUNT_UTILS_SRCS += $(srcdir)/utils/auto-args.c $(srcdir)/utils/dwarf.c LIBMCOUNT_UTILS_SRCS += $(wildcard $(srcdir)/utils/symbol*.c) LIBMCOUNT_UTILS_OBJS := $(patsubst $(srcdir)/utils/%.c,$(objdir)/libmcount/%.op,$(LIBMCOUNT_UTILS_SRCS)) LIBMCOUNT_NOP_SRCS := $(srcdir)/libmcount/mcount-nop.c LIBMCOUNT_NOP_OBJS := $(patsubst $(srcdir)/%.c,$(objdir)/%.op,$(LIBMCOUNT_NOP_SRCS)) LIBMCOUNT_ARCH_OBJS := $(objdir)/arch/$(ARCH)/mcount-entry.op COMMON_DEPS := $(objdir)/.config $(UFTRACE_HDRS) LIBMCOUNT_DEPS := $(COMMON_DEPS) $(srcdir)/libmcount/internal.h CFLAGS_$(objdir)/mcount.op = -pthread CFLAGS_$(objdir)/cmds/record.o = -DINSTALL_LIB_PATH='"$(libdir)"' CFLAGS_$(objdir)/cmds/live.o = -DINSTALL_LIB_PATH='"$(libdir)"' LDFLAGS_$(objdir)/uftrace = -L$(objdir)/libtraceevent -ltraceevent -ldl LIBMCOUNT_FAST_CFLAGS := -DDISABLE_MCOUNT_FILTER LIBMCOUNT_SINGLE_CFLAGS := -DSINGLE_THREAD LIBMCOUNT_FAST_SINGLE_CFLAGS := -DDISABLE_MCOUNT_FILTER -DSINGLE_THREAD CFLAGS_$(objdir)/utils/demangle.o = -Wno-unused-value CFLAGS_$(objdir)/utils/demangle.op = -Wno-unused-value MAKEFLAGS += --no-print-directory all: $(objdir)/.config $(TARGETS) $(objdir)/.config: $(srcdir)/configure $(srcdir)/check-deps/Makefile $(QUIET_GEN)$(srcdir)/configure -p -o $@ $(MAKEOVERRIDES) @$(MAKE) -C $(objdir) # The above recursive make will handle all build procedure with # updated dependency. So just abort the current build. $(error) config: $(srcdir)/configure $(QUIET_GEN)$(srcdir)/configure -o $(objdir)/.config $(MAKEOVERRIDES) $(LIBMCOUNT_UTILS_OBJS): $(objdir)/libmcount/%.op: $(srcdir)/utils/%.c $(LIBMCOUNT_DEPS) $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(objdir)/libmcount/mcount.op: $(objdir)/version.h $(LIBMCOUNT_OBJS): $(objdir)/%.op: $(srcdir)/%.c $(LIBMCOUNT_DEPS) $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(LIBMCOUNT_FAST_OBJS): $(objdir)/%-fast.op: $(srcdir)/%.c $(LIBMCOUNT_DEPS) $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) $(LIBMCOUNT_FAST_CFLAGS) -c -o $@ $< $(LIBMCOUNT_SINGLE_OBJS): $(objdir)/%-single.op: $(srcdir)/%.c $(LIBMCOUNT_DEPS) $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) $(LIBMCOUNT_SINGLE_CFLAGS) -c -o $@ $< $(LIBMCOUNT_FAST_SINGLE_OBJS): $(objdir)/%-fast-single.op: $(srcdir)/%.c $(LIBMCOUNT_DEPS) $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) $(LIBMCOUNT_FAST_SINGLE_CFLAGS) -c -o $@ $< $(LIBMCOUNT_NOP_OBJS): $(objdir)/%.op: $(srcdir)/%.c $(LIBMCOUNT_DEPS) $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(objdir)/libmcount/libmcount.so: $(LIBMCOUNT_OBJS) $(LIBMCOUNT_UTILS_OBJS) $(LIBMCOUNT_ARCH_OBJS) $(QUIET_LINK)$(CC) -shared -o $@ $^ $(LIB_LDFLAGS) $(objdir)/libmcount/libmcount-fast.so: $(LIBMCOUNT_FAST_OBJS) $(LIBMCOUNT_UTILS_OBJS) $(LIBMCOUNT_ARCH_OBJS) $(QUIET_LINK)$(CC) -shared -o $@ $^ $(LIB_LDFLAGS) $(objdir)/libmcount/libmcount-single.so: $(LIBMCOUNT_SINGLE_OBJS) $(LIBMCOUNT_UTILS_OBJS) $(LIBMCOUNT_ARCH_OBJS) $(QUIET_LINK)$(CC) -shared -o $@ $^ $(LIB_LDFLAGS) $(objdir)/libmcount/libmcount-fast-single.so: $(LIBMCOUNT_FAST_SINGLE_OBJS) $(LIBMCOUNT_UTILS_OBJS) $(LIBMCOUNT_ARCH_OBJS) $(QUIET_LINK)$(CC) -shared -o $@ $^ $(LIB_LDFLAGS) $(objdir)/libmcount/libmcount-nop.so: $(LIBMCOUNT_NOP_OBJS) $(QUIET_LINK)$(CC) -shared -o $@ $^ $(LIB_LDFLAGS) $(LIBMCOUNT_ARCH_OBJS): $(wildcard $(srcdir)/arch/$(ARCH)/*.[cS]) $(LIBMCOUNT_DEPS) @$(MAKE) -B -C $(srcdir)/arch/$(ARCH) $@ $(UFTRACE_ARCH_OBJS): $(wildcard $(srcdir)/arch/$(ARCH)/*.[cS]) $(COMMON_DEPS) @$(MAKE) -B -C $(srcdir)/arch/$(ARCH) $@ $(objdir)/libtraceevent/libtraceevent.a: $(wildcard $(srcdir)/libtraceevent/*.[ch]) $(objdir)/.config @$(MAKE) -C $(srcdir)/libtraceevent BUILD_SRC=$(srcdir)/libtraceevent BUILD_OUTPUT=$(objdir)/libtraceevent CONFIG_FLAGS="$(TRACEEVENT_CFLAGS)" $(objdir)/uftrace.o: $(srcdir)/uftrace.c $(objdir)/version.h $(COMMON_DEPS) $(QUIET_CC)$(CC) $(UFTRACE_CFLAGS) -c -o $@ $< $(objdir)/misc/demangler.o: $(srcdir)/misc/demangler.c $(objdir)/version.h $(COMMON_DEPS) $(QUIET_CC)$(CC) $(DEMANGLER_CFLAGS) -c -o $@ $< $(objdir)/misc/symbols.o: $(srcdir)/misc/symbols.c $(objdir)/version.h $(COMMON_DEPS) $(QUIET_CC)$(CC) $(SYMBOLS_CFLAGS) -c -o $@ $< $(UFTRACE_OBJS_VERSION): $(objdir)/version.h $(filter-out $(objdir)/uftrace.o, $(UFTRACE_OBJS)): $(objdir)/%.o: $(srcdir)/%.c $(COMMON_DEPS) $(QUIET_CC)$(CC) $(UFTRACE_CFLAGS) -c -o $@ $< $(objdir)/version.h: PHONY @$(srcdir)/misc/version.sh $@ $(VERSION_GIT) $(srcdir) $(srcdir)/utils/auto-args.h: $(srcdir)/misc/prototypes.h $(srcdir)/misc/gen-autoargs.py $(QUIET_GEN)$(srcdir)/misc/gen-autoargs.py -i $< -o $@ $(objdir)/uftrace: $(UFTRACE_OBJS) $(UFTRACE_ARCH_OBJS) $(objdir)/libtraceevent/libtraceevent.a $(QUIET_LINK)$(CC) $(UFTRACE_CFLAGS) -o $@ $(UFTRACE_OBJS) $(UFTRACE_ARCH_OBJS) $(UFTRACE_LDFLAGS) $(objdir)/misc/demangler: $(DEMANGLER_OBJS) $(QUIET_LINK)$(CC) $(DEMANGLER_CFLAGS) -o $@ $(DEMANGLER_OBJS) $(DEMANGLER_LDFLAGS) $(objdir)/misc/symbols: $(SYMBOLS_OBJS) $(QUIET_LINK)$(CC) $(SYMBOLS_CFLAGS) -o $@ $(SYMBOLS_OBJS) $(SYMBOLS_LDFLAGS) install: all $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(bindir) $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(libdir) $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(etcdir)/bash_completion.d ifneq ($(wildcard $(elfdir)/lib/libelf.so),) ifeq ($(wildcard $(prefix)/lib/libelf.so),) # install libelf only when it's not in the install directory. $(call QUIET_INSTALL, libelf) $(Q)$(INSTALL) $(elfdir)/lib/libelf.so $(DESTDIR)$(libdir)/libelf.so endif endif $(call QUIET_INSTALL, uftrace) $(Q)$(INSTALL) $(objdir)/uftrace $(DESTDIR)$(bindir)/uftrace $(call QUIET_INSTALL, libmcount) $(Q)$(INSTALL) $(objdir)/libmcount/libmcount.so $(DESTDIR)$(libdir)/libmcount.so $(Q)$(INSTALL) $(objdir)/libmcount/libmcount-nop.so $(DESTDIR)$(libdir)/libmcount-nop.so $(Q)$(INSTALL) $(objdir)/libmcount/libmcount-fast.so $(DESTDIR)$(libdir)/libmcount-fast.so $(Q)$(INSTALL) $(objdir)/libmcount/libmcount-single.so $(DESTDIR)$(libdir)/libmcount-single.so $(Q)$(INSTALL) $(objdir)/libmcount/libmcount-fast-single.so $(DESTDIR)$(libdir)/libmcount-fast-single.so $(call QUIET_INSTALL, bash-completion) $(Q)$(INSTALL) -m 644 $(srcdir)/misc/bash-completion.sh $(DESTDIR)$(etcdir)/bash_completion.d/uftrace @$(MAKE) -sC $(srcdir)/doc install DESTDIR=$(DESTDIR)$(mandir) @if [ `id -u` = 0 ]; then ldconfig $(DESTDIR)$(libdir) || echo "ldconfig failed"; fi uninstall: $(call QUIET_UNINSTALL, uftrace) $(Q)$(RM) $(DESTDIR)$(bindir)/uftrace $(call QUIET_UNINSTALL, libmcount) $(Q)$(RM) $(DESTDIR)$(libdir)/libmcount.so $(call QUIET_UNINSTALL, libmcount-nop) $(Q)$(RM) $(DESTDIR)$(libdir)/libmcount-nop.so $(call QUIET_UNINSTALL, libmcount-fast) $(Q)$(RM) $(DESTDIR)$(libdir)/libmcount-fast.so $(call QUIET_UNINSTALL, libmcount-single) $(Q)$(RM) $(DESTDIR)$(libdir)/libmcount-single.so $(call QUIET_UNINSTALL, libmcount-fast-single) $(Q)$(RM) $(DESTDIR)$(libdir)/libmcount-fast-single.so $(call QUIET_UNINSTALL, bash-completion) $(Q)$(RM) $(DESTDIR)$(etcdir)/bash_completion.d/uftrace @$(MAKE) -sC $(srcdir)/doc uninstall DESTDIR=$(DESTDIR)$(mandir) test: all @$(MAKE) -C $(srcdir)/tests TESTARG="$(TESTARG)" test unittest: all @$(MAKE) -C $(srcdir)/tests TESTARG="$(TESTARG)" test_unit runtest: all @$(MAKE) -C $(srcdir)/tests TESTARG="$(TESTARG)" test_run dist: @git archive --prefix=uftrace-$(VERSION)/ $(VERSION_GIT) -o $(objdir)/uftrace-$(VERSION).tar @tar rf $(objdir)/uftrace-$(VERSION).tar --transform="s|^|uftrace-$(VERSION)/|" $(objdir)/version.h @gzip $(objdir)/uftrace-$(VERSION).tar doc: @$(MAKE) -C $(srcdir)/doc clean: $(call QUIET_CLEAN, uftrace) $(Q)$(RM) $(objdir)/*.o $(objdir)/*.op $(objdir)/*.so $(objdir)/*.a $(Q)$(RM) $(objdir)/cmds/*.o $(objdir)/utils/*.o $(objdir)/misc/*.o $(Q)$(RM) $(objdir)/utils/*.op $(objdir)/libmcount/*.op $(Q)$(RM) $(objdir)/gmon.out $(srcdir)/scripts/*.pyc $(TARGETS) $(Q)$(RM) $(objdir)/uftrace-*.tar.gz $(objdir)/version.h $(Q)find -name "*\.gcda" -o -name "*\.gcno" | xargs $(RM) $(Q)$(RM) coverage.info @$(MAKE) -sC $(srcdir)/arch/$(ARCH) clean @$(MAKE) -sC $(srcdir)/tests ARCH=$(ARCH) clean @$(MAKE) -sC $(srcdir)/doc clean @$(MAKE) -sC $(srcdir)/libtraceevent BUILD_SRC=$(srcdir)/libtraceevent BUILD_OUTPUT=$(objdir)/libtraceevent CONFIG_FLAGS="$(TRACEEVENT_CFLAGS)" clean reset-coverage: $(Q)find -name "*\.gcda" | xargs $(RM) $(Q)$(RM) coverage.info ctags: @find . -name "*\.[chS]" -o -path ./tests -prune -o -path ./check-deps -prune \ | xargs ctags --regex-asm='/^(GLOBAL|ENTRY|END)\(([^)]*)\).*/\2/' .PHONY: all config clean test dist doc ctags PHONY uftrace-0.9.3/Makefile.include000066400000000000000000000015071351236475300162520ustar00rootroot00000000000000#-*- mode: makefile -*- ifneq ($(findstring $(MAKEFLAGS),s),s) ifneq ($(V),1) QUIET_CC = @echo ' CC '$(patsubst $(objdir)/%,%,$@); QUIET_CC_FPIC = @echo ' CC FPIC '$(patsubst $(objdir)/%,%,$@); QUIET_AR = @echo ' AR '$(patsubst $(objdir)/%,%,$@); QUIET_ASM = @echo ' ASM '$(patsubst $(objdir)/%,%,$@); QUIET_LINK = @echo ' LINK '$(patsubst $(objdir)/%,%,$@); QUIET_MKDIR = @echo ' MKDIR '$(patsubst $(objdir)/%,%,$@); QUIET_GEN = @echo ' GEN '$(patsubst $(objdir)/%,%,$@); QUIET_FLEX = @echo ' FLEX '$@; QUIET_BISON = @echo ' BISON '$@; QUIET_TEST = @echo ' TEST '$@; QUIET_CLEAN = @printf ' CLEAN %s\n' $1; QUIET_INSTALL = @printf ' INSTALL %s\n' $1; QUIET_UNINSTALL= @printf ' REMOVE %s\n' $1; Q = @ endif endif uftrace-0.9.3/NEWS000066400000000000000000000210761351236475300136720ustar00rootroot00000000000000uftrace v0.9.3 -------------- * dynamic tracing update add (optional) dependency of capstone disassembly engine support tracing executables w/o instrumentation on x86_64 add -Z/--size-filter option not to select small functions * external event support support display user-defined events in uftrace.data/extern.dat it's a text file which has timestamp and message for each line * other changes allow tracing (system) binaries in the PATH add --srcline option to save debug info only if necessary apply --time-filter for analysis commands by default allow tracing execution of shell (interpreter) And many bug fixes and improvements. Thanks for all contributors: Daniel T. Lee, Hanbum Park, Honggyu Kim, Taeung Song uftrace v0.9.2 -------------- * trigger update add --signal option to support trigger by signal * TUI update add C/E key to collapse/expand all child nodes make R/r key to go to report window separately add z key to align screen to center * other changes display data symbols in argument/return value trace library calls even without PLT add -l short option for --nest-libcall rudimentary support for Rust programs And many bug fixes and improvements. Thanks for all contributors: Anas Balboul, Claudia J. Kang, Daniel T. Lee, Honggyu Kim uftrace v0.9.1 -------------- * filter update add --caller-filter option * script changes rename context in uftrace_begin: "args" -> "cmds" rename context in uftrace_begin: "recording" -> "record" * other changes add --watch option to trace cpu task is running add --graphviz option to produce output in DOT format filter 'do_syscall_64' kernel function by default And many bug fixes and improvements. Thanks for all contributors: Ahn Seung-rye, Claudia J. Kang, Daniel T. Lee, GwanYeong Kim, Hanbum Park, Honggyu Kim, Leah Neukirchen, Rikard Falkeborn uftrace v0.9 ============ * argument update automatic argument using DWARF debug info display enum constants properly add -a short option for --auto-args * TUI implementation graph, report and info commands using ncurses redraw graph for a selected function fold/unfold and search nodes in graph * build changes configure script shows status of dependencies add --without-XXX option to the configure script allow build without libelf * filter changes add --match option to select pattern matching method: regex or glob add --no-event option to disable default events apply recover trigger for every function automatically * other changes pass runtime info to script add -h short option for help message add --no-randomize-addr option to disable ASLR enable task scheduling events by default use gray color for comments and green for events add basic gdb (python) script to help debugging add misc/symbols tool to show symbol name from address And many bug fixes and improvements. Thanks for all contributors: GwanYeong Kim, Hanbum Park, Honggyu Kim, Taeguk Kwon, Taeung Song, Khem Raj uftrace v0.8.3 -------------- * i386 arch support (by Hanbum Park): support arguments and dynamic tracing * graph update (by Honggyu Kim): add -f/--output-fields option to control output share common code/behavior with replay command * event update: add task events (fork/comm/exit) using Linux perf subsystem enable task events always if supported * trigger change: change 'read' trigger action to read events twice (at entry and exit) support some pmu-related events using read trigger (with perf syscall) allow 'd' format specifier for default behavior with different size * other changes: add misc/demangler to test demangling easily add --libname option to show library names for PLT functions And many bug fixes and improvements. Thanks for all contributors: Hanbum Park, Honggyu Kim, Taeung Song uftrace v0.8.2 -------------- * trigger update add 'p' format for function pointer add --auto-args option for automatic argument/return value support enum type for auto-args * diff change add 'compact' policy and make it default old behavior is supported on 'full' policy * graph change show full graph when no function given support fork+exec properly * script change flush stdout buffer before fork serialize execution using a mutex And many bug fixes and improvements. Thanks for all contributors: Andrew Slough, Hansuk Hong, Hanbum Park, Honggyu Kim, JangSoJin, Myungjin Ko, MyungSik Ji, Sangwon Hong, Taeung Song, Vincent LE GARREC, Yujeong Kim uftrace v0.8.1 -------------- * trigger update apply filter/trigger to all libraries by default save symbol tables of all libraries -T/--trigger option supports filtering and argument/return value * other changes make --nest-libcall option imply --force option add --record option to script command replay show 's' suffix for std::string arguments allow reading data in current directory And many bug fixes and improvements. Thanks for all contributors: Honggyu Kim, Taeung Song uftrace v0.8 ============ * event tracing support: enable tracing events as well as functions. following events are supported using -E/--event option - SystemTap SDT (x86_64 only) - kernel tracepoint - scheduler (using perf syscall) list available events using --list-event option new read trigger also creates 'proc/statm' and 'page-fault' events * libcall tracing update: fix to trace already resolved functions too trace nested calls from other libraries using --nest-libcall option handle BIND-NOW + PIE properly * python scripting support: add new 'script' command with -S/--script option also support record-time scripting support additional filter for script execution allow to specify options for recording * report diff change: sort by (absolute) diff add --diff-policy option to control behavior add 'func' sort key change color setting * other changes: std::string argument display add elapsed time info "uftrace recv --run-cmd" can execute user-given command add "finish" trigger action to tracing add --opt-file option to allow reading options from file add --keep-pid option to preserve pid when running program And many bug fixes and improvements. Thanks for all contributors: Changhyeok Bae, Honggyu Kim, JeongBong Seo, SeongJae Park, Taeung Song, Paul Cannon uftrace v0.7 ============ * dynamic tracing support (x86_64 only) enable tracing for selected functions with -P option it needs some compiler support though - gcc with -mnop-mcount option - clang (X-ray) with -fxray-instrument option * AArch64 support add preliminary support for ARM v8 (64-bit) first integer argument is missing * kernel tracing change show recorded kernel functions by default partial support for event tracing fix to send/receive kernel data via network filter out sys_clock_gettime() for non-VDSO systems * dump change: show arguments and return values properly show more kernel tracing info fix file offset printing * build change: fix various problems on GCC 7 update configure script for better distro packaging And many bug fixes and improvements. Thanks for all contributors: Dridi Boukelmoune, Honggyu Kim, Taeung Song, Wonseok Ko uftrace v0.6.2 -------------- * dlopen() support: can show functions from dynamic loaded library using dlopen() * kernel tracing update: save kernel metadata so that it can be viewed from a different machine adjust tracer settings to reduce lost kernel data * filter change: remove '+' sign in elapsed time for --time-range option allow to use 'm' or 'min' to specify elapsed time And many bug fixes and improvements. Thanks for all contributors: Abder Benbachir, Geneviève Bastien, Honggyu Kim, Taeung Song, Wonseok Ko uftrace v0.6.1 -------------- * kernel option change: The -K option is same as --kernel-depth The --kernel-skip-out is deprecated and use The --kernel-full is to show kernel functions outside of user functions The --kernel-only option was added * replay change: add --output-fields option to customize the info on the left side currently time, delta, elapsed, duration, tid and addr fields are supported * filter change: apply time filter on replay add --time-range option to limit data analysis report, graph and dump honors same filter on replay add 'time' trigger to set a different threshold on specific functions * flame-graph support: "uftrace dump --flame-graph" creates a SVG file use --sample-time option to control sampling frequency in the output * build change: improve build process to facilitate distro packaging configure script checks dependency and shows warning uftrace v0.6 ============ * project open!uftrace-0.9.3/README.md000066400000000000000000000255051351236475300144530ustar00rootroot00000000000000[![Build Status](https://travis-ci.org/namhyung/uftrace.svg?branch=master)](https://travis-ci.org/namhyung/uftrace) [![Coverity scan](https://scan.coverity.com/projects/12421/badge.svg)](https://scan.coverity.com/projects/namhyung-uftrace) uftrace ======= The uftrace tool is to trace and analyze execution of a program written in C/C++. It was heavily inspired by the ftrace framework of the Linux kernel (especially function graph tracer) and supports userspace programs. It supports various kind of commands and filters to help analysis of the program execution and performance. ![uftrace-live-demo](doc/uftrace-live-demo.gif) * Homepage: https://github.com/namhyung/uftrace * Tutorial: https://github.com/namhyung/uftrace/wiki/Tutorial * Chat: https://gitter.im/uftrace/uftrace * Mailing list: [uftrace@googlegroups.com](https://groups.google.com/forum/#!forum/uftrace) Features ======== It traces each function in the executable and shows time duration. It can also trace external library calls - but usually entry and exit are supported. Optionally it's possible to trace other (nested) external library calls and/or internal function calls in the library call. It can show detailed execution flow at function level, and report which function has the highest overhead. And it also shows various information related the execution environment. You can setup filters to exclude or include specific functions when tracing. In addition, it can save and show function arguments and return value. It supports multi-process and/or multi-threaded applications. With root privilege, it can also trace kernel functions as well( with `-k` option) if the system enables the function graph tracer in the kernel (`CONFIG_FUNCTION_GRAPH_TRACER=y`). How to build and install uftrace ================================ On Linux distros, [misc/install-deps.sh](misc/install-deps.sh) installs required software(s) on your system. Those are for optional advanced features but highly recommend to install them together. $ sudo misc/install-deps.sh Once you installed required software(s) on your system, it can be built and installed like following: $ ./configure $ make $ sudo make install For more advanced setup, please refer [INSTALL.md](INSTALL.md) file. How to use uftrace ================== The uftrace command has following subcommands: * `record` : runs a program and saves the trace data * `replay` : shows program execution in the trace data * `report` : shows performance statistics in the trace data * `live` : does record and replay in a row (default) * `info` : shows system and program info in the trace data * `dump` : shows low-level trace data * `recv` : saves the trace data from network * `graph` : shows function call graph in the trace data * `script` : runs a script for recorded trace data * `tui` : show text user interface for graph and report You can use `-h`, `-?` or `--help` option to see available commands and options. $ uftrace Usage: uftrace [OPTION...] [record|replay|live|report|info|dump|recv|graph|script|tui] [] Try `uftrace --help' or `uftrace --usage' for more information. If omitted, it defaults to the `live` command which is almost same as running record and replay subcommand in a row (but does not record the trace info to files). For recording, the executable needs to be compiled with the `-pg` (or `-finstrument-functions`) option which generates profiling code (calling mcount or __cyg_profile_func_enter/exit) for each function. Note that, there's an experimental support for dynamic tracing on x86_64 which doesn't require such (re-)compilations. Also recent compilers have some options to help uftrace to reduce tracing overhead with similar way (although it still needs recompilation of your program). Please see [doc/uftrace-record.md](doc/uftrace-record.md) file. $ uftrace tests/t-abc # DURATION TID FUNCTION 16.134 us [ 1892] | __monstartup(); 223.736 us [ 1892] | __cxa_atexit(); [ 1892] | main() { [ 1892] | a() { [ 1892] | b() { [ 1892] | c() { 2.579 us [ 1892] | getpid(); 3.739 us [ 1892] | } /* c */ 4.376 us [ 1892] | } /* b */ 4.962 us [ 1892] | } /* a */ 5.769 us [ 1892] | } /* main */ For more analysis, you'd be better recording it first so that it can run analysis commands like replay, report, graph, dump and/or info multiple times. $ uftrace record tests/t-abc It'll create uftrace.data directory that contains trace data files. Other analysis commands expect the directory exists in the current directory, but one can use another using `-d` option. The `replay` command shows execution information like above. As you can see, the t-abc is a very simple program merely calls a, b and c functions. In the c function it called getpid() which is a library function implemented in the C library (glibc) on normal systems - the same goes to __cxa_atexit(). Users can use various filter options to limit functions it records/prints. The depth filter (`-D` option) is to omit functions under the given call depth. The time filter (`-t` option) is to omit functions running less than the given time. And the function filters (`-F` and `-N` options) are to show/hide functions under the given function. The `-k` option enables to trace kernel functions as well (needs root access). With the classic hello world program, the output would look like below (Note, I changed it to use fprintf() with stderr rather than the plain printf() to make it invoke system call directly): $ sudo uftrace -k tests/t-hello Hello world # DURATION TID FUNCTION 1.365 us [21901] | __monstartup(); 0.951 us [21901] | __cxa_atexit(); [21901] | main() { [21901] | fprintf() { 3.569 us [21901] | __do_page_fault(); 10.127 us [21901] | sys_write(); 20.103 us [21901] | } /* fprintf */ 21.286 us [21901] | } /* main */ You can see the page fault handler and the write syscall handler were called inside the fprintf() call. Also it can record and show function arguments and return value with `-A` and `-R` options respectively. The following example records first argument and return value of 'fib' (fibonacci number) function. $ uftrace record -A fib@arg1 -R fib@retval tests/t-fibonacci 5 $ uftrace replay # DURATION TID FUNCTION 2.853 us [22080] | __monstartup(); 2.194 us [22080] | __cxa_atexit(); [22080] | main() { 2.706 us [22080] | atoi(); [22080] | fib(5) { [22080] | fib(4) { [22080] | fib(3) { 7.473 us [22080] | fib(2) = 1; 0.419 us [22080] | fib(1) = 1; 11.452 us [22080] | } = 2; /* fib */ 0.460 us [22080] | fib(2) = 1; 13.823 us [22080] | } = 3; /* fib */ [22080] | fib(3) { 0.424 us [22080] | fib(2) = 1; 0.437 us [22080] | fib(1) = 1; 2.860 us [22080] | } = 2; /* fib */ 19.600 us [22080] | } = 5; /* fib */ 25.024 us [22080] | } /* main */ The `report` command lets you know which function spends the longest time including its children (total time). $ uftrace report Total time Self time Calls Function ========== ========== ========== ==================================== 25.024 us 2.718 us 1 main 19.600 us 19.600 us 9 fib 2.853 us 2.853 us 1 __monstartup 2.706 us 2.706 us 1 atoi 2.194 us 2.194 us 1 __cxa_atexit The `graph` command shows function call graph of given function. In the above example, function graph of function 'main' looks like below: $ uftrace graph main # Function Call Graph for 'main' (session: 073f1e84aa8b09d3) =============== BACKTRACE =============== backtrace #0: hit 1, time 25.024 us [0] main (0x40066b) ========== FUNCTION CALL GRAPH ========== 25.024 us : (1) main 2.706 us : +-(1) atoi : | 19.600 us : +-(1) fib 16.683 us : (2) fib 12.773 us : (4) fib 7.892 us : (2) fib The `dump` command shows raw output of each trace record. You can see the result in the chrome browser, once the data is processed with `uftrace dump --chrome`. Below is a trace of clang (LLVM) compiling a small C++ template metaprogram. [![uftrace-chrome-dump](doc/uftrace-chrome.png)](https://uftrace.github.io/dump/clang.tmp.fib.html) It also supports flame-graph output as well. The data can be processed with `uftrace dump --flame-graph` and passed to [flamegraph.pl](https://github.com/brendangregg/FlameGraph/blob/master/flamegraph.pl). Below is a flame graph result of gcc compiling a simple C program. [![uftrace-flame-graph-dump](https://uftrace.github.io/dump/gcc.svg)](https://uftrace.github.io/dump/gcc.svg) The `info` command shows system and program information when recorded. $ uftrace info # system information # ================== # program version : uftrace v0.8.1 # recorded on : Tue May 24 11:21:59 2016 # cmdline : uftrace record tests/t-abc # cpu info : Intel(R) Core(TM) i7-3930K CPU @ 3.20GHz # number of cpus : 12 / 12 (online / possible) # memory info : 20.1 / 23.5 GB (free / total) # system load : 0.00 / 0.06 / 0.06 (1 / 5 / 15 min) # kernel version : Linux 4.5.4-1-ARCH # hostname : sejong # distro : "Arch Linux" # # process information # =================== # number of tasks : 1 # task list : 5098 # exe image : /home/namhyung/project/uftrace/tests/t-abc # build id : a3c50d25f7dd98dab68e94ef0f215edb06e98434 # exit status : exited with code: 0 # elapsed time : 0.003219479 sec # cpu time : 0.000 / 0.003 sec (sys / user) # context switch : 1 / 1 (voluntary / involuntary) # max rss : 3072 KB # page fault : 0 / 172 (major / minor) # disk iops : 0 / 24 (read / write) The `script` command allows user to run a custom script on a data recorded. Currently python (version 2.7) is supported only. The `tui` command is for interactive text-based user interface using ncurses. It provides basic functionality of `graph`, `report` and `info` commands as of now. Limitations =========== - It can trace a native C/C++ application on Linux. - It *cannot* trace already running process. - It *cannot* be used for system-wide tracing. - It supports x86 (32 and 64 bit), ARM (v6 or later) and AArch64 for now. License ======= The uftrace program is released under GPL v2. See [COPYING file](COPYING) for details. uftrace-0.9.3/TODO000066400000000000000000000015201351236475300136530ustar00rootroot00000000000000- cleanup task management - more trigger action - trigger filtering (ignore, count, at return, ...) - improve documentation - report w/ multi-thread - config file support - filter by argument value - filter by source location - SDT argument support - LTT-ng event (tracepoint) support - reading/watching external data (global variable, cpu, ...) - show kernel function argument and return value (with dynamic events) - different clock support (TSC on x86, ...) - generic field support for report - field and sort support for TUI - filtering on TUI - replay on TUI - python 3 support - python function tracing - write useful script examples - dynamic tracing support - attach to existing process - process and display multiple data together - graph diff support - full demangling support - improve rust demangling - dynamic object naming (tagging?) uftrace-0.9.3/arch/000077500000000000000000000000001351236475300141025ustar00rootroot00000000000000uftrace-0.9.3/arch/aarch64/000077500000000000000000000000001351236475300153325ustar00rootroot00000000000000uftrace-0.9.3/arch/aarch64/Makefile000066400000000000000000000016371351236475300170010ustar00rootroot00000000000000sdir := $(srcdir)/arch/aarch64 odir := $(objdir)/arch/aarch64 LINKFLAGS := -r include $(srcdir)/Makefile.include ARCH_ENTRY_SRC = $(wildcard $(sdir)/*.S) ARCH_MCOUNT_SRC = $(wildcard $(sdir)/mcount-*.c) ARCH_UFTRACE_SRC = $(sdir)/cpuinfo.c ARCH_MCOUNT_OBJS = $(patsubst $(sdir)/%.S,$(odir)/%.op,$(ARCH_ENTRY_SRC)) ARCH_MCOUNT_OBJS += $(patsubst $(sdir)/%.c,$(odir)/%.op,$(ARCH_MCOUNT_SRC)) ARCH_UFTRACE_OBJS = $(patsubst $(sdir)/%.c,$(odir)/%.o,$(ARCH_UFTRACE_SRC)) all: $(odir)/entry.op $(odir)/mcount-entry.op: $(ARCH_MCOUNT_OBJS) $(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^ $(odir)/uftrace.o: $(ARCH_UFTRACE_OBJS) $(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^ $(odir)/%.op: $(sdir)/%.S $(QUIET_ASM)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(odir)/%.op: $(sdir)/%.c $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(odir)/%.o: $(sdir)/%.c $(QUIET_CC)$(CC) $(UFTRACE_CFLAGS) -c -o $@ $< clean: $(RM) $(odir)/*.op $(odir)/*.o uftrace-0.9.3/arch/aarch64/cpuinfo.c000066400000000000000000000006651351236475300171500ustar00rootroot00000000000000#include #include int arch_fill_cpuinfo_model(int fd) { char buf[1024]; FILE *fp; int ret = -1; fp = fopen("/proc/cpuinfo", "r"); if (fp == NULL) return -1; while (fgets(buf, sizeof(buf), fp) != NULL) { if (!strncmp(buf, "CPU architecture:", 17)) { int v = 8; sscanf(&buf[18], "%d", &v); dprintf(fd, "cpuinfo:desc=ARM64 (v%d)\n", v); ret = 0; break; } } fclose(fp); return ret; } uftrace-0.9.3/arch/aarch64/mcount-arch.h000066400000000000000000000012421351236475300177220ustar00rootroot00000000000000#ifndef MCOUNT_ARCH_H #define MCOUNT_ARCH_H #define mcount_regs mcount_regs struct mcount_regs { unsigned long x0; unsigned long x1; unsigned long x2; unsigned long x3; unsigned long x4; unsigned long x5; unsigned long x6; unsigned long x7; }; #define ARG1(a) ((a)->x0) #define ARG2(a) ((a)->x1) #define ARG3(a) ((a)->x2) #define ARG4(a) ((a)->x3) #define ARG5(a) ((a)->x4) #define ARG6(a) ((a)->x5) #define ARG7(a) ((a)->x6) #define ARG8(a) ((a)->x7) #define ARCH_MAX_REG_ARGS 8 #define ARCH_MAX_FLOAT_REGS 8 struct mcount_arch_context { }; #define ARCH_PLT0_SIZE 32 #define ARCH_PLTHOOK_ADDR_OFFSET 0 #endif /* MCOUNT_ARCH_H */ uftrace-0.9.3/arch/aarch64/mcount-support.c000066400000000000000000000104651351236475300205230ustar00rootroot00000000000000#include #include #include "libmcount/internal.h" #include "utils/utils.h" #include "utils/filter.h" /* FIXME: x0 is overwritten before calling _mcount() */ int mcount_get_register_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { struct mcount_regs *regs = ctx->regs; int reg_idx; switch (spec->type) { case ARG_TYPE_REG: reg_idx = spec->reg_idx; break; case ARG_TYPE_FLOAT: if (spec->size <= 4) reg_idx = spec->idx + UFT_AARCH64_REG_FLOAT_BASE; else reg_idx = spec->idx + UFT_AARCH64_REG_DOUBLE_BASE; break; case ARG_TYPE_INDEX: reg_idx = spec->idx; /* for integer arguments */ break; case ARG_TYPE_STACK: default: return -1; } switch (reg_idx) { case UFT_AARCH64_REG_X0: ctx->val.i = ARG1(regs); break; case UFT_AARCH64_REG_X1: ctx->val.i = ARG2(regs); break; case UFT_AARCH64_REG_X2: ctx->val.i = ARG3(regs); break; case UFT_AARCH64_REG_X3: ctx->val.i = ARG4(regs); break; case UFT_AARCH64_REG_X4: ctx->val.i = ARG5(regs); break; case UFT_AARCH64_REG_X5: ctx->val.i = ARG6(regs); break; case UFT_AARCH64_REG_X6: ctx->val.i = ARG7(regs); break; case UFT_AARCH64_REG_X7: ctx->val.i = ARG8(regs); break; case UFT_AARCH64_REG_S0: asm volatile ("str s0, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_S1: asm volatile ("str s1, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_S2: asm volatile ("str s2, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_S3: asm volatile ("str s3, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_S4: asm volatile ("str s4, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_S5: asm volatile ("str s5, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_S6: asm volatile ("str s6, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_S7: asm volatile ("str s7, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_D0: asm volatile ("str d0, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_D1: asm volatile ("str d1, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_D2: asm volatile ("str d2, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_D3: asm volatile ("str d3, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_D4: asm volatile ("str d4, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_D5: asm volatile ("str d5, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_D6: asm volatile ("str d6, %0\n" : "=m" (ctx->val.v)); break; case UFT_AARCH64_REG_D7: asm volatile ("str d7, %0\n" : "=m" (ctx->val.v)); break; default: return -1; } return 0; } void mcount_get_stack_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { int offset = 1; switch (spec->type) { case ARG_TYPE_STACK: offset = spec->stack_ofs; break; case ARG_TYPE_FLOAT: offset = spec->idx - ARCH_MAX_FLOAT_REGS; break; case ARG_TYPE_INDEX: offset = spec->idx - ARCH_MAX_REG_ARGS; break; case ARG_TYPE_REG: default: /* should not reach here */ pr_err_ns("invalid stack access for arguments\n"); break; } if (offset < 1 || offset > 100) pr_dbg("invalid stack offset: %d\n", offset); memcpy(ctx->val.v, ctx->stack_base + offset, spec->size); } void mcount_arch_get_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { /* don't support long double, treat it as double */ if (unlikely(spec->size == 10)) spec->size = 8; if (mcount_get_register_arg(ctx, spec) < 0) mcount_get_stack_arg(ctx, spec); } void mcount_arch_get_retval(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { /* don't support long double, treat it as double */ if (unlikely(spec->size == 10)) spec->size = 8; /* type of return value cannot be FLOAT, so check format instead */ if (spec->fmt == ARG_FMT_FLOAT) { long *float_retval = ctx->retval - 2; if (spec->size <= 4) { asm volatile ("ldr s0, %1\n" "str s0, %0\n" : "=m" (ctx->val.v) : "m" (float_retval)); } else { asm volatile ("ldr d0, %1\n" "str d0, %0\n" : "=m" (ctx->val.v) : "m" (float_retval)); } } else memcpy(ctx->val.v, ctx->retval, spec->size); } unsigned long mcount_arch_plthook_addr(struct plthook_data *pd, int idx) { struct sym *sym; sym = &pd->dsymtab.sym[0]; return sym->addr - ARCH_PLT0_SIZE; } uftrace-0.9.3/arch/aarch64/mcount.S000066400000000000000000000021241351236475300167620ustar00rootroot00000000000000#include "utils/asm.h" .text /* universal stack constraint: (SP mod 16) == 0 */ GLOBAL(_mcount) /* setup frame pointer */ stp x29, x30, [sp, #-16]! mov x29, sp /* save arguments */ stp x6, x7, [sp, #-16]! stp x4, x5, [sp, #-16]! stp x2, x3, [sp, #-16]! stp x0, x1, [sp, #-16]! ldr x0, [x29] add x0, x0, #8 mov x1, x30 mov x2, sp bl mcount_entry /* restore arguments */ ldp x0, x1, [sp], #16 ldp x2, x3, [sp], #16 ldp x4, x5, [sp], #16 ldp x6, x7, [sp], #16 /* restore frame pointer */ ldp x29, x30, [sp], #16 ret END(_mcount) ENTRY(mcount_return) /* setup frame pointer */ stp x29, x30, [sp, #-16]! /* save return values */ stp x0, x1, [sp, #-16]! stp d0, d1, [sp, #-16]! /* * save indirect result location register * used in C++ for returning non-trivial objects */ str x8, [sp, #-16]! add x0, sp, #32 bl mcount_exit mov x16, x0 /* restore indirect result location register */ ldr x8, [sp], #16 /* restore return values */ ldp d0, d1, [sp], #16 ldp x0, x1, [sp], #16 /* restore frame pointer */ ldp x29, x30, [sp], #16 br x16 END(mcount_return) uftrace-0.9.3/arch/aarch64/plthook.S000066400000000000000000000032521351236475300171400ustar00rootroot00000000000000/* * Based on glibc/ports/sysdeps/aarch64/dl-trampoline.S */ #include "utils/asm.h" .text .align 2 .macro save_args stp x6, x7, [sp, #-16]! stp x4, x5, [sp, #-16]! stp x2, x3, [sp, #-16]! stp x0, x1, [sp, #-16]! .endm .macro restore_args ldp x0, x1, [sp], #16 ldp x2, x3, [sp], #16 ldp x4, x5, [sp], #16 ldp x6, x7, [sp], #16 .endm ENTRY(plt_hooker) /* * it gets called with: * [sp, #8] : lr * [sp, #0] : &PLTGOT[n] * x16 (ip0): &PLTGOT[2] * x17 (ip1): address of dl resolver */ stp x16, x17, [sp, #-16]! save_args /* sp -= 64 */ add x0, sp, #88 ldr x1, [sp, #80] sub x1, x1, x16 lsr x1, x1, #3 sub x1, x1, #1 ldr x2, [x16, #-8] mov x3, sp bl plthook_entry cmp x0, #0 b.eq .L1 mov x16, x0 restore_args /* if we skip the resolver, it also needs to pop stacks */ add sp, sp, #32 /* restore original LR */ ldr x30, [sp, #-8] br x16 .L1: restore_args /* restore original stack layout */ add sp, sp, #16 adrp x17, plthook_resolver_addr ldr x17, [x17, #:lo12:plthook_resolver_addr] /* restore original contents */ ldr x16, [sp, #-16] ldr x30, [sp, #8] br x17 END(plt_hooker) ENTRY(plthook_return) /* setup frame pointer */ stp x29, x30, [sp, #-16]! /* save return values */ stp x0, x1, [sp, #-16]! stp d0, d1, [sp, #-16]! /* * save indirect result location register * used in C++ for returning non-trivial objects */ str x8, [sp, #-16]! add x0, sp, #32 bl plthook_exit mov x16, x0 /* restore indirect result location register */ ldr x8, [sp], #16 /* restore return values */ ldp d0, d1, [sp], #16 ldp x0, x1, [sp], #16 /* restore frame pointer */ ldp x29, x30, [sp], #16 br x16 END(plthook_return) uftrace-0.9.3/arch/arm/000077500000000000000000000000001351236475300146615ustar00rootroot00000000000000uftrace-0.9.3/arch/arm/Makefile000066400000000000000000000016271351236475300163270ustar00rootroot00000000000000sdir := $(srcdir)/arch/arm odir := $(objdir)/arch/arm LINKFLAGS := -r include $(srcdir)/Makefile.include ARCH_ENTRY_SRC = $(wildcard $(sdir)/*.S) ARCH_MCOUNT_SRC = $(wildcard $(sdir)/mcount-*.c) ARCH_UFTRACE_SRC = $(sdir)/cpuinfo.c ARCH_MCOUNT_OBJS = $(patsubst $(sdir)/%.S,$(odir)/%.op,$(ARCH_ENTRY_SRC)) ARCH_MCOUNT_OBJS += $(patsubst $(sdir)/%.c,$(odir)/%.op,$(ARCH_MCOUNT_SRC)) ARCH_UFTRACE_OBJS = $(patsubst $(sdir)/%.c,$(odir)/%.o,$(ARCH_UFTRACE_SRC)) all: $(odir)/entry.op $(odir)/mcount-entry.op: $(ARCH_MCOUNT_OBJS) $(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^ $(odir)/uftrace.o: $(ARCH_UFTRACE_OBJS) $(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^ $(odir)/%.op: $(sdir)/%.S $(QUIET_ASM)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(odir)/%.op: $(sdir)/%.c $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(odir)/%.o: $(sdir)/%.c $(QUIET_CC)$(CC) $(UFTRACE_CFLAGS) -c -o $@ $< clean: $(RM) $(odir)/*.op $(odir)/*.o uftrace-0.9.3/arch/arm/cpuinfo.c000066400000000000000000000010611351236475300164660ustar00rootroot00000000000000#include #include int arch_fill_cpuinfo_model(int fd) { char buf[1024]; FILE *fp; int ret = -1; fp = fopen("/proc/cpuinfo", "r"); if (fp == NULL) return -1; while (fgets(buf, sizeof(buf), fp) != NULL) { if (!strncmp(buf, "Processor\t:", 11)) { dprintf(fd, "cpuinfo:desc=%s", &buf[12]); ret = 0; break; } else if (!strncmp(buf, "model name\t:", 12)) { dprintf(fd, "cpuinfo:desc=%s", &buf[13]); ret = 0; break; } } if (ret < 0) dprintf(fd, "cpuinfo:desc=ARM (unknown)\n"); fclose(fp); return ret; } uftrace-0.9.3/arch/arm/mcount-arch.h000066400000000000000000000012671351236475300172600ustar00rootroot00000000000000#ifndef MCOUNT_ARCH_H #define MCOUNT_ARCH_H #define mcount_regs mcount_regs struct mcount_regs { unsigned long r0; unsigned long r1; unsigned long r2; unsigned long r3; }; #define ARG1(a) ((a)->r0) #define ARG2(a) ((a)->r1) #define ARG3(a) ((a)->r2) #define ARG4(a) ((a)->r3) #define ARCH_MAX_REG_ARGS 4 #define ARCH_MAX_FLOAT_REGS 16 #define ARCH_MAX_DOUBLE_REGS 8 struct mcount_arch_context { }; struct symtabs; #define FIX_PARENT_LOC unsigned long * mcount_arch_parent_location(struct symtabs *symtabs, unsigned long *parent_loc, unsigned long child_ip); #define ARCH_PLT0_SIZE 20 #define ARCH_PLTHOOK_ADDR_OFFSET 0 #endif /* MCOUNT_ARCH_H */ uftrace-0.9.3/arch/arm/mcount-support.c000066400000000000000000000272361351236475300200560ustar00rootroot00000000000000#include #include #include #include #ifndef EF_ARM_ABI_FLOAT_HARD # define EF_ARM_ABI_FLOAT_HARD EF_ARM_VFP_FLOAT #endif #include "libmcount/internal.h" #include "utils/utils.h" #include "utils/symbol.h" #include "utils/rbtree.h" #include "utils/filter.h" struct lr_offset { int offset; // 4-byte unit bool pushed; }; #define REG_SP 13 static struct rb_root offset_cache = RB_ROOT; /* whether current machine supports hardfp */ static bool use_hard_float = false; #ifdef HAVE_ARM_HARDFP /* need to check hardfp at runtime */ static bool float_abi_checked = false; #else /* disable hardfp as it's not supported */ static bool float_abi_checked = true; #endif struct offset_entry { struct rb_node node; unsigned long addr; unsigned long offset; }; static struct offset_entry *lookup_cache(struct rb_root *root, unsigned long addr, bool create) { struct rb_node *parent = NULL; struct rb_node **p = &root->rb_node; struct offset_entry *iter; while (*p) { parent = *p; iter = rb_entry(parent, struct offset_entry, node); if (iter->addr == addr) return iter; if (iter->addr > addr) p = &parent->rb_left; else p = &parent->rb_right; } if (!create) return NULL; iter = xmalloc(sizeof(*iter)); iter->addr = addr; rb_link_node(&iter->node, parent, p); rb_insert_color(&iter->node, root); return iter; } static unsigned rotate_right(unsigned val, unsigned bits, unsigned shift) { return (val >> shift) | (val << (bits - shift)); } /* * This function implements ThumbExpandImm() in ARM ARM A6.3.2 * "Modified immediate constants in Thumb instructions". */ static unsigned expand_thumb_imm(unsigned short opcode1, unsigned short opcode2) { unsigned imm_upper = ((opcode1 & 0x0400) >> 7) | ((opcode2 & 0x7000) >> 12); unsigned imm_lower = opcode2 & 0xff; unsigned imm; if ((imm_upper & 0xc) == 0) { switch (imm_upper & 0x3) { case 0: imm = imm_lower; break; case 1: imm = (imm_lower << 16) | imm_lower; break; case 2: imm = (imm_lower << 24) | (imm_lower << 8); break; case 3: imm = (imm_lower << 24) | (imm_lower << 16) | (imm_lower << 8) | imm_lower; break; } } else { unsigned shift = (imm_upper << 1) | (imm_lower >> 7); imm = rotate_right(imm_lower | 0x80, 32, shift); } pr_dbg3("imm: %u (%x/%x)\n", imm, imm_upper, imm_lower); return imm; } static int analyze_mcount_insn(unsigned short *insn, struct lr_offset *lr) { int bit_size = 16; unsigned short opcode = *insn; if (opcode >= 0xe800) bit_size = 32; if (opcode == 0xb500 && (((insn[1] & 0xf800) == 0xf000) && ((insn[2] & 0xc000) == 0xc000))) { /* PUSH $LR + BLX mcount */ if (lr->pushed) lr->offset++; else lr->offset = 0; /* tailcall (use LR directly) */ /* done! */ return 0; } else if ((opcode & 0xfe00) == 0xb400) { /* PUSH (reg mask) */ int i; if ((opcode & 0x100) || lr->pushed) { lr->pushed = true; for (i = 0; i < 8; i++) { if (opcode & (1 << i)) lr->offset++; } } } else if (opcode == 0xe92d) { /* PUSH (reg mask) : 32 bit insn */ int i; unsigned short opcode2 = insn[1]; if ((opcode2 & 0x4000) || lr->pushed) { lr->pushed = true; for (i = 0; i < 13; i++) { if (opcode2 & (1 << i)) lr->offset++; } } } else if ((opcode & 0xff80) == 0xb080) { /* SUB (SP - imm) */ if (lr->pushed) lr->offset += opcode & 0x7f; } else if ((opcode & 0xfbef) == 0xf1ad) { /* SUB (SP - imm) : 32 bit insn */ unsigned short opcode2 = insn[1]; int target = (opcode2 & 0xf00) >> 8; if (lr->pushed && target == REG_SP) { unsigned imm = expand_thumb_imm(opcode, opcode2); lr->offset += imm >> 2; } } else if ((opcode & 0xfbff) == 0xf2ad) { /* SUB (SP - imm) : 32 bit insn */ unsigned short opcode2 = insn[1]; int target = (opcode2 & 0xf00) >> 8; if (lr->pushed && target == REG_SP) { unsigned imm = opcode2 & 0xff; imm |= (opcode2 & 0x7000) >> 4; imm |= (opcode & 0x400) << 1; lr->offset += imm >> 2; } } else if ((opcode & 0xf800) == 0xa800) { /* ADD (SP + imm) */ int target = (opcode & 0x380) >> 7; if (lr->pushed && target == REG_SP) lr->offset -= opcode & 0xff; } else if ((opcode & 0xff80) == 0xb000) { /* ADD (SP + imm) */ if (lr->pushed) lr->offset -= opcode & 0x3f; } else if ((opcode & 0xfbef) == 0xf10d) { /* ADD (SP + imm) : 32 bit insn */ unsigned short opcode2 = insn[1]; int target = (opcode & 0xf00) >> 8; if (lr->pushed && target == REG_SP) { unsigned imm = expand_thumb_imm(opcode, opcode2); lr->offset -= imm >> 2; } } else if (opcode == 0xf84d) { /* STR [SP + imm]! */ unsigned short opcode2 = insn[1]; if (lr->pushed && (opcode2 & 0xfff) == 0xd04) lr->offset++; } else if ((opcode & 0xffbf) == 0xed2d) { /* VPUSH (VFP/NEON reg list) */ unsigned short opcode2 = insn[1]; unsigned imm = opcode2 & 0xff; if (lr->pushed) lr->offset += imm; } else { pr_err_ns("cannot analyze insn: %hx\n", opcode); } return bit_size == 16 ? 1 : 2; } #define MAX_ANALYSIS_COUNT 16 static void analyze_mcount_instructions(unsigned short *insn, struct lr_offset *lr) { int ret; int count = 0; do { ret = analyze_mcount_insn(insn, lr); insn += ret; } while (ret && count++ < MAX_ANALYSIS_COUNT); if (count > MAX_ANALYSIS_COUNT) { pr_dbg("stopping analysis on a long function prologue\n"); return; } pr_dbg2("%s: return address offset = %+d\n", __func__, lr->offset); } /* This code is only meaningful on THUMB2 mode: @loc = $sp + 4 */ unsigned long *mcount_arch_parent_location(struct symtabs *symtabs, unsigned long *parent_loc, unsigned long child_ip) { struct sym *sym; unsigned short buf[MAX_ANALYSIS_COUNT]; struct lr_offset lr = { .offset = 0, }; struct offset_entry *cache; sym = find_symtabs(symtabs, child_ip); if (sym == NULL) pr_err_ns("cannot find symbol for %lx\n", child_ip); // on ARM mode, return as is if ((sym->addr & 1) == 0) return parent_loc; cache = lookup_cache(&offset_cache, sym->addr, false); if (cache) return parent_loc + cache->offset; pr_dbg2("copying instructions of %s\n", sym->name); memcpy(buf, (void *)(long)(sym->addr & ~1), sizeof(buf)); analyze_mcount_instructions(buf, &lr); cache = lookup_cache(&offset_cache, sym->addr, true); cache->offset = lr.offset; return parent_loc + lr.offset; } int check_float_abi_cb(struct dl_phdr_info *info, size_t size, void *data) { unsigned i; for (i = 0; i < info->dlpi_phnum; i++) { const Elf32_Phdr *phdr = info->dlpi_phdr + i; if (phdr->p_type == PT_LOAD) { Elf32_Ehdr *ehdr = (void *)info->dlpi_addr + phdr->p_vaddr; use_hard_float = ehdr->e_flags & EF_ARM_ABI_FLOAT_HARD; break; } } float_abi_checked = true; return 1; } void check_float_abi(void) { dl_iterate_phdr(check_float_abi_cb, NULL); } int mcount_get_register_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { struct mcount_regs *regs = ctx->regs; int reg_idx; switch (spec->type) { case ARG_TYPE_REG: reg_idx = spec->reg_idx; break; case ARG_TYPE_FLOAT: if (use_hard_float) { if (spec->size <= 4) reg_idx = spec->idx + UFT_ARM_REG_FLOAT_BASE; else reg_idx = spec->idx + UFT_ARM_REG_DOUBLE_BASE; break; } /* fall through */ case ARG_TYPE_INDEX: reg_idx = spec->idx; /* for integer arguments */ if (spec->size == 8 && (reg_idx & 1) == 0) reg_idx++; break; case ARG_TYPE_STACK: default: return -1; } switch (reg_idx) { case UFT_ARM_REG_R0: ctx->val.i = ARG1(regs); if (spec->size == 8) ctx->val.ll.hi = ARG2(regs); break; case UFT_ARM_REG_R1: ctx->val.i = ARG2(regs); break; case UFT_ARM_REG_R2: ctx->val.i = ARG3(regs); if (spec->size == 8) ctx->val.ll.hi = ARG4(regs); break; case UFT_ARM_REG_R3: ctx->val.i = ARG4(regs); break; #ifdef HAVE_ARM_HARDFP case UFT_ARM_REG_S0: asm volatile ("vstr %%s0, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S1: asm volatile ("vstr %%s1, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S2: asm volatile ("vstr %%s2, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S3: asm volatile ("vstr %%s3, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S4: asm volatile ("vstr %%s4, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S5: asm volatile ("vstr %%s5, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S6: asm volatile ("vstr %%s6, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S7: asm volatile ("vstr %%s7, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S8: asm volatile ("vstr %%s8, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S9: asm volatile ("vstr %%s9, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S10: asm volatile ("vstr %%s10, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S11: asm volatile ("vstr %%s11, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S12: asm volatile ("vstr %%s12, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S13: asm volatile ("vstr %%s13, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S14: asm volatile ("vstr %%s14, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_S15: asm volatile ("vstr %%s15, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_D0: asm volatile ("vstr %%d0, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_D1: asm volatile ("vstr %%d1, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_D2: asm volatile ("vstr %%d2, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_D3: asm volatile ("vstr %%d3, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_D4: asm volatile ("vstr %%d4, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_D5: asm volatile ("vstr %%d5, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_D6: asm volatile ("vstr %%d6, %0\n" : "=m" (ctx->val.v)); break; case UFT_ARM_REG_D7: asm volatile ("vstr %%d7, %0\n" : "=m" (ctx->val.v)); break; #endif /* HAVE_ARM_HARDFP */ default: return -1; } return 0; } void mcount_get_stack_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { int offset = 1; switch (spec->type) { case ARG_TYPE_STACK: offset = spec->stack_ofs; break; case ARG_TYPE_FLOAT: if (use_hard_float) { if (spec->size <= 4) offset = spec->idx - ARCH_MAX_FLOAT_REGS; else offset = (spec->idx - ARCH_MAX_DOUBLE_REGS) * 2 - 1; break; } /* fall through */ case ARG_TYPE_INDEX: offset = spec->idx - ARCH_MAX_REG_ARGS; if (spec->size == 8 && (offset & 1) == 0) offset++; break; case ARG_TYPE_REG: default: /* should not reach here */ pr_err_ns("invalid stack access for arguments\n"); break; } if (offset < 1 || offset > 100) pr_dbg("invalid stack offset: %d\n", offset); memcpy(ctx->val.v, ctx->stack_base + offset, spec->size); } void mcount_arch_get_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { if (!float_abi_checked) check_float_abi(); /* don't support long double, treat it as double */ if (unlikely(spec->size == 10)) spec->size = 8; if (mcount_get_register_arg(ctx, spec) < 0) mcount_get_stack_arg(ctx, spec); } void mcount_arch_get_retval(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { if (!float_abi_checked) check_float_abi(); /* don't support long double, treat it as double */ if (unlikely(spec->size == 10)) spec->size = 8; /* type of return value cannot be FLOAT, so check format instead */ #ifdef HAVE_ARM_HARDFP if (spec->fmt == ARG_FMT_FLOAT && use_hard_float) { /* d0 register (64 bit) was saved below the r0 */ memcpy(ctx->val.v, ctx->retval - 2, spec->size); } else #endif /* HAVE_ARM_HARDFP */ memcpy(ctx->val.v, ctx->retval, spec->size); } unsigned long mcount_arch_plthook_addr(struct plthook_data *pd, int idx) { return pd->plt_addr; } uftrace-0.9.3/arch/arm/mcount.S000066400000000000000000000043261351236475300163170ustar00rootroot00000000000000/* Shamelessly copied from linux/arch/arm/kernel/entry-common.S */ /* * When compiling with -pg, gcc inserts a call to the mcount routine at the * start of every function. In mcount, apart from the function's address (in * lr), we need to get hold of the function's caller's address. * * Older GCCs (pre-4.4) inserted a call to a routine called mcount like this: * * bl mcount * * These versions have the limitation that in order for the mcount routine to * be able to determine the function's caller's address, an APCS-style frame * pointer (which is set up with something like the code below) is required. * * mov ip, sp * push {fp, ip, lr, pc} * sub fp, ip, #4 * * With EABI, these frame pointers are not available unless -mapcs-frame is * specified, and if building as Thumb-2, not even then. * * Newer GCCs (4.4+) solve this problem by introducing a new version of mcount, * with call sites like: * * push {lr} * bl __gnu_mcount_nc * * With these compilers, frame pointers are not necessary. * * mcount can be thought of as a function called in the middle of a subroutine * call. As such, it needs to be transparent for both the caller and the * callee: the original lr needs to be restored when leaving mcount, and no * registers should be clobbered. (In the __gnu_mcount_nc implementation, we * clobber the ip register. This is OK because the ARM calling convention * allows it to be clobbered in subroutines and doesn't use it to hold * parameters.) */ #include "utils/asm.h" .text .align 2 GLOBAL(__gnu_mcount_nc) push {r0-r3, lr} ands r3, lr, #1 /* check lr for ARM/THUMB detection */ add r0, sp, #20 /* r0 points to pushed LR */ bne 1f ldr r1, [fp] /* fp (=r11) might point to return address on ARM */ ldr r2, [r0] cmp r1, r2 moveq r0, fp 1: mov r1, lr /* child ip */ mov r2, sp /* mcount_args */ bl mcount_entry pop {r0-r3, ip, lr} bx ip END(__gnu_mcount_nc) ENTRY(mcount_return) push {r0-r3, lr, pc} /* ensure 8-byte alignment */ mov r0, sp #ifdef HAVE_ARM_HARDFP vpush {d0-d1} #endif bl mcount_exit #if HAVE_ARM_HARDFP vpop {d0-d1} #endif /* update return address (pc) in the stack */ str r0, [sp, #20] pop {r0-r3, lr, pc} END(mcount_return) uftrace-0.9.3/arch/arm/plthook.S000066400000000000000000000022341351236475300164660ustar00rootroot00000000000000/* * Based on glibc/ports/sysdeps/arm/dl-trampoline.S */ #include "utils/asm.h" .text .align 2 ENTRY(plt_hooker) @ we get called with @ stack[0] contains the return address from this call @ ip contains &GOT[n+3] (pointer to function) @ lr points to &GOT[2] push {r0-r3,ip,lr,pc} add r0, sp, #28 sub r2, ip, lr sub r2, r2, #4 lsr r1, r2, #2 ldr r2, [lr, #-4] mov r3, sp bl plthook_entry cmp r0, $0 beq 1f /* * if we skip the resolver, we also need to pop stack[0] * which saves the original 'lr'. */ str r0, [sp, #24] pop {r0-r3,ip,lr} add sp, sp, #8 ldr lr, [sp, #-4] ldr pc, [sp, #-8] /* return */ 1: ldr r2, .L2 .LPIC0: add r2, pc, r2 ldr r3, .L2+4 ldr r1, [r2, r3] ldr r2, [r1] str r2, [sp, #24] pop {r0-r3,ip,lr,pc} .L3: .align 2 .L2: .word _GLOBAL_OFFSET_TABLE_-(.LPIC0+8) .word plthook_resolver_addr(GOT) END(plt_hooker) ENTRY(plthook_return) push {r0-r3, lr, pc} /* ensure 8-byte alignment */ mov r0, sp #ifdef HAVE_ARM_HARDFP vpush {d0-d1} #endif bl plthook_exit #ifdef HAVE_ARM_HARDFP vpop {d0-d1} #endif /* update return address (pc) in the stack */ str r0, [sp, #20] pop {r0-r3, lr, pc} END(plthook_return) uftrace-0.9.3/arch/i386/000077500000000000000000000000001351236475300145735ustar00rootroot00000000000000uftrace-0.9.3/arch/i386/Makefile000066400000000000000000000016451351236475300162410ustar00rootroot00000000000000LINKFLAGS := -r -m elf_i386 sdir := $(srcdir)/arch/i386 odir := $(objdir)/arch/i386 include $(srcdir)/Makefile.include ARCH_ENTRY_SRC = $(wildcard $(sdir)/*.S) ARCH_MCOUNT_SRC = $(wildcard $(sdir)/mcount-*.c) ARCH_UFTRACE_SRC = $(sdir)/cpuinfo.c ARCH_MCOUNT_OBJS = $(patsubst $(sdir)/%.S,$(odir)/%.op,$(ARCH_ENTRY_SRC)) ARCH_MCOUNT_OBJS += $(patsubst $(sdir)/%.c,$(odir)/%.op,$(ARCH_MCOUNT_SRC)) ARCH_UFTRACE_OBJS = $(patsubst $(sdir)/%.c,$(odir)/%.o,$(ARCH_UFTRACE_SRC)) all: $(odir)/entry.op $(odir)/mcount-entry.op: $(ARCH_MCOUNT_OBJS) $(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^ $(odir)/uftrace.o: $(ARCH_UFTRACE_OBJS) $(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^ $(odir)/%.op: $(sdir)/%.S $(QUIET_ASM)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(odir)/%.op: $(sdir)/%.c $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(odir)/%.o: $(sdir)/%.c $(QUIET_CC)$(CC) $(UFTRACE_CFLAGS) -c -o $@ $< clean: $(RM) $(odir)/*.op $(odir)/*.o uftrace-0.9.3/arch/i386/common.S000066400000000000000000000001271351236475300162070ustar00rootroot00000000000000#include "utils/asm.h" ENTRY(get_pc_thunk) movl 0(%esp), %eax ret END(get_pc_thunk) uftrace-0.9.3/arch/i386/cpuinfo.c000066400000000000000000000005751351236475300164110ustar00rootroot00000000000000#include #include int arch_fill_cpuinfo_model(int fd) { char buf[1024]; FILE *fp; int ret = -1; fp = fopen("/proc/cpuinfo", "r"); if (fp == NULL) return -1; while (fgets(buf, sizeof(buf), fp) != NULL) { if (!strncmp(buf, "model name\t:", 12)) { dprintf(fd, "cpuinfo:desc=%s", &buf[13]); ret = 0; break; } } fclose(fp); return ret; } uftrace-0.9.3/arch/i386/fentry.S000066400000000000000000000015161351236475300162310ustar00rootroot00000000000000#include "utils/asm.h" GLOBAL(__fentry__) sub $32, %esp movl %edx, 28(%esp) movl %ecx, 24(%esp) movl %eax, 20(%esp) movl $0, 16(%esp) /* parent location */ leal 36(%esp), %eax movl %eax, 0(%esp) /* child addr */ movl 32(%esp), %eax movl %eax, 4(%esp) /* mcount_args */ leal 16(%esp), %eax movl %eax, 8(%esp) call mcount_entry cmpl $0, %eax jne 1f /* hijack return address */ call get_pc_thunk addl $_GLOBAL_OFFSET_TABLE_, %eax addl $fentry_return@GOTOFF, %eax movl %eax, 36(%esp) 1: movl 20(%esp), %eax movl 24(%esp), %ecx movl 28(%esp), %edx add $32, %esp ret END(__fentry__) ENTRY(fentry_return) sub $16, %esp movl %edx, 8(%esp) movl %eax, 4(%esp) leal 4(%esp), %eax movl %eax, 0(%esp) call mcount_exit movl %eax, 12(%esp) movl 4(%esp), %eax movl 8(%esp), %edx add $12, %esp ret END(fentry_return) uftrace-0.9.3/arch/i386/mcount-arch.h000066400000000000000000000013761351236475300171730ustar00rootroot00000000000000#include "../../utils/symbol.h" #ifndef __MCOUNT_ARCH_H__ #define __MCOUNT_ARCH_H__ #define mcount_regs mcount_regs struct mcount_regs { unsigned long stack1; unsigned long ecx; unsigned long edx; }; #define ARG1(a) ((a)->stack1) #define ARG_REG1(a) ((a)->ecx) #define ARG_REG2(a) ((a)->edx) #define ARCH_MAX_REG_ARGS 3 #define ARCH_MAX_FLOAT_REGS 8 #define HAVE_MCOUNT_ARCH_CONTEXT struct mcount_arch_context { double xmm[ARCH_MAX_FLOAT_REGS]; }; #define FIX_PARENT_LOC unsigned long * mcount_arch_parent_location(struct symtabs *symtabs, unsigned long *parent_loc, unsigned long child_ip); #define ARCH_PLT0_SIZE 16 #define ARCH_PLTHOOK_ADDR_OFFSET 6 #define ARCH_CAN_RESTORE_PLTHOOK 1 #endif /* __MCOUNT_ARCH_H__ */ uftrace-0.9.3/arch/i386/mcount-dynamic.c000066400000000000000000000061741351236475300176760ustar00rootroot00000000000000#include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "dynamic" #define PR_DOMAIN DBG_DYNAMIC #include "libmcount/internal.h" #include "utils/utils.h" #include "utils/symbol.h" #define PAGE_SIZE 4096 /* target instrumentation function it needs to call */ extern void __fentry__(void); int mcount_setup_trampoline(struct mcount_dynamic_info *mdi) { unsigned char trampoline[] = { 0xe8, 0x00, 0x00, 0x00, 0x00, 0x58, 0xff, 0x60, 0x04 }; unsigned long fentry_addr = (unsigned long)__fentry__; size_t trampoline_size = 16; void *trampoline_check; /* find unused 16-byte at the end of the code segment */ mdi->trampoline = ALIGN(mdi->text_addr + mdi->text_size, PAGE_SIZE) - trampoline_size; if (unlikely(mdi->trampoline < mdi->text_addr + mdi->text_size)) { mdi->trampoline += trampoline_size; mdi->text_size += PAGE_SIZE; pr_dbg2("adding a page for fentry trampoline at %#lx\n", mdi->trampoline); trampoline_check = mmap((void *)mdi->trampoline, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (trampoline_check == MAP_FAILED) pr_err("failed to mmap trampoline for setup"); } if (mprotect((void *)mdi->text_addr, mdi->text_size, PROT_READ | PROT_WRITE)) { pr_dbg("cannot setup trampoline due to protection: %m\n"); return -1; } /* jmpq *0x2(%rip) # */ memcpy((void *)mdi->trampoline, trampoline, sizeof(trampoline)); memcpy((void *)mdi->trampoline + sizeof(trampoline), &fentry_addr, sizeof(fentry_addr)); return 0; } void mcount_cleanup_trampoline(struct mcount_dynamic_info *mdi) { if (mprotect((void *)mdi->text_addr, mdi->text_size, PROT_EXEC)) pr_err("cannot restore trampoline due to protection"); } #define CALL_INSN_SIZE 5 static unsigned long get_target_addr(struct mcount_dynamic_info *mdi, unsigned long addr) { while (mdi) { if (mdi->text_addr <= addr && addr < mdi->text_addr + mdi->text_size) return mdi->trampoline - (addr + CALL_INSN_SIZE); mdi = mdi->next; } return 0; } static int patch_fentry_func(struct mcount_dynamic_info *mdi, struct sym *sym) { // In case of "gcc" which is not patched because of old version, // it may not create 5 byte nop. unsigned char nop[] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 }; unsigned char *insn = (unsigned char *)((uintptr_t)sym->addr); unsigned int target_addr; /* only support calls to __fentry__ at the beginning */ if (memcmp(insn, nop, sizeof(nop))) { pr_dbg2("skip non-applicable functions: %s\n", sym->name); return -2; } /* get the jump offset to the trampoline */ target_addr = get_target_addr(mdi, sym->addr); if (target_addr == 0) return -2; /* make a "call" insn with 4-byte offset */ insn[0] = 0xe8; /* hopefully we're not patching 'memcpy' itself */ memcpy(&insn[1], &target_addr, sizeof(target_addr)); pr_dbg3("update function '%s' dynamically to call __fentry__\n", sym->name); return 0; } int mcount_patch_func(struct mcount_dynamic_info *mdi, struct sym *sym, struct mcount_disasm_engine *disasm, unsigned min_size) { return patch_fentry_func(mdi, sym); } uftrace-0.9.3/arch/i386/mcount-support.c000066400000000000000000000157111351236475300177630ustar00rootroot00000000000000/* * basic i386 support for uftrace * * Copyright (C) 2017. Hanbum Park * * Released under the GPL v2. */ #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "mcount" #define PR_DOMAIN DBG_MCOUNT // a max number that retrieves the stack to find the location of // the real return address of the main function for i386. #define MAX_SEARCH_STACK 5 #include "libmcount/internal.h" #include "utils/filter.h" static bool search_main_ret = false; int mcount_get_register_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { struct mcount_regs *regs = ctx->regs; int reg_idx; switch (spec->type) { case ARG_TYPE_REG: reg_idx = spec->reg_idx; break; default: return -1; } switch (reg_idx) { case UFT_I386_REG_ECX: ctx->val.i = ARG_REG1(regs); break; case UFT_I386_REG_EDX: ctx->val.i = ARG_REG2(regs); break; case UFT_I386_REG_XMM0: asm volatile ("movsd %%xmm0, %0\n" : "=m" (ctx->val.v)); break; case UFT_I386_REG_XMM1: asm volatile ("movsd %%xmm1, %0\n" : "=m" (ctx->val.v)); break; case UFT_I386_REG_XMM2: asm volatile ("movsd %%xmm2, %0\n" : "=m" (ctx->val.v)); break; case UFT_I386_REG_XMM3: asm volatile ("movsd %%xmm3, %0\n" : "=m" (ctx->val.v)); break; case UFT_I386_REG_XMM4: asm volatile ("movsd %%xmm4, %0\n" : "=m" (ctx->val.v)); break; case UFT_I386_REG_XMM5: asm volatile ("movsd %%xmm5, %0\n" : "=m" (ctx->val.v)); break; case UFT_I386_REG_XMM6: asm volatile ("movsd %%xmm6, %0\n" : "=m" (ctx->val.v)); break; case UFT_I386_REG_XMM7: asm volatile ("movsd %%xmm7, %0\n" : "=m" (ctx->val.v)); break; default: /* should not reach here */ pr_err_ns("invalid register access for arguments\n"); break; } return 0; } void mcount_get_stack_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { int offset; switch (spec->type) { case ARG_TYPE_STACK: offset = spec->stack_ofs; break; case ARG_TYPE_INDEX: offset = spec->idx; break; case ARG_TYPE_FLOAT: offset = spec->idx; break; default: /* should not reach here */ pr_err_ns("invalid stack access for arguments\n"); break; } if (offset < 1 || offset > 100) pr_dbg("invalid stack offset: %d\n", offset); memcpy(ctx->val.v, ctx->stack_base + offset, spec->size); } void mcount_arch_get_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { if (mcount_get_register_arg(ctx, spec) < 0) mcount_get_stack_arg(ctx, spec); } void mcount_arch_get_retval(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { /* type of return value cannot be FLOAT, so check format instead */ if (spec->fmt != ARG_FMT_FLOAT) memcpy(ctx->val.v, ctx->retval, spec->size); else if (spec->size == 4) asm volatile ("fstps %0\n\tflds %0" : "=m" (ctx->val.v)); else if (spec->size == 8) asm volatile ("fstpl %0\n\tfldl %0" : "=m" (ctx->val.v)); else if (spec->size == 10) asm volatile ("fstpt %0\n\tfldt %0" : "=m" (ctx->val.v)); } void mcount_save_arch_context(struct mcount_arch_context *ctx) { asm volatile ("movsd %%xmm0, %0\n" : "=m" (ctx->xmm[0])); asm volatile ("movsd %%xmm1, %0\n" : "=m" (ctx->xmm[1])); asm volatile ("movsd %%xmm2, %0\n" : "=m" (ctx->xmm[2])); asm volatile ("movsd %%xmm3, %0\n" : "=m" (ctx->xmm[3])); asm volatile ("movsd %%xmm4, %0\n" : "=m" (ctx->xmm[4])); asm volatile ("movsd %%xmm5, %0\n" : "=m" (ctx->xmm[5])); asm volatile ("movsd %%xmm6, %0\n" : "=m" (ctx->xmm[6])); asm volatile ("movsd %%xmm7, %0\n" : "=m" (ctx->xmm[7])); } void mcount_restore_arch_context(struct mcount_arch_context *ctx) { asm volatile ("movsd %0, %%xmm0\n" :: "m" (ctx->xmm[0])); asm volatile ("movsd %0, %%xmm1\n" :: "m" (ctx->xmm[1])); asm volatile ("movsd %0, %%xmm2\n" :: "m" (ctx->xmm[2])); asm volatile ("movsd %0, %%xmm3\n" :: "m" (ctx->xmm[3])); asm volatile ("movsd %0, %%xmm4\n" :: "m" (ctx->xmm[4])); asm volatile ("movsd %0, %%xmm5\n" :: "m" (ctx->xmm[5])); asm volatile ("movsd %0, %%xmm6\n" :: "m" (ctx->xmm[6])); asm volatile ("movsd %0, %%xmm7\n" :: "m" (ctx->xmm[7])); } /* For 16-byte stack-alignment, the main function stores the return address in its stack scope at prologue. When the time comes for the main function to return, 1. restore the saved return address from stack. 2. After cleaning up the stack. 3. Put the return address at the top of the stack and return. 4. will be returned. 080485f8
: 80485f8: 8d 4c 24 04 lea 0x4(%esp),%ecx 80485fc: 83 e4 f0 and $0xfffffff0,%esp 80485ff: ff 71 fc pushl -0x4(%ecx) 8048602: 55 push %ebp 8048603: 89 e5 mov %esp,%ebp 8048605: 51 push %ecx 8048606: 83 ec 14 sub $0x14,%esp 8048609: e8 02 fe ff ff call 8048410 ... ... 8048645: 8b 4d fc mov -0x4(%ebp),%ecx 8048648: c9 leave 8048649: 8d 61 fc lea -0x4(%ecx),%esp 804864c: c3 ret So, in this case. The return address we want to replace with mcount_exit is in the stack scope of the main function. Non a parent located. we search stack for that address. we will look for it. we will find it, and we will replace it. GOOD LUCK! */ unsigned long *mcount_arch_parent_location(struct symtabs *symtabs, unsigned long *parent_loc, unsigned long child_ip) { if (!search_main_ret) { struct sym *parent_sym, *child_sym; char *parent_name, *child_name; const char *find_main[] = { "__libc_start_main", "main" }; unsigned long ret_addr; unsigned long search_ret_addr; ret_addr = *parent_loc; parent_sym = find_symtabs(symtabs, ret_addr); parent_name = symbol_getname(parent_sym, ret_addr); child_sym = find_symtabs(symtabs, child_ip); child_name = symbol_getname(child_sym, child_ip); // Assuming that this happens only in main.. bool found_main_ret = false; int stack_index = 0; if (!(strcmp(find_main[0], parent_name) || strcmp(find_main[1], child_name))) { ret_addr = *parent_loc; for (stack_index = 1; stack_index < MAX_SEARCH_STACK; stack_index++) { search_ret_addr = *(unsigned long *)(parent_loc + stack_index); if (search_ret_addr == ret_addr) { parent_loc = parent_loc + stack_index; found_main_ret = true; } } // if we couldn't found correct position of return address, // maybe this approach is not available anymore. if (!found_main_ret) { pr_dbg2("cannot find ret address of main\n"); } search_main_ret = true; } } return parent_loc; } // in i386, the idx value is set to a multiple of 8 unlike other. unsigned long mcount_arch_child_idx(unsigned long child_idx) { if (child_idx > 0) { if (child_idx % 8) { pr_err_ns("the malformed child idx : %lx\n", child_idx); } child_idx = child_idx / 8; } return child_idx; } uftrace-0.9.3/arch/i386/mcount.S000066400000000000000000000017031351236475300162250ustar00rootroot00000000000000/* in i386, generally used stack for argument passing. */ /* use register for return : %eax */ /* no need save registers */ /* stack frame (with -pg): parent addr = 4(%ebp) */ /* child addr = (%esp) */ #include "utils/asm.h" GLOBAL(mcount) sub $32, %esp /* save registers */ movl %edx, 28(%esp) movl %ecx, 24(%esp) movl %eax, 20(%esp) movl $0, 16(%esp) /* parent location */ leal 4(%ebp), %eax movl %eax, 0(%esp) /* child addr */ movl 32(%esp), %eax movl %eax, 4(%esp) /* mcount_regs */ leal 16(%esp), %eax movl %eax, 8(%esp) call mcount_entry /* restore registers */ movl 20(%esp), %eax movl 24(%esp), %ecx movl 28(%esp), %edx add $32, %esp ret END(mcount) ENTRY(mcount_return) sub $16, %esp movl %edx, 8(%esp) movl %eax, 4(%esp) leal 4(%esp), %eax movl %eax, 0(%esp) /* returns original parent address */ call mcount_exit movl %eax, 12(%esp) movl 4(%esp), %eax movl 8(%esp), %edx add $12, %esp ret END(mcount_return) uftrace-0.9.3/arch/i386/plthook.S000066400000000000000000000021041351236475300163740ustar00rootroot00000000000000#include "utils/asm.h" .hidden plthook_resolver_addr ENTRY(plt_hooker) sub $32, %esp /* save registers */ movl %edx, 24(%esp) movl %ecx, 20(%esp) /* this is for ARG1 that using in jmp */ movl 44(%esp), %eax movl %eax, 16(%esp) /* stack address contain parent location */ leal 40(%esp), %eax movl %eax, 0(%esp) /* child_idx */ movl 36(%esp), %eax movl %eax, 4(%esp) /* module_id */ movl 32(%esp), %eax movl %eax, 8(%esp) /* mcount_args */ leal 16(%esp), %eax movl %eax, 12(%esp) call plthook_entry /* restore registers */ movl 20(%esp), %ecx movl 24(%esp), %edx add $32, %esp cmpl $0, %eax jnz 1f /* get address of plthook_resolver_addr */ call get_pc_thunk addl $_GLOBAL_OFFSET_TABLE_, %eax leal plthook_resolver_addr@GOTOFF(%eax), %eax movl (%eax), %eax jmp *%eax 1: add $8, %esp jmp *%eax END(plt_hooker) ENTRY(plthook_return) sub $16, %esp movl %edx, 8(%esp) movl %eax, 4(%esp) leal 4(%esp), %eax movl %eax, 0(%esp) call plthook_exit movl %eax, 12(%esp) movl 4(%esp), %eax movl 8(%esp), %edx add $12, %esp ret END(plthook_return) uftrace-0.9.3/arch/x86_64/000077500000000000000000000000001351236475300150405ustar00rootroot00000000000000uftrace-0.9.3/arch/x86_64/Makefile000066400000000000000000000016771351236475300165130ustar00rootroot00000000000000LINKFLAGS := -r sdir := $(srcdir)/arch/x86_64 odir := $(objdir)/arch/x86_64 include $(srcdir)/Makefile.include ARCH_ENTRY_SRC = $(wildcard $(sdir)/*.S) ARCH_MCOUNT_SRC = $(wildcard $(sdir)/mcount-*.c) $(sdir)/symbol.c ARCH_UFTRACE_SRC = $(sdir)/cpuinfo.c $(sdir)/symbol.c ARCH_MCOUNT_OBJS = $(patsubst $(sdir)/%.S,$(odir)/%.op,$(ARCH_ENTRY_SRC)) ARCH_MCOUNT_OBJS += $(patsubst $(sdir)/%.c,$(odir)/%.op,$(ARCH_MCOUNT_SRC)) ARCH_UFTRACE_OBJS = $(patsubst $(sdir)/%.c,$(odir)/%.o,$(ARCH_UFTRACE_SRC)) all: $(odir)/entry.op $(odir)/mcount-entry.op: $(ARCH_MCOUNT_OBJS) $(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^ $(odir)/uftrace.o: $(ARCH_UFTRACE_OBJS) $(QUIET_LINK)$(LD) $(LINKFLAGS) -o $@ $^ $(odir)/%.op: $(sdir)/%.S $(QUIET_ASM)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(odir)/%.op: $(sdir)/%.c $(QUIET_CC_FPIC)$(CC) $(LIB_CFLAGS) -c -o $@ $< $(odir)/%.o: $(sdir)/%.c $(QUIET_CC)$(CC) $(UFTRACE_CFLAGS) -c -o $@ $< clean: $(RM) $(odir)/*.op $(odir)/*.o uftrace-0.9.3/arch/x86_64/cpuinfo.c000066400000000000000000000005751351236475300166560ustar00rootroot00000000000000#include #include int arch_fill_cpuinfo_model(int fd) { char buf[1024]; FILE *fp; int ret = -1; fp = fopen("/proc/cpuinfo", "r"); if (fp == NULL) return -1; while (fgets(buf, sizeof(buf), fp) != NULL) { if (!strncmp(buf, "model name\t:", 12)) { dprintf(fd, "cpuinfo:desc=%s", &buf[13]); ret = 0; break; } } fclose(fp); return ret; } uftrace-0.9.3/arch/x86_64/dynamic.S000066400000000000000000000074371351236475300166230ustar00rootroot00000000000000/* * argument passing: %rdi, %rsi, %rdx, %rcx, %r8, %r9 * * if %rax have value bigger than 0, it means return address * to the function have patched for dynamic tracing. * otherwise, it must be 0 that means error occured. * stack frame : parent addr = 8(%rsp), child addr = (%rsp) * * For example: * * Parent(caller): main() * Child(callee): Hello() * * Dump of assembler code for function main: * 0x00000000004005b6 <+0>: callq *0x20043c(%rip) # 0x6009f8 * 0x00000000004005bc <+6>: nop * 0x00000000004005bd <+7>: nop * 0x00000000004005be <+8>: nop * 0x00000000004005bf <+9>: mov $0x400678,%edi * 0x00000000004005c4 <+14>: callq 0x4004a0 * 0x00000000004005c9 <+19>: mov $0x0,%eax * 0x00000000004005ce <+24>: callq 0x400597 * parent => 0x00000000004005d3 <+29>: mov $0x0,%eax * 0x00000000004005d8 <+34>: pop %rbp * 0x00000000004005d9 <+35>: retq * * Dump of assembler code for function Hello: * 0x0000000000400597 <+0>: callq *0x20045b(%rip) # 0x6009f8 * child => 0x000000000040059d <+6>: nop * 0x000000000040059e <+7>: nop * 0x000000000040059f <+8>: movq $0x400668,-0x8(%rbp) * 0x00000000004005a7 <+16>: mov -0x8(%rbp),%rax * 0x00000000004005ab <+20>: mov %rax,%rdi * 0x00000000004005ae <+23>: callq 0x400480 * 0x00000000004005b3 <+28>: nop * 0x00000000004005b4 <+29>: leaveq * 0x00000000004005b5 <+30>: retq * */ #include "utils/asm.h" GLOBAL(__dentry__) .cfi_startproc sub $48, %rsp .cfi_adjust_cfa_offset 48 movq %rdi, 40(%rsp) movq %rsi, 32(%rsp) movq %rdx, 24(%rsp) movq %rcx, 16(%rsp) movq %r8, 8(%rsp) movq %r9, 0(%rsp) /* child addr */ movq 48(%rsp), %rsi /* parent location */ lea 56(%rsp), %rdi /* mcount_args */ movq %rsp, %rdx .cfi_def_cfa_register rdx /* align stack pointer to 16-byte */ andq $0xfffffffffffffff0, %rsp push %rdx /* save rax (implicit argument for variadic functions) */ push %rax /* save scratch registers due to -fipa-ra */ push %r10 push %r11 call mcount_entry /* original stack pointer */ movq 24(%rsp), %rdx /* child addr */ movq 48(%rdx), %rdi /* find location that has the original code */ call mcount_find_code /* original stack pointer */ movq 24(%rsp), %rdx /* overwrite return address */ movq %rax, 48(%rdx) pop %r11 pop %r10 pop %rax movq %rdx, %rsp /* restore mcount_args */ movq 0(%rsp), %r9 movq 8(%rsp), %r8 movq 16(%rsp), %rcx movq 24(%rsp), %rdx movq 32(%rsp), %rsi movq 40(%rsp), %rdi add $48, %rsp .cfi_adjust_cfa_offset -48 retq .cfi_endproc END(__dentry__) ENTRY(dynamic_return) .cfi_startproc sub $96, %rsp .cfi_def_cfa_offset 96 /* save all caller-saved registers due to -fipa-ra */ movq %r11, 80(%rsp) movq %r10, 72(%rsp) movq %r9, 64(%rsp) movq %r8, 56(%rsp) movq %rdi, 48(%rsp) movq %rsi, 40(%rsp) movq %rcx , 32(%rsp) /* below are used to carry return value */ movdqu %xmm0, 16(%rsp) movq %rdx, 8(%rsp) movq %rax, 0(%rsp) /* set the first argument of mcount_exit as pointer to return values */ movq %rsp, %rdi /* returns original parent address */ call mcount_exit movq %rax, 88(%rsp) movq 0(%rsp), %rax movq 8(%rsp), %rdx movq 16(%rsp), %xmm0 movq 32(%rsp), %rcx movq 40(%rsp), %rsi movq 48(%rsp), %rdi movq 56(%rsp), %r8 movq 64(%rsp), %r9 movq 72(%rsp), %r10 movq 80(%rsp), %r11 add $88, %rsp .cfi_def_cfa_offset 8 retq .cfi_endproc END(dynamic_return) uftrace-0.9.3/arch/x86_64/fentry.S000066400000000000000000000037041351236475300164770ustar00rootroot00000000000000/* argument passing: %rdi, %rsi, %rdx, %rcx, %r8, %r9 */ /* return value: %rax */ /* callee saved: %rbx, %rbp, %rsp, %r12-r15 */ /* stack frame (with -pg -mfentry): parent addr = 8(%rsp), child addr = (%rsp) */ /* * For example: Parent(caller): main() Child(callee): hello() Dump of assembler code for function main: 0x00000000004006bc <+0>: callq 0x400550 <__fentry__@plt> 0x00000000004006c1 <+5>: push %rbp 0x00000000004006c2 <+6>: mov %rsp,%rbp 0x00000000004006c5 <+9>: mov $0x0,%eax 0x00000000004006ca <+14>: callq 0x4006a6 parent addr => 0x00000000004006cf <+19>: nop 0x00000000004006d0 <+20>: pop %rbp 0x00000000004006d1 <+21>: retq Dump of assembler code for function hello: 0x00000000004006a6 <+0>: callq 0x400550 <__fentry__@plt> child addr => 0x00000000004006ab <+5>: push %rbp 0x00000000004006ac <+6>: mov %rsp,%rbp */ #include "utils/asm.h" GLOBAL(__fentry__) .cfi_startproc sub $48, %rsp .cfi_adjust_cfa_offset 48 /* save register arguments in mcount_args */ movq %rdi, 40(%rsp) movq %rsi, 32(%rsp) movq %rdx, 24(%rsp) movq %rcx, 16(%rsp) movq %r8, 8(%rsp) movq %r9, 0(%rsp) /* child addr */ movq 48(%rsp), %rsi /* parent location */ lea 56(%rsp), %rdi /* mcount_args */ movq %rsp, %rdx .cfi_def_cfa_register rdx /* align stack pointer to 16-byte */ andq $0xfffffffffffffff0, %rsp push %rdx /* save rax (implicit argument for variadic functions) */ push %rax call mcount_entry pop %rax /* restore original stack pointer */ pop %rdx movq %rdx, %rsp .cfi_def_cfa_register rsp /* restore mcount_args */ movq 0(%rsp), %r9 movq 8(%rsp), %r8 movq 16(%rsp), %rcx movq 24(%rsp), %rdx movq 32(%rsp), %rsi movq 40(%rsp), %rdi add $48, %rsp .cfi_adjust_cfa_offset -48 retq .cfi_endproc END(__fentry__) uftrace-0.9.3/arch/x86_64/mcount-arch.h000066400000000000000000000024261351236475300174350ustar00rootroot00000000000000#ifndef MCOUNT_ARCH_H #define MCOUNT_ARCH_H #include "utils/arch.h" #include "utils/list.h" #define mcount_regs mcount_regs struct mcount_regs { unsigned long r9; unsigned long r8; unsigned long rcx; unsigned long rdx; unsigned long rsi; unsigned long rdi; }; #define ARG1(a) ((a)->rdi) #define ARG2(a) ((a)->rsi) #define ARG3(a) ((a)->rdx) #define ARG4(a) ((a)->rcx) #define ARG5(a) ((a)->r8) #define ARG6(a) ((a)->r9) #define ARCH_MAX_REG_ARGS 6 #define ARCH_MAX_FLOAT_REGS 8 #define HAVE_MCOUNT_ARCH_CONTEXT struct mcount_arch_context { double xmm[ARCH_MAX_FLOAT_REGS]; }; #define ARCH_PLT0_SIZE 16 #define ARCH_PLTHOOK_ADDR_OFFSET 6 #define ARCH_SUPPORT_AUTO_RECOVER 1 #define ARCH_CAN_RESTORE_PLTHOOK 1 struct plthook_arch_context { bool has_plt_sec; }; struct mcount_disasm_engine; struct mcount_dynamic_info; struct sym; int disasm_check_insns(struct mcount_disasm_engine *disasm, struct mcount_dynamic_info *mdi, struct sym *sym); struct dynamic_bad_symbol { struct list_head list; struct sym *sym; }; struct dynamic_bad_symbol * find_bad_jump(struct mcount_dynamic_info *mdi, unsigned long addr); bool add_bad_jump(struct mcount_dynamic_info *mdi, unsigned long callsite, unsigned long target); #endif /* MCOUNT_ARCH_H */ uftrace-0.9.3/arch/x86_64/mcount-dynamic.c000066400000000000000000000370571351236475300201470ustar00rootroot00000000000000#include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "dynamic" #define PR_DOMAIN DBG_DYNAMIC #include "mcount-arch.h" #include "libmcount/internal.h" #include "utils/utils.h" #include "utils/symbol.h" #define PAGE_SIZE 4096 #define XRAY_SECT "xray_instr_map" #define CALL_INSN_SIZE 5 #define JMP_INSN_SIZE 6 /* target instrumentation function it needs to call */ extern void __fentry__(void); extern void __dentry__(void); extern void __xray_entry(void); extern void __xray_exit(void); struct xray_instr_map { unsigned long addr; unsigned long entry; unsigned long type; unsigned long count; }; enum mcount_x86_dynamic_type { DYNAMIC_NONE, DYNAMIC_FENTRY, DYNAMIC_XRAY, }; struct arch_dynamic_info { enum mcount_x86_dynamic_type type; struct xray_instr_map *xrmap; unsigned xrmap_count; struct list_head bad_targets; /* for non-local jumps */ }; int mcount_setup_trampoline(struct mcount_dynamic_info *mdi) { unsigned char trampoline[] = { 0xff, 0x25, 0x02, 0x00, 0x00, 0x00, 0xcc, 0xcc }; unsigned long fentry_addr = (unsigned long)__fentry__; unsigned long xray_entry_addr = (unsigned long)__xray_entry; unsigned long xray_exit_addr = (unsigned long)__xray_exit; struct arch_dynamic_info *adi = mdi->arch; size_t trampoline_size = 16; void *trampoline_check; if (adi->type == DYNAMIC_XRAY) trampoline_size *= 2; /* find unused 16-byte at the end of the code segment */ mdi->trampoline = ALIGN(mdi->text_addr + mdi->text_size, PAGE_SIZE); mdi->trampoline -= trampoline_size; if (unlikely(mdi->trampoline < mdi->text_addr + mdi->text_size)) { mdi->trampoline += trampoline_size; mdi->text_size += PAGE_SIZE; pr_dbg2("adding a page for fentry trampoline at %#lx\n", mdi->trampoline); trampoline_check = mmap((void *)mdi->trampoline, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (trampoline_check == MAP_FAILED) pr_err("failed to mmap trampoline for setup"); } if (mprotect((void *)mdi->text_addr, mdi->text_size, PROT_READ | PROT_WRITE | PROT_EXEC)) { pr_dbg("cannot setup trampoline due to protection: %m\n"); return -1; } if (adi->type == DYNAMIC_XRAY) { /* jmpq *0x2(%rip) # */ memcpy((void *)mdi->trampoline, trampoline, sizeof(trampoline)); memcpy((void *)mdi->trampoline + sizeof(trampoline), &xray_entry_addr, sizeof(xray_entry_addr)); /* jmpq *0x2(%rip) # */ memcpy((void *)mdi->trampoline + 16, trampoline, sizeof(trampoline)); memcpy((void *)mdi->trampoline + 16 + sizeof(trampoline), &xray_exit_addr, sizeof(xray_exit_addr)); } else if (adi->type == DYNAMIC_FENTRY) { /* jmpq *0x2(%rip) # */ memcpy((void *)mdi->trampoline, trampoline, sizeof(trampoline)); memcpy((void *)mdi->trampoline + sizeof(trampoline), &fentry_addr, sizeof(fentry_addr)); } else if (adi->type == DYNAMIC_NONE) { #ifdef HAVE_LIBCAPSTONE unsigned long dentry_addr = (unsigned long)__dentry__; /* jmpq *0x2(%rip) # */ memcpy((void *)mdi->trampoline, trampoline, sizeof(trampoline)); memcpy((void *)mdi->trampoline + sizeof(trampoline), &dentry_addr, sizeof(dentry_addr)); #endif } return 0; } void mcount_cleanup_trampoline(struct mcount_dynamic_info *mdi) { if (mprotect((void *)mdi->text_addr, mdi->text_size, PROT_EXEC)) pr_err("cannot restore trampoline due to protection"); } static void read_xray_map(struct arch_dynamic_info *adi, struct uftrace_elf_data *elf, struct uftrace_elf_iter *iter, unsigned long offset) { typeof(iter->shdr) *shdr = &iter->shdr; adi->xrmap_count = shdr->sh_size / sizeof(*adi->xrmap); adi->xrmap = xmalloc(adi->xrmap_count * sizeof(*adi->xrmap)); elf_get_secdata(elf, iter); elf_read_secdata(elf, iter, 0, adi->xrmap, shdr->sh_size); /* handle position independent code */ if (elf->ehdr.e_type == ET_DYN) { struct xray_instr_map *xrmap; unsigned i; for (i = 0; i < adi->xrmap_count; i++) { xrmap = &adi->xrmap[i]; xrmap->addr += offset; xrmap->entry += offset; } } } void mcount_arch_find_module(struct mcount_dynamic_info *mdi, struct symtab *symtab) { struct uftrace_elf_data elf; struct uftrace_elf_iter iter; struct arch_dynamic_info *adi; const char *adi_type_names[] = { "none", "fentry", "xray" }; unsigned char fentry_patt1[] = { 0x67, 0x0f, 0x1f, 0x04, 0x00 }; unsigned char fentry_patt2[] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 }; int num_check = 5; unsigned i = 0; adi = xzalloc(sizeof(*adi)); /* DYNAMIC_NONE */ INIT_LIST_HEAD(&adi->bad_targets); if (elf_init(mdi->map->libname, &elf) < 0) goto out; elf_for_each_shdr(&elf, &iter) { char *shstr = elf_get_name(&elf, &iter, iter.shdr.sh_name); if (!strcmp(shstr, XRAY_SECT)) { adi->type = DYNAMIC_XRAY; read_xray_map(adi, &elf, &iter, mdi->base_addr); goto out; } } /* check first few functions have fentry signature */ for (i = 0; i < symtab->nr_sym; i++) { struct sym *sym = &symtab->sym[i]; void *code_addr = (void *)sym->addr + mdi->map->start; if (sym->type != ST_LOCAL_FUNC && sym->type != ST_GLOBAL_FUNC) continue; /* dont' check special functions */ if (sym->name[0] == '_') continue; /* only support calls to __fentry__ at the beginning */ if (!memcmp(code_addr, fentry_patt1, CALL_INSN_SIZE) || !memcmp(code_addr, fentry_patt2, CALL_INSN_SIZE)) { adi->type = DYNAMIC_FENTRY; break; } if (num_check-- == 0) break; } out: pr_dbg("dynamic patch type: %d (%s)\n", adi->type, adi_type_names[adi->type]); mdi->arch = adi; elf_finish(&elf); } static unsigned long get_target_addr(struct mcount_dynamic_info *mdi, unsigned long addr) { return mdi->trampoline - (addr + CALL_INSN_SIZE); } static int patch_fentry_func(struct mcount_dynamic_info *mdi, struct sym *sym) { unsigned char nop1[] = { 0x67, 0x0f, 0x1f, 0x04, 0x00 }; unsigned char nop2[] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 }; unsigned char *insn = (void *)sym->addr + mdi->map->start; unsigned int target_addr; /* only support calls to __fentry__ at the beginning */ if (memcmp(insn, nop1, sizeof(nop1)) && /* old pattern */ memcmp(insn, nop2, sizeof(nop2))) { /* new pattern */ pr_dbg("skip non-applicable functions: %s\n", sym->name); return INSTRUMENT_FAILED; } /* get the jump offset to the trampoline */ target_addr = get_target_addr(mdi, (unsigned long)insn); if (target_addr == 0) return INSTRUMENT_SKIPPED; /* make a "call" insn with 4-byte offset */ insn[0] = 0xe8; /* hopefully we're not patching 'memcpy' itself */ memcpy(&insn[1], &target_addr, sizeof(target_addr)); pr_dbg3("update function '%s' dynamically to call __fentry__\n", sym->name); return INSTRUMENT_SUCCESS; } static int update_xray_code(struct mcount_dynamic_info *mdi, struct sym *sym, struct xray_instr_map *xrmap) { unsigned char entry_insn[] = { 0xeb, 0x09 }; unsigned char exit_insn[] = { 0xc3, 0x2e }; unsigned char pad[] = { 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00 }; unsigned char nop6[] = { 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 }; unsigned char nop4[] = { 0x0f, 0x1f, 0x40, 0x00 }; unsigned int target_addr; unsigned char *func = (void *)xrmap->addr; union { unsigned long word; char bytes[8]; } patch; if (memcmp(func + 2, pad, sizeof(pad))) return INSTRUMENT_FAILED; if (xrmap->type == 0) { /* ENTRY */ if (memcmp(func, entry_insn, sizeof(entry_insn))) return INSTRUMENT_FAILED; target_addr = mdi->trampoline - (xrmap->addr + 5); memcpy(func + 5, nop6, sizeof(nop6)); /* need to write patch_word atomically */ patch.bytes[0] = 0xe8; /* "call" insn */ memcpy(&patch.bytes[1], &target_addr, sizeof(target_addr)); memcpy(&patch.bytes[5], nop6, 3); memcpy(func, patch.bytes, sizeof(patch)); } else { /* EXIT */ if (memcmp(func, exit_insn, sizeof(exit_insn))) return INSTRUMENT_FAILED; target_addr = mdi->trampoline + 16 - (xrmap->addr + 5); memcpy(func + 5, nop4, sizeof(nop4)); /* need to write patch_word atomically */ patch.bytes[0] = 0xe9; /* "jmp" insn */ memcpy(&patch.bytes[1], &target_addr, sizeof(target_addr)); memcpy(&patch.bytes[5], nop4, 3); memcpy(func, patch.bytes, sizeof(patch)); } pr_dbg3("update function '%s' dynamically to call xray functions\n", sym->name); return INSTRUMENT_SUCCESS; } static int patch_xray_func(struct mcount_dynamic_info *mdi, struct sym *sym) { unsigned i; int ret = -2; struct arch_dynamic_info *adi = mdi->arch; struct xray_instr_map *xrmap; uint64_t sym_addr = sym->addr + mdi->map->start; /* xray provides a pair of entry and exit (or more) */ for (i = 0; i < adi->xrmap_count; i++) { xrmap = &adi->xrmap[i]; if (xrmap->addr < sym_addr || xrmap->addr >= sym_addr + sym->size) continue; while ((ret = update_xray_code(mdi, sym, xrmap)) == 0) { if (i == adi->xrmap_count - 1) break; i++; if (xrmap->entry != xrmap[1].entry) break; xrmap++; } break; } return ret; } /* * we overwrite instructions over 5bytes from start of function * to call '__dentry__' that seems similar like '__fentry__'. * * while overwriting, After adding the generated instruction which * returns to the address of the original instruction end, * save it in the heap. * * for example: * * 4005f0: 31 ed xor %ebp,%ebp * 4005f2: 49 89 d1 mov %rdx,%r9 * 4005f5: 5e pop %rsi * * will changed like this : * * 4005f0 call qword ptr [rip + 0x200a0a] # 0x601000 * * and keeping original instruction : * * Original Instructions--------------- * f1cff0: xor ebp, ebp * f1cff2: mov r9, rdx * f1cff5: pop rsi * Generated Instruction to return----- * f1cff6: jmp qword ptr [rip] * f1cffc: QW 0x00000000004005f6 * * In the original case, address 0x601000 has a dynamic symbol * start address. It is also the first element in the GOT array. * while initializing the mcount library, we will replace it with * the address of the function '__dentry__'. so, the changed * instruction will be calling '__dentry__'. * * '__dentry__' has a similar function like '__fentry__'. * the other thing is that it returns to original instructions * we keeping. it makes it possible to execute the original * instructions and return to the address at the end of the original * instructions. Thus, the execution will goes on. * */ /* * Patch the instruction to the address as given for arguments. */ static void patch_code(struct mcount_dynamic_info *mdi, uintptr_t addr, uint32_t origin_code_size) { void *origin_code_addr; unsigned char call_insn[] = { 0xe8, 0x00, 0x00, 0x00, 0x00 }; uint32_t target_addr = get_target_addr(mdi, addr); /* patch address */ origin_code_addr = (void *)addr; /* build the instrumentation instruction */ memcpy(&call_insn[1], &target_addr, CALL_INSN_SIZE - 1); /* * we need 5-bytes at least to instrumentation. however, * if instructions is not fit 5-bytes, we will overwrite the * 5-bytes and fill the remaining part of the last * instruction with nop. * * [example] * In this example, we overwrite 9-bytes to use 5-bytes. * * dynamic: 0x19e98b0[01]:push rbp * dynamic: 0x19e98b1[03]:mov rbp, rsp * dynamic: 0x19e98b4[05]:mov edi, 0x4005f4 * * dynamic: 0x40054c[05]:call 0x400ff0 * dynamic: 0x400551[01]:nop * dynamic: 0x400552[01]:nop * dynamic: 0x400553[01]:nop * dynamic: 0x400554[01]:nop */ memcpy(origin_code_addr, call_insn, CALL_INSN_SIZE); memset(origin_code_addr + CALL_INSN_SIZE, 0x90, /* NOP */ origin_code_size - CALL_INSN_SIZE); /* flush icache so that cpu can execute the new insn */ __builtin___clear_cache(origin_code_addr, origin_code_addr + origin_code_size); } struct dynamic_bad_symbol * find_bad_jump(struct mcount_dynamic_info *mdi, unsigned long addr) { struct sym *sym; struct arch_dynamic_info *adi = mdi->arch; struct dynamic_bad_symbol *badsym; sym = find_sym(&mdi->map->mod->symtab, addr - mdi->map->start); if (sym == NULL) return NULL; list_for_each_entry(badsym, &adi->bad_targets, list) { if (badsym->sym == sym) return badsym; } return NULL; } bool add_bad_jump(struct mcount_dynamic_info *mdi, unsigned long callsite, unsigned long target) { struct sym *sym; struct arch_dynamic_info *adi = mdi->arch; struct dynamic_bad_symbol *badsym; if (find_bad_jump(mdi, target)) return true; sym = find_sym(&mdi->map->mod->symtab, target - mdi->map->start); if (sym == NULL) return true; /* only care about jumps to the middle of a function */ if (sym->addr + mdi->map->start == target) return false; pr_dbg2("bad jump: %s:%lx to %lx\n", sym ? sym->name : "", callsite - mdi->map->start, target - mdi->map->start); badsym = xmalloc(sizeof(*badsym)); badsym->sym = sym; list_add_tail(&badsym->list, &adi->bad_targets); return true; } static int patch_normal_func(struct mcount_dynamic_info *mdi, struct sym *sym, struct mcount_disasm_engine *disasm) { int instr_size; uint8_t jmp_insn[14] = { 0xff, 0x25, }; uint64_t jmp_target; struct mcount_orig_insn *orig; uint64_t sym_addr = sym->addr + mdi->map->start; instr_size = disasm_check_insns(disasm, mdi, sym); if (instr_size < CALL_INSN_SIZE) return instr_size; pr_dbg2("patch normal func: %s (patch size: %d)\n", sym->name, instr_size); /* * stored origin instruction block: * ---------------------- * | [origin_code_size] | * ---------------------- * | [jmpq *0x0(rip) | * ---------------------- * | [Return address] | * ---------------------- */ jmp_target = sym_addr + instr_size; memcpy(jmp_insn + JMP_INSN_SIZE, &jmp_target, sizeof(jmp_target)); orig = mcount_save_code(sym_addr , instr_size, jmp_insn, sizeof(jmp_insn)); /* make sure orig->addr same as when called from __dentry__ */ orig->addr += CALL_INSN_SIZE; patch_code(mdi, sym_addr, instr_size); return INSTRUMENT_SUCCESS; } int mcount_patch_func(struct mcount_dynamic_info *mdi, struct sym *sym, struct mcount_disasm_engine *disasm, unsigned min_size) { struct arch_dynamic_info *adi = mdi->arch; int result = INSTRUMENT_SKIPPED; if (min_size < CALL_INSN_SIZE) min_size = CALL_INSN_SIZE; if (sym->size < min_size) return result; switch (adi->type) { case DYNAMIC_XRAY: result = patch_xray_func(mdi, sym); break; case DYNAMIC_FENTRY: result = patch_fentry_func(mdi, sym); break; case DYNAMIC_NONE: result = patch_normal_func(mdi, sym, disasm); break; default: break; } return result; } #define INSN_CHECK_LEN 16 static void revert_normal_func(struct mcount_dynamic_info *mdi, struct sym *sym, struct mcount_disasm_engine *disasm) { uint8_t jmp_insn[6] = { 0xff, 0x25, }; void *addr = (void *)(uintptr_t)sym->addr + mdi->map->start; void *saved_insn; int i; saved_insn = mcount_find_code((uintptr_t)addr + CALL_INSN_SIZE); if (saved_insn == NULL) return; /* we don't the original copy size, find the jmp insn instead */ for (i = CALL_INSN_SIZE; i < INSN_CHECK_LEN; i++) { if (!memcmp(saved_insn + i, jmp_insn, sizeof(jmp_insn))) break; } if (i == INSN_CHECK_LEN) pr_err_ns("cannot find original insn length\n"); memcpy(addr, saved_insn, i); __builtin___clear_cache(addr, addr + i); } void mcount_arch_dynamic_recover(struct mcount_dynamic_info *mdi, struct mcount_disasm_engine *disasm) { struct arch_dynamic_info *adi = mdi->arch; struct dynamic_bad_symbol *badsym, *tmp; list_for_each_entry_safe(badsym, tmp, &adi->bad_targets, list) { revert_normal_func(mdi, badsym->sym, disasm); list_del(&badsym->list); free(badsym); } } uftrace-0.9.3/arch/x86_64/mcount-event.c000066400000000000000000000026611351236475300176350ustar00rootroot00000000000000#include #include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "event" #define PR_DOMAIN DBG_EVENT #include "libmcount/internal.h" #define INVALID_OPCODE 0xce #define PAGE_SIZE 4096 #define PAGE_ADDR(a) ((void *)((a) & ~(PAGE_SIZE - 1))) static void sdt_handler(int sig, siginfo_t *info, void *arg) { ucontext_t *ctx = arg; unsigned long addr = ctx->uc_mcontext.gregs[REG_RIP]; struct mcount_event_info * mei; mei = mcount_lookup_event(addr); assert(mei != NULL); /* TODO: collect and write arguments */ mcount_save_event(mei); /* skip the invalid insn and continue */ ctx->uc_mcontext.gregs[REG_RIP] = addr + 1; } int mcount_arch_enable_event(struct mcount_event_info *mei) { static bool sdt_handler_set = false; if (!sdt_handler_set) { struct sigaction act = { .sa_flags = SA_SIGINFO, .sa_sigaction = sdt_handler, }; sigemptyset(&act.sa_mask); sigaction(SIGILL, &act, NULL); sdt_handler_set = true; } if (mprotect(PAGE_ADDR(mei->addr), PAGE_SIZE, PROT_READ | PROT_WRITE)) { pr_dbg("cannot enable event due to protection: %m\n"); return -1; } /* replace NOP to an invalid OP so that it can catch SIGILL */ memset((void *)mei->addr, INVALID_OPCODE, 1); if (mprotect(PAGE_ADDR(mei->addr), PAGE_SIZE, PROT_EXEC)) pr_err("cannot setup event due to protection"); return 0; } uftrace-0.9.3/arch/x86_64/mcount-insn.c000066400000000000000000000116551351236475300174660ustar00rootroot00000000000000#include "libmcount/internal.h" #include "mcount-arch.h" #define CALL_INSN_SIZE 5 #ifdef HAVE_LIBCAPSTONE #include #include struct disasm_check_data { uintptr_t addr; uint32_t func_size; uint32_t patch_size; uint32_t copy_size; uint32_t size; }; void mcount_disasm_init(struct mcount_disasm_engine *disasm) { if (cs_open(CS_ARCH_X86, CS_MODE_64, &disasm->engine) != CS_ERR_OK) { pr_dbg("failed to init Capstone disasm engine\n"); return; } if (cs_option(disasm->engine, CS_OPT_DETAIL, CS_OPT_ON) != CS_ERR_OK) pr_dbg("failed to set detail option\n"); } void mcount_disasm_finish(struct mcount_disasm_engine *disasm) { cs_close(&disasm->engine); } /* * check whether the instruction can be executed regardless of its location. * returns false when instructions are not suitable for dynamic patch. * * TODO: this function is incomplete and need more classification. */ static bool check_instrumentable(struct mcount_disasm_engine *disasm, cs_insn *insn) { int i; cs_x86 *x86; cs_detail *detail; bool jmp_or_call = false; bool status = false; /* * 'detail' can be NULL on "data" instruction * if SKIPDATA option is turned ON */ if (insn->detail == NULL) return false; detail = insn->detail; for (i = 0; i < detail->groups_count; i++) { if (detail->groups[i] == CS_GRP_CALL || detail->groups[i] == CS_GRP_JUMP) { jmp_or_call = true; } } x86 = &insn->detail->x86; /* no operand: disallow just to be safer for now */ if (!x86->op_count) return true; for (i = 0; i < x86->op_count; i++) { cs_x86_op *op = &x86->operands[i]; switch((int)op->type) { case X86_OP_REG: status = true; break; case X86_OP_IMM: if (jmp_or_call) return false; status = true; break; case X86_OP_MEM: if (op->mem.base == X86_REG_RIP || op->mem.index == X86_REG_RIP) return false; status = true; break; default: break; } } return status; } static bool check_unsupported(struct mcount_disasm_engine *disasm, cs_insn *insn, struct mcount_dynamic_info *mdi, struct disasm_check_data *insn_check) { int i; cs_x86 *x86; cs_detail *detail = insn->detail; unsigned long target; bool jump = false; if (detail == NULL) return false; detail = insn->detail; /* assume there's no call into the middle of function */ for (i = 0; i < detail->groups_count; i++) { if (detail->groups[i] == CS_GRP_JUMP) jump = true; } if (!jump) return true; x86 = &insn->detail->x86; for (i = 0; i < x86->op_count; i++) { cs_x86_op *op = &x86->operands[i]; switch((int)op->type) { case X86_OP_IMM: /* capstone seems already calculate target address */ target = op->imm; /* disallow (back) jump to the prologue */ if (insn_check->addr <= target && target < insn_check->addr + insn_check->size) return false; /* disallow jump to middle of other function */ if (insn_check->addr > target || target >= insn_check->addr + insn_check->func_size) { /* also mark the target function as invalid */ return !add_bad_jump(mdi, insn->address, target); } break; case X86_OP_MEM: /* TODO */ break; default: break; } } return true; } int disasm_check_insns(struct mcount_disasm_engine *disasm, struct mcount_dynamic_info *mdi, struct sym *sym) { cs_insn *insn = NULL; uint32_t count, i; uint8_t endbr64[] = { 0xf3, 0x0f, 0x1e, 0xfa }; int ret = INSTRUMENT_FAILED; struct disasm_check_data insn_check = { .addr = sym->addr + mdi->map->start, .func_size = sym->size, }; struct dynamic_bad_symbol *badsym; badsym = find_bad_jump(mdi, insn_check.addr); if (badsym != NULL) { list_del(&badsym->list); free(badsym); return ret; } count = cs_disasm(disasm->engine, (void *)insn_check.addr, sym->size, insn_check.addr, 0, &insn); if (unlikely(count == 0) && !memcmp((void *)insn_check.addr, endbr64, sizeof(endbr64))) { /* old version of capstone doesn't recognize ENDBR64 insn */ insn_check.addr += sizeof(endbr64); insn_check.func_size -= sizeof(endbr64); insn_check.copy_size += sizeof(endbr64); count = cs_disasm(disasm->engine, (void *)insn_check.addr, insn_check.func_size, insn_check.addr, insn_check.addr, &insn); } for (i = 0; i < count; i++) { if (!check_instrumentable(disasm, &insn[i])) { pr_dbg3("instruction not supported: %s\t %s\n", insn[i].mnemonic, insn[i].op_str); goto out; } insn_check.copy_size += insn[i].size; if (insn_check.copy_size >= CALL_INSN_SIZE) { ret = insn_check.copy_size; break; } } while (++i < count) { if (!check_unsupported(disasm, &insn[i], mdi, &insn_check)) { ret = INSTRUMENT_FAILED; break; } } out: if (count) cs_free(insn, count); return ret; } #else /* HAVE_LIBCAPSTONE */ int disasm_check_insns(struct mcount_disasm_engine *disasm, struct mcount_dynamic_info *mdi, struct sym *sym) { return INSTRUMENT_FAILED; } #endif /* HAVE_LIBCAPSTONE */ uftrace-0.9.3/arch/x86_64/mcount-noplt.c000066400000000000000000000065211351236475300176470ustar00rootroot00000000000000#include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "mcount" #define PR_DOMAIN DBG_MCOUNT #include "uftrace.h" #include "libmcount/mcount.h" #include "libmcount/internal.h" #include "utils/utils.h" #include "utils/symbol.h" #define TRAMP_ENT_SIZE 16 /* size of trampoilne for each entry */ #define TRAMP_PLT0_SIZE 32 /* module id + addres of plthook_addr() */ #define TRAMP_PCREL_JMP 10 /* PC_relative offset for JMP */ #define TRAMP_IDX_OFFSET 1 #define TRAMP_JMP_OFFSET 6 extern void __weak plt_hooker(void); struct plthook_data * mcount_arch_hook_no_plt(struct uftrace_elf_data *elf, const char *modname, unsigned long offset) { struct plthook_data *pd; void *trampoline; size_t tramp_len; uint32_t i; const uint8_t tramp_plt0[] = { /* followed by module_id + plthook_addr */ /* PUSH module_id */ 0xff, 0x35, 0xa, 0, 0, 0, /* JMP plthook_addr */ 0xff, 0x25, 0xc, 0, 0, 0, 0xcc, 0xcc, 0xcc, 0xcc, }; const uint8_t tramp_insns[] = { /* make stack what plt_hooker expect */ /* PUSH child_idx */ 0x68, 0, 0, 0, 0, /* JMP plt0 */ 0xe9, 0, 0, 0, 0, /* should never reach here */ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, }; void *plthook_addr = plt_hooker; void *tramp; pd = xzalloc(sizeof(*pd)); pd->module_id = (unsigned long)pd; pd->base_addr = offset; if (load_elf_dynsymtab(&pd->dsymtab, elf, offset, 0) < 0 || pd->dsymtab.nr_sym == 0) { free(pd); return NULL; } tramp_len = TRAMP_PLT0_SIZE + pd->dsymtab.nr_sym * TRAMP_ENT_SIZE; trampoline = mmap(NULL, tramp_len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (trampoline == MAP_FAILED) { pr_dbg("mmap failed: %m: ignore libcall hooking\n"); free(pd); return NULL; } pd->pltgot_ptr = trampoline; pd->resolved_addr = xcalloc(pd->dsymtab.nr_sym, sizeof(long)); /* add trampoline - save orig addr and replace GOT */ pr_dbg2("module: %s (id: %lx), addr = %lx, TRAMPOLINE = %p\n", pd->mod_name, pd->module_id, pd->base_addr, pd->pltgot_ptr); /* setup PLT0 */ memcpy(trampoline, tramp_plt0, sizeof(tramp_plt0)); tramp = trampoline + sizeof(tramp_plt0); memcpy(tramp, &pd->module_id, sizeof(pd->module_id)); tramp += sizeof(long); memcpy(tramp, &plthook_addr, sizeof(plthook_addr)); tramp += sizeof(long); for (i = 0; i < pd->dsymtab.nr_sym; i++) { uint32_t pcrel; Elf64_Rela *rela; struct sym *sym; unsigned k; bool skip = false; sym = &pd->dsymtab.sym[i]; for (k = 0; k < plt_skip_nr; k++) { if (!strcmp(sym->name, plt_skip_syms[k].name)) { skip = true; break; } } if (skip) continue; /* copy trampoline instructions */ memcpy(tramp, tramp_insns, TRAMP_ENT_SIZE); /* update offset (child id) */ memcpy(tramp + TRAMP_IDX_OFFSET, &i, sizeof(i)); /* update jump offset */ pcrel = trampoline - (tramp + TRAMP_PCREL_JMP); memcpy(tramp + TRAMP_JMP_OFFSET, &pcrel, sizeof(pcrel)); rela = (void*)sym->addr; /* save resolved address in GOT */ memcpy(&pd->resolved_addr[i], (void *)rela->r_offset + offset, sizeof(long)); /* update GOT to point the trampoline */ memcpy((void *)rela->r_offset + offset, &tramp, sizeof(long)); tramp += TRAMP_ENT_SIZE; } mprotect(trampoline, tramp_len, PROT_READ|PROT_EXEC); pd->mod_name = xstrdup(modname); return pd; } uftrace-0.9.3/arch/x86_64/mcount-support.c000066400000000000000000000101601351236475300202210ustar00rootroot00000000000000#include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "mcount" #define PR_DOMAIN DBG_MCOUNT #include "libmcount/internal.h" #include "utils/filter.h" #include "utils/arch.h" int mcount_get_register_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { struct mcount_regs *regs = ctx->regs; int reg_idx; switch (spec->type) { case ARG_TYPE_REG: reg_idx = spec->reg_idx; break; case ARG_TYPE_INDEX: reg_idx = spec->idx; /* for integer arguments */ break; case ARG_TYPE_FLOAT: reg_idx = spec->idx + UFT_X86_64_REG_FLOAT_BASE; break; case ARG_TYPE_STACK: default: return -1; } switch (reg_idx) { case UFT_X86_64_REG_RDI: ctx->val.i = ARG1(regs); break; case UFT_X86_64_REG_RSI: ctx->val.i = ARG2(regs); break; case UFT_X86_64_REG_RDX: ctx->val.i = ARG3(regs); break; case UFT_X86_64_REG_RCX: ctx->val.i = ARG4(regs); break; case UFT_X86_64_REG_R8: ctx->val.i = ARG5(regs); break; case UFT_X86_64_REG_R9: ctx->val.i = ARG6(regs); break; case UFT_X86_64_REG_XMM0: asm volatile ("movsd %%xmm0, %0\n" : "=m" (ctx->val.v)); break; case UFT_X86_64_REG_XMM1: asm volatile ("movsd %%xmm1, %0\n" : "=m" (ctx->val.v)); break; case UFT_X86_64_REG_XMM2: asm volatile ("movsd %%xmm2, %0\n" : "=m" (ctx->val.v)); break; case UFT_X86_64_REG_XMM3: asm volatile ("movsd %%xmm3, %0\n" : "=m" (ctx->val.v)); break; case UFT_X86_64_REG_XMM4: asm volatile ("movsd %%xmm4, %0\n" : "=m" (ctx->val.v)); break; case UFT_X86_64_REG_XMM5: asm volatile ("movsd %%xmm5, %0\n" : "=m" (ctx->val.v)); break; case UFT_X86_64_REG_XMM6: asm volatile ("movsd %%xmm6, %0\n" : "=m" (ctx->val.v)); break; case UFT_X86_64_REG_XMM7: asm volatile ("movsd %%xmm7, %0\n" : "=m" (ctx->val.v)); break; default: return -1; } return 0; } void mcount_get_stack_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { int offset; switch (spec->type) { case ARG_TYPE_STACK: offset = spec->stack_ofs; break; case ARG_TYPE_INDEX: offset = spec->idx - ARCH_MAX_REG_ARGS; break; case ARG_TYPE_FLOAT: offset = (spec->idx - ARCH_MAX_FLOAT_REGS) * 2 - 1; break; case ARG_TYPE_REG: default: /* should not reach here */ pr_err_ns("invalid stack access for arguments\n"); break; } if (offset < 1 || offset > 100) pr_dbg("invalid stack offset: %d\n", offset); memcpy(ctx->val.v, ctx->stack_base + offset, spec->size); } void mcount_arch_get_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { if (mcount_get_register_arg(ctx, spec) < 0) mcount_get_stack_arg(ctx, spec); } void mcount_arch_get_retval(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec) { /* type of return value cannot be FLOAT, so check format instead */ if (spec->fmt != ARG_FMT_FLOAT) memcpy(ctx->val.v, ctx->retval, spec->size); else if (spec->size == 10) /* for long double type */ asm volatile ("fstpt %0\n\tfldt %0" : "=m" (ctx->val.v)); else asm volatile ("movsd %%xmm0, %0\n" : "=m" (ctx->val.v)); } void mcount_save_arch_context(struct mcount_arch_context *ctx) { asm volatile ("movsd %%xmm0, %0\n" : "=m" (ctx->xmm[0])); asm volatile ("movsd %%xmm1, %0\n" : "=m" (ctx->xmm[1])); asm volatile ("movsd %%xmm2, %0\n" : "=m" (ctx->xmm[2])); asm volatile ("movsd %%xmm3, %0\n" : "=m" (ctx->xmm[3])); asm volatile ("movsd %%xmm4, %0\n" : "=m" (ctx->xmm[4])); asm volatile ("movsd %%xmm5, %0\n" : "=m" (ctx->xmm[5])); asm volatile ("movsd %%xmm6, %0\n" : "=m" (ctx->xmm[6])); asm volatile ("movsd %%xmm7, %0\n" : "=m" (ctx->xmm[7])); } void mcount_restore_arch_context(struct mcount_arch_context *ctx) { asm volatile ("movsd %0, %%xmm0\n" :: "m" (ctx->xmm[0])); asm volatile ("movsd %0, %%xmm1\n" :: "m" (ctx->xmm[1])); asm volatile ("movsd %0, %%xmm2\n" :: "m" (ctx->xmm[2])); asm volatile ("movsd %0, %%xmm3\n" :: "m" (ctx->xmm[3])); asm volatile ("movsd %0, %%xmm4\n" :: "m" (ctx->xmm[4])); asm volatile ("movsd %0, %%xmm5\n" :: "m" (ctx->xmm[5])); asm volatile ("movsd %0, %%xmm6\n" :: "m" (ctx->xmm[6])); asm volatile ("movsd %0, %%xmm7\n" :: "m" (ctx->xmm[7])); } uftrace-0.9.3/arch/x86_64/mcount.S000066400000000000000000000050021351236475300164660ustar00rootroot00000000000000/* argument passing: %rdi, %rsi, %rdx, %rcx, %r8, %r9 */ /* return value: %rax */ /* callee saved: %rbx, %rbp, %rsp, %r12-r15 */ /* stack frame (with -pg): parent addr = 8(%rbp), child addr = (%rsp) */ /* * For example: Parent(caller): main() Child(callee): hello() Dump of assembler code for function main: 0x00000000004006b1 <+0>: push %rbp 0x00000000004006b2 <+1>: mov %rsp,%rbp 0x00000000004006b5 <+4>: callq 0x400520 0x00000000004006ba <+9>: mov $0x0,%eax 0x00000000004006bf <+14>: callq 0x400686 parent addr => 0x00000000004006c4 <+19>: nop 0x00000000004006c5 <+20>: pop %rbp 0x00000000004006c6 <+21>: retq Dump of assembler code for function hello: 0x0000000000400686 <+0>: push %rbp 0x0000000000400687 <+1>: mov %rsp,%rbp 0x000000000040068a <+4>: sub $0x10,%rsp 0x000000000040068e <+8>: callq 0x400520 child addr => 0x0000000000400693 <+13>: movl $0x1,-0x4(%rbp) */ #include "utils/asm.h" GLOBAL(mcount) .cfi_startproc sub $48, %rsp .cfi_adjust_cfa_offset 48 /* save register arguments in mcount_args */ movq %rdi, 40(%rsp) movq %rsi, 32(%rsp) movq %rdx, 24(%rsp) movq %rcx, 16(%rsp) movq %r8, 8(%rsp) movq %r9, 0(%rsp) /* child addr */ movq 48(%rsp), %rsi /* parent location */ lea 8(%rbp), %rdi /* mcount_args */ movq %rsp, %rdx .cfi_def_cfa_register rdx /* align stack pointer to 16-byte */ andq $0xfffffffffffffff0, %rsp push %rdx /* save rax (implicit argument for variadic functions) */ push %rax call mcount_entry pop %rax /* restore original stack pointer */ pop %rdx movq %rdx, %rsp .cfi_def_cfa_register rsp /* restore mcount_args */ movq 0(%rsp), %r9 movq 8(%rsp), %r8 movq 16(%rsp), %rcx movq 24(%rsp), %rdx movq 32(%rsp), %rsi movq 40(%rsp), %rdi add $48, %rsp .cfi_adjust_cfa_offset -48 retq .cfi_endproc END(mcount) ENTRY(mcount_return) .cfi_startproc sub $48, %rsp .cfi_def_cfa_offset 48 movdqu %xmm0, 16(%rsp) movq %rdx, 8(%rsp) movq %rax, 0(%rsp) /* set the first argument of mcount_exit as pointer to return values */ movq %rsp, %rdi /* returns original parent address */ call mcount_exit movq %rax, 40(%rsp) movq 0(%rsp), %rax movq 8(%rsp), %rdx movdqu 16(%rsp), %xmm0 add $40, %rsp .cfi_def_cfa_offset 8 retq .cfi_endproc END(mcount_return) uftrace-0.9.3/arch/x86_64/plthook.S000066400000000000000000000032501351236475300166440ustar00rootroot00000000000000#include "utils/asm.h" .hidden plthook_resolver_addr ENTRY(plt_hooker) .cfi_startproc /* PLT code already pushed symbol and module indices */ .cfi_adjust_cfa_offset 16 sub $48, %rsp .cfi_adjust_cfa_offset 48 /* save register arguments in mcount_args */ movq %rdi, 40(%rsp) movq %rsi, 32(%rsp) movq %rdx, 24(%rsp) movq %rcx, 16(%rsp) movq %r8, 8(%rsp) movq %r9, 0(%rsp) /* module id */ movq 48(%rsp), %rdx /* child idx */ movq 56(%rsp), %rsi /* parent location */ leaq 64(%rsp), %rdi /* mcount_args */ movq %rsp, %rcx .cfi_def_cfa_register rcx /* align stack pointer to 16-byte */ andq $0xfffffffffffffff0, %rsp push %rcx /* save rax (implicit argument for variadic functions) */ push %rax call plthook_entry movq %rax, %r11 pop %rax /* restore original stack pointer */ pop %rcx movq %rcx, %rsp .cfi_def_cfa_register rsp /* restore mcount_args */ movq 0(%rsp), %r9 movq 8(%rsp), %r8 movq 16(%rsp), %rcx movq 24(%rsp), %rdx movq 32(%rsp), %rsi movq 40(%rsp), %rdi add $48, %rsp .cfi_adjust_cfa_offset -48 cmpq $0, %r11 cmovz plthook_resolver_addr(%rip), %r11 jz 1f add $16, %rsp /* resolver function needs 2 entries on stack */ .cfi_adjust_cfa_offset -16 1: jmp *%r11 .cfi_endproc END(plt_hooker) ENTRY(plthook_return) .cfi_startproc sub $48, %rsp .cfi_def_cfa_offset 48 movdqu %xmm0, 16(%rsp) movq %rdx, 8(%rsp) movq %rax, 0(%rsp) /* set the first argument of plthook_exit as pointer to return values */ movq %rsp, %rdi call plthook_exit movq %rax, 40(%rsp) movq 0(%rsp), %rax movq 8(%rsp), %rdx movdqu 16(%rsp), %xmm0 add $40, %rsp .cfi_def_cfa_offset 8 retq .cfi_endproc END(plthook_return) uftrace-0.9.3/arch/x86_64/symbol.c000066400000000000000000000065251351236475300165210ustar00rootroot00000000000000#include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "symbol" #define PR_DOMAIN DBG_SYMBOL #include "uftrace.h" #include "utils/utils.h" #include "utils/symbol.h" #include "libmcount/internal.h" #include "mcount-arch.h" #define R_OFFSET_POS 2 #define JMP_INSN_SIZE 6 #define PLTGOT_SIZE 8 int arch_load_dynsymtab_noplt(struct symtab *dsymtab, struct uftrace_elf_data *elf, unsigned long offset, unsigned long flags) { struct uftrace_elf_iter sec_iter; struct uftrace_elf_iter rel_iter; struct uftrace_elf_iter sym_iter; unsigned grow = SYMTAB_GROW; unsigned long reloc_start = 0; size_t reloc_entsize = 0; memset(dsymtab, 0, sizeof(*dsymtab)); /* assumes there's only one RELA section (rela.dyn) for no-plt binary */ elf_for_each_shdr(elf, &sec_iter) { if (sec_iter.shdr.sh_type == SHT_RELA) { memcpy(&rel_iter, &sec_iter, sizeof(sec_iter)); pr_dbg2("found RELA section: %s\n", elf_get_name(elf, &sec_iter, sec_iter.shdr.sh_name)); reloc_start = rel_iter.shdr.sh_addr + offset; reloc_entsize = rel_iter.shdr.sh_entsize; } else if (sec_iter.shdr.sh_type == SHT_DYNSYM) { memcpy(&sym_iter, &sec_iter, sizeof(sec_iter)); elf_get_strtab(elf, &sym_iter, sec_iter.shdr.sh_link); elf_get_secdata(elf, &sym_iter); } } if (reloc_start == 0) return 0; elf_for_each_rela(elf, &rel_iter) { struct sym *sym; int symidx; char *name; symidx = elf_rel_symbol(&rel_iter.rela); if (symidx == 0) continue; if (elf_rel_type(&rel_iter.rela) != R_X86_64_GLOB_DAT) continue; elf_get_symbol(elf, &sym_iter, symidx); if (elf_symbol_type(&sym_iter.sym) != STT_FUNC && elf_symbol_type(&sym_iter.sym) != STT_GNU_IFUNC) continue; if (sym_iter.sym.st_shndx != STN_UNDEF) continue; if (dsymtab->nr_sym >= dsymtab->nr_alloc) { if (dsymtab->nr_alloc >= grow * 4) grow *= 2; dsymtab->nr_alloc += grow; dsymtab->sym = xrealloc(dsymtab->sym, dsymtab->nr_alloc * sizeof(*sym)); } sym = &dsymtab->sym[dsymtab->nr_sym++]; /* use reloc address as symbol address as it's in the map */ sym->addr = reloc_start + rel_iter.i * reloc_entsize; sym->size = reloc_entsize; sym->type = ST_PLT_FUNC; name = elf_get_name(elf, &sym_iter, sym_iter.sym.st_name); if (flags & SYMTAB_FL_DEMANGLE) sym->name = demangle(name); else sym->name = xstrdup(name); pr_dbg3("[%zd] %c %lx + %-5u %s\n", dsymtab->nr_sym, sym->type, sym->addr, sym->size, sym->name); } return dsymtab->nr_sym; } void mcount_arch_plthook_setup(struct plthook_data *pd, struct uftrace_elf_data *elf) { struct plthook_arch_context *ctx; struct uftrace_elf_iter iter; char *secname; ctx = xzalloc(sizeof(*ctx)); elf_for_each_shdr(elf, &iter) { secname = elf_get_name(elf, &iter, iter.shdr.sh_name); if (strcmp(secname, ".plt.sec") == 0) { ctx->has_plt_sec = true; break; } } pd->arch = ctx; } unsigned long mcount_arch_plthook_addr(struct plthook_data *pd, int idx) { struct plthook_arch_context *ctx = pd->arch; struct sym *sym; if (ctx->has_plt_sec) { unsigned long sym_addr; /* symbol has .plt.sec address, so return .plt address */ sym_addr = pd->plt_addr + (idx + 1) * 16; return sym_addr; } sym = &pd->dsymtab.sym[idx]; return sym->addr + ARCH_PLTHOOK_ADDR_OFFSET; } uftrace-0.9.3/arch/x86_64/xray.S000066400000000000000000000030411351236475300161450ustar00rootroot00000000000000/* argument passing: %rdi, %rsi, %rdx, %rcx, %r8, %r9 */ /* return value: %rax */ /* callee saved: %rbx, %rbp, %rsp, %r12-r15 */ /* stack frame: child addr = 0(%rsp), return addr = 8(%rbp) */ #include "utils/asm.h" GLOBAL(__xray_entry) .cfi_startproc sub $48, %rsp .cfi_adjust_cfa_offset 48 movq %rdi, 40(%rsp) movq %rsi, 32(%rsp) movq %rdx, 24(%rsp) movq %rcx, 16(%rsp) movq %r8, 8(%rsp) movq %r9, 0(%rsp) /* child ip */ movq 48(%rsp), %rsi /* parent location */ lea 56(%rsp), %rdi /* mcount_args */ movq %rsp, %rdx .cfi_def_cfa_register rdx /* align stack pointer to 16-byte */ andq $0xfffffffffffffff0, %rsp push %rdx /* save rax (implicit argument for variadic functions) */ push %rax call xray_entry pop %rax /* restore original stack pointer */ pop %rdx movq %rdx, %rsp .cfi_def_cfa_register rsp /* restore mcount_args */ movq 0(%rsp), %r9 movq 8(%rsp), %r8 movq 16(%rsp), %rcx movq 24(%rsp), %rdx movq 32(%rsp), %rsi movq 40(%rsp), %rdi add $48, %rsp .cfi_adjust_cfa_offset -48 retq .cfi_endproc END(__xray_entry) ENTRY(__xray_exit) .cfi_startproc sub $40, %rsp /* return address already consume 8 byte */ .cfi_def_cfa_offset 40 /* save original return values */ movdqu %xmm0, 16(%rsp) movq %rdx, 8(%rsp) movq %rax, 0(%rsp) /* set the first argument of mcount_exit as pointer to return values */ movq %rsp, %rdi call xray_exit /* restore return values */ movq 0(%rsp), %rax movq 8(%rsp), %rdx movdqu 16(%rsp), %xmm0 add $40, %rsp retq .cfi_endproc END(__xray_exit) uftrace-0.9.3/check-deps/000077500000000000000000000000001351236475300151735ustar00rootroot00000000000000uftrace-0.9.3/check-deps/Makefile000066400000000000000000000026241351236475300166370ustar00rootroot00000000000000CHECK_LIST := clock_without_librt CHECK_LIST += cc_has_mfentry CHECK_LIST += cxa_demangle CHECK_LIST += have_libelf CHECK_LIST += cc_has_mno_sse2 CHECK_LIST += have_libpython2.7 CHECK_LIST += perf_clockid CHECK_LIST += perf_context_switch CHECK_LIST += arm_has_hardfp CHECK_LIST += have_libncurses CHECK_LIST += have_libdw CHECK_LIST += have_libcapstone # # This is needed for checking build dependency # CHECK_CFLAGS = $(CFLAGS) $(CFLAGS_$@) -Werror CHECK_LDFLAGS = $(LDFLAGS) $(LDFLAGS_$@) CFLAGS_cc_has_mfentry = -mfentry LDFLAGS_cxa_demangle = -lstdc++ LDFLAGS_have_libelf = -lelf CFLAGS_cc_has_mno_sse2 = -mno-sse2 LDFLAGS_have_libpython2.7 = -lpython2.7 CFLAGS_have_libncurses = $(shell pkg-config --cflags ncursesw 2> /dev/null) LDFLAGS_have_libncurses = $(shell pkg-config --libs ncursesw 2> /dev/null) CFLAGS_have_libdw = $(shell pkg-config --cflags libdw 2> /dev/null) LDFLAGS_have_libdw = $(shell pkg-config --libs libdw 2> /dev/null || echo "-ldw") CFLAGS_have_libcapstone = $(shell pkg-config --cflags capstone 2> /dev/null) LDFLAGS_have_libcapstone = $(shell pkg-config --libs capstone 2> /dev/null) check-build: check-tstamp $(CHECK_LIST) $(CHECK_LIST): %: __%.c @$(CC) $(CHECK_CFLAGS) -o $@ $< $(CHECK_LDFLAGS) > /dev/null 2>&1 check-tstamp: PHONY @touch $@ @if [ `id -u` -eq 0 ]; then chmod 666 $@; fi check-clean: @$(RM) $(shell find -type f -executable) check-tstamp *.o .PHONY: PHONY; uftrace-0.9.3/check-deps/Makefile.check000066400000000000000000000032311351236475300177060ustar00rootroot00000000000000ifeq ($(wildcard $(srcdir)/check-deps/clock_without_librt),) LDFLAGS_libmcount.so += -lrt endif ifneq ($(wildcard $(srcdir)/check-deps/cc_has_mfentry),) export HAVE_CC_MFENTRY = 1 endif ifneq ($(wildcard $(srcdir)/check-deps/cxa_demangle),) COMMON_CFLAGS += -DHAVE_CXA_DEMANGLE COMMON_LDFLAGS += -lstdc++ endif ifneq ($(wildcard $(srcdir)/check-deps/cc_has_mno_sse2),) LIB_CFLAGS += -mno-sse2 endif ifneq ($(wildcard $(srcdir)/check-deps/have_libpython2.7),) COMMON_CFLAGS += -DHAVE_LIBPYTHON2 endif ifneq ($(wildcard $(srcdir)/check-deps/perf_clockid),) COMMON_CFLAGS += -DHAVE_PERF_CLOCKID endif ifneq ($(wildcard $(srcdir)/check-deps/perf_context_switch),) COMMON_CFLAGS += -DHAVE_PERF_CTXSW endif ifneq ($(wildcard $(srcdir)/check-deps/arm_has_hardfp),) COMMON_CFLAGS += -DHAVE_ARM_HARDFP endif ifneq ($(wildcard $(srcdir)/check-deps/have_libncurses),) COMMON_CFLAGS += -DHAVE_LIBNCURSES $(shell pkg-config --cflags ncursesw) UFTRACE_LDFLAGS += $(shell pkg-config --libs ncursesw) TEST_LDFLAGS += $(shell pkg-config --libs ncursesw) endif ifneq ($(wildcard $(srcdir)/check-deps/have_libelf),) COMMON_CFLAGS += -DHAVE_LIBELF COMMON_LDFLAGS += -lelf endif ifneq ($(wildcard $(srcdir)/check-deps/have_libdw),) COMMON_CFLAGS += -DHAVE_LIBDW COMMON_CFLAGS += $(shell pkg-config --cflags libdw 2> /dev/null) COMMON_LDFLAGS += $(shell pkg-config --libs libdw 2> /dev/null || echo "-ldw") endif ifneq ($(wildcard $(srcdir)/check-deps/have_libcapstone),) COMMON_CFLAGS += -DHAVE_LIBCAPSTONE COMMON_CFLAGS += $(shell pkg-config --cflags capstone 2> /dev/null) COMMON_LDFLAGS += $(shell pkg-config --libs capstone 2> /dev/null) endif uftrace-0.9.3/check-deps/__arm_has_hardfp.c000066400000000000000000000001271351236475300205730ustar00rootroot00000000000000int main(void) { float f; asm volatile ("vstr %%s0, %0\n" : "=m" (f)); return 0; } uftrace-0.9.3/check-deps/__cc_has_mfentry.c000066400000000000000000000000361351236475300206200ustar00rootroot00000000000000int main(void) { return 0; } uftrace-0.9.3/check-deps/__cc_has_mno_sse2.c000066400000000000000000000000361351236475300206610ustar00rootroot00000000000000int main(void) { return 0; } uftrace-0.9.3/check-deps/__clock_without_librt.c000066400000000000000000000001211351236475300217010ustar00rootroot00000000000000#include int main(void) { return clock_gettime(CLOCK_MONOTONIC, 0); } uftrace-0.9.3/check-deps/__cxa_demangle.c000066400000000000000000000002361351236475300202450ustar00rootroot00000000000000extern char *__cxa_demangle(const char *name, char *output, long *len, int *status); int main(void) { __cxa_demangle("_Z1fv", 0, 0, 0); return 0; } uftrace-0.9.3/check-deps/__have_libcapstone.c000066400000000000000000000003141351236475300211410ustar00rootroot00000000000000#include #include #include #include #include int main() { cs_insn insn; printf("size: %zu\n", sizeof(insn)); return 0; } uftrace-0.9.3/check-deps/__have_libdw.c000066400000000000000000000001751351236475300177440ustar00rootroot00000000000000#include int main(void) { Dwarf *dw; dw = dwarf_begin(0, DWARF_C_READ); dwarf_end(dw); return 0; } uftrace-0.9.3/check-deps/__have_libelf.c000066400000000000000000000001611351236475300200730ustar00rootroot00000000000000#include #include int main(void) { GElf_Ehdr ehdr; elf_version(EV_CURRENT); return 0; } uftrace-0.9.3/check-deps/__have_libncurses.c000066400000000000000000000001131351236475300210040ustar00rootroot00000000000000#include int main(void) { initscr(); endwin(); return 0; } uftrace-0.9.3/check-deps/__have_libpython2.7.c000066400000000000000000000001331351236475300210740ustar00rootroot00000000000000#include int main(void) { Py_Initialize(); return 0; } uftrace-0.9.3/check-deps/__perf_clockid.c000066400000000000000000000004341351236475300202620ustar00rootroot00000000000000#define _GNU_SOURCE #include #include #include #include int main(void) { struct perf_event_attr attr = { .use_clockid = 1, .clockid = CLOCK_MONOTONIC, }; syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); return 0; } uftrace-0.9.3/check-deps/__perf_context_switch.c000066400000000000000000000005161351236475300217200ustar00rootroot00000000000000#define _GNU_SOURCE #include #include #include int main(void) { struct perf_event_attr attr = { .context_switch = 1, }; syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0); if (PERF_RECORD_SWITCH != 14 || PERF_RECORD_MISC_SWITCH_OUT != (1 << 13)) return -1; return 0; } uftrace-0.9.3/cmds/000077500000000000000000000000001351236475300141135ustar00rootroot00000000000000uftrace-0.9.3/cmds/dump.c000066400000000000000000001246141351236475300152340ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "uftrace.h" #include "version.h" #include "utils/list.h" #include "utils/utils.h" #include "utils/fstack.h" #include "utils/filter.h" #include "utils/kernel.h" #include "utils/graph.h" #include "libtraceevent/kbuffer.h" #include "libtraceevent/event-parse.h" struct uftrace_dump_ops { /* this is called at the beginning */ void (*header)(struct uftrace_dump_ops *ops, struct uftrace_data *handle, struct opts *opts); /* this is called when a task starts */ void (*task_start)(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task); /* this is called when a record's time is before the previous */ void (*inverted_time)(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task); /* this is called for each user-level function entry/exit */ void (*task_rstack)(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task, char *name); /* this is called for each user-level event */ void (*task_event)(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task); /* this is called when kernel data starts */ void (*kernel_start)(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel); /* this is called when a cpu data start */ void (*cpu_start)(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel, int cpu); /* this is called for each kernel-level function entry/exit */ void (*kernel_func)(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel, int cpu, struct uftrace_record *frs, char *name); /* this is called for each kernel event (tracepoint) */ void (*kernel_event)(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel, int cpu, struct uftrace_record *frs); /* thius is called when there's a lost record (usually in kernel) */ void (*lost)(struct uftrace_dump_ops *ops, uint64_t time, int tid, int losts); /* this is called when a perf data (for each cpu) starts */ void (*perf_start)(struct uftrace_dump_ops *ops, struct uftrace_perf_reader *perf, int cpu); /* this is called for each perf event (except for schedule) */ void (*perf_event)(struct uftrace_dump_ops *ops, struct uftrace_perf_reader *perf, struct uftrace_record *frs); /* this is called at the end */ void (*footer)(struct uftrace_dump_ops *ops, struct uftrace_data *handle, struct opts *opts); }; struct uftrace_raw_dump { struct uftrace_dump_ops ops; uint64_t file_offset; uint64_t kbuf_offset; }; struct uftrace_chrome_dump { struct uftrace_dump_ops ops; unsigned lost_event_cnt; bool last_comma; }; struct uftrace_flame_dump { struct uftrace_dump_ops ops; struct rb_root tasks; struct fg_node *node; uint64_t sample_time; }; struct uftrace_graphviz_dump { struct uftrace_dump_ops ops; }; static const char * rstack_type(struct uftrace_record *frs) { return frs->type == UFTRACE_EXIT ? "exit " : frs->type == UFTRACE_ENTRY ? "entry" : frs->type == UFTRACE_EVENT ? "event" : "lost "; } static void pr_time(uint64_t timestamp) { unsigned sec = timestamp / NSEC_PER_SEC; unsigned nsec = timestamp % NSEC_PER_SEC; pr_out("%u.%09u ", sec, nsec); } static int pr_task(struct opts *opts) { FILE *fp; char buf[PATH_MAX]; struct uftrace_msg msg; struct uftrace_msg_task tmsg; struct uftrace_msg_sess smsg; char *exename = NULL; snprintf(buf, sizeof(buf), "%s/task", opts->dirname); fp = fopen(buf, "r"); if (fp == NULL) return -1; while (fread(&msg, sizeof(msg), 1, fp) == 1) { if (msg.magic != UFTRACE_MSG_MAGIC) { pr_red("invalid message magic: %hx\n", msg.magic); goto out; } switch (msg.type) { case UFTRACE_MSG_TASK_START: if (fread(&tmsg, sizeof(tmsg), 1, fp) != 1) { pr_red("cannot read task message: %m\n"); goto out; } pr_time(tmsg.time); pr_out("task tid %d (pid %d)\n", tmsg.tid, tmsg.pid); break; case UFTRACE_MSG_FORK_END: if (fread(&tmsg, sizeof(tmsg), 1, fp) != 1) { pr_red("cannot read task message: %m\n"); goto out; } pr_time(tmsg.time); pr_out("fork pid %d (ppid %d)\n", tmsg.tid, tmsg.pid); break; case UFTRACE_MSG_SESSION: if (fread(&smsg, sizeof(smsg), 1, fp) != 1) { pr_red("cannot read session message: %m\n"); goto out; } free(exename); exename = xmalloc(ALIGN(smsg.namelen, 8)); if (fread(exename, ALIGN(smsg.namelen, 8), 1,fp) != 1 ) { pr_red("cannot read executable name: %m\n"); goto out; } pr_time(smsg.task.time); pr_out("session of task %d: %.*s (%s)\n", smsg.task.tid, SESSION_ID_LEN, smsg.sid, exename); break; default: pr_out("unknown message type: %u\n", msg.type); break; } } out: free(exename); fclose(fp); return 0; } static int pr_task_txt(struct opts *opts) { FILE *fp; char buf[PATH_MAX]; char *ptr, *end; char *timestamp; int pid, tid; char sid[20]; snprintf(buf, sizeof(buf), "%s/task.txt", opts->dirname); fp = fopen(buf, "r"); if (fp == NULL) return -1; while (fgets(buf, sizeof(buf), fp)) { if (!strncmp(buf, "TASK", 4)) { ptr = strstr(buf, "timestamp="); if (ptr == NULL) { pr_red("invalid task timestamp\n"); goto out; } timestamp = ptr + 10; end = strchr(ptr, ' '); if (end == NULL) { pr_red("invalid task timestamp\n"); goto out; } *end++ = '\0'; sscanf(end, "tid=%d pid=%d", &tid, &pid); pr_out("%s task tid %d (pid %d)\n", timestamp, tid, pid); } else if (!strncmp(buf, "FORK", 4)) { ptr = strstr(buf, "timestamp="); if (ptr == NULL) { pr_red("invalid task timestamp\n"); goto out; } timestamp = ptr + 10; end = strchr(ptr, ' '); if (end == NULL) { pr_red("invalid task timestamp\n"); goto out; } *end++ = '\0'; sscanf(end, "pid=%d ppid=%d", &tid, &pid); pr_out("%s fork pid %d (ppid %d)\n", timestamp, tid, pid); } else if (!strncmp(buf, "SESS", 4)) { char *exename; ptr = strstr(buf, "timestamp="); if (ptr == NULL) { pr_red("invalid session timestamp\n"); goto out; } timestamp = ptr + 10; end = strchr(ptr, ' '); if (end == NULL) { pr_red("invalid session timestamp\n"); goto out; } *end++ = '\0'; if (sscanf(end, "pid=%d sid=%s", &tid, sid) != 2) sscanf(end, "tid=%d sid=%s", &tid, sid); ptr = strstr(end, "exename="); if (ptr == NULL) { pr_red("invalid session exename\n"); goto out; } exename = ptr + 8 + 1; // skip double-quote end = strrchr(ptr, '\"'); if (end == NULL) { pr_red("invalid session exename\n"); goto out; } *end++ = '\0'; pr_out("%s session of task %d: %.*s (%s)\n", timestamp, tid, 16, sid, exename); } } out: fclose(fp); return 0; } static void pr_hex(uint64_t *offset, void *data, size_t len) { size_t i; unsigned char *h = data; uint64_t ofs = *offset; if (!debug) return; while (len >= 16) { pr_green(" <%016"PRIx64">:", ofs); pr_green(" %02x %02x %02x %02x %02x %02x %02x %02x " " %02x %02x %02x %02x %02x %02x %02x %02x\n", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15]); ofs += 16; len -= 16; h += 16; } if (len) { pr_green(" <%016"PRIx64">:", ofs); if (len > 8) { pr_green(" %02x %02x %02x %02x %02x %02x %02x %02x ", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]); ofs += 8; len -= 8; h += 8; } for (i = 0; i < len; i++) pr_green(" %02x", *h++); pr_green("\n"); ofs += len; } *offset = ofs; } static void pr_args(struct fstack_arguments *args) { struct uftrace_arg_spec *spec; struct uftrace_task_reader *task; struct uftrace_session_link *sessions; void *ptr = args->data; size_t size; int i = 0; task = container_of(args, typeof(*task), args); sessions = &task->h->sessions; list_for_each_entry(spec, args->args, list) { /* skip return value info */ if (spec->idx == RETVAL_IDX) continue; if (spec->fmt == ARG_FMT_STR || spec->fmt == ARG_FMT_STD_STRING) { char *buf; const int null_str = -1; size = *(unsigned short *)ptr; buf = xmalloc(size + 1); strncpy(buf, ptr + 2, size); buf[size] = '\0'; if (!memcmp(buf, &null_str, 4)) strcpy(buf, "NULL"); if (spec->fmt == ARG_FMT_STD_STRING) pr_out(" args[%d] std::string: %s\n", i , buf); else pr_out(" args[%d] str: %s\n", i , buf); free(buf); size += 2; } else if (spec->fmt == ARG_FMT_PTR) { struct sym *sym; unsigned long val = 0; memcpy(&val, ptr, spec->size); size = spec->size; sym = task_find_sym_addr(sessions, task, task->rstack->time, (uint64_t)val); if (sym) pr_out(" args[%d] p: %lx (&%s)\n", i, val, sym->name); else if (val) pr_out(" args[%d] p: %p\n", i, (void *)val); else pr_out(" args[%d] p: 0\n", i); } else if (spec->fmt == ARG_FMT_ENUM) { long long val = 0; struct uftrace_mmap *map; struct uftrace_session *s; struct debug_info *dinfo; char *enum_def; s = find_task_session(sessions, task->t, task->rstack->time); map = find_map(&s->symtabs, task->rstack->addr); if (!map || !map->mod) goto print_raw; dinfo = &map->mod->dinfo; memcpy(&val, ptr, spec->size); enum_def = get_enum_string(&dinfo->enums, spec->enum_str, val); pr_out(" args[%d] enum %s: %s (%lld)\n", i, spec->enum_str, enum_def, val); free(enum_def); size = spec->size; } else { long long val = 0; print_raw: memcpy(&val, ptr, spec->size); pr_out(" args[%d] %c%d: 0x%0*llx\n", i, ARG_SPEC_CHARS[spec->fmt], spec->size * 8, spec->size * 2, val); size = spec->size; } ptr += ALIGN(size, 4); i++; } } static void pr_retval(struct fstack_arguments *args) { struct uftrace_arg_spec *spec; struct uftrace_task_reader *task; struct uftrace_session_link *sessions; void *ptr = args->data; size_t size; task = container_of(args, typeof(*task), args); sessions = &task->h->sessions; list_for_each_entry(spec, args->args, list) { /* skip argument info */ if (spec->idx != RETVAL_IDX) continue; if (spec->fmt == ARG_FMT_STR || spec->fmt == ARG_FMT_STD_STRING) { char *buf; const int null_str = -1; size = *(unsigned short *)ptr; buf = xmalloc(size + 1); strncpy(buf, ptr + 2, size); buf[size] = '\0'; if (!memcmp(buf, &null_str, 4)) strcpy(buf, "NULL"); if (spec->fmt == ARG_FMT_STD_STRING) pr_out(" retval std::string: %s\n", buf); else pr_out(" retval str: %s\n", buf); free(buf); size += 2; } else if (spec->fmt == ARG_FMT_PTR) { struct sym *sym; unsigned long val = 0; memcpy(&val, ptr, spec->size); size = spec->size; sym = task_find_sym_addr(sessions, task, task->rstack->time, (uint64_t)val); if (sym) pr_out(" retval p: %lx (&%s)\n", val, sym->name); else pr_out(" retval p: %p\n", (void *)val); } else { long long val = 0; memcpy(&val, ptr, spec->size); pr_out(" retval %c%d: 0x%0*llx\n", ARG_SPEC_CHARS[spec->fmt], spec->size * 8, spec->size * 2, val); size = spec->size; } ptr += ALIGN(size, 4); } } static void pr_event(int eid, void *ptr, int len) { union { struct uftrace_proc_statm *statm; struct uftrace_page_fault *pgfault; } d; /* built-in events */ switch (eid) { case EVENT_ID_READ_PROC_STATM: d.statm = ptr; pr_out(" proc/statm: vmsize=%"PRIu64"K vmrss=%"PRIu64"K shared=%"PRIu64"K\n", d.statm->vmsize, d.statm->vmrss, d.statm->shared); break; case EVENT_ID_READ_PAGE_FAULT: d.pgfault = ptr; pr_out(" page-fault: major=%"PRIu64" minor=%"PRIu64"\n", d.pgfault->major, d.pgfault->minor); break; case EVENT_ID_DIFF_PROC_STATM: d.statm = ptr; pr_out(" proc/statm: vmsize=%+"PRId64"K vmrss=%+"PRId64"K shared=%+"PRId64"K\n", d.statm->vmsize, d.statm->vmrss, d.statm->shared); break; case EVENT_ID_DIFF_PAGE_FAULT: d.pgfault = ptr; pr_out(" page-fault: major=%+"PRId64" minor=%+"PRId64"\n", d.pgfault->major, d.pgfault->minor); break; default: break; } /* user events */ } static void get_feature_string(char *buf, size_t sz, uint64_t feature_mask) { int i; size_t len; bool first = true; const char *feat_str[] = { "PLTHOOK", "TASK_SESSION", "KERNEL", "ARGUMENT", "RETVAL", "SYM_REL_ADDR", "MAX_STACK", "EVENT", "PERF_EVENT", "AUTO_ARGS", "DEBUG_INFO" }; /* feat_str should match to enum uftrace_feat_bits */ for (i = 0; i < FEAT_BIT_MAX; i++) { if (!((1U << i) & feature_mask)) continue; len = snprintf(buf, sz, "%s%s", first ? "" : " | ", feat_str[i]); buf += len; sz -= len; first = false; } } static void dump_raw_header(struct uftrace_dump_ops *ops, struct uftrace_data *handle, struct opts *opts) { int i; char buf[1024]; struct uftrace_raw_dump *raw = container_of(ops, typeof(*raw), ops); pr_out("uftrace file header: magic = "); for (i = 0; i < UFTRACE_MAGIC_LEN; i++) pr_out("%02x", handle->hdr.magic[i]); pr_out("\n"); pr_out("uftrace file header: version = %u\n", handle->hdr.version); pr_out("uftrace file header: header size = %u\n", handle->hdr.header_size); pr_out("uftrace file header: endian = %u (%s)\n", handle->hdr.endian, handle->hdr.endian == 1 ? "little" : "big"); pr_out("uftrace file header: class = %u (%s bit)\n", handle->hdr.class, handle->hdr.class == 2 ? "64" : "32"); get_feature_string(buf, sizeof(buf), handle->hdr.feat_mask); pr_out("uftrace file header: features = %#"PRIx64" (%s)\n", handle->hdr.feat_mask, buf); pr_out("uftrace file header: info = %#"PRIx64"\n", handle->hdr.info_mask); pr_hex(&raw->file_offset, &handle->hdr, handle->hdr.header_size); pr_out("\n"); if (debug) { pr_out("%d tasks found\n", handle->info.nr_tid); /* try to read task.txt first */ if (pr_task_txt(opts) < 0 && pr_task(opts) < 0) pr_red("cannot open task file\n"); pr_out("\n"); } } static void dump_raw_task_start(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task) { struct uftrace_raw_dump *raw = container_of(ops, typeof(*raw), ops); pr_out("reading %d.dat\n", task->tid); raw->file_offset = 0; setup_rstack_list(&task->rstack_list); } static void dump_raw_inverted_time(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task) { pr_red("\n"); pr_red("*************************************\n"); pr_red("* inverted time - data seems broken *\n"); pr_red("*************************************\n"); pr_red("\n"); } static void dump_raw_task_rstack(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task, char *name) { struct uftrace_record *frs = task->rstack; struct uftrace_raw_dump *raw = container_of(ops, typeof(*raw), ops); if (frs->type == UFTRACE_EVENT) name = get_event_name(task->h, frs->addr); pr_time(frs->time); pr_out("%5d: [%s] %s(%"PRIx64") depth: %u\n", task->tid, rstack_type(frs), name, frs->addr, frs->depth); pr_hex(&raw->file_offset, frs, sizeof(*frs)); if (frs->type == UFTRACE_EVENT) free(name); if (frs->more) { if (frs->type == UFTRACE_ENTRY) { pr_time(frs->time); pr_out("%5d: [%s] length = %d\n", task->tid, "args ", task->args.len); pr_args(&task->args); pr_hex(&raw->file_offset, task->args.data, ALIGN(task->args.len, 8)); } else if (frs->type == UFTRACE_EXIT) { pr_time(frs->time); pr_out("%5d: [%s] length = %d\n", task->tid, "retval", task->args.len); pr_retval(&task->args); pr_hex(&raw->file_offset, task->args.data, ALIGN(task->args.len, 8)); } else abort(); } } static void dump_raw_task_event(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task) { struct uftrace_record *frs = task->rstack; struct uftrace_raw_dump *raw = container_of(ops, typeof(*raw), ops); char *name = get_event_name(task->h, frs->addr); pr_time(frs->time); pr_out("%5d: [%s] %s(%"PRIx64") depth: %u\n", task->tid, rstack_type(frs), name, frs->addr, frs->depth); pr_hex(&raw->file_offset, frs, sizeof(*frs)); if (frs->more) { pr_time(frs->time); pr_out("%5d: [%s] length = %d\n", task->tid, "data ", task->args.len); pr_event(frs->addr, task->args.data, task->args.len); pr_hex(&raw->file_offset, task->args.data, ALIGN(task->args.len, 8)); } free(name); } static void dump_raw_kernel_start(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel) { pr_out("\n"); } static void dump_raw_cpu_start(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel, int cpu) { struct uftrace_raw_dump *raw = container_of(ops, typeof(*raw), ops); struct kbuffer *kbuf = kernel->kbufs[cpu]; pr_out("reading kernel-cpu%d.dat\n", cpu); raw->file_offset = 0; raw->kbuf_offset = kbuffer_curr_offset(kbuf); } static void dump_raw_kernel_rstack(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel, int cpu, struct uftrace_record *frs, char *name) { int tid = kernel->tids[cpu]; struct kbuffer *kbuf = kernel->kbufs[cpu]; struct uftrace_raw_dump *raw = container_of(ops, typeof(*raw), ops); /* check dummy 'time extend' record at the beginning */ if (raw->kbuf_offset == 0x18) { uint64_t offset = 0x10; uint64_t timestamp = 0; void *data = kbuffer_read_at_offset(kbuf, offset, NULL); unsigned char *tmp = data - 12; /* data still returns next record */ if ((*tmp & 0x1f) == KBUFFER_TYPE_TIME_EXTEND) { uint32_t upper, lower; int size; size = kbuffer_event_size(kbuf); memcpy(&lower, tmp, 4); memcpy(&upper, tmp + 4, 4); timestamp = ((uint64_t)upper << 27) + (lower >> 5); pr_time(frs->time - timestamp); pr_out("%5d: [%s] %s (+%"PRIu64" nsec)\n", tid, "time ", "extend", timestamp); if (debug) pr_hex(&offset, tmp, 8); else if (kbuffer_next_event(kbuf, NULL)) raw->kbuf_offset += size + 4; // 4 = event header size else raw->kbuf_offset = 0; } } pr_time(frs->time); pr_out("%5d: [%s] %s(%"PRIx64") depth: %u\n", tid, rstack_type(frs), name, frs->addr, frs->depth); if (debug) { /* this is only needed for hex dump */ void *data = kbuffer_read_at_offset(kbuf, raw->kbuf_offset, NULL); int size; size = kbuffer_event_size(kbuf); raw->file_offset = kernel->offsets[cpu] + kbuffer_curr_offset(kbuf); pr_hex(&raw->file_offset, data - 4, size + 4); if (kbuffer_next_event(kbuf, NULL)) raw->kbuf_offset += size + 4; // 4 = event header size else raw->kbuf_offset = 0; } } static void dump_raw_kernel_event(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel, int cpu, struct uftrace_record *frs) { struct uftrace_raw_dump *raw = container_of(ops, typeof(*raw), ops); struct event_format *event; int tid = kernel->tids[cpu]; char *event_data; int size = 0; event = pevent_find_event(kernel->pevent, frs->addr); event_data = read_kernel_event(kernel, cpu, &size); pr_time(frs->time); pr_out("%5d: [%s] %s:%s(%ld) %.*s\n", tid, rstack_type(frs), event->system, event->name, frs->addr, size, event_data); if (debug) { /* this is only needed for hex dump */ struct kbuffer *kbuf = kernel->kbufs[cpu]; void *data = kbuffer_read_at_offset(kbuf, raw->kbuf_offset, NULL); int size; size = kbuffer_event_size(kbuf); raw->file_offset = kernel->offsets[cpu] + kbuffer_curr_offset(kbuf); pr_hex(&raw->file_offset, data - 4, size + 4); if (kbuffer_next_event(kbuf, NULL)) raw->kbuf_offset += size + 4; // 4 = event header size else raw->kbuf_offset = 0; } } static void dump_raw_kernel_lost(struct uftrace_dump_ops *ops, uint64_t time, int tid, int losts) { pr_time(time); pr_red("%5d: [%s ]: %d events\n", tid, "lost", losts); } static void dump_raw_perf_start(struct uftrace_dump_ops *ops, struct uftrace_perf_reader *perf, int cpu) { struct uftrace_raw_dump *raw = container_of(ops, typeof(*raw), ops); if (cpu == 0) pr_out("\n"); pr_out("reading perf-cpu%d.dat\n", cpu); raw->file_offset = 0; } static void dump_raw_perf_event(struct uftrace_dump_ops *ops, struct uftrace_perf_reader *perf, struct uftrace_record *frs) { struct uftrace_raw_dump *raw = container_of(ops, typeof(*raw), ops); char *evt_name = get_event_name(NULL, frs->addr); pr_time(frs->time); pr_out("%5d: [%s] %s(%"PRIu64")\n", perf->tid, rstack_type(frs), evt_name, frs->addr); if (debug) { /* XXX: this is different from file contents */ switch (frs->addr) { case EVENT_ID_PERF_SCHED_IN: case EVENT_ID_PERF_SCHED_OUT: pr_hex(&raw->file_offset, &perf->u.ctxsw, sizeof(perf->u.ctxsw)); break; case EVENT_ID_PERF_TASK: case EVENT_ID_PERF_EXIT: pr_hex(&raw->file_offset, &perf->u.task, sizeof(perf->u.task)); break; case EVENT_ID_PERF_COMM: pr_hex(&raw->file_offset, &perf->u.comm, sizeof(perf->u.comm)); break; default: break; } } free(evt_name); } static void dump_chrome_header(struct uftrace_dump_ops *ops, struct uftrace_data *handle, struct opts *opts) { struct uftrace_chrome_dump *chrome = container_of(ops, typeof(*chrome), ops); struct uftrace_info *info = &handle->info; struct uftrace_task *task; int tid; int i; if (handle->hdr.feat_mask & PERF_EVENT) update_perf_task_comm(handle); pr_out("{\"traceEvents\":[\n"); for (i = 0; i < info->nr_tid; i++) { tid = info->tids[i]; task = find_task(&handle->sessions, tid); pr_out("{\"ts\":0,\"ph\":\"M\",\"pid\":%d," "\"name\":\"process_name\"," "\"args\":{\"name\":\"[%d] %s\"}},\n", tid, tid, task->comm); pr_out("{\"ts\":0,\"ph\":\"M\",\"pid\":%d," "\"name\":\"thread_name\"," "\"args\":{\"name\":\"[%d] %s\"}},\n", tid, tid, task->comm); } chrome->last_comma = false; } static void dump_chrome_task_rstack(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task, char *name) { char ph; char spec_buf[1024]; struct uftrace_record *frs = task->rstack; enum argspec_string_bits str_mode = NEEDS_ESCAPE; struct uftrace_chrome_dump *chrome = container_of(ops, typeof(*chrome), ops); bool is_process = task->t->pid == task->tid; int rec_type = frs->type; if (rec_type == UFTRACE_EVENT) { switch (frs->addr) { case EVENT_ID_PERF_SCHED_IN: /* * new thread starts with a sched-in event * which should be ignored */ if (task->timestamp_last == 0) return; rec_type = UFTRACE_EXIT; break; case EVENT_ID_PERF_SCHED_OUT: rec_type = UFTRACE_ENTRY; break; default: return; } } if (chrome->last_comma) pr_out(",\n"); chrome->last_comma = true; if (rec_type == UFTRACE_ENTRY) { ph = 'B'; if (is_process) { /* no need to add "tid" field */ pr_out("{\"ts\":%"PRIu64".%03d,\"ph\":\"%c\",\"pid\":%d,\"name\":\"%s\"", frs->time / 1000, (int)(frs->time % 1000), ph, task->tid, name); } else { pr_out("{\"ts\":%"PRIu64".%03d,\"ph\":\"%c\",\"pid\":%d,\"tid\":%d,\"name\":\"%s\"", frs->time / 1000, (int)(frs->time % 1000), ph, task->t->pid, task->tid, name); } if (frs->more) { str_mode |= NEEDS_PAREN | HAS_MORE; get_argspec_string(task, spec_buf, sizeof(spec_buf), str_mode); pr_out(",\"args\":{\"arguments\":\"%s\"}}", spec_buf); } else pr_out("}"); } else if (rec_type == UFTRACE_EXIT) { ph = 'E'; if (is_process) { /* no need to add "tid" field */ pr_out("{\"ts\":%"PRIu64".%03d,\"ph\":\"%c\",\"pid\":%d,\"name\":\"%s\"", frs->time / 1000, (int)(frs->time % 1000), ph, task->tid, name); } else { pr_out("{\"ts\":%"PRIu64".%03d,\"ph\":\"%c\",\"pid\":%d,\"tid\":%d,\"name\":\"%s\"", frs->time / 1000, (int)(frs->time % 1000), ph, task->t->pid, task->tid, name); } if (frs->more) { str_mode |= IS_RETVAL | HAS_MORE; get_argspec_string(task, spec_buf, sizeof(spec_buf), str_mode); pr_out(",\"args\":{\"retval\":\"%s\"}}", spec_buf); } else pr_out("}"); } else if (rec_type == UFTRACE_LOST) chrome->lost_event_cnt++; } static void dump_chrome_kernel_rstack(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel, int cpu, struct uftrace_record *rec, char *name) { int tid; struct uftrace_task_reader *task; tid = kernel->tids[cpu]; task = get_task_handle(kernel->handle, tid); dump_chrome_task_rstack(ops, task, name); } static void dump_chrome_perf_event(struct uftrace_dump_ops *ops, struct uftrace_perf_reader *perf, struct uftrace_record *frs) { uint64_t evt_id = frs->addr; bool is_process = perf->u.comm.pid == perf->tid; switch (evt_id) { case EVENT_ID_PERF_COMM: if (is_process) { pr_out(",\n{\"ts\":0,\"ph\":\"M\",\"pid\":%d," "\"name\":\"process_name\"," "\"args\":{\"name\":\"%s\"}}", perf->tid, perf->u.comm.comm); pr_out(",\n{\"ts\":0,\"ph\":\"M\",\"pid\":%d," "\"name\":\"thread_name\"," "\"args\":{\"name\":\"%s\"}}", perf->tid, perf->u.comm.comm); } else { pr_out(",\n{\"ts\":0,\"ph\":\"M\",\"pid\":%d,\"tid\":%d," "\"name\":\"thread_name\"," "\"args\":{\"name\":\"[%d] %s\"}}", perf->u.comm.pid, perf->tid, perf->tid, perf->u.comm.comm); } break; default: break; }; } static void dump_chrome_footer(struct uftrace_dump_ops *ops, struct uftrace_data *handle, struct opts *opts) { char buf[PATH_MAX]; struct stat statbuf; struct uftrace_chrome_dump *chrome = container_of(ops, typeof(*chrome), ops); /* read recorded date and time */ snprintf(buf, sizeof(buf), "%s/info", opts->dirname); if (stat(buf, &statbuf) < 0) return; ctime_r(&statbuf.st_mtime, buf); buf[strlen(buf) - 1] = '\0'; pr_out("\n], \"displayTimeUnit\": \"ns\", \"metadata\": {\n"); pr_out("\"version\":\"uftrace %s\",\n", UFTRACE_VERSION); pr_out("\"recorded_time\":\"%s\",\n", buf); if (handle->hdr.info_mask & (1UL << CMDLINE)) pr_out("\"command_line\":\"%s\"\n", handle->info.cmdline); pr_out("} }\n"); /* * Chrome trace format requires to have both entry and exit records so * that it can identify the range of function call and return. * However, if there are some lost records, it cannot match the entry * and exit of some functions. It may show some of functions do not * return until the program is finished or vice versa. * * Since it's very difficult to generate fake records for lost data to * match entry and exit of some lost functions, we just inform the fact * to users as of now. */ if (chrome->lost_event_cnt) { pr_warn("Some of function trace records are lost. " "(%d times shown)\n", chrome->lost_event_cnt); pr_warn("The output json format may not show the correct view " "in chrome browser.\n"); } } /* flamegraph support */ static struct uftrace_graph flame_graph = { .root.head = LIST_HEAD_INIT(flame_graph.root.head), .special_nodes = LIST_HEAD_INIT(flame_graph.special_nodes), }; static void adjust_fg_time(struct uftrace_task_graph *tg, void *arg) { struct uftrace_dump_ops *ops = arg; struct uftrace_flame_dump *flame = container_of(ops, typeof(*flame), ops); struct fstack *fstack = &tg->task->func_stack[tg->task->stack_count]; struct uftrace_graph_node *node = tg->node; uint64_t curr_time = fstack->total_time; uint64_t sample_time = flame->sample_time; uint64_t accounted_time; if (flame->sample_time == 0) return; if (tg->node->parent == NULL) return; /* * it needs to track the child time separately * since child time not accounted due to sample time * should be accounted to parent. * * For example, with 1us sample time: * * # DURATION TID FUNCTION * [12345] | main() { * 4.789 us [12345] | foo(); * 4.987 us [12345] | bar(); * 10.567 us [12345] | } // main * * In this case, main's total time is more than 10us * so 10 samples should be shown, but after accounting * foo and bar (4 samples each), its time would be * 10.567 - 4.789 - 4.987 = 0.791 so no samples for main. * But it acctually needs to get 2 samples. * * So add the accounted child time only, not real time. */ accounted_time = (curr_time / sample_time) * sample_time; node->parent->child_time -= curr_time; node->parent->child_time += accounted_time; } static void print_flame_graph(struct uftrace_graph_node *node, struct opts *opts) { struct uftrace_graph_node *child; unsigned long sample = node->nr_calls; if (sample && opts->sample_time) sample = (node->time - node->child_time) / opts->sample_time; if (sample) { struct uftrace_graph_node *parent = node; char *names[opts->max_stack]; char *buf, *ptr; int i = 0; size_t len = 0; while (parent != NULL && parent->name != NULL) { names[i++] = parent->name; len += strlen(parent->name) + 1; parent = parent->parent; } buf = ptr = xmalloc(len + 32); while (--i >= 0) ptr += snprintf(ptr, len, "%s;", names[i]); ptr[-1] = ' '; snprintf(ptr, len, "%lu", sample); pr_out("%s\n", buf); free(buf); } list_for_each_entry(child, &node->head, list) print_flame_graph(child, opts); } static void dump_flame_header(struct uftrace_dump_ops *ops, struct uftrace_data *handle, struct opts *opts) { graph_init_callbacks(NULL, adjust_fg_time, NULL, ops); } static void dump_flame_task_rstack(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task, char *name) { struct uftrace_record *frs = task->rstack; struct uftrace_task_graph *graph; graph = graph_get_task(task, sizeof(*graph)); graph->graph = &flame_graph; flame_graph.sess = find_task_session(&task->h->sessions, task->t, frs->time); if (graph->node == NULL) graph->node = &flame_graph.root; graph_add_node(graph, frs->type, name, sizeof(struct uftrace_graph_node)); } static void dump_flame_kernel_rstack(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel, int cpu, struct uftrace_record *rec, char *name) { int tid; struct uftrace_task_reader *task; struct uftrace_task_graph *graph; tid = kernel->tids[cpu]; task = get_task_handle(kernel->handle, tid); graph = graph_get_task(task, sizeof(*graph)); graph->graph = &flame_graph; flame_graph.sess = kernel->handle->sessions.first; if (graph->node == NULL) graph->node = &flame_graph.root; graph_add_node(graph, rec->type, name, sizeof(struct uftrace_graph_node)); } static void dump_flame_footer(struct uftrace_dump_ops *ops, struct uftrace_data *handle, struct opts *opts) { print_flame_graph(&flame_graph.root, opts); graph_destroy(&flame_graph); graph_remove_task(); } /* to graphviz support */ static struct uftrace_graph graphviz_graph = { .root.head = LIST_HEAD_INIT(graphviz_graph.root.head), .special_nodes = LIST_HEAD_INIT(graphviz_graph.special_nodes), }; static void dump_graphviz_header(struct uftrace_dump_ops *ops, struct uftrace_data *handle, struct opts *opts) { pr_out("# version\":\"uftrace %s\",\n", UFTRACE_VERSION); if (handle->hdr.info_mask & (1UL << CMDLINE)) pr_out("# command_line \"%s\"\n", handle->info.cmdline); pr_out("digraph \""); pr_out("%s", (&handle->info)->exename); pr_out("\" { \n"); pr_out("\n\t# Attributes \n"); pr_out("\tsplines=ortho;\n"); pr_out("\tconcentrate=true;\n"); pr_out("\tnode [shape=\"rect\",fontsize=\"7\",style=\"filled\"];\n"); pr_out("\tedge [fontsize=\"7\"];\n\n"); graph_init_callbacks(NULL, NULL, NULL, ops); } static void dump_graphviz_task_rstack(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task, char *name) { struct uftrace_record *frs = task->rstack; struct uftrace_task_graph *graph; graph = graph_get_task(task, sizeof(*graph)); graph->graph = &graphviz_graph; graphviz_graph.sess = find_task_session(&task->h->sessions, task->t, frs->time); if (graph->node == NULL) graph->node = &graphviz_graph.root; graph_add_node(graph, frs->type, name, sizeof(struct uftrace_graph_node)); } static void dump_graphviz_kernel_rstack(struct uftrace_dump_ops *ops, struct uftrace_kernel_reader *kernel, int cpu, struct uftrace_record *rec, char *name) { int tid; struct uftrace_task_reader *task; struct uftrace_task_graph *graph; tid = kernel->tids[cpu]; task = get_task_handle(kernel->handle, tid); graph = graph_get_task(task, sizeof(*graph)); graph->graph = &graphviz_graph; graphviz_graph.sess = kernel->handle->sessions.first; if (graph->node == NULL) graph->node = &graphviz_graph.root; graph_add_node(graph, rec->type, name, sizeof(struct uftrace_graph_node)); } static void print_graph_to_graphviz(struct uftrace_graph_node *node, struct opts *opts) { struct uftrace_graph_node *child; unsigned long n_calls = node->nr_calls; if (n_calls) { struct uftrace_graph_node *parent = node->parent; pr_out("\t"); if (parent != NULL && parent->name != NULL) { pr_out("\"%s\" -> ", parent->name); } pr_out("\"%s\"", node->name); // Edge Attributes pr_out(" [xlabel = \"Calls : %lu\"]\n", n_calls); } list_for_each_entry(child, &node->head, list) print_graph_to_graphviz(child, opts); } static void dump_graphviz_footer(struct uftrace_dump_ops *ops, struct uftrace_data *handle, struct opts *opts) { pr_out("\t# Elements \n"); print_graph_to_graphviz(&graphviz_graph.root, opts); pr_out("}\n"); graph_destroy(&graphviz_graph); graph_remove_task(); } static void do_dump_file(struct uftrace_dump_ops *ops, struct opts *opts, struct uftrace_data *handle) { int i; uint64_t prev_time; struct uftrace_task_reader *task; struct uftrace_session_link *sessions = &handle->sessions; call_if_nonull(ops->header, ops, handle, opts); for (i = 0; i < handle->info.nr_tid; i++) { if (opts->kernel && opts->kernel_only) continue; task = &handle->tasks[i]; task->rstack = &task->ustack; prev_time = 0; call_if_nonull(ops->task_start, ops, task); while (!read_task_ustack(handle, task) && !uftrace_done) { struct uftrace_record *frs = &task->ustack; struct sym *sym; char *name; if (frs->more) { add_to_rstack_list(&task->rstack_list, frs, &task->args); } /* consume the rstack as it didn't call read_rstack() */ fstack_consume(handle, task); if (!check_time_range(&handle->time_range, frs->time)) continue; if (prev_time > frs->time) call_if_nonull(ops->inverted_time, ops, task); prev_time = frs->time; if (!fstack_check_filter(task)) continue; if (frs->type == UFTRACE_EVENT) { if (!opts->no_event) call_if_nonull(ops->task_event, ops, task); continue; } sym = task_find_sym(sessions, task, frs); /* skip it if --no-libcall is given */ if (!opts->libcall && sym && sym->type == ST_PLT_FUNC) continue; name = symbol_getname(sym, frs->addr); call_if_nonull(ops->task_rstack, ops, task, name); symbol_putname(sym, name); } } if (!has_kernel_data(handle->kernel) || uftrace_done) goto perf; call_if_nonull(ops->kernel_start, ops, handle->kernel); for (i = 0; i < handle->kernel->nr_cpus; i++) { struct uftrace_kernel_reader *kernel = handle->kernel; struct uftrace_record *frs = &kernel->rstacks[i]; struct uftrace_session *fsess = handle->sessions.first; call_if_nonull(ops->cpu_start, ops, kernel, i); while (!read_kernel_cpu_data(kernel, i) && !uftrace_done) { int tid = kernel->tids[i]; int losts = kernel->missed_events[i]; struct sym *sym = NULL; char *name; uint64_t addr; if (losts) { call_if_nonull(ops->lost, ops, frs->time, tid, losts); kernel->missed_events[i] = 0; } if (!check_time_range(&handle->time_range, frs->time)) continue; if (frs->type == UFTRACE_EVENT) { if (!opts->no_event) call_if_nonull(ops->kernel_event, ops, kernel, i, frs); continue; } addr = get_kernel_address(&fsess->symtabs, frs->addr); sym = find_symtabs(&fsess->symtabs, addr); name = symbol_getname(sym, addr); call_if_nonull(ops->kernel_func, ops, kernel, i, frs, name); symbol_putname(sym, name); } } perf: if (!has_perf_data(handle) || uftrace_done) goto footer; for (i = 0; i < handle->nr_perf; i++) { struct uftrace_perf_reader *perf = &handle->perf[i]; call_if_nonull(ops->perf_start, ops, perf, i); while (!uftrace_done) { struct uftrace_record *rec; rec = get_perf_record(handle, perf); if (rec == NULL) break; call_if_nonull(ops->perf_event, ops, perf, rec); /* for re-read perf data from file */ perf->valid = false; } } footer: call_if_nonull(ops->footer, ops, handle, opts); } static bool check_task_rstack(struct uftrace_task_reader *task, struct opts *opts) { struct uftrace_record *frs = task->rstack; if (!fstack_check_opts(task, opts)) return false; if (!fstack_check_filter(task)) return false; if (!check_time_range(&task->h->time_range, frs->time)) return false; return true; } static void dump_replay_func(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task, struct opts *opts) { struct uftrace_record *rec = task->rstack; struct uftrace_session_link *sessions = &task->h->sessions; struct sym *sym; char *name; sym = task_find_sym(sessions, task, rec); /* skip it if --no-libcall is given */ if (!opts->libcall && sym && sym->type == ST_PLT_FUNC) return; name = symbol_getname(sym, rec->addr); if (is_kernel_record(task, rec)) { struct uftrace_kernel_reader *kernel = task->h->kernel; call_if_nonull(ops->kernel_func, ops, kernel, kernel->last_read_cpu, rec, name); } else { call_if_nonull(ops->task_rstack, ops, task, name); } symbol_putname(sym, name); } static void dump_replay_event(struct uftrace_dump_ops *ops, struct uftrace_task_reader *task) { struct uftrace_record *rec = task->rstack; /* handle schedule events as if functions */ if (rec->addr == EVENT_ID_PERF_SCHED_IN || rec->addr == EVENT_ID_PERF_SCHED_OUT) { call_if_nonull(ops->task_rstack, ops, task, "linux:schedule"); return; } if (is_user_record(task, rec)) { call_if_nonull(ops->task_event, ops, task); } else if (is_kernel_record(task, rec)) { struct uftrace_kernel_reader *kernel = task->h->kernel; call_if_nonull(ops->kernel_event, ops, kernel, kernel->last_read_cpu, rec); } else if (is_event_record(task, rec)) { struct uftrace_perf_reader perf = { .tid = task->tid, .time = rec->time, }; if (rec->addr == EVENT_ID_PERF_COMM) { strncpy(perf.u.comm.comm, task->args.data, TASK_COMM_LAST); perf.u.comm.comm[TASK_COMM_LAST] = '\0'; perf.u.comm.pid = task->t->pid; } call_if_nonull(ops->perf_event, ops, &perf, rec); } else if (is_extern_record(task, rec)) { call_if_nonull(ops->task_event, ops, task); } else { struct uftrace_perf_reader *perf; assert(task->h->last_perf_idx >= 0); perf = &task->h->perf[task->h->last_perf_idx]; call_if_nonull(ops->perf_event, ops, perf, rec); } } static void do_dump_replay(struct uftrace_dump_ops *ops, struct opts *opts, struct uftrace_data *handle) { uint64_t prev_time = 0; struct uftrace_task_reader *task; int i; ops->header(ops, handle, opts); while (!read_rstack(handle, &task) && !uftrace_done) { struct uftrace_record *frs = task->rstack; task->timestamp_last = frs->time; if (!check_task_rstack(task, opts)) continue; if (prev_time > frs->time) ops->inverted_time(ops, task); prev_time = frs->time; if (task->rstack->type == UFTRACE_EVENT) dump_replay_event(ops, task); else dump_replay_func(ops, task, opts); } /* add duration of remaining functions */ for (i = 0; i < handle->nr_tasks; i++) { uint64_t last_time; task = &handle->tasks[i]; if (task->stack_count == 0) continue; last_time = task->timestamp_last; if (handle->time_range.stop && handle->time_range.stop < last_time) last_time = handle->time_range.stop; while (--task->stack_count >= 0) { struct fstack *fstack; struct uftrace_session *fsess = handle->sessions.first; fstack = &task->func_stack[task->stack_count]; if (fstack->addr == 0) continue; if (fstack->total_time > last_time) continue; fstack->total_time = last_time - fstack->total_time; if (fstack->child_time > fstack->total_time) fstack->total_time = fstack->child_time; if (task->stack_count > 0) fstack[-1].child_time += fstack->total_time; /* make sure is_kernel_record() working correctly */ if (is_kernel_address(&fsess->symtabs, fstack->addr)) task->rstack = &task->kstack; else task->rstack = &task->ustack; task->rstack->time = last_time; task->rstack->type = UFTRACE_EXIT; task->rstack->addr = fstack->addr; task->rstack->more = 0; if (!check_task_rstack(task, opts)) continue; if (task->rstack->type == UFTRACE_EVENT) dump_replay_event(ops, task); else dump_replay_func(ops, task, opts); } } ops->footer(ops, handle, opts); } int command_dump(int argc, char *argv[], struct opts *opts) { int ret; struct uftrace_data handle; ret = open_data_file(opts, &handle); if (ret < 0) { pr_warn("cannot open record data: %s: %m\n", opts->dirname); return -1; } fstack_setup_filters(opts, &handle); if (opts->chrome_trace) { struct uftrace_chrome_dump dump = { .ops = { .header = dump_chrome_header, .task_rstack = dump_chrome_task_rstack, .kernel_func = dump_chrome_kernel_rstack, .perf_event = dump_chrome_perf_event, .footer = dump_chrome_footer, }, }; do_dump_replay(&dump.ops, opts, &handle); } else if (opts->flame_graph) { struct uftrace_flame_dump dump = { .ops = { .header = dump_flame_header, .task_rstack = dump_flame_task_rstack, .kernel_func = dump_flame_kernel_rstack, .footer = dump_flame_footer, }, .tasks = RB_ROOT, .sample_time = opts->sample_time, }; do_dump_replay(&dump.ops, opts, &handle); } else if (opts->graphviz) { struct uftrace_graphviz_dump dump = { .ops = { .header = dump_graphviz_header, .task_rstack = dump_graphviz_task_rstack, .kernel_func = dump_graphviz_kernel_rstack, .footer = dump_graphviz_footer, }, }; do_dump_replay(&dump.ops, opts, &handle); } else { struct uftrace_raw_dump dump = { .ops = { .header = dump_raw_header, .task_start = dump_raw_task_start, .inverted_time = dump_raw_inverted_time, .task_rstack = dump_raw_task_rstack, .task_event = dump_raw_task_event, .kernel_start = dump_raw_kernel_start, .cpu_start = dump_raw_cpu_start, .kernel_func = dump_raw_kernel_rstack, .kernel_event = dump_raw_kernel_event, .lost = dump_raw_kernel_lost, .perf_start = dump_raw_perf_start, .perf_event = dump_raw_perf_event, }, }; do_dump_file(&dump.ops, opts, &handle); } close_data_file(opts, &handle); return ret; } uftrace-0.9.3/cmds/graph.c000066400000000000000000000374071351236475300153730ustar00rootroot00000000000000#include #include #include #include #include #include #include "uftrace.h" #include "utils/utils.h" #include "utils/symbol.h" #include "utils/filter.h" #include "utils/fstack.h" #include "utils/field.h" #include "utils/graph.h" static LIST_HEAD(output_fields); struct graph_backtrace { struct list_head list; int len; int hit; uint64_t time; uint64_t addr[]; }; struct session_graph { struct uftrace_graph ug; struct graph_backtrace *bt_curr; struct list_head bt_list; struct session_graph *next; char *func; }; struct task_graph { struct uftrace_task_graph utg; struct graph_backtrace *bt_curr; int enabled; }; static bool full_graph = false; static struct session_graph *graph_list = NULL; static void print_total_time(struct field_data *fd) { struct uftrace_graph_node *node = fd->arg; uint64_t d; d = node->time; print_time_unit(d); } static void print_self_time(struct field_data *fd) { struct uftrace_graph_node *node = fd->arg; uint64_t d; d = node->time - node->child_time; print_time_unit(d); } static void print_addr(struct field_data *fd) { struct uftrace_graph_node *node = fd->arg; /* uftrace records (truncated) 48-bit addresses */ int width = sizeof(long) == 4 ? 8 : 12; pr_out("%*lx", width, node->addr); } static struct display_field field_total_time= { .id = GRAPH_F_TOTAL_TIME, .name = "total-time", .alias = "total", .header = "TOTAL TIME", .length = 10, .print = print_total_time, .list = LIST_HEAD_INIT(field_total_time.list), }; static struct display_field field_self_time= { .id = GRAPH_F_SELF_TIME, .name = "self-time", .alias = "self", .header = " SELF TIME", .length = 10, .print = print_self_time, .list = LIST_HEAD_INIT(field_self_time.list), }; static struct display_field field_addr = { .id = GRAPH_F_ADDR, .name = "address", .alias = "addr", #if __SIZEOF_LONG == 4 .header = " ADDR ", .length = 8, #else .header = " ADDRESS ", .length = 12, #endif .print = print_addr, .list = LIST_HEAD_INIT(field_addr.list), }; /* index of this table should be matched to display_field_id */ static struct display_field *field_table[] = { &field_total_time, &field_self_time, &field_addr, }; static void setup_default_field(struct list_head *fields, struct opts *opts) { add_field(fields, field_table[GRAPH_F_TOTAL_TIME]); } static void print_field(struct uftrace_graph_node *node) { struct field_data fd = { .arg = node, }; if (print_field_data(&output_fields, &fd, 2)) pr_out(" : "); } static int create_graph(struct uftrace_session *sess, void *func) { struct session_graph *graph = xzalloc(sizeof(*graph)); pr_dbg("create graph for session %.*s (%s)\n", SESSION_ID_LEN, sess->sid, sess->exename); graph->func = xstrdup(full_graph ? basename(sess->exename) : func); INIT_LIST_HEAD(&graph->bt_list); graph_init(&graph->ug, sess); graph->ug.root.name = graph->func; graph->next = graph_list; graph_list = graph; return 0; } static void setup_graph_list(struct uftrace_data *handle, struct opts *opts, char *func) { struct session_graph *graph; walk_sessions(&handle->sessions, create_graph, func); graph = graph_list; while (graph) { graph->ug.kernel_only = opts->kernel_only; graph = graph->next; } } static struct uftrace_graph * get_graph(struct uftrace_task_reader *task, uint64_t time, uint64_t addr) { struct session_graph *graph; struct uftrace_session_link *sessions = &task->h->sessions; struct uftrace_session *sess; sess = find_task_session(sessions, task->t, time); if (sess == NULL) { struct uftrace_session *fsess = sessions->first; if (is_kernel_address(&fsess->symtabs, addr)) sess = fsess; else return NULL; } graph = graph_list; while (graph) { if (graph->ug.sess == sess) return &graph->ug; graph = graph->next; } return NULL; } static int start_graph(struct task_graph *tg); static struct task_graph * get_task_graph(struct uftrace_task_reader *task, uint64_t time, uint64_t addr) { struct task_graph *tg; struct uftrace_graph *graph; tg = (struct task_graph *)graph_get_task(task, sizeof(*tg)); graph = get_graph(task, time, addr); if (tg->utg.graph && tg->utg.graph != graph) { pr_dbg("detect new session: %.*s\n", SESSION_ID_LEN, graph->sess->sid); tg->utg.new_sess = true; } tg->utg.graph = graph; if (full_graph && tg->utg.node == NULL) start_graph(tg); return tg; } static int save_backtrace_addr(struct task_graph *tg) { int i; int skip = 0; struct graph_backtrace *bt; struct uftrace_task_reader *task = tg->utg.task; struct session_graph *graph = (struct session_graph *)tg->utg.graph; int len = task->stack_count; uint64_t addrs[len]; if (graph->ug.kernel_only) { skip = task->user_stack_count; len -= skip; } if (len == 0) return 0; for (i = len - 1; i >= 0; i--) addrs[i] = task->func_stack[i + skip].addr; list_for_each_entry(bt, &graph->bt_list, list) { if (len == bt->len && !memcmp(addrs, bt->addr, len * sizeof(*addrs))) goto found; } bt = xmalloc(sizeof(*bt) + len * sizeof(*addrs)); bt->len = len; bt->hit = 0; bt->time = 0; memcpy(bt->addr, addrs, len * sizeof(*addrs)); list_add(&bt->list, &graph->bt_list); found: bt->hit++; tg->bt_curr = bt; return 0; } static void save_backtrace_time(struct task_graph *tg) { struct uftrace_task_reader *task = tg->utg.task; struct fstack *fstack = &task->func_stack[task->stack_count]; if (tg->bt_curr) tg->bt_curr->time += fstack->total_time; tg->bt_curr = NULL; } static int print_backtrace(struct session_graph *graph) { int i = 0, k; struct graph_backtrace *bt; struct sym *sym; char *symname; list_for_each_entry(bt, &graph->bt_list, list) { pr_out(" backtrace #%d: hit %d, time ", i++, bt->hit); print_time_unit(bt->time); pr_out("\n"); for (k = 0; k < bt->len; k++) { sym = find_symtabs(&graph->ug.sess->symtabs, bt->addr[k]); if (sym == NULL) sym = session_find_dlsym(graph->ug.sess, bt->time, bt->addr[k]); symname = symbol_getname(sym, bt->addr[k]); pr_out(" [%d] %s (%#lx)\n", k, symname, bt->addr[k]); symbol_putname(sym, symname); } pr_out("\n"); } return 0; } static int start_graph(struct task_graph *tg) { if (!tg->enabled++) { save_backtrace_addr(tg); pr_dbg("start graph for task %d\n", tg->utg.task->tid); tg->utg.node = &tg->utg.graph->root; tg->utg.node->addr = tg->utg.task->rstack->addr; tg->utg.node->nr_calls++; } return 0; } static int end_graph(struct task_graph *tg) { if (!tg->enabled) return 0; if (!--tg->enabled) { save_backtrace_time(tg); tg->utg.lost = false; pr_dbg("end graph for task %d\n", tg->utg.task->tid); } return 0; } static void pr_indent(bool *indent_mask, int indent, bool line) { int i; int last = -1; for (i = 0; i < indent; i++) { if (line && indent_mask[i]) last = i; } for (i = 0; i < indent; i++) { if (!line || i < last) { if (indent_mask[i]) pr_out(" | "); else pr_out(" "); } else { if (i == last) pr_out(" +-"); else pr_out("---"); } } } static void print_graph_node(struct uftrace_graph *graph, struct uftrace_graph_node *node, bool *indent_mask, int indent, bool needs_line) { char *symname = node->name; struct uftrace_graph_node *parent = node->parent; struct uftrace_graph_node *child; int orig_indent = indent; /* XXX: what if it clashes with existing function address */ if (node->addr == EVENT_ID_PERF_SCHED_IN) symname = "linux:schedule"; print_field(node); pr_indent(indent_mask, indent, needs_line); /* FIXME: it should count fork+exec properly */ if (full_graph && node == &graph->root) pr_out("(%d) %s\n", 1, symname); else pr_out("(%d) %s\n", node->nr_calls, symname); if (node->nr_edges > 1) { pr_dbg2("add mask (%d) for %s\n", indent, symname); indent_mask[indent++] = true; } /* clear parent indent mask at the last node */ if (parent && parent->nr_edges > 1 && orig_indent > 0 && parent->head.prev == &node->list) indent_mask[orig_indent - 1] = false; needs_line = (node->nr_edges > 1); list_for_each_entry(child, &node->head, list) { print_graph_node(graph, child, indent_mask, indent, needs_line); if (&child->list != node->head.prev) { /* print blank line between siblings */ if (print_empty_field(&output_fields, 2)) pr_out(" : "); pr_indent(indent_mask, indent, false); pr_out("\n"); } } indent_mask[orig_indent] = false; pr_dbg2("del mask (%d) for %s\n", orig_indent, symname); } static int print_graph(struct session_graph *graph, struct opts *opts) { bool *indent_mask; /* skip empty graph */ if (list_empty(&graph->bt_list) && graph->ug.root.time == 0 && graph->ug.root.nr_edges == 0) return 0; pr_out("# Function Call Graph for '%s' (session: %.16s)\n", graph->func, graph->ug.sess->sid); if (!full_graph && !list_empty(&graph->bt_list)) { pr_out("=============== BACKTRACE ===============\n"); print_backtrace(graph); } setup_field(&output_fields, opts, &setup_default_field, field_table, ARRAY_SIZE(field_table)); if (graph->ug.root.time || graph->ug.root.nr_edges) { pr_out("========== FUNCTION CALL GRAPH ==========\n"); print_header(&output_fields, "# ", 2); indent_mask = xcalloc(opts->max_stack, sizeof(*indent_mask)); print_graph_node(&graph->ug, &graph->ug.root, indent_mask, 0, graph->ug.root.nr_edges > 1); free(indent_mask); pr_out("\n"); } return 1; } static void build_graph_node(struct opts *opts, struct uftrace_task_reader *task, uint64_t time, uint64_t addr, int type, char *func) { struct task_graph *tg; struct sym *sym = NULL; char *name; tg = get_task_graph(task, time, addr); sym = find_symtabs(&tg->utg.graph->sess->symtabs, addr); if (sym == NULL) sym = session_find_dlsym(tg->utg.graph->sess, time, addr); name = symbol_getname(sym, addr); /* skip it if --no-libcall is given */ if (!opts->libcall && sym && sym->type == ST_PLT_FUNC) goto out; if (tg->enabled) { graph_add_node(&tg->utg, type, name, sizeof(struct uftrace_graph_node)); } /* cannot find a session for this record */ if (tg->utg.graph == NULL) goto out; if (type == UFTRACE_EVENT) goto out; if (full_graph) goto out; if (!strcmp(name, func)) { if (type == UFTRACE_ENTRY) start_graph(tg); else if (type == UFTRACE_EXIT) end_graph(tg); } out: symbol_putname(sym, name); } static void build_graph(struct opts *opts, struct uftrace_data *handle, char *func) { struct uftrace_task_reader *task; struct session_graph *graph; uint64_t prev_time = 0; int i; setup_graph_list(handle, opts, func); while (!read_rstack(handle, &task) && !uftrace_done) { struct uftrace_record *frs = task->rstack; uint64_t addr = frs->addr; if (!fstack_check_opts(task, opts)) continue; if (!fstack_check_filter(task)) continue; if (frs->type == UFTRACE_EVENT) { if (frs->addr != EVENT_ID_PERF_SCHED_IN && frs->addr != EVENT_ID_PERF_SCHED_OUT) continue; } if (is_kernel_record(task, frs)) { struct uftrace_session *fsess; fsess = task->h->sessions.first; addr = get_kernel_address(&fsess->symtabs, addr); } if (frs->type == UFTRACE_LOST) { struct task_graph *tg; struct uftrace_session *fsess; if (opts->kernel_skip_out && !task->user_stack_count) continue; pr_dbg("*** LOST ***\n"); /* add partial duration of kernel functions before LOST */ while (task->stack_count >= task->user_stack_count) { struct fstack *fstack; fstack = &task->func_stack[task->stack_count]; if (fstack_enabled && fstack->valid && !(fstack->flags & FSTACK_FL_NORECORD)) { build_graph_node(opts, task, prev_time, fstack->addr, UFTRACE_EXIT, func); } fstack_exit(task); task->stack_count--; } /* force to find a session for kernel function */ fsess = task->h->sessions.first; tg = get_task_graph(task, prev_time, fsess->symtabs.kernel_base + 1); tg->utg.lost = true; if (tg->enabled && is_kernel_address(&fsess->symtabs, tg->utg.node->addr)) pr_dbg("not returning to user after LOST\n"); continue; } if (prev_time > frs->time) { pr_warn("inverted time: broken data?\n"); return; } prev_time = frs->time; if (task->stack_count >= opts->max_stack) continue; build_graph_node(opts, task, frs->time, addr, frs->type, func); } /* add duration of remaining functions */ for (i = 0; i < handle->nr_tasks; i++) { uint64_t last_time; struct fstack *fstack; task = &handle->tasks[i]; if (task->stack_count == 0) continue; last_time = task->rstack->time; if (handle->time_range.stop) last_time = handle->time_range.stop; while (--task->stack_count >= 0) { fstack = &task->func_stack[task->stack_count]; if (fstack->addr == 0) continue; if (fstack->total_time > last_time) continue; fstack->total_time = last_time - fstack->total_time; if (fstack->child_time > fstack->total_time) fstack->total_time = fstack->child_time; if (task->stack_count > 0) fstack[-1].child_time += fstack->total_time; build_graph_node(opts, task, last_time, fstack->addr, UFTRACE_EXIT, func); } } if (!full_graph || uftrace_done) return; /* account execution time of each graph */ graph = graph_list; while (graph) { struct uftrace_graph_node *node; list_for_each_entry(node, &graph->ug.root.head, list) { graph->ug.root.time += node->time; graph->ug.root.child_time += node->time; } graph = graph->next; } } struct find_func_data { char *name; bool found; }; static int find_func(struct uftrace_session *s, void *arg) { struct find_func_data *data = arg; struct symtabs *symtabs = &s->symtabs; struct uftrace_mmap *map; for_each_map(symtabs, map) { if (map->mod == NULL) continue; if (find_symname(&map->mod->symtab, data->name)) { data->found = true; break; } } return data->found; } static void synthesize_depth_trigger(struct opts *opts, struct uftrace_data *handle, char *func) { size_t old_len = opts->trigger ? strlen(opts->trigger) : 0; size_t new_len = strlen(func) + 32; struct find_func_data ffd = { .name = func, }; walk_sessions(&handle->sessions, find_func, &ffd); opts->trigger = xrealloc(opts->trigger, old_len + new_len); snprintf(opts->trigger + old_len, new_len, "%s%s@%sdepth=%d", old_len ? ";" : "", func, ffd.found ? "" : "kernel,", opts->depth); } int command_graph(int argc, char *argv[], struct opts *opts) { int ret; struct uftrace_data handle; struct session_graph *graph; char *func; struct graph_backtrace *bt, *btmp; __fsetlocking(outfp, FSETLOCKING_BYCALLER); __fsetlocking(logfp, FSETLOCKING_BYCALLER); if (argc > 0) func = argv[0]; else { func = "_start"; full_graph = true; } ret = open_data_file(opts, &handle); if (ret < 0) { pr_warn("cannot open record data: %s: %m\n", opts->dirname); return -1; } if (opts->depth != OPT_DEPTH_DEFAULT) { /* * Applying depth filter before the function might * lead to undesired result. Set a synthetic depth * trigger to prevent the function from filtering out. */ synthesize_depth_trigger(opts, &handle, func); } fstack_setup_filters(opts, &handle); build_graph(opts, &handle, func); graph = graph_list; while (graph && !uftrace_done) { ret += print_graph(graph, opts); graph = graph->next; } if (!ret && !uftrace_done) { pr_out("uftrace: cannot find graph for '%s'\n", func); if (opts_has_filter(opts)) pr_out("\t please check your filter settings.\n"); } while (graph_list) { graph = graph_list; graph_list = graph->next; free(graph->func); list_for_each_entry_safe(bt, btmp, &graph->bt_list, list) { list_del(&bt->list); free(bt); } graph_destroy(&graph->ug); free(graph); } graph_remove_task(); close_data_file(opts, &handle); return 0; } uftrace-0.9.3/cmds/info.c000066400000000000000000000647131351236475300152250ustar00rootroot00000000000000/* * uftrace info command related routines * * Copyright (C) 2014-2018, LG Electronics, Namhyung Kim * * Released under the GPL v2. */ #include #include #include #include #include #include #include #include #include #include #include "uftrace.h" #include "libmcount/mcount.h" #include "utils/utils.h" #include "utils/filter.h" #include "utils/symbol.h" #include "utils/fstack.h" #include "version.h" #define BUILD_ID_SIZE 20 #define BUILD_ID_STR_SIZE (BUILD_ID_SIZE * 2 + 1) struct read_handler_arg { struct uftrace_data *handle; char buf[PATH_MAX]; }; struct fill_handler_arg { int fd; int exit_status; struct opts *opts; struct rusage *rusage; char *elapsed_time; char buf[PATH_MAX]; }; static char *copy_info_str(char *src) { char *dst = xstrdup(src); size_t len = strlen(dst); if (dst[len-1] == '\n') dst[len-1] = '\0'; return dst; } static int fill_exe_name(void *arg) { struct fill_handler_arg *fha = arg; char *exename; exename = realpath(fha->opts->exename, fha->buf); if (exename == NULL) exename = fha->opts->exename; return dprintf(fha->fd, "exename:%s\n", exename); } static int read_exe_name(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "exename:", 8)) return -1; info->exename = copy_info_str(&buf[8]); return 0; } static int fill_exe_build_id(void *arg) { struct fill_handler_arg *fha = arg; unsigned char build_id[BUILD_ID_SIZE]; char build_id_str[BUILD_ID_STR_SIZE]; struct uftrace_elf_data elf; struct uftrace_elf_iter iter; bool found_build_id = false; int offset; if (elf_init(fha->opts->exename, &elf) < 0) return -1; elf_for_each_shdr(&elf, &iter) { char *str; if (iter.shdr.sh_type != SHT_NOTE) continue; /* there can be more than one note sections */ str = elf_get_name(&elf, &iter, iter.shdr.sh_name); if (!strcmp(str, ".note.gnu.build-id")) { found_build_id = true; break; } } if (!found_build_id) { pr_dbg("cannot find build-id section\n"); return -1; } elf_for_each_note(&elf, &iter) { if (iter.nhdr.n_type != NT_GNU_BUILD_ID) continue; if (!strcmp(iter.note_name, "GNU")) { memcpy(build_id, iter.note_desc, BUILD_ID_SIZE); break; } } elf_finish(&elf); for (offset = 0; offset < BUILD_ID_SIZE; offset++) { unsigned char c = build_id[offset]; sprintf(&build_id_str[offset*2], "%02x", c); } build_id_str[BUILD_ID_STR_SIZE - 1] = '\0'; return dprintf(fha->fd, "build_id:%s\n", build_id_str); } static int convert_to_int(unsigned char hex) { if (!isxdigit(hex)) return -1; if (hex >= '0' && hex <= '9') return hex - '0'; if (hex >= 'a' && hex <= 'f') return hex - 'a' + 10; if (hex >= 'A' && hex <= 'F') return hex - 'A' + 10; return -1; } static int read_exe_build_id(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char build_id_str[BUILD_ID_STR_SIZE]; char *buf = rha->buf; int i; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "build_id:", 9)) return -1; memcpy(build_id_str, &buf[9], BUILD_ID_STR_SIZE - 1); build_id_str[BUILD_ID_STR_SIZE - 1] = '\0'; for (i = 0; i < BUILD_ID_SIZE; i++) { int c1 = convert_to_int(build_id_str[i*2]); int c2 = convert_to_int(build_id_str[i*2 + 1]); if (c1 < 0 || c2 < 0) return -1; info->build_id[i] = c1 << 4 | c2; } return 0; } static int fill_exit_status(void *arg) { struct fill_handler_arg *fha = arg; return dprintf(fha->fd, "exit_status:%d\n", fha->exit_status); } static int read_exit_status(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "exit_status:", 12)) return -1; sscanf(&buf[12], "%d", &info->exit_status); return 0; } static int fill_cmdline(void *arg) { struct fill_handler_arg *fha = arg; char *buf = fha->buf; FILE *fp; int ret, i; char *p; fp = fopen("/proc/self/cmdline", "r"); if (fp == NULL) return -1; ret = fread(buf, 1, sizeof(fha->buf), fp); fclose(fp); if (ret < 0) return ret; /* cmdline separated by NUL character - convert to space */ for (i = 0, p = buf; i < ret; i++, p++) { if (*p == '\0') *p = ' '; } p = strquote(buf, &ret); p[ret - 1] = '\n'; if ((write(fha->fd, "cmdline:", 8) < 8) || (write(fha->fd, p, ret) < ret)) { free(p); return -1; } free(p); return ret; } static int read_cmdline(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "cmdline:", 8)) return -1; info->cmdline = copy_info_str(&buf[8]); return 0; } static int fill_cpuinfo(void *arg) { struct fill_handler_arg *fha = arg; unsigned long nr_possible; unsigned long nr_online; nr_possible = sysconf(_SC_NPROCESSORS_CONF); nr_online = sysconf(_SC_NPROCESSORS_ONLN); dprintf(fha->fd, "cpuinfo:lines=2\n"); dprintf(fha->fd, "cpuinfo:nr_cpus=%lu / %lu (online/possible)\n", nr_online, nr_possible); return arch_fill_cpuinfo_model(fha->fd); } static int read_cpuinfo(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; int i, lines; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "cpuinfo:", 8)) return -1; if (sscanf(&buf[8], "lines=%d\n", &lines) == EOF) return -1; for (i = 0; i < lines; i++) { if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "cpuinfo:", 8)) return -1; if (!strncmp(&buf[8], "nr_cpus=", 8)) { sscanf(&buf[8], "nr_cpus=%d / %d\n", &info->nr_cpus_online, &info->nr_cpus_possible); } else if (!strncmp(&buf[8], "desc=", 5)) { info->cpudesc = copy_info_str(&buf[13]); /* guess CPU arch from the description */ if (!strncmp(info->cpudesc, "ARMv6", 5) || !strncmp(info->cpudesc, "ARMv7", 5)) { handle->arch = UFT_CPU_ARM; } else if (!strncmp(info->cpudesc, "ARM64", 5)) { handle->arch = UFT_CPU_AARCH64; } else if (data_is_lp64(handle)) { handle->arch = UFT_CPU_X86_64; } else { handle->arch = UFT_CPU_I386; } } } return 0; } static int fill_meminfo(void *arg) { struct fill_handler_arg *fha = arg; long mem_total = 0; long mem_total_small; long mem_free = 0; long mem_free_small; char *units[] = { "KB", "MB", "GB", "TB" }; char *unit; char *buf = fha->buf; size_t i; FILE *fp; fp = fopen("/proc/meminfo", "r"); if (fp == NULL) return -1; while (fgets(buf, sizeof(fha->buf), fp) != NULL) { if (!strncmp(buf, "MemTotal:", 9)) sscanf(&buf[10], "%ld", &mem_total); else if (!strncmp(buf, "MemFree:", 8)) sscanf(&buf[9], "%ld", &mem_free); else break; } fclose(fp); mem_total_small = (mem_total % 1024) / 103; /* 103 ~= 1024 / 10 */ mem_free_small = (mem_free % 1024) / 103; for (i = 0; i < ARRAY_SIZE(units); i++) { unit = units[i]; if (mem_total < 1024) break; mem_total_small = (mem_total % 1024) / 103; mem_free_small = (mem_free % 1024) / 103; mem_total >>= 10; mem_free >>= 10; } dprintf(fha->fd, "meminfo:%ld.%ld / %ld.%ld %s (free / total)\n", mem_free, mem_free_small, mem_total, mem_total_small, unit); return 0; } static int read_meminfo(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "meminfo:", 8)) return -1; info->meminfo = copy_info_str(&buf[8]); return 0; } static int fill_osinfo(void *arg) { struct fill_handler_arg *fha = arg; struct utsname uts; char *buf = fha->buf; FILE *fp; int ret = -1; uname(&uts); dprintf(fha->fd, "osinfo:lines=3\n"); dprintf(fha->fd, "osinfo:kernel=%s %s\n", uts.sysname, uts.release); dprintf(fha->fd, "osinfo:hostname=%s\n", uts.nodename); fp = fopen("/etc/os-release", "r"); if (fp != NULL) { while (fgets(buf, sizeof(fha->buf), fp) != NULL) { if (!strncmp(buf, "PRETTY_NAME=", 12)) { dprintf(fha->fd, "osinfo:distro=%s", &buf[12]); ret = 0; break; } } fclose(fp); return ret; } fp = fopen("/etc/lsb-release", "r"); if (fp != NULL) { while (fgets(buf, sizeof(fha->buf), fp) != NULL) { if (!strncmp(buf, "DISTRIB_DESCRIPTION=", 20)) { dprintf(fha->fd, "osinfo:distro=%s", &buf[20]); ret = 0; break; } } fclose(fp); return ret; } dprintf(fha->fd, "osinfo:distro=\"Unknown\"\n"); return 0; } static int read_osinfo(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; int i, lines; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "osinfo:", 7)) return -1; if (sscanf(&buf[7], "lines=%d\n", &lines) == EOF) return -1; for (i = 0; i < lines; i++) { if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "osinfo:", 7)) return -1; if (!strncmp(&buf[7], "kernel=", 7)) { info->kernel = copy_info_str(&buf[14]); } else if (!strncmp(&buf[7], "hostname=", 9)) { info->hostname = copy_info_str(&buf[16]); } else if (!strncmp(&buf[7], "distro=", 7)) { info->distro = copy_info_str(&buf[14]); } } return 0; } struct tid_list { int nr; int *tid; }; static int build_tid_list(struct uftrace_task *t, void *arg) { struct tid_list *list = arg; list->nr++; list->tid = xrealloc(list->tid, list->nr * sizeof(*list->tid)); list->tid[list->nr - 1] = t->tid; return 0; } static int fill_taskinfo(void *arg) { struct fill_handler_arg *fha = arg; bool first = true; struct tid_list tlist = { .nr = 0, }; struct uftrace_session_link link = { .root = RB_ROOT, .tasks = RB_ROOT, }; int i; if (read_task_txt_file(&link, fha->opts->dirname, false, false, false) < 0 && read_task_file(&link, fha->opts->dirname, false, false, false) < 0) return -1; walk_tasks(&link, build_tid_list, &tlist); dprintf(fha->fd, "taskinfo:lines=2\n"); dprintf(fha->fd, "taskinfo:nr_tid=%d\n", tlist.nr); dprintf(fha->fd, "taskinfo:tids="); for (i = 0; i < tlist.nr; i++) { dprintf(fha->fd, "%s%d", first ? "" : ",", tlist.tid[i]); first = false; } dprintf(fha->fd, "\n"); delete_sessions(&link); free(tlist.tid); return 0; } static int read_taskinfo(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; int i, lines; int ret = -1; char *buf = NULL; size_t len = 0; if (getline(&buf, &len, handle->fp) < 0) goto out; if (strncmp(buf, "taskinfo:", 9)) goto out; if (sscanf(&buf[9], "lines=%d\n", &lines) == EOF) goto out; for (i = 0; i < lines; i++) { if (getline(&buf, &len, handle->fp) < 0) goto out; if (strncmp(buf, "taskinfo:", 9)) goto out; if (!strncmp(&buf[9], "nr_tid=", 7)) { info->nr_tid = strtol(&buf[16], NULL, 10); } else if (!strncmp(&buf[9], "tids=", 5)) { char *tids_str = &buf[14]; char *endp = tids_str; int *tids = xcalloc(sizeof(*tids), info->nr_tid); int nr_tid = 0; while (*endp != '\n') { int tid = strtol(tids_str, &endp, 10); tids[nr_tid++] = tid; if (*endp != ',' && *endp != '\n') { free(tids); goto out; } tids_str = endp + 1; } info->tids = tids; assert(nr_tid == info->nr_tid); } else goto out; } ret = 0; out: free(buf); return ret; } static int fill_usageinfo(void *arg) { struct fill_handler_arg *fha = arg; struct rusage *r = fha->rusage; struct rusage zero = {}; if (!memcmp(r, &zero, sizeof(*r))) return -1; dprintf(fha->fd, "usageinfo:lines=6\n"); dprintf(fha->fd, "usageinfo:systime=%lu.%06lu\n", r->ru_stime.tv_sec, r->ru_stime.tv_usec); dprintf(fha->fd, "usageinfo:usrtime=%lu.%06lu\n", r->ru_utime.tv_sec, r->ru_utime.tv_usec); dprintf(fha->fd, "usageinfo:ctxsw=%ld / %ld (voluntary / involuntary)\n", r->ru_nvcsw, r->ru_nivcsw); dprintf(fha->fd, "usageinfo:maxrss=%ld\n", r->ru_maxrss); dprintf(fha->fd, "usageinfo:pagefault=%ld / %ld (major / minor)\n", r->ru_majflt, r->ru_minflt); dprintf(fha->fd, "usageinfo:iops=%ld / %ld (read / write)\n", r->ru_inblock, r->ru_oublock); return 0; } static int read_usageinfo(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; int i, lines; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "usageinfo:", 10)) return -1; if (sscanf(&buf[10], "lines=%d\n", &lines) == EOF) return -1; for (i = 0; i < lines; i++) { if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "usageinfo:", 10)) return -1; if (!strncmp(&buf[10], "systime=", 8)) sscanf(&buf[18], "%lf", &info->stime); else if (!strncmp(&buf[10], "usrtime=", 8)) sscanf(&buf[18], "%lf", &info->utime); else if (!strncmp(&buf[10], "ctxsw=", 6)) sscanf(&buf[16], "%ld / %ld", &info->vctxsw, &info->ictxsw); else if (!strncmp(&buf[10], "maxrss=", 7)) sscanf(&buf[17], "%ld", &info->maxrss); else if (!strncmp(&buf[10], "pagefault=", 10)) sscanf(&buf[20], "%ld / %ld", &info->major_fault, &info->minor_fault); else if (!strncmp(&buf[10], "iops=", 5)) sscanf(&buf[15], "%ld / %ld", &info->rblock, &info->wblock); } return 0; } static int fill_loadinfo(void *arg) { struct fill_handler_arg *fha = arg; FILE *fp = fopen("/proc/loadavg", "r"); float loadavg[3]; if (fp == NULL) return -1; if (fscanf(fp, "%f %f %f", &loadavg[0], &loadavg[1], &loadavg[2]) != 3) { fclose(fp); return -1; } dprintf(fha->fd, "loadinfo:%.02f / %.02f / %.02f\n", loadavg[0], loadavg[1], loadavg[2]); fclose(fp); return 0; } static int read_loadinfo(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "loadinfo:", 9)) return -1; sscanf(&buf[9], "%f / %f / %f", &info->load1, &info->load5, &info->load15); return 0; } static int fill_arg_spec(void *arg) { struct fill_handler_arg *fha = arg; char *argspec = fha->opts->args; char *retspec = fha->opts->retval; int n; n = extract_trigger_args(&argspec, &retspec, fha->opts->trigger); if (n == 0 && !fha->opts->auto_args) return -1; dprintf(fha->fd, "argspec:lines=%d\n", n + 3 + !!fha->opts->auto_args); if (argspec) { dprintf(fha->fd, "argspec:%s\n", argspec); free(argspec); } if (retspec) { dprintf(fha->fd, "retspec:%s\n", retspec); free(retspec); } dprintf(fha->fd, "argauto:%s\n", get_auto_argspec_str()); dprintf(fha->fd, "retauto:%s\n", get_auto_retspec_str()); dprintf(fha->fd, "enumauto:%s\n", get_auto_enum_str()); if (fha->opts->auto_args) dprintf(fha->fd, "auto-args:1\n"); return 0; } static int read_arg_spec(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; int i, lines; int ret = -1; char *buf = NULL; size_t len = 0; if (getline(&buf, &len, handle->fp) < 0) goto out; if (strncmp(buf, "argspec:", 8)) goto out; /* old format only has argspec */ if (strncmp(&buf[8], "lines", 5)) { info->argspec = copy_info_str(&buf[8]); ret = 0; goto out; } if (sscanf(&buf[8], "lines=%d\n", &lines) == EOF) goto out; for (i = 0; i < lines; i++) { if (getline(&buf, &len, handle->fp) < 0) goto out; if (!strncmp(buf, "argspec:", 8)) info->argspec = copy_info_str(&buf[8]); else if (!strncmp(buf, "retspec:", 8)) info->retspec = copy_info_str(&buf[8]); else if (!strncmp(buf, "argauto:", 8)) info->autoarg = copy_info_str(&buf[8]); else if (!strncmp(buf, "retauto:", 8)) info->autoret = copy_info_str(&buf[8]); else if (!strncmp(buf, "enumauto:", 9)) info->autoenum = copy_info_str(&buf[9]); else if (!strncmp(buf, "auto-args:1", 11)) info->auto_args_enabled = 1; else goto out; } ret = 0; out: free(buf); return ret; } static int fill_record_date(void *arg) { struct fill_handler_arg *fha = arg; time_t current_time; time(¤t_time); dprintf(fha->fd, "record_date:%s", ctime(¤t_time)); dprintf(fha->fd, "elapsed_time:%s\n", fha->elapsed_time); return 0; } static int read_record_date(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "record_date:", 12)) return -1; info->record_date = copy_info_str(&buf[12]); if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "elapsed_time:", 13)) return -1; info->elapsed_time = copy_info_str(&buf[13]); return 0; } static int fill_pattern_type(void *arg) { struct fill_handler_arg *fha = arg; dprintf(fha->fd, "pattern_type:%s\n", get_filter_pattern(fha->opts->patt_type)); return 0; } static int read_pattern_type(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; size_t len; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "pattern_type:", 13)) return -1; len = strlen(&buf[13]); if (buf[13 + len - 1] == '\n') buf[13 + len - 1] = '\0'; info->patt_type = parse_filter_pattern(&buf[13]); return 0; } static int fill_uftrace_version(void *arg) { struct fill_handler_arg *fha = arg; return dprintf(fha->fd, "uftrace_version:%s\n", UFTRACE_VERSION); } static int read_uftrace_version(void *arg) { struct read_handler_arg *rha = arg; struct uftrace_data *handle = rha->handle; struct uftrace_info *info = &handle->info; char *buf = rha->buf; if (fgets(buf, sizeof(rha->buf), handle->fp) == NULL) return -1; if (strncmp(buf, "uftrace_version:", 16)) return -1; info->uftrace_version = copy_info_str(&buf[16]); return 0; } struct uftrace_info_handler { enum uftrace_info_bits bit; int (*handler)(void *arg); }; void fill_uftrace_info(uint64_t *info_mask, int fd, struct opts *opts, int status, struct rusage *rusage, char *elapsed_time) { size_t i; off_t offset; struct fill_handler_arg arg = { .fd = fd, .opts = opts, .exit_status = status, .rusage = rusage, .elapsed_time = elapsed_time, }; struct uftrace_info_handler fill_handlers[] = { { EXE_NAME, fill_exe_name }, { EXE_BUILD_ID, fill_exe_build_id }, { EXIT_STATUS, fill_exit_status }, { CMDLINE, fill_cmdline }, { CPUINFO, fill_cpuinfo }, { MEMINFO, fill_meminfo }, { OSINFO, fill_osinfo }, { TASKINFO, fill_taskinfo }, { USAGEINFO, fill_usageinfo }, { LOADINFO, fill_loadinfo }, { ARG_SPEC, fill_arg_spec }, { RECORD_DATE, fill_record_date }, { PATTERN_TYPE, fill_pattern_type }, { VERSION, fill_uftrace_version }, }; for (i = 0; i < ARRAY_SIZE(fill_handlers); i++) { errno = 0; offset = lseek(fd, 0, SEEK_CUR); if (offset == (off_t)-1 && errno) { pr_dbg("skip info due to failed lseek: %m\n"); continue; } if (fill_handlers[i].handler(&arg) < 0) { /* ignore failed info */ errno = 0; if (lseek(fd, offset, SEEK_SET) == (off_t)-1 && errno) pr_warn("fail to reset uftrace info: %m\n"); continue; } *info_mask |= (1UL << fill_handlers[i].bit); } } int read_uftrace_info(uint64_t info_mask, struct uftrace_data *handle) { size_t i; struct read_handler_arg arg = { .handle = handle, }; struct uftrace_info_handler read_handlers[] = { { EXE_NAME, read_exe_name }, { EXE_BUILD_ID, read_exe_build_id }, { EXIT_STATUS, read_exit_status }, { CMDLINE, read_cmdline }, { CPUINFO, read_cpuinfo }, { MEMINFO, read_meminfo }, { OSINFO, read_osinfo }, { TASKINFO, read_taskinfo }, { USAGEINFO, read_usageinfo }, { LOADINFO, read_loadinfo }, { ARG_SPEC, read_arg_spec }, { RECORD_DATE, read_record_date }, { PATTERN_TYPE, read_pattern_type }, { VERSION, read_uftrace_version }, }; memset(&handle->info, 0, sizeof(handle->info)); for (i = 0; i < ARRAY_SIZE(read_handlers); i++) { if (!(info_mask & (1UL << read_handlers[i].bit))) continue; if (read_handlers[i].handler(&arg) < 0) { pr_dbg("error during read uftrace info (%x)\n", (1U << read_handlers[i].bit)); return -1; } } return 0; } void clear_uftrace_info(struct uftrace_info *info) { free(info->exename); free(info->cmdline); free(info->cpudesc); free(info->meminfo); free(info->kernel); free(info->hostname); free(info->distro); free(info->tids); free(info->argspec); free(info->record_date); free(info->elapsed_time); free(info->uftrace_version); } static void print_info(void *unused, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(outfp, fmt, ap); va_end(ap); } void process_uftrace_info(struct uftrace_data *handle, struct opts *opts, void (*process)(void *data, const char *fmt, ...), void *data) { char buf[PATH_MAX]; struct stat statbuf; const char *fmt = "# %-20s: %s\n"; uint64_t info_mask = handle->hdr.info_mask; struct uftrace_info *info = &handle->info; if (info_mask == 0) return; snprintf(buf, sizeof(buf), "%s/info", opts->dirname); if (stat(buf, &statbuf) < 0) return; process(data, "# system information\n"); process(data, "# ==================\n"); if (info_mask & (1UL << VERSION)) process(data, fmt, "program version", info->uftrace_version); if (info_mask & (1UL << RECORD_DATE)) process(data, fmt, "recorded on", info->record_date); else process(data, "# %-20s: %s", "recorded on", ctime(&statbuf.st_mtime)); if (info_mask & (1UL << CMDLINE)) process(data, fmt, "cmdline", info->cmdline); if (info_mask & (1UL << CPUINFO)) { process(data, fmt, "cpu info", info->cpudesc); process(data, "# %-20s: %d / %d (online / possible)\n", "number of cpus", info->nr_cpus_online, info->nr_cpus_possible); } if (info_mask & (1UL << MEMINFO)) process(data, fmt, "memory info", info->meminfo); if (info_mask & (1UL << LOADINFO)) process(data, "# %-20s: %.02f / %.02f / %.02f (1 / 5 / 15 min)\n", "system load", info->load1, info->load5, info->load15); if (info_mask & (1UL << OSINFO)) { process(data, fmt, "kernel version", info->kernel); process(data, fmt, "hostname", info->hostname); process(data, fmt, "distro", info->distro); } process(data, "#\n"); process(data, "# process information\n"); process(data, "# ===================\n"); if (info_mask & (1UL << TASKINFO)) { int i; int nr = info->nr_tid; bool first = true; struct uftrace_task *task; char *task_list; int sz, len; char *p; /* ignore errors */ read_task_txt_file(&handle->sessions, opts->dirname, false, false, false); process(data, "# %-20s: %d\n", "number of tasks", nr); if (handle->hdr.feat_mask & PERF_EVENT) { if (setup_perf_data(handle) == 0) update_perf_task_comm(handle); } sz = nr * 32; /* 32 > strlen("tid (comm)") */ len = 0; p = task_list = xmalloc(sz); for (i = 0; i < nr; i++) { int tid = info->tids[i]; task = find_task(&handle->sessions, tid); len = snprintf(p, sz, "%s%d(%s)", first ? "" : ", ", tid, task ? task->comm : ""); p += len; sz -= len; first = false; } process(data, "# %-20s: %s\n", "task list", task_list); free(task_list); } if (info_mask & (1UL << EXE_NAME)) process(data, fmt, "exe image", info->exename); if (info_mask & (1UL << EXE_BUILD_ID)) { int i; char bid[BUILD_ID_SIZE * 2 + 1]; for (i = 0; i < BUILD_ID_SIZE; i++) snprintf(bid + i * 2, 3, "%02x", info->build_id[i]); process(data, "# %-20s: %s\n", "build id", bid); } if (info_mask & (1UL << ARG_SPEC)) { if (info->argspec) process(data, fmt, "arguments", info->argspec); if (info->retspec) process(data, fmt, "return values", info->retspec); if (info->auto_args_enabled) process(data, fmt, "auto-args", "true"); } if (info_mask & (1UL << PATTERN_TYPE)) process(data, fmt, "pattern", get_filter_pattern(info->patt_type)); if (info_mask & (1UL << EXIT_STATUS)) { int status = info->exit_status; if (status == UFTRACE_EXIT_FINISHED) { snprintf(buf, sizeof(buf), "terminated by finish trigger"); } else if (WIFEXITED(status)) { snprintf(buf, sizeof(buf), "exited with code: %d", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { snprintf(buf, sizeof(buf), "terminated by signal: %d (%s)", WTERMSIG(status), strsignal(WTERMSIG(status))); } else { snprintf(buf, sizeof(buf), "unknown exit status: %d", status); } process(data, fmt, "exit status", buf); } if (info_mask & (1UL << RECORD_DATE)) process(data, fmt, "elapsed time", info->elapsed_time); if (info_mask & (1UL << USAGEINFO)) { process(data, "# %-20s: %.3lf / %.3lf sec (sys / user)\n", "cpu time", info->stime, info->utime); process(data, "# %-20s: %ld / %ld (voluntary / involuntary)\n", "context switch", info->vctxsw, info->ictxsw); process(data, "# %-20s: %ld KB\n", "max rss", info->maxrss); process(data, "# %-20s: %ld / %ld (major / minor)\n", "page fault", info->major_fault, info->minor_fault); process(data, "# %-20s: %ld / %ld (read / write)\n", "disk iops", info->rblock, info->wblock); } process(data, "\n"); } int command_info(int argc, char *argv[], struct opts *opts) { int ret; struct uftrace_data handle; ret = open_info_file(opts, &handle); if (ret < 0) { pr_warn("cannot open record data: %s: %m\n", opts->dirname); return -1; } if (opts->print_symtab) { struct symtabs symtabs = { .dirname = opts->dirname, .filename = opts->exename, .flags = SYMTAB_FL_USE_SYMFILE | SYMTAB_FL_DEMANGLE, }; struct uftrace_module *mod; if (!opts->exename) { pr_use("Usage: uftrace info --symbols [COMMAND]\n"); return -1; } mod = load_module_symtab(&symtabs, symtabs.filename); if (mod == NULL) goto out; print_symtab(&mod->symtab); unload_module_symtabs(); goto out; } fstack_setup_filters(opts, &handle); process_uftrace_info(&handle, opts, print_info, NULL); out: close_data_file(opts, &handle); return 0; } uftrace-0.9.3/cmds/live.c000066400000000000000000000061411351236475300152200ustar00rootroot00000000000000#include #include #include #include #include #include #include "uftrace.h" #include "utils/utils.h" #include "utils/fstack.h" #include "utils/kernel.h" #include "libmcount/mcount.h" static char *tmp_dirname; static void cleanup_tempdir(void) { if (!tmp_dirname) return; remove_directory(tmp_dirname); tmp_dirname = NULL; } static void reset_live_opts(struct opts *opts) { /* this is needed to set display_depth at replay */ live_disabled = opts->disabled; /* * These options are handled in record and no need to do it in * replay again. */ free(opts->filter); opts->filter = NULL; free(opts->caller); opts->caller = NULL; opts->depth = MCOUNT_DEFAULT_DEPTH; opts->disabled = false; opts->no_event = false; } static void sigsegv_handler(int sig) { pr_warn("Segmentation fault\n"); cleanup_tempdir(); raise(sig); } static bool can_skip_replay(struct opts *opts, int record_result) { if (opts->nop) return true; return false; } static void setup_child_environ(struct opts *opts) { char *old_preload, *libpath; #ifdef INSTALL_LIB_PATH if (!opts->lib_path) { char *envbuf = getenv("LD_LIBRARY_PATH"); if (envbuf) { envbuf = xstrdup(envbuf); libpath = strjoin(envbuf, INSTALL_LIB_PATH, ":"); setenv("LD_LIBRARY_PATH", libpath, 1); free(libpath); } else { setenv("LD_LIBRARY_PATH", INSTALL_LIB_PATH, 1); } } #endif libpath = get_libmcount_path(opts); if (libpath == NULL) pr_err_ns("cannot found libmcount.so\n"); old_preload = getenv("LD_PRELOAD"); if (old_preload) { size_t len = strlen(libpath) + strlen(old_preload) + 2; char *preload = xmalloc(len); snprintf(preload, len, "%s:%s", libpath, old_preload); setenv("LD_PRELOAD", preload, 1); free(preload); } else setenv("LD_PRELOAD", libpath, 1); free(libpath); } int command_live(int argc, char *argv[], struct opts *opts) { char template[32] = "/tmp/uftrace-live-XXXXXX"; int fd; struct sigaction sa = { .sa_flags = SA_RESETHAND, }; int ret; umask(022); fd = mkstemp(template); if (fd < 0) pr_err("cannot create temp name"); close(fd); unlink(template); tmp_dirname = template; atexit(cleanup_tempdir); sa.sa_handler = sigsegv_handler; sigfillset(&sa.sa_mask); sigaction(SIGSEGV, &sa, NULL); opts->dirname = template; if (opts->list_event) { if (geteuid() == 0) list_kernel_events(); if (fork() == 0) { setup_child_environ(opts); setenv("UFTRACE_LIST_EVENT", "1", 1); execv(opts->exename, argv); abort(); } return 0; } ret = command_record(argc, argv, opts); if (!can_skip_replay(opts, ret)) { int ret2; reset_live_opts(opts); if (opts->use_pager) start_pager(setup_pager()); pr_dbg("live-record finished.. \n"); if (opts->report) { pr_out("#\n# uftrace report\n#\n"); ret2 = command_report(argc, argv, opts); if (ret == UFTRACE_EXIT_SUCCESS) ret = ret2; pr_out("\n#\n# uftrace replay\n#\n"); } pr_dbg("start live-replaying...\n"); ret2 = command_replay(argc, argv, opts); if (ret == UFTRACE_EXIT_SUCCESS) ret = ret2; } cleanup_tempdir(); return ret; } uftrace-0.9.3/cmds/record.c000066400000000000000000001362331351236475300155450ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "uftrace.h" #include "libmcount/mcount.h" #include "utils/utils.h" #include "utils/symbol.h" #include "utils/list.h" #include "utils/filter.h" #include "utils/kernel.h" #include "utils/perf.h" #define SHMEM_NAME_SIZE (64 - (int)sizeof(struct list_head)) struct shmem_list { struct list_head list; char id[SHMEM_NAME_SIZE]; }; static LIST_HEAD(shmem_list_head); static LIST_HEAD(shmem_need_unlink); struct buf_list { struct list_head list; int tid; void *shmem_buf; }; static LIST_HEAD(buf_free_list); static LIST_HEAD(buf_write_list); /* currently active writers */ static LIST_HEAD(writer_list); static pthread_mutex_t free_list_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t write_list_lock = PTHREAD_MUTEX_INITIALIZER; static bool buf_done; static int thread_ctl[2]; static bool has_perf_event; static bool has_sched_event; static bool finish_received; static bool can_use_fast_libmcount(struct opts *opts) { if (debug) return false; if (opts->depth != MCOUNT_DEFAULT_DEPTH) return false; if (getenv("UFTRACE_FILTER") || getenv("UFTRACE_TRIGGER") || getenv("UFTRACE_ARGUMENT") || getenv("UFTRACE_RETVAL") || getenv("UFTRACE_PATCH") || getenv("UFTRACE_SCRIPT") || getenv("UFTRACE_AUTO_ARGS") || getenv("UFTRACE_WATCH") || getenv("UFTRACE_CALLER") || getenv("UFTRACE_SIGNAL")) return false; return true; } static char *build_debug_domain_string(void) { int i, d; static char domain[2*DBG_DOMAIN_MAX + 1]; for (i = 0, d = 0; d < DBG_DOMAIN_MAX; d++) { if (dbg_domain[d]) { domain[i++] = DBG_DOMAIN_STR[d]; domain[i++] = dbg_domain[d] + '0'; } } domain[i] = '\0'; return domain; } char * get_libmcount_path(struct opts *opts) { char *libmcount, *lib = xmalloc(PATH_MAX); bool must_use_multi_thread = has_dependency(opts->exename, "libpthread.so.0"); if (opts->nop) { libmcount = "libmcount-nop.so"; } else if (opts->libmcount_single && !must_use_multi_thread) { if (can_use_fast_libmcount(opts)) libmcount = "libmcount-fast-single.so"; else libmcount = "libmcount-single.so"; } else { if (must_use_multi_thread && opts->libmcount_single) pr_dbg("--libmcount-single is off because it uses pthread\n"); if (can_use_fast_libmcount(opts)) libmcount = "libmcount-fast.so"; else libmcount = "libmcount.so"; } if (opts->lib_path) { snprintf(lib, PATH_MAX, "%s/libmcount/%s", opts->lib_path, libmcount); if (access(lib, F_OK) == 0) { return lib; } else if (errno == ENOENT) { snprintf(lib, PATH_MAX, "%s/%s", opts->lib_path, libmcount); if (access(lib, F_OK) == 0) return lib; } free(lib); return NULL; } #ifdef INSTALL_LIB_PATH /* try first to load libmcount from the installtion path */ snprintf(lib, PATH_MAX, "%s/%s", INSTALL_LIB_PATH, libmcount); if (access(lib, F_OK) == 0) return lib; #endif strcpy(lib, libmcount); return lib; } void put_libmcount_path(char *libpath) { free(libpath); } static void setup_child_environ(struct opts *opts, int argc, char *argv[]) { char buf[PATH_MAX]; char *old_preload, *libpath; #ifdef INSTALL_LIB_PATH if (!opts->lib_path) { char *envbuf = getenv("LD_LIBRARY_PATH"); if (envbuf) { envbuf = xstrdup(envbuf); libpath = strjoin(envbuf, INSTALL_LIB_PATH, ":"); setenv("LD_LIBRARY_PATH", libpath, 1); free(libpath); } else { setenv("LD_LIBRARY_PATH", INSTALL_LIB_PATH, 1); } } #endif if (opts->filter) { char *filter_str = uftrace_clear_kernel(opts->filter); if (filter_str) { setenv("UFTRACE_FILTER", filter_str, 1); free(filter_str); } } if (opts->trigger) { char *trigger_str = uftrace_clear_kernel(opts->trigger); if (trigger_str) { setenv("UFTRACE_TRIGGER", trigger_str, 1); free(trigger_str); } } if (opts->args) { char *arg_str = uftrace_clear_kernel(opts->args); if (arg_str) { setenv("UFTRACE_ARGUMENT", arg_str, 1); free(arg_str); } } if (opts->retval) { char *retval_str = uftrace_clear_kernel(opts->retval); if (retval_str) { setenv("UFTRACE_RETVAL", retval_str, 1); free(retval_str); } } if (opts->auto_args) setenv("UFTRACE_AUTO_ARGS", "1", 1); if (opts->patch) { char *patch_str = uftrace_clear_kernel(opts->patch); if (patch_str) { setenv("UFTRACE_PATCH", patch_str, 1); free(patch_str); } if (opts->size_filter) { snprintf(buf, sizeof(buf), "%d", opts->size_filter); setenv("UFTRACE_PATCH_SIZE", buf, 1); } } if (opts->event) { char *event_str = uftrace_clear_kernel(opts->event); if (event_str) { setenv("UFTRACE_EVENT", event_str, 1); free(event_str); } } if (opts->watch) setenv("UFTRACE_WATCH", opts->watch, 1); if (opts->depth != OPT_DEPTH_DEFAULT) { snprintf(buf, sizeof(buf), "%d", opts->depth); setenv("UFTRACE_DEPTH", buf, 1); } if (opts->max_stack != OPT_RSTACK_DEFAULT) { snprintf(buf, sizeof(buf), "%d", opts->max_stack); setenv("UFTRACE_MAX_STACK", buf, 1); } if (opts->threshold) { snprintf(buf, sizeof(buf), "%"PRIu64, opts->threshold); setenv("UFTRACE_THRESHOLD", buf, 1); } if (opts->caller) { char *caller_str = uftrace_clear_kernel(opts->caller); if (caller_str) { setenv("UFTRACE_CALLER", caller_str, 1); free(caller_str); } } if (opts->libcall) { setenv("UFTRACE_PLTHOOK", "1", 1); if (opts->want_bind_not) { /* do not update GOTPLT after resolving symbols */ setenv("LD_BIND_NOT", "1", 1); } if (opts->nest_libcall) setenv("UFTRACE_NEST_LIBCALL", "1", 1); } if (strcmp(opts->dirname, UFTRACE_DIR_NAME)) setenv("UFTRACE_DIR", opts->dirname, 1); if (opts->bufsize != SHMEM_BUFFER_SIZE) { snprintf(buf, sizeof(buf), "%lu", opts->bufsize); setenv("UFTRACE_BUFFER", buf, 1); } if (opts->logfile) { snprintf(buf, sizeof(buf), "%d", fileno(logfp)); setenv("UFTRACE_LOGFD", buf, 1); } setenv("UFTRACE_SHMEM", "1", 1); if (debug) { snprintf(buf, sizeof(buf), "%d", debug); setenv("UFTRACE_DEBUG", buf, 1); setenv("UFTRACE_DEBUG_DOMAIN", build_debug_domain_string(), 1); } if (opts->disabled) setenv("UFTRACE_DISABLED", "1", 1); if (log_color == COLOR_ON) { snprintf(buf, sizeof(buf), "%d", log_color); setenv("UFTRACE_COLOR", buf, 1); } snprintf(buf, sizeof(buf), "%d", demangler); setenv("UFTRACE_DEMANGLE", buf, 1); if ((opts->kernel || has_kernel_event(opts->event)) && check_kernel_pid_filter()) setenv("UFTRACE_KERNEL_PID_UPDATE", "1", 1); if (opts->script_file) setenv("UFTRACE_SCRIPT", opts->script_file, 1); if (opts->patt_type != PATT_REGEX) setenv("UFTRACE_PATTERN", get_filter_pattern(opts->patt_type), 1); if (opts->sig_trigger) setenv("UFTRACE_SIGNAL", opts->sig_trigger, 1); if (opts->srcline) setenv("UFTRACE_SRCLINE", "1", 1); if (argc > 0) { char *args = NULL; int i; for (i = 0; i < argc; i++) args = strjoin(args, argv[i], "\n"); setenv("UFTRACE_ARGS", args, 1); free(args); } /* * ----- end of option processing ----- */ libpath = get_libmcount_path(opts); if (libpath == NULL) pr_err_ns("cannot found libmcount.so\n"); pr_dbg("using %s library for tracing\n", libpath); old_preload = getenv("LD_PRELOAD"); if (old_preload) { size_t len = strlen(libpath) + strlen(old_preload) + 2; char *preload = xmalloc(len); snprintf(preload, len, "%s:%s", libpath, old_preload); setenv("LD_PRELOAD", preload, 1); free(preload); } else setenv("LD_PRELOAD", libpath, 1); put_libmcount_path(libpath); setenv("XRAY_OPTIONS", "patch_premain=false", 1); setenv("GLIBC_TUNABLES", "glibc.cpu.hwcaps=-IBT,-SHSTK", 1); } static uint64_t calc_feat_mask(struct opts *opts) { uint64_t features = 0; char *buf = NULL; glob_t g; /* mcount code creates task and sid-XXX.map files */ features |= TASK_SESSION; /* symbol file saves relative address */ features |= SYM_REL_ADDR; /* save mcount_max_stack */ features |= MAX_STACK; /* provide automatic argument/return value spec */ features |= AUTO_ARGS; if (has_perf_event) features |= PERF_EVENT; if (opts->libcall) features |= PLTHOOK; if (opts->kernel) features |= KERNEL; if (opts->args || opts->auto_args) features |= ARGUMENT; if (opts->retval || opts->auto_args) features |= RETVAL; if (opts->event) features |= EVENT; xasprintf(&buf, "%s/*.dbg", opts->dirname); if (glob(buf, GLOB_NOSORT, NULL, &g) != GLOB_NOMATCH) features |= DEBUG_INFO; globfree(&g); free(buf); return features; } static int fill_file_header(struct opts *opts, int status, struct rusage *rusage, char *elapsed_time) { int fd, efd; int ret = -1; char *filename = NULL; struct uftrace_file_header hdr; char elf_ident[EI_NIDENT]; xasprintf(&filename, "%s/info", opts->dirname); pr_dbg3("fill header (metadata) info in %s\n", filename); fd = open(filename, O_WRONLY | O_CREAT| O_TRUNC, 0644); if (fd < 0) pr_err("cannot open info file"); efd = open(opts->exename, O_RDONLY); if (efd < 0) goto close_fd; if (read(efd, elf_ident, sizeof(elf_ident)) < 0) goto close_efd; strncpy(hdr.magic, UFTRACE_MAGIC_STR, UFTRACE_MAGIC_LEN); hdr.version = UFTRACE_FILE_VERSION; hdr.header_size = sizeof(hdr); hdr.endian = elf_ident[EI_DATA]; hdr.class = elf_ident[EI_CLASS]; hdr.feat_mask = calc_feat_mask(opts); hdr.info_mask = 0; hdr.max_stack = opts->max_stack; hdr.unused1 = 0; hdr.unused2 = 0; if (write(fd, &hdr, sizeof(hdr)) != (int)sizeof(hdr)) pr_err("writing header info failed"); fill_uftrace_info(&hdr.info_mask, fd, opts, status, rusage, elapsed_time); try_write: ret = pwrite(fd, &hdr, sizeof(hdr), 0); if (ret != (int)sizeof(hdr)) { static int retry = 0; if (ret > 0 && retry++ < 3) goto try_write; pr_dbg("writing header info failed.\n"); goto close_efd; } ret = 0; close_efd: close(efd); close_fd: close(fd); free(filename); return ret; } /* size including NUL at the end */ #define MSG_ID_SIZE 36 static void parse_msg_id(char *id, uint64_t *sid, int *tid, int *seq) { uint64_t _sid; unsigned _tid; unsigned _seq; /* * parse message id of "/uftrace-SESSION-TID-SEQ". */ if (sscanf(id, "/uftrace-%016"SCNx64"-%u-%03u", &_sid, &_tid, &_seq) != 3) pr_err("parse msg id failed"); if (sid) *sid = _sid; if (tid) *tid = _tid; if (seq) *seq = _seq; } static char *make_disk_name(const char *dirname, int tid) { char *filename = NULL; xasprintf(&filename, "%s/%d.dat", dirname, tid); return filename; } static void write_buffer_file(const char *dirname, struct buf_list *buf) { int fd; char *filename; struct mcount_shmem_buffer *shmbuf = buf->shmem_buf; filename = make_disk_name(dirname, buf->tid); fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644); if (fd < 0) pr_err("open disk file"); if (write_all(fd, shmbuf->data, shmbuf->size) < 0) pr_err("write shmem buffer"); close(fd); free(filename); } static void write_buffer(struct buf_list *buf, struct opts *opts, int sock) { struct mcount_shmem_buffer *shmbuf = buf->shmem_buf; if (!opts->host) write_buffer_file(opts->dirname, buf); else send_trace_data(sock, buf->tid, shmbuf->data, shmbuf->size); shmbuf->size = 0; } struct writer_arg { struct list_head list; struct list_head bufs; struct opts *opts; struct uftrace_kernel_writer *kern; struct uftrace_perf_writer *perf; int sock; int idx; int tid; int nr_cpu; int cpus[]; }; static void write_buf_list(struct list_head *buf_head, struct opts *opts, struct writer_arg *warg) { struct buf_list *buf; list_for_each_entry(buf, buf_head, list) { struct mcount_shmem_buffer *shmbuf = buf->shmem_buf; write_buffer(buf, opts, warg->sock); /* * Now it has consumed all contents in the shmem buffer, * make it so that mcount can reuse it. * This is paired with get_new_shmem_buffer(). */ __sync_synchronize(); shmbuf->flag = SHMEM_FL_WRITTEN; munmap(shmbuf, opts->bufsize); buf->shmem_buf = NULL; } pthread_mutex_lock(&free_list_lock); while (!list_empty(buf_head)) { struct list_head *l = buf_head->next; list_move(l, &buf_free_list); } pthread_mutex_unlock(&free_list_lock); } static int setup_pollfd(struct pollfd **pollfd, struct writer_arg *warg, bool setup_perf, bool setup_kernel) { int nr_poll = 1; struct pollfd *p; int i; if (setup_perf) nr_poll += warg->nr_cpu; if (setup_kernel) nr_poll += warg->nr_cpu; p = xcalloc(nr_poll, sizeof(*p)); p[0].fd = thread_ctl[0]; p[0].events = POLLIN; nr_poll = 1; if (setup_perf) { for (i = 0; i < warg->nr_cpu; i++) { p[i + nr_poll].fd = warg->perf->event_fd[warg->cpus[i]]; p[i + nr_poll].events = POLLIN; } nr_poll += warg->nr_cpu; } if (setup_kernel) { for (i = 0; i < warg->nr_cpu; i++) { p[i + nr_poll].fd = warg->kern->traces[warg->cpus[i]]; p[i + nr_poll].events = POLLIN; } nr_poll += warg->nr_cpu; } *pollfd = p; return nr_poll; } static bool handle_pollfd(struct pollfd *pollfd, struct writer_arg *warg, bool trace_task, bool trace_perf, bool trace_kernel, int timeout) { int start = trace_task ? 0 : 1; int nr_poll = trace_task ? 1 : 0; bool check_task = false; int i; if (trace_perf) nr_poll += warg->nr_cpu; if (trace_kernel) nr_poll += warg->nr_cpu; if (poll(&pollfd[start], nr_poll, timeout) < 0) return false; for (i = start; i < nr_poll; i++) { if (!(pollfd[i].revents & POLLIN)) continue; if (i == 0) check_task = true; else if (trace_perf && i < (warg->nr_cpu + 1)) { record_perf_data(warg->perf, warg->cpus[i - 1], warg->sock); } else if (trace_kernel) { int idx = i - (nr_poll - warg->nr_cpu); record_kernel_trace_pipe(warg->kern, warg->cpus[idx], warg->sock); } } return check_task; } static void finish_pollfd(struct pollfd *pollfd) { free(pollfd); } void *writer_thread(void *arg) { struct buf_list *buf, *pos; struct writer_arg *warg = arg; struct opts *opts = warg->opts; struct pollfd *pollfd; int i, dummy; sigset_t sigset; pthread_setname_np(pthread_self(), "WriterThread"); if (opts->rt_prio) { struct sched_param param = { .sched_priority = opts->rt_prio, }; if (sched_setscheduler(0, SCHED_FIFO, ¶m) < 0) pr_warn("set scheduling param failed\n"); } sigfillset(&sigset); pthread_sigmask(SIG_BLOCK, &sigset, NULL); setup_pollfd(&pollfd, warg, has_perf_event, opts->kernel); pr_dbg2("start writer thread %d\n", warg->idx); while (!buf_done) { LIST_HEAD(head); bool check_list = false; check_list = handle_pollfd(pollfd, warg, true, has_perf_event, opts->kernel, 1000); if (!check_list) continue; if (read(thread_ctl[0], &dummy, sizeof(dummy)) < 0) { if (errno == EAGAIN || errno == EINTR) continue; /* other errors are problematic */ break; } pthread_mutex_lock(&write_list_lock); if (!list_empty(&buf_write_list)) { /* pick first unhandled buf */ buf = list_first_entry(&buf_write_list, struct buf_list, list); list_move(&buf->list, &head); warg->tid = buf->tid; list_add(&warg->list, &writer_list); } list_for_each_entry_safe(buf, pos, &buf_write_list, list) { /* list may have multiple buf for this task */ if (buf->tid == warg->tid) list_move_tail(&buf->list, &head); } pthread_mutex_unlock(&write_list_lock); while (!list_empty(&head)) { write_buf_list(&head, opts, warg); pthread_mutex_lock(&write_list_lock); /* check someone sends bufs for me directly */ list_splice_tail_init(&warg->bufs, &head); if (list_empty(&head)) { /* I'm done with this tid */ warg->tid = -1; list_del_init(&warg->list); } pthread_mutex_unlock(&write_list_lock); if (!has_perf_event && !opts->kernel) continue; handle_pollfd(pollfd, warg, false, has_perf_event, opts->kernel, 0); } } pr_dbg2("stop writer thread %d\n", warg->idx); if (has_perf_event) { for (i = 0; i < warg->nr_cpu; i++) record_perf_data(warg->perf, warg->cpus[i], warg->sock); } finish_pollfd(pollfd); free(warg); return NULL; } static struct buf_list *make_write_buffer(void) { struct buf_list *buf; buf = malloc(sizeof(*buf)); if (buf == NULL) return NULL; INIT_LIST_HEAD(&buf->list); return buf; } static void copy_to_buffer(struct mcount_shmem_buffer *shm, char *sess_id) { struct buf_list *buf = NULL; struct writer_arg *writer; pthread_mutex_lock(&free_list_lock); if (!list_empty(&buf_free_list)) { buf = list_first_entry(&buf_free_list, struct buf_list, list); list_del(&buf->list); } pthread_mutex_unlock(&free_list_lock); if (buf == NULL) { buf = make_write_buffer(); if (buf == NULL) pr_err_ns("not enough memory!\n"); pr_dbg3("make a new write buffer\n"); } buf->shmem_buf = shm; parse_msg_id(sess_id, NULL, &buf->tid, NULL); pthread_mutex_lock(&write_list_lock); /* check some writers work for this tid */ list_for_each_entry(writer, &writer_list, list) { if (buf->tid == writer->tid) { /* if so, pass the buf directly */ list_add_tail(&buf->list, &writer->bufs); break; } } if (list_no_entry(writer, &writer_list, list)) { int kick = 1; /* no writer is dealing with the tid */ list_add_tail(&buf->list, &buf_write_list); if (write(thread_ctl[1], &kick, sizeof(kick)) < 0 && !buf_done) pr_err("copying to buffer failed"); } pthread_mutex_unlock(&write_list_lock); } static void record_mmap_file(const char *dirname, char *sess_id, int bufsize) { int fd; struct shmem_list *sl; struct mcount_shmem_buffer *shmem_buf; /* write (append) it to disk */ fd = shm_open(sess_id, O_RDWR, 0600); if (fd < 0) { pr_dbg("open shmem buffer failed: %s: %m\n", sess_id); return; } shmem_buf = mmap(NULL, bufsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (shmem_buf == MAP_FAILED) pr_err("mmap shmem buffer"); close(fd); if (shmem_buf->flag & SHMEM_FL_RECORDING) { if (shmem_buf->flag & SHMEM_FL_NEW) { bool found = false; if (!list_empty(&shmem_need_unlink)) { sl = list_last_entry(&shmem_need_unlink, struct shmem_list, list); /* length of "uftrace--" is 25 */ if (!strncmp(sl->id, sess_id, 25)) found = true; } if (!found) { sl = xmalloc(sizeof(*sl)); memcpy(sl->id, sess_id, sizeof(sl->id)); /* link to shmem_list */ list_add_tail(&sl->list, &shmem_need_unlink); } } if (shmem_buf->size) { /* shmem_buf will be unmapped */ copy_to_buffer(shmem_buf, sess_id); return; } } munmap(shmem_buf, bufsize); } static void stop_all_writers(void) { buf_done = true; close(thread_ctl[1]); thread_ctl[1] = -1; } static void record_remaining_buffer(struct opts *opts, int sock) { struct buf_list *buf; /* called after all writers gone, no lock is needed */ while (!list_empty(&buf_write_list)) { buf = list_first_entry(&buf_write_list, struct buf_list, list); write_buffer(buf, opts, sock); munmap(buf->shmem_buf, opts->bufsize); list_del(&buf->list); free(buf); } while (!list_empty(&buf_free_list)) { buf = list_first_entry(&buf_free_list, struct buf_list, list); list_del(&buf->list); free(buf); } } static void flush_shmem_list(const char *dirname, int bufsize) { struct shmem_list *sl, *tmp; /* flush remaining list (due to abnormal termination) */ list_for_each_entry_safe(sl, tmp, &shmem_list_head, list) { pr_dbg("flushing %s\n", sl->id); list_del(&sl->list); record_mmap_file(dirname, sl->id, bufsize); free(sl); } } static char shmem_session[20]; static int filter_shmem(const struct dirent *de) { /* compare session ID after the "uftrace-" part */ return !memcmp(&de->d_name[8], shmem_session, 16); } static void unlink_shmem_list(void) { struct shmem_list *sl, *tmp; /* unlink shmem list (not used anymore) */ list_for_each_entry_safe(sl, tmp, &shmem_need_unlink, list) { char sid[128]; struct dirent **shmem_bufs; int i, num; list_del(&sl->list); sscanf(sl->id, "/uftrace-%[^-]-%*d-%*d", shmem_session); pr_dbg2("unlink for session: %s\n", shmem_session); num = scandir("/dev/shm/", &shmem_bufs, filter_shmem, alphasort); for (i = 0; i < num; i++) { sid[0] = '/'; memcpy(&sid[1], shmem_bufs[i]->d_name, MSG_ID_SIZE); pr_dbg3("unlink %s\n", sid); shm_unlink(sid); free(shmem_bufs[i]); } free(shmem_bufs); free(sl); } } static void flush_old_shmem(const char *dirname, int tid, int bufsize) { struct shmem_list *sl; /* flush remaining list (due to abnormal termination) */ list_for_each_entry(sl, &shmem_list_head, list) { int sl_tid; sscanf(sl->id, "/uftrace-%*x-%d-%*d", &sl_tid); if (tid == sl_tid) { pr_dbg3("flushing %s\n", sl->id); list_del(&sl->list); record_mmap_file(dirname, sl->id, bufsize); free(sl); return; } } } static int shmem_lost_count; struct tid_list { struct list_head list; int pid; int tid; bool exited; }; static LIST_HEAD(tid_list_head); static bool child_exited; static void sigchld_handler(int sig, siginfo_t *sainfo, void *context) { int tid = sainfo->si_pid; struct tid_list *tl; list_for_each_entry(tl, &tid_list_head, list) { if (tl->tid == tid) { tl->exited = true; break; } } child_exited = true; } static void add_tid_list(int pid, int tid) { struct tid_list *tl; tl = xmalloc(sizeof(*tl)); tl->pid = pid; tl->tid = tid; tl->exited = false; /* link to tid_list */ list_add(&tl->list, &tid_list_head); } static void free_tid_list(void) { struct tid_list *tl, *tmp; list_for_each_entry_safe(tl, tmp, &tid_list_head, list) { list_del(&tl->list); free(tl); } } static bool check_tid_list(void) { struct tid_list *tl; char buf[128]; list_for_each_entry(tl, &tid_list_head, list) { int fd, len; char state; char line[PATH_MAX]; if (tl->exited || tl->tid < 0) continue; snprintf(buf, sizeof(buf), "/proc/%d/stat", tl->tid); fd = open(buf, O_RDONLY); if (fd < 0) { tl->exited = true; continue; } len = read(fd, line, sizeof(line) - 1); if (len < 0) { tl->exited = true; close(fd); continue; } line[len] = '\0'; sscanf(line, "%*d %*s %c", &state); if (state == 'Z') tl->exited = true; close(fd); } list_for_each_entry(tl, &tid_list_head, list) { if (!tl->exited) return false; } pr_dbg2("all process/thread exited\n"); child_exited = true; return true; } struct dlopen_list { struct list_head list; char *libname; }; static LIST_HEAD(dlopen_libs); static void read_record_mmap(int pfd, const char *dirname, int bufsize) { char buf[128]; struct shmem_list *sl, *tmp; struct tid_list *tl, *pos; struct uftrace_msg msg; struct uftrace_msg_task tmsg; struct uftrace_msg_sess sess; struct uftrace_msg_dlopen dmsg; struct dlopen_list *dlib; char *exename; int lost; if (read_all(pfd, &msg, sizeof(msg)) < 0) pr_err("reading pipe failed:"); if (msg.magic != UFTRACE_MSG_MAGIC) pr_err_ns("invalid message received: %x\n", msg.magic); switch (msg.type) { case UFTRACE_MSG_REC_START: if (msg.len >= SHMEM_NAME_SIZE) pr_err_ns("invalid message length\n"); sl = xmalloc(sizeof(*sl)); if (read_all(pfd, sl->id, msg.len) < 0) pr_err("reading pipe failed"); sl->id[msg.len] = '\0'; pr_dbg2("MSG START: %s\n", sl->id); /* link to shmem_list */ list_add_tail(&sl->list, &shmem_list_head); break; case UFTRACE_MSG_REC_END: if (msg.len >= SHMEM_NAME_SIZE) pr_err_ns("invalid message length\n"); if (read_all(pfd, buf, msg.len) < 0) pr_err("reading pipe failed"); buf[msg.len] = '\0'; pr_dbg2("MSG END : %s\n", buf); /* remove from shmem_list */ list_for_each_entry_safe(sl, tmp, &shmem_list_head, list) { if (!memcmp(sl->id, buf, msg.len)) { list_del(&sl->list); free(sl); break; } } record_mmap_file(dirname, buf, bufsize); break; case UFTRACE_MSG_TASK_START: if (msg.len != sizeof(tmsg)) pr_err_ns("invalid message length\n"); if (read_all(pfd, &tmsg, sizeof(tmsg)) < 0) pr_err("reading pipe failed"); pr_dbg2("MSG TASK_START : %d/%d\n", tmsg.pid, tmsg.tid); /* check existing tid (due to exec) */ list_for_each_entry(pos, &tid_list_head, list) { if (pos->tid == tmsg.tid) { flush_old_shmem(dirname, tmsg.tid, bufsize); break; } } if (list_no_entry(pos, &tid_list_head, list)) add_tid_list(tmsg.pid, tmsg.tid); write_task_info(dirname, &tmsg); break; case UFTRACE_MSG_TASK_END: if (msg.len != sizeof(tmsg)) pr_err_ns("invalid message length\n"); if (read_all(pfd, &tmsg, sizeof(tmsg)) < 0) pr_err("reading pipe failed"); pr_dbg2("MSG TASK_END : %d/%d\n", tmsg.pid, tmsg.tid); /* mark test exited */ list_for_each_entry(pos, &tid_list_head, list) { if (pos->tid == tmsg.tid) { pos->exited = true; break; } } break; case UFTRACE_MSG_FORK_START: if (msg.len != sizeof(tmsg)) pr_err_ns("invalid message length\n"); if (read_all(pfd, &tmsg, sizeof(tmsg)) < 0) pr_err("reading pipe failed"); pr_dbg2("MSG FORK1: %d/%d\n", tmsg.pid, -1); add_tid_list(tmsg.pid, -1); break; case UFTRACE_MSG_FORK_END: if (msg.len != sizeof(tmsg)) pr_err_ns("invalid message length\n"); if (read_all(pfd, &tmsg, sizeof(tmsg)) < 0) pr_err("reading pipe failed"); list_for_each_entry(tl, &tid_list_head, list) { if (tl->pid == tmsg.pid && tl->tid == -1) break; } if (list_no_entry(tl, &tid_list_head, list)) { /* * daemon process has no guarantee that having parent * pid of 1 anymore due to the systemd, just pick a * first task which has tid of -1. */ list_for_each_entry(tl, &tid_list_head, list) { if (tl->tid == -1) { pr_dbg3("override parent of daemon to %d\n", tl->pid); tmsg.pid = tl->pid; break; } } } if (list_no_entry(tl, &tid_list_head, list)) pr_err("cannot find fork pid: %d\n", tmsg.pid); tl->tid = tmsg.tid; pr_dbg2("MSG FORK2: %d/%d\n", tl->pid, tl->tid); write_fork_info(dirname, &tmsg); break; case UFTRACE_MSG_SESSION: if (msg.len < sizeof(sess)) pr_err_ns("invalid message length\n"); if (read_all(pfd, &sess, sizeof(sess)) < 0) pr_err("reading pipe failed"); exename = xmalloc(sess.namelen + 1); if (read_all(pfd, exename, sess.namelen) < 0) pr_err("reading pipe failed"); exename[sess.namelen] = '\0'; memcpy(buf, sess.sid, 16); buf[16] = '\0'; pr_dbg2("MSG SESSION: %d: %s (%s)\n", sess.task.tid, exename, buf); write_session_info(dirname, &sess, exename); free(exename); break; case UFTRACE_MSG_LOST: if (msg.len < sizeof(lost)) pr_err_ns("invalid message length\n"); if (read_all(pfd, &lost, sizeof(lost)) < 0) pr_err("reading pipe failed"); shmem_lost_count += lost; break; case UFTRACE_MSG_DLOPEN: if (msg.len < sizeof(dmsg)) pr_err_ns("invalid message length\n"); if (read_all(pfd, &dmsg, sizeof(dmsg)) < 0) pr_err("reading pipe failed"); exename = xmalloc(dmsg.namelen + 1); if (read_all(pfd, exename, dmsg.namelen) < 0) pr_err("reading pipe failed"); exename[dmsg.namelen] = '\0'; pr_dbg2("MSG DLOPEN: %d: %#lx %s\n", dmsg.task.tid, dmsg.base_addr, exename); dlib = xmalloc(sizeof(*dlib)); dlib->libname = exename; list_add_tail(&dlib->list, &dlopen_libs); write_dlopen_info(dirname, &dmsg, exename); /* exename will be freed with the dlib */ break; case UFTRACE_MSG_FINISH: pr_dbg2("MSG FINISH\n"); finish_received = true; break; default: pr_warn("Unknown message type: %u\n", msg.type); break; } } static void send_task_file(int sock, const char *dirname) { send_trace_metadata(sock, dirname, "task.txt"); } /* find "sid-XXX.map" file */ static int filter_map(const struct dirent *de) { size_t len = strlen(de->d_name); return !strncmp("sid-", de->d_name, 4) && !strncmp(".map", de->d_name + len - 4, 4); } static void send_map_files(int sock, const char *dirname) { int i, maps; struct dirent **map_list; maps = scandir(dirname, &map_list, filter_map, alphasort); if (maps < 0) pr_err("cannot scan map files"); for (i = 0; i < maps; i++) { send_trace_metadata(sock, dirname, map_list[i]->d_name); free(map_list[i]); } free(map_list); } /* find "XXX.sym" file */ static int filter_sym(const struct dirent *de) { size_t len = strlen(de->d_name); return !strncmp(".sym", de->d_name + len - 4, 4); } static void send_sym_files(int sock, const char *dirname) { int i, syms; struct dirent **sym_list; syms = scandir(dirname, &sym_list, filter_sym, alphasort); if (syms < 0) pr_err("cannot scan sym files"); for (i = 0; i < syms; i++) { send_trace_metadata(sock, dirname, sym_list[i]->d_name); free(sym_list[i]); } free(sym_list); } /* find "XXX.dbg" file */ static int filter_dbg(const struct dirent *de) { size_t len = strlen(de->d_name); return !strncmp(".dbg", de->d_name + len - 4, 4); } static void send_dbg_files(int sock, const char *dirname) { int i, dbgs; struct dirent **dbg_list; dbgs = scandir(dirname, &dbg_list, filter_dbg, alphasort); if (dbgs < 0) pr_err("cannot scan dbg files"); for (i = 0; i < dbgs; i++) { send_trace_metadata(sock, dirname, dbg_list[i]->d_name); free(dbg_list[i]); } free(dbg_list); } static void send_info_file(int sock, const char *dirname) { int fd; char *filename = NULL; struct uftrace_file_header hdr; struct stat stbuf; void *info; int len; xasprintf(&filename, "%s/info", dirname); fd = open(filename, O_RDONLY); if (fd < 0) pr_err("open info failed"); if (fstat(fd, &stbuf) < 0) pr_err("stat info failed"); if (read_all(fd, &hdr, sizeof(hdr)) < 0) pr_err("read file header failed"); len = stbuf.st_size - sizeof(hdr); info = xmalloc(len); if (read_all(fd, info, len) < 0) pr_err("read info failed"); send_trace_info(sock, &hdr, info, len); close(fd); free(info); free(filename); } static void send_kernel_metadata(int sock, const char *dirname) { send_trace_metadata(sock, dirname, "kernel_header"); send_trace_metadata(sock, dirname, "kallsyms"); } static void send_event_file(int sock, const char *dirname) { char buf[PATH_MAX]; /* kernel events doesn't create the events file */ snprintf(buf, sizeof(buf), "%s/events.txt", dirname); if (access(buf, F_OK) != 0) return; send_trace_metadata(sock, dirname, "events.txt"); } static void send_log_file(int sock, const char *logfile) { if (access(logfile, F_OK) != 0) return; send_trace_metadata(sock, NULL, (char*)logfile); } static void load_session_symbols(struct opts *opts) { struct dirent **map_list; int i, maps; maps = scandir(opts->dirname, &map_list, filter_map, alphasort); if (maps <= 0) { if (maps == 0) errno = ENOENT; pr_err("cannot find map files"); } for (i = 0; i < maps; i++) { struct symtabs symtabs = { .dirname = opts->dirname, .flags = SYMTAB_FL_ADJ_OFFSET, }; char sid[20]; sscanf(map_list[i]->d_name, "sid-%[^.].map", sid); free(map_list[i]); pr_dbg2("reading symbols for session %s\n", sid); read_session_map(opts->dirname, &symtabs, sid); load_module_symtabs(&symtabs); delete_session_map(&symtabs); } free(map_list); } static char *get_child_time(struct timespec *ts1, struct timespec *ts2) { #define SEC_TO_NSEC (1000000000ULL) char *elapsed_time = NULL; uint64_t sec = ts2->tv_sec - ts1->tv_sec; uint64_t nsec = ts2->tv_nsec - ts1->tv_nsec; if (nsec > SEC_TO_NSEC) { nsec += SEC_TO_NSEC; sec--; } xasprintf(&elapsed_time, "%"PRIu64".%09"PRIu64" sec", sec, nsec); return elapsed_time; } static void print_child_time(char *elapsed_time) { pr_out("elapsed time: %20s\n", elapsed_time); } static void print_child_usage(struct rusage *ru) { pr_out(" system time: %6lu.%06lu000 sec\n", ru->ru_stime.tv_sec, ru->ru_stime.tv_usec); pr_out(" user time: %6lu.%06lu000 sec\n", ru->ru_utime.tv_sec, ru->ru_utime.tv_usec); } #define UFTRACE_MSG "Cannot trace '%s': No such executable file.\n" #define MCOUNT_MSG "Can't find '%s' symbol in the '%s'.\n" \ "\tIt seems not to be compiled with -pg or -finstrument-functions flag\n" \ "\twhich generates traceable code. Please check your binary file.\n" #define UFTRACE_ELF_MSG "Cannot trace '%s': Invalid file\n" \ "\tThis file doesn't look like an executable ELF file.\n" \ "\tPlease check whether it's a kind of script or shell functions.\n" #define MACHINE_MSG "Cannot trace '%s': Unsupported machine\n" \ "\tThis machine type (%u) is not supported currently.\n" \ "\tSorry about that!\n" #define ARGUMENT_MSG "uftrace: -A or -R might not work for binaries" \ " with -finstrument-functions\n" #define STATIC_MSG "Cannot trace static binary: %s\n" \ "\tIt seems to be compiled with -static, rebuild the binary without it.\n" #define SCRIPT_MSG "Cannot trace script file: %s\n" \ "\tTo trace binaries run by the script, use --force option.\n" #ifndef EM_AARCH64 # define EM_AARCH64 183 #endif static bool is_regular_executable(const char *pathname) { struct stat sb; if (!stat(pathname, &sb)) { if (S_ISREG(sb.st_mode) && (sb.st_mode & S_IXUSR)) return true; } return false; } static void find_in_path(char **exename) { /* try to find the binary in PATH */ struct strv strv = STRV_INIT; char *env = getenv("PATH"); char *pathname = NULL; char *path; bool found = false; int i; if (!env || *exename[0] == '/') pr_err_ns(UFTRACE_MSG, *exename); /* search opts->exename in PATH one by one */ strv_split(&strv, env, ":"); strv_for_each(&strv, path, i) { xasprintf(&pathname, "%s/%s", path, *exename); if (is_regular_executable(pathname)) { found = true; break; } free(pathname); } if (!found) pr_err_ns(UFTRACE_MSG, *exename); *exename = pathname; strv_free(&strv); } static void check_binary(struct opts *opts) { int fd; int chk; size_t i; char elf_ident[EI_NIDENT]; uint16_t e_type; uint16_t e_machine; uint16_t supported_machines[] = { EM_X86_64, EM_ARM, EM_AARCH64, EM_386 }; again: /* if it cannot be found in PATH, then fails inside */ if (!is_regular_executable(opts->exename)) find_in_path(&opts->exename); pr_dbg("checking binary %s\n", opts->exename); fd = open(opts->exename, O_RDONLY); if (fd < 0) pr_err("Cannot open '%s'", opts->exename); if (read(fd, elf_ident, sizeof(elf_ident)) < 0) pr_err("Cannot read '%s'", opts->exename); if (memcmp(elf_ident, ELFMAG, SELFMAG)) { char *script = check_script_file(opts->exename); char *p; if (script == NULL) pr_err_ns(UFTRACE_ELF_MSG, opts->exename); if (!opts->force && !opts->patch) pr_err_ns(SCRIPT_MSG, opts->exename); /* ignore options */ p = strchr(script, ' '); if (p) *p = '\0'; opts->exename = script; close(fd); goto again; } if (read(fd, &e_type, sizeof(e_type)) < 0) pr_err("Cannot read '%s'", opts->exename); if (e_type != ET_EXEC && e_type != ET_DYN) pr_err_ns(UFTRACE_ELF_MSG, opts->exename); if (read(fd, &e_machine, sizeof(e_machine)) < 0) pr_err("Cannot read '%s'", opts->exename); for (i = 0; i < ARRAY_SIZE(supported_machines); i++) { if (e_machine == supported_machines[i]) break; } if (i == ARRAY_SIZE(supported_machines)) pr_err_ns(MACHINE_MSG, opts->exename, e_machine); chk = check_static_binary(opts->exename); if (chk) { if (chk < 0) pr_err_ns("Cannot check '%s'\n", opts->exename); else pr_err_ns(STATIC_MSG, opts->exename); } if (!opts->force) { enum uftrace_trace_type chk_type; chk_type = check_trace_functions(opts->exename); if (chk_type == TRACE_NONE && !opts->patch) { /* there's no function to trace */ pr_err_ns(MCOUNT_MSG, "mcount", opts->exename); } else if (chk_type == TRACE_CYGPROF && (opts->args || opts->retval)) { /* arg/retval doesn't support -finstrument-functions */ pr_out(ARGUMENT_MSG); } else if (chk_type == TRACE_ERROR) { pr_err_ns("Cannot check '%s'\n", opts->exename); } } close(fd); } static void check_perf_event(struct opts *opts) { struct strv strv = STRV_INIT; char *evt; int i; bool found = false; enum uftrace_pattern_type ptype = opts->patt_type; has_perf_event = has_sched_event = !opts->no_event; /* * caller filter focuses onto a given function, * displaying sched event with it is annoying. */ if (opts->caller != NULL) has_sched_event = false; if (opts->event == NULL) return; strv_split(&strv, opts->event, ";"); strv_for_each(&strv, evt, i) { struct uftrace_pattern patt; init_filter_pattern(ptype, &patt, evt); if (match_filter_pattern(&patt, "linux:task-new") || match_filter_pattern(&patt, "linux:task-exit") || match_filter_pattern(&patt, "linux:task-name")) found = true; if (match_filter_pattern(&patt, "linux:sched-in") || match_filter_pattern(&patt, "linux:sched-out") || match_filter_pattern(&patt, "linux:schedule")) { has_sched_event = true; found = true; } free_filter_pattern(&patt); if (found && has_sched_event) break; } strv_free(&strv); has_perf_event = found; } struct writer_data { int pid; int pipefd; int sock; int nr_cpu; int status; pthread_t *writers; struct timespec ts1, ts2; struct rusage usage; struct uftrace_kernel_writer kernel; struct uftrace_perf_writer perf; }; static void setup_writers(struct writer_data *wd, struct opts *opts) { struct uftrace_kernel_writer *kernel = &wd->kernel; struct uftrace_perf_writer *perf = &wd->perf; struct sigaction sa = { .sa_flags = 0, }; if (opts->nop) { opts->nr_thread = 0; opts->kernel = false; has_perf_event = false; wd->nr_cpu = 0; goto out; } sigfillset(&sa.sa_mask); sa.sa_handler = NULL; sa.sa_sigaction = sigchld_handler; sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO; sigaction(SIGCHLD, &sa, NULL); if (opts->host) { wd->sock = setup_client_socket(opts); send_trace_dir_name(wd->sock, opts->dirname); } else wd->sock = -1; wd->nr_cpu = sysconf(_SC_NPROCESSORS_ONLN); if (opts->kernel || has_kernel_event(opts->event)) { int err; kernel->pid = wd->pid; kernel->output_dir = opts->dirname; kernel->depth = opts->kernel_depth ?: 1; kernel->bufsize = opts->kernel_bufsize; if (!opts->nr_thread) { if (opts->kernel_depth >= 4) opts->nr_thread = wd->nr_cpu; else if (opts->kernel_depth >= 2) opts->nr_thread = wd->nr_cpu / 2; } if (!opts->kernel_bufsize) { if (opts->kernel_depth >= 8) kernel->bufsize = PATH_MAX * 1024; else if (opts->kernel_depth >= 4) kernel->bufsize = 3072 * 1024; else if (opts->kernel_depth >= 2) kernel->bufsize = 2048 * 1024; } err = setup_kernel_tracing(kernel, opts); if (err) { if (err == -EPERM) pr_warn("kernel tracing requires root privilege\n"); else pr_warn("kernel tracing disabled due to an error\n" "is CONFIG_FUNCTION_GRAPH_TRACER enabled in the kernel?\n"); opts->kernel = false; } } if (!opts->nr_thread) opts->nr_thread = DIV_ROUND_UP(wd->nr_cpu, 4); else if (opts->nr_thread > wd->nr_cpu) opts->nr_thread = wd->nr_cpu; if (has_perf_event) { if (setup_perf_record(perf, wd->nr_cpu, wd->pid, opts->dirname, has_sched_event) < 0) has_perf_event = false; } out: pr_dbg("creating %d thread(s) for recording\n", opts->nr_thread); wd->writers = xmalloc(opts->nr_thread * sizeof(*wd->writers)); if (pipe(thread_ctl) < 0) pr_err("cannot create an eventfd for writer thread"); } static void start_tracing(struct writer_data *wd, struct opts *opts, int ready_fd) { int i, k; uint64_t go = 1; clock_gettime(CLOCK_MONOTONIC, &wd->ts1); if (opts->kernel && start_kernel_tracing(&wd->kernel) < 0) { opts->kernel = false; pr_warn("kernel tracing disabled due to an error\n"); } for (i = 0; i < opts->nr_thread; i++) { struct writer_arg *warg; int cpu_per_thread = DIV_ROUND_UP(wd->nr_cpu, opts->nr_thread); size_t sizeof_warg = sizeof(*warg) + sizeof(int) * cpu_per_thread; warg = xzalloc(sizeof_warg); warg->opts = opts; warg->idx = i; warg->sock = wd->sock; warg->kern = &wd->kernel; warg->perf = &wd->perf; warg->nr_cpu = 0; INIT_LIST_HEAD(&warg->list); INIT_LIST_HEAD(&warg->bufs); if (opts->kernel || has_perf_event) { warg->nr_cpu = cpu_per_thread; for (k = 0; k < cpu_per_thread; k++) { if (i * cpu_per_thread + k < wd->nr_cpu) warg->cpus[k] = i * cpu_per_thread + k; else warg->cpus[k] = -1; } } pthread_create(&wd->writers[i], NULL, writer_thread, warg); } /* signal child that I'm ready */ if (write(ready_fd, &go, sizeof(go)) != (ssize_t)sizeof(go)) pr_err("signal to child failed"); } static int stop_tracing(struct writer_data *wd, struct opts *opts) { int status = -1; int ret = UFTRACE_EXIT_SUCCESS; /* child finished, read remaining data in the pipe */ while (!uftrace_done) { int remaining = 0; if (ioctl(wd->pipefd, FIONREAD, &remaining) < 0) break; if (remaining) { read_record_mmap(wd->pipefd, opts->dirname, opts->bufsize); continue; } /* wait for SIGCHLD or FORK_END */ usleep(1000); /* * It's possible to receive a remaining FORK_START message. * In this case, we need to wait FORK_END message also in * order to get proper pid. Otherwise replay will fail with * pid of -1. */ if (check_tid_list()) break; if (finish_received) { status = UFTRACE_EXIT_FINISHED; break; } pr_dbg2("waiting for FORK2\n"); } if (child_exited) { wait4(wd->pid, &status, 0, &wd->usage); if (WIFEXITED(status)) { pr_dbg("child terminated with exit code: %d\n", WEXITSTATUS(status)); if (WEXITSTATUS(status)) ret = UFTRACE_EXIT_FAILURE; else ret = UFTRACE_EXIT_SUCCESS; } else if (WIFSIGNALED(status)) { pr_yellow("child terminated by signal: %d: %s\n", WTERMSIG(status), strsignal(WTERMSIG(status))); ret = UFTRACE_EXIT_SIGNALED; } else { pr_yellow("child terminated with unknown reason: %d\n", status); memset(&wd->usage, 0, sizeof(wd->usage)); ret = UFTRACE_EXIT_UNKNOWN; } } else if (opts->keep_pid) memset(&wd->usage, 0, sizeof(wd->usage)); else getrusage(RUSAGE_CHILDREN, &wd->usage); stop_all_writers(); if (opts->kernel) stop_kernel_tracing(&wd->kernel); clock_gettime(CLOCK_MONOTONIC, &wd->ts2); wd->status = status; return ret; } static void finish_writers(struct writer_data *wd, struct opts *opts) { int i; char *elapsed_time = get_child_time(&wd->ts1, &wd->ts2); if (opts->time) { print_child_time(elapsed_time); print_child_usage(&wd->usage); } if (opts->nop) { free(elapsed_time); return; } if (fill_file_header(opts, wd->status, &wd->usage, elapsed_time) < 0) pr_err("cannot generate data file"); free(elapsed_time); if (shmem_lost_count) pr_warn("LOST %d records\n", shmem_lost_count); for (i = 0; i < opts->nr_thread; i++) pthread_join(wd->writers[i], NULL); free(wd->writers); close(thread_ctl[0]); flush_shmem_list(opts->dirname, opts->bufsize); record_remaining_buffer(opts, wd->sock); unlink_shmem_list(); free_tid_list(); if (opts->kernel) finish_kernel_tracing(&wd->kernel); if (has_perf_event) finish_perf_record(&wd->perf); } static void write_symbol_files(struct writer_data *wd, struct opts *opts) { struct dlopen_list *dlib, *tmp; if (opts->nop) return; /* main executable and shared libraries */ load_session_symbols(opts); /* dynamically loaded libraries using dlopen() */ list_for_each_entry_safe(dlib, tmp, &dlopen_libs, list) { struct symtabs dlib_symtabs = { .dirname = opts->dirname, .flags = SYMTAB_FL_ADJ_OFFSET, }; load_module_symtab(&dlib_symtabs, dlib->libname); list_del(&dlib->list); free(dlib->libname); free(dlib); } save_module_symtabs(opts->dirname); unload_module_symtabs(); if (opts->host) { int sock = wd->sock; send_task_file(sock, opts->dirname); send_map_files(sock, opts->dirname); send_sym_files(sock, opts->dirname); send_dbg_files(sock, opts->dirname); send_info_file(sock, opts->dirname); if (opts->kernel) send_kernel_metadata(sock, opts->dirname); if (opts->event) send_event_file(sock, opts->dirname); if (opts->logfile) send_log_file(sock, opts->logfile); send_trace_end(sock); close(sock); remove_directory(opts->dirname); } else if (geteuid() == 0) chown_directory(opts->dirname); } int do_main_loop(int ready, struct opts *opts, int pid) { int ret; struct writer_data wd; char *channel = NULL; if (opts->nop) { setup_writers(&wd, opts); start_tracing(&wd, opts, ready); close(ready); wait(NULL); uftrace_done = true; ret = stop_tracing(&wd, opts); finish_writers(&wd, opts); return ret; } xasprintf(&channel, "%s/%s", opts->dirname, ".channel"); wd.pid = pid; wd.pipefd = open(channel, O_RDONLY | O_NONBLOCK); free(channel); if (wd.pipefd < 0) pr_err("cannot open pipe"); if (opts->sig_trigger) pr_out("uftrace: install signal handlers to task %d\n", pid); setup_writers(&wd, opts); start_tracing(&wd, opts, ready); close(ready); while (!uftrace_done) { struct pollfd pollfd = { .fd = wd.pipefd, .events = POLLIN, }; ret = poll(&pollfd, 1, 1000); if (ret < 0 && errno == EINTR) continue; if (ret < 0) pr_err("error during poll"); if (pollfd.revents & POLLIN) read_record_mmap(wd.pipefd, opts->dirname, opts->bufsize); if (pollfd.revents & (POLLERR | POLLHUP)) break; } ret = stop_tracing(&wd, opts); finish_writers(&wd, opts); write_symbol_files(&wd, opts); return ret; } int do_child_exec(int ready, struct opts *opts, int argc, char *argv[]) { uint64_t dummy; char *shebang; char fullpath[PATH_MAX]; struct strv new_args = STRV_INIT; if (opts->no_randomize_addr) { /* disable ASLR (Address Space Layout Randomization) */ if (personality(ADDR_NO_RANDOMIZE) < 0) pr_dbg("disabling ASLR failed\n"); } /* * The current working directory can be changed by calling chdir. * So dirname has to be converted to an absolute path to avoid unexpected problems. */ if (realpath(opts->dirname, fullpath) != NULL) opts->dirname = fullpath; shebang = check_script_file(argv[0]); if (shebang) { char *s, *p; int i; s = shebang; while (isspace(*s)) s++; p = strchr(s, ' '); if (p != NULL) *p++ = '\0'; strv_append(&new_args, s); if (p != NULL) strv_append(&new_args, p); for (i = 0; i < argc; i++) strv_append(&new_args, argv[i]); argc = new_args.nr; argv = new_args.p; free(shebang); } setup_child_environ(opts, argc, argv); /* wait for parent ready */ if (read(ready, &dummy, sizeof(dummy)) != (ssize_t)sizeof(dummy)) pr_err("waiting for parent failed"); /* * The traced binary is already resolved into absolute pathname. * So plain 'execv' is enough and no need to use 'execvp'. */ execv(opts->exename, argv); abort(); } int command_record(int argc, char *argv[], struct opts *opts) { int pid; int ready; int ret = -1; char *channel = NULL; /* apply script-provided options */ if (opts->script_file) parse_script_opt(opts); check_binary(opts); check_perf_event(opts); if (!opts->nop) { if (create_directory(opts->dirname) < 0) return -1; xasprintf(&channel, "%s/%s", opts->dirname, ".channel"); if (mkfifo(channel, 0600) < 0) pr_err("cannot create a communication channel"); } fflush(stdout); ready = eventfd(0, EFD_CLOEXEC | EFD_SEMAPHORE); if (ready < 0) pr_dbg("creating eventfd failed: %d\n", ready); pid = fork(); if (pid < 0) pr_err("cannot start child process"); if (pid == 0) { if (opts->keep_pid) ret = do_main_loop(ready, opts, getppid()); else do_child_exec(ready, opts, argc, argv); if (channel) unlink(channel); return ret; } if (opts->keep_pid) do_child_exec(ready, opts, argc, argv); else ret = do_main_loop(ready, opts, pid); if (channel) unlink(channel); return ret; } uftrace-0.9.3/cmds/recv.c000066400000000000000000000350161351236475300152230ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "uftrace.h" #include "utils/utils.h" #include "utils/list.h" struct client_data { struct list_head list; int sock; char *dirname; }; static LIST_HEAD(client_list); static int server_socket(struct opts *opts) { int sock; int on = 1; struct sockaddr_in addr = { .sin_family = AF_INET, .sin_addr = { .s_addr = htonl(INADDR_ANY), }, .sin_port = htons(opts->port), }; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) pr_err("socket creation failed"); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) pr_err("socket bind failed"); if (listen(sock, 5) < 0) pr_err("socket listen failed"); return sock; } static int signal_fd(struct opts *opts) { int fd; sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGCHLD); if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) pr_err("signal block failed"); fd = signalfd(-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK); if (fd < 0) pr_err("signalfd failed"); return fd; } /* client (record) side API */ int setup_client_socket(struct opts *opts) { struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(opts->port), }; struct hostent *hostinfo; int sock; int one = 1; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) pr_err("socket create failed"); setsockopt(sock, SOL_TCP, TCP_NODELAY, &one, sizeof(one)); hostinfo = gethostbyname(opts->host); if (hostinfo == NULL) pr_err("cannot find host: %s", opts->host); addr.sin_addr = *(struct in_addr *) hostinfo->h_addr; if (connect(sock, &addr, sizeof(addr)) < 0) pr_err("socket connect failed"); return sock; } void send_trace_dir_name(int sock, char *name) { ssize_t len = strlen(name); struct uftrace_msg msg = { .magic = htons(UFTRACE_MSG_MAGIC), .type = htons(UFTRACE_MSG_SEND_DIR_NAME), .len = htonl(len), }; struct iovec iov[] = { { .iov_base = &msg, .iov_len = sizeof(msg), }, { .iov_base = name, .iov_len = len, }, }; pr_dbg2("send UFTRACE_MSG_SEND_HDR\n"); if (writev_all(sock, iov, ARRAY_SIZE(iov)) < 0) pr_err("send header failed"); } void send_trace_data(int sock, int tid, void *data, size_t len) { int32_t msg_tid = htonl(tid); struct uftrace_msg msg = { .magic = htons(UFTRACE_MSG_MAGIC), .type = htons(UFTRACE_MSG_SEND_DATA), .len = htonl(sizeof(msg_tid) + len), }; struct iovec iov[] = { { .iov_base = &msg, .iov_len = sizeof(msg), }, { .iov_base = &msg_tid, .iov_len = sizeof(msg_tid), }, { .iov_base = data, .iov_len = len, }, }; pr_dbg2("send UFTRACE_MSG_SEND_DATA\n"); if (writev_all(sock, iov, ARRAY_SIZE(iov)) < 0) pr_err("send data failed"); } void send_trace_kernel_data(int sock, int cpu, void *data, size_t len) { int32_t msg_cpu = htonl(cpu); struct uftrace_msg msg = { .magic = htons(UFTRACE_MSG_MAGIC), .type = htons(UFTRACE_MSG_SEND_KERNEL_DATA), .len = htonl(sizeof(msg_cpu) + len), }; struct iovec iov[] = { { .iov_base = &msg, .iov_len = sizeof(msg), }, { .iov_base = &msg_cpu, .iov_len = sizeof(msg_cpu), }, { .iov_base = data, .iov_len = len, }, }; pr_dbg2("send UFTRACE_MSG_SEND_KERNEL_DATA\n"); if (writev_all(sock, iov, ARRAY_SIZE(iov)) < 0) pr_err("send kernel data failed"); } void send_trace_perf_data(int sock, int cpu, void *data, size_t len) { int32_t msg_cpu = htonl(cpu); struct uftrace_msg msg = { .magic = htons(UFTRACE_MSG_MAGIC), .type = htons(UFTRACE_MSG_SEND_PERF_DATA), .len = htonl(sizeof(msg_cpu) + len), }; struct iovec iov[] = { { .iov_base = &msg, .iov_len = sizeof(msg), }, { .iov_base = &msg_cpu, .iov_len = sizeof(msg_cpu), }, { .iov_base = data, .iov_len = len, }, }; pr_dbg2("send UFTRACE_MSG_SEND_PERF_DATA\n"); if (writev_all(sock, iov, ARRAY_SIZE(iov)) < 0) pr_err("send kernel data failed"); } void send_trace_metadata(int sock, const char *dirname, char *filename) { int fd; void *buf; size_t len; char *pathname = NULL; struct stat stbuf; int32_t namelen = strlen(filename); struct uftrace_msg msg = { .magic = htons(UFTRACE_MSG_MAGIC), .type = htons(UFTRACE_MSG_SEND_META_DATA), .len = sizeof(namelen) + namelen, }; struct iovec iov[4] = { { .iov_base = &msg, .iov_len = sizeof(msg), }, { .iov_base = &namelen, .iov_len = sizeof(namelen), }, { .iov_base = filename, .iov_len = namelen, }, { /* to be filled */ }, }; if (dirname) xasprintf(&pathname, "%s/%s", dirname, filename); else pathname = xstrdup(filename); fd = open(pathname, O_RDONLY); if (fd < 0) pr_err("open %s failed", pathname); if (fstat(fd, &stbuf) < 0) pr_err("stat %s failed", pathname); len = stbuf.st_size; buf = xmalloc(len); msg.len = htonl(msg.len + len); iov[3].iov_base = buf; iov[3].iov_len = len; if (read_all(fd, buf, len) < 0) pr_err("map read failed"); namelen = htonl(namelen); pr_dbg2("send UFTRACE_MSG_SEND_META_DATA: %s\n", filename); if (writev_all(sock, iov, ARRAY_SIZE(iov)) < 0) pr_err("send metadata failed"); free(pathname); free(buf); close(fd); } void send_trace_info(int sock, struct uftrace_file_header *hdr, void *info, int len) { struct uftrace_msg msg = { .magic = htons(UFTRACE_MSG_MAGIC), .type = htons(UFTRACE_MSG_SEND_INFO), .len = htonl(sizeof(*hdr) + len), }; struct iovec iov[] = { { .iov_base = &msg, .iov_len = sizeof(msg), }, { .iov_base = hdr, .iov_len = sizeof(*hdr), }, { .iov_base = info, .iov_len = len, }, }; hdr->version = htonl(hdr->version); hdr->header_size = htons(hdr->header_size); hdr->feat_mask = htonq(hdr->feat_mask); hdr->info_mask = htonq(hdr->info_mask); hdr->max_stack = htons(hdr->max_stack); pr_dbg2("send UFTRACE_MSG_SEND_INFO\n"); if (writev_all(sock, iov, ARRAY_SIZE(iov)) < 0) pr_err("send metadata failed"); } void send_trace_end(int sock) { struct uftrace_msg msg = { .magic = htons(UFTRACE_MSG_MAGIC), .type = htons(UFTRACE_MSG_SEND_END), }; pr_dbg2("send UFTRACE_MSG_SEND_END\n"); if (write_all(sock, &msg, sizeof(msg)) < 0) pr_err("send end failed"); } /* server (recv) side API */ static struct client_data *find_client(int sock) { struct client_data *c; list_for_each_entry(c, &client_list, list) { if (c->sock == sock) return c; } return NULL; } #define O_CLIENT_FLAGS (O_WRONLY | O_APPEND | O_CREAT) static void write_client_file(struct client_data *c, char *filename, int nr, ...) { int i, fd; va_list ap; struct iovec iov[nr]; char buf[PATH_MAX]; snprintf(buf, sizeof(buf), "%s/%s", c->dirname, filename); fd = open(buf, O_CLIENT_FLAGS, 0644); if (fd < 0) pr_err("file open failed: %s", buf); va_start(ap, nr); for (i = 0; i < nr; i++) { iov[i].iov_base = va_arg(ap, void *); iov[i].iov_len = va_arg(ap, int); } va_end(ap); if (writev_all(fd, iov, nr) < 0) pr_err("write client data failed on %s", buf); close(fd); } static void recv_trace_dir_name(int sock, int len) { char dirname[len + 1]; struct client_data *client; if (read_all(sock, dirname, len) < 0) pr_err("recv header failed"); dirname[len] = '\0'; client = xmalloc(sizeof(*client)); client->sock = sock; client->dirname = xstrdup(dirname); INIT_LIST_HEAD(&client->list); create_directory(dirname); pr_dbg3("create directory: %s\n", dirname); list_add(&client->list, &client_list); } static void recv_trace_data(int sock, int len) { struct client_data *client; int32_t tid; char *filename = NULL; void *buffer; client = find_client(sock); if (client == NULL) pr_err_ns("no client on this socket\n"); if (read_all(sock, &tid, sizeof(tid)) < 0) pr_err("recv tid failed"); tid = ntohl(tid); xasprintf(&filename, "%d.dat", tid); len -= sizeof(tid); buffer = xmalloc(len); if (read_all(sock, buffer, len) < 0) pr_err("recv buffer failed"); write_client_file(client, filename, 1, buffer, len); free(buffer); free(filename); } static void recv_trace_kernel_data(int sock, int len) { struct client_data *client; int32_t cpu; char *filename = NULL; void *buffer; client = find_client(sock); if (client == NULL) pr_err_ns("no client on this socket\n"); if (read_all(sock, &cpu, sizeof(cpu)) < 0) pr_err("recv cpu failed"); cpu = ntohl(cpu); xasprintf(&filename, "kernel-cpu%d.dat", cpu); len -= sizeof(cpu); buffer = xmalloc(len); if (read_all(sock, buffer, len) < 0) pr_err("recv buffer failed"); write_client_file(client, filename, 1, buffer, len); free(buffer); free(filename); } static void recv_trace_perf_data(int sock, int len) { struct client_data *client; int32_t cpu; char *filename = NULL; void *buffer; client = find_client(sock); if (client == NULL) pr_err_ns("no client on this socket\n"); if (read_all(sock, &cpu, sizeof(cpu)) < 0) pr_err("recv cpu failed"); cpu = ntohl(cpu); xasprintf(&filename, "perf-cpu%d.dat", cpu); len -= sizeof(cpu); buffer = xmalloc(len); if (read_all(sock, buffer, len) < 0) pr_err("recv buffer failed"); write_client_file(client, filename, 1, buffer, len); free(buffer); free(filename); } static void recv_trace_metadata(int sock, int len) { struct client_data *client; int32_t namelen; char *filename = NULL; void *filedata; client = find_client(sock); if (client == NULL) pr_err_ns("no client on this socket\n"); if (read_all(sock, &namelen, sizeof(namelen)) < 0) pr_err("recv symfile name length failed"); namelen = ntohl(namelen); filename = xmalloc(namelen + 1); if (read_all(sock, filename, namelen) < 0) pr_err("recv file name failed"); filename[namelen] = '\0'; len -= sizeof(namelen) + namelen; filedata = xmalloc(len); pr_dbg2("reading %s (%d bytes)\n", filename, len); if (read_all(sock, filedata, len) < 0) pr_err("recv symfile failed"); write_client_file(client, filename, 1, filedata, len); free(filedata); free(filename); } static void recv_trace_info(int sock, int len) { struct client_data *client; struct uftrace_file_header hdr; void *info; client = find_client(sock); if (client == NULL) pr_err_ns("no client on this socket\n"); if (read_all(sock, &hdr, sizeof(hdr)) < 0) pr_err("recv file header failed"); hdr.version = ntohl(hdr.version); hdr.header_size = ntohs(hdr.header_size); hdr.feat_mask = ntohq(hdr.feat_mask); hdr.info_mask = ntohq(hdr.info_mask); hdr.max_stack = ntohs(hdr.max_stack); len -= sizeof(hdr); info = xmalloc(len); if (read_all(sock, info, len) < 0) pr_err("recv info failed"); write_client_file(client, "info", 2, &hdr, sizeof(hdr), info, len); free(info); } static void recv_trace_end(int sock, int efd) { struct client_data *client; client = find_client(sock); if (client) { list_del(&client->list); pr_dbg("wrote client data to %s\n", client->dirname); free(client->dirname); free(client); } if (epoll_ctl(efd, EPOLL_CTL_DEL, sock, NULL) < 0) pr_err("epoll del failed"); close(sock); } static void execute_run_cmd(char **argv) { if (!argv) return; int pid = fork(); if (pid < 0) pr_err("cannot start child process"); if (pid == 0) { execvp(argv[0], argv); pr_err("Failed to execute '%s'", argv[0]); } } static void epoll_add(int efd, int fd, unsigned event) { struct epoll_event ev = { .events = event, .data = { .fd = fd, }, }; if (epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev) < 0) pr_err("epoll add failed"); } static void handle_server_sock(struct epoll_event *ev, int efd) { int client; int sock = ev->data.fd; struct sockaddr_in addr; socklen_t len = sizeof(addr); char hbuf[NI_MAXHOST]; client = accept(sock, &addr, &len); if (client < 0) pr_err("socket accept failed"); getnameinfo((struct sockaddr *)&addr, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); epoll_add(efd, client, EPOLLIN); pr_dbg("new connection added from %s\n", hbuf); } static void handle_client_sock(struct epoll_event *ev, int efd, struct opts *opts) { int sock = ev->data.fd; struct uftrace_msg msg; if (ev->events & (EPOLLERR | EPOLLHUP)) { pr_dbg("client socket closed\n"); recv_trace_end(sock, efd); return; } if (read_all(sock, &msg, sizeof(msg)) < 0) pr_err("message recv failed"); msg.magic = ntohs(msg.magic); msg.type = ntohs(msg.type); msg.len = ntohl(msg.len); if (msg.magic != UFTRACE_MSG_MAGIC) pr_err_ns("invalid message\n"); switch (msg.type) { case UFTRACE_MSG_SEND_DIR_NAME: pr_dbg2("receive UFTRACE_MSG_SEND_DIR_NAME\n"); recv_trace_dir_name(sock, msg.len); break; case UFTRACE_MSG_SEND_DATA: pr_dbg2("receive UFTRACE_MSG_SEND_DATA\n"); recv_trace_data(sock, msg.len); break; case UFTRACE_MSG_SEND_KERNEL_DATA: pr_dbg2("receive UFTRACE_MSG_SEND_KERNEL_DATA\n"); recv_trace_kernel_data(sock, msg.len); break; case UFTRACE_MSG_SEND_PERF_DATA: pr_dbg2("receive UFTRACE_MSG_SEND_PERF_DATA\n"); recv_trace_perf_data(sock, msg.len); break; case UFTRACE_MSG_SEND_INFO: pr_dbg2("receive UFTRACE_MSG_SEND_INFO\n"); recv_trace_info(sock, msg.len); break; case UFTRACE_MSG_SEND_META_DATA: pr_dbg2("receive UFTRACE_MSG_SEND_META_DATA\n"); recv_trace_metadata(sock, msg.len); break; case UFTRACE_MSG_SEND_END: pr_dbg2("receive UFTRACE_MSG_SEND_END\n"); recv_trace_end(sock, efd); execute_run_cmd(opts->run_cmd); break; default: pr_dbg("unknown message: %d\n", msg.type); break; } } int command_recv(int argc, char *argv[], struct opts *opts) { struct signalfd_siginfo si; int sock; int sigfd; int efd; if (strcmp(opts->dirname, UFTRACE_DIR_NAME)) { char *dirname = "current"; if ((mkdir(opts->dirname, 0755) == 0 || errno == EEXIST) && chdir(opts->dirname) == 0) dirname = opts->dirname; pr_dbg("saving to %s directory\n", dirname); } sock = server_socket(opts); sigfd = signal_fd(opts); efd = epoll_create1(EPOLL_CLOEXEC); if (efd < 0) pr_err("epoll create failed"); epoll_add(efd, sock, EPOLLIN); epoll_add(efd, sigfd, EPOLLIN); while (!uftrace_done) { struct epoll_event ev[10]; int i, len; len = epoll_wait(efd, ev, 10, -1); if (len < 0) pr_err("epoll wait failed"); for (i = 0; i < len; i++) { if (ev[i].data.fd == sigfd) { int nr = read(sigfd, &si, sizeof si); if (nr > 0 && si.ssi_signo == SIGCHLD) waitpid(-1, NULL, WNOHANG); else uftrace_done = true; } else if (ev[i].data.fd == sock) handle_server_sock(&ev[i], efd); else handle_client_sock(&ev[i], efd, opts); } } close(efd); close(sigfd); close(sock); return 0; } uftrace-0.9.3/cmds/replay.c000066400000000000000000000667501351236475300155710ustar00rootroot00000000000000#include #include #include #include #include #include #include "uftrace.h" #include "utils/utils.h" #include "utils/symbol.h" #include "utils/filter.h" #include "utils/fstack.h" #include "utils/list.h" #include "utils/kernel.h" #include "utils/field.h" #include "libtraceevent/event-parse.h" static int column_index; static int prev_tid = -1; static LIST_HEAD(output_fields); #define NO_TIME (void *)1 /* to suppress duration */ static void print_duration(struct field_data *fd) { struct fstack *fstack = fd->fstack; void *arg = fd->arg; uint64_t d = 0; /* any non-NULL argument suppresses the output */ if (fstack && arg == NULL) d = fstack->total_time; print_time_unit(d); } static void print_tid(struct field_data *fd) { struct uftrace_task_reader *task = fd->task; pr_out("[%6d]", task->tid); } static void print_addr(struct field_data *fd) { struct fstack *fstack = fd->fstack; /* uftrace records (truncated) 48-bit addresses */ int width = sizeof(long) == 4 ? 8 : 12; if (fstack == NULL) /* LOST */ pr_out("%*s", width, ""); else pr_out("%*lx", width, fstack->addr); } static void print_timestamp(struct field_data *fd) { struct uftrace_task_reader *task = fd->task; uint64_t sec = task->timestamp / NSEC_PER_SEC; uint64_t nsec = task->timestamp % NSEC_PER_SEC; pr_out("%8"PRIu64".%09"PRIu64, sec, nsec); } static void print_timedelta(struct field_data *fd) { struct uftrace_task_reader *task = fd->task; uint64_t delta = 0; if (task->timestamp_last) delta = task->timestamp - task->timestamp_last; print_time_unit(delta); } static void print_elapsed(struct field_data *fd) { struct uftrace_task_reader *task = fd->task; uint64_t elapsed = task->timestamp - task->h->time_range.first; print_time_unit(elapsed); } static void print_task(struct field_data *fd) { struct uftrace_task_reader *task = fd->task; pr_out("%*s", 15, task->t->comm); } static void print_module(struct field_data *fd) { struct uftrace_task_reader *task = fd->task; struct fstack *fstack = fd->fstack; uint64_t timestamp = task->timestamp; struct uftrace_session *s; struct uftrace_mmap *map; char *modname = "[unknown]"; /* for EVENT or LOST record */ if (fstack == NULL) { pr_out("%*s", 16, ""); return; } s = find_task_session(&task->h->sessions, task->t, timestamp); if (s) { map = find_map(&s->symtabs, fstack->addr); if (map == MAP_KERNEL) modname = "[kernel]"; else if (map) modname = basename(map->libname); } pr_out("%*.*s", 16, 16, modname); } static struct display_field field_duration = { .id = REPLAY_F_DURATION, .name = "duration", .header = " DURATION ", .length = 10, .print = print_duration, .list = LIST_HEAD_INIT(field_duration.list), }; static struct display_field field_tid = { .id = REPLAY_F_TID, .name = "tid", .header = " TID ", .length = 8, .print = print_tid, .list = LIST_HEAD_INIT(field_tid.list), }; static struct display_field field_addr = { .id = REPLAY_F_ADDR, .name = "addr", #if __SIZEOF_LONG__ == 4 .header = " ADDRESS", .length = 8, #else .header = " ADDRESS ", .length = 12, #endif .print = print_addr, .list = LIST_HEAD_INIT(field_addr.list), }; static struct display_field field_time = { .id = REPLAY_F_TIMESTAMP, .name = "time", .header = " TIMESTAMP ", .length = 18, .print = print_timestamp, .list = LIST_HEAD_INIT(field_time.list), }; static struct display_field field_delta = { .id = REPLAY_F_TIMEDELTA, .name = "delta", .header = " TIMEDELTA", .length = 10, .print = print_timedelta, .list = LIST_HEAD_INIT(field_delta.list), }; static struct display_field field_elapsed = { .id = REPLAY_F_ELAPSED, .name = "elapsed", .header = " ELAPSED ", .length = 10, .print = print_elapsed, .list = LIST_HEAD_INIT(field_elapsed.list), }; static struct display_field field_task = { .id = REPLAY_F_TASK, .name = "task", .header = " TASK NAME", .length = 15, .print = print_task, .list = LIST_HEAD_INIT(field_task.list), }; static struct display_field field_module = { .id = REPLAY_F_MODULE, .name = "module", .header = " MODULE NAME", .length = 16, .print = print_module, .list = LIST_HEAD_INIT(field_module.list), }; /* index of this table should be matched to display_field_id */ static struct display_field *field_table[] = { &field_duration, &field_tid, &field_addr, &field_time, &field_delta, &field_elapsed, &field_task, &field_module, }; static void print_field(struct uftrace_task_reader *task, struct fstack *fstack, void *arg) { struct field_data fd = { .task = task, .fstack = fstack, .arg = arg, }; if (print_field_data(&output_fields, &fd, 1)) pr_out(" | "); } static void setup_default_field(struct list_head *fields, struct opts *opts) { if (opts->range.start > 0 || opts->range.stop > 0) { if (opts->range.start_elapsed || opts->range.stop_elapsed) add_field(fields, field_table[REPLAY_F_ELAPSED]); else add_field(fields, field_table[REPLAY_F_TIMESTAMP]); } add_field(fields, field_table[REPLAY_F_DURATION]); add_field(fields, field_table[REPLAY_F_TID]); } static int task_column_depth(struct uftrace_task_reader *task, struct opts *opts) { if (!opts->column_view) return 0; if (task->column_index == -1) task->column_index = column_index++; return task->column_index * opts->column_offset; } static void print_backtrace(struct uftrace_task_reader *task) { struct uftrace_session_link *sessions = &task->h->sessions; int i; for (i = 0; i < task->stack_count - 1; i++) { struct display_field *field; struct sym *sym; char *name; struct fstack *fstack = &task->func_stack[i]; struct field_data fd = { .task = task, .fstack = fstack, }; sym = task_find_sym_addr(sessions, task, fstack->total_time, fstack->addr); pr_out(" "); list_for_each_entry(field, &output_fields, list) { if (field->id == REPLAY_F_DURATION) pr_out("%*s", field->length, "backtrace"); else field->print(&fd); pr_out(" "); } if (!list_empty(&output_fields)) pr_out("| "); name = symbol_getname(sym, fstack->addr); pr_gray("/* [%2d] %s */\n", i, name); symbol_putname(sym, name); } } static void print_event(struct uftrace_task_reader *task, struct uftrace_record *urec, int color) { unsigned evt_id = urec->addr; char *evt_name = get_event_name(task->h, evt_id); if (evt_id == EVENT_ID_EXTERN_DATA) { pr_color(color, "%s: %s", evt_name, task->args.data); } else if (evt_id >= EVENT_ID_USER) { /* TODO: some events might have arguments */ pr_color(color, "%s", evt_name); } else if (evt_id >= EVENT_ID_PERF) { pr_color(color, "%s", evt_name); if (evt_id == EVENT_ID_PERF_COMM) pr_color(color, " (name=%s)", (char *)task->args.data); } else if (evt_id >= EVENT_ID_BUILTIN) { union { struct uftrace_proc_statm *statm; struct uftrace_page_fault *page_fault; struct uftrace_pmu_cycle *cycle; struct uftrace_pmu_cache *cache; struct uftrace_pmu_branch *branch; int *cpu; } u; switch (evt_id) { case EVENT_ID_READ_PROC_STATM: u.statm = task->args.data; pr_color(color, "%s (size=%"PRIu64"KB, rss=%"PRIu64"KB, shared=%"PRIu64"KB)", evt_name, u.statm->vmsize, u.statm->vmrss, u.statm->shared); return; case EVENT_ID_READ_PAGE_FAULT: u.page_fault = task->args.data; pr_color(color, "%s (major=%"PRIu64", minor=%"PRIu64")", evt_name, u.page_fault->major, u.page_fault->minor); return; case EVENT_ID_READ_PMU_CYCLE: u.cycle = task->args.data; pr_color(color, "%s (cycle=%"PRIu64", instructions=%"PRIu64")", evt_name, u.cycle->cycles, u.cycle->instrs); return; case EVENT_ID_READ_PMU_CACHE: u.cache = task->args.data; pr_color(color, "%s (refers=%"PRIu64", misses=%"PRIu64")", evt_name, u.cache->refers, u.cache->misses); return; case EVENT_ID_READ_PMU_BRANCH: u.branch = task->args.data; pr_color(color, "%s (branch=%"PRIu64", misses=%"PRIu64")", evt_name, u.branch->branch, u.branch->misses); return; case EVENT_ID_DIFF_PROC_STATM: u.statm = task->args.data; pr_color(color, "%s (size=%+"PRId64"KB, rss=%+"PRId64"KB, shared=%+"PRId64"KB)", evt_name, u.statm->vmsize, u.statm->vmrss, u.statm->shared); return; case EVENT_ID_DIFF_PAGE_FAULT: u.page_fault = task->args.data; pr_color(color, "%s (major=%+"PRId64", minor=%+"PRId64")", evt_name, u.page_fault->major, u.page_fault->minor); return; case EVENT_ID_DIFF_PMU_CYCLE: u.cycle = task->args.data; pr_color(color, "%s (cycle=%+"PRId64", instructions=%+"PRId64", IPC=%.2f)", evt_name, u.cycle->cycles, u.cycle->instrs, (float)u.cycle->instrs / u.cycle->cycles); return; case EVENT_ID_DIFF_PMU_CACHE: u.cache = task->args.data; pr_color(color, "%s (refers=%+"PRId64", misses=%+"PRId64", hit=%"PRId64"%%)", evt_name, u.cache->refers, u.cache->misses, (u.cache->refers - u.cache->misses) * 100 / u.cache->refers); return; case EVENT_ID_DIFF_PMU_BRANCH: u.branch = task->args.data; pr_color(color, "%s (branch=%+"PRId64", misses=%+"PRId64", predict=%"PRId64"%%)", evt_name, u.branch->branch, u.branch->misses, (u.branch->branch - u.branch->misses) * 100 / u.branch->branch); return; case EVENT_ID_WATCH_CPU: u.cpu = task->args.data; pr_color(color, "%s (cpu=%d)", evt_name, *u.cpu); return; default: pr_color(color, "%s", evt_name); break; } pr_color(color, "user_event:%u", evt_id); return; } else { /* kernel events */ pr_color(color, "%s (%.*s)", evt_name, task->args.len, task->args.data); } free(evt_name); } static int print_flat_rstack(struct uftrace_data *handle, struct uftrace_task_reader *task, struct opts *opts) { static int count; struct uftrace_record *rstack = task->rstack; struct uftrace_session_link *sessions = &task->h->sessions; struct sym *sym = NULL; char *name; struct fstack *fstack; sym = task_find_sym(sessions, task, rstack); name = symbol_getname(sym, rstack->addr); fstack = &task->func_stack[rstack->depth]; /* skip it if --no-libcall is given */ if (!opts->libcall && sym && sym->type == ST_PLT_FUNC) goto out; switch (rstack->type) { case UFTRACE_ENTRY: pr_out("[%d] ==> %d/%d: ip (%s), time (%"PRIu64")\n", count++, task->tid, rstack->depth, name, rstack->time); break; case UFTRACE_EXIT: pr_out("[%d] <== %d/%d: ip (%s), time (%"PRIu64":%"PRIu64")\n", count++, task->tid, rstack->depth, name, rstack->time, fstack->total_time); break; case UFTRACE_LOST: pr_out("[%d] XXX %d: lost %d records\n", count++, task->tid, (int)rstack->addr); break; case UFTRACE_EVENT: pr_out("[%d] !!! %d: ", count++, task->tid); print_event(task, rstack, task->event_color); pr_out(" time (%"PRIu64")\n", rstack->time); break; } out: symbol_putname(sym, name); return 0; } static void print_task_newline(int current_tid) { if (prev_tid != -1 && current_tid != prev_tid) { if (print_empty_field(&output_fields, 1)) pr_out(" | "); pr_out("\n"); } prev_tid = current_tid; } #define print_args(fmt, ...) \ ({ int _x = snprintf(args + n, len, fmt, ##__VA_ARGS__); n += _x; len -= _x; }) #define print_escaped_char(c) \ do { \ if (c == '\n') \ print_args("\\\\n"); \ else if (c == '\t') \ print_args("\\\\t"); \ else if (c == '\\') \ print_args("\\\\"); \ else if (c == '"') \ print_args("\\\""); \ else if (isprint(c)) \ print_args("%c", c); \ else \ print_args("\\\\x%02hhx", c); \ } while (0) void get_argspec_string(struct uftrace_task_reader *task, char *args, size_t len, enum argspec_string_bits str_mode) { int i = 0, n = 0; char *str = NULL; const int null_str = -1; void *data = task->args.data; struct list_head *arg_list = task->args.args; struct uftrace_arg_spec *spec; union { long i; void *p; float f; double d; long long ll; long double D; unsigned char v[16]; } val; bool needs_paren = !!(str_mode & NEEDS_PAREN); bool needs_semi_colon = !!(str_mode & NEEDS_SEMI_COLON); bool has_more = !!(str_mode & HAS_MORE); bool is_retval = !!(str_mode & IS_RETVAL); bool needs_assignment = !!(str_mode & NEEDS_ASSIGNMENT); bool needs_escape = !!(str_mode & NEEDS_ESCAPE); if (!has_more) { if (needs_paren) strcpy(args, "()"); else { if (is_retval && needs_semi_colon) args[n++] = ';'; args[n] = '\0'; } return; } assert(arg_list && !list_empty(arg_list)); if (needs_paren) print_args("%s(%s", color_bold, color_reset); else if (needs_assignment) print_args("%s = %s", color_bold, color_reset); list_for_each_entry(spec, arg_list, list) { char fmtstr[16]; char *len_mod[] = { "hh", "h", "", "ll" }; char fmt, *lm; unsigned idx; size_t size = spec->size; /* skip unwanted arguments or retval */ if (is_retval != (spec->idx == RETVAL_IDX)) continue; if (i > 0) print_args("%s, %s", color_bold, color_reset); memset(val.v, 0, sizeof(val)); fmt = ARG_SPEC_CHARS[spec->fmt]; switch (spec->fmt) { case ARG_FMT_AUTO: memcpy(val.v, data, spec->size); if (val.i > 100000L || val.i < -100000L) { fmt = 'x'; /* * Show small negative integers naturally * on 64-bit systems. The conversion is * required to avoid compiler warnings * on 32-bit systems. */ if (sizeof(long) == sizeof(uint64_t)) { uint64_t val64 = val.i; if (val64 > 0xffff0000 && val64 <= 0xffffffff) { fmt = 'd'; idx = 2; break; } } } /* fall through */ case ARG_FMT_SINT: case ARG_FMT_HEX: idx = ffs(spec->size) - 1; break; case ARG_FMT_UINT: memcpy(val.v, data, spec->size); if ((unsigned long)val.i > 100000UL) fmt = 'x'; idx = ffs(spec->size) - 1; break; default: idx = 2; break; } if (spec->fmt == ARG_FMT_STR || spec->fmt == ARG_FMT_STD_STRING) { unsigned short slen; unsigned short newline = 0; char last_ch; memcpy(&slen, data, 2); last_ch = *((char *)data + slen + 1); if (last_ch == '\n') newline = 1; str = xmalloc(slen + newline + 1); memcpy(str, data + 2, slen); str[slen] = '\0'; if (newline) { str[slen - 1] = '\\'; str[slen] = 'n'; str[slen + 1] = '\0'; } if (!memcmp(str, &null_str, sizeof(null_str))) print_args("NULL"); else if (needs_escape) { char *p = str; print_args("\\\""); while (*p) { char c = *p++; print_escaped_char(c); } print_args("\\\""); } else { print_args("%s", color_string); print_args("\"%.*s\"", slen + newline, str); print_args("%s", color_reset); } /* std::string can be represented as "TEXT"s from C++14 */ if (spec->fmt == ARG_FMT_STD_STRING) print_args("s"); free(str); size = slen + 2; } else if (spec->fmt == ARG_FMT_CHAR) { char c; memcpy(&c, data, 1); if (needs_escape) { print_args("'"); print_escaped_char(c); print_args("'"); } else { print_args("%s", color_string); print_args("'%c'", c); print_args("%s", color_reset); } size = 1; } else if (spec->fmt == ARG_FMT_FLOAT) { if (spec->size == 10) lm = "L"; else lm = len_mod[idx]; memcpy(val.v, data, spec->size); snprintf(fmtstr, sizeof(fmtstr), "%%#%s%c", lm, fmt); switch (spec->size) { case 4: print_args(fmtstr, val.f); break; case 8: print_args(fmtstr, val.d); break; case 10: print_args(fmtstr, val.D); break; default: pr_dbg("invalid floating-point type size %d\n", spec->size); break; } } else if (spec->fmt == ARG_FMT_PTR) { struct uftrace_session_link *sessions = &task->h->sessions; struct sym *sym; memcpy(val.v, data, spec->size); sym = task_find_sym_addr(sessions, task, task->rstack->time, (uint64_t)val.i); if (sym) { print_args("%s", color_symbol); print_args("&%s", sym->name); print_args("%s", color_reset); } else if (val.p) print_args("%p", val.p); else print_args("0"); } else if (spec->fmt == ARG_FMT_ENUM) { struct uftrace_session_link *sessions = &task->h->sessions; struct uftrace_session *s; struct uftrace_mmap *map; struct debug_info *dinfo; char *estr; memcpy(val.v, data, spec->size); s = find_task_session(sessions, task->t, task->rstack->time); map = find_map(&s->symtabs, task->rstack->addr); if (map == NULL || map->mod == NULL) { print_args(" %lx", val.i); goto next; } dinfo = &map->mod->dinfo; estr = get_enum_string(&dinfo->enums, spec->enum_str, val.i); if (strstr(estr, "|") && strcmp("|", color_enum_or)) { struct strv enum_vals = STRV_INIT; strv_split(&enum_vals, estr, "|"); free(estr); estr = strv_join(&enum_vals, color_enum_or); strv_free(&enum_vals); } print_args("%s", color_enum); if (strlen(estr) >= len) print_args(""); else print_args("%s", estr); print_args("%s", color_reset); free(estr); } else { if (spec->fmt != ARG_FMT_AUTO) memcpy(val.v, data, spec->size); assert(idx < ARRAY_SIZE(len_mod)); lm = len_mod[idx]; snprintf(fmtstr, sizeof(fmtstr), "%%#%s%c", lm, fmt); if (spec->size == 8) print_args(fmtstr, val.ll); else print_args(fmtstr, val.i); } next: i++; data += ALIGN(size, 4); if (len <= 2) break; /* read only the first match for retval */ if (is_retval) break; } if (needs_paren) { print_args("%s)%s", color_bold, color_reset); } else { if (needs_semi_colon) args[n++] = ';'; args[n] = '\0'; } } static int print_graph_rstack(struct uftrace_data *handle, struct uftrace_task_reader *task, struct opts *opts) { struct uftrace_record *rstack; struct uftrace_session_link *sessions = &handle->sessions; struct sym *sym = NULL; enum argspec_string_bits str_mode = 0; char *symname = NULL; char args[1024]; char *libname = ""; struct uftrace_mmap *map = NULL; if (task == NULL) return 0; rstack = task->rstack; if (rstack->type == UFTRACE_LOST) goto lost; sym = task_find_sym(sessions, task, rstack); symname = symbol_getname(sym, rstack->addr); /* skip it if --no-libcall is given */ if (!opts->libcall && sym && sym->type == ST_PLT_FUNC) goto out; if (rstack->type == UFTRACE_ENTRY) { if (symname[strlen(symname) - 1] != ')' || rstack->more) str_mode |= NEEDS_PAREN; } task->timestamp_last = task->timestamp; task->timestamp = rstack->time; if (opts->libname && sym && sym->type == ST_PLT_FUNC) { struct uftrace_session *s; s = find_task_session(sessions, task->t, rstack->time); if (s != NULL) { map = find_symbol_map(&s->symtabs, symname); if (map != NULL) libname = basename(map->libname); } } if (rstack->type == UFTRACE_ENTRY) { struct uftrace_task_reader *next = NULL; struct fstack *fstack; int rstack_depth = rstack->depth; int depth; struct uftrace_trigger tr = { .flags = 0, }; int ret; ret = fstack_entry(task, rstack, &tr); if (ret < 0) goto out; /* display depth is set in fstack_entry() */ depth = task->display_depth; /* give a new line when tid is changed */ if (opts->task_newline) print_task_newline(task->tid); if (tr.flags & TRIGGER_FL_BACKTRACE) print_backtrace(task); if (tr.flags & TRIGGER_FL_COLOR) task->event_color = tr.color; else task->event_color = DEFAULT_EVENT_COLOR; depth += task_column_depth(task, opts); if (rstack->more) str_mode |= HAS_MORE; get_argspec_string(task, args, sizeof(args), str_mode); fstack = &task->func_stack[task->stack_count - 1]; if (!opts->no_merge) next = fstack_skip(handle, task, rstack_depth, opts); if (task == next && next->rstack->depth == rstack_depth && next->rstack->type == UFTRACE_EXIT) { char retval[1024]; /* leaf function - also consume return record */ fstack_consume(handle, next); str_mode = IS_RETVAL | NEEDS_SEMI_COLON; if (next->rstack->more) { str_mode |= HAS_MORE; str_mode |= NEEDS_ASSIGNMENT; } get_argspec_string(task, retval, sizeof(retval), str_mode); print_field(task, fstack, NULL); pr_out("%*s", depth * 2, ""); if (tr.flags & TRIGGER_FL_COLOR) { pr_color(tr.color, "%s", symname); if (*libname) pr_color(tr.color, "@%s", libname); pr_out("%s%s\n", args, retval); } else { pr_out("%s%s%s%s%s\n", symname, *libname ? "@" : "", libname, args, retval); } /* fstack_update() is not needed here */ fstack_exit(task); } else { /* function entry */ print_field(task, fstack, NO_TIME); pr_out("%*s", depth * 2, ""); if (tr.flags & TRIGGER_FL_COLOR) { pr_color(tr.color, "%s", symname); if (*libname) pr_color(tr.color, "@%s", libname); pr_out("%s {\n", args); } else { pr_out("%s%s%s%s {\n", symname, *libname ? "@" : "", libname, args); } fstack_update(UFTRACE_ENTRY, task, fstack); } } else if (rstack->type == UFTRACE_EXIT) { struct fstack *fstack; /* function exit */ fstack = &task->func_stack[task->stack_count]; if (!(fstack->flags & FSTACK_FL_NORECORD) && fstack_enabled) { int depth = fstack_update(UFTRACE_EXIT, task, fstack); char *retval = args; depth += task_column_depth(task, opts); str_mode = IS_RETVAL; if (rstack->more) { str_mode |= HAS_MORE; str_mode |= NEEDS_ASSIGNMENT; str_mode |= NEEDS_SEMI_COLON; } get_argspec_string(task, retval, sizeof(args), str_mode); /* give a new line when tid is changed */ if (opts->task_newline) print_task_newline(task->tid); print_field(task, fstack, NULL); pr_out("%*s}%s", depth * 2, "", retval); if (opts->comment) pr_gray(" /* %s%s%s */\n", symname, *libname ? "@" : "", libname); else pr_gray("\n"); } fstack_exit(task); } else if (rstack->type == UFTRACE_LOST) { int depth, losts; lost: depth = task->display_depth + 1; losts = (int)rstack->addr; /* skip kernel lost messages outside of user functions */ if (opts->kernel_skip_out && task->user_stack_count == 0) return 0; /* give a new line when tid is changed */ if (opts->task_newline) print_task_newline(task->tid); print_field(task, NULL, NO_TIME); if (losts > 0) pr_red("%*s/* LOST %d records!! */\n", depth * 2, "", losts); else /* kernel sometimes have unknown count */ pr_red("%*s/* LOST some records!! */\n", depth * 2, ""); return 0; } else if (rstack->type == UFTRACE_EVENT) { int depth; struct fstack *fstack; struct uftrace_task_reader *next = NULL; struct uftrace_record rec = *rstack; uint64_t evt_id = rstack->addr; depth = task->display_depth; if (!fstack_check_filter(task)) goto out; /* give a new line when tid is changed */ if (opts->task_newline) print_task_newline(task->tid); depth += task_column_depth(task, opts); /* * try to merge a subsequent sched-in event: * it might overwrite rstack - use (saved) rec for printing. */ if (evt_id == EVENT_ID_PERF_SCHED_OUT && !opts->no_merge) next = fstack_skip(handle, task, 0, opts); if (task == next && next->rstack->addr == EVENT_ID_PERF_SCHED_IN) { /* consume the matching sched-in record */ fstack_consume(handle, next); rec.addr = sched_sym.addr; evt_id = EVENT_ID_PERF_SCHED_IN; } /* show external data regardless of display depth */ if (evt_id == EVENT_ID_EXTERN_DATA) depth = 0; /* for sched-in to show schedule duration */ fstack = &task->func_stack[task->stack_count]; if (!(fstack->flags & FSTACK_FL_NORECORD) && fstack_enabled) { if (evt_id == EVENT_ID_PERF_SCHED_IN && fstack->total_time) print_field(task, fstack, NULL); else print_field(task, NULL, NO_TIME); pr_color(task->event_color, "%*s/* ", depth * 2, ""); print_event(task, &rec, task->event_color); pr_color(task->event_color, " */\n"); } } out: symbol_putname(sym, symname); return 0; } static void print_warning(struct uftrace_task_reader *task) { if (print_empty_field(&output_fields, 1)) pr_out(" | "); pr_red(" %*s/* inverted time: broken data? */\n", (task->display_depth + 1) * 2, ""); } static bool skip_sys_exit(struct opts *opts, struct uftrace_task_reader *task) { uint64_t ip; struct sym *sym; if (task->func_stack == NULL) return true; /* skip 'sys_exit[_group] at last for kernel tracing */ if (!has_kernel_data(task->h->kernel) || task->user_stack_count != 0) return false; ip = task->func_stack[0].addr; sym = find_symtabs(&task->h->sessions.first->symtabs, ip); if (sym == NULL) return false; /* Linux 4.17 added __x64_sys_exit, __ia32_sys_exit and so on */ if (strstr(sym->name, "sys_exit")) return true; if (!strcmp(sym->name, "do_syscall_64")) return true; return false; } static void print_remaining_stack(struct opts *opts, struct uftrace_data *handle) { int i, k; int total = 0; struct uftrace_session_link *sessions = &handle->sessions; for (i = 0; i < handle->nr_tasks; i++) { struct uftrace_task_reader *task = &handle->tasks[i]; int zero_count = 0; if (skip_sys_exit(opts, task)) continue; for (k = 0; k < task->stack_count; k++) { if (task->func_stack[k].addr) break; zero_count++; } total += task->stack_count - zero_count; } if (total == 0) return; pr_out("\nuftrace stopped tracing with remaining functions"); pr_out("\n================================================\n"); for (i = 0; i < handle->nr_tasks; i++) { struct uftrace_task_reader *task = &handle->tasks[i]; int zero_count = 0; if (task->stack_count == 0) continue; for (k = 0; k < task->stack_count; k++) { if (task->func_stack[k].addr) break; zero_count++; } if (zero_count == task->stack_count) continue; if (skip_sys_exit(opts, task)) continue; pr_out("task: %d\n", task->tid); while (task->stack_count-- > 0) { struct fstack *fstack = &task->func_stack[task->stack_count]; uint64_t time = fstack->total_time; uint64_t ip = fstack->addr; struct sym *sym; char *symname; sym = task_find_sym_addr(sessions, task, time, ip); symname = symbol_getname(sym, ip); pr_out("[%d] %s\n", task->stack_count - zero_count, symname); symbol_putname(sym, symname); if (task->stack_count == zero_count) break; } pr_out("\n"); } } int command_replay(int argc, char *argv[], struct opts *opts) { int ret; uint64_t prev_time = 0; struct uftrace_data handle; struct uftrace_task_reader *task; __fsetlocking(outfp, FSETLOCKING_BYCALLER); __fsetlocking(logfp, FSETLOCKING_BYCALLER); ret = open_data_file(opts, &handle); if (ret < 0) { pr_warn("cannot open record data: %s: %m\n", opts->dirname); return -1; } fstack_setup_filters(opts, &handle); setup_field(&output_fields, opts, &setup_default_field, field_table, ARRAY_SIZE(field_table)); if (!opts->flat && peek_rstack(&handle, &task) == 0) print_header(&output_fields, "#", 1); while (read_rstack(&handle, &task) == 0 && !uftrace_done) { struct uftrace_record *rstack = task->rstack; uint64_t curr_time = rstack->time; if (!fstack_check_opts(task, opts)) continue; /* * data sanity check: timestamp should be ordered. * But print_graph_rstack() may change task->rstack * during fstack_skip(). So check the timestamp here. */ if (curr_time) { if (prev_time > curr_time) print_warning(task); prev_time = rstack->time; } if (opts->flat) ret = print_flat_rstack(&handle, task, opts); else ret = print_graph_rstack(&handle, task, opts); if (ret) break; } print_remaining_stack(opts, &handle); close_data_file(opts, &handle); return ret; } uftrace-0.9.3/cmds/report.c000066400000000000000000000361571351236475300156060ustar00rootroot00000000000000#include #include #include #include "uftrace.h" #include "utils/utils.h" #include "utils/rbtree.h" #include "utils/symbol.h" #include "utils/list.h" #include "utils/fstack.h" #include "utils/report.h" enum { AVG_NONE, AVG_TOTAL, AVG_SELF, AVG_ANY, } avg_mode = AVG_NONE; /* maximum length of symbol */ static int maxlen = 20; static void insert_node(struct rb_root *root, struct uftrace_task_reader *task, char *symname) { struct uftrace_report_node *node; node = report_find_node(root, symname); if (node == NULL) { node = xzalloc(sizeof(*node)); report_add_node(root, symname, node); } report_update_node(node, task); } static void find_insert_node(struct rb_root *root, struct uftrace_task_reader *task, uint64_t timestamp, uint64_t addr) { struct sym *sym; char *symname; sym = task_find_sym_addr(&task->h->sessions, task, timestamp, addr); symname = symbol_getname(sym, addr); insert_node(root, task, symname); symbol_putname(sym, symname); } static void add_lost_fstack(struct rb_root *root, struct uftrace_task_reader *task) { struct fstack *fstack; while (task->stack_count >= task->user_stack_count) { fstack = &task->func_stack[task->stack_count]; if (fstack_enabled && fstack->valid && !(fstack->flags & FSTACK_FL_NORECORD)) { find_insert_node(root, task, task->timestamp_last, fstack->addr); } fstack_exit(task); task->stack_count--; } } static void add_remaining_fstack(struct uftrace_data *handle, struct rb_root *root) { struct uftrace_task_reader *task; struct fstack *fstack; int i; for (i = 0; i < handle->nr_tasks; i++) { uint64_t last_time; task = &handle->tasks[i]; if (task->stack_count == 0) continue; last_time = task->rstack->time; if (handle->time_range.stop) last_time = handle->time_range.stop; while (--task->stack_count >= 0) { fstack = &task->func_stack[task->stack_count]; if (fstack->addr == 0) continue; if (fstack->total_time > last_time) continue; fstack->total_time = last_time - fstack->total_time; if (fstack->child_time > fstack->total_time) fstack->total_time = fstack->child_time; if (task->stack_count > 0) fstack[-1].child_time += fstack->total_time; find_insert_node(root, task, last_time, fstack->addr); } } } static void build_function_tree(struct uftrace_data *handle, struct rb_root *root, struct opts *opts) { struct uftrace_session_link *sessions = &handle->sessions; struct sym *sym = NULL; struct uftrace_record *rstack; struct uftrace_task_reader *task; uint64_t addr; while (read_rstack(handle, &task) >= 0 && !uftrace_done) { rstack = task->rstack; if (rstack->type != UFTRACE_LOST) task->timestamp_last = rstack->time; if (!fstack_check_opts(task, opts)) continue; if (!fstack_check_filter(task)) continue; if (rstack->type == UFTRACE_ENTRY) continue; if (rstack->type == UFTRACE_EVENT) { if (rstack->addr == EVENT_ID_PERF_SCHED_IN) insert_node(root, task, sched_sym.name); continue; } if (rstack->type == UFTRACE_LOST) { /* add partial duration of functions before LOST */ add_lost_fstack(root, task); continue; } /* rstack->type == UFTRACE_EXIT */ addr = rstack->addr; if (is_kernel_record(task, rstack)) { struct uftrace_session *fsess; fsess = sessions->first; addr = get_kernel_address(&fsess->symtabs, rstack->addr); } /* skip it if --no-libcall is given */ sym = task_find_sym(sessions, task, rstack); if (!opts->libcall && sym && sym->type == ST_PLT_FUNC) continue; find_insert_node(root, task, rstack->time, addr); } if (uftrace_done) return; add_remaining_fstack(handle, root); } static void print_and_delete(struct rb_root *root, bool sorted, void *arg, void (*print_func)(struct uftrace_report_node *, void *)) { while (!RB_EMPTY_ROOT(root)) { struct rb_node *n; struct uftrace_report_node *node; n = rb_first(root); rb_erase(n, root); if (sorted) node = rb_entry(n, typeof(*node), sort_link); else node = rb_entry(n, typeof(*node), name_link); print_func(node, arg); free(node); } } static void print_function(struct uftrace_report_node *node, void *unused) { if (avg_mode == AVG_NONE) { pr_out(" "); print_time_unit(node->total.sum); pr_out(" "); print_time_unit(node->self.sum); pr_out(" %10lu %-s\n", node->call, node->name); } else { uint64_t time_avg, time_min, time_max; if (avg_mode == AVG_TOTAL) { time_avg = node->total.avg; time_min = node->total.min; time_max = node->total.max; } else { time_avg = node->self.avg; time_min = node->self.min; time_max = node->self.max; } pr_out(" "); print_time_unit(time_avg); pr_out(" "); print_time_unit(time_min); pr_out(" "); print_time_unit(time_max); pr_out(" %-s\n", node->name); } } static void report_functions(struct uftrace_data *handle, struct opts *opts) { struct rb_root name_root = RB_ROOT; struct rb_root sort_root = RB_ROOT; const char f_format[] = " %10.10s %10.10s %10.10s %-.*s\n"; const char line[] = "================================================="; build_function_tree(handle, &name_root, opts); report_calc_avg(&name_root); report_sort_nodes(&name_root, &sort_root); if (uftrace_done) return; if (avg_mode == AVG_NONE) pr_out(f_format, "Total time", "Self time", "Calls", maxlen, "Function"); else if (avg_mode == AVG_TOTAL) pr_out(f_format, "Avg total", "Min total", "Max total", maxlen, "Function"); else if (avg_mode == AVG_SELF) pr_out(f_format, "Avg self", "Min self", "Max self", maxlen, "Function"); pr_out(f_format, line, line, line, maxlen, line); print_and_delete(&sort_root, true, NULL, print_function); } static struct sym * find_task_sym(struct uftrace_data *handle, struct uftrace_task_reader *task, struct uftrace_record *rstack) { struct sym *sym; struct uftrace_task_reader *main_task = &handle->tasks[0]; struct uftrace_session *sess = find_task_session(&handle->sessions, task->t, rstack->time); struct symtabs *symtabs = &sess->symtabs; if (task->func) return task->func; if (sess == NULL) { pr_dbg("cannot find session for tid %d\n", task->tid); return NULL; } if (is_kernel_record(task, rstack)) return NULL; if (task == main_task) { /* This is the main thread */ struct uftrace_module *mod = symtabs->maps->mod; task->func = sym = find_symname(&mod->symtab, "main"); if (sym) return sym; pr_dbg("no main thread???\n"); /* fall through */ } task->func = sym = find_symtabs(symtabs, rstack->addr); if (sym == NULL) pr_dbg("cannot find symbol for %lx\n", rstack->addr); return sym; } static void print_thread(struct uftrace_report_node *node, void *arg) { int pid; const char *symname; struct uftrace_task_reader *task; struct uftrace_data *handle = arg; pid = strtol(node->name, NULL, 10); task = get_task_handle(handle, pid); if (task == NULL || task->func == NULL) symname = "unknown"; else symname = task->func->name; pr_out(" %5d ", pid); print_time_unit(node->self.sum); pr_out(" %10lu %-s\n", node->call, symname); } static void report_threads(struct uftrace_data *handle, struct opts *opts) { struct uftrace_record *rstack; struct rb_root task_tree = RB_ROOT; struct uftrace_task_reader *task; const char t_format[] = " %5.5s %10.10s %10.10s %-.*s\n"; const char line[] = "================================================="; char buf[10]; while (read_rstack(handle, &task) >= 0 && !uftrace_done) { rstack = task->rstack; if (rstack->type == UFTRACE_ENTRY) { if (task->func == NULL) find_task_sym(handle, task, rstack); continue; } if (rstack->type == UFTRACE_LOST) continue; if (!fstack_check_opts(task, opts)) continue; if (!fstack_check_filter(task)) continue; /* UFTRACE_EXIT */ snprintf(buf, sizeof(buf), "%d", task->tid); insert_node(&task_tree, task, buf); } if (uftrace_done) return; pr_out(t_format, "TID", "Run time", "Num funcs", maxlen, "Start function"); pr_out(t_format, line, line, line, maxlen, line); print_and_delete(&task_tree, false, handle, print_thread); } struct diff_data { char *dirname; struct rb_root root; struct uftrace_data handle; }; #define NODATA "-" static void print_time_or_dash(uint64_t time_nsec) { if (time_nsec) print_time_unit(time_nsec); else pr_out("%10s", NODATA); } static void print_function_diff(struct uftrace_report_node *node, void *arg) { struct uftrace_report_node *pair = node->pair; if (avg_mode == AVG_NONE) { pr_out(" "); if (diff_policy.full) { print_time_or_dash(node->total.sum); pr_out(" "); print_time_or_dash(pair->total.sum); pr_out(" "); } else if (diff_policy.percent) pr_out(" "); if (diff_policy.percent) print_diff_percent(node->total.sum, pair->total.sum); else print_diff_time_unit(node->total.sum, pair->total.sum); pr_out(" "); if (diff_policy.full) { print_time_or_dash(node->self.sum); pr_out(" "); print_time_or_dash(pair->self.sum); pr_out(" "); } else if (diff_policy.percent) pr_out(" "); if (diff_policy.percent) print_diff_percent(node->self.sum, pair->self.sum); else print_diff_time_unit(node->self.sum, pair->self.sum); pr_out(" "); if (diff_policy.full) pr_out(" %9lu %9lu", node->call, pair->call); pr_out(" "); print_diff_count(node->call, pair->call); pr_out(" %-s\n", node->name); } else { uint64_t time_avg, time_min, time_max; uint64_t pair_avg, pair_min, pair_max; if (avg_mode == AVG_TOTAL) { time_avg = node->total.avg; time_min = node->total.min; time_max = node->total.max; pair_avg = pair->total.avg; pair_min = pair->total.min; pair_max = pair->total.max; } else { time_avg = node->self.avg; time_min = node->self.min; time_max = node->self.max; pair_avg = pair->self.avg; pair_min = pair->self.min; pair_max = pair->self.max; } pr_out(" "); if (diff_policy.full) { print_time_unit(time_avg); pr_out(" "); print_time_unit(time_avg); pr_out(" "); } else if (diff_policy.percent) pr_out(" "); if (diff_policy.percent) print_diff_percent(time_avg, pair_avg); else print_diff_time_unit(time_avg, pair_avg); pr_out(" "); if (diff_policy.full) { print_time_unit(time_min); pr_out(" "); print_time_unit(pair_min); pr_out(" "); } else if (diff_policy.percent) pr_out(" "); if (diff_policy.percent) print_diff_percent(time_min, pair_min); else print_diff_time_unit(time_min, pair_min); pr_out(" "); if (diff_policy.full) { print_time_unit(time_max); pr_out(" "); print_time_unit(pair_max); pr_out(" "); } else if (diff_policy.percent) pr_out(" "); if (diff_policy.percent) print_diff_percent(time_max, pair_max); else print_diff_time_unit(time_max, pair_max); pr_out(" %-s\n", node->name); } } static void print_nothing(struct uftrace_report_node *node, void *unused) { /* just delete */ } static void report_diff(struct uftrace_data *handle, struct opts *opts) { struct opts dummy_opts = { .dirname = opts->diff, .kernel = opts->kernel, .depth = opts->depth, .libcall = opts->libcall, }; struct diff_data data = { .dirname = opts->diff, .root = RB_ROOT, }; struct rb_root base_tree = RB_ROOT; struct rb_root pair_tree = RB_ROOT; struct rb_root diff_tree = RB_ROOT; const char *formats[] = { " %35.35s %35.35s %32.32s %-.*s\n", /* diff numbers */ " %32.32s %32.32s %32.32s %-.*s\n", /* diff percent */ " %35.35s %35.35s %35.35s %-.*s\n", /* diff avg numbers */ " %11.11s %11.11s %11.11s %-.*s\n", /* diff compact */ }; const char line[] = "================================================="; const char *headers[][3] = { { "Total time (diff)", "Self time (diff)", "Calls (diff)" }, { "Avg total (diff)", "Min total (diff)", "Max total (diff)" }, { "Avg self (diff)", "Min self (diff)", "Max self (diff)" }, { "Total time", "Self time", "Calls" }, { "Avg total", "Min total", "Max total" }, { "Avg self", "Min self", "Max self" }, }; int h_idx = (avg_mode == AVG_NONE) ? 0 : (avg_mode == AVG_TOTAL) ? 1 : 2; int f_idx = diff_policy.percent ? 1 : (avg_mode == AVG_NONE) ? 0 : 2; if (!diff_policy.full) { h_idx += 3; f_idx = 3; } build_function_tree(handle, &base_tree, opts); report_calc_avg(&base_tree); if (open_data_file(&dummy_opts, &data.handle) < 0) { pr_warn("cannot open record data: %s: %m\n", opts->diff); goto out; } fstack_setup_filters(&dummy_opts, &data.handle); build_function_tree(&data.handle, &pair_tree, &dummy_opts); report_calc_avg(&pair_tree); report_diff_nodes(&base_tree, &pair_tree, &diff_tree, opts->sort_column); if (uftrace_done) goto out; pr_out("#\n"); pr_out("# uftrace diff\n"); pr_out("# [%d] base: %s\t(from %s)\n", 0, handle->dirname, handle->info.cmdline); pr_out("# [%d] diff: %s\t(from %s)\n", 1, opts->diff, data.handle.info.cmdline); pr_out("#\n"); pr_out(formats[f_idx], headers[h_idx][0], headers[h_idx][1], headers[h_idx][2], maxlen, "Function"); pr_out(formats[f_idx], line, line, line, maxlen, line); print_and_delete(&diff_tree, true, NULL, print_function_diff); out: destroy_diff_nodes(&diff_tree); print_and_delete(&base_tree, false, NULL, print_nothing); print_and_delete(&pair_tree, false, NULL, print_nothing); close_data_file(&dummy_opts, &data.handle); } char * convert_sort_keys(char *sort_keys) { const char *default_sort_key[] = { "total", "total_avg", "self_avg", "total" }; struct strv keys = STRV_INIT; char *new_keys; char *k; int i; if (sort_keys == NULL) return xstrdup(default_sort_key[avg_mode]); if (avg_mode == AVG_NONE) return xstrdup(sort_keys); strv_split(&keys, sort_keys, ","); strv_for_each(&keys, k, i) { if (!strcmp(k, "avg")) { strv_replace(&keys, i, avg_mode == AVG_TOTAL ? "total_avg" : "self_avg"); } else if (!strcmp(k, "min")) { strv_replace(&keys, i, avg_mode == AVG_TOTAL ? "total_min" : "self_min"); } else if (!strcmp(k, "max")) { strv_replace(&keys, i, avg_mode == AVG_TOTAL ? "total_max" : "self_max"); } } new_keys = strv_join(&keys, ","); strv_free(&keys); return new_keys; } int command_report(int argc, char *argv[], struct opts *opts) { int ret; char *sort_keys; struct uftrace_data handle; if (opts->avg_total && opts->avg_self) { pr_use("--avg-total and --avg-self options should not be used together.\n"); exit(1); } else if (opts->avg_total) avg_mode = AVG_TOTAL; else if (opts->avg_self) avg_mode = AVG_SELF; ret = open_data_file(opts, &handle); if (ret < 0) { pr_warn("cannot open record data: %s: %m\n", opts->dirname); return -1; } fstack_setup_filters(opts, &handle); sort_keys = convert_sort_keys(opts->sort_keys); if (opts->diff) ret = report_setup_diff(sort_keys); else ret = report_setup_sort(sort_keys); free(sort_keys); if (ret < 0) { pr_use("invalid sort key: %s\n", opts->sort_keys); return -1; } if (opts->diff_policy) apply_diff_policy(opts->diff_policy); if (opts->report_thread) report_threads(&handle, opts); else if (opts->diff) report_diff(&handle, opts); else report_functions(&handle, opts); close_data_file(opts, &handle); return 0; } uftrace-0.9.3/cmds/script.c000066400000000000000000000110331351236475300155610ustar00rootroot00000000000000/* * Python script binding for function entry and exit * * Copyright (C) 2017-2018, LG Electronics, Honggyu Kim * * Released under the GPL v2. */ #include #include #include #include "uftrace.h" #include "version.h" #include "utils/utils.h" #include "utils/symbol.h" #include "utils/filter.h" #include "utils/fstack.h" #include "utils/script.h" #include "libtraceevent/event-parse.h" static int run_script_for_rstack(struct uftrace_data *handle, struct uftrace_task_reader *task, struct opts *opts) { struct uftrace_record *rstack = task->rstack; struct uftrace_session_link *sessions = &handle->sessions; struct sym *sym = NULL; char *symname = NULL; sym = task_find_sym(sessions, task, rstack); symname = symbol_getname(sym, rstack->addr); /* skip it if --no-libcall is given */ if (!opts->libcall && sym && sym->type == ST_PLT_FUNC) goto out; task->timestamp_last = task->timestamp; task->timestamp = rstack->time; if (rstack->type == UFTRACE_ENTRY) { struct fstack *fstack; int depth; struct uftrace_trigger tr = { .flags = 0, }; int ret; ret = fstack_entry(task, rstack, &tr); if (ret < 0) goto out; /* display depth is set in fstack_entry() */ depth = task->display_depth; fstack = &task->func_stack[task->stack_count - 1]; fstack_update(UFTRACE_ENTRY, task, fstack); if (!script_match_filter(symname)) goto out; /* setup context for script execution */ struct script_context sc_ctx = { .tid = task->tid, .depth = depth, /* display depth */ .timestamp = rstack->time, .address = rstack->addr, .name = symname, }; if (tr.flags & TRIGGER_FL_ARGUMENT) { sc_ctx.argbuf = task->args.data; sc_ctx.arglen = task->args.len; sc_ctx.argspec = task->args.args; } /* script hooking for function entry */ script_uftrace_entry(&sc_ctx); } else if (rstack->type == UFTRACE_EXIT) { struct fstack *fstack; /* function exit */ fstack = &task->func_stack[task->stack_count]; if (!(fstack->flags & FSTACK_FL_NORECORD) && fstack_enabled) { int depth = fstack_update(UFTRACE_EXIT, task, fstack); if (!script_match_filter(symname)) { fstack_exit(task); goto out; } /* display depth is set before passing rstack */ rstack->depth = depth; /* setup context for script execution */ struct script_context sc_ctx = { .tid = task->tid, .depth = rstack->depth, .timestamp = rstack->time, .duration = fstack->total_time, .address = rstack->addr, .name = symname, }; if (rstack->more) { sc_ctx.argbuf = task->args.data; sc_ctx.arglen = task->args.len; sc_ctx.argspec = task->args.args; } /* script hooking for function exit */ script_uftrace_exit(&sc_ctx); } fstack_exit(task); } else if (rstack->type == UFTRACE_LOST) { /* Do nothing as of now */ } else if (rstack->type == UFTRACE_EVENT) { /* TODO: event handling */ } out: symbol_putname(sym, symname); return 0; } int command_script(int argc, char *argv[], struct opts *opts) { int ret; struct uftrace_data handle; struct uftrace_task_reader *task; struct script_info info = { .name = opts->script_file, .version = UFTRACE_VERSION, }; if (!SCRIPT_ENABLED) { pr_warn("script command is not supported due to missing libpython2.7.so\n"); return -1; } if (!opts->script_file) { pr_out("Usage: uftrace script [-S|--script] []\n"); return -1; } if (opts->record) { /* parse in-script record option - "uftrace_options" */ parse_script_opt(opts); char *script_file = opts->script_file; opts->script_file = NULL; pr_dbg("start recording before running a script\n"); ret = command_record(argc, argv, opts); if (ret < 0) { pr_warn("cannot record data: %m\n"); return -1; } opts->script_file = script_file; } __fsetlocking(outfp, FSETLOCKING_BYCALLER); __fsetlocking(logfp, FSETLOCKING_BYCALLER); ret = open_data_file(opts, &handle); if (ret < 0) { pr_warn("cannot open record data: %s: %m\n", opts->dirname); return -1; } fstack_setup_filters(opts, &handle); strv_copy(&info.cmds, argc, argv); /* initialize script */ if (script_init(&info, opts->patt_type) < 0) return -1; while (read_rstack(&handle, &task) == 0 && !uftrace_done) { if (!fstack_check_opts(task, opts)) continue; ret = run_script_for_rstack(&handle, task, opts); if (ret) break; } /* dtor for script support */ script_uftrace_end(); script_finish(); close_data_file(opts, &handle); return ret; } uftrace-0.9.3/cmds/tui.c000066400000000000000000001640731351236475300150730ustar00rootroot00000000000000#ifdef HAVE_LIBNCURSES #include #include #include #include #include #include #include #include #include #include #include "uftrace.h" #include "version.h" #include "utils/utils.h" #include "utils/fstack.h" #include "utils/graph.h" #include "utils/report.h" #include "utils/list.h" #include "utils/rbtree.h" #include "utils/field.h" #include "utils/dwarf.h" #define KEY_ESCAPE 27 #define BLANK 32 static bool tui_finished; static bool tui_debug; struct tui_graph_node { struct uftrace_graph_node n; struct uftrace_graph *graph; struct list_head link; // for tui_report_node.head bool folded; }; struct tui_report_node { struct uftrace_report_node n; struct list_head head; // links tui_graph_node.link }; struct tui_list_node { struct list_head list; void *data; }; struct tui_window; struct tui_window_ops { void * (*prev)(struct tui_window *win, void *node, bool update); void * (*next)(struct tui_window *win, void *node, bool update); void * (*top)(struct tui_window *win, bool update); void * (*parent)(struct tui_window *win, void *node); void * (*sibling_prev)(struct tui_window *win, void *node); void * (*sibling_next)(struct tui_window *win, void *node); bool (*needs_blank)(struct tui_window *win, void *prev, void *next); bool (*enter)(struct tui_window *win, void *node); bool (*collapse)(struct tui_window *win, void *node, bool all, int depth); bool (*expand)(struct tui_window *win, void *node, bool all, int depth); void (*header)(struct tui_window *win, struct uftrace_data *handle); void (*footer)(struct tui_window *win, struct uftrace_data *handle); void (*display)(struct tui_window *win, void *node); bool (*search)(struct tui_window *win, void *node, char *str); bool (*longest_child)(struct tui_window *win, void *node); struct debug_location * (*location)(struct tui_window *win, void *node); }; struct tui_window { const struct tui_window_ops *ops; void *top; void *curr; void *old; int top_index; int curr_index; int last_index; int search_count; }; struct tui_report { struct tui_window win; struct list_head list; struct rb_root name_tree; struct rb_root sort_tree; int nr_sess; int nr_func; }; struct tui_graph { struct tui_window win; struct uftrace_graph ug; struct list_head list; struct tui_graph_node *disp; int top_depth; int curr_depth; int disp_depth; int width; bool *top_mask; bool *disp_mask; size_t mask_size; bool disp_update; }; struct tui_list { struct tui_window win; struct list_head head; int nr_node; }; static LIST_HEAD(tui_graph_list); static LIST_HEAD(graph_output_fields); static struct tui_report tui_report; static struct tui_graph partial_graph; static struct tui_list tui_info; static struct tui_list tui_session; static char *tui_search; static const struct tui_window_ops graph_ops; static const struct tui_window_ops report_ops; static const struct tui_window_ops info_ops; static const struct tui_window_ops session_ops; static void tui_window_move_down(struct tui_window *win); #define FIELD_SPACE 2 #define FIELD_SEP " :" #define POS_SIZE 5 #define C_NORMAL 0 #define C_HEADER 1 #define C_GREEN 2 #define C_YELLOW 3 #define C_RED 4 static const char *help[] = { "ARROW Navigation", "PgUp/Dn", "Home/End", "Enter Fold/unfold graph or Select session", "G Show (full) call graph", "g Show call graph for this function", "R Show uftrace report", "r Show uftrace report for this function", "I Show uftrace info", "S Change session", "O Open editor", "c/e Collapse/Expand direct children graph", "C/E Collapse/Expand all descendant graph", "n/p Next/Prev sibling", "u Move up to parent", "l Move to the longest executed child", "j/k Move down/up", "z Set current line to the center of screen", "/ Search", "/N/P Search next/prev", "v Show debug message", "h/? Show this help", "q Quit", }; static void init_colors(void) { if (!has_colors()) return; start_color(); /* C_NORMAL uses the default color pair */ init_pair(C_HEADER, COLOR_WHITE, COLOR_BLUE); init_pair(C_GREEN, COLOR_GREEN, COLOR_BLACK); init_pair(C_YELLOW, COLOR_YELLOW, COLOR_BLACK); init_pair(C_RED, COLOR_RED, COLOR_BLACK); } static void print_time(uint64_t ntime) { char *units[] = { "us", "ms", " s", " m", " h", }; int pairs[] = { C_NORMAL, C_GREEN, C_YELLOW, C_RED, C_RED }; unsigned limit[] = { 1000, 1000, 1000, 60, 24, INT_MAX, }; uint64_t fract; unsigned idx; if (ntime == 0UL) { printw("%7s %2s", "", ""); return; } for (idx = 0; idx < ARRAY_SIZE(units); idx++) { fract = ntime % limit[idx]; ntime = ntime / limit[idx]; if (ntime < limit[idx+1]) break; } /* for some error cases */ if (ntime > 999) ntime = fract = 999; printw("%3"PRIu64".%03"PRIu64" ", ntime, fract); attron(COLOR_PAIR(pairs[idx])); printw("%2s", units[idx]); attroff(COLOR_PAIR(pairs[idx])); } static void print_graph_total(struct field_data *fd) { struct uftrace_graph_node *node = fd->arg; uint64_t d; d = node->time; print_time(d); } static void print_graph_self(struct field_data *fd) { struct uftrace_graph_node *node = fd->arg; uint64_t d; d = node->time - node->child_time; print_time(d); } static void print_graph_addr(struct field_data *fd) { struct uftrace_graph_node *node = fd->arg; /* uftrace records (truncated) 48-bit addresses */ int width = sizeof(long) == 4 ? 8 : 12; printw("%*lx", width, node->addr); } static struct display_field field_total_time= { .id = GRAPH_F_TOTAL_TIME, .name = "total-time", .alias = "total", .header = "TOTAL TIME", .length = 10, .print = print_graph_total, .list = LIST_HEAD_INIT(field_total_time.list), }; static struct display_field field_self_time= { .id = GRAPH_F_SELF_TIME, .name = "self-time", .alias = "self", .header = " SELF TIME", .length = 10, .print = print_graph_self, .list = LIST_HEAD_INIT(field_self_time.list), }; static struct display_field field_addr = { .id = GRAPH_F_ADDR, .name = "address", .alias = "addr", #if __SIZEOF_LONG == 4 .header = " ADDR ", .length = 8, #else .header = " ADDRESS ", .length = 12, #endif .print = print_graph_addr, .list = LIST_HEAD_INIT(field_addr.list), }; /* index of this table should be matched to display_field_id */ static struct display_field *graph_field_table[] = { &field_total_time, &field_self_time, &field_addr, }; static void setup_default_graph_field(struct list_head *fields, struct opts *opts) { add_field(fields, graph_field_table[GRAPH_F_TOTAL_TIME]); } static inline bool is_first_child(struct tui_graph_node *prev, struct tui_graph_node *next) { return prev->n.head.next == &next->n.list; } static inline bool is_last_child(struct tui_graph_node *prev, struct tui_graph_node *next) { return prev->n.head.prev == &next->n.list; } static int create_data(struct uftrace_session *sess, void *arg) { struct tui_graph *graph = xzalloc(sizeof(*graph)); pr_dbg("create graph for session %.*s (%s)\n", SESSION_ID_LEN, sess->sid, sess->exename); graph_init(&graph->ug, sess); list_add_tail(&graph->list, &tui_graph_list); tui_report.nr_sess++; return 0; } static void tui_setup(struct uftrace_data *handle, struct opts *opts) { walk_sessions(&handle->sessions, create_data, NULL); tui_report.name_tree = RB_ROOT; setup_field(&graph_output_fields, opts, setup_default_graph_field, graph_field_table, ARRAY_SIZE(graph_field_table)); } static void tui_cleanup(void) { struct tui_graph *graph; if (!tui_finished) endwin(); tui_finished = true; while (!list_empty(&tui_graph_list)) { graph = list_first_entry(&tui_graph_list, typeof(*graph), list); list_del(&graph->list); free(graph); } graph_remove_task(); } static struct uftrace_graph * get_graph(struct uftrace_task_reader *task, uint64_t time, uint64_t addr) { struct tui_graph *graph; struct uftrace_session_link *sessions = &task->h->sessions; struct uftrace_session *sess; sess = find_task_session(sessions, task->t, time); if (sess == NULL) { struct uftrace_session *fsess = sessions->first; if (is_kernel_address(&fsess->symtabs, addr)) sess = fsess; else return NULL; } list_for_each_entry(graph, &tui_graph_list, list) { if (graph->ug.sess == sess) return &graph->ug; } return NULL; } static bool list_is_none(struct list_head *list) { return list->next == NULL && list->prev == NULL; } static void update_report_node(struct uftrace_task_reader *task, char *symname, struct uftrace_task_graph *tg) { struct tui_report_node *node; struct tui_graph_node *graph_node; /* graph is not set probably due to filters (or error?) */ if (tg->node == NULL) return; node = (struct tui_report_node *)report_find_node(&tui_report.name_tree, symname); if (node == NULL) { node = xzalloc(sizeof(*node)); INIT_LIST_HEAD(&node->head); report_add_node(&tui_report.name_tree, symname, (void *)node); tui_report.nr_func++; } graph_node = (struct tui_graph_node *)tg->node; if (list_is_none(&graph_node->link)) list_add_tail(&graph_node->link, &node->head); report_update_node(&node->n, task); } static int build_tui_node(struct uftrace_task_reader *task, struct uftrace_record *rec, struct opts *opts) { struct uftrace_task_graph *tg; struct uftrace_graph *graph; struct tui_graph_node *graph_node; struct sym *sym; char *name; uint64_t addr = rec->addr; if (is_kernel_record(task, rec)) { struct uftrace_session *fsess; fsess = task->h->sessions.first; addr = get_kernel_address(&fsess->symtabs, addr); } tg = graph_get_task(task, sizeof(*tg)); graph = get_graph(task, rec->time, addr); if (tg->node == NULL || tg->graph != graph) tg->node = &graph->root; tg->graph = graph; if (rec->type == UFTRACE_ENTRY || rec->type == UFTRACE_EXIT) { sym = task_find_sym_addr(&task->h->sessions, task, rec->time, addr); /* skip it if --no-libcall is given */ if (!opts->libcall && sym && sym->type == ST_PLT_FUNC) return 0; name = symbol_getname(sym, addr); if (rec->type == UFTRACE_EXIT) update_report_node(task, name, tg); } else if (rec->type == UFTRACE_EVENT) { sym = &sched_sym; name = symbol_getname(sym, addr); if (addr == EVENT_ID_PERF_SCHED_IN) update_report_node(task, name, tg); else if (addr != EVENT_ID_PERF_SCHED_OUT) return 0; } else /* rec->type == UFTRACE_LOST */ return 0; graph_add_node(tg, rec->type, name, sizeof(struct tui_graph_node)); if (tg->node && tg->node != &graph->root) { graph_node = (struct tui_graph_node *)tg->node; graph_node->graph = graph; } symbol_putname(sym, name); return 0; } static void add_remaining_node(struct opts *opts, struct uftrace_data *handle) { uint64_t last_time; struct fstack *fstack; struct uftrace_task_reader *task; struct uftrace_task_graph *tg; struct sym *sym; char *name; int i; for (i = 0; i < handle->nr_tasks; i++) { task = &handle->tasks[i]; if (task->stack_count == 0) continue; if (opts->kernel_skip_out && task->user_stack_count == 0) continue; last_time = task->rstack->time; if (handle->time_range.stop) last_time = handle->time_range.stop; while (--task->stack_count >= 0) { fstack = &task->func_stack[task->stack_count]; if (fstack->addr == 0) continue; if (fstack->total_time > last_time) continue; tg = graph_get_task(task, sizeof(*tg)); sym = task_find_sym_addr(&handle->sessions, task, fstack->total_time, fstack->addr); name = symbol_getname(sym, fstack->addr); fstack->total_time = last_time - fstack->total_time; if (fstack->child_time > fstack->total_time) fstack->total_time = fstack->child_time; if (task->stack_count > 0) fstack[-1].child_time += fstack->total_time; update_report_node(task, name, tg); graph_add_node(tg, UFTRACE_EXIT, name, sizeof(struct tui_graph_node)); symbol_putname(sym, name); } } } static struct tui_graph_node * append_graph_node(struct uftrace_graph_node *dst, struct tui_graph *graph, char *name) { struct tui_graph_node *node; node = xzalloc(sizeof(*node)); node->n.name = xstrdup(name); INIT_LIST_HEAD(&node->n.head); node->n.parent = dst; node->graph = &graph->ug; list_add_tail(&node->n.list, &dst->head); dst->nr_edges++; return node; } static void copy_graph_node(struct uftrace_graph_node *dst, struct uftrace_graph_node *src) { struct uftrace_graph_node *child; struct tui_graph_node *node; list_for_each_entry(child, &src->head, list) { list_for_each_entry(node, &dst->head, n.list) { if (!strcmp(child->name, node->n.name)) break; } if (list_no_entry(node, &dst->head, n.list)) { struct tui_graph *graph; node = (struct tui_graph_node *)src; graph = container_of(node->graph, typeof(*graph), ug); node = append_graph_node(dst, graph, child->name); } node->n.addr = child->addr; node->n.time += child->time; node->n.child_time += child->child_time; node->n.nr_calls += child->nr_calls; copy_graph_node(&node->n, child); } } static int tui_last_index(struct tui_window *win) { int count = win->curr_index; void *next, *prev = win->curr; while (true) { next = win->ops->next(win, prev, false); if (next == NULL) return count; count++; if (win->ops->needs_blank(win, prev, next)) count++; prev = next; } } static void tui_window_init(struct tui_window *win, const struct tui_window_ops *ops) { void *top = ops->top(win, true); win->ops = ops; win->top = top; win->curr = win->old = top; win->top_index = win->curr_index = 0; win->last_index = tui_last_index(win); } static struct tui_graph * tui_graph_init(struct opts *opts) { struct tui_graph *graph; struct uftrace_graph_node *top, *node; list_for_each_entry(graph, &tui_graph_list, list) { /* top (root) is an artificial node, fill the info */ top = &graph->ug.root; top->name = basename(graph->ug.sess->exename); top->nr_calls = 1; list_for_each_entry(node, &graph->ug.root.head, list) { top->time += node->time; top->child_time += node->time; } tui_window_init(&graph->win, &graph_ops); graph->mask_size = sizeof(*graph->top_mask) * opts->max_stack; graph->top_mask = xzalloc(graph->mask_size); graph->disp_mask = xmalloc(graph->mask_size); } graph = list_first_entry(&tui_graph_list, typeof(*graph), list); partial_graph.mask_size = graph->mask_size; partial_graph.top_mask = xzalloc(graph->mask_size); partial_graph.disp_mask = xmalloc(graph->mask_size); INIT_LIST_HEAD(&partial_graph.ug.root.head); INIT_LIST_HEAD(&partial_graph.ug.special_nodes); tui_window_init(&partial_graph.win, &graph_ops); /* select first session */ partial_graph.ug.sess = graph->ug.sess; return graph; } static void tui_graph_finish(void) { struct tui_graph *graph; list_for_each_entry(graph, &tui_graph_list, list) { graph_destroy(&graph->ug); free(graph->top_mask); free(graph->disp_mask); } graph_destroy(&partial_graph.ug); free(partial_graph.top_mask); free(partial_graph.disp_mask); } static void build_partial_graph(struct tui_report_node *root_node, struct tui_graph *target) { struct tui_graph *graph = &partial_graph; struct tui_graph_node *root, *node; char *str; graph_destroy(&graph->ug); graph->ug.sess = target->ug.sess; xasprintf(&str, "=== Function Call Graph for '%s' ===", root_node->n.name); root = (struct tui_graph_node*) &graph->ug.root; root->n.name = str; root->n.parent = NULL; root->n.time = 0; root->n.child_time = 0; root->n.nr_calls = 0; /* special node */ root = append_graph_node(&graph->ug.root, target, "========== Back-trace =========="); list_for_each_entry(node, &root_node->head, link) { struct tui_graph_node *tmp, *parent; int n = 0; if (node->graph != &target->ug) continue; tmp = root; parent = node; while (parent->n.parent) { tmp = append_graph_node(&tmp->n, target, parent->n.name); tmp->n.addr = parent->n.addr; tmp->n.time = node->n.time; tmp->n.child_time = node->n.child_time; tmp->n.nr_calls = node->n.nr_calls; /* fold backtrace at the first child */ if (n++ == 1) tmp->folded = true; parent = (void *)parent->n.parent; } /* but, unfoled it if it's the last child */ if (n == 2) tmp->folded = false; } /* special node */ root = append_graph_node(&graph->ug.root, target, "========== Call Graph =========="); root = append_graph_node(&root->n, target, root_node->n.name); list_for_each_entry(node, &root_node->head, link) { if (node->graph != &target->ug) continue; root->n.addr = node->n.addr; root->n.time += node->n.time; root->n.child_time += node->n.child_time; root->n.nr_calls += node->n.nr_calls; copy_graph_node(&root->n, &node->n); } tui_window_init(&graph->win, &graph_ops); memset(graph->top_mask, 0, graph->mask_size); } static inline bool is_special_node(struct uftrace_graph_node *node) { return node->name[0] == '='; } static struct tui_graph_node * graph_prev_node(struct tui_graph_node *node, int *depth, bool *indent_mask) { struct uftrace_graph_node *n = &node->n; struct tui_graph_node *parent = (void *)n->parent; /* root node */ if (parent == NULL) { *depth = 0; return NULL; } /* simple case: if it's the first child, move to the parent */ if (is_first_child(parent, node)) { if (!list_is_singular(&n->parent->head) && *depth > 0) { *depth -= 1; if (indent_mask) indent_mask[*depth] = false; } n = n->parent; goto out; } /* move to sibling */ n = list_prev_entry(n, list); node = (struct tui_graph_node *)n; /* if it has children, move to the last child */ while (!list_empty(&n->head) && !node->folded) { if (!list_is_singular(&n->head)) { if (indent_mask) indent_mask[*depth] = false; *depth += 1; } n = list_last_entry(&n->head, typeof(*n), list); node = (struct tui_graph_node *)n; } out: if (n->parent && !list_is_singular(&n->parent->head)) { if (indent_mask && *depth > 0) indent_mask[*depth - 1] = true; } return (struct tui_graph_node *)n; } static struct tui_graph_node * graph_next_node(struct tui_graph_node *node, int *depth, bool *indent_mask) { struct uftrace_graph_node *n = &node->n; struct tui_graph_node *parent = (void *)n->parent; if (parent && !list_is_singular(&n->parent->head) && is_last_child(parent, node) && indent_mask && *depth > 0) indent_mask[*depth - 1] = false; /* simple case: if it has children, move to it */ if (!list_empty(&n->head) && (parent == NULL || !node->folded)) { if (!list_is_singular(&n->head)) { if (indent_mask) indent_mask[*depth] = true; *depth += 1; } n = list_first_entry(&n->head, typeof(*n), list); if (is_special_node(n)) *depth = 0; return (struct tui_graph_node *)n; } /* parent should not be folded */ while (n->parent != NULL) { parent = (struct tui_graph_node *)n->parent; /* move to sibling if possible */ if (!is_last_child(parent, (void *)n)) { n = list_next_entry(n, list); if (is_special_node(n)) *depth = 0; return (struct tui_graph_node *)n; } /* otherwise look up parent */ n = n->parent; if (!list_is_singular(&n->head) && *depth > 0) { *depth -= 1; if (indent_mask) indent_mask[*depth] = false; } } return NULL; } /* per-window operations for graph window */ static void * win_top_graph(struct tui_window *win, bool update) { struct tui_graph *graph = (struct tui_graph *)win; if (update) graph->top_depth = 0; return &graph->ug.root; } static void * win_prev_graph(struct tui_window *win, void *node, bool update) { void *prev; int depth; struct tui_graph *graph = (struct tui_graph *)win; if (update) prev = graph_prev_node(node, &graph->top_depth, graph->top_mask); else prev = graph_prev_node(node, &depth, NULL); return prev; } static void * win_next_graph(struct tui_window *win, void *node, bool update) { void *next; int depth; struct tui_graph *graph = (struct tui_graph *)win; if (update) { /* update top node for new page */ next = graph_next_node(node, &graph->top_depth, graph->top_mask); } else if (graph->disp_update) { /* update display node for next */ next = graph_next_node(node, &graph->disp_depth, graph->disp_mask); graph->disp = next; } else { next = graph_next_node(node, &depth, NULL); } return next; } static bool win_needs_blank_graph(struct tui_window *win, void *prev, void *next) { return !is_first_child(prev, next); } static void * win_sibling_prev_graph(struct tui_window *win, void *node) { struct uftrace_graph_node *curr = node; struct uftrace_graph_node *parent = curr->parent; if (parent == NULL) return NULL; if (list_first_entry(&parent->head, typeof(*curr), list) == curr) return NULL; return list_prev_entry(curr, list); } static void * win_sibling_next_graph(struct tui_window *win, void *node) { struct uftrace_graph_node *curr = node; struct uftrace_graph_node *parent = curr->parent; if (parent == NULL) return NULL; if (list_last_entry(&parent->head, typeof(*curr), list) == curr) return NULL; return list_next_entry(curr, list); } static void * win_parent_graph(struct tui_window *win, void *node) { struct uftrace_graph_node *curr = node; return curr->parent; } static bool win_enter_graph(struct tui_window *win, void *node) { struct tui_graph_node *curr = node; /* root node is not foldable */ if (curr->n.parent == NULL) return false; if (list_empty(&curr->n.head)) return false; curr->folded = !curr->folded; win->last_index = tui_last_index(win); return true; } static int fold_graph_node(struct tui_graph_node *node, bool fold, bool all, int depth) { struct tui_graph_node *child; int count = 0; bool curr_fold = fold; if (!all && depth < 0) return 0; else if (depth > 0) curr_fold = false; /* do not fold leaf nodes - it's meaningless but confusing */ if (list_empty(&node->n.head)) return 0; if (node->folded != curr_fold) { node->folded = curr_fold; count++; } list_for_each_entry(child, &node->n.head, n.list) count += fold_graph_node(child, fold, all, depth - 1); return count; } static bool win_collapse_graph(struct tui_window *win, void *node, bool all, int depth) { bool result = fold_graph_node(node, true, all, depth); win->last_index = tui_last_index(win); return result; } static bool win_expand_graph(struct tui_window *win, void *node, bool all, int depth) { bool result = fold_graph_node(node, false, all, depth); win->last_index = tui_last_index(win); return result; } static void win_header_graph(struct tui_window *win, struct uftrace_data *handle) { int w = 0, c; char *buf, *p; struct tui_graph *graph = (struct tui_graph *)win; struct display_field *field; /* calculate width for fields */ list_for_each_entry(field, &graph_output_fields, list) { w += field->length + FIELD_SPACE; } if (!list_empty(&graph_output_fields)) w += strlen(FIELD_SEP); graph->width = w; w += strlen(" FUNCTION"); if (list_empty(&graph_output_fields)) { printw("%-*.*s", COLS, COLS, "uftrace graph TUI"); goto out; } buf = p = xmalloc(w + 1); list_for_each_entry(field, &graph_output_fields, list) { c = snprintf(p, w, "%*s%*s", FIELD_SPACE, "", field->length, field->header); p += c; w -= c; } snprintf(p, w+1, "%s %s", FIELD_SEP, "FUNCTION"); printw("%-*.*s", COLS, COLS, buf); free(buf); out: /* start with same make as top */ graph->disp = graph->win.top; graph->disp_depth = graph->top_depth; graph->disp_update = true; memcpy(graph->disp_mask, graph->top_mask, graph->mask_size); } static int win_pos_percent(struct tui_window *win) { return win->curr_index * 100.0 / win->last_index; } static void win_footer(struct tui_window *win, char *msg) { int pos_start = COLS - POS_SIZE; int msg_len = strlen(msg); char footer[COLS + 1]; memset(footer, BLANK, sizeof(footer)); memcpy(footer, msg, COLS < msg_len ? COLS : msg_len); if (pos_start > msg_len) snprintf(footer + pos_start, POS_SIZE, "%3d%%", win_pos_percent(win)); footer[COLS] = '\0'; printw("%-*s", COLS, footer); } static void win_footer_graph(struct tui_window *win, struct uftrace_data *handle) { char buf[COLS + 1]; struct tui_graph *graph = (struct tui_graph *)win; struct tui_graph_node *node = win->curr; struct uftrace_session *sess = graph->ug.sess; if (tui_debug) { snprintf(buf, COLS, "uftrace graph: top: %d depth: %d, curr: %d depth: %d last: %d", graph->win.top_index, graph->top_depth, graph->win.curr_index, graph->curr_depth, graph->win.last_index); } else if (tui_search) { snprintf(buf, COLS, "uftrace graph: searching \"%s\" (%d match, %s)", tui_search, graph->win.search_count, "use '<' and '>' keys to navigate"); } else { struct debug_location *dloc; dloc = win->ops->location(win, win->curr); if (dloc != NULL && dloc->file != NULL) { snprintf(buf, COLS, "uftrace graph: %s [line:%d]", dloc->file->name, dloc->line); } else if (find_symtabs(&sess->symtabs, node->n.addr) != NULL) { /* some symbols don't have source location */ snprintf(buf, COLS, "uftrace graph: %s [at %#"PRIx64"]", "source location is not available", node->n.addr); } else { snprintf(buf, COLS, "uftrace graph: session %.*s (%s)", SESSION_ID_LEN, sess->sid, sess->exename); } } win_footer(win, buf); graph->disp_update = false; } static void print_graph_field(struct uftrace_graph_node *node) { struct display_field *field; struct field_data fd = { .arg = node, }; if (list_empty(&graph_output_fields)) return; list_for_each_entry(field, &graph_output_fields, list) { printw("%*s", FIELD_SPACE, ""); field->print(&fd); } printw(FIELD_SEP); } static void print_graph_empty(void) { struct display_field *field; if (list_empty(&graph_output_fields)) return; list_for_each_entry(field, &graph_output_fields, list) printw("%*s", field->length + FIELD_SPACE, ""); printw(FIELD_SEP); } static void print_graph_indent(struct tui_graph *graph, struct tui_graph_node *node, int depth, bool single_child) { int i; struct tui_graph_node *parent = (void *)node->n.parent; for (i = 0; i < depth; i++) { if (!graph->disp_mask[i]) { printw(" "); continue; } if (i < depth - 1 || single_child) printw(" │"); else if (is_last_child(parent, node)) printw(" â””"); else printw(" ├"); } } static void win_display_graph(struct tui_window *win, void *node) { struct tui_graph *graph = (struct tui_graph *)win; struct tui_graph_node *curr = node; struct tui_graph_node *parent; int d = graph->disp_depth; int w = graph->width; const char *fold_sign; bool single_child = false; int width; if (node == NULL) { print_graph_empty(); print_graph_indent(graph, graph->disp, d, true); return; } fold_sign = curr->folded ? "â–¶" : "─"; parent = win_parent_graph(win, node); if (parent == NULL) fold_sign = " "; else if (list_is_singular(&parent->n.head)) { single_child = true; if (!curr->folded) fold_sign = " "; } print_graph_field(&curr->n); print_graph_indent(graph, curr, d, single_child); width = d * 3 + w; if (is_special_node(&curr->n)) { width = COLS - width; if (width > 0) printw("%-*.*s", width, width, curr->n.name); } else { char buf[32]; /* 4 = fold_sign(1) + parenthesis92) + space(1) */ width += snprintf(buf, sizeof(buf), "%d", curr->n.nr_calls) + 4; width = COLS - width; if (width > 0) { printw("%s(%d) %-*.*s", fold_sign, curr->n.nr_calls, width, width, curr->n.name); } } } static bool win_search_graph(struct tui_window *win, void *node, char *str) { struct tui_graph_node *curr = node; return strstr(curr->n.name, str); } static bool win_longest_child_graph(struct tui_window *win, void *node) { struct tui_graph_node *curr = node; struct tui_graph_node *child; struct tui_graph_node *longest_child = NULL; uint64_t longest_child_time = 0; curr->folded = false; list_for_each_entry(child, &curr->n.head, n.list) { fold_graph_node(child, true, false, 0); if (longest_child_time < child->n.time) { longest_child_time = child->n.time; longest_child = child; } } if (longest_child == NULL) return false; longest_child->folded = false; while (win->curr != longest_child) tui_window_move_down(win); win->last_index = tui_last_index(win); return true; } static struct debug_location *win_location_graph(struct tui_window *win, void *node) { struct tui_graph *graph = (struct tui_graph *)win; struct tui_graph_node *curr = node; struct uftrace_session *sess = graph->ug.sess; return find_file_line(&sess->symtabs, curr->n.addr); } static const struct tui_window_ops graph_ops = { .prev = win_prev_graph, .next = win_next_graph, .top = win_top_graph, .parent = win_parent_graph, .sibling_prev = win_sibling_prev_graph, .sibling_next = win_sibling_next_graph, .needs_blank = win_needs_blank_graph, .enter = win_enter_graph, .collapse = win_collapse_graph, .expand = win_expand_graph, .header = win_header_graph, .footer = win_footer_graph, .display = win_display_graph, .search = win_search_graph, .longest_child = win_longest_child_graph, .location = win_location_graph, }; /* some default (no-op) window operations */ static bool win_needs_blank_no(struct tui_window *win, void *prev, void *next) { return false; } static void * win_sibling_prev_no(struct tui_window *win, void *node) { return win->ops->prev(win, node, false); } static void * win_sibling_next_no(struct tui_window *win, void *node) { return win->ops->next(win, node, false); } static void * win_parent_no(struct tui_window *win, void *node) { return NULL; } /* per-window operations for report window */ static struct tui_report * tui_report_init(struct opts *opts) { struct tui_window *win = &tui_report.win; report_setup_sort("total"); report_sort_nodes(&tui_report.name_tree, &tui_report.sort_tree); tui_window_init(win, &report_ops); return &tui_report; } static void tui_report_finish(void) { } static void * win_top_report(struct tui_window *win, bool update) { struct tui_report *report = (struct tui_report *)win; struct rb_node *node = rb_first(&report->sort_tree); return rb_entry(node, struct tui_report_node, n.sort_link); } static void * win_prev_report(struct tui_window *win, void *node, bool update) { struct tui_report_node *curr = node; struct rb_node *rbnode = rb_prev(&curr->n.sort_link); if (rbnode == NULL) return NULL; return rb_entry(rbnode, struct tui_report_node, n.sort_link); } static void * win_next_report(struct tui_window *win, void *node, bool update) { struct tui_report_node *curr = node; struct rb_node *rbnode = rb_next(&curr->n.sort_link); if (rbnode == NULL) return NULL; return rb_entry(rbnode, struct tui_report_node, n.sort_link); } static bool win_search_report(struct tui_window *win, void *node, char *str) { struct tui_report_node *curr = node; return strstr(curr->n.name, str); } static void win_header_report(struct tui_window *win, struct uftrace_data *handle) { int w = 46; printw(" %10s %10s %10s %s", "Total Time", "Self Time", "Calls", "Function"); if (COLS > w) printw("%*s", COLS - w, ""); } static void win_footer_report(struct tui_window *win, struct uftrace_data *handle) { char buf[COLS + 1]; if (tui_debug) { snprintf(buf, COLS, "uftrace report: top: %d, curr: %d", win->top_index, win->curr_index); } else if (tui_search) { snprintf(buf, COLS, "uftrace report: searching \"%s\" (%d match, %s)", tui_search, win->search_count, "use '<' and '>' keys to navigate"); } else { struct debug_location *dloc; dloc = win->ops->location(win, win->curr); if (dloc != NULL && dloc->file != NULL) { snprintf(buf, COLS, "uftrace report: %s [line:%d]", dloc->file->name, dloc->line); } else { struct tui_report *report = (struct tui_report *)win; snprintf(buf, COLS, "uftrace report: %s (%d sessions, %d functions)", handle->dirname, report->nr_sess, report->nr_func); } } win_footer(win, buf); } static void win_display_report(struct tui_window *win, void *node) { struct tui_report_node *curr = node; int width = 38; /* 3 output fields and spaces */ printw(" "); print_time(curr->n.total.sum); printw(" "); print_time(curr->n.self.sum); printw(" "); printw("%10lu", curr->n.call); printw(" "); printw("%-*.*s", COLS - width, COLS - width, curr->n.name); } static struct debug_location *win_location_report(struct tui_window *win, void *node) { struct tui_report_node *curr = node; struct tui_graph_node *gnode; struct uftrace_session *sess; struct debug_location *dloc; list_for_each_entry(gnode, &curr->head, link) { sess = gnode->graph->sess; dloc = find_file_line(&sess->symtabs, gnode->n.addr); if (dloc != NULL && dloc->file != NULL) return dloc; } return NULL; } static const struct tui_window_ops report_ops = { .prev = win_prev_report, .next = win_next_report, .top = win_top_report, .parent = win_parent_no, .sibling_prev = win_sibling_prev_no, .sibling_next = win_sibling_next_no, .needs_blank = win_needs_blank_no, .header = win_header_report, .footer = win_footer_report, .display = win_display_report, .search = win_search_report, .location = win_location_report, }; /* per-window operations for list window */ static void * win_top_list(struct tui_window *win, bool update) { struct tui_list *list = (struct tui_list *)win; return list_first_entry(&list->head, struct tui_list_node, list); } static void * win_prev_list(struct tui_window *win, void *node, bool update) { struct tui_list *list = (struct tui_list *)win; if (list_first_entry(&list->head, struct tui_list_node, list) == node) return NULL; return list_prev_entry((struct tui_list_node *)node, list); } static void * win_next_list(struct tui_window *win, void *node, bool update) { struct tui_list *list = (struct tui_list *)win; if (list_last_entry(&list->head, struct tui_list_node, list) == node) return NULL; return list_next_entry((struct tui_list_node *)node, list); } /* per-window operations for info window */ static void build_info_node(void *data, const char *fmt, ...) { va_list ap; struct tui_list *info = data; struct tui_list_node *node; char *str = NULL; node = xmalloc(sizeof(*node)); va_start(ap, fmt); xvasprintf(&str, fmt, ap); va_end(ap); /* remove trailing newline */ str[strlen(str) - 1] = '\0'; node->data = str; list_add_tail(&node->list, &info->head); } static struct tui_list * tui_info_init(struct opts *opts, struct uftrace_data *handle) { INIT_LIST_HEAD(&tui_info.head); process_uftrace_info(handle, opts, build_info_node, &tui_info); tui_window_init(&tui_info.win, &info_ops); return &tui_info; } static void tui_info_finish(void) { struct tui_list_node *node, *tmp; list_for_each_entry_safe(node, tmp, &tui_info.head, list) { list_del(&node->list); free(node->data); free(node); } } static void win_header_info(struct tui_window *win, struct uftrace_data *handle) { printw("%-*.*s", COLS, COLS, "uftrace info"); } #define print_buf(fmt, ...) \ ({ int _x = snprintf(buf + len, sz - len, fmt, ## __VA_ARGS__); len += _x; }) static void win_footer_info(struct tui_window *win, struct uftrace_data *handle) { char buf[256]; snprintf(buf, COLS, "uftrace version: %s", UFTRACE_VERSION); win_footer(win, buf); } static void win_display_info(struct tui_window *win, void *node) { struct tui_list_node *curr = node; printw("%-*.*s", COLS, COLS, (char *)curr->data); } static const struct tui_window_ops info_ops = { .prev = win_prev_list, .next = win_next_list, .top = win_top_list, .parent = win_parent_no, .sibling_prev = win_sibling_prev_no, .sibling_next = win_sibling_next_no, .needs_blank = win_needs_blank_no, .header = win_header_info, .footer = win_footer_info, .display = win_display_info, }; #define TUI_SESS_REPORT 1 #define TUI_SESS_INFO 2 #define TUI_SESS_HELP 3 #define TUI_SESS_QUIT 4 #define TUI_SESS_DUMMY_NR 4 /* per-window operations for session window */ static struct tui_list * tui_session_init(struct opts *opts) { struct tui_graph *graph; struct tui_list_node *node; int i; INIT_LIST_HEAD(&tui_session.head); tui_session.nr_node = 0; list_for_each_entry(graph, &tui_graph_list, list) { node = xmalloc(sizeof(*node)); node->data = graph->ug.sess; list_add_tail(&node->list, &tui_session.head); tui_session.nr_node++; } for (i = 1; i <= TUI_SESS_DUMMY_NR; i++) { node = xmalloc(sizeof(*node)); node->data = (void *)(long)i; list_add_tail(&node->list, &tui_session.head); } tui_window_init(&tui_session.win, &session_ops); return &tui_session; } static void tui_session_finish(void) { struct tui_list_node *node, *tmp; list_for_each_entry_safe(node, tmp, &tui_session.head, list) { list_del(&node->list); free(node); } } static void win_header_session(struct tui_window *win, struct uftrace_data *handle) { printw("%s %-*s", "Key", COLS - 4, "uftrace command"); } static void win_footer_session(struct tui_window *win, struct uftrace_data *handle) { char buf[256]; struct tui_list *s_list = (struct tui_list *)win; struct tui_list_node *node = win->curr; struct uftrace_session *s = node->data; switch ((long)node->data) { case TUI_SESS_REPORT: case TUI_SESS_INFO: case TUI_SESS_HELP: case TUI_SESS_QUIT: snprintf(buf, sizeof(buf), "uftrace: %d session(s)", s_list->nr_node); break; default: snprintf(buf, sizeof(buf), "session %.*s: exe image: %s", SESSION_ID_LEN, s->sid, s->exename); break; } win_footer(win, buf); } static struct tui_graph * get_current_graph(struct tui_list_node *node, int *count) { struct tui_graph *graph; int n = 1; list_for_each_entry(graph, &tui_graph_list, list) { if (graph->ug.sess == node->data) { if (count) *count = n; return graph; } n++; } if (count) *count = 0; return NULL; } static void win_display_session(struct tui_window *win, void *node) { int len = 0; char buf[1024]; size_t sz = sizeof(buf); struct tui_list_node *curr = node; struct uftrace_session *s = curr->data; struct uftrace_session *curr_sess = NULL; int count = 0; switch ((long)s) { case TUI_SESS_REPORT: print_buf(" R Report functions"); break; case TUI_SESS_INFO: print_buf(" I uftrace Info"); break; case TUI_SESS_HELP: print_buf(" h Help message"); break; case TUI_SESS_QUIT: print_buf(" q quit"); break; default: curr_sess = partial_graph.ug.sess; get_current_graph(node, &count); print_buf(" %c %s #%d: %s", s == curr_sess ? 'G' : ' ', "call Graph for session", count, basename(s->exename)); break; } printw("%-*.*s", COLS, COLS, buf); } static bool win_enter_session(struct tui_window *win, void *node) { /* update partial graph for different session */ struct tui_list_node *curr = node; struct uftrace_session *old = partial_graph.ug.sess; struct uftrace_session *new = curr->data; struct uftrace_graph_node *ugnode; struct tui_report_node *func; if ((unsigned long)curr->data <= TUI_SESS_DUMMY_NR) return true; if (old == new) return false; partial_graph.ug.sess = curr->data; /* get root node */ ugnode = &partial_graph.ug.root; if (list_empty(&ugnode->head)) return true; /* get function call node */ ugnode = list_last_entry(&ugnode->head, typeof(*ugnode), list); /* get first child (= actual function) */ ugnode = list_first_entry(&ugnode->head, typeof(*ugnode), list); func = (void *)report_find_node(&tui_report.name_tree, ugnode->name); build_partial_graph(func, get_current_graph(node, NULL)); return true; } static const struct tui_window_ops session_ops = { .prev = win_prev_list, .next = win_next_list, .top = win_top_list, .parent = win_parent_no, .sibling_prev = win_sibling_prev_no, .sibling_next = win_sibling_next_no, .needs_blank = win_needs_blank_no, .enter = win_enter_session, .header = win_header_session, .footer = win_footer_session, .display = win_display_session, }; /* common window operations */ static void tui_window_move_up(struct tui_window *win) { void *node; node = win->ops->prev(win, win->curr, false); if (node == NULL) return; win->curr_index--; if (win->ops->needs_blank(win, node, win->curr)) win->curr_index--; if (win->curr_index < win->top_index) { win->top = win->ops->prev(win, win->top, true); win->top_index = win->curr_index; } win->curr = node; } static void tui_window_move_down(struct tui_window *win) { void *node; node = win->ops->next(win, win->curr, false); if (node == NULL) return; win->curr_index++; if (win->ops->needs_blank(win, win->curr, node)) win->curr_index++; win->curr = node; while (win->curr_index - win->top_index >= LINES - 2) { node = win->ops->next(win, win->top, true); win->top_index++; if (win->ops->needs_blank(win, win->top, node)) win->top_index++; win->top = node; } } static void tui_window_page_up(struct tui_window *win) { void *node; if (win->curr != win->top) { win->curr = win->top; win->curr_index = win->top_index; return; } while (win->top_index - win->curr_index < LINES - 2) { node = win->ops->prev(win, win->top, true); if (node == NULL) break; win->curr_index--; if (win->ops->needs_blank(win, node, win->top)) win->curr_index--; win->top = node; } win->curr = win->top; win->top_index = win->curr_index; } static void tui_window_page_down(struct tui_window *win) { int orig_index; int next_index; void *node; orig_index = win->top_index; next_index = win->curr_index; node = win->ops->next(win, win->curr, false); if (node == NULL) return; next_index++; if (win->ops->needs_blank(win, win->curr, node)) next_index++; if (next_index - win->top_index >= LINES - 2) { /* we're already at the end of page - move to next page */ orig_index = next_index; } do { /* move curr to the bottom from orig_index */ win->curr = node; win->curr_index = next_index; node = win->ops->next(win, win->curr, false); if (node == NULL) break; next_index++; if (win->ops->needs_blank(win, win->curr, node)) next_index++; } while (next_index - orig_index < LINES - 2); /* move top if page was moved */ while (win->curr_index - win->top_index >= LINES - 2) { node = win->ops->next(win, win->top, true); win->top_index++; if (win->ops->needs_blank(win, win->top, node)) win->top_index++; win->top = node; } } static void tui_window_move_home(struct tui_window *win) { win->top = win->curr = win->ops->top(win, true); win->top_index = win->curr_index = 0; } static void tui_window_move_end(struct tui_window *win) { void *node; /* move to the last node */ while (true) { node = win->ops->next(win, win->curr, false); if (node == NULL) break; win->curr_index++; if (win->ops->needs_blank(win, win->curr, node)) win->curr_index++; win->curr = node; } /* move top if page was moved */ while (win->curr_index - win->top_index >= LINES - 2) { node = win->ops->next(win, win->top, true); win->top_index++; if (win->ops->needs_blank(win, win->top, node)) win->top_index++; win->top = node; } } /* move to the previous sibling */ static bool tui_window_move_prev(struct tui_window *win) { void *prev = win->ops->sibling_prev(win, win->curr); int count = 0; if (prev == NULL) return false; if (win->ops->collapse == NULL) { while (win->curr != prev) tui_window_move_up(win); return false; } /* fold the current node before moving to the previous sibling */ count = win->ops->collapse(win, win->curr, false, 0); while (win->curr != prev) tui_window_move_up(win); /* collapse the current node after moving to the previous sibling */ count += win->ops->collapse(win, win->curr, false, 1); return count; } /* move to the next sibling */ static bool tui_window_move_next(struct tui_window *win) { void *next = win->ops->sibling_next(win, win->curr); int count = 0; if (next == NULL) return false; if (win->ops->collapse == NULL) { while (win->curr != next) tui_window_move_down(win); return false; } /* fold the current node before moving to the next sibling */ count = win->ops->collapse(win, win->curr, false, 0); while (win->curr != next) tui_window_move_down(win); /* collapse the current node after moving to the next sibling */ count += win->ops->collapse(win, win->curr, false, 1); return count; } static void tui_window_display(struct tui_window *win, bool full_redraw, struct uftrace_data *handle) { int count; void *node = win->top; /* too small screen */ if (LINES <= 2) return; move(0, 0); attron(COLOR_PAIR(C_HEADER) | A_BOLD); win->ops->header(win, handle); attroff(COLOR_PAIR(C_HEADER) | A_BOLD); for (count = 0; count < LINES - 2; count++) { void *next; if (!full_redraw && node != win->curr && node != win->old) goto next; if (node == win->curr) attron(A_REVERSE); move(count + 1, 0); win->ops->display(win, node); if (node == win->curr) attroff(A_REVERSE); next: next = win->ops->next(win, node, false); if (next == NULL) break; if (win->ops->needs_blank(win, node, next)) { count++; move(count + 1, 0); win->ops->display(win, NULL); } node = next; } move(LINES - 1, 0); attron(COLOR_PAIR(C_HEADER) | A_BOLD); win->ops->footer(win, handle); attroff(COLOR_PAIR(C_HEADER) | A_BOLD); } static void tui_window_set_middle_prev(struct tui_window *win, void *target) { void *prev; while (win->curr != target) tui_window_move_up(win); while (win->curr_index - win->top_index < LINES / 2) { prev = win->ops->prev(win, win->top, false); if (prev == NULL) break; if (win->ops->needs_blank(win, prev, win->top)) win->top_index--; win->top = win->ops->prev(win, win->top, true); win->top_index--; } } static void tui_window_set_middle_next(struct tui_window *win, void *target) { void *old, *next; int next_index; while (win->curr != target) tui_window_move_down(win); /* move next to the end of the page */ old = next = win->curr; next_index = win->curr_index; while (next_index - win->top_index < LINES - 2) { next = win->ops->next(win, old, false); if (next == NULL) return; next_index++; if (win->ops->needs_blank(win, old, next)) next_index++; old = next; } next = win->ops->prev(win, old, false); /* move the top down only if there's node at the end */ while (win->curr_index - win->top_index >= LINES / 2) { next = win->ops->next(win, next, false); if (next == NULL) break; old = win->top; win->top = win->ops->next(win, old, true); win->top_index++; if (win->ops->needs_blank(win, old, win->top)) win->top_index++; } } static void tui_window_set_middle(struct tui_window *win) { int offset_from_top = win->curr_index - win->top_index; int offset_half = LINES / 2; if (offset_from_top < offset_half - 2) tui_window_set_middle_prev(win, win->curr); else if (offset_from_top > offset_half + 1) tui_window_set_middle_next(win, win->curr); } static bool tui_window_can_search(struct tui_window *win) { return win->ops->search != NULL; } static char * tui_search_start(void) { WINDOW *win; int w = COLS / 2; int h = 8; char buf[512]; int n = 0; char *str = NULL; struct tui_graph *graph; win = newwin(h, w, (LINES - h) / 2, (COLS - w) / 2); box(win, 0, 0); mvwprintw(win, 1, 1, "Search function:"); mvwprintw(win, 2, 2, "(press ESC to exit)"); wrefresh(win); wmove(win, 5, 3); wrefresh(win); buf[0] = '\0'; while (true) { int k = wgetch(win); switch (k) { case KEY_ESCAPE: goto out; case KEY_BACKSPACE: case KEY_DC: case 127: case '\b': if (n > 0) { mvwprintw(win, 5, 3, "%*s", n, ""); buf[--n] = '\0'; } break; case KEY_ENTER: case '\n': str = xstrdup(buf); goto out; default: if (isprint(k)) buf[n++] = k; buf[n] = '\0'; break; } mvwprintw(win, 5, 3, "%-.*s", w - 5, buf); wmove(win, 5, 3 + n); wrefresh(win); } out: list_for_each_entry(graph, &tui_graph_list, list) graph->win.search_count = -1; partial_graph.win.search_count = -1; tui_report.win.search_count = -1; delwin(win); return str; } static void tui_window_search_count(struct tui_window *win) { void *node; if (tui_search == NULL || win->ops->search == NULL) return; if (win->search_count != -1) return; win->search_count = 0; node = win->ops->top(win, false); while (node) { if (win->ops->search(win, node, tui_search)) win->search_count++; node = win->ops->next(win, node, false); } } static void tui_window_search_prev(struct tui_window *win) { void *node = win->curr; if (tui_search == NULL || win->ops->search == NULL) return; while (true) { node = win->ops->prev(win, node, false); if (node == NULL) return; if (win->ops->search(win, node, tui_search)) break; } tui_window_set_middle_prev(win, node); } static void tui_window_search_next(struct tui_window *win) { void *node = win->curr; if (tui_search == NULL || win->ops->search == NULL) return; while (true) { node = win->ops->next(win, node, false); if (node == NULL) return; if (win->ops->search(win, node, tui_search)) break; } tui_window_set_middle_next(win, node); } static bool tui_window_change(struct tui_window *win, struct tui_window *new_win) { if (win == new_win) return false; tui_window_search_count(new_win); return true; } static bool tui_window_enter(struct tui_window *win, struct tui_window *prev_win) { if (win->ops->enter == NULL) return false; return win->ops->enter(win, win->curr); } static bool tui_window_collapse(struct tui_window *win, bool all) { if (win->ops->collapse == NULL) return false; /* fold all the directly children */ return win->ops->collapse(win, win->curr, all, 1); } static bool tui_window_expand(struct tui_window *win, bool all) { if (win->ops->expand == NULL) return false; /* unfold all the directly children */ return win->ops->expand(win, win->curr, all, 1); } static bool tui_window_move_parent(struct tui_window *win) { void *parent = win->ops->parent(win, win->curr); if (parent == NULL) return false; while (win->curr != parent) tui_window_move_up(win); return tui_window_collapse(win, false); } static bool tui_window_longest_child(struct tui_window *win) { if (win->ops->longest_child == NULL) return false; return win->ops->longest_child(win, win->curr); } static bool tui_window_open_editor(struct tui_window *win) { struct debug_location *dloc; const char *editor = getenv("EDITOR"); struct strv editor_strv; int pid, status; int ret; if (win->ops->location == NULL) return false; dloc = win->ops->location(win, win->curr); if (dloc == NULL || dloc->file == NULL) return false; /* can read file? */ if (access(dloc->file->name, R_OK) < 0) return false; if (editor == NULL) editor = "vi"; endwin(); strv_split(&editor_strv, editor, " "); if (!strncmp(editor, "vi", 2) || !strncmp(editor, "emacs", 5)) { char buf[16]; /* run 'vi +line file' */ snprintf(buf, sizeof(buf), "+%d", dloc->line); strv_append(&editor_strv, buf); strv_append(&editor_strv, dloc->file->name); } else { /* I don't know what to do */ strv_append(&editor_strv, dloc->file->name); } pid = fork(); if (pid < 0) { int saved_errno = errno; endwin(); errno = saved_errno; pr_err("forking editor failed"); } if (pid == 0) { execvp(editor_strv.p[0], editor_strv.p); exit(1); } strv_free(&editor_strv); do { /* can return early by signal (e.g. SIGWINCH) */ ret = waitpid(pid, &status, 0); } while (ret < 0 && errno == EINTR); refresh(); return true; } static void tui_window_help(void) { WINDOW *win; int w = 64; int h = ARRAY_SIZE(help) + 5; unsigned i; if (w > COLS) w = COLS; if (h > LINES) h = LINES; win = newwin(h, w, (LINES - h) / 2, (COLS - w) / 2); box(win, 0, 0); mvwprintw(win, 1, 1, "Help: (press any key to exit)"); for (i = 0; i < ARRAY_SIZE(help); i++) mvwprintw(win, i + 3, 2, "%-*.*s", w-3, w-3, help[i]); mvwprintw(win, h-1, w-1, ""); wrefresh(win); /* wait for key press */ wgetch(win); delwin(win); } static inline void cancel_search() { free(tui_search); tui_search = NULL; } static void tui_main_loop(struct opts *opts, struct uftrace_data *handle) { int key = 0; bool full_redraw = true; struct tui_graph *graph; struct tui_report *report; struct tui_list *info; struct tui_list *session; struct tui_window *win; void *old_top; graph = tui_graph_init(opts); report = tui_report_init(opts); info = tui_info_init(opts, handle); session = tui_session_init(opts); /* start with graph only if there's one session */ if (session->nr_node > 1) win = &session->win; else win = &graph->win; old_top = win->top; while (true) { switch (key) { case KEY_RESIZE: full_redraw = true; break; case KEY_UP: case 'k': cancel_search(); tui_window_move_up(win); break; case KEY_DOWN: case 'j': cancel_search(); tui_window_move_down(win); break; case KEY_PPAGE: cancel_search(); tui_window_page_up(win); break; case KEY_NPAGE: cancel_search(); tui_window_page_down(win); break; case KEY_HOME: cancel_search(); tui_window_move_home(win); break; case KEY_END: cancel_search(); tui_window_move_end(win); break; case KEY_ENTER: case '\n': full_redraw = tui_window_enter(win, win->curr); if (win == &session->win) { struct tui_list_node *cmd = win->curr; switch ((long)cmd->data) { case TUI_SESS_REPORT: win = &report->win; tui_window_move_home(win); break; case TUI_SESS_INFO: win = &info->win; tui_window_move_home(win); break; case TUI_SESS_HELP: tui_window_help(); break; case TUI_SESS_QUIT: goto out; default: /* change window for the current graph */ graph = get_current_graph(win->curr, NULL); win = &graph->win; tui_window_move_home(win); break; } } break; case KEY_ESCAPE: cancel_search(); break; case 'G': if (tui_window_change(win, &graph->win)) { /* full graph mode */ win = &graph->win; full_redraw = true; } break; case 'g': if (win == &graph->win || win == &partial_graph.win) { struct tui_report_node *func; struct tui_graph_node *curr = win->curr; func = (void *)report_find_node(&report->name_tree, curr->n.name); if (func == NULL) break; build_partial_graph(func, graph); } else if (win == &report->win) { build_partial_graph(win->curr, graph); } else { break; } win = &partial_graph.win; tui_window_move_home(win); tui_window_search_count(win); full_redraw = true; break; case 'R': if (tui_window_change(win, &report->win)) { win = &report->win; tui_window_move_home(win); full_redraw = true; } break; case 'r': if (tui_window_change(win, &report->win)) { struct tui_report_node *func; struct tui_graph_node *graph_curr = win->curr; func = (void *)report_find_node(&report->name_tree, graph_curr->n.name); if (func == NULL) break; /* change to report window */ win = &report->win; /* move focus on the same function */ tui_window_move_home(win); tui_window_set_middle_next(win, func); full_redraw = true; } break; case 'I': if (tui_window_change(win, &info->win)) { win = &info->win; full_redraw = true; } break; case 'S': if (tui_window_change(win, &session->win)) { win = &session->win; full_redraw = true; } break; case 'O': full_redraw = tui_window_open_editor(win); break; case 'c': full_redraw = tui_window_collapse(win, false); break; case 'e': full_redraw = tui_window_expand(win, false); break; case 'C': full_redraw = tui_window_collapse(win, true); break; case 'E': full_redraw = tui_window_expand(win, true); break; case 'p': full_redraw = tui_window_move_prev(win); break; case 'n': full_redraw = tui_window_move_next(win); break; case 'u': full_redraw = tui_window_move_parent(win); break; case 'l': full_redraw = tui_window_longest_child(win); break; case 'z': tui_window_set_middle(win); break; case '/': if (tui_window_can_search(win)) { free(tui_search); tui_search = tui_search_start(); tui_window_search_count(win); /* move to the next match if found */ if (win->search_count > 0) tui_window_search_next(win); full_redraw = true; } break; case '<': case 'P': tui_window_search_prev(win); break; case '>': case 'N': tui_window_search_next(win); break; case 'v': tui_debug = !tui_debug; break; case 'h': case '?': tui_window_help(); full_redraw = true; break; case 'q': goto out; default: break; } if (win->top != old_top) full_redraw = true; if (full_redraw) clear(); tui_window_display(win, full_redraw, handle); refresh(); full_redraw = false; win->old = win->curr; old_top = win->top; move(LINES-1, COLS-1); key = getch(); } out: tui_graph_finish(); tui_report_finish(); tui_info_finish(); tui_session_finish(); } static void display_loading_msg() { char *tuimsg = "Building graph for TUI..."; int row, col; getmaxyx(stdscr, row, col); mvprintw(row / 2, (col - strlen(tuimsg)) / 2, "%s", tuimsg); refresh(); } int command_tui(int argc, char *argv[], struct opts *opts) { int ret; struct uftrace_data handle; struct uftrace_task_reader *task; ret = open_data_file(opts, &handle); if (ret < 0) { pr_warn("cannot open record data: %s: %m\n", opts->dirname); return -1; } setlocale(LC_ALL, ""); initscr(); init_colors(); keypad(stdscr, true); noecho(); atexit(tui_cleanup); /* Print a message before main screen is launched. */ display_loading_msg(); tui_setup(&handle, opts); fstack_setup_filters(opts, &handle); while (read_rstack(&handle, &task) == 0 && !uftrace_done) { struct uftrace_record *rec = task->rstack; if (!fstack_check_opts(task, opts)) continue; if (!fstack_check_filter(task)) continue; ret = build_tui_node(task, rec, opts); if (ret) break; } add_remaining_node(opts, &handle); tui_main_loop(opts, &handle); close_data_file(opts, &handle); tui_cleanup(); return 0; } #else /* !HAVE_LIBNCURSES */ #include "uftrace.h" #include "utils/utils.h" int command_tui(int argc, char *argv[], struct opts *opts) { pr_warn("TUI is unsupported (libncursesw.so is missing)\n"); return 0; } #endif /* HAVE_LIBNCURSES */ uftrace-0.9.3/configure000077500000000000000000000153441351236475300151030ustar00rootroot00000000000000#!/usr/bin/env bash #-*- mode: shell-script; -*- prefix=/usr/local srcdir=$(readlink -f $(dirname $0)) objdir=$(readlink -f ${objdir:-${PWD}}) output=${output:-${objdir}/.config} usage() { echo "Usage: $0 [] --help print this message --prefix= set install root dir as (default: /usr/local) --bindir= set executable install dir as (default: \${prefix}/bin) --libdir= set library install dir as (default: \${prefix}/lib) --mandir= set manual doc install dir as (default: \${prefix}/share/man) --objdir= set build dir as (default: \${PWD}) --sysconfdir= override the etc dir as --with-elfutils= search for elfutils in /include and /lib --without-libelf build without libelf (and libdw) (even if found on the system) --without-libdw build without libdw (even if found on the system) --without-libstdc++ build without libstdc++ (even if found on the system) --without-libpython build without libpython2.7 (even if found on the system) --without-libncurses build without libncursesw (even if found on the system) --without-capstone build without libcapstone (even if found on the system) --without-perf build without perf event (even if available) --without-schedule build without scheduler event (even if available) -p preserve old setting Some influential environment variables: ARCH Target architecture e.g. arm, aarch64, or x86_64 CROSS_COMPILE Specify the compiler prefix during compilation e.g. CC is overridden by \$(CROSS_COMPILE)gcc CFLAGS C compiler flags LDFLAGS linker flags " exit 1 } # preserve old settings preserve() { if [ -f ${output} ]; then while read pre opt op val; do # do not change directory settings (to prevent confusion) if [ "${opt:3}" = "dir" ]; then continue fi if [ "$op" = ":=" -o "$op" = "=" ]; then eval "$opt=\"$val\"" fi done < ${output} fi } IGNORE= while getopts ":ho:-:p" opt; do case "$opt" in -) # process --long-options case "$OPTARG" in help) usage ;; without-libelf) IGNORE="${IGNORE} libelf libdw" ;; without-*) IGNORE="${IGNORE} ${OPTARG#*-}" ;; *=*) opt=${OPTARG%%=*}; val=${OPTARG#*=} eval "${opt/-/_}='$val'" ;; *) ;; esac ;; o) output=$OPTARG ;; p) preserve ;; *) usage ;; esac done shift $((OPTIND - 1)) for arg; do opt=${arg%%=*} val=${arg#*=} eval "$opt='$val'" done if [ -z "$ARCH" ]; then uname_M=$(uname -m 2>/dev/null || echo not) ARCH=$(echo $uname_M | sed -e s/i.86/i386/ -e s/arm.*/arm/ ) if [ "$ARCH" = "x86_64" ] && echo "$CFLAGS" | grep -w m32 ; then ARCH=i386 fi fi bindir=${bindir:-${prefix}/bin} libdir=${libdir:-${prefix}/lib} etcdir=${etcdir:-${prefix}/etc} mandir=${mandir:-${prefix}/share/man} if [ "$etcdir" = /usr/etc ]; then etcdir=/etc fi if [ -n "$sysconfdir" ]; then etcdir=$sysconfdir fi CC=${CC:-${CROSS_COMPILE}gcc} LD=${LD:-${CROSS_COMPILE}ld} # objdir can be changed, reset output objdir=$(readlink -f ${objdir}) output=${output:-${objdir}/.config} # # this is needed to suppress warning from make below. # otherwise it'll get the following warning # when called from make -jN. # # warning: jobserver unavailable: using -j1. Add '+' to parent make rule. # MAKEFLAGS= MAKEOVERRIDES= export CC CFLAGS LD LDFLAGS make -siC ${srcdir}/check-deps check-clean make -siC ${srcdir}/check-deps check-build for dep in $IGNORE; do TARGET= case "$dep" in libelf) TARGET=have_libelf ;; libdw) TARGET=have_libdw ;; libpython*) TARGET=have_libpython2.7 ;; libncurse*) TARGET=have_libncurses ;; libstdc++) TARGET=cxa_demangle ;; capstone) TARGET=have_libcapstone ;; perf*) TARGET=perf_clockid ;; sched*) TARGET=perf_context_switch;; *) ;; esac if [ ! -z "$TARGET" ]; then rm -f ${srcdir}/check-deps/$TARGET fi done echo "uftrace detected system features:" print_feature() { item=$1 file=$2 description=$3 if [ -t 1 -a "$TERM" != "dumb" ]; then # use colored output only when stdout is tty if [ -f ${srcdir}/check-deps/${file} ]; then onoff="\033[32mon \033[0m" else onoff="\033[91mOFF\033[0m" fi else if [ -f ${srcdir}/check-deps/${file} ]; then onoff="on " else onoff="OFF" fi fi printf "...%15s: [ ${onoff} ] - %s\n" "${item}" "${description}" } printf "...%15s: %s\n" "prefix" "${prefix}" print_feature "libelf" "have_libelf" "more flexible ELF data handling" print_feature "libdw" "have_libdw" "DWARF debug info support" print_feature "libpython2.7" "have_libpython2.7" "python scripting support" print_feature "libncursesw" "have_libncurses" "TUI support" print_feature "cxa_demangle" "cxa_demangle" "full demangler support with libstdc++" print_feature "perf_event" "perf_clockid" "perf (PMU) event support" print_feature "schedule" "perf_context_switch" "scheduler event support" print_feature "capstone" "have_libcapstone" "full dynamic tracing support" cat >$output <> $output fi cat >>$output < $objdir/Makefile < /dev/null 2>&1 && echo yes || echo no) RM := rm -f INSTALL = install include ../Makefile.include COMMANDS = record replay live report recv info dump graph script tui MANPAGES = uftrace.1 $(patsubst %,uftrace-%.1,$(COMMANDS)) ifeq ($(has_pandoc),yes) all: $(MANPAGES) %.1: %.md $(QUIET_GEN)pandoc -s $< -t man -o $@ # $(DESTDIR) already contains $(mandir) by ../Makefile install: all $(call QUIET_INSTALL, man-pages) $(Q)$(INSTALL) -d -m 755 $(DESTDIR)/man1 $(Q)for F in $(MANPAGES); do $(INSTALL) -m 644 $${F} $(DESTDIR)/man1; done uninstall: $(call QUIET_UNINSTALL, man-pages) $(Q)for F in $(MANPAGES); do ${RM} $(DESTDIR)/man1/$${F}; done clean: $(call QUIET_CLEAN, man-pages) $(Q)$(RM) *.1 else ifneq ($(MAKECMDGOALS),clean) $(warning To install man pages, please install 'pandoc'.) endif install: uninstall: clean: endif .PHONY: all clean PHONY uftrace-0.9.3/doc/uftrace-chrome.png000066400000000000000000005271671351236475300173660ustar00rootroot00000000000000‰PNG  IHDRÞ‹gŽ ÏbKGDÿÿÿ ½§“ pHYs  šœtIMEà   I¥9 IDATxÚìw|ÅöÀgfwoÉMï•„Tzï)O)bA@A±`£øž~–X±‚½7)‚  ”"B é!¤—›Ü²»3óûcárIãÞ½©0ß?ÜÍÎΞ3g§œ93/^¼ ƒÁ`0 ƒÑöá8îøñã§NR‘–Rš0`À€]»veeeAo0åŒ1"88xåÊ•”Rf*­ „ÏóV«UEZNg±XÔåÛ¿ÿ;¬[»®ªº ¨Ú®V­ZEQ‘Bxçwò²,+Ÿ¥B¨Ø¨òÚ?¹ÍÅä­*—n»‘r¹Q‹™"3E– 3– 3E¦X– 3E–ËÍf$€K—.Mœ81((È©"B¨¼¼|Æ ”Ò¬¬¬'Ÿ|’çùÆ…Áó|RRReee@@BhÖ¬Y¢(2oH«òË8p`üøñ’$9•V£Ñ,]ºtöìÙ”R§,–ã¸ÔÔÔ¬¬,Jhqqñ‚ œµ žç÷ìÙc4ýýý!„ÿþ÷¿}‚ k×®5›Í¼ò Û¼¤—Ý6ˆã‘½»ˆbI&µnSþA»Ç!€eL¼­§A®M®æ6pÙiÖÀmˆ8H€`L!ÏAŒIS¼ qˆâ+Ç!,ËKs(–åÂDf¹0Sd¹°\˜È,fŠ,f$M— ¼‚mb!ŽãƘˣ3žC˘\M‚R’\“q±$“Ë·!Žç %”RLˆs®ˆ8Žã€RBä+ã¦!J€‡(–q£8‡lâBj)‡ÑòØÌOEѨ.P%ÓËãz„löïì—íýk[=Ïqª|o×Ú¼íøZžTÈñ8}÷ï{Ó ¯Ñð@Eë'OŽ$uŸ„R1çÔŸ;[Œ`pÒ™¥| ´ª¨XÔ»{»éa³8o!DØXR$óþ^<¬³Ò€€Èéû×í+ Ž%¥%oêŸ{ðíÙ»«7g«âíe 9cû®Ó1·Œˆ4 h<¹v[Î-Çø™°p<ƒÁ`0 ƒ!uø; $%yÇv² Ú;Ä[C!²^º°s߉à[GwöÔá+þ…kFˆãË’7í«2îOQ¦"¾ò¯M{ph„ŽóìÙ¹½:<œF®8õÏ?‡Ïå^ßsh®M‘TYT¼½¼M9+8 NÀ¤±”Cˆ2š ׋FÝl6¯:yv‘ •¦lûëH¡Yˆé3j` €ÖõÚ!jcàÝÍ#èâÙ­íž|d\;=òxA‹xJ$Q†‚F@Š%QÂq‚Às"‹¢L/¶?¢åø¯?†O÷÷r×hB)‘e8GJ°$ÉH£å@ A@‰$IŠ“ƒG–“~/ŽvGÇvp^ÎB¦/p@&C«U†¼Fà.G¾`I”®|Òq‚F@”ˆ• àTE Ç <D’)(8{ä—€GF÷ÔðŠ£KEÉæY¸j××ëLS–D†øziËr¬Ù)$ô묕e,Š"¼ò@ Èxhˆ%Q&ñGP"KV CŽxžCYe h‚ <㢽xH(¥€ _t¼à)â´,‰"W3Ä’(S^# Å‹¨,IrãÕk ƒÁ`0 £MŒo¢¥ù—ÌÜ9ÿ÷÷Æû†sPÌ<½ç½g>Ÿv`XW/=¾6Iq&ç÷|û)4|œ¯,ÏÛöɪsó— Æ@€ ZÁeQ"¼FÃÙ*Žç ²Œ)€-Ý¿ñ«/þA“Æßæƒ/l_óá?9O½4®3Çó1aÿÓofEz‹=zfˆîà ¯¯.’„ÎcŸ;ý¶ /N^Ô7äÈŽ\ßÑS;•ÿ–t”ÄÝ>wö´^€BzñÌß«^a=é-¯ü±ûùÏþïÃ?+d}ÿo¾z»ÏöÞÞ¾‹4ï¢ý¯±íN®Ù|Þ±ú›©ù[æ|´Növ7¦åÉ“<¹›»Œ)€Ð”Ÿúí›o§úEˆÇöèÌÌm[ÿ×ÅγÞ\t{lÞ¡Õï.ùîœQŒ¾÷å×&„lýtÁ’íôìÇ›G혻à‡\QvKœ»|áX7Y&rplÙ³ÿÛ¾·“×Oó‰c÷,øo¤N<¼òÕÙ¤'Ÿðäw/<Wyè—7Þû.µG%Þ?gö}Õ_Í} „†§þsªÄwú¢wt Jþiö _¤Z¡ÐcÖ;ïMìX–qpùïl8šßnðÌ—ßoHݺlégIâ€{ç=w¯Ç†o× ÿï‹}ü(?úñÛžÿbçø{¶Å,yiŇò»~þê£åURÈi‹Ÿ¹?`åk︢ä´K°û³óŸ’àC0iÜ•±M·€¶yr¹ ·t¹Qsa¦Èra¦ÈŠåÂL‘åÂL‘_ÝãL çÑ¿Kùî”±#ܬÅ9Yça».:x½a*Ų¾çã·j—­?u×Sx(]»%üŽ×<3ÿ\ŸùèøÁ›¾ùã9³à7îÙ‹Þýªè±Å‡îX6ÿ;ë´óãþö}2ìqß¿zê,=ujÃ>ôÌÜ'{DxRУg¨ÛsÿûúÄí¯zü³ôó_°Á˜vÑ<þ¹ùÁÉß~¶,yç¹Þ½=iý±^³ßôÁ‡+ö¦ >xòÉÛ{[ßžö^x$µÀÿŽ·^'”íûô•OSJD4ìÝgK’µÊXe±! „ð^^]oÍhÅ\ÞÙÄågÔÿzc^ ­2Ên¼,›Òk¬+$ Öª¦ü _”ã¦ÎzèÖ@úŸJz㟋uŒ×¾÷ꂦk—)‰cB°$I² $SÑÙv}¿{yFW¼{¾yÄW¿ÿ'èŸÇ¿´mÂêÁËßÚuë’_? úgñ;«wEù퇌G?Ùø¯°ŒYw<¿!æÇûâ8Y¶ yùÕ‡5º»g Ùœš¹kÒº “=öÎzrëÄ÷×M*þú•9[O„‡K4‰üpÏ·/LÿÊðÁŸßÎøáÅ9'ß?,„È ¤}—Mé>ðé±^Gxë¬Ûîð<øäíÏþÞÿGhÌÌéþô—³†ÿqgøÎ¼U﮾çãG¦¯OŸ4Àtñb§{_™ó ç©…“–}=àËyÑœL ¤D*:F}úÜ”gt~øž«GÿøÀ¢½%ÀÊÅk¿þÓWýÅ7ï™ðM¿ßn{àé»;/¹#hßÛéw¾²öÁ¾%sÇÞ·"ãö§#9 !À ËÓKþïìÛñ  øñÙ?ªe@¥så]^_úÒ0Ϥ»Ç¿¶»×üóË×uxæ³ûxnz÷Ñ »Ûõµóó£¿[õì…Kÿ·=cX;sRzôÂ5Ÿ6¯yû§Ç|˜½é»òA/þþqü¶ç_Þ·¹½õØÆÐéŸýÙ—üôÊÊ”ãLÆJJ(bkYQuÁ¥Ã«O„<ÿÝçÃøÃŸÿ–š’\µb3~ñ»Í]øãÏN]º­ÓóÄœu@ø¿½«ãþøîå_“Ïv`”°5Ã,¶–›åÂra"³\˜)²\X.Ìoè\®""£.£ûdž<š{g×à’ü¼jèº:o®±å‘HÌ„IàÅŸS¦-îIÿ´×pÿ÷‘â?;L„y«_üÞðæê•ñå{žyqu·÷$‡Ž”™ÈyQ+Ÿ8X(^, è¨EBñbÉk|ïo‚EB‘.¾W5û3ÈhsqQÄйs&e|òÈÛŸlʸûG>ùï¾Õ‡~µbËÉ «×T&þ¼æ‚#«__û{ç¸Äê’ ß.ï¼óTÙçó_Þž{kŸ¾$ƒü4­{Þ«R²hx;zéèšÙsí+â5b)J|qíÒ½ÂÜl¢©;C‡Ñr~‰å¥’ÁßSP¬•RBZE§ì^£ü‹TWU¤uÓÖ±³uÍE|v1/<¼øÇÇodö5ļy_Y÷‡îá/€:3¯û ‹ž½ž™…ˆ,ËÏþ‘‡?Rç„z÷ܦÊWM©òqªÔ>ÀÇ [„~Œ4¥n^“Rp΂BË,égü¢Fke¯Ä—^œ‘²ü°´Û³¹@+ó–’K§ HB(–­¢,#Q”0 ŽéÒNSt,·ˆÒ?Š·Ð®þ¸Tí+ ¡½´´ŒºÅŽíän•¬®‹ŠŠ`,K’$Éæì¿³)ãÀÆ\6žØsÞ<Œ ¼%Ò âÓ90 €A§+2Y)ôMŒpC.¼¯ÎºaÿÑÃ'³Î™¡Oï~!n=ãý½<$½_¯„ðè`ä@7µÚš±§€”]+2(§ÿ)Æ`Y²ZD~ÀÔ{œHZ¹¡¢¬Zæ*ª.žÞŸ”RNô±£nñ—eYE™P(Å ÓðØ`_-öèy‹ÇçgRr*LLJ¬õ´%«<ÞÂvÓ›Dtæ* ‹¾÷žnG÷¯Ý`ɰÊ2‹µ0uë@«ù1/¾lÍ>ºt[èH-¦“_ú(=°ý'%ŠÊæË¦~q·Em^óÑ;ºv8&§|KútòÑ#Æ ±Tåbh2$T2Ë@ã-)Á€"æ(f0 ƒÁ`0nLê]A0 Èß~®t¬õîÒÑxŒÔ5L­ñJd0hxØÚã'KÚ›fu×ß]:N!â¹²Ó§*´ž©Û~IÅ…é{Rt¯´£N $¡‰ÿº¸çPfU¥Ñ3. £@ ¦àJdD<âEòéäÉÖËPù{vIÅ’(ÊÏ—šº íDõôÄ»Ecµà  ÂÓ /«†AÝï†ëÖòmJL\ïEQIä"GMµ3ý³uŸ4ud\¨%2@Ì4Ú¤c†'E;–žì1dDGOeKh7ÿÈøv¾à:Þ‰¥8;#·ÄB!Dœ”{úxé‚ÑJ¡Pëã¯ã»———Œ)@§Àõ´@¤Ñ»{zi„ˆ³<<‘ ¨'æ¥ÞI¸¼ÔêÓ²jà¡×ÔYƒ{A _ÊC1#&ÝÙ…uoþJ)EÊKÐËjû©\S<$PBd ñä®óÞCo/X­gQ}LÏ¢Ô´³$w۳ϼ’ïÖ¥‹U l×e`Ÿ¨œ]æ=$„R@ !X&„‚E‰`ŒÝC#CÑŽÍU¸,ÿÂß]ý´œUÆ„Še B)ÅX¾úv”"V˜D.â–v–jM@Ïa½üOþ±GÔk0– &”R"‹˜PJÆ2¦‚ò-'2KŒ¸øï-VïŽ;u1êö±·v—EYÆ”RB°$*YQym‡[ÐãäÆóEÄ\‘¾ó@LX—NeB)%c Ì—ö“ãGôöæÂü|‘Ó‡Æá¿Î§™@ùšggo8"#²¶œ/-_ÏymWrB”Rpr_rz)…„Kç~ýpş΃ï;¨äàÞ½½~ÿÑüâ*±ìį9>¾±@´Ê„*Ž®Ë¥i_Àõ”~Ã×¼Íñ\ZÕ˰\næ\˜bY.ÌY.,¦X– 3Å#—:Ç~²,ê{ŽŒOûvSqt¯8wY’)pÄ5(€AqÃÜ}üÉÙÐQ1Þ”R@‰,ɾ]úùUe: ÜÑãlr¡›^å¹soН¯wd¯ˆÓ+•}ô˜R@êÐe€wÊËŸn¼„yl¼°úóOÎõ˜ÜßKCHÙ䌢JPylg¹l”®¬¢”B°ˆ½;‡{ŸÚtH‚òÅüSé!zo–¤Ë+·”ú浤¢Ð>ƒÇ ko>nBR™zÞ÷LŸ Þ=ïì.Ø/~©wÎh­ž =zÞ5sú˜žQícbbbbcbÂ<€…H¡àØ.&6&&&:º}‡a£'Ü?ª›¯ût¤zü2HÎñ†>>ÃüsQ§Ñ÷ô£õ¸öpùQ ¼BÛí`€´¾XBêYHt~#d ¤„­wl”è$1xÌÜ‘½öØÔßFNôï'ö»ºzæ’?^òÌÏF‘ÿ~íÖŽîáÓ»~õÚ“T‚ãÿ=,`B)$r¾Qq7Dx¿Þ½dK’oïçæ=üî30úŽ{bBçè Ñ=¢ÝL¸€ð8IÏ€¼Âž(Å‚w—^ƒÿ~ÿù¯^újÉ }—,zàK«.öŽçîs£Eqž:Љ{t¿pÛM§ùw)>þÅÂÝ™UÁOÍŸ ¬"Àë#â ÁTßk`‰àÓ©+ÔºN|qÚïÿgÂ[R»-wª{öܶlÞÚ>þÎìûpÿƒÓŸþiÕûG¢ævuǘ øàޱ^<Õ…Ævòæ¡&辑§wÿôâg§*ï÷ÊÀ¨ÐÎLÿú«W&;Ýöðô[z”çÆtòå1¦Á:·.Ó XðÂÔ'º¿÷?O ÞøyÒ¬)ÏöûnÙ£ã ão{ú?÷ Ô] ¾\2å8ivâ`!ÿTŒ;Góo:Ô±7¤Xö é׉¼ò߇V[8¯ñ‹ßÑ‹y4ãËž¸îž=ï¶ÍÆð¼Äºy‡Åè HqÍÔUó6Ñ ØÆ½­y^†år3çÂËra¦Èra¹0Ų\˜)¶é\êñË! Ìσv“Ç üÕ}L(~áQ GAÇ3Õz[àÚç_#JÝxê ±è=Ã%- ºsÉìì·þó`çÛgò¼­Ø.1qð¹ho!lÔðŽ%QcÝ‘”`·vÌy)pÍ ¦Ý/ë¼;œöŸÁ:(Þ¿½)ýç·fœ)ö{üù)ÑýÖÏyÍ燢Ã|½:Œ~à™Ò¯žšú„.ªÿôG&·3T„vêàÉ@y߈h­6ð÷¥sÖ-Ã^Ñcÿw_¸$Y¢ä5éÝûèºêd_ÏñÄhÝÎB V'P\×Ö¹×Ijw:â„úö®×5C‰ÄGOÿè[ˆeÒga"À’„ôf^ãà¡ÒÅcÛŽ !#zëH½?ðôéÓvÑ:×l8Œ8žG@–e äI–)à´ZJ0Q"Ë §ÿ,Ê”ãyžç Ë’Í !/Ë2EZ)§š]=u˲Œ‘ AX1I&ãy@d¬œž  òd*‰2䔢¯žÍ‚1!H‘% xAàeãßë^ü›àéIƒõXÆò僼!„Bžçˆ,c‚´ZNEyA€’(CÄ —ÉÆ¢(Žx CžGŒâ •Eñò©àñOe‰rGe™r< B,‹²LÇ <‡ ¤X–d #²(SÄs<¤²L9†ƒ€bLB”H2ᮞ-)'“ó<‚€`IÆ€ç9,K€ÓpÁ¼õ“¦í\²ýÃö€@ÁUý < ¥K² ”r“0àxžD’q½¦a&U㺃·'siU/Ãr¹™saŠe¹0Sd¹°\˜bY.ÌÛt.<ÏïÞ½{Ô¨QAAAö3ùˆã9HeCAÃSY”)/ðË2±Ø`EEÅÚµkÇŒ³víÚ3fð¼Ýöñ¼ÀeX9ŽCÊÓxÀApyhFâÊ’2Ôâ±,^3þ€ˆçyîòQØX”1Rêö7÷ZÇNß_–¬2åGK2ä‘% ‡ T–$L  á‰$b yA€D’)'(oˆd•ÈÕ¬8H±-Hçù¤¤$I’"##ÿøã™3gŠ¢Èü­„PAAÁÆ/I’Si5ÍÒ¥KgÏžíìj5ŽãNŸ>}æÌ™¾}û®\¹rÁ‚ÎZ…bW²,GDDìØ±cÆŒu=r¼€–ëŒ ‚°nݺÈÈÈköš©ñUcYºâ˜¢€X¯ü[¶˜åÃvdI”¥:üH’ÕªÜkÁ¶T¢}Blµ(ÿ¯x6É5.Nj÷dŒí²°ÝF.g$‘BdÑh’,‹™Òkd/»ÜˆÅ¢¼tY]ßy1 @)‹‹ëÛ·oRRRNNŽŠ'¨Ø f×ÜrË-AAAk×®e±3­„ÇqêšiµZë•x-géÓ§O||üÆ«««ÕÙ¼‹v!3f LIIaFÀ`0 ƒÁ`07Ç)ø¶XÛɾÊ?jÿv«™0ÆÇ!„¸­ëÞæÈË4z.cBˆ(ÑÖei=¹¨xsi ¹ƒ·Ùç¢X…#¦NY–)¥<Ï«cÌcŒ/=uõ& (J\¹^ë6J¬}Û•ä”RX#y]·µ©\€Ó/ãˆb¯I®JäÖ“‹ÝmÇ)FÖü­„P£Ñ¨ö›2t:ÅbazPV«E‘ÍÃ0í5?F–eWJß´‚ t˘*ÔiÒ"Íý €2e™©‚uö—†JÑ^ýÛ,]”Žu•]ÔžÙl¾‘¬BñôaŒ]l aqi³F£ƒÊÌÈàHHèÐÌ]¡ÅbyóÍ7_}õU[8œ-2Í6ê«}…aë&Κ5ëÓO?µZ­7ôªÀ&ñ,<÷Üs¯¿þº2OUCuÌä®ëYxõÕWŸ~úiOOOÛÅÚ dÚ«¯OðñÇßu×]¡¡¡µÏUe¶w]íýøã½{÷ŽgÚSÑdüúë¯!!!½{÷Æ;x Cã¸Ý»wSJ‡.Ëríãx˜í5ÐÙ+//ÿú믕ãTêl ˜56ÆxÑ¢Eo½õV=Öà^·¿7}úô¯¾úŠi¯Ñµ×FÛÁM›6yyyuëÖMiÚ@!^§Ó3a4…k†R@)h‘íµ „iiiÇéõ—ÍÛb±ˆ¢¨Óé4rÅl6˲,‚í†cÇŽ!„t:]uu5ÀÍÍ !ÄÔâ§OŸvssS L’$777ÛþyÕÕÕ„­Vk3BF ²²²t:2%Š¢^¯·ßÎM’$Œ1û`룠 €çye¡µÕjµ¯î$I²X,Ç)ÆÉ¨MYY¸²LÝjµjµZN§üÉjµJ’dß 0jPUU%˲·e±XX“áÊŽ¤‚ „Ìf³^¯W‚Ž¢(*Cwww¦¨:xÙÙÙÊ·YUU¥Ñhj4¯&“I¯×7ÏV)mÑ5söìY„^¯¯®®æyÞVéÙz,z½¾Yön“ÆøÝwßU®ïÛ·oùòåþþþ:uš}-Z´oß>eUÆxÞ¼yóçÏEÑd2)ÝÄ·Þz+;;;33“iÌÞö²³³ãââ-Z”ššjÛD`÷îÝÞÞÞŠUi¼_zé¥ÜÜÜÌÌL¶?ÈÕ¡‹/úùù-\¸°¸¸¸´´TñÂäååõìÙ3!!Á6+õÌ3Ï(ÕÛáÂ^{EEEÂ… B/]ºP&äÃÃà ƒÍ óÔSOåååedd¨;Bâ&&&fìØ±¶Ÿ¹¹¹_~ùezzzrr2SÎu‰ˆˆ?~¼­sOILL|íµ×:wî¬X#`þüù¹¹¹éééÊ´|¸C‡¶‹¿üò˾}û222JJJ˜ÆìÑëõS¦L±YؼysTTT¿~ýlmîŽ;vìØ‘‘‘QXXÈ4fV«0a‚½»J«Õúùùët:ås>pàÀ¦M›233óóó™Æì yá…žyæÛÑ[¶lY¿~}fffqqñMÚafÁ¸Y±bÅüùó+**”uUžžž__ßÈÈÈ%K–ÜvÛmQQQF3xðà¿ÿþ[Ù‘ž ô Êö=€?ž©¨(¥f³YéåxxxF@```HHÈÒ¥KGŽ©Äȸ»»'$$üóÏ?,fÁÞð(¥&“I J·}°999{÷î}ì±Çl^­VÛ¯_¿¿ÿþÛ6kÊP0JPº»»»âw.++ƒ¶k×.99ùÌ™3Êm#GŽÜ¿¿²N‡)Í^{Êtº^¯W´WYYÉq\ll¬¯¯¯mL2nܸ}ûö™L&¬^ƒØØX`D°ÿ~æ?u„¸¸8ûHv½^ß¾}ûuëÖEDDôë×Ïf{{÷î---e ck ð4½övîÜ–˜˜h«âºwï~ñâųgϲ™ÖX­™žž®Ñh¶nݪh5!!¡¢¢"99™}ÔÀßßßÃÃÃÞörrrbccãââJJJ”ɨ¨(Y–:Ä´WƒÈÈȼ¼¼eË–Ù"¶úöí[YYyòäÉ›¶sÂz´Œ™‰'.^¼8,,L™=.** –eY–å¹sçŽ;vèСJ}Z]]=f̘G}ô?þPÆÒ73J7Z¯×Fe¤§te”hÿÐÐÐãÇ3ëjÀ¿ øŒF£ŸŸÆXÅ'žxbêÔ©Jl0@ÅqãÆ=øàƒ?ýôSš‚â T6þ()) ÛS´—œœÜ­[·Î;+‹˜:îᇾûî»?ûì3¦.{RRR¾ùæ›gžy&$$D¹RYY¹hÑ¢nݺyâ‰'zöìùꫯÆÄÄ : ×ëW­Z%Bß¾}mk¹],>ůªªreŸ]eq‡‹; PJ ÃСCgÍš5räH·ß~û‘GÉÎÎ~ã7”²V«Ý¸q#¥´{÷ÂÅ⫪ªB©žÌ7™LÊË«öH’äáááŠö”ZkÙ²e%%%§OŸŽˆˆP6Ú¾}{~~þ­·ÞÚÀtquu5„Pµøf³c¬z:ÚEñEQ4›Í^^^®·¹|ðÁÅ‹?ÿÓO?=:==Ýh4=zôî»ï0`€ X¿~}LLŒmïÅWÆäöçâ9+¾ÉdR½%„,ËF£ÑÇÇÇEÕýúë¯ýõ—ÅbÙµkW~~~ÇŽW¯^ ظqã°aáìììåË— †©S§Ú>ùââ Õù¶é¾¢;vlÛ¶­ººú·ß~ÃLžú¨—ZPPðÛo¿ñù$''Guòï¿ÿþܹs®hï±Ç+//Wü½÷Þ+((Pü‹/¾ÈÌÌT|ÅŠ©©©ª“oذáðáîhïùçŸÏÊÊRü›o¾IKKS|õêÕ)))ª“oÞ¼ùŸþQ|çÎ;wîtE{K—.MNNV|ݺuÇŽS|Û¶mûöíS|Ïž=Û·oWüðáÃ6lpE{Ë—/ß³gêä;vìp%ùþýû•eê8~üøÚµkU'?wîÜ÷ßïŠö~ýõWÅÙ§Žƒþú믪“Ÿ|¸Í½¿N§ÓjµUUU-þò½zõRú»ê’wïÞã8ÕÉ»téRc7D§Ê½C‡nnnê’§¦¦†……yzzªf(ïß­[7žçU¿çεZ­ºäÇŽ‹uwwWñþÇ={600ÐÛÛ[]òŒŒ ???W´×©S'N§Nü”””ÈÈHuïþüy???uɳ²²ôz}@@Àu“+{E+ÿWŽ«T޽ Q&¯ê¼Mù ®lidã¸3g΄„„ج×þ~GšŒ .('ˆ©P>B(''G£ÑªH®&…1W¡|aII‰Ñhlß¾½:ÛCeffº»»ûùù©?//!¬NüÂÂB«ÕÚ®];uâ—–––——ÇÄĨK^YY™——שS'ÕÚS¶ó U÷ÅÅÅ&“)22R]reŽ7..N]r£Ñ˜••ÕµkWuÉÍfsjjjß¾}ÕŒ)Ërrr²êä”ÒcÇŽ©NŽRúê’ó<ðàÁ~ýú©îo¸’\áèÑ£ªŸÀqÜ¡C‡Zêý[\{múý%¹jËo‹âÛ·MJw«wïÞö•žÒݾ}»+ã¯Ë£$IÌpcA€WþßÀOÐØ·Õn´¸<9¥¤¤ÄÏÏYƒ:ŠŠŠ\Y}}3S\\ìïïÏô ŽÒÒRÛQ g©¨¨ðôôt%hëfÆh4êõzvâ’:ª««A`g©Ãb±PJ] ›º™)++s}«Öca¨ i7aÚkM`Œí1¶Ù‚ |óÍ7!!!ƒ rÑ5Ã_ºtÉ‘ûBJРò*²,7ú¶Éµg¨AP„WüGÇ)“ɲ,+¯¡¬$Iù)BH¹¢Ü!Ä»¨¦ÆÍ6YWßÜ]íë­{¡™ŸlÑ0Æ®ŸQûmë“¥ •W}¢Ù˨x·]ÑZêWppaKÃÕBÃÕEK‰Vû%ë“¥¾O¦áOI™Án‘jÙ©êºu‚RNwvÊ–š³ZnôÇ‘fÔAÑ”ÞEËžÑ@¹´ò¦çºÚkà¯{½ µ8êdQzª-ÛMm=í©S@5ŠƒÒZк®Ûô4§þõz½rØÕr×[¿i5\-+×ÝÝÝíµÑœS£›Æí*PJ===óòòšh2©¾Ñ#ÕuO ®qDz dYVNãrÞ‘¸%^T9/>fÌ___e·ËëvÐìÚ?Gq¸¬]»6;;;((hêÔ©ÊVg{÷îuwwŸ8q¢¯¯¯ ;vìÈËË»ï¾ûBZ­vË–-ÉÉÉþþþãÇ÷òòÊÉÉÙ²eKuuu¿~ý† V[e W‹N B®ë›°Ée/i?k_o†•½)«ó³8(K#ŠÖ°,„ŶÕÉRŸe:R|-8vv¬ÒÀ;+ËšN4§dT]“4¿ÿ‚b¯:Ç‹µN?E›v͸R“´׌‹¦Øœ¥!¬Ñ «ÍÙâk…Ãg‹Où‰jAѪ5î×׈¶§hÏAÑ—Eu—² ™¢¢·Ú¶WŸÈ-ø¹¹Ø‹¾n±ª3ú裻¢¢âÇ´X,}ôQ``à„ Þ{lŒŒÚ†ú†ÜuŽÀkTÊõ™…ýhÊv›S> ×ÊR§hו¥öuÇei\Ñ.¾×”ÅAÑ®+r£tsÙ)S¬í(t¶øK4§>7§ŠO…)6ÑçÖÀmΚ¢#2¶†šÄ>S5I}Ok‘š¤Îë®×$N_sÖ$ö]ÇMÑ‘¹‡6Q“Ô§5‰jUÔ$¶wn[5‰ƒ&zcôI®û¹9ûõ9Õ¨5EMâˆÅ^wlÜâ5‰Š!@}Åäl¿«¥j’†Ø&ju"«hÔÁÁ+Ôî4©e^÷ssÐ]©Iš¿!¨¯†oôšÄYÑšÎYÃÛûeRRR0ÆŠ`‚ (»šÙ6Õ h×®F£™={ö¼yóŽ=úÞ{ïqwÛm·õêÕëí·ß.++‹ŠŠZ°`APPÐóÏ?¿wïÞÀÀÀùóçwïÞýÉ'ŸÌÌÌÔjµ¯¿þzDDÄìÙ³/]º”ŸŸÿÉ'Ÿ.\¸°´´´¤¤äûï¿W6rÃ÷íÛwܸqáá቉‰'Nœðòò:tè€zôèñÀœ={vÈ!÷Þ{ïØ±c!„<ϯ\¹rÊ”)Ý»w×ëõsæÌ™:ujAAAÏž=;wî”––V{4ÕÞ8g}±öîÉÿhø§j—¤+ñ*DvP–×e†ªá0%×çºÕ_cM¾9R.×^×eîTñ¹(S¦¨z¡œ³¦Ø¢5EM⸌+Z“Êâzñ5iMÒ("7M¢B–ë^w†ªM×$*Dkôâk¶>É _“´Â>I D¥ïb—²é>·&*>gk×C°›´!¨ïsk=5‰ãªh%5‰êâs%j¦NYlÿ·%lôÎÙšDEÔL³õ»j»)¥hÄ>‰S¢!„L&“››[S,‚¾HÂóüš5kF=jԨѣGoÚ´I‰p±9“BÊAkÙÙÙÞÞÞF£qÞ¼y÷ßÿš5k¦OŸ¾uëÖ.]ºüõ×_»víÊÉÉÙ·oßܹsKJJ–/_îíí½gÏž¹sç~þùç………ÕÕÕ«W¯^µj•ÉdÊÎÎŽŒŒ\¿~ýgŸ}VTT¤dGéÑ£BhÆ [·n4iRvv¶^¯W¼6žžž¥¥¥áááö%qéÒ¥ððpQ•2t:Ý!C~ùå—uëÖY­ÖÔÞGZÅ4¦ê¨W¼¡*Üx*\†Nù\™ënx¬±f¨®;‘┌õM¾]W–&šv¤ø\šqP´F)8§¼×5ÓÔŧ"´JuÔŒ³²4úçÖtÅ×:k’:‹µõ×$*5I=-gƒZCMRc޸Έ†æ¬Iœ-¾¸&Q1×í¸,­¡&©=>¹îüp³Õ$®w)1þ®Ñ'«UÇØ:kŠŽ×$û¹©ˆhý5‰êâkĨ™Ú/ÐâÅç”):R“8\¦º¼o =jÆõ†€ã¸’’’mÛ¶UTT4ÅŠ¶«®I’žxâ ÛÏÇ{Ì~O2„О={>þøãeË–}ñÅwß}·¯¯¯,Ëݺu»téRiiiHHÆxÀ€%%%§NRޤêիט1cÒÒÒJJJ>øàƒ]»v­[·Îßß?&&fÑ¢E»wïîÚµkdd¤Õj]¸parr²íø=E³’$F__ßâââÚË‘öT);ÒQJÍf³Á`(++k%çVÔn‰בÜ"R8(B£ÌP5,ö}ú6$KSèÁñZüµÿšn¤âk…²4JÐG›®Iêì°¶QStöÝÚhMr#™â S“4µ,¬ø˜,¬Åú$®yn*[½ÉŽã öïßO)Ý¿iii£FŒìß,((襗^,\¸Ðßßßæ%Qü Æ 1bÄ‚ •^”ÍVm'BÏóZ­Öl6s'IREEB¨K—.Æ »ÿþû“’’¼¼¼æÎû製óÎ;íÛ·ÿïÿûàƒ?~üûï¿WÎâ8îСCnnnS¦L™ýˆŒŒÜ¶m[mÏ–³…N9#íokÁzÄ©¸PW¦q?5n­á`øîue¬¯øœ*—ÆÚ±Ü)YCÑ@x‚ƒ^§FŒ>uE4Ç—'¨0ÅFùÜœ*>Çמà ,M]“4`-ê–â·¶šÄñâŽ{·¹š8uÒ Åç”):5ÃÜp±uÖ$ ®P‹6W“8Øïj+5‰êõ8e7[MÔ®pÊ[UMâˆÈN™bËÖ$Î_ë¯I¥ßåÔú€†_^ÝDuóà«&qeA“#¹8ò¹µ`Ÿ!”ŸŸŸ””T]]1®¨¨ØµkW£ðö¯(­·Þú矎5 !¤¬²‰íëë› ‚MqV«•RôèQŸ+V >¼}ûöÏ>ûìÔ©SwìØaµZÇŒóÅ_<üðÃÇÏÊÊÊÉÉ9pàÀŒ3ºté²qãÆM›6M˜0¡k×®éééŠx‚ ¬Y³&00ð±ÇKJJêСCttôÊ•+{öìyèС„„„èè芊 BˆÉd*//§”Nœ8qΜ9‰‰‰[¶l˜êvâTaŠÎ6-Þp7, €çyY–íÿÚÊû$ª‹OEŸ¤a销I’š¨·ìÔ×çlc×â5 @£ÑØ´çÊáÙÍÐ'¡”º»»k4šÚííßÇ8qÂÛÛ;""ÂŽa^^^jÎ~{ûëÇÙï>!T"S”ó<¯Ô²,SJyžW–;)?APÞ^–eBˆýO寊äÊ_mÏ·iA’$J©r¤·r›- ›Ÿc,BˆRj»_ÙɘRÛ/£ºxT´mbå^[®Ô9¡ÝÊ¥“eY)ýf§"˜ÚPÁ9µm{âAeYnŠ­­\´IGl¯ÅKÍæt°Ô€ª]÷Û–M6ÃÄu‹ˆVÛêZ¶&q1£†»5 ‹Ü¶J­NY”ÎC˺fkØ škâÚ†M{Íãõhx Óæj¥µµÚp_ÜX›A¸ÞÁæy¾±zøMíh…hµZ‹ÅÒÀÙaFд­J8JÙÀê777³ÙܪêÇ»”-[“PJ CuuuS8Ó].BHPP»»{OáûᅩŒ4h½·äÚú q|ø/¿]V!Ù IDATüÂ7Fƒ}S!Kò­·þk÷î=”’ëŒñh­Ií ¬ç¶ZN‡nkõ½ Ë·$&=zÔb±Ô3Àh[ýãbùÕyÝ ¯VÿþýÏŸ?_^^ÞJŽ#lC`Œ{öì™éRaAÓžÓÚ#¤s§NUUUÙÙÙ~VÅÍÐàÆÄÆBÒÒÒ˜öœíì¹¹¹õèÑ#))‰uöœ×à84$1ñ¯?ÿdÚS$Icƌٺu«‹¾-  €ãÐͦ½Ñ£GÿñÇB[hH’të­·zyyöîÝûúƒS·àA#†I€ÄŒ-[sÜ3Ü”ØqÔ(bûn´H˜}`ŒF‡C(5õ”¹ºª[·n¶Ø¥æl°ËËË}}}oÔ¸ß&E„Y/¼Z­v#´7²,°^ŽZdYæxfxª´‡1×l1Gm XxÁ•`C„„×ñžÕ™¼¾Ûn0Æ@Ä1Ï‚&Ütc³ÆêìaóksUz$Y˜öT÷÷DIЮ۰V£}uÞÌÆŠôom2„EEEm(x !ôÏ?ÿÔçšéׯß7ß|Óð‚¦+ÛÆ Ázþ‡Ÿ/Œš66”ìÞ´Ë{ð­}õØ5#‰"ûºßÕà8,ËcI’ZÄ5£l0Ä\3êÐi5¶áNÁs¦¦½ÒÚ¹ = Óž Úcá®À´çB+ص¹7©ötÚF°pJ’ nÜm¤j£,ÅjCÃ4e?–údq¦´)€PB(!„JjoÒÆÚƒÁ`0Œ§×‹Øx•Á`0ŒÖ/OOžä5ðZg _«A¿61 :`0 ƒÁh5Ôè«Ùïì!,/-I?wº[Ÿ¶= Y_ŽÁ`0Œ–m¹„@ª‹¸íö0 "„º÷1jlB“} Œå»…#¶pÁ`0 £u@)­ª¬PBc(¥c›‚Èdª¦„huz/ïNÝ{Œ•B@Áð-œ ƒÁh DÖªó›~Ú^Ž  bU%Ž2ê_4ÛOž\uÍ¿víÏUUU" =IA¿þýºtéÚü{…0 ƒÁ`0®íÞA«ÅòËŠoû–Ÿ“jµZ¼¼}|ý³ÒÏs/ËR»ö±§“õè7è·u+z HL;sjè¨; î,v†Á`0Œæ‡R¢1D{øQ KÆÌÓ©UÔl˜yûö¾ººzö̶+ݺuï? ?Ó&ƒÁ`0 F+!(4¬[Ÿþå¥ÅQq ¡ÓÉGCÃyAT”–˜ƒBBÞ¥WßÊò2“ÑhððÌ5Ã`0 FK!'h€ÅJô: Ôéâºv+.—k·ËWwž‘eyܸ{ÂÂÂlWÆÞqG×.ÝXÈ ƒÁ`0 F+ãx ‡8„¥Bt)7ÛÓÓ;2&NÐh¯DÇ@Žã)BL[ÎÄ`0 FË!ËoøþÛ¯¿ýåpŽÕ˜±3é<çí¯õ»f!ÞÞÞï-û@ù>sæ,L˜_†Á`0 £µ@¦B€‚±ÅlÒ ³©²¼T-”e(!„/Ã`0 F˲š/ë{<úôÝùée( Ò½ åø D5&N®9¯ !Ô³GÛÇŽ<ùäÓÁ!Á„¦MƒÁ`0Œ‡RŠ8®]t!8(4œx^àCÂ"ÚÇäfe”tìÞ‹R!h4a‘í &Á¡z7Ûh†Á`0Œ–i»å…€/R%j=4D†¼· @Ì˜Ö i½æðlŒqhXØ]wÝýÛ–-=ôÕ*2U2 ƒÁ`´AèØ­—,IÑ ‡KTl<À?0˜( (%ñ»Ë²Ô>.RÊ\3 ƒÁ`´ˆãLE§þØœ%•Uæî¬†VÕcˆ’3_3B‰‰·¬Z½Æ×Ï…Ì0 ƒÁ`´*Á@YÐ@q»Ô^Né5·1 ƒÁh~ ’µ¬D Jìf@„Š4nžžîˆÔB“Æ82**2*ŠM°0 ƒÁ`0 ƒÁ`¨ƒRªq éÖMÀ’Ūüe!ÞÓ ^ëráëLÌ4È`ÜÌ`L …8w¦@ ; „Á`0 ƒÁp û̸áP‹OŸ8R8!ÄrEEUx¡ƒ{Dò×uÍ0Œ›º‰ ´W¸¿.ì8Á™†…ºSm©‡Õ$1ï ƒÁ`0 ƒÑ„ îz¦†›ap¥q‹51!€eœÌ-¯c¸Ä\3 ãÚÚƒÒŽ£Öo0ðnN4.€°^[h°T˜ bZd0 ƒÁ`0°S׳ù̱µ4-%Û B\v1—zÇÅ\Þ¸ÿ*Ì5Ã`0jB0AêDc²5M ãéG)µškK¼!„¶'(KD©“±ëBpymé5§,¹ü´štN7µò…^©ùÕ( ]òé$žãý|BÊ*ŠbÛw?wþhdXG„P—„AJ)€ +÷ BÈß'4;ïLdx§ì¼Óå•EÞ^QáÌ–ª“g÷ܼâ£{¥eïÒa±º¼´ü’ÑXzæÂá öK¹—.ðß%apaIŽ$‹½ºŽÐºâÒ<žLæÊ“g÷ ¼&*¼“—gÀ‘“ ¼†GÇñFSy»Ðhaq.ƲNg‰% ¥T«qEsZæ‰ c±¯WpHPtrêžvaÜôžî¾e…Ù'eYì×_”ÌEÙ„`Ǹ~Ìt ƒÑÊ»¢Å"ñBà&PR#”m×É`0êB(™Ä¼cY±Ã;•fY«,í#Ã`0nDâ2sN‚£":gç‘e@`2WDöèôÿìÝydGzö/3ßY÷]Õgõ1==÷`n`0X`±8â’»\’+J»$MIä†M[¦h…a˲­ eK2išf†",R䊤±ÀX,Ç`p æÀÜWÓ÷YÝUÕÕu½÷2?ÿñº=°`±˜|¿@ôTW½3»/ß÷2¿|øÝ ¯8ns|êjGËfMˆëcF'.·dº³©üµ¡S€¬5ÛË…–J´Å¢ékçӉ¶žÎËÕ’ã6.\ycKïþz}Y*wlò ¢ªÕ+õÆòàõ3-ÙžžüÎÑÉ+•jñ•7»:¶eR™dç¼³}+祒Jy±HÊ2Fõâµ·º;¶!ªzcyjfx¹Zª,/V«å+ƒ'ÂÁXᄅÙá¥åÅK×ÞηoÇr­ÙnÁE[®×¶Bˆˆˆ~O¥T.?{éèôÜu‰²\)Ì/LìÞöp½±\®Þ9óƒm}‡vx¡838rsœú|a"Œg’íšÐ§f†7wRWßi4k­Ù^]3•’‰XK"–;~úùÞü®l:?8z®Ñ¬]<Ù›ß]©•4ÝèÍïº:|ªZ+/Uz»vÏÆÆ&¯ÌÆüî?fͲ‚»·=<:qy¹Ztœ†¡›†n ®5›5OºÑp2JÖj•F³–Iu†Ñ@ ÒhÖ¤K!„»µ…ÎòÙWþ¿KKVs¡l‰œ9ûîÚÝ¸éÆŠB3„Â5.]G ÁTˆ Á5.]É5¨×•!dÃC°­P£Qõ¤S\œWJ6›µñ©«ÛûïOÄZ¾÷ÒŸ1Æü ˆPÓt?f⹎TxÒã+éf8ó¤§3QoVWSÒ *¥ºÚ·÷ùP ¶)¿{düÒƒ~.ŒWªEC·Q!*D`ŒyÒ&¸à\”–æUÀŽCD¥dgûÖ7O~wkßÁîŽíBh÷íø|k¶g©²¨iº¿""JƸRgÜóœ'ùÕp0Ž€JJ¥Ô\a¬%ÓUZš³­@gë–ülii^Ó ÌõÜZ}iµp=éú9zÝ;öí|LJ×õœRynhô\.“·ÍÐäÌ &tƸë5¥”°šOWÊcÀªµ%`ÐhVuÍ”Òõ£c ÅéD,·­ÿþç^ø¿ýAø~WM!4DTJIå! ¦é®Óô“éPONB!wudX³65ãmùÊ/ï:ÿܱÖ'?71ÖhßjQ`BÈߪ azÀ¸ðì©å¹¥]¿xpôøPÛîÎé Ù­­nÝ©ÎWÚöu#¥&„lp UwÇŽg_˜-ŒÇ"I!tÎE0½2x2J°‘ñKˆ€RIÓ°CøÅko麥ë–ByõÚÉþÞýÓƒ¡@¤%Ó}îÒk–tœ†RÒu@ðà ñhv±4%‚HWǶÓç_¶¬`À õõìm4kŒ±rea®0Ñ›ßuúÂË;6ö¤söòkA;Z­•7÷ìµ­P½± %"Ó5#`‡Íj8”èïÝwêìÆ§®ºµ©kw³YgŒUkåщ+›{÷^:ÙÕ¾1~òì‹¶R¨bá”DevO~ç•Á“[z÷Žœ}ûô÷·¹}ó¡­}ß:õ])½¾î=ùö­'ÏýQ¹n#OÎ t¶õ ®<ûÃ¦ÛØÒ»?“ê(,N8ó‚i]¯¹­ïЮ­½}úyHÄr¦h4« ¥DT€àzMÆøôܰ'ÒÒüÖ¾×Ç."¢ã6LÃ9SoV ÓžÆGÎÖUÛ %c¹K×ÞæBëëÞÃóSùxÒUH B!w9ªÙt\D·V.Ö¸–ìæ!M¬R­SQ‘Ÿ8!ĕ˗êµêŽ;üçf?Õ€b¥R‰F£H]œ?Âߎ‹³Cçÿåëÿ6¨Ûþ;nÃukM¡kfØj,Õ éÖÝÖQ¡t¥2AÊʶÈPëR¡Æ8=Å$„lHµú’Rʲ‚þ Aœ‹F³*„î÷øB3 Ûó…ªXš5tKhú©s?úüá¯ÕêÛ 5:çBZ­±Ì„ОôVÈñš€hvµVB³Ì€RªV¯ *ð ݪ՗‚¨ë9®Û´­Ðrµ DšNÃõš€ iºecµúR0sÜ:3t³ÞXfŒYfªµ2¢ÒuÓ4lkžç6ºÐ1 Û“®ã4€ øSzº)„ÞhÖ,Óö÷¥ Ý2ƒˆªZ_â\ØVH)ÙhT9œ Ó°«õ%C7c~ô'`G8çžçÖˈ¨ë¦eUµ¶Ä³Ì€z­^ ¢ÍfMM­éÔ'§0—éò·Ùt†n5ªiëeÔ5C*%¸ð¤Ë7tü ÈvD)O!š†UoT5¡kšN_]BȆ£Æ¡ÿæŸý’¦kŸ{ÆX±XŒÇãå”9皦?~\Ó´Û~zðàÁ§Ÿ~:ŸÏ>|Øó¼Ûž4xÕ+'O`Û¦âé£çf—;úÜ¡Ö@š¡‰ò¡è¶aØ ¢ ¢±ý >„©…¿!÷Š` «ó<ûLº±~DÔ4“sŽˆ'Ͻˆ÷m˜s DѶ‚þäÙá`lu0 @D]3Q;Œ±P0ê/ƒ€Á@5¡ëšˆáPÜß  Áµ]ûGˆ¨tÍZ©“­ÐÚG+[ðgéöcIþù?5M·ÌÀ§°Cë÷…ˆŒ‰H(á¿æB„CÆÚ–ÃÁ˜_íúÊ1ø; ‡âkË0Æý_ýíDe6€m…4M7t+ˆ!àj¹aÀŽ âÚYøL°×`l帹zúAzC!ä·~@63¿xȰM ”’ŠÒB>|}ò^Ë×¹òµ‡ !÷lm· ¹Ý?*%[³=m-}€J*¥nZý†xÞøÏ »¸ÍëõÕì­q‡Õw~2[»MÅþ¾ÿ-¿àûÝmWWPJvul„µ±Hwr7ÒmwJ!„Üí ?_¾a™€Ò{Ÿ!%š!„Bùp* 4[¹ô!„Ïœ~¢@¡BÈ-µC¦5™øS/1P =Á¥&$PªB!„BÞä\R9|0&4]Ür‡„Òõäº` …f!7W†ŒO¿ùKQûNëDGÜðfuòzÛä$rNeH!„BÈû’ÛÛ,œrÜÛâ…ÿøï_töˆa kýñð÷wĬµè …f!·Ô øáº¾0ˆ@ÿ !„Bù`ŒšÍŸ•¿5BºoïƒO+éÏ4 xåÍï¿7¦¦Ð !äŽ1Ƙ@åÝæâòÞ"TL„{¦Òã âÇêpΘ†(WêIÆpDïÃoD¨>Òê€`ˆê†Ç³Œ"cÔnŒëëš›àGHÃnºv¬nYDïÆËІ >Ò^!䮾a§"øìÜCqàšnèù­ Î9ã7Ü8Qh†rg5 §VZœ8“ëÿ*o¥o !„ܳ•kÔ®7SáØÆôuÍh¿öcë~}¿F6cL[˜}6?¬ ¬^jÔãé/®†WØÛ„ÛmX¥xb©x P…ãF’GP97F7ÖÃml~ê¯Â±ƒÍÆd8¶Ÿ1&ldŒ7êcº‘Y.Ÿ´=†Õ 7Lÿtûè‰Rõ™áߦ c"Ùò‹¦ÕŠ7ÄMnZñ–‹ãžS`LZdýa+YýB&2_ZxµEqîy;¼Õ²óëbdt"„²Q fÆP¡"ã&2.Ty±Ô´º ë.g”‚òcîO•‡R:•Â0c Q¡òVï!äÞªô=^¥Ù˜@@¹Ú•ƒJ€µ®+ Q‚ÿß{}Rü.+KÖ*•j"*×´Û#‰#ˆîjí*×v·Uñ_ûÛGT¬Ù_œ}6ÝúËÙθ0ûl½r™1è!z«•°x @áÊ6aõ˜KdVzËÍú8àús‹3Ï*Y G÷ëF½÷V_9G\9G@@€¨\DÙÒõ_ä:3Ûñu#(qxo&ìµóOÇ]ñ·°\:å4gã« pŒ¥÷œDVúãH`¼^îÒj\fõ¯Ch!„lˆÀ ¢ng7u4^ûþ çFçkÍfqââ‹?x£ÙÖ•¶ôõƒÚ¨× !äîP˜×¨ ½óçÊm™Þ#\µòÔäÅ ò¸0º|F0Bî¥ZÏsKóS)½²¦'CÑ}œiJ6'‡ÿMkz"ÝöõK§~>ÛöêÒùdîç 3;1ô¯‚á…™g·îûVyá˜af•jH¯Ší›þ?M«µ¾|YÉÚèÕÿQÓBðÎZõšHâ¡`xçÀùovnþ_gžÏ+·vÿãù‰¿¨U¯´äkaæorÿyyá•plqö»‰ÜÏv —ßü?3®—--¾‘äç„^œyÖ´»–K'‰õ¥ó¹ü7ëÕkŹïBÛ¤¬åò¿1>ð¿¦[ÿcšBwrð_jz\3RáØ¡âü‹†Ý!½¥hâsÚõ¥â›€2žý’’µ…™g¡mžSléþ­ù‰¿ˆ¥«W ³Í ´sZ• Œ5k#‹sßKæ~aêúïç:¿Y¯Ô–/I·œjûe]‹¦ÿÚsKº™‰Ä¨UÒ-¿8=ú߆w1àóÓ-DÐ tÇÓOpas`ܳc&½ŠB'Óþ«Œk‹sß-Ìüm ¸9ÕòKCÿ›Ðâˆ2ÛñkB‹R÷B!w{p†[½‡¾lÅO8ñÒ™ºÇ`Û–‡þζ¼ÉQQh†rg‘^)\DÛò{¾º0vÚo3àát¯n†'/ý Y-Øá =½$„Ü+•ž¨UΛv>™ýRuéœç.ú}F‚‘]†Õ^œû’Ë@o<ýÅ@hk}y ^¹”jýZ(z Q€xúq\­<—Šo…cûS­¿mŸ›ø÷±ÔcšYZ<M~^zK ÓOÑöÅ3?S^|Qrn0ÆMÃÈFâGÂñC…©ÿd‡6Ffqî{‘Äa.þ0+§1é4§º¶þ›âÜóµÊ%T^8þ@$~xêúÿ%UÝiZ[ÿ rnÑ7–BÈh] Z*ÎÕõ¶G~öPDóêŽ iÒñnÌLš!X“8õ¢f Õu1Œ5*³²YÓ [•¤2"„ÜKP9šGÄPì€f¤X½zÍu„áš;0„ùËJ¯¢i1¡…u#‰€ŒkŒ Æcºç¹0`B " AÎMDŒV‹ç–Ë ¯FSxÍMO2®·uÿŽn¤3Ó%0¦3Æ„r›sÀ0îyÏ-2`ŒkŒiŒ %ëš@.‚BVC1&DP2n*Yó3´3õê5ÏZ„‹¢B”þ@!DLnqnúC–„F”Œ1äÜàŒéÀ pakz\ÓcšeLèF¢8÷};´E)‡s[Óãv¨/Óö ¥šLXˆ^,ù(ckÏýQ`Ò-šV‡n¤³ÿ€ó¢ëƒòœÍH"z\XÒ« ®'9797±µë·–˧J…—¤¬ÓוBÈ];ÅÝú̉co^<òå×ëÕéc?øÑ¥ñeà7= Ð !äƒîQ±öFe•>þ”rQ©ze.˜êÄÛkåIêIN¹Çj=¡Gµ!@¯0ùWåkŒkÕ¥³v°ß03ncÖïDƒˆˆ 5#á4gÜæL£>Ê€I¯¦TS©†’5ÃÌzî‚’u§1íW§þzRÓcJÕ—_·݆ÝÂ…Œì­W¯qnãÊ4IÌs‹(eU©f"ýÔÂì3žS%§¯ÿë,2.¤·,Ýe`(´ÐJ×Å•¤-þ^”ÓœQèynIèQTcÕŠ.9·9 À ""g¸Î‚t‹\ØŒ ÿH€ynÑS²†Ê@ÃÌ…¢ûƒÑ}¡è)—kËWZ»§0õ-ÎmÎ-ÓjzÜiNsayÍL^ÿC)k¨šØ¬2`  «PYÁ^éUJ…—fžEå"*+¸©YAD08qÏ++ÙT²êÛ[„- IDAT4¦Óm_çÂtyFCj !„Üå‘Ï]rÌM_ø™‡£µ™%=»cKhf|¬qËĶ4 ‰òþ÷(ˆ¡D¾²\:91ü¯ «3Ó0sŒé\X†‘Ö´˜e÷ÄÒO0fØ¡­õêàÈåj‡¶-¨ëIÎ-Æ´™Ñ?iÉÿ—å…W‚‘]vhK2û•ñ߆‰ìW"‰ÃšžXœý¶ç–Z»GzKšA@+Ð À„æÜTªé4g&~×mÑ´¨iwaiZ$`zäÜæ\(ºo©øF(ºwqöYMO2&Z»{bè_kz$Õú÷=§€ÊT†™æÂšŸüËxú±zuÐ0[­`O³>6|ñ·q=Ù-´p<ýTaꯚñXæñ™±?UªÑÖóO8·šÕá‘Ëÿ4žþb ¼µ^½29ü{¦Ý©)ÆÂÌ·³í¿63ú'¥Â‹±ô‰ì—&ÿ÷jå\ºõëV ;žûÙÑ+ÿèIµ|ÍmÎ9ÍÙéëM=fX- 3ß.-¾jZ¦Õ†H!„ÜÝM @Ãζ…ÎÌËËuÍcìvS©°J•ºƒ’ŸC5æZøãnJI»ÒQœ²äBÈG­DÙ'[‡z’jéϼYŸ^ ì~ðÁ(÷XeqbbÎímKˆÿþš!„Üx)Ð@îpfm¡ßáå O†t}S ’ KF¹f!„BȆm Û£±ì|¢éP”ÄTÐe€F¿Ç¿M¨ô@ç¾ÝšRÒN¤Ãl^£\3„ÂÀTÎCK'5iÝé ¤lmOȆjÒl¦„B!dƒRJ¥{Ó‹c‹(ñÝK4ã°Ÿº›ßë÷V ½ÚèÀ…ùh™û¾pŸ~òÍ‘ü¾ƒ]›SÙSh†r3&™¶2qÆÕ8 r‰ÜS‚zÍB>ëͰÕG ø L!Ä€}¨Í®ï’ÿ“=žOô4?òùBÈÇm #ó$÷¿u¡Ÿ`„È<¤Ç™Ÿ…&¸ÍŲl{ø‰Ž¯ •ùžŽìðØõ±–TŸ Hi€ !„rï5¦Q*© ícnAá<å1`‚‹×cÌ•®'=Ƙ.tþ!ÃÕžò`5êqÓ®‘1ÖôššÐîp³RIOyþÝg\×ô« ãŒ1l®2÷êÕWŸÜþdÄŽø·Ü~e»V«û‚µ_ÁJ]G>ËgõÒØŸ×Œýðy…Ö¶CŸ3AÑ€&Bȇ •:39ìHoSª5Q»˜r—ÕQòÚìµR­”Oæ¦f.V‡æ‡”RÝén[·'ŠM¯©Pu§ºc³Œ±°ÎD2CsC»Úw ÎÆ1C×f¯5½¦³87ylÝëá3ãgötîYn,O–&ÛcíWg¯J%sÑ\6œ=;qVº¥[Oæ/M_Ê'ò'GNö¦{ôYn.ŸŸ8ï)Ï?$ký¹þ¥ÆÒ|eÞS^ÌŽÕœ"ö¤{f–f–Ë Uk¬5jE%ÊBµ ˜(V‹CóCRÉžTÏüòü냯‡¬P6’Õ…>R™_žèþ\ÿxi¼á4jn-l…;Æ/lmÙz}ñzÔŽ .ÛúØ}÷I” ØÂòÂõÂõÍÙÍ×f¯u$:–¦ÊSA#¸)³ ΞãŒ÷çúgÊ3©PÊ2¬Éâ¤&´—¯¼¼)³Ip1¶8ÆÛœÙ\sjçÆÏ}uïWS¡Ôpa¸îÔàÜņÛH‡ÒùTþÔ詪»õª4*©P*`æ*s®tc=P¬·¶lEÄ+³W¤”]©®x ~uæ*ÖšµÍ¹ÍºÐfÖnŠè«Nù´â2ʼn©ÒTÄŽ$‚ C3W¦¯”ëåˆéÍôÎ,Ï,./ºÊ ›áît÷èÂèle6 "v$d†JõROª‡¢3Ÿé¸ 0éÕTxÓ‘Ý­&  D“‰hÔÍß Ê Ay_‚ó˳cSK‹†ÐNO *zbI¹ËZÌsKs×f¯¥B©×^çÀcs•¹°N†’ï\§á6^¾òrÔŽºž;47t~â¼Be ó¥Ë/Õš5Û°ÀÔLS3ßzÃÒ­Zj,Àsgž‹ZÑÙ¥ÙùÊü±cµf­°\)Œœ?ÝôšépúÒÔ¥R½ôÜÙçÂV8` Í`ÀlÝv¤Sª•¶¶nu¤chÆÞüÞˆùÁÅÄìØrsùüäùñÅñËÓ—-ÍzéòK!+4Yš¼^¸~fì "ŒÀ»cï^›»6ÞôšŽç Í=Uª—Ï9;~Ö†ßëçÂä…¨ ™¡Óc§ç+óí‰öˆq¥ÛoïÏõ/Ž_šº”‹æÞ·á6¾sö;œñÉâäÀì@ÄŽœ==Už:9r2jGßx£Ü(/V¯Î^]ª/qàñ`üèµ£å›CoºÒõ”wjäÔdqrfi&Œ—ke;@ù´nªËõò‰‘‰`btattaÔïÜ7²0Òê* U•±…±ËÓ—s‘ÜÛ×ßv<çØÀ±L8sqêâÕ™«†0>¹ñžd£@Tš•ÛÿÀÞMùŽŽÎÎÎÎŽdľ5.Ôk†òÁ¤+s“{Ú{7§[ϣ疄»ÍØâX.šëÏõw¥ºæ*s ˜©™o ¾áIÏ2,…*L´ÆZ ͸:su©±ôÈæG8ã—§/ .¶ä¶(TíñvÆØTiê‰íO”j¥±Å1 šÁM™M‹µEÎù®ç&Î…¬PG¢ãüäùB¥`v©VÚѶ#ˆ÷¤{\éö¤{nC¢\m!cL)5SžÙÞ¶=d…Þz«#ÑÑkíHt„­pK¤¥X-VšC3ºÓÝ×®Í\+×ÊÉPÒ_wå\”gj¦¡‰`"d…4¡ÍWæ3áLOºGãÚÀÜ€©™½™Þ¶XÛ…É u¯Þ—íS¨ÚbmBÎùwÎ|絫¯9Ò¹¿çþ]ÛúØ·N~뇾Q®•ÏŽŸõ;õXºunòܯ?øë#À€­Å†8ã‰`"d†¦. Î"b[¬-hýœ>~w}ÎùÕ™«[[¶ö¦{/M]*×ÊéPº7Ý;_™Ù±¶XÛÙñ³ ·Ñokµf£ÙL8cjæLy&ŸÌŸŸ<Ϙøòî/ǃñöx»Tò…‹/X†Õoß”Þ Ä( 0!äÓi 36¿îíÜûû/þþ¡îCÛZ·!âW÷~µ=Ñ^mVýT,¸."Úº0SÅ©ímÛé\žºÜ•ìò÷¥”òÁ3%„X‰8àʧÈQ‚4¸À \/O–&ßöxÐ >óî3ˆ€k[𤇈Žçø¹Z4®!¾w"þy‚§¼/ïùòÞŽ½¥R ‹ÕbÈ UjÈ ílßùúG•FEãÚù‰ó®çzÂs¥ëŸŽBå*w-MLg¢óÉíOŒ@Í©ÍWæ_¹úʾÎ}!+4[ž­:UÆ™¿¢DÉ9÷»ê(P\¬Nq‚°–€f-Ðÿê•Wè} =Öþ§¯ÿ)0àŒ3`€À€qàþ®ý?!„|*4¦ù×…†Ûh¸ ÁÅpa¸°\øæÃß|îìs~5î×ê°šó˯ ýÖÒÍpÆýŸRÉ›]ž|V¾lT„÷£w´tžš[.{RîëØ4X˜îÏ´]›ÜÕÚuvòzo*„éy&!äS€‰Ž×^çú;× ×ôáŒàåéË®rkNmziZ*‰+Ù¡%Úòîø»¶n7¼†TòäÈÉ}ù}ƒsƒépº'ÕóÖÐ[ˆXiV±îÕýØ„TÒÖmkU§š&ötîyåê+›2›ncgÛN?7Í\e®\/÷¦{/L^èNuïíÜûÂÅjN­Ò¬”ëåM™M}Ù¾7ß\¨.ô¦{Ïñ”‡€®týœ‘~cýÂÔk!36Þôü8EÐ^™¹"•¬;õbµX¬§JS®tsÑÜDqâÝñwÇÆötîšR¨Гž'½3ãg¶·m)ŒÄqìÒÔ%Çu$JCépúìÄÙ¯Ü÷•Óc§l:o ½5SžÙÓ¹g_~ß±Ác–f¥Ãéöxû…É éHzayæ+óåz9hOžbÀlþ¯ã¾®d×+W_i‰¶L'zÒ=;Ûv¾xñE]èžçEíhÝ©ûQ•µ“Jú ?¨¤”ò¤— %‡ç‡‹Õâ\ynª4åüU²Ñì™±3žò ˺ÈB>« b:œV¨Þ{w¾2Ÿ§¥’#°Ü\~gä©ÒTÐ j\ó#Ȏ瘚)¸xçú;£ £Ùpvaya¡º %çwwì¾8yqsnóÅÉ‹ÛZ· µŸÉMÄÿ?ü3*òÇ9/æ=×Íd2ŸÊ” ŽãX–Eˆ€qV.,޾z‚ÆìPØ  ³?Ûn3¶À b1dÙ׃]a1ôj’zÒB~jlÝŽ⌱í­ÛCV¨5ÖÚo\´D[zR=~Zܰ6„Æ aè\ZA?’¢ -ˆzʳt«#Ññ`¼?Û DóÉ|Ċغ Ä ÍèJvùCâxØ ›šÙoØ‘ŽDGÄŽø…̧¼ L…SþŒHÑ@t{ëö lµ*TÙH¶+Õ±"©P*h3áLØ `<Ÿ(N´ÅÚ¢è¦ô¦T(•&R¡T.šk‰µh\ËEs=éžx0Þk±u»#ÑÑoK‡Ó ˜ÿ:l…cvÌÔÌx(Ä‘aÔŽJ”–ne"™¨Õ5݆©›¶n÷¦{sÑ\ÄŠ„­p>™÷S§Cél$ë™êJvå¢9C3âx_¶/fÇò©|È å“yÎxÈ å“y]è¹hÎÔLMhùd>ŸÈGíh<çœoÊl Ûá¶X[ÔŽ†Íp,³t+Je"™L80‰`"ˆ…¬P&œéHtš‘fwµï öD{ÔŽšºÙmÉF³A3hjæÞνñ`üÃÎAN!#$x ¾TGDS3Óá4´'ÚóÉ|2”ÌEs™pÆ6ìþlÈ µD[Òá´¥[©p*bE¤’‰`¢Ò¨Ä±\,燳9ãþ4sa+Ì [aÁ ˜A³ÿá~&>CMgÆX£Ñ°m{0ç|rrÒŸÄðÖOÛÚÚÞ}÷ÝX,ÖÑÑ¡ÔǼÆ*Õ:ýßG~â„W._ª×ª;vìò§Ý+•J4¥‰6?.øè•Á£ÿÓkÁ•Øg V&R}o&T4ú=æ¨4Â#-ú™ú¼CígBÈOµÖòg_ôSÞÀMYcýÙ 9çÃóÃ/_~w¶ï<Ô}hå£ÕpòÚZkS;¯ò'Øö¯)k»óß¿y1\v´2¶VÆR½7ÔˆÁÚÂþº Õ3§Ÿy|Ûã±@ìÖ”ï ?§µŸÐØÊG+€°6ÜÉï<ëyÁ]ëoÞȺY½ýææZé­Í/þÞÈ/ÀµåᦉÉ߯d×—ÒÚAÝ|‚ëÜ´}Bù)ÝJ(Lu§ÇQ­ÔHkµŸ_i¯¯¯Ü$Ê—/½~ŽIB!§¨>'…f!7c€¤ù¡Ö‘r!9%5#„B!*äŠ Å•ÄOv/rcdX?³ÞGö1ó°|Ph†rÓ…¦ŸÕ¶™üNëä,\õvÔ/·N”bË4£6!„BÙ ”RõgÖœ‘J}r­Z¥T2žD¶’Gìn.f³933³¼¼,¥ü°1DÔ4-§R©Û¦k!k¨t!·Ô¡À–™å±;ÍRhšp²Á(4C!„B6&¥”c8u³¡”‚O24Ó0›wiÔjµÑÑÑ@ Íf…a žç•J¥jµÚÞÞNSè~ ÍBnƒ!²¿_IKÉ1 Ð !dCâœÜ™/×Mr ü‰Š>ìÓPÆÙÊlGˆŸhð[Ïwm×gïþüJôu"„lØf0ŒÁ Ía\ÏOªZfÈØ]_S*¥,ËZ›S ×®ëgÓ[{í×µk"™L...–ËeÓ4é ö~(4C!„Rʱk£›ó½ÍØÂ삦kÑDzsnr>Óž1,ãΣ3\ðÅÙ…‰¡ `Ê¥²íYÆ?‘dœóÁ }yM_i 2Îf¦®OcˆކÛzÚuCÿp…ÀY©PŠ%c!„ÜKcz£05ŸíÈ­U›÷<¥T­V‹ÅbËËËóóóˆ˜ËåÚÛÛ]×]XXèéé ‡ÃÁ`ptt´§§gqqÑqœööö––)e&“MÓ]>…f!?æ:ĹÆü™M”¤!„Üc„Œ3pwèâ`¾?Ï…`¨¤âb]©„æ÷åfè÷rG@DÆ*ä‚s!Ê‹%Ã0’Ù¤RʰÌd.iZ&ãleSŒ1`ë7Φ”bœ1ÆÊ åã?z{÷áû¸WÞ½ÌkÉ·úë*T¨Phâ†Y®úð0Ƥ'à(¥P¡býGœ M—O]jën3mSIÅ9gœ¦çuÓȶç”Rº¡ë†.4áªRŠ3¾vðþö•òO¸àžë]}÷òƒO=$=É8gRIÿ !d£^&NÓMæRVÀTRù ýd1R*ÁùZ·…Š1vwÎ xç¡?¿L(J$à8Îý÷ßßl6c]]]õz}÷îÝRJ)eKKK½^O$Œ±f³yèÐ!ÇqüUcœs×u)4C¡BÈGŒËÔêK¯ŸüKÇ­ïÞòD{Ë6 é—!÷%ÕÅwÎ]Ч‡»_ÓµfÝ9ûæ™R¡Ž…÷=ràÜ[gÕz³ÑììË÷íÚüú÷^«-×ç};ûª•ªi™ñt|bxbëÞmGÿö.x£ÞØ÷ð~ëy;ŒÄÂRÊJ©’íÈõß·åÜ[gS-©ÅÙÅñÁ1Ó6÷=ràò©KåB)ßßU^,m?¸óú¥á@(P¯Ö7íèkín„h2ªëz©P<ö½£\ˆ­û¶µt¶~çÿ}6בcÀtS_*.mÛ¿]zòúåaÎy³ÑLæ’£WGû…ÇÇyç¥w<×Ýyÿ®d6ùú÷^KæRcƒ£_þõ¯.-–O¾zÂ0 Æ ¶\»øÎ…þ½[/¼˜ßœç‚Gâ‘TK ƒ±k£ÃûÞòÕ[ölž˜› „ƒ»îßí:îÛ?|Shâ¾#{Ç®lÝ¿]~ùäE)Õ…wΧ[3†e^>uÑu¼žx žIPt†²AÃ矻~y8–ŒmÞ³Ehš¦‹×¾s´RZ EC=460:r庮ëVÐ:ðè¡3¯Ÿž™ÔM£%ß’mÏÍNÌî¼׆ŽÎø…P*•&&& ««ëèÑ£ýýýÍfszzzçΧNŠÅb±XìâÅ‹»wïž™™i4}}}¯¿þzOOçy‘¡Ð !äcáL\»þöæîû[2}“³W¥ø%„ÜK îF­¾8_üêoüâ•ӗݦÃó1=:552ùù¯|KóE×qý"•R¶vµW+ÕξüÑç^Ù~`‡ÓtÞùÑñ§¾ñ3’ú]B6àe¢0S(ÎÿÎ7¾436])–cJa8ÞõÀ®sož­Wë¨0Õ’>ô…ûðWÏ7ëÍùɹŸýϾrêÕž#Ó­™x:¾Ñã2€ˆÑh4ûWÉG}TJ ===®ëàŠT«—l+l[‘¾ü!ƸŸâw5Ñ/U²„MJi˜lÝ·Í XЬ7f ‹3é)¥Phš¦ëJ).Dm¹MD Ý’ñqÁgš¡7ªõh"Ê‹$¢€ˆáxDJ…ˆ±d\¡š˜5–RJhbnb6 ¥ZRŒ±P4¬¤Ò øä‚×–ª cÌi:®ãÖ«õP4¬[¦Ð8"†!8×u]÷“øyaba%U ÐtÁ…ž,/–æ§æ+¥%) Âÿ\œ¦ã6¡iœs;h3BÀ@Ó5Î90XZ\Zœ[\œ]¬-×°kK÷Ñg_Îu´Ô—ëLðÂÔœašéÖŒô¤néÁH0¿¥Û¸ÀüñYˆ(¥¬×ê•REºrûÁÔe†²1[Âà4šP@)ÕÙ—Ïu¶¢ÂF­Qœ+f õZ2ÎLÛDD!¸ô<Ã2¹àÁhȯÏ5]‡Õ ñën´Öl6 …‚뺓““ÕjuiiizzÚó¼ÙÙÙR©Ôh4&''›Íæâââüü¼çy“““ËËË•J…â2wˆzÍBÞb(˜¨ÖJÍfudòlwÇé9ºn;^ÝÐmÇ­iÂà\P9B6(¡iÍFS)8{%Ý–æ‚/Ì"±ÈæÝ[/ 2ÀV¦[B…†i,Î.@aºŽplT IDAT‡¥'ý^3žëZ¶5;1ƒ ‹óÅp,²2c *Tm=í—O]ìÛ¹9•M)…[÷m›ŸššXk­ºŽ«iš”3m™³ožÍu¶M\=s¥¥# +¥¥0‹(O1ÆýM¯TÔ7þDDéyS×'·îÛ&¥òS!¬.€BÓ8cÒó1ñÒßþˆqˆ§ãWÎ\^Ë5³eÏÖó×^ü›œ†ÛÕßÅøJJHÆ*ÕÙ—¿øÎùp< {·õüíŸüµ zü~.80¦¤<ýÚÉ]‡ï»~iش;]›ëÕÆ3ö7š®uo鉦âûÞô»¯ !¶íßa˜†ôYkæúÿ2~–_ð»À´vµ}îվݛgƒç„&Ðÿ(žNñ­kg¯FÑZµvñÄ…-{·^:q1¿9o˜Æþú…`$„J¥ZÒvÐ'"ùÍ]§Žž€ÖLº%ýíÿç™P$¸çÈÞ]ì>úÜ+BˆÝîéÙÖûÖ oBÍЃÑP³Þ¼òm½/?ó’çxG~æsHyÊ!ó2‘È&’¹ä÷ÿü»Ñd´÷–¥År®³åä«'Ž>û çüÜ›gZ»Û[IÁ®éZ,ýÞŸ‡sÞ’oŸš›ŸšÏu¶\xçÜý~÷Ø©‡v>vjÏ‘}¡hhc…”²V«ù×µµŽ0~ä¥Z­ú¿úïûÖ/Fî«TëT ä'Nqåò¥z­ºcÇáO¹­T*Ñh”2N}œók£ð/^¶Ü8C¢âL(”œ ¥$çÂbÂ{ ¿tÊnëT B6Ø‹qæOÀÄW WFçàʨ͵¹‡šõæèµ‘L[v|p,–Šwöu*©ÖÍÐ$pm®%)%Æ9WJ€Ð„”ÒŸ)ÉoÄû“"ùãóýÜ.~ߥœs¨peu!Vfhâ‚KOú«ø•6"ÿ#¿Œ?UçÜïlï'’RúN!¢à0©$g\)Å9WˆŒçïMJåGTÖ>匭üúš€qîwÝQJ .*@ðGHù'Nß4BÈF¡”êÈuL¦WªY!8cèרþl}kwþ ÿMÏõF®\OæRg¯¶v··÷¶û‘}ι_çû5¼íPJ¥âÉòõÿZÓ´»öžÅqœÁÁÁt:­ëúÇÜT¥Rq]·««kii)o”Û4ι¦iÇ×4í¶Ÿ"Jé®ý*Ñ{ï§ò¨|!”VŸ HOÀm36JOjº¦úØÀh8δg=w¥D‰ ×7È”ÛÁµ‡k ¯\±öÚáoÇoâß”6r}koå o\wýGë·°îùÈÚf½u¸þ+ǰn™›Ké†-à õÞZkï+E}* !ž’ëªEuC•~Óe‚1fZæøÀX4Ëvdý:ü<è+©·Ár¢3ÆÊåòZÔþ£ÝM$“Iú"ýXš!„B¹#]ýÝÀÀïÛB¥A!ä&í½í›:Áï]xO@Äx<þ1{ÍÐEóNPh†r»Zø}kg¸u¸âê ѼM„{5. !äÞÇV´â‡oØ~ˆËÛ0“2Æ8çœs?ùÚ‡-J1q‡(4C¹g,`k ð¦ ÐLá6å­ï›!áÙLxºæè”k†B!„lP •p5áêL}‚ó2¥„«oˆ‘R...;vlzzÚ0Œ;lê7›ÍX,väÈ‘l6û™¿;`\ð[Ÿn+yC&6 ÍBn®&LSÛÚœâ½a¥(4‘kN Ïß4ÜTIìÜ)vT¢o¤p6Ä8…f!„BȆ¤” óT}ÒïÃ>¹½DšÑ 1çü7ÞPJ=üðÃÑht%ýüûó;×T*•ÁÁÁãÇ?þøãÁ`ð3ü…bÒ- ]™roü.!è­½Ý1¯%…f!·áÇpo¬tý©CÝT#‚’È"Cä (4C!„B6&D®ûÓÔá'¶…7ʘ¦B¡ðàƒ& žÁvˆº®÷÷÷Ÿ8qÂqœÏth†1TÍÂÌLƒ‹u‡RYÉîÖÕºIJom™µ­ù»€wÊãŒÍ\G’A;ÀØê‚‹3×N~çµÿôÏãßx+|ïSÆçb¦0yâÒœñG</ÿîŽÞ=½ý‡Î—ŽÜ÷¥¤Ìç®lÏæKËŶt‡¡›”â‘r/_„öâÛϵg» ¥ùMíý-©6©äû]V"8«W{¦4MÓu]Ó4MÓü_ŸþùŽŽŽíÛ·@¢_D4 ã3þýaŒ7+מùóJ\gÀe£[Ž<þÈþÍ&JÊ5C!„rÇír.8ãºÐJó DJK‹š¦/UK 8ãŒ3î¸Íh(Î9¯Õ«ÉXjbn4—l[ª–ªõeMh¡@Ä“n4w=§\Y4M{i¹ÄË&[+Õ%C7UÃi®åR­‡w=´ÃØpÓó™Dni¹Œš±PžgŒÅÂÉ€˜Y˜r¼f4çœI¥"Áh©Räœ_¹ÐšîØÜ¹­XYh8õ€LŲ®ç,– ‘`t|v´=Ó¹¸´ày®ë9†a%£©År¡áÔ+Õ¥¶LçBiÞõ6³0µ©c "ŽÏŒô¶o^(Ï-×*š¦g-ùÖ^ÁÅ©‹o‰¢#ÛEßBȽ|k½zЄV^.Z¦ Ç«õe×s·)ÿöÞ;>Žë:ü½ef{G%: A€$Hˆ”HJ"EYÝV‰cG?;²Ÿã$¶Sœü^òüql'ÎósüÉó‹KÊïcù=9ŽlÅ’m¹ÈV±e’¢D± Á¢—]lo3sïy ¹ѸXàùþAbggwçœ{çÜsÏœ{®” *–¬–vÚ]N›+ x‹B}eE«8ã+Gã²>(¥‘HäŸøÄ~ðƒöövÎ9î`8ÒâZýØÇ>.J‰‘î=Îð©TNˆh1T‚ ‚ ÈõüQÊöëz—zêÂÑp,ôÓ×þ;•Iž8{øÒà…X2zøôAC±T€„"£±dôĹ£ñTl`´·o¤çĹ#º¡õw¿{úàé‹'#ñ±ÑÞh"’Ê$4=›Ñ²±d”^Þ®•&ïv†‡ß=}0•Nt\<žH'Æb¡s½ý#='ÎŽÄÇ:/?Ó}êB_t]êèéÑ…žÕ3ÁÈð¹ÞÓRÊÇ_Ó -5„¾wÛ'ξ«*jWOÇ© Çâ©Ø‘ÓoŒ ¾Ó±/šˆô w«Üâs†BºÐ‹¼Å‰TÌ0ô`dØï)ê¾”Φu<}ñd02’ÑÓš®aÊ ‚ 7Ã8@e”##O¾Î(»4p¾oèҫ8HÆ/ôuu\8–Ê$ß8òk KD@ÊPddeG+cn·û3ŸùÌóÏ?ŸH$8çØK¦÷"‡Ëív»Ý.—Ç_²ªÔ•ÈÂÄòœ˜5ƒ ‚ r}„­kÚ~¹ï'ñT̆Ëáq;<ëê[â©h‘¯¤º´îÙ ÿéwÜ!¤uí–T:™Î$BQº¾®Õíô†¢£-s®÷ô–¦mÝ'“™Äúº¿;@=Eæ÷ûJ±ÐX4ôË}?VÕismY·}WÛÞ÷?ßX»Áíô^<öªÓîÖ Í¢ZFûÖÕµÔW®M¦çûΘƸËávÚœÕeõ}ÃÏõžÉh™s=§CÍ#ÑD´¢´zãš-OîK¦Œ²šòºšU«‡ÆÎ÷u¹ìîæú«#’—Wœî>I]S½>‘Š…ãcª¢úÜþž¡‹}×ƢÁ`d”sîqzÝOEIõu·ê@YH)ª_=ô¢¦gCÑ`CUçÊÚÚu6«m,liØ|àøoíVçêêFJhËš¶¿c´ªªŒ±o~ó›/^ü£?ú#¯×kö“ PÊ´äÅ_üt_œ)”B¤f(kÛï²NÊšÁÐ ‚ ‚ Èõ‹jõ{Š:.ó¹‹\v7¥ŒbVx”RB)%ÔüÛawî¹åþÁ`ßË~{ÛÞb_IÿHoVK¯*©ò{‹‡Ç_?òÊ–uÛkš…„PJ(ø=mv9í. À)§bñTLHƒâ°:vo½Ç¢Z)¥Ž¿Î£”Ú­vθ”’R*¥q¹Ô%´½ù¶æú»6ßeãhסþÑž“玆~iðcÌ¢Ú@JF©ÂL¹g\‘RV–Ö¾zè%‹bÝÔ¸µ«§£óâñ†ª¦áÐ`4¾½í®CoHóR%,àÞ%‚ Kn DQÔ겺ÓÝ'%È’@YnòM©¹)¥”0€€9.¬x˜K™~ô£>|ø«_ýjeeå ¥gnÖnŠ}ÕÎ{î1€B(WlÈœ¨%\Є ‚ 2†0¤BHÑTÛüNǯËÇ× "Í ;€H)©ØP¨\ì?Ž…NwŸ°Yí«+צ³©š²ú#gnX½9‘Žw^8Î)[[½>M##‰T,žŒ †ú(eélz$<4<68ˆ$Âoùõûîü`$>OFÝ.oÿho÷àù΋'*K«ÏötvœÛìU ‰‡†Çƒý@À¢ZGÃC_I022zíÝ—bÉ(¥ô‰þøÃ÷ÿáû?Ø;ÜÕ²@$b£È[‡ûFzÎtŸ$„XT‹ÃfÇC~o±×åíÝ—ªš€¡$ $Rñ¬ž*WGÃÃR ì!‚¬l„4¤”B£¥aó¯ßþ¥ßP¹ª ÍÔECèY-30Ú+„¸8pV1ŠÄÃRÊ®žC½CÝY=KɊʦaŒY­Ö#GŽÜu×]o¾ùf*•ZñéByB©¸pâèÑ'Îôô ô÷\:{ºãÒȘ˜¤%ÌšAA™ °¡a³×é³Û WW•Tíi¿§Ä_F¹­õ!ŒŠ’*›ÕÚÖm× =«g t6UQRíuùGÆ}î@}ÅZBÀasV—×sÎÞ’`tÄj±­©^ŠŽ2Ƥ”Y-ãw­­^OFãÉ(xÝþõõ­EÞâÍ·èBßÜxË¥Á‹”’Š’jŸ;`#¯­Y_ä-¹¨XcÉhëÚ-^—ßiwûžb!Œ¡`ßÚšõ›£¥a³ªX4]ó¹u•k!^§1ÖPÙTä-v;<áx¨¾bÛé5„±mÃ.ÝÐ@ÊUÅUï»ó^—ßj±W–$GÃ#;7í‰$Æ,ŠÕau¶­Û–L'„” ÇG}‚¬ÜQ@ʵ5Í.»Ûåp;l.Ë·»ýÞÚŠغþ6 àuù­ªMcçæ» adõ ™Ñ2òrÈ€€™KbHƒ¬¬Œ)e:öz½÷wW]]M)Íf³‡» !„Rèº.Ev »›—®.õ¨ÄÈŽô $X ªœNè šAA™Þ±¹ºr-yK$%¤yõf Mu a”*̪½æ~F^§O‚ÜÐÐ ë*(¡„Òh|lÿñתUE%„T—ÕÖ”×!rUq•¹,¨È[šêZrÏÑÌdx)eÀ[lnÌÚ²¦Í¼$XSÝd.,€µµëÍÌý¹‹}¥ÒåXk®®Ãknãª*–úŠ5äJášòz à´»Í?ˆFuY¡DHár¸7­mRXUëššuæÏ™9üPe«%”ஂ¬ðÐ ÈÚòÕ@À´¨B›Û%Hh¬]/¥ô8½§×ƺºVrue#4¯Þ(%”W™æ¶yõFÐPÕVÌB']×ívû£>úoÿöoªªÞsÏ=RÊL&#fSšþƒZVÓTQdz‰n#ílÙs‹Ÿ¡ê9Ó;–„(×® ÆÐ ‚ ‚ ÈŒ~¹”¹@ W–ð\>ròiæ2ŸÜz{§Ýµ{ë=f\Ætôǹcpå? „ˆ©Ü»ËU]Æ¿;>&×,Y¿ü³ãWû› €w²¯rÍL!wy @˜'\ý ÷XOA›a9ÞŠ‰£\yyÕò›6sÜ[r’­^îqˆÇã_ÿú×KKK{{{ÿú¯ÿzýúõ---—¹FKR BׂÃ}Ãcëœ~‘Ùà॰¬›|2†fAAJ™Uµa$AYX­Öï|ç;ÍÍÍ„'žxâøñã_þò—Ÿ|òIUU± ðx¤ÕU{ËÆÞý/>w@—@_åú[o[cƒ‰I§šAd²=k¤“:WÆ•§Â¦eLRcüš²UÒ º!,„‚Á@ç”aé/AI¦U€ ²,ƒƒXÈz¶’ƒX–n³a»wïöz½ÙlZZZ}ôÑÿøÿøÑ~ô¡}H×uìD×Àxùúw—ŽÅ©Xm6Å*ÒØÁZ3‚Ì0yb³[ü½[3™ì„úñ”P‹UÉfôIuå©B´ '{DÛùTª—âÖo‚ ‚ Èru†¥­x¥îÒ‚î@ w aàËPEàóùrûdsÎüñï}ï{o¿ýöïÿþïcºvžD…>öÛß^JZ¬*%(•--U Ë#23ŠÊë›J¦, dŠíþ(cÉѱ¡B]=Ê´³ ‚ ‚ ²<‘`(^7·_  “Ûè@p{šÐåšR9¾¦Œa>ŸïÀ„l6{­˜7{Î(%TKŽŒAížZlBB(W&ÑÇ‚ SIBæoI)€”%’É á¨@Añ0FÍÝ=ä×€¤ŒšÛ4QJ¥fÉIÆ©W7— ÕA¦€ÉÇ[IÓ¨^yw^~„`(YKšt]O&“>ŸèT˼„ SJÓét2™¼Ù{!Šê+²E³º´ñ™ŠÎahAAd ÷§ì.%7Êj Yº€Œ\J¹»[‰‡´LJ”TÙ!—Nū׹r焇³ŒS«+vMM1Ad*(%ɨ‘I )ÀåWíN~³…¶].×ùóç].ç× ‰D¢§§TU½Ùû—Ñ‘®Ó¿ô»m”µbí†õ«W)×&Î`hAAdz]“G~=Z·Á}þXì¡OÔQJ¥®P„)ôÊv¬@ •%”)€q*pN)£.ç„ (%f-vó¸’1jîvÍzöp¤¢ÁY¿ÑÛy0êO¿ç‰šLÊxýÙþþÃzs"!tÉU­ìôÛá†Í^OÀ"%&Ï ‚\Ç”ÒÃÝéLÒX·Íïö;õ¬¤Œ2F.§P(¥`p)VÎRhoo?zôè;ï¼ãñxò ÍÄb1]×7nÜh·ÛoêeMŒ{›wî]Ï9 ”d’q1Æ(×äÐ`hAAd!]zB¸Ê§vãÙ†ÍÞÚf÷Ï Öoô¼õ³!›ƒ»|ª”ÕÚï-MDõhPÛp[`ÿóƒ»?Xyä·ÁsG¢¾Rky½CˈMwÇÂú…ã1›ƒŸ~;¬Zùíï_uñx¬¸Òfw+gß–Ö8†.¦ª×¹‡»SŒ‘T\ïëJT7¹N ûmòðŸ¯f!íÔ¾±žŽøýX«Xn… 23ŒQΩ¢2C—/ü¯KþqÝàùäÙÃ!@è iU®à@ÚéQo¹¿ôçn{¨ÜîVVFDJJJvíÚ¥iÚ¬‚,ªªÚívJoúôL*ÂŽv §€PBˆ¡§²Âқܵ³i•2n÷ Í ‚ ‚,R’Ê5ήw"U¶‘žtÓ-¾xH{äÏÖýìß.n°œ«ôØ«Á;·Bפjå·½¯<3ÎÞ÷µ™¤‘ŠG\k`à\"Õƒýé;?PÉ8MEõ·'ŒÒÍ{ŠÓIãÔ¾¡I®Ðêu®tBœ;kÛ[¬¥ÅÞWŸ9>üÒˆ»ÈâðªUÖ[,·X9fÍ ‚䤰»•`:2’é=“(ª°y'Òt‹¯vƒûÝ—GÞ÷©Õ¿þ^o°/³ã}«,6¶’²f!v»Ýn·öÙ›JY6Õwz€5ï¸ÃÇ¡$êë5Ö¬ ðkcVšAAY ¤€ŠFWÇ[áîSñЇjeb±s›S±»¸@€¨6Î8 v·Jil÷¿öLy½£eWQQ…m¸;Õ{&¹ý¡²ÑžôŸ •TÚšo Øœ$!6‹bw)H°?ã¨v—k¡ôªÕÎC/_ꌇ‡²«”™•, ¦Ë ‚ÌÖ’“æ3ïDRq£¡ÍsáXÌ]dѳ²¬ÆN)±Ø¸0ÀáQ„„’ËF–„ÒåZ|Rj®Õ*ì³7y‡ª£f×å¾ò"…!¤8à+¯•—JÜ<AAä8h„sê+±5¸ã‘U\e—÷I „P"ŒQC“†&W58ê7zN¼:}0Ü|›ÿõglNîôª¢\ÞõxÕ™·ÃGÜõè*)€P*„´:xQ…í_ o¼³ØåSß}yÄ[bMÅŒ±ÁìýX{à'CpeÂ8¡£3‚ ³1äêZ²)AÑ3$ RÀ…cÑðH¶ùÖÀŸn¨üðË£™¤àœVí..©v$Âúú[”’SûÃcC®Ð–]EÇ^ UXí.¥ó­ðîVV6¹^zª÷?¬%„Ž dšw,6fhòùo\(«svîc;hI•½¨ÂöÊö=øÇµv—‚»h#‚ÌŒ`èÒÈ‚àvr-#\~ÕáQ2)à ©ëYzVêYùæsÛ,ï80æ)²H‰¨¾n›ÿà/†nÿ >¾¸Èò ²²Òb±ÌåK2™ÌMî ˆ&'"Ñx2w2ïpÎOwv¤SÉ––– [Ü/މÇã^¯7¥4‰ø|¾üµGMÇüTk÷v’aÌAdÂÀteçÊ)ÌUERçTŠË/M» òòîL¡ @JB)aŒ¦“ƾvþ‰/®“¤ R¥„)T 0>`nùd~-æ7Sb~W.ÿ%„P" ÀͳA& Á¨òµ Å:%×L®/»ÊW­:eä²@(# ‰yq*%PBÍ2F̓ã~Eøÿ£íÛ S—ìêRMÓÎ;WZZªªjÁ+sø‹Ç㺮×ÕÕÅb1¿ß¿\¦iŒ1EQ<¨(Ê”ïnÛ¶í;ßùNmmíŽ; ØΠÐu&ÊL‹e|¹œA!‚ ‚,,fä…^Y>dh!ŒQ€Ëïæ<~Ê)!„qJ€PF9'”ÒX0{è¥ÑÝW• ç—KưÜÇs_Ë©éæÊʘßCàòvÝ&\ÅåL‚ yÚqB'Yõ«œ^1àì²6-üø2¾\CáRJ)eÁ€›¹â ¥<>ùŸßyÕVUj¹Ãpìxäþ5n«¼r C3‚ ‚ ‹ ÌîdðYîþý*D ¸þ—Àô¡ÐË@A¤øªÆ-»Úé¹:„BcTŽË¤ÁÐ ‚ ó7Õ èì#‚,Œ…"t´®‚ ‹èÙ.¤O»b²@1—O7”s¦(ŒÂxÅ]{ †f™‡‘ËÌÔ¿2Ä`åAAdyO¦Ô­½â5/ûpFWWW6›Ý¸q#ö˜™:55Ï¿ÂÐ ‚ ó@Ö®žjX>SÓ7ÜÊC… ‚ ‚ Ë)%­Yuq`ƒráB3Rʲ"/læDY®ç”Òt:ÝÙÙ)„(///++ÃÄ™ÉH«¯þ¶mm,”r¹m A '¸y6‚ bš p)7¸bäjž!‚ ‚ È2CJÆW 2‡Ú·×wž¥dÜXÖËšcÇO§Ó”ÒS§Nùý~‹Å‚Ñ™)¦IZúâñƒ=é®»åŽfåð¡þšM›*½—€áÃmAAåá3Æ¥“·ºà\¹ö4ŽêBY¤©7¥ŒsJ)”9N»zðÊi+Fp)åúõ륔°fÍ,73u÷ TËŒ˜×¢" IDAT'KvîÙb \Ї×9¾O›Ô04ƒ ‚ ²TüûÜ¿æk3cúýNëí:-t=aŒ]y‡‚”^ø±ùAΕK§O]8y£3‚ ókœs‘qJ)ÉYgJ3©dÇÁ}éD|¤§ûrŒÆ´ÛŒ^8Û®Ë|¡g2§¼‘ŒE—{t†RÊ97‡!ÇRJ—Ë¥( cÌ| ûL D±ø+Š-°ªÌ.Áâ­ª.¥ZRLZ+‡ šAAnËŠ†Æo¼ZÝÔìõŸë*©ªéé¶ØíUkן9t ”€”U5ËÑPJ ÃP,-“±9œ`±Ú–ûPzè¡cÇŽ9ÎæææL&óÔSO1Æ|ðÁŠŠŠááá£GîܹÓn·kš&—ùê­yR–M ?=PÞÚìå’PBô˜3T®LH ÂÐ ‚ ‚ ÈGQU—×?t©ÛæprE‰GÆÊjë´LZµÚƆ)cŒ1EUãÙTš[ÔÁ‹çk×µ„‡ËjW ]W-Öl: ƒý½¾²rÔ'‚ ÈüÄ#¤,*¯è=w¦fÝ·/pà?zø“yþØaw (6Ôµl&• Œ3-“ѵl&™LÅ#\á›Íj³K!Š+ªúÏu¹|þÐàÀr׆®ë”ÒíÛ·K)S©”a¹ãét:¼÷½ïÅb™L{ÎåþR±—ߺ˨,¦RJAÔ5iÒãór)qA‚ ‚ ÈRóÞÀætm¾s/Sxæ-B×}%åÕMÎ~ÛST¢eÒ”—/`sººO7¢Y—ÏöÈ;ÞâÒâʪŠÐÕj­n\ßùö>_i™¯¸”`9‚ ÈüÙç¶Ýïñ[lö¦­Ûo嚦‹'yEÍÛw…úŠVUÊ*Â¥CƒÎ9ÜîáKÝ׺[wÞ) !A®»elj7_M'âµë7(ªeh#‹B8烃ƒfà‘‘‘ââbMÓ²ÙìJÚ |^¦(néÙÿò[ý#Q‹ÇWZ³¾­e-,Œ ‚ ²$]O È{ë.²zí:B¨0ôÕ­›)¡@ whÛýžÓ‡H!š·ïÂ)×mÛ!…¨Û°±¾e“y¦‘#‚Ì£}nÙq‡i]·ÜuŸ¡ë¾’²­{ïËgs)Ó¦;÷¦“‰SûßhØÔ([%„Ƚ{˽™…W@ÊP%·‰x,Ji<7kÍ`\f’®˜ž:~äbѦf#ÙYÜÖ"/=ÕåÚ¾©’Ã5#5†fAA–Š÷B+ !RLQ5ÆÐµª5M@ˆ¡k—}}!¦;A™;9+„ABLŒ€ ÃPTKSûv«Ínèú„·VžN„­­­ÃÃÑHdÆ Š¢àS)1Œ˜æ¨i^Wîè.©Yã·¥]ÓI•B.hBAY®˜KŸÈ¸‚ ²`Œ9=Þ›Ç8@{{ûØØ˜×ëøx`J¢Z¼ŽÌùKƒÕ„d{O¼}âboiË]6‚ šÅ¾[áFÙ¦øÓ+¤ÙòÖ%Dh†¡éFZÓc7ïxL)v;ÔjoYj£…kÁÊ6b&þ£ö Q!”R‰ºCí-RJÍ0Òš.¤ dŠå9ŒQ)aî¿’Õ €¥;g¡”^÷¤”'ÿ¸ÌåLÏ›jšRµ—mݽ]£¥¶´k$Ó°ýîÆj?5 Í ‹Õ ±¨»Ý¾ÈTJ©”2™L:Ì©+LÑhtVÚ£”ú¾wc{¶A¤3™)ǰ›Ducá1¿Ï½¨0íE"·Û}3‡ö梽X,æpØ® £]€ö≸ÕbµXTœ§YH&S\á6«µW€öÒé !Än·¡ö ˜ÖÆ Ÿ×‹QÕÂüôp$ðûQ{Ó…<.g"•žR?”ÒP(TTT4Gí€Ífu:Œ±%šaŒqί+H>תª:ŽD"±\¦iæöçsÿC‹ ŽjŒ1{QC…äèà,-ññkõ†¡dᬱX-Ë (Bn£²Z­Ø›¡ÙjÏf³m_׊ªXUQz(Œ‘ááÒ²2ÔCa„‚Á@ @1°U‘pØår)ªŠª(€x,f±X¬6ª¢RÉ$!Äát¢* `td¤¤´õPCƒå«Ðc)þ¾Þʪê›ARÎùuC3ù£ªªÝn_^Ó´t:=×(¥R¦Gú’”SBÁˆ¦vî-+½¶Ò †fÂŒžÞ¨`(>@n.²›ö„óèÜlÚÓ ã†DÃWŒö04S°ö¨aേNKª3 }%ÖU]4WY7Ðc)œ›G{ók nRsR±–Ýrg‰¹„•ê?ßM (fׯft‚W“W’ÀµašÕ&y‡ü«PÆÜng7fa ¥·mCeiÁðÎEí¡öP{¨=$p^t•ñ¶]v’.ÇŽ7LAfãѤ¼¼ã8Äcñd†B,vh¡Mû%W6j§äš?f~yõ8½\ÕÌüã껹ã×~™¥@ÇiüòËËo^m˜ ǯ¼4ÿ˜ö´kO[ªª²‚’H$æ[>0ïñ¿~åâiî!D2™4“w¦<-w|üË ÇoÎÈ®)x"‘X¦âvÙs1»¹_4ëÅb1´C…5a±XlqjÍL° 3¼œá´é Ñ”/Z{º®Çãñ›íqËxË?ùåuOËý¡iZ"‘Èf³s7&7á›Édt]ׯÝ&öæés±$„L&C1³åóù8v¹RJ]×#‘Hj™Î œÎDäiI¦;mi*Ð0Œp8Œª0»'¥œ_íw&§¼å¯kaò_ÈË¥I€®ë3¬¹šESJ- cLJ©i!DQEQÌ_7+ËZ,JiΗ2/2÷.¥TQƘ¦ióÕöË¥ÍÖ=]Ž¢Í< !B¡Ð„‰Óòòð¦saÖ'¥ ƒ‹#ÚÐÎcŸÌý ¯;^.Ç8×Ìcÿ|ÉhÞ¶ j–—W×ÊÿdÆX&“¹±¢M7ô,ý‘”1fFóç8ô,kW!Ÿi產qÎ`It,` }£ZÍ §†Ãá¼ ™Ÿ0‘eaÌG– -‹ÅÒßß¿¬¼èÙl¶¾¾¾)-X1îYÅ%o¬«–,Ó‰–ûÃétööö^7P²˜¢Ív‘g4GÓ´L&3<<<—'gRʪª*sË‚žž¿ßßÓÓs]‡aîOËfëÄNyåååå>Ÿon$¹½¬ýöÛ£ÁáÁ±˜bT54”8™ÇM%¥pλ»»?ö±©ªªëz{{û_üÅ_TVVæª1›Š0eËý{I®$/MxI®<%È]Cn\§”¦ÓéÏ}îs‡Ú°aÃW¿úUBÈüãoûÛ%%%_úÒ—*++EyòÉ';;;ÿþïÿÞ Áôõõýíßþí'?ùÉ;w !4MûÞ÷¾wòäÉø‡°X,“õ^@W6ã…ù[ÕÅs¿;¥,úâøÓ®+Úb†®;³šY–ñ/'Ÿ¿”CS^óÌÇÇ_mžÍ—hóž¾8s»Le²hK³+NPWîJ&Ë2Á˜mW¼AÆ)o« ²Ì,ãB7_}u¶÷KaVq‘Eß N–ëº> Ôd3»×syÊaeJÑ&\ü”²&à"tÅ)'·Ó]ö”"Ï ï ^û¢uÅëŠ6ƒÈsiµ¹7_nÔÈGä<݃…»Ý®ùò‘eÂ˦‹ dIò±0ù‹¶–ÄÔÞ„ã¹äˆ Í7a¦0þ´Y9® g™¹]Ì«Í]ót²äN›yB‘{9þ„ù½éHÞÉþ®y:Y¦m:#9þ¥™'±zõê¹³3·Í}!· qsÍdŸN–)›µ°1nÁæD”I2Òñ›×Ïd^'7Ο8sqÇ]{×ø©˜¡ ðä T®Ûe2™={ö|þóŸ·Z­O>ùä×¾öµ/|á étZ¡ªªÇã …Bš¦9¿ßÏ‹D"ÑhÔjµ«Õ “ɤªª%%%Œ±P(”N§)¥¥¥¥Œ±±±±l6Ë+//7Ýb±üË¿üËêÕ«¿úÕ¯~ñ‹_üú׿~ï½÷¾òÊ+?øÁ:;;?ûÙÏ~÷»ß}òÉ'“Éä¹sçÌ‹×4íOÿôOëêêâñ8¥TñüóÏÿö·¿µZ­Ó¹Å³ÕfoòÏnXè9جl}Á“¨yñœæ%x1]óM©¹ ½³j¾ËLxY˜çD®—b}Ý9ØBôÌé~}q¦Ðó+Z–dAß…¸Ýf9O«8åE.)Krc›oé[’¹Gs–Ž%™Ç±o‡ï|D^Á–d1£9‹iIòì{sÔávËó1ØBÁ’,š{¼˜–äF…õçëyز$S>–[|—rî},KÇUU‹hÓEQgu»üàöÆ>ߥ”f—N =ø‘{+,‚:ýæ±Ó]•;Ö[A”¡EQ~ö³Ÿe2óâ\.×ý÷ßoîãm^«"“ÉH)ï¿ÿþW_}µ««ëË_þr]]Ýý÷߯ªêÏþó’’’žžžO}êS•••ŸÿüçËˡ‡‡~øá7~æ3ŸY¿~}OOÏ>ð–––ÏþóMMM?þxuuõ·¾õ­ÚÚÚcÇŽ}úÓŸÞ¸q£B×õGy¤¤¤Š‹‹‰Ä¥K—vïÞíóùÚÚÚt]?{öìÃ?~þóŸçâJßþö·üãç4{ÿý÷¯Y³æ©§žºî³Ž™_ÎýY÷x'{Â3¿œ{îÌ ²L)Za]9OY&Ÿ£h³*1Pð XXóÍWêS>"OȚɧù&LüfÕ|ó%Ú¬n·ÙZÕÙvźÝf8mî>ÍÒ´$ó2(.K2åñlIægYKR@…ˆYYÅüE›÷æ›—º9ËÂ’ä/Ka^ø’òIòi¯r)ç}àοÇNn¾9ÞnSŠ6÷܄¬eaO1o¸%™YcËÂ’&rÁ \3È2^%2ƒ›í££ÙºÇó˜ô4—æ[KBe eÜ"2ñX<ãµ2#1L3µt²6•ñ¡¬ÁÁÁÏ}îsæËú§š }EQl6›Åb9|ø°ßï/))I§ÓŸþô§ý~ÿ?þã?~à¸í¶Û¾ÿýïøÁnذ!2íeee<òH"‘xùå—­Vkî¸"·¨lrØ2ÿ)k>+Æ'_ú šfm‘g% ™M*æ‚&çÙ|ËbAÓ¬º"™[ò0YôM4ß<.hʧùæýv›­%Yˆ®8¿¢å)òr\д¤,ɼßn gIASwßòZÐT@ó­`KB–ü‚¦‚›oY,h*¸ùgÂÂMgy¹,h* µ  ÆtÙH>eSbAÓ„^±d]J2çMù\öø¤ÅùyÞ- Yô£”êCG¬e¥‡£¶mG…`6•KMµ‘Èà@_‘§ÞF®ùá«‹¾¤”~¿ÿ+_ù !äßø†y1…Ã0>ñ‰O<ýôÓÏ=÷Ü~ðƒÖÖV3>"„°Z­V«Õ,366æv»W­ZÕ××§(J(:wîœ×ëýƒ?øƒ§Ÿ~ú‡?üáÅ‹ !þð‡_xá…={öüùŸÿ¹Ûíþ³?û³_ýêWUUU_úҗ̽©EyöÙgGFFÚÚÚ~ï÷~ï§?ýéš5kFGG¥”™L&‹UVVRJ9çŒ1ó_󥉢(f‘¡ñ'Lé®å$y$ãåÓ-¦<Ì&}qîyŒüÊt¢åsœ,nÎX>²L×Êו%OÑ®«Øy-Ïæ›UWœUöé¼§hæÿ+ùË2¹ùÈXÐ4Ûæ›mWœ{óÍ×í¶pÍ7Û{|q,ɼ4YÜe³’åºí•È+À’L÷ˆ¢°N2GÑfÛ|+̶ؒ+Îì“,KB¦_Ðt]‘gû+ q»åéR®0K2h³½Ý–”%¼0KrC–,‚%™nW Ó,qš¯ž9[K’gW,Ì’Ì c,N÷÷÷§R©ÊrÏêvËGäœó…ʘ¡2<ÐñîéT&«eÒážc/>ûäÿúÏzÁWVVj%Óg͘šÝ¼yóÇ?þñ¶¶¶ÉO-²Ù¬¹>HJiJžH$ÌZ0Û¶mûõ¯‡Ÿ}öÙǼ¦¦æg?ûÙ‹/¾xèСšššÇ{ì‹_übccã©S§l6[SSÓý×=þøãápxÛ¶m¯¿þúî¹ç]×›››sŽÔÐÐÐ7¿ùÍÇ{ì‡?üáûÞ÷¾úúúgžyæùçŸ?yòä=÷ÜS^^~òäÉH$ÒÓÓóæ›o®]»VUÕS§N9s&™Lz<ž-[¶œ8qâðáÃÝÝÝû÷ﯫ««­­°³ãb–ž!,=¿ÐÞ2ÀSŠv]‘çåYwže€É|”X¸´‹éD¸±e€¿š Y˜2À Ý|‹YGvÑ,I]‘,LàkI ³–7%ÉÿiÛR¶$ßV7Ü’ü¬{¹X’EèŠ7Ö’LNïšY³Øê┞Rä…,Là%eIÈÜÊ/²%YL—rfY&lÌ´LËÏKW4드8q¢§§§¢¢bãÆ¥¥¥³zV½˜e€h ˜!î$ÀÞÔÚš|çÈ+/ õœãe›nÝù‘ÇÖ{¡ë†”ÿÕ_ýÕøQÁáp´µµùýþ &ÏÜ>©¢¢b¼¾êêêêëëcÕÕÕ†aƒÁ]»vµµµµk×vww¯^½úöÛo¯©©1óh<Ïí·ß^WWg³Ù†‡‡Ýn÷£>ZUU%¥)++{àÌ`›”²¥¥EUÕ`0ØÔÔôÞ÷¾×ãñÔ××WWW?ôÐC”Ò³gÏöõõÝ{qH¤¸¸˜rúô醆ŸÏ‡Ož<É9ߺuk<w»Ýååå󛳺Û.2ù{„ ‘M:¿H)'nó‘eü»Ë®áækÛBJédí-‘>yÝ®xÃ[-ÿ„…ÍU–Sú.+ÃHζ+.¦%™û]W–)O[¾­6e|j9öÉnIH]v®ÍÇ’,G+·ÿëÊv)'7Óܫп¶õ]²Þòo#EQ ØÒú­0Ÿd¶–äº2€ªª¹ÒKß[.¬ùÌÓÌ€¼^ïä©aÝÝÝo¿ýv8VUÕÜ·‡sîñx8ç“¿MÓ´T*e³Ùl6›®ëù\Æ"X’ëö—Ëe³Ùúúú¦œQJ+++9âóùª««'Y$ VOmC}‰Çá-YUê±ñÐÀÐH"KT›ÝªNüB:000ù&äö˜ÒrÎ…ã£Vœs³Sš›3:3³Æ\CæGrKŠr/Íï4?n¾ÌœûÑ Çc¾$§ !¹vƒtÃ0ÌeMæKóÂ&ÏV+X´Y hvl¸Â˜_íÝT}réDµ–cÛ-fÌw…uËy¬uusöÉ¥ ½eÚv¦{fZ¿én^tºf §= .ä9Á[Ž}²°]¨òͬG±ŒºÖâ?˜a{2»ÝžN§§{wé‹–?Ùl6×ÔÔL95 ”ƒÁ_|QUU]×ï»ï¾¢¢¢)e¡”&‰`0èõz½^o2™\R¾éô¥¥¥^¯wß¾}“ãMfã¶ÛnûÎw¾S[[»cÇŽiv”2ÊhéD<‘ ôœ=;àªoݺ±Á6aóìuON);!tú—SŸ¡/%ÑÉlQB »­ þàRöt5MËÝó7•_˜§}Ÿá4Ƙ¦i7|´(`©ËÌ2æyÚ\.Øtg%ÚÌÉË= ¸â"¡”B !WÚ—€P²èmxùb1oÃËÀe“3á8¢(ŠÆeƒ4½,D†Ñ5g–e¢ÈSªâŠ,3œ6+ÑTE1Æ=Þ(p¾®,y‰<Í·]ùø¢›”™.ÆlEQ¥àªq}Y¦=í†8.fŠ‹¼ö´¿Ó(eñXLÃëõ.¾…ReÆ GŽ™2º‰ÌŒ”²½½ýwÞAíÍ!ÄÖ­[;6_}žRÚ78O$n†M…!n»íÖãÇg2‚{|ξïµoÝrþüÅh,z{KþŽïÓžlmmeØ÷f«=)×55&“©¾¾þ\$yɸ4³:í\¼”²¾¾ŽRzáÂÆpÌ]ôÇa·oذáàÁƒœ+¨Ùêq~ë¶m¯¿ù¦bj-ßµS ËUVRÌ9›nÌݶm[GGÇÍà*g³Y¯×;CRäÐТ¢”Æb±âfŠMooïÎ;;;;—…ö Ãðx<3h€ÌêQÚ•28eÖ ¥4K)ëëëÃáðòÒÞÌ—ªªêSO=5ウ|É+÷Af ç\CaÆ Í˜õ†0¸P˜FíÍQuów1É)½Ižä[TôQ{7†ó“9içÆsÐ&¨>èÎð΋öTTÃÔÞ¥Ò0Œéœá›ÊU6 cÊD³,¬Åb‰Åb¹Z¼ñxœ1¦(Š˜f…µ97\^ÚËU³]Т!‚ ‚ à’ A•¥tttôàÁƒfí˜\hFJùÃþs¾}ûö’’|Ê;[&î.<Ô‚ ‚ 2µÎ.CéåÉ•%™Œ1ÆxßÅó½Ï›k.æãGAd!€ªªªööö »î@6›moo¯ªªÂ¸L\Íš¡”¦R©‰o+ŠÅbAÍ"‚ ‚ Â5-kèºÛëKÄ¢N·'P\FÆBŠ¢®ª®ñŠÈXp4I).wqiÙÒÜ.AɇL&SSS³iӦÇç úJ)·lÙRSS“ÉdPEp54£ª–o~ãÿ_ÈíÑÇ~g×®]óX:AAYPJ Ý8sâhYeU"ë½x¾fuÃÙŽ[ Ò-¤ IDATo»}°¯Ç(èéVT5:6&A àŒŠKO~ûŽ÷<ˆË›A–5𦵶¶rÎ…«V­jmmÕ4 •SWC3²­mË£¼/wäÎ;wú/þk ‚ ‚ SbµÛKÊ+Ü>ÿ¥³§+jêû/u !¬V{ç±w£á1—ÇË#@$£åÕE¥e§Ö´¬uš­OAe躾wïÞgžyFÓ4‹Å²wï^]×ѶÌÕÃ0î¼óÎz(wäñ}hõêÕšAAA¦v%¯d[3®¡ÞyóÕ{ùÀÆö[s•e(¡„’Ë'tÜA–=RJxøá‡}>ßÃ? :˜Óxšû ¬6Û'?õ'æË––Ö÷ÿÎû'”öAAAœÿhn’ R !€°Úì½ÏG†G‡ aH)MžbFfAVB‹ÅòðÃ[,!*d.LÜ<»µ¥õ‰'>òÝï>õù—¯C3‚ ‚ Èd@Q- MͧËj³­Y·qÞ´a“Åf»u÷ݺ¦­Y¿!“N¹\ʘ”ÒîpPJ7¶ßª¨*f¼#‚¬ ¤”X_f^P&¨µ´¬lïÝwÿè'?~è½ïÓu„ ‚ ‚L 缨´ÌüÛátÈ’ò YQ]KB(!ã£0P^U ˜ñŽ ‚ ×Â&¼–RîÝ{÷o_}ÍápàR1AAdà*’bþ{yÓ•uL9!—AYFPJ5MË+\ˆ“'4I)}~ ¨—Š!‚ ‚ ‚ ÈM X­Ö¹¬BµZ­¨Æ|P¦Ô>ÆeA–’Á›Ã“ AA$O#°Ö5PJs›ñ*4T‚ ÈÒ©ãöÐ@Z±¨¨ AA…ÆÈjõínÛÜòDVŒ±þþþ¹„f¤”uuu¨Éë‚¡A¥‹ƒrGÊPCU ‚ ‚,4FF8˜Â8ÃÂX&Bˆõë×ÏeM¥tll 5y]04ƒ ²t @)àz&A–*”RF©(hÃ(“€“A–’ëE Ì—¹ÆÈG"E™SÜ`Žë¡nPG‚ ‚ HA~$¥±tòð¥NC|üDÿYÔ!‚ È҇ΠT`^C*ªAA™Ù)WW¹ÂÏý­p%žIë=óÜ¡W4aLp¾e WÎU®˜ç›ºÊ•Ü÷”¸ýãOC÷A¹iÁM‚ ‚ È´PJSÙÌ›gw ]ÚZ×Ü^·á7]ïv \h©ZsgSûöÕ­#±± 5eƒý‡»;cš¡»ü}á¡7Ýá²:þ¿ƒ¿4¤ØTݸµ¶yßÙ£Ûë[]ê$’Ùô­·ûœn,½‰ ²d‡ƒüMô¬NFfÍ ‚ ‚ 3¹×„^ úžÿyïi-Óì·(–ÿyï†0¤”‹M•íbÃcw½¿ý=ýá‘Í5«›†¢¡”–Ù\³î½›ïì¸5´h:!¤ÌêÙ7ÞÑT^×9xQtMA–äX@i"‘Bäyr$Á\ÈYã‚ ‚ 2 ¤a·X )î߸‹b·X…÷o¼s>Ý#Q ÄçpSBÝ6‡Ëê „)™Ô¹áž #}ÉlŠjÆtŠœ^BÀ¦Z°$0‚ ÈÒ 0vüøñx<žOÀ…RúꫯrÎQo³Ð0ªAA™ÁÇV¸’Ö2 cûÎ Óz†1¶ÿìQ]*Wc*WøÔ /WÓÙ9£G{ά¯XÝZµVa ctü ˜öŽ ²Äáœçâ2Œ±É1šñ;1ÍqS§5ˆ2ÅfŸŒMa×(õ… ‚ ‚L ¨ð•t\øç¿ÛPZÓ\ÑpvèÒÿýâw««ËkŸ~ë…×:Ïôí]¿mKíz’B)• )€”– †`}Eý÷þò–ú]o_8i!¤Ô…„)ôüòäA 缿¿ßív»\®\A8{ölSS“a¨¢”)ñáŸ?p×ߥË<ŒÛ}n5é„S½èoôí{І¼¬@ Í ‚ ‚ Ó»ëý·ÜC ò‘­wQB€ònôãwaH±­~ƒyü‹ü I €=ënR®)«R¶Õ®#„ ‰ÑA% clxxxÿþý{öìáœKy%"/å[o½E)mhhÀ*3WÇP)\%w?·§ÁU>öò?üÒW~ùÃfqöŸÿúKQMŒW†fAA=KC\} jŒKoÑ…a:å¡Dôdÿ9Î!„ÚPZUå/Ë ®H åœÓ+%«$ȶ¬¦”RB%L sÆe¦ï.¤€ÙÌp(¥æg)¡†4¦“ÚÌmâty"„3>Ý!‚ “¢ WöÚBUU³˜íøœN§®ë¨¨kFÆ“£ÿ÷ÿíƒ.§” R‰TÙçžþÚîâ«kš04ƒ ‚ ²L<<3$Bgüß_û÷íücÌ ²H¹w€ùT“z9Š„PŒ²Œžyåø+ƒ6Õ–5²ïi~ÏæêÍÌÝOs¼æK®|ƒù+±L,šŠVU›GL—]‚­§ûÂ}íµí#s´÷hKEËó>ºó£‡º™Q†þHÿ£›ˆøþ®á®öÚvr%+ÄÌ[é릣•¾ÊÈ@]Q]çPg©»4œ o®Þ|àü€3MGו¯{¹óå?¾ã‡£ÃB2Z&žÄFÎŽœ 8]Ã]w6ÞIF6Vo´©6)宵»$ÈW:^ñÚ½ñl¼ÜSî´:yâ—·6ÜÚ9й¦lÍhl´*P%¤¸º´¦tMÇ@ÇöÕÛ/Œ^(õ”2ƆbCÇûŽ—{Ê÷ŸßGã?=úÓúâúO g<ž‰¿ÜùòÚ²µi- =Ó^×î±y^îx¹µ²µ?Üïsø"»Öìz·ç]§ÕLo©½e86,AŽ%ÇVùVeôL4MjÉO½¸½~ûé¡Ó~‡¿?Ü¿wýÞßœþM¹·t¡ïiÚƒ½AäJ€†ÃáüC-—¹¬7Æ2¡SOÿëOª?òÁ[Gž[ÿ‘ßÓßþÉ3/z>ù»›-òš-W±<‚ ‚ È2@‚<|éðÝëᆱé.3á…Qfá–X&–ʦÎÏsÆ×–®ÝV¿MáÊPt(ž‰o«ß¶­n»‹7¬Ú@ ½}íí W$ÈN¼ðÜáç~rô'=¡ž­µ[G㣃Ûê·]^Œ Ž&F»†ºº†ºF£»›vß¾öv¿Ã¯rÕôÎ-ÜRä*ª/®çŒí=:‰t tÒàŒ›qÆX"“Œî\³³µ²u0:˜Ñ3¥žÒ-5[Š\EµEµ[ë¶öŒõ(Li®hÞ¾z;!d(:dQ,”P!ÅÅàÅK¡K£‰Ñ³Ãg‡¢C¥îÒöºv+·š«®ìª½µ¢uKÍ–¬‘-q—Œ%ÇFâ#E΢T6ÕXÖ¸£a‡Ûî>pá!dGÃŽ½ëöz^UQ#éH8ަ£~‡Cå»jW™:h*kÚѰÃesõGú9ã«6n¬ÚhfßäÖ@!‚ ³ µ`\&rÉfÎkîzÿCwÔoÜýàûkÏ„.&åÄP fÍ ‚ ‚,·˜PF™ÓêT¸B)MjÉSƒ§ö4íéqõ„’!ó] Ò¬nË£”:mN³ c 8ãºÐew6ÞYä*‹bጠ)b™˜UµfŒÌε;ëŠêv7î&‚]#]@Àc÷h†v¹ ¥¹:,ä¦êM·¯¹}×Ú] SŽõKf“„Îx,Š©\Œ2)¥Â¦ÚU¹â1sv8åˆÂ]è¦+/AJíµíÍÍ;vÆ2±þH?£ìreÅ"‰$„@¥¿òXï1ÝÐ[«Z"æ/Z¸%¨'øþ¡Èйás{ÖíŽ ņȕò4@@©pÅüˆ©4F™.u³°v9AdN€´:êœ]ß}ûäv°¤Þ~á©g~øÒºÿñ/›XI³fAA–œñ*Õ™¡3Î8ÙRº;Ð…Þ馣š¡™Á ]èvÕÎ(ˆ ¹tĪXÙÄPtˆrnäœ%Id‰L"ž‰§µôÉþ“n›»½¶ý­óoÕjO œŠ¤"G{Z è÷¿yöÍî`·U±ŽÆG‡bCºÐ-Š%’ŠPJ“Ùd(Úwn_4­Té9rfèLÏXÏ/Žÿ‚snQ,‘¡ØßéwX†0)¥¹–JHý‘þè@äÿgï¾ãä8®ñ׫Ꞟœvfs‹‘A€Q$E‘’¨D*J¶e[–}öOöÏòÙ?ßlI÷³Ï–­³}:' :Û’%Q%RÌ@›ÓÌNNªÞýÑ»‹E EB ˆïûáœÐ]]]t×¼©ªWÉ5F鸣š#Í3噲Y~ìÈc Ù|²'÷¬¥’îêÆ–´ÚãíÅjñìÌÙž†ž°/<œžÈOL¦×u¬+ÖŠù‰§žÚ7¼O×tÓ1&ªVÕQÎLyÆ 6EýÑ‘ÌÈD~bº8ÝntË¿8í!„¼9¹ù+ @|sŽ£A”þèªÏ~ù“ͨ-^±øðSG×ÿÆ»ÿž^î\¸Ž²øÏøGô#WçŸ/‹RÊË›éÉ9眇B!ŸÏ÷fŠ\Á™tÅ@*))y6!„BÈ/>C3 Ý`Ww”Á«y‘Q„B®Fœó@ †a8ŽsÙwÃ0ü~¿×ë}S†f@ï{øÁ#üžwßÝê/رmÿ„gåõ›{‚ !„«—”ªj9BpG*`ÌÐ5DÆ$[PãB^k¯ªG!¯ñŠd#C` EÝx¦Ã0ÜÜ/§I4MBüì Ö\“Ÿ(àvþä·ÿü¿—îû›ˆO¤žû«ýÞÙ÷ÜÍþᙡ¯ù“­~M͵*…f!ä*¥W.mû4°³ÇG{Wv"ƒ<½×Ši¼i¬Üyé !„BÈå85§±h8ßB!èGÁ˼Z>q¼þ½¿Ïƺ`æï¿öã·þéO¾xwñK¿þå#¥¶Bó³š(4C!W)Dloއ=¦ ëWv#ƒ‡·ïÁ¸€¶”iîGäÔD„B!W£ 2zµ¹’]z&Áãñz4½tìÑ¡ä'7´p8«û æ¨…¿²Rh†B®^ QJåþ‰Œ!2†Œ)Jcš!äcÀ.;GwH¾Rx9GgŒ¼bެ |q Wd‰~.—Cd¨.o8ý¥+Ã9 ^b„¾»=ð¹«.!äMÔ÷ÒiT2¹rPù‚}í#mÛs2sôŸFz>yKcùп÷ø‘¶¿ûÞÓ(4C!„ru`fE– N$áá.cwËT©‘ªc)ÝàMÝ×[BvÊ:·M®Ó5ýÂ@0pH W Ç'.¹@…¦©<^ñ3.øÈ9LU̲dŒ!¢/¤Õ·û_otZ¦Ò/ª "?]ÆôP\¿ V-K—gÇÍpG÷rŠÎB¹<ˆÊêþØçnù»¯a»høÏ_|oÌ,añ_úâ{º‚ÆÂœ†ô£+!„BÈÕBÐt®é<;m½ütʪIÍÃ5 ˜ÐAh éœs`Œ¹[j:`\À9 Ùþ§R‡·Ïf¬}O¦oŸÚ쎳åh ôÙ§šÎ¹¦é\è\èÀlSÙ¦ÜûèT¥à¸‡pwä4ëßþƒ‰ÂŒ¥i|¾·XwcÛT§öå•ÄùW€p:ˆ¹ƒ{DàÌ=º{^îiÎWòé=s0ŸO™Ù)³œw„·¶B6wD¡cŒs˜o¹C0M絊<} ¯º•:æXòïþÓ¡³nÇxþ]¡Ááçg­šT ÏË æZƒ>«„B~:`–Ìyï»>ôáèMÓ{ŸÞ}:¾ò¶ÕQ;gÛ 7¤Q3„B!WdGvfN½”oZäïìkÏ~{,?cµ. ¬¸©î¹o‡ë<©‘êòã-=ÁŸüà7 IGm|Gãȱ Dô™‰ZÏÚÈ™ƒ…÷üVw ¢w¯Šd'jfEx&==\m^Xº16ðb¶”·Í²lé ¯‰6tú·?0î àpÃ{šòiÓð Ýàš‡Þ>sæ`>Öà]ÿ¶ú‘¥ÓûóËà € ìÌL WªEÙ¶4¸xudÏcÓ3ãµæn¼ÑûÄ7GQ]Úêøžœ?¬­¹-i[êøž¬UUÞ€¸îÖD­"Ÿù÷±X½±æ­I¡ñg¿=¦{ùŠëêZ¼Û¶ŽÝüþ–Ϥ—oŽû‚Úò-uMÝ~¥!;¾; Zz;œ¼åƒ-/=ž?]N¶ù6¾½aòLyÏcÓ¯¸ùÍŸYº!¦$Û­kò>ñÍÑ`Ô#txùéT ¢¯º%‘hñ*4vùs)³”³ÃqÏ™ùÏÌ4uû;–ŸØ:¢{9ˆÕc'KûžLyýâú{šR£Õá¢UUuÍÆÊ[n€ŒByÅÈ »pú{_ùÊ ¦1¥”R¶ª{ûGnç#3KÞÿÁë97«–FÍB!„¼ñ8‡‰³åñÓåÛ?ÞZ.8“ƒ. \°CuúÍïoÎLšÙIsðH1Ùî[²!:x°¸ÿÉ”nðÕ·%ÇN–ÍŠì\l[L¶z—¬d'ÍXƒŒèŽ¥a­}yè졼íSí#ÇŠ'^Ê/öo‰Gë=“ƒ• w7Û•1+ÎÌXõÆ{›•ÄábnÊ,fl. ”µ^Þ–ºó“팱áb>e¢Â¥›bî,§é‘J ¢ßöÑÖ]OVKN­,ïþ•ÝàÉvßÒ Ñ–Å|ÚºõÃ-Í‹ÃE«&OìÍÝúáá\ÊzôŸ‡ïøD[ko03nþäï·¼·©oSìÈŽ³"7ÜU¯¼oS4Ñ”B«*keY+KÇÆD›ox øÌ·ÇºV„¦†*™ÉÚŸjŸ8]9^zéÉÔ†»êÛ}#¥é¡Šc)«¦FO”:üË®Åç¾;vÇÇÛZz‚Ç÷d•ÂýO¤ßöK^¿(fl)q×ÃSwýr»tÐãÓºW…­Š¤F«R²Ç¿1rë‡Z[{ƒ/?ÊM›fE¾å#-ƒG Ž©€"3„B^"xBÝ·â¿üõ×·nݺõ›ßüÇ¿ù£›Wn¸ïWï_÷Ë«Qh†B!ä*¬Z’±zÃÐîøX[cçì¢*Ã¥<9ÿÀø#ÿ4ôÐ×ÇO•âF¢Ù;q¦ÜÚ;Y<\xú_F¼­Vr¤ñFïº;ë{ÖD•rÏ \€æáù´U-Émß;ýrÞÖóisðH!’ð ²3󵊣{x0ªßt_s²ÍÇ ¸é(¥0ÞhÔ5ûr)8‹6¾ ¦iœÖŸ!„ònîÜ*ý³ßùÈç¿ô7ÏN‹€/;¸ý_Ù^Ö½L¥ M„B!WM‡JÁfÀ†ŽJyÛLT×dlyoó#ÿ8Ä€0d³)…|Q)8¶©Š‹(‰¨S £I#;i¦G«õí¾‰Ó•³G ¡˜nV$笘¶ü!­VqÖeŒ±ùEfU!²ZÙ Å=µ’ÃC…á„§yqà]Ÿíš®>1°+ÃØ«é2tÿc¸þm Èðÿü×ãÿB/× Ÿ2OìÉâO—Ùž©€sÛ c¶) iK:(¼ýcmŒ±BÚòx…m*¡´•‚ ¸ó“íM‹¨PI,eíRÎFõìT-ZoômŠßþÑÖ‘ã%_H;¼}ƪÉÂŒe›Rp—R–Ò=Iˆêƒßó™®Rζªêøîì’uÑ‘ã%_@œÜŸ_{GÒ¶µW| IDAT”’8z¢Iz€3àÀ㤎…fEz¼æÏ—>¬„B^DýŽOý—÷¾·ýÁ¯þÿ'îýÀÚ„Çï‘pÑ„B3„B!WA×Ma²Íwæ`ᑲjrÕ­ ³*[{‚;4‰Œ3Öé—ó3ã5ƘR¬V–+nŠ?ôµÁbÆš®jœØ›cŒ"Zz¼¶ò¦Äú»ëÿÆH¸N/f¬ïkñúÅžG§ÇO—+EgÙæØþ§Óˆ(t,DdVU2`“gÊOýËÈБâ»>Û}x{ÚãfU%Z|†O<ø?ÏTKòÖµ(¥­cVM¡DÇRnì£ZrÌŠ|ú[£uMÞúŸáÓÃÕ‰3eÍàO|c¤VqÌŠä‚9¶bŒIG)7ÜÝðïžÎÖ½µá¦{›ð×g<>Þ½2Ü}]äٻ孶¥–o©3+ò‰­#‘¤GI 'ŒhÒ£yøÍ÷µ<û±»¥s`gæÁ¿=[ÌXïüLWçŠðc_®;>ÑVßáÛþý o@«¡Ãøérko keø‡ÿó,*ìÛ;úbæžßèŽ5 ÙÔ`5=Zkí >ø·gͲs×/w"²CÏ¥Ëy›![ysÝC_;[-ÉuoKf'Mgîô)q‡t$cìë_ü kÿ²ç'ÛøÄŽvÐ5!„BÈ•R3åš/p©] yýyT¡ä¦w´ìÞ÷ü©H“ù[kúw~æ¿}þm1æØçoI¡B¹º/è åÌu,)2GãŽðÚL£Ð !„BÈ£\R;+Ø•gžø¿û'\•Çš~kãûÿxQ_»ß©Ù4j†B!äpΕºœoÀù|Ÿ¥”-à{‰]ÐÍõÓp.Qpι”Î¥ sÿ÷:ê/„6Ÿ Q]î‰sDŠqBùyB¥¤RÌhZÔ× ¨¬š}©­(4C!„ríškXfõ쩽K–Ýà>Ÿ‹›ÀløÂM)n4g3Y»¯Õª¥ý»d[5dèõ†Önz·¦{fKpw9¿4`P,¤ #à1|ˆ ༠€±¹|QÀ…85ðB$Ö”lìʦGynà ÷Í•âVœÙ¶Y­ Ã?tfOß–W«ÿlAq`ïO2éQÒYÔ»±½kÕ¹].¬6€Ù³ž«+(¥òÙ±h¼æ›…B¹ò·j` •TsÏÝ*çPh†B!äZ%¥%[QòÓŒ1Ûª)¥¸šf8މˆ Qh:çšmÕ*àBpM*€¢’Ò©ÕJ·Ýõ)mƘRÒ²ª\ݱkˆ¨ ¸ÒB¥0]÷žÞ×ØÔ“hìrSIG]hºc×c •®{À±kàðb!åÄ8ð‘¡C©‰3ãÃGÚ:W)¥l«†J麑INOœ^~Ýí]=ëÀ¶M¥$çBÓ< ëÏ“Ž­ë†í˜œûÇGÞöžÏ©Ù18`[5.4Ž­é^·p¡iBèJIÇ69šnØVU×}J9Œ±ìÌØÄè±h¼YIÛ‘6hš1/"„B® V.URÑPÜëaf©PsÀ ‚/ ÏPh†B!äšìëÙVíØ¡m¶mÖªÅ5ß͹V«•N ¼€ˆ–U[¶ò-‡÷?æDm»ŽÔ'ºï{4©ŸI ÷¯¾£\Êú|a¯/˜ÏNÆ“‚k\hÈ<½ïðþÇûW¿U×ÑáÚðx ²±ûÈËO4¶,)3õÝÅ|Ê6«ÃwöÔ^Ýã+3˯»ã¥ß'ÚrÙ‰E½›‚¡ºc‡žñú‚Ù™ñ¦–¾Z­TÈNm¸áýƒ§_jﺮTHÚÿ¸ÇðCuJ:£Ç’ ãcÇ{—Ý8pà)ÝðJéôôm9¼ÿ‰H´¾Z-ÅëZâ‰Ö±á#‹û6Ÿ=±§«g½šà‚1wˆ ;}|?"úÑ|n²£{õÁ— EJ:ËWÝ~ìȳÕrÁ¶kk6¾ë©‡ÿî÷~~|äh!7U*fjÕb.;91zÌq,%¦¶¾úÆnT4ʼnBÈ•ºYs´3|å³oÝûµÏÝ[ŸÝñåßüÜsÙ–›îÿÜï}`c@œ¯É©­!„B®½Îcf­¤”ܰå¾%}7¸k¦ ‰5˜µR1? À{ú6÷.¿±V-œ=бxmÿê·ÃuˆØÑ½º¾±;©oí\É9/—²'Ž1r¬RÊ&ºÖl|—á ‡™Ôp8Z_ßÔí8V©”:Ô¹hÍÚMïnh^ÅÛ»¯‹%Z5MŸš8YWß¹zÃ=ñºÖLjz–ݰdÙ–r9Õ-í¿E×½=}[¼¾ÐôãG·Ÿ<ºãø‘g«•BWÏúr1“žìîÙ0:t˜!F¢ £Ç*åüôÄé 7¾¿oÅ­œkÃÏ€q.xk犆æ`lzât(TÀÓ“ghN!„+y³^É}ò`óþê;;ë`ÿÿþÿÖ|á¿ò‰é?p4[ †jÒ¨B!„k’RJ6¶öVÊ9Èe'ªÕBKr¹?5Šˆ\à\Ù ,³æ÷GcÁ`"r.CÆ90Æt·.Ù!¥­{¼¹ì¤ÇR*¥<2ÔuñM¯/¤”dÈ•”–U‰Æ›Â‘ä·R)©My8çœs…R¡Ò4úü%e±:\­ä'ÇNæf&”r|þZ²¾«ZΗ•t—¿q+J"¢á V+!4•r—ŒáBCT\ ¤L$;JTJhÎZ¥œÓ=ÞZµ˜hèŒD¯¿ù#†/Àx<ÑÆ¹@¦Î-¬C´¬Z0\‰5Æ­†áG ÍB¹’À±§d{WgsH“§ðŒ¼ýŸî^½täºÎGFm{áZ5C!„rMÒuO­V®UK{w¸ïQ¯?ØÐÜ7€Ð<‘hC¹”:ý’ãXÃÌZ©½{ծ羵gÇ÷v?ÿ³§öŒ]¼ôú–ÖeÙôhSk¯¦yöîx@M}Åê;_ÞócÇ1ƒ¡xOß–Ãû7«ÅH¬!o®”sÒ±»—l8¸÷á±áÃáhMh"„rEoÖ*P·òž–ò÷¾ãW¿³ñ×~»M>óÐÓ}ï]Y n:P,W©½È'„86p´Z)÷÷÷K)ÿã{«Åb1‰Ð°ä˹\.Rë]^ÓE"‘ŸëQt¡}÷À£Ú-ö´1Öª$äÍŽsˆ¨Pqàˆ fÇÍ–­¤`œ‹b!=:tÄë rS‹z7Cu •›fQ7ocÌÍܤ”àCTˆÀ•’ÜÄ+¥À­¢à³KÞÌÕdA®n¦”t/•óù’98»âœ/<£Ùj¸»ÌVu¾p˜ïø²Ù4¤À*>[mTJç82¦¤œ-ÜÝçâÜ)0†JÒ½79Órîÿàæ›oèwùJý½l6‹Åèrqy½åk«õܻƫõÌu}ëÖ­›7ovçÒ…á˜é#»÷§õÖoX¥—Ǝʵ÷.j(eh"„B¹ö¹ñŽÙÇ(c(/ì"2)¯7”lèRÊ©K¶Ÿ›4ÃAtl¯æ^Ä…¥¡[>º“¤˜dj~÷…œÛR^¢“Šˆsïž .Ë[^âŒæwÁŸRøü»jaµ•r«zAáóÇ¥¯W„B~^€;µÌÎûúó°];ûv)7™.ú¶Ü÷éÞÚëlþD¡B!„_|\ˆx¢•1æÆ:¨A!„Ÿ7QÎ<÷—߸ç³ïÐ-ÅØô‰·Ÿ¬Õ·DùùÃq(4C!ש$2‰ŒÓ—+BÈë»~Ìö©%!äbÈ@"£î¹’*é‹núÏ¿‹¯ZÞK„½2½zÅ-ŽÖØ\¶³ð³F¡B¹–(Äe ‹ž8|°ÐNkÍB!„\15[:¢3ä §6ðÌ?=ðU³ÿ¿ûûßøæáÛ?|o³”ôã)4C!שäÚ¶åˆN/kH¡B!„+++eG¼@³>É•¢\Ø¿=³ê ±fë—ŸÏGÚ?ùR×Goò35C!×2‰Š1ä ©ß@È›¦cŒý ËÕÎ¥—ÀW)ä’‡`ŒÁ«ïøºê ð:ÎbAV dWzµÞW¯Éëª'!äæZË—HÿüÉ•„ÊðwohŸH.Y»¢õY3ܱeó²c»'MÿùRh†B!䪦L•>ßå|aµš¬”cÂëÕATêâmœr™k7Œs‡P¶å”J 4] €óW?²LY«éÁ;?Õ(*å&²VfM …_ËY RN¹ŒŽí>>ÿeœ>JÉ.®6Jé”Jz8|Éz‚¦Y¹¬'¥!„Ÿz¼ñ`æ—}=®‰ø¡}f&ù«_üB„Ë †¿Sh†B!äê\0D,œ¨¥RÍo½k6³’R ‘qî®ç‹Jsˆ¨pJç QZÖð÷¿ƒŽÍ ÃÊfº?úI=qC(%c 8çºgèuu'6\?i™SÏn«Œk ]È'¯¿!Ò·„` ç œÁìAc™—öû›¿Üø¿¾®‡#ÀÂ-ª:1.-S†ÊÃuë7Íž Rˆ87@)ÝQ2ˆÈ5­:9yöß¾¡‡Ãz8Âc«ÖF–ö)Çq+ìž#Æ”B¥æj… Ñ-Šp]ÏØg$ê} ŒãÀCÇ! 'Žü®þÒ_;»gë JCg•m…ºg_Þ×pËmîë ¥.Æâù¸ !„W¾›ójùäIí®¿úêÚ H4|±XskKT0@ÆhB!„BÈU—‘•röàËf6_½4{ï Üã­NO彬l;±~S-ª¥¦:îû'+ I³œN+9¥‡#ñÕkkÓÓåÑ!eÙžH4ºb•¬Õ*㣾¦æêĸ‹×Ò©ÌË/¡ã$6lžxòQ-¬Û°IøüN¹4³çEY­F–õ{“õÙƒ•]È'6m‘¥’•Ï;»§ž}*¾j­¯±¹é­wy“õ Q9Nz× ‘e+”i–G‡B‹–dö¿$kÕ@Gg¤·/wø`i謯©9ÐÒV‰®Xiçòå‘!÷4;îýPyx°4xVx<õ7¿…1Vj|ËÓ;ž -îu ùìÁýV.îé-Í;ÒõáûõPHYVþèáZzÚH$ã«×å5gÒʶüM-áÞ>7ªE!„ü¨Œ@ßæ®ƒƒ£ƒi…x8ýØð$ßøž¾kc—ÎÏEg8µ!„BÈÕ¦pú¤],Dz—M<þ®iÀyu|4ÐÚèèÊìÛ[›œyðØŠUN­Rìá`ç"nSÏoCiûš[so²AøüÙûêÖn!Ðqâk7h>ÿôsÏø›4`rÛµôtix(Ò¿²65é”KÙû|ÍÑþUc<ä”K‘ž¥z0„¨‚]‘%}ʶ'ž|,¹ù&§\.ž9UÉ9]±jfÿeš²ZQŽÓöÞ¤_|AI™Þó¢æŸfÏ‹F¢ÞßÜê”K™}{²/ïS–Y¾røßUŽLí|^…ߟÚþœ éÑ(îknuïg @e;ÓÏo›Úþ p1óÒn=Ž,[ž=ôræå}©Û£ËVT†‡²‡æd í|®:>.üpO¯S.å®[·ÁÊçr‡Ø…|ub¬õíï,ž<®l+?pXÖj‘å+¦w<Ë #ÐÙ­ù“Ûž, ž®LŒÅV­™ÙóbyðLáØQ.D¨{ñôŽç”mÓç“BÈk¼šß÷¿¿»#ËCA¿? «<žI;Æ…£dhÔ !„BÈÕÕCÛ®ŒÛ»ÂKzC‹{r‡0Æ„?0öèCÊ4=‘¨2kŽN_c“7Yï”Kµé©h_el¤tö p-²tJhk]WR± ªÈjEÙvxIcpä|1ÜÓë«o¶w„–ôZ¹l~àHfß^aÞdƒ¬T¹Çš6þø#ãü8Ðѕظ9ìÈ™ùg§\J[¸®ûÛÚ-mÂc ªÌÁýz(_µfôÁìbÑL§â×­ñ7µ*Çž|îi-ƒ!–G†7‡÷ÈJÅ.|M¾–V=Ÿxì'žXL b¤·ÏL§ªÓ“õgÂðêáHË;ÞÕpó[ŽüÅ—Œh<¾zíÙûfê…ç5¿_ óG{ÁÎîòÈPul”0áó1†F]RV«cü¨2>êT*žh¬æ÷ƒZ èknɼ´Û*B]Ý¡Ž®Ð'?Þ»ËÃ9÷x@v>ïoi ´µ‡÷–ÏrÇßÖáM$•4kš?@ …BùéP¡¿ù¹ß^vÇõI[•r6³áΚֱ¨Ms$Mh"„B¹zûqŒsaø”c3ÆÊÃCî:2“O?ÑõÁ¡”c<Äç¨!pÆ*©¤T–Å€)Ç¥—2º|EfߞТд̾½  ÆPÙ6:¶ðztƘS,êáh ½½é¶;½õ µÔtmzjfïîpo_Ë]ïŒ_·fâ‰G„Ï]¶bÙÿóy33BdöíaÀpnÃÔŽçË{Æ~ШKÌìÙ) /ÚŽS­˜é07bšG™*TŽÍuÝ].‡Í-pƒJ:"úšßÿ+ÞúFTiΤ„áUÒ± ÆaÑ'~9ÐÞiå³ÅS'òG0ÆÌLÚ.ä‘!pî”Ëî"8 hZóoïúÐÇ­lS/n7gÒcüXø…S'| MÒ²aul g6%ƹ²,Æ@VÊF]BV« Qѧ“BÈë¹£3M©C>ìoþÐòÌ_üî?›\wÿg~}ñEkòSh†B!äêB;»Ò{^¬MOÛåbtér”ŽQ—Hï~ÛÊeªÓ“ʲØl"]Ö?öèCʶQIe[“O=ÖpËmÙ—÷‡õ$Öm<{êÄÈ¿§ù¥¡3mï¾Ï›l˜|úq»Xh¸ù6=N¿0þÄ£åá¡È²~aSÏ<%áó%7n)ž9=þȺDm&í­o ÷ô¦w½0úÐk©©úoA%ÑvÜ:”ϱx÷Ç Êãc'¾öÕ–»î™ÞùõÏ_óÖ7ä, 9¥Rxñ’Ô‹ÛC=½Ê2} éÝ;'ž|´:1–Ü|ãÔsÛC¦L“ÆËBy­7tà¥Âþm'ë~ç?uø__Þ³òþ_Kz~Û®åŸzkˆ9 o'P,W©½È'„86p´Z)÷÷÷Ëÿð¥ò±X,F"¤ÎÓå\> —ËE£Qj½ËkºH$òó>¡ë÷ã/Gã+ý~KÈ/îmÛœIËZÍHÖ0å8 ÀÊf…a¸™ƒP)_C“],‡ÒàYáõ:¥RáÔ‰æ;î²ò9_S³9“ÒÃÍç· s&ÍꑘQWg V&Ãúš[C3–¦)  çf:…Jy“õš? «ÕZj¥ºîMÔ ŸÏÊd¬|–ëo}ƒ»¸ŒQ—¨MOÐP:Þd=*Å€WÇGŒºd-5Jú›[¥iZÙŒ )éx"ÑÚô¤»£0¼nšjTÒ.4@š5=©NŒûšZjÓSÊ2ÝûºŽ ãu TÒÎåôhÌL§”më¡Q—0gÒv¡ ùýF"iΤ•i‚® à šf¦S¾¦fY©X…pákl23i#Q ÑœI ¯×©Td­jÄÜã©MOuuv¡`Ô×[33NµªùýÞd½9“ÖA®ëµtʨKü”<â„kVYª?X±ä®î[©Wêïe³ÙX,F]åËë-_[­Ç9w³¾]×·nÝÚÑѱyófÇq.qÊ\Ï=ðG—û“?½áo>ñûýÿã['¶þîÄo~úÞ˜²iB!„BÈU 4Í×ÔÌsû¯‚1Ƙ'<üEÆ€¡’Z0覎úî·„ßß|ûÛôpD‡Q)_}#2†Ji¡»E¡”Z ¨CŒ1w0µ¯±iî˜È ´uÌn©÷zíóz4ê‰ÅØl±aÆJéM$‘1˜+¡ò·´!b ­ÝÝQÓ4=DD` ó·´ÍÑ›H""€îMú¡b ­•ò7·,hˆ „ð&ë‘1÷]·VžX܈׹µò&êçæH!cÌ=.÷xf«èkhš­'€7Ù€ õpäÜé·w ¢¢RÞdÆ¡Ržx[¨¯¾‘¦5ByÍ7tˆl\7þö;×ý•ý–?þl0÷/=»è3çò‚è…f!„B®ÊîÜE¿Ùž÷3#νä8Ñå+b+¯cÈPÉù¼Îç6F<Çóž^p”WÙòÂW港àE5?ï( ¶¹øu7NsáîTŒáÂ_©žî´£‹Oçâ³_²ž³.(jaù„BÈk¼•£Ò‚MûÚ¶[†2õ]~ÿÊ¿~Ãcè–}Y+„_ IDATáÌ ÍB!„\ã=?y."C!„«è­÷„;{#¨”BÅ„¸8.Ã(4C!×¢’mU5M£o !„B®œ —Š“"W"¢¼pÌé(4C!×[ʯÜù‘ÿ諞€—ZƒB!äJq,»-TÝLÑ`ä?…f!䃌…¼>£P6€ƒB!äŠqj–ph~(yPh†B®= ‘ Pl†_4€1P?ÃtEÁ9"*D·4œÍfBÎØìuÃ]Uwþ©B|-åê5d<Æ8p‰Ê­C&/*‘àkú¾zÏ•‹ùÇÕe¤_uO^|j ”º¸D˜Mú3ý½B® ŒúWä@¡B!„«ʦ,i/N4_FÐ1†ˆ/œh‰&Ú£ ÆØT1w`bPJYŠô7vì:s¢`VçR©¸?ñÏf&cR©Þú–¥õm¯zàã…Ls8þêÑ`¬j[ÇScËÛ½šgçÐ1¿n¬lî\˜&fÊ…°×?šKš§9-çË~xøEÀs”ÜÜÙ— F^WCƒŠmJ%C†at&‹ÙÁÌôªæ.¯¦/,Q*U0+ˬXfO²™>¥„B~.}jB!„7èBèBÓ…–.çÇóà>Õ¸æ>ºÐç0û–ðhœsÁ¹Î&ŠÙÇŽïß~æˆÆ…#åö3G—&[6t,™*懳©Õ­Ý+š:§ ¹þÆŽUÍÝÃÙé€Ç{Cײº–µE“çúl™neÄÜc¡ ¡qáÚÓ'z„&8w_À9ðùê¹5Ñ…¦žL+DÁá뻟<0~Ötl`Ì}×­ü®áã–ã´E“É`xþ|Ý™+P€Æ.€ Îc‡&oêsé ]Ë£¾€{úºø\á>ߤîîîX]hl$—š.åç7Ö¸pÇïì<öƒC/f«eXØþ™JñÄôXk$ѯ?ïïÀ#4·­8ýÆN!ägC£f!„BÞȸL±Vù÷—·W¬Úu-ÝAë ‘©”þÏÞm`ycÛ–®e_{ᑘ/0YÊÝÜÝßY×ð¯/=ã÷‡'ÿß·¼ïÐÄPo²åTz"î­m[|ffòžå;¾¿b›ˆX±Md̯w÷­D†Œ<Þ˜?ñú9ð¨/ F¤R¶tþê¹c÷®ºa`jøèÔˆ.´w,[¿oôôL¹¨P5‡ëÁðö³G—Ö·š¶{ä$*¼iQ?l;y0ê d*¥÷­Ü<˜Ú5t§{bþ ~pbh]Ûâ°á;›™ZÞо{äÄ“'Ä| íKöž±'×£º?<¼Ëдº–šþ“½Má˜éØïYqý3§õ7v”­šDµº¥;ìõ'ƒa[J–«–¿ûòŽ»—­{èèU,sûÙ£¶tÞ¶t]"úÁ¡éraCû’¶XòDjì]Ë7~åÙßÕ¿ñ‡‡wµE>ÝøÉÀ^Öo¸¡k˜(doëY5UÌ6‡ã“ÅÌ¿í{Ötœ÷®¸þÉS4àÓ¥|ÌXÕÜõ=Oë\tÆëo_rÝïýèŸoY¼âðÄÐGÖÞÒM¨ËèD!„Ph†B!ä$€¿4zzuK÷ÚÖEÇScÓ¥¼Æ¹Bµ¡½'æ >v|ßõKƒ†wK÷2CÓ=¶ObM뢻—}éÉïz5Ï­‹WcMá8È×ÊéraUsתbîàøà¦ŽÞº—ï:æ8²#ž¼®eQÈð!"2DDd gS×Q2G¼þ»ûC†ïàøàço»÷å±³gf&%ªÞdËêÖE ì]ZßÚߨ±¼±ý‡v®m]ìáÚ ƒ7t-‹ùï[µeÏðÉCƒ¹jùþõ·YÒyäØKp`ìÌ[—¬.[µ©b®¯¾íñã/ÿÁ[îͧ Mo‰ÔݱdõÀôˆàü¡£{ëÆwä«•íg¶Dêêü¡Om¸ã±ãûrÕòÛ—­Æº‹kA¦R:29ì(©—5´¯i]ôÐÑÝmÑDK¤î뻞ÜÔ¹T*õÈÀž[{Vö5´mêXº{øй`ŒyuWóÜØµ¬9?41ØU×Ыßqöh¶RÊ×Êñú•ÍÏŸ9²¼±}ÏðÉ»–®k‹%†2Ó7w÷—ÌjÄÈUJ/œº¾£÷†®eÿ´ë‰²YëªkxKϪÖhâøôhG¬^!-J!ä2Ñ„&B!„7RÕ¶ê!ÁùÊæ®°×ãùLªT°¤ƒ ‘1C×=BÀ±lÕ¼š®q-â 0ÆÜ=ššùjy`jdÇÙT)zfB*Õoxߊͷö¬ÈVËǦGáoléÔl«f[ŽR^ÝãÕ=¹j)ê 8JéB«Ù–å8_ÝjêmI¥,ÇV oëYå(õ¢Gh%«&8G†š†¦g*Å¡lêdjüÈÔÈÉÔx¾ZֹЄh‹&["u •£C¦‘¡O7ÜéZ¶r"¾€TÊ]{w~^•à‚1æ(YsìšcWmSpˆùƒÇ&G;£ ±&mDåÕõ·õ­ÍVJ^ÍÃnè^&•b³«#c(bѬútåØÚ—$ƒá2ûFO¿<~¦fÛeÛô{<¯Më"[J©”ÊU+oÀòT˯>MK#B!¯‚FÍB!„¼aaÈðäR±úÝÙj1ê ^ݺ(ê T-Ë͸„n\aÀcjUKÚ™J³¤äRJ0š›ÙÔÑ»ª¹ËrœGï;818˜™ºséš®ºÆ‰BÖQr681Fƺë×´.’¨Ü"Æ|Aw)–šcù=Þ’UC†ÈfS>I¥ÃÐô%É–á;25ðxÝ·1àñæª%ÆXÕ2m)O¦ÇûÛV4w:R¾08Pµ-ưj›#Ù4PJq à ŠfÕ’ŽB¥smnLcŒ™ŽÃJ`LZ}0²±}‰­$cÌtì‘lêú®¥{ÇNÝÝõú[£I¿îÌNÇý¡L¥ÄûÁ¡kš»0È×*n“ƒ¨7`}ESçÉÔøt1Ÿ*åeÓ •£äÀÔH?”­–sÕòþ±3QoÀ]}F!ÖB©r+[µ€Çë¦rÿj!„ ÍB!„\“”R;–üèð®¿ÝñðõK›ÃñšmoèXòýC;W7w·DêvŸ{ýnü"høºâßÚÿìH.åæxþÌá%É–33“^MŸ.Öµ-®F%ªþÆvDìŒ7|í…GaG¬þÖÅ+0ð{ @††æ\H¥Ü,Ô~—„¼¾Û{Výù¶ï'á·õ®1[ãøt€<ÆîáëÚ÷ÀvG©·÷­“¨¼šÎjB$áæpü›{Ÿ¾¦P,[)mh[ÒŠƒÅÉæ‘\ê=+6ÿõs?®EÞ±lÃòÆŽ½Ø]×È>¸æ¦xñ1¿î¹µgpÃM34íñãû–5´•-S)µª¥{²ûâ“ßADGÉum=5Ûº«oÝ3§ž˜»yñŠïØnKç}+7G}ÁcÓc¶íÛzV…}ñBæ›{Ÿö]Z2yúäw¯Øôðѽ»†O¬m]4ŸìI¡Úܹôá½÷­ÜòíýÏ=sêл—oòÆ÷ìh&šÂ±µ­=ß9ðüç~´¶u‘_7‚/2¦sáÕt¤ø !„ŸËUjrÅ !Ž ­VÊýýýRþGO½FÄb±‰D_ÆE —ËE£Qj½ËkºH$òs?ç¥tæ_û¯žH€š_„«c‚ ˜Ï]ÈÜÁ2L!w€†ÆEº\8•o‰ÖýøÈî_Û|70¦pvî0P¨Ü1,n>#ÆîÞÝø àîcÁ9C&çªqáî.8çÀC©®g'4¡r·Ad‚cÌ͇ îàî´!w_÷rA}Üób ¥(wDCÁc(2Æ8€£¤ÛnÜùH•Gh¸àvïÖa~`‘{©$2&€»Mª5Α1`à(Épî^Œks÷\Ü$SŽRçŒTÊ­›»F[”»—R(8w”äÀØÂÔà„k—¬Yë?}_ß­›¥ã¼R/›ÍÆb1ê*_^oùÚj=Î9¼j>]×·nÝÚÑѱyófç>3¯š!„By#!cîl£…”¼ÄW}G:^M÷hÚH.}gï7à2˹àÛÅ\¤@²óÊADgnµÚ ¢ óuJÍï5¿´­û®-¹êW¨7qŽ\pÄ Ž5^ÎùuVò\Vá¹].X[×’—èøÎ×|a£9 v´üJ$ºÏÔ¥~:Rˆîë wYX·…¯»ÇUs'N!„\6 ÍB!„\1¯¦_×ÒÍCÄù„B¹¦Qh†B®=À(ô¥Œ7%57¨-!äÊv±GÞš!„k ¢âib^Zj†B!äÊq,0 jò Ð !„\c€1Ç€§6ó¨‡SkB!„\)5 ýu4p†¼(4C!×$dº¤f „B¹b¤¤¸ ycPh†B!„œ0¸Ìä¦l6i0T—Sp`lvßs‰K1dÈ0€ÙìÙ”¿–BȵB3„B!„17 À c™á]Ç—¿k#㜱ÙtPÀç&Q""CàÜ¿ " RJÓùÇþð›-kÛU3ÞÝØ÷ÎŒ0dî6ŒÃl<Å}‘ÍÅb˜Bd¨õÒ??jˆöÞµ–k";4}ì¡=šW/¥ ×}è¦üèÌÄþ3Ï6­ì 5ÅݺÒ "h!„\Ë(4C!„B*,ŒÍT2E]X3tÍФ£²ƒNÍöŃ¡ÆXöÌ$J%jŠA_j`8p] 7ųƒSu=͵|¥m›z7ÿÆ;œšµý¯´+µZ®\™) öÙ{ï0;ŽëÀ÷œª7ß;wrÀ 0È$(fÂäJe‘’%[–ž-‡µµ²­uz~–×Z¿ç ·ö÷ìµ÷sX¯¬à$É–VŒ¢HY@ rž„ÉñÎÍ¡SÕyô½ˆLÀì߇0Ó]]uΩêªÓUçÔô4ÙbflÎ "g…DVÑ”hk-ã,Ñ?É8 7Åý±0ÍìxBÑÕRº¨Oêz`}뎞ÄÀ”‘ÌwÝ¿®û‘?øƒoÞ󹑔$¤ç—ñðððð¸ÓñBHzxxxxxxx¼×AÄR*?qx©¼ï{‡¤Ș‘Îç¦SLåŠÉÜéçö G™DßÄÌÉ‘¹³vÉ:õô¾R:ïHGG@%«·”HRrxFñkãò³éülfäÍ3Lågž;à‹ŒLÁÊ—†÷œb ·JæÔ‘!a;ó“M[VD›ã¥dc­5ÃoœêùWXã¦Na9Â$IØŽt„ç—ñððððøw€·kÆÃÃÃÃÃÃÃã=‚‘-ø"Æ UmufÞ"5è+Ìe“CÓF¦Ø°¡“kJ]okzÔ—žIôM¬xh£¿*”š&)›6¯ ¢P] ‹ÉÜè¾³vɲ «yËJ-à#‚‘7Ï$§7t¨_MwSU{=SØøþþ–íÝšèÌñ‘Ô¹ǰ¤¤Ö«F÷÷­ùàN#[œë›Œ¯hlÚÔ¬‹Ížyëo^\ýmÍ[Vzêòðððð¸ƒ^±Œá…?%¹,›çšñððððððððDV™B"1…ì9iªjÝy÷©ïì"äå¸3@’!" "P9@/@9îoëΞ»?ó¸p (&óóý“;þÑÓÏ@D΄eoùÔC¹éôÙï¾Ý¾«W q×/¾_ )aæŠsg&N:oÑüÀäʇ7Ú#ÒXU½¢¡ó oþås-ÛzñÐb±êêˆ_%á, 6ã¹f<<<<<<<<<HU¶¢”3‰¥;SÈý…䇷}z7P9Ûç™e÷.+——P~ÖÒm/´ð %÷ÒBuÄùy˜<¿Œ‡‡‡‡ÇJiN뛊îZÛØÙÚPÕ5Ÿ`ÐsÍxxxxxxxxx\Û„Ó;TäáááááqIˆ„Zÿ»ÿòúoÌô½úÒ‹_ÿ³ÿ;«×m»kתŽÖ+[ÂÌ ìáááqgó 2‚Êj×ùÎ[þ>Xøˆ Œ!¸ß Ý8šˆË2ùI"†(¤Ι$r—]pÞ•åŸ.yÊùH)ÙòÊ\å›lY™D$¤äŒYŽ£0Î9+? ØŽc9BWÎØÂ]RRɲÀ§ªîõŰ,±,w!¨œ« GD)‰!–[J@p‘f^¾ p¡èþá…¹¨%¼;µ“ÀˆI&oHuÜv-(tY3—÷…ë4€…{ÄxéŠy\w$¼œU_‡lߡܮZ“RÚŽÐTåz-S0@B&’gž·' mDÏåìqÃ@äFæÈWÿj¯ôëšX¹ºkÿ÷¿õ™?ÿ"À†ê{îý5AÇ ìáááqÇ®ˆAã¼'”¬JoÊ éˆäè>¿¦ij(äï?;Æ*n"ˆÆœ±RÉŠFƒ‰D†s¦ªŠ²º&šœÏ–Š& hªbÙÕ7ħ&çWt7úýúñCç›jŠÅ’߯ ¦Q2å’m—~¿V*•Ó£( G‚ÉùÌÒ)»”Ôµ¢qhpб«˜~«ª"¥BA,J§óXq‹øüÚÚõG>öÄŽÓÇGûÏŒb{{ÝÔTÒ¶œïëݾ«÷•ïšO¦’YD$IѪà'~f7¼øô¾¡é‹ÖĶœþäƒu 1Y9Á9;sbôÐ[ýÅ¢Q[OæÈ¶MW|~=“ÎkšjÛÎeZÁ9'")euu¤T²ŠãÆ®µñ‚ó"7a& ¨ÊeZªiªîSsÙâÒŠU×DçfRª¦!oz/·üƒð*šUÆk§WäÖ•È_áÜâR]®*™ŸÏ„Ã~ݧ¥’¹p8P,Ž#Q×U㢩‚üŠóJ € òišÊž˜K_§‘\²bïä:©oˆÏL'݈âñp2™[:¾éº*„tq z‰Ç#‰DúR]WG !n+™HIMÍÕwß·öÙoíulqíÜ:¥NÅ ³=‰€m“ç=ô¸ çXEK˜M¸Ú;2éq£lЏ^³iÇv¦© g´që}?û‚ÐÒ¥ØÃÃÃ㎆1 ©FØñ™³>äŒúÒç'=ŽÎ%…—çÓDaæ*g#ªG ó¶ªqMW[TEbfFR†¢Ï§0Ã&IÑX49[ŒwUѯÏLGãQ–å!ðc¦9.%-l †ý”+! ©šQ"Å9ké!d¼­jr.}™í*¾ºtŸ&á8’ˆÂJØHVY#¾z¥ÖŸœj4ÍŠüè\«šbé¤ÁJvƒVÛÓÐyFó»4g3Ƥ”a5ÔÓÐEDû³³E¹HM°huD[šëk–¸fxnÐêÏMS†Å¢ÑRJ/Ù¾€~sNè6^bIA@Šª$!DÄa9C¦ðÆn$AÄÊæ§›ë›ÑtÕ4¬‹¶”€üÍô9‰…Ÿc F² ÃçW[л7­%B+eŠS¨tæ8¾“€TUqqQ©QÄ.ÌY!ù¥Ï˜!A–[¦Íú:äù…R"¢`Ì€2ͮЈ($ƒ¾€®¨<Ÿ0ñz–­9ŽÞÚ÷ªÝ2‹fæJî€&‰Âz¤X‹\k }Ž#,Ó¾*ñ"D|‘üœyÑ…äú˱mç¶Rœ2Vm¶RËp®}@#5S³“ñÒH¤Tÿn7zÜÉä‹R–üÞØéqã&%Rõ5nZë;uàÕ7OApå}>²ºA'r¿F‚çšñððð¸ÃÇy@ĈI‚$ `D¬2ÌK"$‚ò W’$b„„ ÜËÀ½$±Ê@À- ÎéU3Á€ˆÁâsH’¬<ô*.nå¹5$bå%ëB%të,+u“D’$$(ׄIHAD—‹eé3 ’BÊ× 0” —J `‰è˜{¾ èһˢ–e‘»ä—aDF»‚U÷îšaÈäõ8H.ÕR" „óôK ȵ+BxGÕ_oõ.cJ¬ìc!bW`„®~/ª)×ü–Ø@Y,n3ÝöÂR"*ÿü2pñÛõ.RæU¨ñR»1Fèj±…ã7RÊuöý]õÞ+ÄeŽ0’òj½˜ ÝÖ5`’Kúþ¢ñÓ°yµÍ»p´\Ú­Ês±’Ù’¨ÈpÍb¹©‘’$éjìùâ `™DN7ôØVN^›ˆ”%Íïôy•µ’ˆ¬1$Ýb¿µÛ¡H"'º’®Zþ¢@•ŠB`K C\•´/öt\0ÑËŠ!bù‚%͹ d¸1£âíçò¸Á}Pä'¿ñ…Oxê•êhæÕ÷ªŠÇö ŽÓµÀCÛŸ?>™¶m³¶ªyKïcÇ÷í©7s¦ô´o›X·ò®;Ñ»‡ˆùbæíS¯Ì%ÇïÚðh[cÏÕj™€úÌtòç IDATFŽœØ Dwßõñë9án×ÚüeÓ.=¼ó£•eÿ±“ƒoéZ`kììôü¨a£¡øÆUïK¤§ö~>®ŽGë{Ú6î9òƒ۟xðÌ+¶mu·mXݹmßñçR“õñÖ=÷œ|+•™m¨m/”²k»vœ›<­k~Î•êªÆ–†îX±v.9aÙæÙ‘Ãç«"µÛ×>|føp23ÓÚ°’3åìð!®¨;×í–R9ûši½ÛºZÖÆ£ ÑÁ·jÚëâ-BŠ›Üi¿qð;éÜÜšÎí=›nÔø†È2ùù7?‹€ÛÖ>¬*c|rîÜþ“ßGÀ]߯*Úk‡Ÿ ¢–e<|× Oö:ýÃÚª&"Ú´êÞ¾‘ÃëVÞýò¾¯ð¾ŸfŒÕW·µ6¬Œ†ª÷ûn"5u¬oO¾”YѲ®µ¡ûÄÀ¾™ùñÝw,à ]m凯O=»GUµÜûStëãK¥/§/é¾¶êÆ§ª€lzôoŒâ°?´º¦áÉé‘¿RõºR¾/Vóp$þ¾é±/…!Æ”ªº'„“NÖè*æNÆžð:CÑÍ–9++äO&&ÿEˆ|CëÏêþÖù™ͦöF«ïE·2¦IaLžûÓ†öÏäÓr©7Ó»~%=û’YvìT$~_´ú¾äÌs¹ô>E­Ö|¥ü™pÕÝ‘ø=ä v!ÓMc|êÜ_0¬nü0¢šž{‘H2¬mþxvþµlj¯ªÕÖµ|rfìËÍ+~Ã,rÇU½!—ÜC$U½ÌÒHCë§™žÿ¶iŒÃÂUw§æ^,åNÕµþT>ýv¼áG'ûÿ´µûó€ "D@D¦²ù™§s©ýª^[×ü‰bþt1wR89U««i|*Ü“™‘‡ã»UDÕ2fæÆ¿ê8™xÝãáøÝº¿=—z3Z§éu¹ôù©‰V?è ®œû2"«kþ”¢Å'Ïý™¦7'ßÔõ+™y·@µ©ó?3îä™ùW2‰W÷W7<™ÏÌ¥ö5¯üÍBæp\}|nòfi$Ù©¾7=û¢ãd„“«ixŠ1Q©œ}â Õljo.µÈÖô¦š¦¤f^„×Mžûïˆr×ÕT5 ŒÍÒïø(‘œKMšV©¦ªiC÷®=ïóéÁU›»ZÖJ) ¥\*33“U¸¢k~"zt×O„ƒU©\²JuUÍ+Z×OÌí\ÿ#÷l|É,ô^Õ±åî H‚ÈŒÒ9£4ܾê÷ý¡Ufq '§ùZ›:™È1Jö5Œl©kùT1¶˜;UÊŸíXýG¾ÀJÇI†«vFköWÆëgLÏ¥ö Ÿùíѳ_ˆTß'¥I$kŸªoýôìä?™¥1@¾bÝ_ Q’¢0;þµê†§H‹¹“ŸÕ|ÍÉé§… Wíj_õûÉéïXÆ”eL´uÿ®îoNζӪVDRÑjT5>1ø'­=ÿ¥¾íÓÙä›–1a[©ÖîÏkz½c%Ò‰ï·vÿNuÇËœ@"G8y&‘lêü¬eNWÕ>ZUûX6õf>½_ó55¶ÿ‚Qʧ˜Åá–îÏûƒ=ÕæÜßÔõ9 @Ó#=|æ·FÎþ³8,…Á•HcÇgt{.}€¤%¥ÙÜõkˆj.ýv:ñrgïÇë?(EIZ™ÄKÁè–¦ÎÏMÿI"@@°ÓÑšGâõ;N®®ùUuïO%¾GÒbLoîú5E‹›¥ñ\ú­†ö_¨mþ‘ €$ †¾ú¶Ÿ Ŷç3ýÁž†Ž_T”˜c§séýþÐêŽÕh™SùÔ~Ó¯où©ºæOåÒoÁoF)Š\‰´uÁ¶æ¤0l;¡úkš>Ží¸lÌwÇ7ƒZü?üÂoíÞÜû‰ßøÿöì}ëï>ÿ‰Z;iœ÷2÷vÍxxxxxÜä 4`¾”Ž…k¾p,\#¤Cnºªn|ïˆ"S© ú#«;¶æŠi"Ê3ã3ƒ¡@Ôv,@„rte\8åËKG8ºê€mk*”2`;ÖôüX®˜6Ìb¥0 7ÇÖ-k}¡” ø‚ÔXÛ!¥ì= @ÉìŒaSÙ¹êh窪h 0…Hjª®«zm¬i:1ÂWUhÁ`ΓÒm²häB¨ÂÕ]ÿƒíXËÿ[!¤ðëA†líÊ»¤•M7Wo$R !…¢¨Õцx´áÐéÚŽU2 ƒcÇ‹f>¬’$ãÑz)¥¢hް9cšêÓT=ˆ"‚®ù%IUÑN÷%³3á`¼§}S*;7=?b «dä¥Á@Dáj{CO*;{øÌkm =…bÖVßÈUõ…Q"Š…k„šª‘‚*cç’ã ‘suíÊœ+¹BªôØ\j¢¾º¢áj•k+ZÖ>äÓƒM5†U›î÷ëÁîö ¸¯h™ß$kÁ’Ul¬íP¹ºnå]BŠJ®·‹I’¤OóëZ`udëLr3ùd¡”q„c;"êšTE³“3ŧâ‘:UÑ2MÕˆH×üB:@01;hXE]ó¯Y±#‘šŸôé~"‰…«+Ñs¯N\R MósÆ{»¶ÉÅ`ê×2v]£ÓSÚŠZ€ñú˜¥±RqPŠR©Ð'¥iSnt_³mÍ"*–9­ûZ™¢U—鸚B…€Â±»:Vÿ‘”æXÿïó}¶•0‹ƒ\‰ I6WÂN}ë§B_jö»þ`·Ïßn“–9žK½ÁÕˆ¦7š¥V>…¤ÙЦèþNácL#²Ëu¦)JLŠcœ¤©ûšˆ2…HÖ6ýÄìØWU½>V»ÁM/ç¾@Õ눤¦Õc:I›¤c”†¤(Âk%ªêuó¢„H:ØØñÙHü>)ŠÓ£#¥a–FmkÎ2¦¡ðùÛ‰Æý¶5£êµ‚ó¢`³4)DQ8ÙÚ¦™þ%à ÷ mÎÍ)Â@®„jXUûXræU‹Çjv ”¶iŒ¥a!òœˆ¤ã†>'šVE$t_‹c'5­Ž@"SÜsLD€i@¶ªV–Ïê2 Iä ï8“Çm7÷CfGŸûû>8–C i~âäñTÍOýÚoýäÎN•-”Þ®› …U™ü|ÑÈ Ož6-ÃvL"i;&¸;GÞC¢ðGÓ¹„a•ÎMž6Ì¢$1sPQ¢ÕõâJXÅ5&5êØó œtÜ•<‘SöD¹‘kPv²˜;VUûX ¼€÷ 'ÀS³/§«yØ\™I¾Î”€?ÐSÝðT(²IÓ—nÖ@äÂÉIÓaܯêuÙä)-H%^²ŒQdºpòD‘D¦.ˆIŠ"WBõm?Cd—ò}H ‰)JP®ãB *ä€<ÙZÓô1_ “«1(»z%I „0\_I›¤éþ°”?#D¡¦á#®WkI;R”¨°³\ˆRÅ—Ä4_c8vWMÓÇU½1ý¼¡†Yræ™ê†'ƒ‘M@s€dL¯où””V>s1Í2Æmk¦¦ñ)M«/‹  dˆÜ±³ˆÜ¶f5JP9GRó5˜¥a"AÒ6K£ª^[I>GË=Ï€èÅ•÷¸ }3¼˜:üõgûw>ñ¡'üñÇl÷ûîYÕÑ œçÀö\37)åö5½üæ×Ÿý«B83óc‡N¿šÉ'þ¡#ì—ßüºå˜øÞˆÛ'¥Ø´ê¾7?÷ì«_.yÆ8ÕW·¾¼ï#Sg³ÅÔѾ=O¿R2 GϾ1>;8;?Þ?zô —7Dà׃~_ð›/ýùÙáCªª™V)­ï=ò➌…j&f‡öy!•›KMœ>÷v*;ûú¡gù­Š>CD=ÔÕ²öÛÿö7ûŽOáªi W‹fþ™WÿζÍCg^µÛ=µQ4ršê«Ž6<ÿúWÇg9cóééû,ÛxéÍv„sèÌk™üü‘3¯Ï Üö§œˆ1ÖPÓÞ7rä/ý9"¦²³'ÞBÄïïû¦a•úGMÏ^¦D ÆCèÓ¯|é­ã/ù´À¡3¯¦s ×HÜ=)¦}Eˆ€4Õ×ÚÐóúÁg¾óÿ ù¢¶c†ƒ1¿xîõ¯ŒNŒM÷NõI)È–”rCÏ=ßúþ_=û†¦úlÛ|éͶlãÀÉË’–m:Ž-¤R@}¼å­/¿~øÙH0þæÑ$I""’/¼þµ}ǾçÓkWì(”rßüÞŸ>óš$i;–”B’Øòû%#zè`ÿè1"²mKHGH!¤¬ŠÔ犩öü}23{r`_*7'I0ÆÏMœúÞ›ÿØ?z´«ymkÝÊ×?ûWþg23íŠÑ²KD”+$÷{Év̽‡ŸOeçN ˜MŽßðC7’dwÛ¦þÑcßùÁÿLåùbæÃÏÛŽµïøK…Rvß±ïåŠék;€F$×víø·ýÿòâÞp„åžÒj¬mîõ/'ÒS³Cs© !ÊþΔ–ºÏ¿þÕáÉÓŒ±L~þðÙ×-Ûxá¯q¦8ÂqDYª U¿~øÙW~'à Oœ¶m §çGÏJffÞ8üœe›o)WL]¦æDòGª"õϾúw?<ø€/räìó™éûF¦Ïº#¼i¯ùðÝ• )º¯Eá¡‘3¿˜ú–ª×I‘„×ä3oOžûï$­LòBö8 !Šº¿ƒHŽö}!—~“3&¹7=û¢Q蟟úßDv.µoèäçOü'!J¡Ø6Moøb)w¦˜?k“ÂN ø¥bþ4ã:ãÁÚÆ'gž–N‘+¡s§~}là‹ŒHnˆÛšSõ"9röóÅìq)ŒPt«¢Õ üܹS¿&ì¬æk©kþÄð™ßž:÷þP¯¢VIQ’2-xy¬ÿŠùSªV­y`ôÌï$§Ÿ&²‰l) ’Ò’$…ÅPdcfþÕáÓ¿‘N¼Â˜.EÑ­ÀÜä×…Sø"#iWb¯pòº¿]Ø©±þß#içRûK…³$’¢¤êu¾ÀŠs§}nòLŠ"" WÝ=;ñC'Å2Æ+/²’WˆÈ!r(Ý>Ú÷{Å܉R¡¿TÒ’&‘Ì&÷Ž üA>½ßìvœŒªÕÐÈÙߢϴ̙™±¯˜Åa)KÁðú\rïÈÙÏQ ¼ÑõmI!ŠšÞ­Ù=têWÏúu΃º¿¤EÒtYR8®FK…¾TâeÏ;ãqûÍD°öž/üÑÞÚÕÞÑÙÙÑÙµåž'?ûËÿñÑÍÊò7æ %O\7Îù™Ó§Jźu넸՟4‰(—ËE£Ñ÷l¨ÑëÓét,ó¤wm¢‹F£·àA%«ðß¾÷³ñ©ûæùËPÄû|~-V:²¯Ÿ+åy Iª®p…²Fu}dr4¡ª\ÓUÇ ­5³É\¶ˆˆº®˜¦#¥l[Ù0|fjýÎÎ`Ø·÷åS«šr™|(ìÏeJ…\I.Ið ûòÙ’ûÅ[Õ•ªÚÈôØ]WÍK´”üÍÔS‰Üâ³6¶TŸ›Õýšc‹‹V‘1ŽåêI†Ì]f/œ~pOUH)9WlÛœJŒ„Ñ©¹a[X›WÝ'I$Ƙ”[Ò…ÁGɪ4®õ5nLW²Wî8âRï”úæøÔØ|UMÈôÍN¦ªâá\¶h™cèh…¼yáò“ˆBÑ"äÒEDDD7ID”RrÆ%I$"IDѪ Ï¯+*ŸIœW¦{ØÇuð!²%FâêqY\D µ|μ躘!CÆÜþX> °ð­ݾHR ÷‰Cc'«¢u™\"™]·r§¦ø¤®ürI‹ŠFdŒ1X<7G®±¹î·á•hJä€ën`Ì5Tt·K¹m\4iΗ~U$’î-®!¹ÚÇÊ#Ü9SÜ@3î ³ÄZä;¾ÚÜ‘pt`Ú™-%Õ7WÍL¤Æ7"uǶå,vêEå"^ꡈXߟM,-—v«@P·mDZŢHݦ¹6³D€îÐMs&¤39{.à%R“ÙbfÇÚ‡%ÉÊëö2ZIc¸ü묔¢¼‡‰– Í­¹²sUãcOíüòŸ>o™ÎÒí³¤r)á/;ÏE Òk²#›‹” yÝ~,¸nök@D•#HÒvOÄPrö»‘ø½é¹áuÐ7‹ Š1ma›I§\, +—\þº-Xåð‘@`îÓI D ‰$2¤½¤bD$.ø/w`*+…Ùˆ€x¥'º-Z‘@·¨r$¼b>»^D^¹R”{ 7_€dËÏœUjTn©[^ù­AåP/D•Â"@®„H *牋ÈFTʧäÄdE˜T¹$#•¶¸r^ÚW#l™‰D•È)«9¼þX3ù}ñwZ?ðX½mËK™]*•ªªªò¦Ê×Öiï,é1Æ.ïbVUõ«_ýj{{û®]»ç"{`‘)…Ùïæ#_˜òJÇ6Nû™ÿñÕ_ÿăá,•‚kÆÃÃÃÃãV8L—Ùp_ÇîüéŽ8róD±lubÉebÑ›r5Å/•§p¿”^$m -UÁ­D.«ž€‹JCÇÍ |føg|Óª{…pÜ5žÛ@rÿ¾sÂ=‘ ç<”ÛreJ^*:·á‹Fr•r$AHXfaò¢ODd¡@ôäà>] ¬l]¯pÍÝÖäÊ_,OƒB$…¸ˆ±‰%¸ôQ©¶,k“.fñï/ç»—¹[ÉEAÝdk¹@¹p£J$¥Gp¡Ì—¶—såìðaΕõ+ïÒYjcç‰KJyÓ²a®ld¾˜Yµ™åµÊÞYb3²âX<ôSéoÒÍñN¾+%YSÕTo7Œ'“Û–Æšö¦ÚΊ¦¼þrFUí£îN wÓ‡'[3£‘"?=’s2¬YýÐÆR ;Ÿ…uâÂ`ä¹f<<<<îÔyæ¿®ðg×t^M×ÿ¸[SÈE ë{ þ;˜÷ã%[zk"I’pí¾ººnrõƀ˞…7Zö×Y&ݨŠ-Û¸ñœP_¤ÐuëåÒJÇw«¿Üº‘•ˆÊßê·&9ÞÔÁã ìÄ“Ç ?/Ìîý¥'w6QÈ‘§~j÷ëÏNoùù_~¤>ìT"x®;qâ`ûIº‰Ê~7bÅ¢÷Ý=#^™»ÿÀÊŸòo*×Vn©\\¾ÞÍk‰D•eCåWKþí¿Èº®¦Q•Uª±8OÂ…ªÂbͱü«JbŸÅåšÊ9úKÖdIR ‹­dE¸¬b—Yð–åITÎD7!Æñ­ØCR¶‹Çšóuäþ§"´«TýŸXc¹_^Ñ$»Ò5.ZkWûr±§,šÀ‰KнÒj/Ho1ÍÉ5«ïjíqžºÒ yѯÖñµ0J_j8Zb`·•êˆÞÁÚ¯Ø%ƒ€Èˆi jº$гPÛ™ô¶Uyܰ!T:¡Ú‡¾öÚý¦Q²…àšÏ¯k(¢³$’£çšñððð¸ªõýæ«”œÈ€D´pTépMð¬­*' Iò9Š,ï(~‡çME®+ªecL(y[ÉY*"تfØ %%k«†Pɳ¶Z²yÁV˜£ä%ï(R,qÍØjήçCeŠÏæ9[=/ pQðœ­rºâ|(6WmG ‡‘ßQr¶Z,lÅ,o©Ð=^_³âNù6+¥(”ÒŽcU× e(yÃÌ1¦Dõ7¼ÕˆX4r†‘ÓT¿®,«D$³¹9Gغø£ÅRÆq,!…ßÒÔ@¾˜rÕ§i~Gت¢Ké)¤]­[Öö<àkßáoÅcÍ¡@¼ddãÁ@•m¶c2dš(–ÒD Äã…RZÛ§‡UU/•²Ž°C*ÃÌû}ᢑ ú£@ldžEÃõoæÌЫ»îÉåç…tþ¨ÂÕ’‘s„‹4¼‹úÍæBØ>=ä×Ã7#H7"Z¶Q(¦cÌÝÓd˜ù¢‘eÈÂÁjÛ1-«(I*ŠôÇŠ¥¬i8SÜ~T,e‚X&7 T)\½wûO4ÖuŒ¼}ü̿ݽù#â:òf¡ddY,ÒðžZŠ#bf~N ŒÄ¤”±ÛÎ¥æ¥#ü¡°ªëÅ\–ˆ¤áX ÙŒŽ¢jšÏo%(l–ŠŒ+Žm÷î¼§gË×Ç!„È$æ™cÛþP¨º©†Žql»¦©¥½wíÚ]÷ Û~õ[ÿÜÒÓ ’Šùc,‰(šžMÎ Ç D"ÒÝóB”KÎ"Q£·-SÑô@8RÌf„$¥/ÔÁ\*IB²™`$Úwð-Çvžø…_ql{ï3ÿŒÆª›…cûBá\rúèZ¿É,cîÏUMÏ¥’‘êšR>Çuðè¡@$ŒV¹.Z"©„ŸøÃ¯ô¦t¿jd2Ÿû“ß¿kG Ú¶çšñðððð¸¥0Æ'¦OŸ?êÓƒ±pCgë&Ä÷èŒ!›ž=ôÇBÁj!lDLggƧOq®ál^ó˜W±LBÄé¹ÁÑÉ£ªâ‹Çšãˆl&q.›Ÿs}"‘PÍéÁ7:š7ÌÎtw옜í㌗Œ¼ö–uPnÉ®)ÅcÏÔVw”ŒlOç]œ©†™<®kщã;6~ødÿý¾°¦úM«ÐÖ´¾x,Òpvhïö OI] êZpv~Ø]{»ßfUE¿³Vqóéñáñ£>=DD›Ö·8 Rå\-–RuÕ™ÜìÄô™U+vf¾PLkª/ªÕ}&q.¬šKíïlÙ|ää‹ u+»Z·Ì%GêºgC-›ÐÍzFBSýRÊtvfbæ¬_ Žìnß±ÿèwjW¼[®D6Ÿ;;´×õövßw3º ޼íËvÌšªVΆ|tâ¥2S+Ú¶eós#“ÇÛ›7LÎôݵùÉç^¬Š6Î͇C5ëzœnÓ×OLŸYÕu7 iª®+]7Úv©ïÜ>šÞµåÇþÈ{ä "æRÉÃ?x)ÞØ¤é~(„ŒçRÉÑ3§áÈü‘·×ì¼çí—žoééMNO¶®êÕtßðéÑêš#7?ô#F¡Ðع"=7«¨*2FB.ìs$!¾ÿO_Þòðc3£çáˆ/,d2umíf©˜M&Ð6ÍÔìôàÑC–aÔ¶´ù‚¡þCûI’Y*Fâ5‘êê3ûß Ç«‘1EÓUë;šnîêžì Åâùt²µ§÷Ô[{j›Û,ÓÐt_ëªÞƒ/¿ÐÒ³zêÜ`Ï–#§OÜó£%)U]µýîþCû‰(ŸNöî|ßÞç¾½ñþ‡R³Ó–iì{áé6;–¥êz{ﺽÏþëã?÷Ë£§O£‘äì0tlKóù½4ÔîkÂ.Ž~û¯þ6ø¡ß\?úÃ?ù¿Î5®.êÿé‘õun* Ï5ãááááqëÞIg÷nßø!¿.™¹÷´(ïÙ¿¶ûþH¸Î4ó#o€¢èBØRŠ‘‰ã[Ö¾ÿjËŸ>ÙÕ¶µ¦ª­hd'¦O#¢ªúlÛÒ¶l#®­Š4tµm#¢©¹þb)½mýóÅTßÐ^¼UÚOfÆ9W6¬~8Q¸F 9S2Ã,ä‹É\>¡©¾–†55ñÖ_ýËêXk}M×ÊöícS'¨±¶[’DÄÎÖÍÉôD:;}àØÓR:>= ×ß!Û¯PH1Ÿkªëim\3Ÿž¸úÍX42RŠõ«.4§9ã7v½ƒÈÒÙiË*­_ýH67Ë#’Œ+ˆÌ´Šƒ#îÛþ“ ×jW¶4®yúå?î06UE×v?07?Ìoªïv[„ȦçǧOJi)` ª*Ú˜ÍÏå ©|! V#²†º•mëNôÿд uÝÁ@|`x_:7‹ §fúâÑæh¤¾§ónMõw´lDd+Ú¶P®8rêEMógó‰][~Ì0 R:¦Uœ›?×ݾ#®[ÕµË=RqëµËOŸnoÙØ\¿:›ŸÃ›£KF.•™Úºþ yÉÌͧÆ@Ó™ÜlÉÈ¥2“ТׯÛW¯xßÌÜm†‘Û°ó“§ú_-•²>-è:Ä{W¾OJaYÅ}¯ŒŒÍRë{–R^k­À° ¦Uزöý­Yv£ÍòöÉÙ虓m«×u­ß˜Ï¤S3S ¨*IiÅ™‘s½;w…ªâm«×FªkfF†ÂñšæÝ-ݽãýg9WÚ{×@CGãü܉£Ã'eæf¥”5Í­Í+{|ÁðÊMÛ„ãøCáÖžÕ/ýý—:»M‹V×êþ@0ãŠê…5¿ovdØÈå|`zn¦˜Ëªš–K%Úz×6­è)¤SÓÃCsc¶iìzüÉ‘Ó'fÇFÙÜøX¨*ÎïX·Á,‡OŸªªkXµí. )…p| $ùAË0cntUÓu_ ¡½3^ßè ;×m”BœÚ÷†ešÏŒsEÕª›kšZÊ…xxxòböÄátÛon«}ëÿýûñÇ~õ³ñ¯8´sÃû# ½0À·GšâSUŸªèÊÁ&Ϩ¿—DaiŠ_嚪Q¸*¥87v¨ºªµ:Ö25Ûïîc/Ú§rªžËËÇ6gªªúbšbê´»„ki\ã×C'ú~Dšê'’Œ1Ç1Ý8Á ×¹ºbY˜€›»ÑvLUñ@$Të8f Û1{WÜ›JOH¼ä€$IÎøÂD€Œ3"`ŒQ8X½¶û~Î…kŠ¢WBl,šÓmªu"G8Œqd¼ºªÅ=_¶Tòî'óË@œ© ×I’‹ƒ®ÌH®XG Æ…° `61ĹºjÅ=#ˆ1ÅÝ솒g ø|!bÈ"0äD²¾¦«»c'犪øL«xnìÈ®­?6Ÿ+™yòi!XÕyw"=Þ7ôf(ç\[Ѷ­®ºcU×=™ìt¾0_ÉÇ]½Ké|ÑU]»‚*Ƙµ¡Ñƒ±p}Kãšá‰£D¤«Š*±onéÀ"¤­)~ÆX4\çz©–+—nÄ#×Ôu- ªåQôìÐÞûv|r|úI ˆœ«n$W2UÑ d€À'"Î)…ªøZ›ÖÕTµ!¢®ÊÉñ…WìZB"É#b4T»Ì,oÿ.yë,@Û4#Õ:ãJ´º&;Ÿpl{zd(TUÕÞ»~øäq RuÀ5`""ÆðCÀ8—B0Æc$eÓŠž®õ›ˆ€+ çœ+ܽ‘1¶• ÜNDD2«ªoïäœ'§§ÆúÏ$&F×Ýs)—›ŸšŽ£ê~ÆX¤º615‘™›qŸîØöŠõ››»{VmÛɸ2}n‘‘$°ËŽTuéþ@zn&V[ˆ™d"X|ãær”@$¥"RuÝ,•ˆ–ÓY¬¦7íñðXö‚‚^<þ‘ü'~sCÿþâ¤%éüodÞ!@›½,•­ëGß›<~¢ÿ•tv&‘³ìb"5F$'¦ÏÜÞ…n°(Zê{ÇNÌœ9~æû…R†H a!â\r8_˜/Ó‰ä¨ö|j¼PJK™tfúòk„úꎙÄàØä‰GŸaŒ9–RÉÉÙ~Û1JFÖ%K)‚ÿ?{ï\Y’d‰¹GÄOãZË@jQY™¥[LË™©mÎls»6ckKÈþð“?4~?¤Ñ(Œ\[®èÙéž–5]ÕU]]2%Rg"ZãiýîçÇ}@"UUêÌêºÇ`°‡‡{#<Ü=üFøu÷Ä0[ØØHÍéj­¸žœÑZm¦æ¥t2Ù•|1õÄ«ÏQs¼;›_ËdWÎ\øy®°A¤µ’X© ¥T©’ÓZ·¨·­P.¿‘É­®%gcùÂF¹’wÝj*³ìU·´­°mE87Ö“7•r3¹µ|1YsÊkÉ™ö ^ÎEc¬-“[Mg–Þÿäÿv¥7¶¼vMk•Í­•*™/$ž,3XsÊ©Ìâ§ç~²¶y#]©9¥Tf©XÉÖœb*³ô8“ˆˆ:ÊÕl&»ráêo7ÓóäÊ"¤3K•JÞs—i RZYf¨PJer+ëÉÌ6jN±TÉeóëÀ™°­°m…97”rÈq+ëÉ™j­PsÊ^Ëó+âž±o–*Ù†Hk±”vemêòo ~¾:N5]–²–Ê.iÒ`™¡€6€ÖJ*—€Ö6ojí–*푑ͯ—*ÙtvE“^YŸ~6¥O¨9Þ;¿2µ™š?}ñçéìÊzjn{Z­mθ²ö˜‡˜Q(3Í@6·:¿|þòôïr­•ãVµ–ÅR*_Ji%½ñ*-Mak­6Ó ÉÌ¢")¥“Ê,k­×“³@ M#°#–,–ÒÙüzµV\OÍédf©Z+>ðÙØä‰c3=ÿÙÔXݘNçV«µB:»R(¥= ¯”ü£´äštÇàðÒôÕ…¹³ï½S.äµVÊu`sqÞub.KZiv0˜ÛÜÈn®'— ½¾¦¤›Ï¤ ™4H§æT«n­Z+—”’ZJOè^‘l%%i"ÒÂ4Ëùœ[«UKÅ|j3»±^̤ƒá°VJ¹îÚüL¥TŒ4&¯]Ú\^<û»wr›ƒûî{ígß'o,ÍWË¥…kWò©Mo.‘R2ÞÒº¹4ŸÝX]º~Ek=yüµÏ~õ³ÌúêúÂܵ“ŸN¢R,ä’›¹T#¥*¥".]¿š^]†ŠÆœJ%ŸNæRI­´F9ŸS® >|ø¨Ûpi|å[üoÿ—sGþå‰@þƒÿsáèáWA’ïšñáÇÏt«õÈÀKD”+lö´OQ©œQJ–Ê"Ê7¿>Å#µV= a¥²Ëmc=ã ѶžC¹ÂFÀŠìÝýítv©XÎ*­J•lÍ)KY«ÔŠ_TU”¨§càf:·²kàXC´­£e¤§sb#5g[¡ÎÖQ@lnê„X´­¹©·51°žœ)W –RZŠI*”RJËr5_­syO…°&Gßš]:×ÜÔ %zFÃÍ–XY¿v`â{ÔÒÔg›a"=Ø{(ŒèÕë±ÁÍR%[sJR9¹âzÀŽz#ò^—ÊY"]®æ¼ ÅäS þ mÞ}¶š_¹°oüÛ®[­Ts/mj­ªNIÊÚ—íÌú»÷­%gâÑöæÆÞB)¥”[ªd§,¥[,g4©Ç’7÷Ž}{vé\$ܵönoÀB9utÿŸ§³Ë-MýÁ@L“Ú5p̶†°W6®‡CMB˜ÅJÆ+4“+n„ƒ‰Æžm…CMƒ½‡—×®${V$lŒE[97¢¡ÄzrvaåÂÞÑo¶$ú…0gæOu·‡‚ ­‰Î…+kùbR*'“[‚¾®½B˜ÞfU³§c¢XÎHU›y³V+µ&97*ÕBµVpeµTÉéb9ùl ‹Öª«},ëXÙ˜înŸ0Í`¡°¹=­Jå´Rîãû ùpßÑTv¹TÍõwïon쵬ÐÄÈësËSÍ}‘Pc$œhŠwk­ºÛws.ºÚF—ׯj­VD*·PÚÔ¤R¹%d¼½y8`Gˆ48nµæ”]Y+Sže–ªö€Óˆˆl+<Ø{p35 5µ&Š¥””N¹š«ÕJJÉRÉSKüã³ä¤uKO_¢³km~¦k×X¢£«c`¨c`¸Z*Ö*å='Þ(çóm}œ‹@$ÚÜÝmL¸Nm}~&ÞÚÎ9/¤“Jªr.SÊgã­mŒ‹¹Ëçç._¸zÉ©V‡ÑJÆÍ¡hŒ4 ìÙŠÆÂ í}ƒ€HZ‡𖦝-N_Ú{°sx´wlreæF¼¹-Ú˜hî쎷¶¯ÍÞìéÄ›Zº{í]‘xcçð®ÅëW ÓŒ65w 2Î ÛnîìItv÷Œ/ߘnëE={N¼>åÒÚìÍ=¯¼ŒD"ñ&+X™¹>ñò«p¤¥·¿R(H§…Lªbî:ôÒâµËÑÆ¦pCcçð.¥Tµ\za}å>|<{“Á ßýïÿÕO~öoþ¯ÿòDÐjú§ÿËÿðýƒ êΚü„&>|øðñôJ ÅÄ®7€H`cC‘îëܧIï~íë5ˆ¸{øU/ iõ¾llèÒí­#^iÝÛ1é§‹¶~Á“€LÃ:€D*Œ{ß·4 lg%x›äæÆ^†,“[UÊUÊÇÚ¢­ ÑV­õ`ï!"ÝÕ6FOç\­UWëXwÛn"­‡ûŽéÑ¡ÞÚ[†½ó¤5é‘þ—²ù ­•#«œ‹X´Õ–÷êx û‘î ÆµV„È{i­»ZG=Fô¿ôÂ*YF`¨ïzyá`\“Þ=ôªÖº­yèA]N4ö67õÖº¯s…ƒ@‘P£~<Ái­ZíÍCD¤‡ûéÉ]oÝÊm!" ¥äèÀñB9­I¹nUk•ˆw†M¤½SÚ (Nlk‘îëÚ{+ˆt¢±§¹©oË ÀpßÒÔÕÓ¤CÁX8´ŸH÷ÑZô$/´ €ˆ¢mñXÇNÚ4é¶æAï¯x´]í8þ õ‡zoàMÃýG·§ÕPß"ýøùD:NŒ¼î}îj#¢žƒ·q@)·¯kŸW1D*·æ”[ƒ–ìï> u]ߺÛÇiKß:½›c‘f­•§WEmcCWS¼ÇSËÞŽIІÞ”ìëÚçiûéVKo«ñ–V"ùÕÛd¦)oŒ55g6×´RNµj˜vCsk¢³›´nëªó°­ãÖIçZï?¬¤lêè"­Õоƒ¤µwîõø±W€¨}`hëèzÒJu ï­§òiil‚©©¤©b‘Ž44vŒ&Ý·{Ö* ‡F´¦þ‰}Ûƒ’®ÓÞ?Ô10â=´Öv04rðèöÝãÜ0N¿÷ëž± θÖZI9°gÿöoi#­ý´&>vZ Á¶î‘ÖD€èÊ{<µ}׌>|øx6O%yÛ€@A=áë…»‡\ßÊlÿÞ±¨ý’Õ­·<¿ãâ»=,DZuµ9N‘YVHëú®É£‡žæJ“ºµöºÛŽòØÑ­R2ˆ õÑZöÜÜæ•w=íˆ ñþ¥·w ôB+Òíbªs»ÎùÛÀém±êzEµ³µÇßü«[.°{d£(-Vx°÷Vr çÖ–Œ¶‡A_¬íwŒåÙmû_vJüŽFî¸ý§û÷ûl&õNšŸ Znóä—î5F¯ßžƒRÖñ Ýž}wL™Û˜æÑüð¾{©åÖ”„?rÛ¾³Ìmý¡¦î¶í ” Çâƒ{h¥ ËæBÔoܶ]wÜ¢Ô–cg/tÏöàŽBÎw_s·ÑõÉUwÃÝQ¯Wk  oS¼ÛFJä8oýåâåCÝÍŠÞûðñ¼Ö¤¿ìqï»f|øðáǯ˺ÀÓl-Ó_ÄWšŒñ` zǾÑÇ D´}½Ð°ÍX!ð#^³Æy0²=e¾ò!¢`$ê«–O¾kƇ>¾Š #pªR‡ BÜŠ¶ @MLoÕÓ@¬)M¸”˜w”Pý_õã^wìÖë9â´#”cç2Œ¡Þ Rýç®w;~?È~o»ºW#èLÀpF í¼˜5xÃGD[ƒÐÀv²e'0 {çÃk`¸Í¤B½o$Àm¶?y%xäEõn¿¿¨otw\€TÿÞ-ǧAâ‹Aa=×àA(Á-Áݓ՚PÛþ!BÜR/ÜVÝ;ïÂ;?<€L=޷͇dÒÓ3AÔ»²ºw‰øžÊÿÐíÓ}l ÜË–>JO> Ž0MüKˆb¤ÁѲâºl» ‚à\°¯@̺y¿  ¤íyÏè®)C„/ê "†°CÀ·Îܺ[Áðxþû^'¾kƇ>|<ئÈ4Å_þõÑKW–VrYΙkk×RÂ<ÙoÜ`Fݶ“¦˜h͎̚ ÒÒn@Ìb´à˜q×Ö®£‘”CŠˆ¤¥Ý V†VB;íZÚµ´´´kk×ÕZßJ±qmí¸   t-í4c·VjJiej7 5ˆu;·™ëj¥´&’^›[':+[ExÖ¶ Ša‚¯÷7±…³¶v@iNØÈ’bћșf:.š¼­n‚¯÷›7™àwwY3ª&«Öóö·= œj6õ”gƒ¦plÒ.hÇÖ®¥Ý€¶vP}Ѻ\ I©¤¥\©Ü€~²Õ½#‚ŸÁ­ûŽ”ˆ„­¤­ÜÀ­  d(-í·™+ÔsÜz(‘"-†«ñPm½Äù—ï÷H€”÷QbA1#n¶il¢Ù• ˜*ÆÐµêsán¹–FD7 PˆÈµµ°̱Õ㨠"¸–vʯÄù°ÐZ{Ö’1Z“kiǾe߈Ȱ•”Úe]ãÑ3Å·YË `ØÊåÚ/V,’RZšš1ÙkÌ:ÊEöHJE‘9;纺Å|{ìøÎ+Mtáê«3ó2[Ÿïó7å|í~en ÛÊ ‘EƒÂb›¥w6a6'’\8Z¿P““"\ð¥Õܺ7’(ÑN¦‹_33BŠˆ‘¿Göá»f|øðáÃǃØnƒ96¼‘ÏÕ„2M†V†v óL‹˜EnÖ¯c:ÄkE‘†% íš †n’++Æ^ijij@†’i­•A®©• -ȵ´4I™Z ’Ió–k†¤©¥¥˜©•AÒª»Q]Q6йÇ ¹&%ĉv×´´«µaioÔÒ$I÷ †!0PkR\K“¤CÒ|ò®zº•a¼n€ß¤$Mí)ÆöÀCOjÒ$‰ô+\‚@™7TË}öƒ(!€’ë{rÕÖ(–I,‡yÉäa&–J"ê˜M’4C¶=îÅ"B|ÐTç*tÏ6ÎpÂ||‰BkÏZz.‚ºPvØ7’I¦]xè 8DP†¾ÃZÞ¡3.j_¬M»TZÄP%ø‚5ÀGóž4,O¦@©qh÷.!¶Â”Ò¹dúúÕëÂ0^ð]{$ ª1·ZÊâ}øÀEœ†– A‚ˆÁb§ÞYu‡4™±hÁ´KR¾PRÖ–i™óU]®»•¦PKd¥\åìkdF¶:þÙ‡ïšñáDzt RjËW²•¦äEQkàl+s‡¶šn…åÝZgÝJØÙþ†ê‰Û1üxçž}ë_x{lÿc.Þè‘t·Ÿ NQ=¡IGDòFz«ú(j`€Q=™ËãÃml¹½Ovï°l¢­m±â~ ¹ƒÐ­+¿|׆[1Aï6y !">ºä‹GJxGžÎm 8š3…OÉ}ƒ€¤‘àÁÚÿy1 \£ú—´…uIн Ûúú0bÝ‘Á÷˜N|¨FGˆ·úÄj!î ý™ºù}”Ú IDAT°žP†·”™n·o[ª‚ÖüXKBزt÷<7GL¸Ã`j࡚¤¡ PJ᎑h­½cKî0k!ëù8¸£Ìí“´À¸­x?>xbÒ è>ù²D„´3çéþ½1FDX?üëik>€ÞVA„­´V|(C†õü臎í|fá é¢ñáÃwÍøðáÇä@ÄR1ø"Oc=ªµ*Ó‘hó‹ÊÊg7ÃÑ&Dæ+ÃsWÅ|v#idŒ?´‰JÅLµRÎH,Á¹ùØerЭ•ó¹Mï¯p4aÛ!¿æ("òIÓ švða½3žµ©”óÀ¸ˆDš Ó~‘Yê:ŽãÔ<÷@(ü «•r!—õ-²ÁH¬á bÖ*å²”n$Ûn_º.2Æ9!¸@TZœ´¶W3i»¹å+¡£NµäÖ*¦TÒ „c®cN¥¤” >Ì->|üñÁ_ùðáÇg±dã\p.ü}ø6+ó3ç6Wo2ÆŸ s¶[“®syê]@dÌ+¯ùBl6™G]8û%]`Æ 2Æl‹ZdŒsÁ˜`Œ#â 2„GÞW³Ç“r\µ¶r½O.Í_^¼LZïÓ£Qp.žhD–˦g¯_»y}inFˆzŠçœ1ƹ§›a/B5bD­ÔÿãuKÅõ÷‹Bxá+È9 B0a0a Ì0CΑ1â9Z¹lrùÆ…³©•Õ…+\uÓ·Ãì°*¸­¥ŒñôÆÂêü¥íkÐßúl›Ðºù¶Ý¨?/!c^Ëþ’ËÇW~ÔŒ>|øxê 6­ä™ÏþŽ!ë>ÜÐØþ5~-†DêÌg¿ÐZöÂd\ ©éË)éônLt?Nà:‘^š¿²¼p©1ÑÕ3°OKIçæÓùÜf,ÞÖ?tèùVsdŒ'7æg®‰&z÷† ˆ‹óÖ—¯›Vp÷ž·VWod3«®S‰ÅÛûl®Î,ÌNEcÍÈE[ûP*¹ÐÝ·ç«èÝCÄjµ4;}²Û=öhR^_ž^œ¿DÆ÷‹´z|’Ê¥Üå©wM;8´ë%ô1¹1?ó ŽíySºÕ¹§@´çàwÒÉř럇£Í®Sé:¸²x¥oðÀùÓ¿Ý5ñšFgïxsk&¹4{ãtkÇÐÍkŸUËù¦Ö¾Îîñ›×>©”óÍ­ýÙÌZ±lnéïØ·8w~smÖ²C»÷½µ¹6»87ÕÚ>\È';ºGóÙP8ŽŒ·uíÚuL“úõßþN­¼¹6³¶2ÍŸ<ø'™Å…¹©Ö¶!Ó.ÌNqnŒì>Á…yõÂ{ZëÞýñ¦®g™@DWο[*f:zÆÛ;w=ÁÜDtÚù3¿bŒÂDÆ3©åÙ§¤ëŒíyC)¹²p]éLìûf>»>{ã4c,jhní__¹60|ôꕺúö0ÆzöÇâm©ù¹›gÚ»Fg.~P.çšš{ºz'9ÖéæFòÌÜ¢mŠîŸTšžàÀ=G cü̧Žï? Dg?û¨µ£kcuÙujÍ­ÙtJ˜Æèľ«Îõ–KÅj¥Ì…héèÚ½ï ÖúÔGd’›ÁPøÌÉOªåR÷ÀpwßÀÚÒâôÕ‹ ñ&Dììí¯U+k+7®\dÈ:ûgoäR©oüéÛÂÏ=£x à97>ü]|rS§O»ù Êb‘ a44”æç:¿÷gNj³–N::Ò§?ïúá_”ÏÉÖ1. Æx)Ÿ¼qá=#]§º¾xÍ©– Ó*æRPTk]«Ç{öÊɆDG1—†Å…Á¹¨UK×Ͻ¯”ÛÖ;ÖÚµëÆùß—‹Ó ¶t‡š/Ÿü uôM´vïZž9¿ù°ïä±XH­,]›|2©åÇçc|êô/wM¼ÚÞ±+\&­È©•wmLtÏ^?é:5éÖÆ&ߨX›)ä“ó³S=ã‘Xbaö\ ëèã\ æÜ %éÖrÙuË9Õr$Ö¼küÕÔÆB>»¾8{¾ø0çg|ÿ‘jRÅ|*›YßÿM¥äÒÜ…R1‰6·uŽt÷Mƒ MÍ=áh3i¥¤t ¹$2†Èh×ø+–Zœ™ònéè¿zþý‘±]½Z«+Sï¶vŒ Œ™¾ò±RÎ3{sΟ¿yíy3›^©V OÐÊ¿tîÚ;wuõL¤“ ®¬‘ÖŽSíéß×?räòÔ{Ò­ ©þáõJa}ezuéj{çHïà™ëŸYf «w㢧_(Ü@DJ:Ò©–KYË)éÚÈî=or›…\òhFÄ\¹2µ°ôúذ%Œ…d†= Ï/b©XHm¬m¬®8µZ>“fŒ î?wòãÝû’Ò«Ëý#£v0‹7¶´wÖZ)×q*åR©Än\¹íâéÏkÕêÕ‹çvï=+‹óÕj¥˜ÏÎ\»2¶çÀØÞƒœóH4¶{ÿ!Ã0^¨}=³,·P(ÌÍhÇÉ_»BZ—æÚ^+ãºo ´wdÎttF‡¬xSâè Pê9SL޵¤7•tªåBµœwj%DÞ7vdmájçÀžBv£Z)´õŒ†¢M‰öÆ–/ŒëÆùÛûv÷]_¸6{ù“ÔÚÜèo²Éj¥P*¤ÛzÆúv^[¸šM®L_øp߉?ÓZ1Æg.}¢µJo.j­úÇ^âÂôý2>¾¢ð£f|øðáÃÇSÞ˜¦6çG'^³áæÖ­åíQ3øõYE!`:µt`ð@0Ò˜hé»4õ.(éÎ^ÿÜ0ùüæãmêPº5Ó´í@øðñ·+åÃ͹õÕùìf{ç("Þ±ôì˜ïU»²ìpOß­ÕÊÂe¨”sW¦ÞK§–ÂÑ„¦0¶FDo͉5·J§Ù†dœˆ¾Š £µ*äS‰®p¤ñè‰íðN>hAgéÖ,+ÆöüŽÖJ?vԌ֪ZÎGbÍÑX æÊâe@¨ÕÊ‹ó\§jÛÆX ³¬` ­V Zº¡p<k>êWBÁPŒˆ" -Êu‰ô…3¿ †"ÑÄðØ §VZ[¾¾±2],d”’´ÂÑ&ÆØü칩S¿>ì8åŹ)§VÆ8C‰&„0Cá8ÃôO³Ó'«•"‘>râGŢ֖® éö®Ñ@ Ž6 aô î¿xöÖŽá†ÆŽ•å«®[åÜ0 ‘a½ÆìÓ×ÄB>ÙÕ;Š4Žïû†Vê‰Ú7L§Ç÷½eÙaÆE&½®S¿À¹áÔÊkì°á@(V,¤]éXH¬¡Õ¶BLÛ ’Ö¡HÜËþ8wò– †âC£Ç„07Öf²éÕtj©³gÖ2 €£”)D<üîÞÝJ“Òú)pú‡G“k®ã Ml®­†"Q;lhL˜¦e®ëDcq¥¤c —æÞÿõ߯.-Lì?ÔÔÜrêã´RéÍÍP$âÔªoLh­“kH]}'?z¿­£{hlbsmÕ0Œ[U±ïâËó² ±Ýë¼k75±†@{'p;hm3b ²R®¬­Š`ˆ›ضMZ×)Nô¢±¥{mñš[«ÄÛ3›Kñæ..ŒHCs µ!·V5µkÒ^Èi%kÕâÍKsnà Å\2ÞÚc#í½»‰ˆ!›»zR†ãT2›‹áhÂD†&O0Æ—nN%Wg¥S‹Ä[Áèã›G>|׌>|øø£…ˆ”Ë9d¬OF£Í^EÒŠqáºUð¾6œ Û—J9ÓfS)ש*[ÎÝ<;2þŠa’›ó ”ä\(%cÞ #üAË‹ãBJÖW§Á(çb}åF$Ò<4vìÓþ5"Jé""iÒŒq­\.žÙQµdZA×­"B©˜©ÕJŒqéÖ’ëso~÷?;úW;Nñ¶Ô¨•ÔZVÊy"­•RŒ1éV…a)%ãZ+† Ù‹JƒÈ¼º˜°¼p©­cX)— S:õ±|i%ƸëV‰tjsAV EdZ+ÆzSé!IâˆLº5¥¤S+Vráæ¹coüxmùúæÚŒw: y<ÒZ•‹YïÜ­2¦¤K@ˆlÿ‘$ZûµVxãêÇ­mƒ]}“Ÿÿáß!CNZsnìÞó¦ëV?þÝ¿:|âí¾Áƒ“¾ÏnÃ\Y¼êIÜ“¯V9ÀÐè±}G~ •$¢Lz¥TH<ö®œˆéXCk{ç®k—~¿4!k|#k.ä7™ëÖ„0¥¬ ah¥áéÕ*2L»TÌ4&ºRÉÅP¸ÉKÍPÊå\Hépn<ŽËղ•r*å‚VªV-n®ÍŽï}ËukϾƒ ½›ˆˆsîÿ$¥#¥ Z)DÔJ!2©ÜC/ÿy4Ö¢I#ÀõKˆF›Çö¾yæÓ¿CD¥$l×nUö{g€!:R*­SÁyC0€ˆZCD¥µxüzºцøÍ«—‰(‹m¬®lÓé¿´M¼ÖÚ3˜Ýýƒ¯|ó;3ׯ&××´ÖñxSKGçÐØäúÊ’eÛJ*¥d¥T$­@I7Öõ›ß›¾zåüιç”®+ Ã­Õ ÓTJ!âs,@CJ…zúd>Ÿ:óytxT×j·æ&xòGÒZ+‰Èµ–ȹvfªZá–MJ‘ÖìÙžJ®µjë=ÿñßV gø@j}Þs÷‘G:i­¼3´¼ ‚ŒÀøá? G›J…ôæÊL.µJåb:o½vö½]Þ°ìÐ¥Ï 7¬T €˜Ý\²ìÐÀøËWÏü¶³2ŒJ·Æ¸ÐJ¢§üŒ ­çþž×ÇW~B“>|øxêK´‘ñW§Nþòìg?+æSéÔÒìôçåRvfú¤RòÂé_Ié|Mêöi­G]žz÷Ìg?ˤW¼åiC¼õêÅV¯” ™…Ù©™ëŸ;µòÜÓ©Í…\fmuéÊ–æ!Ë aüø'×.þ‘¹N5iÜ\Ÿ½pú×Bˆtjùڥߗ ©\v}iþB©¾ráwϬ¶.‘æÖþ3ŸýìÊùß9NUJ‡qî:Õs'^­çgÎ*íz/õñOÎ|úSÐJ’ÖŒñk?(ä6—/gRË^¦›VR)I¤MÓvemêä/ˆÔÚêt±˜"ÒˆlþæÙ«ß/ÓÁPÃÐèñ©“??õñßn¬Íh­.O½+¥3}å#ש-Í_ØX½ñ”\x¤uWïÄâÜ…3Ÿþt}u¦TL_»ø¾’îô•«•âõK>NŠ“&52þʹS¿<ûÙÏJÅ´Ò’q#n¸4õîæÚL.»¾¾rƒH‘’Ž0¬X¼íú¥¯L½g•rîÆ•”t¯^ü ŸÛ ­•t•rµ’Zëx¢smuúê…÷+åÜÆê̵KȤWR› ë«7\·váÌ;ìK½*DÑ€Ý ýôôù¿=5…§f6ò…s ‹77’ÙråÓ›sÇÅGä*)%•RJIÓ²µV¦e™¦¥¤ôâ’\Çñ”/=U,ä“ëk 37€À©Õ””m]Å|vy~vptüê…sþÃ/n\½È…ÑØÜòé¿]œ»Iš4,ÎÍœýôÙT2m†#S§>I'7.Oq÷Ì'*¥n^½´¹¶òì]À$‹%"RNqêíKü,:2ª‡\”ãÖZ*R²4?›9w¦²¾ºò›_¨juí½wd±°ô÷'+åòòbúì©gSâHK×!­”tñær) PLº5"M¤•t@IGIwáú™|zuyöÂúâ5OšÝƒû.}þ«³þíÊÜ¥D{1»qéó_%׿ Ñ14=õÁÜÕ“ÕrA¹N Ôpúƒ;séé:‰öþJ!·1Æ/~þ+שn,ßH¯/d“+³W>­”r³W>uj@¿<°¾ч>|<õµZcS×ÑWÞ‰­ ñv!ÌÞýœ‹ñýßÜøšä4éX¼íè+?""ì‡#BWß.ŒÞÁý  ÃêéßË8GÀH4ñÀû:†µ{Ï›RÖ†aï;ò!ŒXCqaÖš´&…#Œ‹‘Ý'ôSÈAøçÑðØqש"c†a7ÄÛ Ã~åÿLkÍ…¡•äÜéÖÞøÎJDMͽÁ¾†Lr1—]…㦘ØÿMÆEïÀ~.ÌÞþ}Œó'Xuõé¹¥bñö½‡¾«µ2ÌtõM¦ñ}ßÂjëAd_8 †5²ûeé:Și¬þ½\u%AÖÛ¿ïaË+h­:ºw'ZúÑ0íx¢Ksßáï)é aŒáÂhí–ní¥Wþ’ Ãuª±x›àæÆÚÍ@0ÚÓ¿ 1:ùºiwM¼ÊX] Z«öÎÑDK2Ψg`Äâm{}—ˆ87 ÓÚ½÷-%]D4Í@ÏÀ^TÊÜu´Ä8"Æ›:”Ru§^0ºÿÈ´R°¥Ë8gÈ”rwï«·c˜DŒ7¶{Ó‡s1:ñšàÆà®—„aut"=U'ÒáHâᤵò²±Bá8ÆÀÈð†Æ^6 ë‘wŤu¢¥÷ȉ·À4Í-ýŒó¶Îaé:B˜=û‘!C®Iíy“1žM¯ ½lÛ‘Sÿ$k±ƒQ.„ÇØÑÉ×½“Ñê69Ñõòë?ÄÁ]G €Hsnx‘(œ»÷½õ¥¥¦ Ààüåášt1dšAË48ƒÈP ;Øßc AöÈhnihläœ}í-ï®]“{½£˜^ûö÷qx|‘)é à ‚ššãm]J)aG^}…0^ýÖ÷IkaˆØÜÞÑ;¼+½¹¾¹¶ÚÖÑ•hiC×uдLèìé3Lktr¯aˆ}G_æœ÷ ï⌓ÖÏØj0aŒÿ·ÿ»ø¶–²ý›ßm}íÈXÞ} 53ŒÞ·ÿ’™–ÝÜZgV¢… ÑúڛܲZ^yÛÎï|_ØÖÑi·´=ƒð¤u¢­¿±¥‡qÑØÚ«¤sü;ˆÒ­í>ô-Î @œ|éû°ïÄŸsa„b ÎE(Úä™ Òš #o!"a˜¤©kh_k÷ÈüµSZë¾ÑÃí½cŒ‹¡Éˆ¬¹sÈ 1­@­Z E›Úz•rG÷¿) +Ñ1€€ˆŽ5 aõކ þ±Ü>|׌>|øðá%òÀV º·ðÎP°íð×ëÀ&"ËÕYÁ„·¶Æíehû€ ö~+.La˜ÞöË0l²ì çï\ºÕ¬i‡žíj•ãv ® †"Óª“‡†µ¦`YA­µëT§®üœsãÐËŽˆÞp<…ñøÃ¾:Çp âÖH½œ±=!¬ç¦æ-Ö1³®?Û–¤[²0lÂ2 Ë+ø²•*A¦ÒêÊ…÷•’Žþ으wÐŒmi¸× â­/½[¼4FÏPïÈÛšÛ¼V 3à)¯ƶžìlnÍ,¯5Ó Ñ—ææ<¾b×¹D°=­¼®½ßÙú¶ñ†Çj!„Y“ç#!ÂB†ˆìÚÅßKéìÞóçYîbì6KëìÚé:½ÕcèͲÁ™!ìºÍ0@0æÝdÆ#œ1¶3È0-/IleåX¶MDÞ¹ÚB"ÚÎXã¢îòî;Øv’J×ýü÷ï a¼üæ·Q^³Þ]`ˆˆ¼6í@ˆLë¹íêE( D<"fšÌ4IkfšÞ`x DèÅ7a‘0"@äÝ(ÂÏÅãýë̸`Â"`‚ˆ +à¥/mÏAïƒay#ĸQ÷õ1P>zâ(dÖ¦Ï4·$ÚûÑFhÛ/ ³›ËWN½³çå ‘6aØa”|øðáãÆ#±saDÛ¿¿†iï2íüævNÐ]Ówqøö=Ÿ ‘ÛÒmäÝF&"v÷Möô£·>Ð#1çÅš·å¡%ûJr?U$¢{È-}-mƒ µÚð¹ý·J÷þ=T¾pPÛÑ}™zÇ÷jó™wg×ObŠ=ˆ˜ˆ45&º_~ýǨiG­èÓƒÿëÎ+wÐñd”ò>}¡ŽÑ½/¾Óhô÷ ïnmçï繫¿§.ÝñážÞï–gFóº×£ç*³SãG¿ë•döªÒÜ£¢†DçñïþÍ-»t‡¶?w úðá»f|øðáÇ_uh­ü³6^i¥´Ï_L_}«¢Aû,úŠKI_ç}|­à»f|øðá㫼ÇúB”ŒÓ½rÉ hû2B Ü G ¨ÿ&ï@Úþ’nû ;§í{ëŸáŽ ¶›zˆôvòz¼uË­ÏxŸ·^Oœ³·Ó°“'÷/¹J€Þ C´óÞ'NÛÓ~ ˆ[¼½õDHumÙ¾Åi]sžçkÊztûXî˜A÷Òº[“è®:uî=¸ÔÏz¾›#?ª‹Ï¯|ùÊS×a„Ùia뚇žÛžù½¯p£å§ü ybä­ôÝöA3Tå‹}à–\ŽvŸ§C`¢&HFʗ󺦶NJ™R‚I/äè@#hD¯0F"€_'3B@[ÓÞ‡ß5ãÇ> †ÃCÃ0yX³Éê\k¡LÁ–ÛÖ@dVx0Çm[³†arËÀÀ.ò`NÈœ€É* 5ÙÌf…‚‡2"NAØÈy®òBïXK”PyÃëÊ4yÀ⡬@v«k%µYâÁŒàâ!ÖÙvÍp¥RR‘Á¬ðV„D`“@"£Â™ÜÙ rBW˜pØ=Ö˜¸š$î²@N€pX +U!舉PÖ°ƒ‚U¿P.‚k"%™ª(œ¬ñd—µˆø òÀÁ´8«÷[½\ÃVF0{k!ÁÚ1ÌvÀp]öSÕ”£Q¡UâÁ¬àüË•Ð4„ëÊ{R,5ƒÄí‹§ å„[ÕÈ0à ]0'’@ÄW" 0aKa̳5@Ä€4T^ùû‹‡…ÖdD0k0†@šaÜiß‚Òp]%œG‘‹¡¬±ÓZÞ6­¤!tÝKlJi»(P?6U„`éÝ[,C¨íè$èØÌ¾´Ì-ó…Þ·+ÝP5Çί‡ï}frLXúÙÏpÍ,fýëþÌUî-ëÁð·óËÿÓÔ•Ð%Ñ`ðpÑ‘™úaFZëXÜiÎTûéK@hº’|ãéÃwÍøðáÇ_@Ôc442uŸ³=·_ìÃíQ-[_â­‡/Šê‹’íoîx‡„@Hˆè­b¼¼Gûñæ‰hÇ-´£;77wî©x&èÖH¶ÃCvFôÜw [WÖß~?ñÈ|6ÚõEÝÑN ¹màO#Pèa‰ÇÛ]/jæžJèqï©ü[ÓsÇÔçܫ‰|Ï6JI¼ùA3>Åð–.íä$Ý2ªØòýäB;-ö‹ø¸yB Ð=‚f€5Ã{;­^ > f¨8(Èî5ƒh(ƒkÆ´p\¹Ó5£“/lmÏÛžbðõrRx¡Å¾WÛ‡ïšñáÇÏf—î×Ä{œ#Œq"z‚g?3ÆH?ÁäñÉ+gBiù(´ wh‹ç½ÐZ?Ç24äèñdÄëd™Á¸ÒŠ8c^a_Î(Mš4CÆwÍ k.1@FZyål‘sЄœoyøHKù|+Ýî´Ì¥–£É_Ð&«»Íî]?؇¾kƇ>|<o†÷&Ê_$A½* c3‹gV¸½yHác½—®78·tÎvgÛ¨®o`¨ÎûÛvø<ü 译Ê={é—‡&¨´ÚŠŽ¢¡‘å ëWo~T®d±·sooç†ì+'÷ÇÙ ?íI„€€ ”|øx$GV]Y}‚"_]•+«Ž¬éR9S­ È•UÇ­<2s¶n§R9W©HkWV]Y!ÒDZ)GʪT5Ф]Y‘²ª´û,—#J»5·"• DëÉY@”ÊqÜŠT*íJYó©j®[QÊ!ÒJ¹Þ©¨R9®[#Ò¯þñ±ýÿx#5—Î,áWÊ5#e­öRÖZ9nÅóz< )i­jnEJ—€Ö“7Ñ#ØS•my0žø”r4)¥\MZk)•[sʱHË+‡ÿÉÑ}1·4•Î.ydW Hk%UM*‡Ho+­Ç×­xR9ž&HU#"OèÕZñàÄ÷ß:þ7t}îDæÊjÍ­hÒD$•㺕ç;­¥ª9®Çœ§•A¤]YqÝå‹I­¤§®¬zê!UÍ•U¥ÐZ:nEªšÒ.IYÇ­QµZ~í­—ÿ:ë¼píÝí(§GƒÒºâºU)Ÿ^¥X©Õf1W¬U× WIM„ˆ5%5QU:Ué8JÕ”¬J—ˆ¤V®RDT“®ÁŮ掿»øÙf1wmc©»!ñÎõ³‡{†¿9²ï³—+Ní½SÿäÀkÓ,Öª/JVU¹¬Ö²Rró¹êÆ:©ZEW«•õ5íºååÅîþùèõß:»–ý÷ȹªVU¹¤]µã¨rYU*Ï$/Ëå|¾˜*35§¢µBD­•ÖÊ•Ž+kR:R9Ž[ÕZ‘+käº5¥U¡˜‘Ò%‚š[ud•ˆÑ‘U)k®¬€ÒªæVY«+ƒr¼.<3‚ˆJ9DäºUÏ’@±”ìÛ÷­×þéÈàÁNþô15܇'dÁU­æj@ÆØXK?jƇ>|<í¥&KeO_ü…e{;öôtNâ×µ"ËäVN]ø¹m…:ÛÆˆ‘¥3ËWfþ€±öÝïë‡É×@ÄÔüÅkï"â`ÏaÎC±¼qmyí*5Æ»‚vôÊÍ›ã=¹Âæäè[+×rù ©Ë îÿŽàÖ³‰5øäÌ¿cLÂÞ=tÂfµZ¸|ã÷J¹™üÚñÿÑùk¿ED ãmc¯¿gÁÔ܉ïVkÅ` °¢ +çÛ[F㜜›¡@ÃW(±S™å+7?ÔZ'»Ç‡_{ÈLteõÚÌÇùâf±”~ã¥nö“ Ð@„S~®”ù9:ø²v¥š?sé—¦”*Ù‡þêÜå_»nU¶ÁÍ‘þ—Î^þ)ìÍôüøÈë¤u4Ú\«•‹åt4œàLpn bÀŠj­¦g?+”Ó®[è9”Î.-­^êïÞϹ¹²q3ÞÓ¹Ç23‹g7 ¨·còô…ŸGÂMãÃo.®]ìíÜ{sþäî¡W9‚œ ‘¶J­˜Î.OÏ}Æ™0 »·sÏççþC(ùàž×¤Î7Ï\ú•)¬H8±{èÕ§±DÄ› g6’³šh {?g‚1>=÷Y.¿Qªd÷Ž}+[ž]8ÓÜÔ_,¥^Úÿ§/þ’HK™ÆxçøÐ«7æO÷½töò¯N|ë“ÈhŒu$Ós¼uGG©O¦gW²¹|á_¼~<`™O#<¼#ƒlaþýåχ{Úûþ÷Oßùáø‘ÿçôït ®å3±¦l¥¸§½_j%µêol=·8ùÖÅk‡ƒñÏÏýz×àÁtv=ˆ€!ÌÝ#/]»yztèÐåëŸvµ0Æ7æÎ¥3«5·Úß=‹$ÞûÃÿ×Ù1tuúäÛßÿ¯oÎMJ™B1spÏ7BÁè'§~΄ãš(ŽþÃÉŸíŸxãÊôg&Þ¼rãóѡÌqÁ…ࢱ¡µ\-¢_5ÆÇ °ö«•çÞýõ…pÿPo[sc¼!¶@k}WÕ-?jƇ>|<]0Æ/\{ïèÞ?;¶ÿíH¸éë8ûróûÇÿäØþ·ãÑ6Ï Ã¸Ñëjnìž;ÉÞi5·<56üêñCD7:ã ©Ì""FÃÍ{ƾÙÖ<´¼v5—ß8¼ç‡ï“ÖÏfÁŠÈ²ùu­ä«‡<Øs‘" ãÍM}ŽSÎÖ…0‡z¿´ïÏ—Ö®J©ÎÖÑcþ1çôvîIÄ{BÁøØÐ«DºXÎ\ŸýäÊ· 5}EòãPkµ™žïíœ|õÈcáæ‡Ý&!b©œqÜÊKûß>8ñ=WÕàIŸù•/&‹¥ä+Gþã‘þ—ÄÇÂ--‰þùåóÄ™Ñß}àØþ·WÖ¯•ʹD¼ûåƒ? bœ‰Þ®= ‘¶ÖÄÀPïa"ÚÌÌ_ŸýôÚÌÇœ‹X¤Evs¼Ç¶ÃÅRŠ3ÑÚ<4Ò¬\Í5DZFO„ «Óˆ,ï^Z½œ+lF#-&¾ 7b»Þä\”+¹› §¯Þøpiír_×^ÆxC´­51°´v#áÄ¡=?x^_†l~ij {ÿ±?jK *-Ÿxà "Vk¥äìÁÉïœüžiØÞ÷¦L4öÑTf‘!oI Ùû§ŒqÇ­æ‹›ÇýUWûCfÛ‘ÑÁ†ašüI·6·4uõæG×f>êï>@Z?2YùJ5S.¿}xÿ_ÞW“OÝUª´>Ô5´šO¯æÓ­áXÀ°Fš;ÿtü¨&zmpâDÿîbv¢½w²½/b÷ïæŒ)­wµt]\›o„ lZ©r!YÊÛÂ(:Õ\¥¼”M½síìf)Ç^Ööpÿ ›Í8™ôæG¿ùÿEëko¡©“Ÿµ­ç/þ22¼ ˆHºÉO?^{÷äg%ŽGÄ@[gtd4sö´vY*ÅFÇ»¾û§Ï’v­ÕpÿþµÍùJ­T­–£‘FÓ´N~£«}¨­¥ïøá.¬\ ¢»^6 {ÏîW›âíDˆÎ]ü]ScG([¼tmæôøèË'ßêhË ¶4uÛv(•YI¦WbÍoÿQ{KÿÈÀäb6¿°ÃÁ@äÐÞo†5¾ëeÛ )%ç—®^¾þÙ™ ïMîzYícu}<ÿiMÚ t½tl"Á’'÷Þ‡}üÙéKóëEB~‡åñ]3>|øðáã©£æ”l+b[áæ¦>ÎëE(·~­žDè8å€5@KS¿aØšÔêæ4g<mãŒ×ß×™ƒÞËÈ/nÑu*†°l+ÜÑ2¢Iלr2½`X¤…¼ó˜­ˆÖšs^sËœd˜ÆÄvãÛ¿Ÿ†³*µ‚mG ¥©ß¶ÂT®æKål4ܰcJK!,ïÐÒZ aP4ÜLDŒ Æ"p.ˆÈVC´½5106øJ(÷¢ßñÁõ\—eäÊ*gCÖÓ9éedìäü—næ5iƒ[Øš ã[öU’/•RµV²­5Å»B"ÊäV·Òi ãDšsc{ªj’‚ 5g‘1dŒ " ZÑx´­5186ô ‘^Ûœ‡£¡iÒ¡@ {‡‚—®¿¿žœÑZy½¼qìŸ1Û €'qàL€f,ÒÚkß?þÝp0žLÏ#bC´ ‘iÛ ïdÈNÞ>¸ª´cœñ¶æAÓx=?Y2¤¬yübÍM}^ÔÕâêÅh¸9l$Ò€`6‘FdJKC˜ ™e†ãˆè1Sp±X¤9mÛ=üZkb¼Â4¬Š;§¶&28gýÍMál«ã<É?éÆP´ê:çVfÇÛ{A0†È .8zU~A0ÆCÁ9ÑÉÅé·†÷Φ׉èÙËßÚµÿ›#ûn¦ÖãÍ‘Øñþ±®xb&µÎm+Ð3ÖŸÎ.VZ˜«l¬Ú;ÌÆ&-%0Æ 瀛Ï qä܈D‰ ´w»º;¿óƒÈÐpqnFU+ÁöN ápÇŸ|¿šÜ\þÍ/Tµ‚ȼУ[?OÍÐ…‚QË´WÖn†5p&ÿöÞ;X“ã¸̬jûy÷¼ïg0†pHÑSHI¤–’(iEÊyZ]¬öâvµ±Zíí®öî"tw»Ú[+Å•(‘"EA€p„!ì Æa0Þ?ï>ﺻ*óþèï½yc9‡Ñ¿˜xñ¦_wuUºªÊÎÊD!¤„%㤔¡j‡Df&!d!׿bpÓöÍR*p„iØ17ÍLg'¥Sùd<ÃL­VÝ2ê_›ˆ¥,Ó>vrOo÷¨!ÍP¶ i ""¦’¹l¦gÃê÷ n ã¡ÞA¶Fˆ€Fn`ÍwoïI¸}kVö¸jâÐkO>ùÒtK-¯J¹f"Dˆ!ÂMߘ²ÃÓsÇÊ㇎½Po–ëÍ’ÖA½YbàReê=”¢9—œš;Z®Í¼uì¹F³ÌDÕÚL6Ýç«vË«)å×Eb £$ü ÙlU¯<Û§SÝ•êL©<¹ëÍG¥0<¿Ùl•sé¾¶×ÐÚW:O¾“k'µ‚À¯Öæ4©@yÕú<3×E"Ýl–Û~ã†{g8Ÿ(–'‚ uàè+µY`ðü†mÇ“ñ|½¹&  ‰¦aµZÕ hOÏ(Ú^Ý<­u³U 7Ÿ…Üp!7â:©j}–H7[Õ–_WÚ¯ÖçoÛÀu!d2žk´Êžß|ᵿ"RõF K•ifn¶*¾ß¸â–˜MÃnyµ–W{óÈÓS³Ç­ŠÒ^($Jyf麂ј³©žrm&ZÇN¾2_<ƒµÆBÌÍ![íªR>3003³aØ-¯îûí™…SØòêJ{¾j·½:»n:Ÿ.d‡\;Ñöê­V5“êm¶kJûa˜Xxó¥³…ÜÐöMŸ›:ˆç ÃÊgÏŒï7¤ÁL¨”j¶ª!™Ùf>3ЕI'»•ökb*Ñ­t(Oi?¬FÝjךíª4­ 3—«³·¦f 'ã…©¹cÍvußá§ÊÕ™Zc™k"]©Í]ÿÉ;fp"z~s~áìÁc/!‰t©2]Èé¶ßâÄÚ4,?h·½zµ>«µZ"c­Q"“êíÊdR½žßh¶ªJyÕú×›¥@µ¯Ò;Ö”í ¨´Ú?;õV´Æ§•«SµÆÂì©+º®xõÈûŠå‰}‡Ÿ¼Ãu’]¹‘þžuû=ÕjWRñB¹:•JÀuRùì`_÷Ú½‡žŸ>sRÍVåÄÙ]š‚Óã{=¿99{l¾tö†TdfÇN¬]qß ;¿. +ËtåW¤…zcáßÛ²îÃóÅ3Éx>Œ”éίH'{ʵ™]o>šÏ IÜš=V©Nµ¼êɱ7l3–Iö„5™‰ô™ñýJûSsÇŠ¥ñf«râÌ.¸M¿ˆ2"öv­n¶*?zãëVÝßh–¦æŽàÑS¯(åÍ.œ©6æ¯@yfNÆóC}wø~Ûk²Ãg'´ZÕPHšíÊØÔA¥ƒkV"¶¬ø–u~aç×}í§’ÝÝ…ý=ëçNŸÛ½}ã'Ž~-ì±L—™{»W'bYÏoì|󑸛BNÍ­7Š ¥ñ³û;‘ˆeà îÄ”JvônعÿË´}¯¡IÅÜ´!Mbß¡'ÃÔ'ý=k*µ™ç_ûÉDÁ±“ÉD—²Ù®œßÓòjÇN¿J¬ Ùá0@†™LÃìÛxâÌΩ¹c«†îšœ9’Iõ aÌ.œš?]­ÍML&R'μ~k²éUÃw3ÓÎýdS}ˆxüÌ.MÁé±}žß<=¾×ó×­VlHsíÊûÞ:úÃco õmJÆó–鬾ëåÝßr¤4,ÃIIJL”K÷Kaô¬mßßWë Žo{S㻕öß:þ<¢H'{ i‡”ËÕ™ùÒX½Y<5¶‡HMl¶ÊWÙYfNÇÜ;†Ÿxóà|½¾ª+`|ªÔh›ž/•ëmï͉ɶRׯ“†”݉tÂvúS9S+ ½w­‰[Ž!e_2KÌC™.´ 3O›Ÿ<:7ÑðÛû&OÏÕ«íÀ¿tƒkZÛV™›xhãŽ×ÆŽþàÈžWmŽYö½Ãëÿr×-i¬.ôÍ6*'¦ÊíÆÎ±cé='j~ëY°Ö¹»vÕÒôŸÌß¹£~âØÐg>wâkV=r8±bU×}èv{âñG®naY‰«„a²¦ðHZöŽíÕ#‡^e𡟟õ%U«œøÚ'?HoÜRÜ÷F{n¶zø`ýÔ‰ \®>xí§Ø.Óñx,NÒÉ<¢ì_“Ïõwåú™¹¿w1¹NÒ¶]bì[ÓòêÇNí ïȉ]•ê\:U(Øñ™]ûž:tôÕ˜“X½rûôìéã§÷" ”ÆèЦ½þÝT2_o”“ñl:Uxîå¿íí5 Ëqâ£C›Ã€š‡_RÊ?qf_ÛkfR]ŽcÒ ÜlUÏNmµÇOïÓZ8³¯ÑªF±3Þ‘•@»Q›ši¶k»ô{Ï€þ{¾ðÅÏ­IZ´l‡µF+"U„)åáC[ÍÆæÍ›õ-ÿìÀ̵Z-NGÕò®ˆX.—3™LD½k#]:¾e¯ûÁ÷ö<öí}¦e¤SÖf{¦ÛjŠÑ‰×_†±¨ ”èê‚õSe»»'1~¦dšÒvŒ5âÕbÏÏÌŽÏW+-Dt\³Õ ˜xåÚîc‡¦ïºo4‘t~øÄ¡µë{+Õf2åTJ­z­½üûg"éÔª-DÓ–…îäÄÙ’X”©mÛ1²oçi„ß0Œa‹:#bxODRHM€™ÁuÍ@i­ˆ‰»ûÒ³SaÀ3¤Ræg>œ|ú‰?÷~eö¥ïõ%8°yÛ3oå›MúÌ/mÿø§ï~ñ|uæøáÊä$ ÁZ'û>û¯þ3?û_ÿãÙ7^_"ËrÍÆCøoóãKKUï½tüñ‡¬òž”C÷î;ík¯¸1+™tf¦«®kzÞ•¶|†!™Y)êÊ5ê­J©yþB¥€@DaP@!Ãb¡Þ…ÄY þ e,b§î¿% †u1²©aSK5G‰´@(NŽíÏoI!×®¸7ô !Â7†;ê¥Ù¶q¹‘2ƒ·â1{a¾v®c‡²gNÎÛ®¥½Ü†!—¶Ö%±(þ! 33KiVª3SsÇcNêäØî{ïøÛëžrø8¢X¢†èM3#Ê¥ ÊŠà®L•ùîwŸ]Â+Á4e\z¶R$>¾úðüØd¢P°c‰òÔ¸—Ùrd¾+ð|!Ð[šwñRŸ™Si+åfc¿Ä¦p8DZ ƒX#ˆ% drq×µ SŒ.^Ц@‰B3‘ÆE–-‡ˆÎ¯5ޱ„U¯zW¿¹„\V™9ŒÊ )ÍZcabú°ë$OœÙußöÏ:N*ŒÙéHÝù¨a^¬rÌDL ±h8¤Løêp,ˆ°Äq&B!™ÏI¢Bœk˜ˆ @Xì@hX®Å5CšW®í>ytVH"îÈLM”—ì3Ķ ´ïŸk_ #|{˜Û›Î©Õ=ÇþÁìØ™…åÖr¹ZÅã¶(u)Q G Ô±$Pv† Ø Ž#-„d¢£§_µ­ØÔÜñUÃwwçG€‰„‹ú΋,šÃˆDöùâÙ_+Z½¡÷sŸßöÜø×ç/7hB DÁÀZ‡wŠ"3€@¼0Ë%s*½ñĈó‘‡~fkïˆ^r °¢½ÿäÁGž‘¶uñd'BBÐDQ ÐD€ 5‘!„"BD±è$`HÌEXl[ ‹.‡¿hbb’(„@fФqÑl† Ô‰C:ŸGD™Ãí«³%—Ö.¢¼­½sp¿$a õÕ‡¾ès‘†ÏŽMýé#m­ñ’l6 ४èj 3³Öç&w¥@Jд.‡B ”K‘b¼xx‡”B!©ã¹fD¾ÔÊ\opãñN¨…&ˆPøideÓBˆg=Dèf&`Rif–ÂФ `¦ŽÅCÁLu¤…¢×áãÍVíðñ]©d®XšÞºñ§\';s\§ºÍBiêÔÙ=…áÁþµçl)^8—…¦·ó:"¼Œ„_à«€_üµïºw½Vúr °R©”Íf£¥òµ-_ß]Ô»rM%0Mók_ûÚÈÈÈý÷߯.™u …jM¾öÜžºt²…žþÑÃÝiÁš4ÑùDˆ*4Eˆ!B„[á2í6/î@€YÀ»¨ÎÎ #ÅâÏÍÈš.Ú¤é ï¹¼3Zóù ^êbBàBn¤ÞXˆ»™T²;¬Unç–¿ñf€HtÚ{»Ôçóö:pœd.3 ”·mÃGm+¶´É»·¼“t›ù¶¤ålº@ø®ŠòÄ7T|áØõMᑾ4l+–ÏA{Û†:N’Ηç $ö’µ¨ˆi¹Ì_Læó8Îç[ fÒ© ±†e¸Å†eùëÂÝò¢|ª'BçFÝã¥ßÛSXÙjWW ßÏ ,± ìärŽ0w\'aƒo³pXøÓ’Ø„®–E Ð7hßÅ̦ÂN2S(ðM ˆ:·-³}?-ª1->®—ÝCK> ^:tÓÑM~§,Ásç9j/ÿÓù;Àð8ÑE†°…›® tþ«—LGGäýG‹RxQÓGٹǶܾîQfî^=d™ÎV(| iö­ÉezC¡]Þòr{ÈÌ罎4DˆðN(6J»oåúxW!³©Q)3°°bŽ‘k&B„"Dx¯- ˜±L'‰,3ß–å i²CçvSn?Haä3ƒWð¼DxÇ‘Nv§“=°è'ŠáÝDÑ×½ “ÚêrsY2‘M&r‘xGxwH5 ö‹{_~® Fè5ef` 8ý¡_úôÚ„½;¹f"Dˆá]këPJFÍB“Єá¿Åõ 2ƒfЀšQ2#£fԀȨ5qç"10w®h½ìúÒ«ŸgÔŒËQ¸ôòÕ›ê¼Ã@8ü‰ÌÀ,€ß:;ÃÇűŸ#Ôr²,)]"?2  _ -’EñÒz .{$$û .u®Z¯Ñ?³l­ðã^t…‘ò9ŸÇA‚Î5_GV}•=¼|Ï ®RQœ7– é°$Zçþuä³Ãh¼‰B] 5媘ŠÙbãx]BrÙŽÝ\/n_»ºdЖ¸OçÛ·eFïZ”—.´–ÊÌ5µ|9MÇEZÔ,º®œN"L{)ãÀZëvpy Â0n}>)q~H³@®d‚€°¸t BF`„[0fF†ðØš^v.‰ëÄSi>ïèÌ3þêLú7½×j_W3Þ B„, k–D'•"Ü@5$;±öó¿½Îo5=E€Âv㎉L¬”Z~¦)rÍDˆ!»~Æ*mˆÛ†Ä˜=e÷µMÊgÚ•>S$„=ÈaÃrZ…D+íV¬¸eH×2ª-l Īf¼ÒàÛVÓ3‰¹9+ëD«Ç6ãNeC²9ìÖê(bv='* ƒ¨“Fž9îT2Lp`›†“‰Uœ@,[%)¢fŸ[^—0ÄÕæ›gà„cùZûf7+'tØ&ƒkz ¬Ž8Ú6ši,÷""f3P]¯¤M$n%¡žÇ ! dBÌ2C3•>\"Ëy4l£6Î_…1¨„Q[¯–Ðê1«2¬Û¾ lbv%©•c5½àrÅ€Ø6¤fV²pã® IDATšr=ñZCTºnlQj–BÀ-ˆ·Gp-ãr#eàÀ±Àµ+™sV!0Û+q×2¥ßÁSä€J0•›­§\ÿñBÈÀŽezºäj\¨e¡âgÑw BdÍJ:¦@¤˜]iS‰EÂE„JMàÕ–¼a™tɱM+¦w=bƒ·+u!Jxyµ/‰X35ceŒK@Ì©®X%¦–ì“kJ·õvÉ‹©®XÅò^Z­Èµ½@ùJßVŒSDW›XéÆ ¸Žbí ÊŽ÷ôôtÅSçyg±kÝŠ¿øQ!/éËíry|ï^íßÒœñô¤»Á÷—Ÿ£ä!£àª6Âeo3 ‚L ,Q£¼ø³­óM#Ð7ÝÇÁœL¸¥¤Ù´k›«NO°ÖŒ ±¤ÓhV—û6˜i0›[`òd'³†Œa¥z8§Víѹ²á8ØlüÆÊ n²!­60 I‘s&›`˜¼‰·öî?613_5S©\ïêíÛ6ââ‚•R䚉!B„w+š=ÎÙ;r®mÛjZ=¦iÝ«÷OVQ.sÍ)\HŪf޲̩p¤L29+½UÉ™.5ßvBÂ0k*ÐÌý]©³™`S_Âpí1•íͧæ[¶vì¢ç̵=½,¿ çXó-À•RÆÝñ>”ËyñÚþĸ5ÅÕ®=™¡àØmÒõ@1³‘ˆOÔeÇ5Ãà[²žmͬ«„Q.Àä( ÄLNçÓe^—ƒÕ<Î)œ‰£@$Æ Ư@©€“£(/Õ“v ëÂ…µ—³ç6eÜ1‘´§ú²Èº¨”ix–5Þ0²–] |¼ìÖb†ÔÄž¦®Bf¦aͶqC¿ì9RÀ¥SHÞÈ*¤,³ì— š¤iŽ=Q;·ˆ©tj¼›†áizLµ‚†R~£¶:5æ4­ÇHYfÝøÒŽ9à”#Ú tm˜¡.Ø“"ãë@"æk¦é]üb ˜ƒÍ«b\;ëØâD×õÅ& *מl´E䙹j7…ôI+æîBj<¯ŒpwÊË$ÇËbɾ1Cζ<­o_ –J÷²ÄK§Î9VKéÖMÖî·‹€¸;Ÿ\93ŒžÂë)p#Uæ#+Ö e þù©RPàÈ][Fwl»´ñû-wC{;q/—| tWp£l"ÐB`7‚ìñrÛ nv© "^ÙãåcÍ@%bÎûvR& ²æ®Íý3gö¢8ç9bÒù•k^äÁ¦ÙYC)ÙZ@”‚½†ýþcóno—qb¼-~Âjü2ضNMÄbóD(„ CF3n˜%Aô›³ÍÞµ _?еcž=räx:sǰ<ÿP^䚉!B„w­­'š%°Ð,‰ MH –6cÌËN^ Í b$á1(D$43‡£‰‘@†,Fׇ7,íc;w"0€aãË™‚‰…&ÁW5Ã-ïÌR›"<ÐĨY \I.zD,j– Æë£À‘½ëgÁò–o¯³Í·¯P˾ÃS^´–Æ:L9gWCÕ¸¢ø±j%.o¡IhºtËï³³ FæÐÀ^‡?3‘¦Kõô¹D×ýIh¥€/xýR…©›Sí Ö&Óòƒ@Â)çʯ#„°pø¥|p,‘å²±„³)Â5‰ ¸ÔufІԦˆ,H ¡ ó|׌ÐRvÃe-@ø)€I ¨ AWçšé0çíû8ðŠÖ/ºrÝ„bŒKÇÀ#D¸¡Ðª¸ý«Wõ–÷ËõdÚ¾3åFŒó%8rÍDˆ!B„ïˆk u«…BÛ¾) fÕl±ØmKÕ¨nìÖ'ˆ°$ªV3‰k”®FƒUhZ†ëÞ>êv›Úm!Œxßæ§yò= Ž?y;+DÝl ËB)¯‰°-j{×LØÛÌÜVÊ’F[ùqÛ~·V2F ¼¦IiþÄpG뺔1­êÒH¼Ý™üÃB¸ þÑFŠÉÓºúh¤Œ¡°£ð–·»¥°ì\28yzb¡}r׋•‰¹¡íqáÂσ‘k&B„"ÜŠ¥ggGqQÏ÷,)Pˆ‰Ç¾kº»ï°söçF… 㦂JùÔ_ÿÅšßù]"üÞÎúO€B€@¾â/þûê/}ÙˆÇÃ/ÆLEøé˜µF);“™Â¤•ïbáA¼NFtHÇ×[ w±FÃxóÿpûÿ JãB„ÛÞs,8—Ô™™QÊ R>òŸþ}lp)ðû?þ)·¯¿ãÑš™Ñ0 ,Ƈ1ó9 u~'DÖ ƒ‚`öÅçŠ{v%W­ö+•ìÖ; ÷ÜÌ€ÄL‹¡ð+~‡’KZ—쪕¾~’µîD hº5Û¶¥¾Ý`]f.N?üíž|(68|ŽÎá{™µZâ,„îÖ÷gž{¶|`_bt¥_­äî¸3¿ãÞNðÁù„½†Î£@ȤéÖ«TµÕ~îðÑ£#ß|ýÿõg?(MÌB 0,;+ÄÆéb@¦ÛÈ‹#…±óG÷n,Í­Øpo2ÛMZ‡ç¶.8ñÄÌaL  !nãúhȬ¦Nÿ¿}#_;þïF7ü¡Ú#Êóc^˜Ex3ÍŽ}Õ÷fÜØ*â žÚ^-¾ÈäYNŸ×žìêÿ%¿=QœyØMlÔªf;C¹žO [$Enš·¥o† §ëÎÞ [;rj>Øüþ­ìKºp6\3"Dˆ᦯ Y©égŸ™Í[®nxÏF #²¦™çŸeÒÙÍÛ„íÓôÊÅâî¨Ìæ­±¾þëÙÚ1síØáúÉãNwojízé¸ÅûüRÉ.²›·½³!*(dsr¬|`¿•Φ6l CfªG5Ξ–ŽS¸çÚ™SÞüyž]èJoØT>°¿5=i$’nO¯™Lµ¦§Rë7â»1Ê‘‚ zä`kb">º"½aÓ5xgê§NVO5bñî¼f/ Ñ?[yëM+“Ëï¸ÇLg˜¨zô­æÄ¸tì½4ÆÎ¶¦&I)§«;µnCiÿÞöìŒË[¹œn·ÍTÊÎæKû÷$×®7Sé¿ü«Âr¦ž~¢5=¥7÷JËÎlÙf¦33O?a¦2V&Ûœš ßO­[ït÷–÷ï j·o 68\;qÔ›ŸËlÚÚšžÊnÛ>óü³¹;ï–5ð3ŸÎß}O{zêÌ·þ:µvCåÐըLJF’k×—ìoÏÎ$FWzÅy¯¸`ç ù;wÔNž¨Ÿ:!-«ëý¢4„íÔNóæu³if²©µë…aÞôÝóü«/µJbÕšäŠU7Ì;ƒ¨êõ…7^Àì¶íÒuQíÙ™Òþ=ˆ˜»sJYÜó†0Mfîº÷æäxåà+“€Ôºõµ“dz[·Ï<÷Lî®÷ ÛøÔgrÛïnMŒ=ú÷ÉUk+‡¨f#><š\³®´¯7?—^¿Ñ}ûöga¢åšf±Ñ”•¦„c—›­5=]šhºR[Ñ•;=_\ÝÝå˜Æí3¦-„aZÎìÄñÀoçzFJscÀP+Ï3 ¦Ój”³]CN,UšëZwêÐÎáµwIiÞ¶VO…Œ7ë‡ #i;ƒÚ›:¨ &È·ì¯=‘H߉ÂnÖÄ“[Õ}Éì½ÒHr&³÷0k­ª­Útá§c‰ÕÒ«µÒKNlM¦ðÑ\ÏC?7;þ×¾?ç·ÆÞrúâÉ-QM„ÛSüöôþ݇ÛB !¤ÓÇxÍ‘U#}æù¹¨DD«"Dˆps§$)gž˜Ídª|`ÝÚ·)æ_ù‘n5í|WéÀ~U¯€_,ZÙ\bdÅäß»¶Ó Ë6rµù×^NoÜ<÷Ú˪Ñ@!ýj…‚ ³qsåÐ[ñ³ïd¨<"þÄãßK­]¯ZÚ±#hH`jMOe6mmMO×Ïœª8ÖœO­ß8ùƒÇt»5ÿÚË©µ^µ~ê„t\3~—Ê "¶&Çë§N¦·l›|òûo÷q¿Tœßùjbx´zôHó:øˆ†qö;›\»¡19Þž™F!u«Ôké ›ZÓS•Ck'Žëv+µfÝô³OÖO/¿õfjÝúɧoœ>e¥3ÒqQ+_è¤bEÁ¤u³!l»~údzÝFaYå·Þä 8õÍ¿Š W¿å éõÚ3Ó•Co1SfÓÖÒ›{«GM?ûdlp؈ǭLœ®n†‡  À QCÓô+%Ãg6n™}ñ9U«Î¿ö²™JÀú©…÷¶g¦U³Qܳ3»m»_­÷íA)QˆÆéS¥}{â#£•C¼ù9¼É™QÊÒþ½Íñ³ñ‘¥½»ƒZõF9@…4f^xÖLg¬l®´/k [S“±!éÆB/îÞ™\³®¸g—WœŸ~»5=9ýü³Òv¬Lì®n!EE‚ƒF]†_.ñdzæ¹—^PµÚÜË/šé´™Î¼­AˆØª{GvŸÍ÷¥gÇ‹ó“e|ç’NK!|¥OÌΛB>óÖa)pßÙñžTòÕ§}¥ !NÌÎ[ÒÈÅ]CÊl,v»–ßAf}òà«À<7~¼Ý¬Úõd¦{°Q+Õ+ó…¾U‡ßxÊ´œX"ƒˆñTáVfD¾F04o¦Y;ˆ¥™Ç®ºð‚í U‹/yíID£VzÑ0­.DÓ´zÂÍ)bX;[t—K8Tš˜¨+˸(^5!B„nòbSˆ…Ý;×}å÷ÌTЉ€/H ˆïo\ˆ¢ôæž‘ÏÿªSèFß$ÜÚÍýèy²qê$\‡ëU£!m'±rõº/ÿnP¯3“´íæØ™Òž]^±øÎFÍ bkn–TY‘]IJ÷¼ˆ:ðÎ~÷[ͱ³±Ai;V:“]A*Pͦ§Ö¬K­ß(ÌdJÆbã-ï¨+¿Rqºº#£ë÷÷Ã…ÚÛ~Ä ^“Ž“Xµ&µv=_Ç©íù~¹”^·>1ºB˜“BÓôË¥â®×ÚssN¡G˜¦Û×!ãcñá‘ÄÈŠÂŽ{™(60HJsjÕš ^#ß?ðÇÿ„ÈnÝž\¹ºzäàÙ‡¿­›ÔÚ¬ubdebdEkrbü±GòwßS¸ç¾¹—^˜{åGV6B8Ý=NWO|xÄpcF" ÌéõIk&:þÕÿ6þ½‡drô|‰föïV†ª×T£†™Z·ˆšã“?ø~÷~ZÕëã~§=;£ua±Á¡p˜É5ëÜþA#×^û"™¿ÁQÔNÏÞqgzÍúäêµË]'HëæÄxïOÔˆÇQˆÓßü: aL=õ¸ö<3™ÊÝq·Û×¶sy¯TÒFfÓV+“mŒ•±X|xˆ36‘RÌtìÏÿ‹ópÁLgG~ñ—Y3/<«MÝjªfC˜VzÝF#{{r…àµØ7ZXÝÍÄLüš—|"~|fîàät>‘H¹no:5˜ËÆmk´+_¬7ÎÌ㎕‰»Ì<ËÜžYiˆtßÈÆñûµb»Uï[±ÉrbÙ®¡Zir=ÃZÉrâÓbæžÁ5ï–Ü:Ž;Zž:ð´nÄSwhU·ÜaÛ²œ!ÌZéu)]7±˜Ýä: Ý?ñ'¦ÝMºÕ3ô%¥ªãÇÿwi$íØhïðoÕË»æ'¿]ž{F;ß÷Y'¶º²ð\£vÀoOÄ/úðƒQM„ÛÁ7#ÌôêYì,Šy kÿ‘©¹ 6è( p„"D¸•S±˜j4¤ãø•²•J‡y7˜ …$å Ã|ïÐB:®nÔ9“õkU  ‚é>Õÿ‰‡ìBáðŸþ † >Â$–ºêP4 R0·fg„i Ã,íÛmeó£ŸÿÕ_ûó0©3c'…줙¸ECgiÛ š Ýj¡ºÝ.íݽåþÕØÃßÅš¼LaÅd"Öí¶0-fb"D$ߦ١ÏRÊ’ÛBÊ ð°59át÷„* ?kÝÉDsÎ AAD^¥, CÆâˆÈLágóP•®ª†d¥XSP.Ëx\H³5>æÖ~å÷Æ¿÷ÝN:€p‹Žˆá±#™dMÀ€¬50ËÜüÏþHX61ðÉ¿üÿîþ¿ÿsùÍ}ÕcG IAZ».¹zí®×Î|ûnÿŠ_ù‡™M[¼bÑ/—šãg™™™4 AJ…o\ýÅßÉÝõ>Vš™&{¤ð¾ûÒë6þÓ?@”ˆ¤ã®úâïx³3þõnù—ÿ¦ÿ­þßö+@¨zk‰\@ ÀZ‡/`’_˜Ö Ý­±°,]¯3“7?g&“(Ž KÉJu2¹\ƒ»A AO¥ê5`!Î|û~g¦g_~1 ,"bêv;ô€ŸOX±æ7¿œ½ãΰã|§ëþ$W®:òŸÿC‡°Ì¬‰I/™Ö¥¸R„#"h­‰¨UöP¢ãZ€È,CÓ¾Ü"ëÂI×q,óé‡>¸a­&êœY†bZJ㨉Š0Ï—@Tš )ÞùÉ’±whý©ƒ¯ºñd,™ §€s.i 7!"‘FáOD$­„4ˆ´òöšóXÙî Yšy,•{ ´ZŠe'53‚3I !ÝÁU¿ŸÈÜLJ•›µýƒ«ÿ©›XǬ™8(ô.Ûý)€ÒÜ€bxÍ¿˜ÿZHAf}.s ù(Þ; Œ·1(¨ÌÍW=: ½:›è-”½)g¹•Œ4Eˆ!B„›¼2#ÝóÁO<þÈÄ÷©>Ø;»°{§_)/¼±“•šzê òý÷H™&êzàÁ©§~0ñÄ÷Šû÷h¯ ÀNWOqïÅ=»Ús³åCÞx]·šÅ½o4ÆÏ¶¦'+G^åGxf6ãqbòÉïŸýößp ´ï™éL{vfæùgU³Þš™ž}鿸К™.¿µß+-̾øÜ-sÍ0³•ËÇú§Ÿ}jò©'𓬠ÁJO?÷Œ7?[~ëMR*Ì¢¢› #×íöôÓ?hœ9…Bxós•·Þ$ߟzêqÖª¸{—_.÷ìjŒyW4±ó…ÖÌôÔÓOL<þHP©,ìz|oê™hÏ«=Ôšœ¸Â(˜ÙÊdÑ0¦Ÿ}òôß~ݯTJ{ßðJÅâžÝñ³^q¡¸{ùÞÕ( ‘Þ°iâñGÆýNP*évK:Žö¼™çT+ͱÓA¥ D [M§§·59>óÜ3õ³§…aV¿Õšš$ߟ{õ%Rn{øø¡70608óâs•ÃgN͆n·±´oÏÜ«/¡aع|bxÅ®×&ŸüþÔÓëv‹|‚j¥¸{ Î<ÿ¬öÚ¬µö<ò} | 2’‰ÊáƒÓÏ?KZ7§ÆÉ÷À+'¾ÿˆ_.%×®3bqbü±‡Oã/ýrˆXkÒ*Ì”LJŠ…7^oNŽ7'ƪǎ’ïO=ýòÆ*uv˶…7^Ÿzêñ¹W_jMO;üÁük/«zmöå‚zíZíf6o›þáÓ“O~¿rè-R ˆbýó¯¿R;q¬~ú¤W,²R@¾Rº}}SO=Q>°˜ýJ¥´w7¢˜yîíµY«ó ›¬:0ó³ø­é í{€Ðšš¨:àçg_zž|þõW‚ê•g±·˜ýæK'^|xo«Þ>}hªZlœ=<=;VjÖZ'ß÷ÛÁM=½Ê &bnú¾k™×Ý769”Ïjâ@xJ103óL¥ºl¢îyÆ'­÷žŸ«ÕÆJc ¥v¼|ü¤|ç,‰V>‘ÖZ©•[¾ñtx^É÷š@‹r*ð[õòÔé·ˆô‰/)åÏŒiÖŠ¾×:sd§ï5ÇŽíQÁmrd˜‰Ú¬u Ѱìþ™±?KeßOäùÌì3kfͬTP®,¼¨Uµ²ð<³Ïä“n3yD³&Ý&ò˜<&€4é6“Oä1+ÓêVþBiî^ód»yªU;\+½øóµÒ+Ìzaú»LïÝ3Ôn Š 5ñÒSÏî9xäÈáÃG>tøà¡ÃGÏÌÖ.ˆ5Œ¢f"Dˆ!ÂM^ iÙ°ÙL$Àéîa¥ŒXLº±Äð(‘Ù¼ ùI ÌZ§Ö¬“Ž DvWù>J¶çf­t&¹jt\3ž@ÓŠH×E!¤sÕe‰™¥ëûè'ýR1³a³•Ë |â!+“µ29&JoÜÌJQàñ“¦iÄâÉ5ëàžA@€¾~¢=7+mÛ.t;….#žXù…ß ¤Ö¬S†™L¡@ò½5¿õ?…I£cýƒ³§ÍTÚˆÇÝÞ>”2³y lH×½ý£ú™ÈîêîýÀ‡ƒZ5»y«‘LÆGFQ™[…a¸=}²®4 f#žèýÀ‡¼b1½iK¬o d_|hXº®0ÍøðJãj”ˆ”üÔϵçf3›¶Ø…ª/}ÙéééûÈÇ©ÝÎn»CÕj²Œx‚‰F?ÿkÒuSë7ºÝ½­Ù4 §»G&J™YaÄ£Ÿÿ‚0ÌÎK™WüÊo¨F=¹r5™H¬ùÒWX«ô¦­~i¬lÞL$Œx‚¼vzý&3øä§…e£ñÁa`H­^+L+wçaÈpÊ̹;îòæçQÊÌÆÍ€ënLº±îû$¥FÿÁÌD²ï£Ÿ Ê¥äêµN¡Ëp¦N1/¢ûÍxB:¶ŒÅÀL¤PÊÌæ­pC‹(1Q|x´ÿãŸÒžgçr²Ñ0PÊÄŠU¶SkÖIÛ¹f§vîλZS}Ààtw'W¯5SéáŸÿE¿R¶Ò™Ìæ­f2Ý÷‘OïõâgÍdR{ž†W\P͆tœØÀ3'׬•¦•¿ûašK„Íß¹Ã[X@Cf6nA)Ýž>a;f:-LjŒ«×¢a$V¬”Žse·ˆå˜ïYQ/5‡ÖöäzÒÒnÜÂÞ”aJÓ6º²Ò”7ï4 3Çm뵫¶õK÷Ü¥´^ÝÓõÏ?ý Û0dLÜ¿f%ýÜ]ÛÓìˤr‰¸D´LÃ6ŒÞLZ 1œËÆÛµL`0¥\ÓÓýNY"µþÎX¶“í´Ý„4Ì|îN¤ À|ïG])¿Ð¿”òïûد ÃLåzE¡o¥2•ëµì˜F¾o¥4¬\÷°ò68ÂȲ{à BÆúF¿Ì¬’™{Voù¯ÒHØÎ€ÑýqD™ïùŒ0’hZ)cN|% lj¯B¹žŸ2–[ÂÉõ~Æ0Ò܉¯ÑñôvXÌœÊLnb}AÆE,±Y éH#)e‰­D‰Ì]€2:ÓáÖÖÀº+·®²„”íÚÜlÉï,HŒ\3"Dˆá11º:µ?ÁL¥™Ùèíg¦ÄÈŠ÷Z9íÄÈh‡ñΕd2 v¾†¬3‘ÛÓFÚ‡™8®¾q+›³sùpÇèöö1s|h¸³‘B\bO@|høVŸ™D2™L…¿‡å`–òƒ@¡«³øÖ:68¬½Vsb|æùg„ilÚ" Ct9Àœ]ÁDno?NŒß~= ¬t÷Çú˜(12ÊDV¾ÐaÐa¦3V&ÛálOn¬#$nœ™®’F2™L¥:>…Á!fŽõ „±Ò™Ž„0ÇU½^?uræÙ§¬|>÷3IÇíü)|ª`Ix˜ÈéîèYbtlpˆµ6S)+>×fÿ@¸Je`··‰ÐvÜÞ~fЇ¤ÈfÏ‘‚Ùˆ'B—î’‡oŒ,½×Êdíl.üÝH¦–ÔÉÀuúyicÆ|“ Nl`pI¹âƒÃajfý#×(¢Ì´#+:ºãÆÀÎåí|!4Ìt{z™HÕÓÏ>ÉD«~ã·…aº=½¼8^+›;°‰¤¹D«E‰¤‘H@|0ÎD±þÁ«éy,áÄ’0q¦`ÛµB&gº’7ÛÙ!…È'âÀÜ—Ikâ¸c%›˜M)ó‰81÷¦SÄláZ$]˜»SIfîN§–[Ålú*¨ÍÌÉLl·#BÙ®¡ð^:ßÏD¶›%<ïgæd¦‹™³]CÌ”HåC«™Îõ2s*×sû¸ª-w˜lw˜¤‘4̳2.d€L§?”.!lÃÀlÇF€Étú–rÒ!J«sg8.6ÌìÒn€ 7¾’Ïs"0[F˜Üøê«µ"ÜL%·ì|Ú8yòLnëšøá—^˜ÝÛîØœ0ð³¹f"Dˆ!Â-™˜–m‡:;pà ®¿I±œ ‹KÍðÛ൒¥“Vã܋έÔ/Z²¿‹øåÝãË “–=ò Ÿ@ApÑ hI„ÞÅ*^¹J.œGºó†ÿöèpy Y.¬µŒÅF?÷Ë ˜I©åŽ˜‹…ç>.Š4Ÿ×æE}6—%ÅùÃùݾÄ=ti™¹‚öÝTæ^¯Š-gÖÒÏeæb9õ ï»·ë¾€•bÒçuìj{ŠyÉ.s|ñ²žÞ"õ\ ¦èæœR0,&—¹€ËYºNï¨GãBmb:ï— Ÿ—ÿÎÓáö1yç~/^v}I”—ÿ¤K´O¿Az IDAT³ìÿ+ÉnÀL!Â"z•ñÇ›w<”/ïzô•RaKròÍ©Þ7jjŽÒGˆ!B„nsO“ "2D,ˆpµìÒ:LÕ!B„n' q`$»ºœÆ®3Þöß³ªqh"¼ Iu䚉!B„wíB¥B#@¡Ðð‘#x.ã!hOë*¨¬k6™["`fÝPª¬Ô\ Á(ûAÀ\Wz:ZJk„é†Ò•@™RzÈÊÀJ[DqÓPDYC([n+4^Ú8¯PŽ&Ðge_¾B‡)„eˆ¦¯Ãïœed t ¡æé¬ÒÚ–ìÂo÷(DЕ@Íj ‚2@Z€Bai—¢Ô%ûqÉ늸ª€ ,“VR6‘…R³~°4,‰˜²Í€¨hbf†³"n“&‰d 6_k’cEÔ´^þA Μ´M‚#Ä,[¶ a¾"!Ðè)j*$uÜ2X"1ˆó˜E` \ž+±¨¸š0üBYRÂâ·åš¯ ÓhÍÊ6„kJh*ª+=ã†6é„eB3" t^Úð•%…)/]ÔDž&Ça±Xä…;º*êyJ7~Pmz~à{¾  Ô—ÏîRÏ×äJô%†/CDE$€Ö¨Á@Ôˆ Q‡0yd !´‰ØVÚ1$3{š ¨x®1%LCRhbã¼þ0„:«ˆjZJ™(”D``‰bñ><Ÿ L¼tûšê¾bE&n+—_|ÜšŒ˜ Ìç‹Ù•2ârZªN³j#…4™ç—ÔÑDÄ^\ÖVÄ‘X/^iøÊ5¥D¬{*gI¨H¢' M†$Q‚¸î)Ç”&iH‹] 1031„ƒŒ€å¶oKéš²î+yÉZÒ²ª§L)ik`ŒK&êœêcH¥0F±#Q€‹ZT7 á2Yº9l,´!I"Kˆ>¡ Ä€u_)"¸®41 °¾fb |-Ùv‘Aj –$š!ÀK%tn7ÛD„€–åJy]Õy$1œ³Ô9žƒÂKÏÌøãäž´-o¶.¢F&éI£% _H‚@­Œ ÂXîÚÏ£€@‹Ž¥  _€’h$…¤‘¢ü‰ZMBÐŒ1JNáÆNˆ¦“w«OþàÑs<øY·uòå£räA/ ùŠ\3"Dˆð®ZÇï)>jJ+á$ß·þ¾6çKÝ3p¿¹X}€5%ÿáÆík¾þÕ—~j°ðà‡Ö+EÿÏc“ÿfÇ–¶ï3ÀâZßâ_¹¶ùÌûÿÛª k×õiM¦)ŸøÞ¾çxö7¿üÕk»ùΫÖö~ý«/wIñË¿vÏúý­fðð·vñþIÃ8·àö}½ñcÙ>ýa\ú+. ?[Üõꩇ>»]Dã3g~°çïøøÝ•Zý—ýÞ¾þì?ùÝ¿éêN"@µìoùT­¬Ö%¹íª†«f@#`V÷ÿå‡ÞoÒ–†"Uƒá"˜³0(5°„4!@VΗ*JØ?€Ø»»ûû»wôuÿÑ·d¦ãœn*EhËÈh¡Y÷{tßG>¾1Ž-íŽêõöÿùo¾¿ãž•üȺdÒ ÷Ïáfé/ÿü%g¡–-6ðš*ÈjÍ+Väþwä q^JÖ‹@šÿÓ¿vv¶’ÍÆ{zRÙ|bj¢ô³?¿uç«§oÔÛ<¸zf²vàÍñróƒÛ@DS㥿ú‹WÒY·^÷ÊÅFß@vr¢Öµ%Í+VÒ™ØýãDÎ{mõÅßú©o}sg—d2qßî¼{ô…ûú2õzë‹¿ó½oœÚ°b`ð¾ü®×N~ï»ûÚíàó_xߎ{VùBD)ðÏþËó'ŽMõõ§+•gs±3§‹_þݾñú™½{ÎÆã– t.Ÿœš*¯\Y¸ç¾Õ?¶Ï÷T*íÎÎÔ2ÙX­ÖŽÇív;Pþ±˜ Ð?õµŸúôZ‡'}ÀPíàÉçO=3iZ—ÞF0qOozb¢t÷ŽáR©$Z-¿ÕòË•ÖÖ­ƒ'OÍkŸWß§¦ÔÞJpGµÜcBºmƧ¹ÿžØêµcòµ×Îôd¿š)7Ÿ>ûù»¾ýÍ]™LìÁ¬=vl¶\lºø³¿tÏ‘CSû7¯KùB²^o¯ZÕ}àÀ¸ } ¦)mÛ¨Õ=f.â_ú¦3."þ³ßÿVOoÒYgN/ÌœËÅ}_×ëÞÒ¶b1³«;uúÔ¼¨ßûÀèg>»C)­5}ëë;§¦ªårÁ0„e­vp+Ž<0X–‘ÉÆf¦+W#üD<8˜(]|3÷ôeŠ õBW¢¸ÐÈdbž§²ÙØÑ#“ïÿ©Õ¯¼rR.&Q$Í+Væ³¹ø®g¤±˜‹Yós5ØzÇðÉ㳎kÕj-Ï ÇZ³¶çÌéyþµ/¾ÿûì›+ý/ÿü“ÿñÿzºZmóèFìõyëJéWtÒu=+¦Ó1Ç6¿ô•þ»]þè†oãuM\¯µãq[Q.7µ¢Þþ´”¢«+yüجeí¶ŸËÇ+•Öüѧ÷î:ýÝoïùÇÿôã»_?ýÈ£G,[2C.3,Á Žc}å}øÈ¡É¿ûÆ.?PA  ):¾^D¥©¯7=5UI¥]D¨TZ…®D³î¦¨TÚCCÙ±±b¡ô}U¯·-ÓÈdcÕjËk+@`âîžTµÚ’Rj­]Ç*—›=½©J¥eZÆ]w ï|åT*åVÊ-"Îcg‹±˜åºÖ¯ÿæ¹B‚ˆ )‰ÚÒñQâµ{xcï.3‘Øúvç»z ÞØ•VÇD¬2>tò°ßÕ ôÿöŸIÄMú;;ÿîåÓ/×áaÀušYž_òjà˜È”fÕm]N¶b]ö¥³Ï2R²¬;(o²oF™©Ú/¼0]­VòýÝpu[ˆ(õ­ÛÿvÝ:gÙ´ØÔúoßÔìØÜÄdÇF8µ®¶oð°&c;_~ O&ûºìJ¼"åONÍ#f° ±z(•¬zF¹f)ÅQ]§7LÈH:ù»?ô¡‰ÙÆûúS¦¹ú¾™‰´  1D®™"Dx·:g$–®`™c’€}b©ÁË]3lÆL+ëØ†GqY×ñMh¥,Ó¹x€†!E@)ÓLÙ¦teM¥ 3sc$R†)ªÊ0EÊ0²®c“0}2jÊ0Ïm€ÉSfÀ9×QÆ¥]3B`Í´\YÇ…5Ë0© m¶Z”6­Œm‹²²š¶Ù'FôA2˜lTld\Û’F¸ƒa04X,¡¬Î”عÿ®Èç_g[Ê„ah´@ Çg?à´ieÇ ¦!mYY×YrÍŠdMÇ3¶Z¼þI¶´ÑÐF]_›kÙ>gl+ë:¼lúÖš¬¶6jÊrÉQ#´}N[fŒÐn“ßÔq®£¦ã(s®CDMË2›Ú‰³ß"£®mŸÍº «5“&'`W£Q×Dî{TS¥ CÖ•á)Ë&ö(BÖ”a í‘×ÔËrÒȺNBF]ɦJ#íXÚ0@ÂñAÖ”í±ÙÐDlÇYT‚”iº ª2AB íÿŸ½7±äÊîüι÷F¼=÷ÌÊÌÊÚ’E‹,²¸vSÍ^Èn©»­–Z­–¥±5cäñŒmŒþ0€Ã óÁÀƒÁŒ-[’²F¶fZÖIÝêÝd“â¾kß׬\ß÷œ¿?Ä{/_feÖÖUɪæýá!/2^ÄsϽqω{έÀ-øBF5ÅMѦŠp‹>.ª[ô±‰¤!”úë®Q…Ä—aËEñÚ5æ2E)Ü‚¸ÂZƒ%Zpó¾¤ÔH@€$ê›ê|I8nHÖB RÐyÕX%RDB‘§82‘Ø_h-q ¢©ÔŒ³s>Š¥j\1CÜÒ8E!®çæ½u¦PÕ¤.yÕXמþÅ©‰½*âªöâþB »_DÑ‘[ðÆ(â²"‘h±G@D¶˜µáLËj†JÅ,-¤ˆ›ê$ŸÚE6ãë²95€¨È…2nPùUµ®~0…D£ºûÕ¥PZZÌ`ç³2Œ[ð¶ãVÑBFee·à3ÙØÀ- •„£¦Œ¶ê"M‰TJÂqSˆ Ŕܢ ‹QCÝ¢¨Â%Z̨jœgŽ[°¤nAâXc`°X(fÔÅqKE)jhÁª±Õ…½R8‹²š¸¡UmJ!¥¸)ÃåRÍ9·(ÅBì¼Ëˆ€¸¨@1T.öE‘«‹¦‚L"#Ðv?CÌÌ^ Ü¢ã¼Wô…šf ‰br ¾˜’[BUs…t.”ÕEšž˜¡( ª‹ÈdCÝ¢D ‰…+d£†Šˆ¢Šü*Ù˜Ñßé˜x.I<“g6·d²‚ÄÆ5ÙÈMϼ©QCÚ”„ ¶Øàö¥îqMÖr_¥Zò*TŠë1âŸb~‡0EMµî-3I•!kφ“^ûþŒ"JÁwåùºïm•Häù˜ˆèm=ô­½ìÅšv`geíì… æ|:1A ù(˜™ˆ¯Âèæ>\vý¹2WÈáÆ—ÏÌ‹ÃÝT›¼L¹è:RiG‰€H±´Ÿò&´ëçÖª—Àísê’ǧmá´åOùìkZ±Ýþ9A yÐS{†6·m¢îœû¥ŸZ*(“v,Â\øßrûÓhWÜ> Úzeºê|ÐÕ ‘aâž«ç!L=;»—¦°ÚEêT'k˹ëùv7â¥+OêJ{Yt…j—³]Å t7Ú2éê§é^‹–ÄÒ‘[~u2 ÎZ‚‹š@Krè¹ä™é¶úü“×x;Ê Ýâq§‚ri¬‘Ó›kÊí02ßPHSGìWŒ%ýéùpG\´¬gw,£{¿½;i©²:…„òKäXªšŽ†wª¸}ÂN²ÕåËËÏÝ®xIµ¸Ûc,k§Äm)µwr§/íª÷¸/¸§±p§ñvd‚NñV*d§lÌÝÿæ-š{~ÒSà¼1ÐÓNÿÓ­Æ-vhÜî±oݤçÎ3z;•å{Þ†  Õ¼…t¹‹“ Cqƒzδò¹qûüšyÄfÇãcMg©¬Ûºä\®®~»Û§2@È«º§È»®¼Ïâ¥Ç&£û$ ß`é˜ u»I©oô—0+€ã:©œ(³eæÎ7ýéë¤-Ý5FXm;p'\¥PHw{u ®™@ O4ÆØã§ßêßX«Á* üÌi¸5'^=1¾güÒáKÃÛ†‹ÕâÝ£çlÍÙ×TFû[óõþ©‘B­L÷xd6õÙÓ¾µ`\,Yk`ò¡õÎ0§õ™s¿ÍÆ4*ömØù܉wÿfèàÄC•á-—½’4®¡<05¼éQ6Qp¤~f®™@ ÖÑB`ÃÆT4¬ëø¸-(kl¾uæÂÁR±¯¿oåùkUˆ™Ù´ЪL&"ˆø ½kò04ñr7Èløô[§GvŽ\üèâàÔ ±F¼Ûêü˜ehøâ§Æ˜çN_ªŽ Xg%óyÙØ ŸÒ‡|’&TٵΈ׻ԉÜ,^nΟw…j֜ڴ_‘j\ Uî¤-Ï…z6ªy‡“% ‹WNìzúï«dÆFY²˜,NoÝÿu‘ìÈÿ-þòÂô±±íOÇ¥³þu…á͵§7A¡¡_ ÜÛ×L ë5gsþò‘WßþV!®ì½ïùñÑ]Þ™ÀÇf=™KÓÇôÆ¿³Æ=³ÿÖFL|üÔ›9ËZþj+©>ñ“r©~qú¹'~ýðñŸœ<÷n­<ì\üôþ¯ïL@E¿|èä+G|+{þŸü;s7{gŒ3Dä ýhxûð¦G6|ýdÖÈv|jÇÇïq– »Btè¯ß¨mÜõ£'~ø>GöØ÷ÞØ<Úœ­—*ÍÙÅÁ­ããm9ýw‡v}þ‘Wþå_?ö›Ÿw¥ønõÎ6ÖÛ˜;{øÇ¿;qßgKý“¯ýñ?™zø«—޾dl•úIÕgOþ½ÓïþùȖǓƌ±q±2\(–6ª¤DÜœ;W¨ –ú'‰(.õ7çϹ¸Rªm(ÔÆÆ÷¤™ù‹‡N¾õï¡~dË“vÿ…Gjà^&¸f@ X¿Ñê›ïÿÕŸû$m,Ô§ƒ_&ðqZƒÆ¾õÁ_?ÿÔoQš6 ªÐ8.íÙù\’6uËÔÞ‘ÁÍûøÂ^ÿwGN¼VoÎ~îéÿìü¥#g/~¤`æÖlcáì쳿ó…é£ëWkcý¸ëCK Ù1råø•‰=ÓG¦·>½õî‰lRÑMvþö›Û>ý`cfqlÏfõ²ï×~îÔ+‰hóS÷çüÃÝ/<º{h¿qæñðyGwyè€bmCT¬¤­ù´57´iŸsñø®ŸÝþÌOþè=ù«ÿâÔ;ßJ›³[÷ƒ™«PfÛ˜=Ýœ?åô[*YT¨FžÆì¹™³ïHÖ"âêðöù‹‡æ.|Íž™9ûRõã÷}–€™Óo µŠ5 !™{÷¹DÀzS…Ϊ•¡É »ÛÉ<‰ò¿Ìa©ÎÀ:šÖD©o– µÚ†‰±ÝÌÆûäÊÜÙ…ú´H–gê®”@ä\!ÍqTaxpJ¡Ý¼Üó7ðIS Uµ…ˆ OìÝÔ7>ÐöËp†Ý…°b`ã@–di=M[iÿd»Ôy÷ûñ–(÷¹B|åø"*×läŒaë¬\ûQaØF–ˆ\!ÎËÝv»üwÐ]T,VÇÒÆÌ…¾7¶ó9@Ù:c+TòØ^¶Ž­%"ÉZYk.kÍù´NL’5³æœO7?ú5—T|ÖZÈ’Å ;ž­loΞMëÓYk>¯]îy¤®º‚@ p7\3@ ¬×C—-³i%‹ó —ŽŸ~;I^RUI³5šsÁ;X?3¨WêÓ3sgzC¡ÍdaañÒÖ©}ÆXÌ…Q¬‹“´ÁħYv"iæ[D”¤u@[i]oj–ÀÏ„k³F"™œ~ýøå#|âU4kf’‰ŠfÍô®J)Ý]]ËF¶¢ÿÐ÷ mR¯Y’hÍ·dìc)s{e6TÇ÷n=úÝwŠ}å¸RTQ´×2l Ÿz"Êš e–z,4¤õÖ]#ón¹¥Ô·¡~åä•3oW‡¶@¥½îW{59“d ê3BehËØŽOíøÔàä^ˆ¯ŽlÛñìØŽgK}ãªâ Õá-íx¶6ºƒˆgξ;ºí™Úȶ,Y$â¤1CÄ>m¨xÉâ“à ×L •(ô‰}¿øÿîkïüiµ:ל©ùî‡Y#½[æq€âRLL®à ˜|hòò‘ËSNÿàüÅ.¦ôÝ?7­§~ûôž®³‹ ¨g\ì xKãò|ÿ¦ }eŒ3ÆYJÕ…ó3‡¿ý¦dþ?ønÖLN¿vxñÂlºÐ<ø—¯'óÍCõºoÝ27Ƴ‰Ø¸Rÿ;¾û3D`ëØ8"ĥƌ-œ|óO/9ýæìÙ·™ŠP@ˆÙºâ¡BPf¶QÔJÌCS|ðÝÿå¡ïÇ¥þ…ËGýèäÜÁo7æÎ\8ôƒÙ³o³ ýRàž! @ X·!¸ôù³ÿUnNåÎ@ÿ8 /~ú·E² ¥Àºic_mì>ûÛnš‡~Љ±]{v=è®mOå¯òEýþ¿ä%Ë|úÈž/yÉ6n¸bl—ª>ýè×úÈž/r'}â`šztë¦Ç¶‘z½ï…‡ nÉg§ìùò#*¸Kˆ—¿v@E÷~e/Dô…úõºqßF""¥¿~‚}¿¸‚užx¢^üÚÓŒïÝ Q}öŸ}SE xú·¿ä“lÃ[ˆÈ'ÙS¿ý%}àËO¨è“¿ý%xÝñ™½ùŒ›}ß|¢{¿þ)•Ù&¨ L>DÄíõÝ|ºuÿ׉X%ÙúIÖÚûâ'YsâþÏtû¿–¯Ð”wL;ŸúOU²üáX¬Žlyä—U}÷ë¶Ç¾•ö(õv=—;}ò>mdË¿yß/´6²ƒúÁ5@`U{X:«tÇÏùFðË>Fm”ܱ²ä^Y²gD=3—ŠµÙ¹sÖF[§ÉòX'i›LÁ)ó EE»š’»<°´(òÝ•U¼|»T’I¯šçû»ÿ]o1úeîÉ|o!¡ºü«‘æÛÒ‘vûîî7Ä ‡ˆvtëîo;_ò$г~Ù×åkÃA—ÕHº§ «5î9‚k&@ pF7mÎ Å»!ž@ î-‚k&î]À b˜H¯Ú 3W@t•ù严8ôu^çÜÞÃ*ûòÝ q¾OUE—½Ó<¦P@zþ«Š¬³m kÏ»\/²êÜoy¨nè¾q½ÿò£§X»0è©Cu$ÇʤÄD¬=¯ÁD”ëÖ’†u6nÌ*ÏËÕ=í " ž“sg'÷^4ÿª¸~æ¬-b¾AºdVnKÜVA&0H€LE‘Ÿø*à*Q/וkÀ Wϱ²ebU5ãµt±ÖÉ;EñOáSôã$xU!\[ø×è•pµyµÛà_¸Pquu6¸§¢W8¸sÀŠ„%c¬©QtuSí-ñŠ“wãîáËû^Ñ7bÍ>s…PV—Cï\ÿ‘5jn)U%ÚÏ,¥[ÕAt; "äeÙÌ€¼_z(Ä«77“‰™MOj¬V멨xY#¹`Œˆ¦ªV±j¢^%SévmLdŒ¹í)b°¤yJÔÛ~W[ŽŠ;£ fp{TXó$ /d®ê•A¤ë²TÛOÿD]q ±‚Ta@ÄÝž=®™@ ÜØèBû¬Ÿ5WľYïxt£XÃÝñ_µX,Æ10„ÎÑÖùz#àev˜Ô¡m¼"&uP‹®1¥¶½gÉKâ ×7ÇzŽŒH…-Ô¶‡Eâ ̤"Åþbe²f y­°Ý26²yd„©`¢¿q¡™Íg'Du°\η˜|4ˬaUœ>7»q¼ßÚ¶,Rï Q´Š÷ xh|¢¸/˜†š¥aššUîB`VqЍ%µP‡[p+fõ",ÚU`¡†rÉà ¿ Ô [eù˜;?>ÿHŸøao ‘(¤¦RV?$ÚñÍd-‡ϧ&«ŠLsÒgæ­1ÆÔÔK–(Cìò˨l}f¾l ™YPBÅp¿™³$EÓì³óSòÆWØö™…’©9Ϊf12Y™Ñgª†`ã­I¼ñ×Íj™_àÖÕÂC¬]]•¶Ä©…T$#/U•Añ™ªu¾ÙWMQH'˜,—6Ô*uºÜgæË¦Ø´‘:¨ÝvaÚu¼^êÀ°¤0îI]§* ÐӦʶ®¶?/‚iÿëSQBæ=ýG=Îl˜)ieð¯¿ÿÍ短Ԋ¤Ëä³rD«ú„f½Ù IDAT_|ñÍ·þÙ‰·)j{dÀä ²ò=*S«&¾ W¿õO‹’T´•›[m‹hZÔU'$eiU}Z‘¬(RЬ¨`d1Ò²$*!+j«"i^X5”V|Z’4“¤"õûs ¹…#ÐúH_±bç¢ù®ê>•ìþèÕ”²J4âѳ}÷^‰,].¾Ðò |GIÄ!©ú–õêz%Û£ƒQá¡x[½0 ‘j4V)~Xá/M¸£Iá•BÜ/œÖ¢ …cnOŸÝ´#~Ë£Uއ† §+ñh³0S,ô¥ÒN¯û–T(³£+,{p®º^ã5½›iE[UïcM‹ ¢ÒmÎVæ›ó}‹™úFiëüÙ6/HvVûšòõ_;082ИŸûñ;/?Pxy ÞuÚ=ÜJ%MEµj’TT"dEIÊš•˜Ä¡Ug‘–%ñ⋚TÄ»ö1‰ &¯@Z–îl-¾w¶<¥UñÆ(’²$NíqT®l³‚$o¬ñ^}¬ÝæŸ5)K«%l˜@QD\0 ‹®CŠP€ œ–|R½!åWÕ´,Ie•ƒU‘•$©HV–¤"iYS#iQZ5Ÿ´UÛÑ:ÍŠ’¤UõÎWvQY’ªQV”¤ì]Å&Þ·ŒØ¢¦~ap‘ZÒú}Ù±²”V$ñyo©Þ©Z¤#éÂ#‹ö½þVE’²pQˆ)+* ¥%U É$.‹±HZ’yI‹Þº¼F„ œ@ZÓ…Â" û?÷Ø",r}@ HÊB10EÍÝgIEÒLÒX"G"šW31³÷š–5©JRfj%>o•J.À´$‰‘– œ”5I%±ž˜¡HK’¤"$S[ÒV"iI’² f#-KZÒ¤âU‘•´U•¨â]Ùõö?Q=üG%Å­{@ß~|äáÁIæ›NµŠ“‡¶÷Ï6r%Éÿð×§öÿâžr¹Òë[Q– fþùG~þ+~åÆ/aœy÷'ÿüå¿MZYûE±/’‚¥ŽfŠh4XùÂ/j¨¿r¦ÔžHD DdÅÃåÁ‰o¼{æ?e©ÿýþÿž=qÑÜÖå„:6µ!›Ûé§¾Ò?P:T攘Äú¢fæ‡j⥺Œ3-p[NÏÈ›§¬µD¤â‡£gfß9`­¡ îùÅὋÿå×¾ú££þ_½ôgͬٽaìȆö}Pi\ºtWD\©hœMêlØÆ‘$éÍΡèè}ÛfNž•¤½”¹'wmš›¼ï÷þüt3Iå¤&΂k&73Æ`Vf!Vbe«^%õ~õÕ%z÷Ù›½ÎÒ;ÎN˜ /Ñ ¾zNþÍlò êþè„i€‰!ª^‘_GÔûL¤÷š^Ô«xHšeYO6ÄL„H˜9õÞ“¦â£Ì_w ŽÌ{¯zƒòYk†~;\ç–lákÌ©fP>é¼fƒž*ÀUÕÝU–NÔ+±Pþz–•sõaá¥Z&e…S‚’Ur £ä„˜ˆ«Ÿ…HFÉ)¬Â‚XaÄ€DBNI•¬À)Y+9…S8Aþ+§pJNo üAI®žžÑÑL^KþX¨’o䢼a1L &e†!/’úÌ‹(å%´´\ì½×âv£2 wι¬Ý1(ÿ÷J«wK½{0+±tE„{õ#¯Ž±ê†Yåæ=_¥Eù%¸[­˜,îÄöœ¤“hœ{T¨-ðeÚµô+îs-oâ©Þ²k†AÖz6·˜œFÕjîšQ«M3qéš¹ïÉßøù-l¦™UÛ 5Zmò„Âg>M³[^ÈI–Gã2sæ3oT­ÞôÓùzNOX%2B,)ƒ fŠ–‚hûñY­!gˆd`¡NØ‚€D9Í$Ë â Q×M ‚¨ód…£;»t7;CFØ3ØÉÍwg`Í`|þÛî cr™xe%™[º ‚k&@ p«c5,1|ì-1Ï_“çžúÙZ`È0s'ÛÕš»gÙ(­÷ÚçÀm$¸f@ XG˜Mþ6aøx5‘ó©^ü÷ÿêwŸ}þ7\TÈSÏB•ó'D4?Kii)ho ­EdˆH\{?µgÁÚWÞý~¥Tm´êµáû·>äÅ·eÜÎõ½4›C¡†Mºà._4Í󿙣'f.Mõ[c÷OmÏD˜8O¢t{lZcÿøí—žÜr߯¾! ½SàÞ$¸f@ X?;Ƨ­K[ë' ÅJ°o“&šz}fîʹ¸Pî‹ %"š›9__œq6Ù°maþrÒZñÅbu`hrqazaîR\(3s¹:ØjÌ÷n áÏLsúÂâYgÜ®á=ú³5Ëãã1Ìld­‹\¼Ø˜¿8s~°6ì%›™Ÿ¶Æ´²–ˆ” åVÒˆãâèà†³—N ŒMÏ]ì.Åå»Ý;Ã6¶ÎY[O“cÓ7Ž,¦­ÙF}¬ÖïÌí‰ã*ØÈpè”÷0!ýt ëõÐ5öÈG/'­Å¹™ În™ÀÇ…ª|ç{ªrñüÑé˧Œ±.?fŒ=yì­ùÙ gO¾úÄ{ÌüÎë)â|¥Õ\8yìÍC¼DÐ,kíý„ÃÄͬþÚ™—Yý'g~x¹q‘ƒU|»dË\o.¾õÑk^²K3ç|ÿ½£oÍ-ÌÌ-^yý×Axåï©j’6Uµ•6Uô^q“æyŽþìƒW ›‹ ³\<ÍÁÃtG‰A@ ¬P=wúàÖí¸ï©ñÉÝ!Ó`àc3ü¯4ó›¶>¼{ϳCÃSy“1öäÑ7/]86?wÑF…¡‘©©Í%­ºø4ËZ[v<:9õ€a[® ŒŒm vxP£FVÏ4}xüñ¯=ð뵸/ôg· …NŽNf/þø¹#“£›¬µ›6lÝ1uä¢Ý›Á³mãîb¡´mrW¹tÏLÀ0T®•«gæ¦/×ç6Tûcb86Á5Àú3íŒÌfÙî¼#°Þº˜¿«6Æ2"ÊÒÖ™“ï>õÜ7·ï:«(1ƒçšé,‹Û]×$hì'ÈÇÌÝ€¬¹P\àFÅjŒÛ0¨‘ÏZÎÅÆ¸Ó'Þ;æ ÓlÌ]¹|ZÄŸ8ú†ª\8w8IêÎ^œ¿¦Ò|¢Ô¨UÛ÷/½ù­ÿïs §Ïžm]™i^><ýA#«¾r0•4$$º)TEUâ%Û2±óí#7Ò?æläŃ@!"/^UNœ?’¤­Sç5“æÜ•ó—ÏÔ›‹GNôâŸ=ÒJ›wU{T¨¨ ©ì™|ã̱Ⱥ¢sï?áU>8ªž&§f/Ÿš½|Ëùb<„‰N\¹xnþÊ……ÙãW.dâß;w2dA Ü+„)d@ ¬—-£²óþ§ÏŸ9—Š#c[õYbcŒq."¢(.†÷ÌõÁ°¹ïg®\>Õ7°ahdSãBy÷žO%Í…»Ÿj4檵!cˆß÷ø/c7Lìð>-–úò·÷ùš1q\$"k“±Ö‡~Ÿ¤ÞŒPŽ*o|æÌüÉFžêßvrî¨a£DÎFLìŒk/ñ¸Aç…bËäg‰]\-WŸ|ðÓÃý£ ¹ËCŸdŒÙ³}Ÿ`ϧòÉn bf"°±Î:æ\øä¬»«r¸(0Ù?"0Ä›AÅOnÚã}š´êÎnÔg{úkÅR-ר[‚êèøv"Œ·ç ÂÙ~¢.o-‘@¶ ì̧_ •FlÜf+Ül«œÈý-ù™›î`rtS¾BöÆÑÍ"~ëÄ…nØ Âæñí˜A"TK} Ý2¾€¨Ü5·†áJm¤RË êUß@÷mRèýcSª…"Ñ-.§­À–Á1€6ŒRWˆ@~þ ]{‚àš @`]G¨@w¸ŒÞà— |¼ªØÕÀ^ËHUŒ±[vìß¼ýQf2ÆjÇÞË#žÐ6{‚SæêM%Û¸£?!yÖO!ÏÞÖÔm’]Ùæ½±ü9’½ +·ÒÕ,ø§T™Ü§Ó= –‰4¸®™@ ÀµÈ³{;;DpÍÀ½k- È™|æî5ß[ƒ 7n«~+í¥…Ú'&ýǂ—Gs3]ÿ-:ˆtùw&R&íœH˜„Û;{NòfV Ì5¯y3é0Ð)L÷V”W¹ YM¶hŒ|]¦›¼¶•I˜´Séyå¢#=tªl©TLJ¤‘Lš¯cÁ¤ %(CÚ^@ ºfõµ+(//I@ùnœ6‘× ðÚÈ$¦}˜”`ä7©Lš·2&0¯ÑÀòóçÒ–¥ó, $ÿÊ’ô¶&"²ÌK-“!ˆÀÝ…XÚþ®ð—ª•ÛÕÚ½èRÁˆ”Y¸­féžÖí‘ÆõîªîíHz ¯æŠ×•†2kGÙ°tÛ«¢Ò­¬N“åÕM„N1–†¡K5Ûm\èT–t*·{÷´Dí^ˆòZ®“=çlW=s·œ†Y yù™‰©GÜQ†Î…¤£Ý{T&].^ /;z¶uù‘+zèÄrjn=·,(%«¸—$©_l¦¶ó¼ó¢Iæo»ƒDY’µ©±í'”³6rîÆ%%Ð4ÍVKU³ÔÑÖÛ´™%Í”˜}šùLfš’eKhd+³7œ?(½+1ai‚U»ô`V‰ñ¸s)§@d=Ú ‚YɈÞìó Uh緀ɕL0¬–ÉpHO®™@ Ü„gfÞ™cE[S+Ð.Ö‘lM·ƒ2ÆëÔW#0²âµ3¦}Ûߦ¡&vÎRÁCM*eØ5CÆRшAQb uë\ÏêB)\j®éa*xm,}O=c÷< ,R,D„û¯Ð c fz’Ò|ìÄ“WΕ¦/9ñWŸ´H{dˆV‰±7¬7: ,yl\ b* “6È.¿)«´k†F›+÷ñÄ¢møÂ¢ã[ZvÉ G‰¹z!P"`óª³ÚŽ©Ï‘,’Snaó<š êOXêØ9K}IÛg{l§Ñ`æêÅGgÓrn`‰j½0\ŠË³åLùptÁ{oK«TŸ2FšVŠ„Zy5Q-¥s”$TMï"ïLži`¨…]3°«vÐh„hà ŠÉ4[­RuÆ Ôã sE›’J½bOÌ6í‚·V­®ÐalÃÐ,yOµ»gPô·0±HÕôP-ÅÎYCƒŒzãí¯í˜C¡Ñ€~ëD'”¢4¡>F:C#Mê‘$ ˜¬ ÏÒÎYX‹bÅÕY"¢±’9*ihIJ…‚ nXhM1‘šh±01[, ¶ÎcqƇ žj­ÌöÍ7×6žC4«5A“Õ© ˜Z €†ê(¥0óÁHLÖÒ`LÍyÄš­¤ë6143å™âbC-Ú5ˆjJÎ@…”@TôØ6‡,ƒ÷p¢m33C„F"f©&DDà 0h6á,†i¼Dv–Y†FQD}Àà"¥)r [ .Â:BCóqX€‹0Т-ó¨)ú ŠA;‹R Å”œvµ)hãWþZ4å[4¾AD/žxxÊDJ[ïÒ§*3ò¿D”$Ùo|õq/Ú«¥b\-o£w€söË¿ñ|šù¼Xcß>ñÑ_¾ý“ÈÞÐÃCT§†F¿ñäóÖØeAALÈð£ñ²©&ÞѯýÖW@yv)Ôúþåæ±Z­Ú=^­‡ÿâÌôsÊGL"ÉÆûž¹tÉD{оéJe!£Öªn>¼¹•$Ý  ¨Uß‹Ò;º,T\(L^©—NÏ‘áFµÿÌØˆ¹ÉŠPÕt¬ÿ¢&Y–qû%œµ÷—ŠRœmL¾ÓÌš†­/=LÞ™@pÍ@àÉ Ï9Ž Ã’2õZ¯yJq{-ל_C(ÙÎ1 е¤½§ ä”j Œ#×°!›Ûsy›£|Qº}wIJ\·Ti@S2 &êkQ5%br Í–|Å夑5øªrYöEn¬}s(ó O`rJ匈Ȁ@Ä ¢§Î&ÔR®ÚODåÌXµó­á=[¹z* URʪ¤(eTðTΈ‰ ž*)Ù„b¡’§Z‚Üu’‹º’R9§¤IfK-§y}yoKÞ[UÓ¾X‹DWõ'¨èÉz² ‚Pµ…„"¹»„j YYÓ$ª¤¨%m&“ú¨?A5³ÅÔV2gæl6À)L¶êH½–’&O±P-A%—FšQ)#¦¼½1¨dÄ)•²ük»VLBªd]-‚•33Í6c†0P%¥(]ÞT™Êª)&U*ø¥Y$%O•è˜OÖQŠRºó™@TRJ’z§ P9£Újçÿ’„Ê|Šr†(m\ôH’TQʨèQKÈXEK>!"*zª¤(pŠ8ALZ Ì—‰Œ²Íl©å<Q%!N_Q=E"'¶ŠJFµ„*¸-Xª¤Á¤Tpd…@„ÊY¡¢G5¥ˆÈ&>v©/l[%êt§N „jJPÁ1E5¡,#ñd-T©ãš3‰P%£VB•ˆ@ URØ„œ#N¨œ¡– šQ–’Mà€JF”"M˜‰ªdD …z QB•Œ’<ª U ¤) ñZ*š¥n Ä~ãAA“éçE€uɉ 7ïês¸ëÙ%Ù<9좨×ß‚Þnÿ&3OnïJÅ{Ê_œ?š]|CÏ 3ä¶ìÜè̲§;37ç›à„¢L9Ù¼c’;#(âõô÷ú˜œ‰[Õf}dÞrDD^›®ß4JGœJ-WM#0E>*ÏVlÃqwò¬ *—f§üEŠÌuÍÄÑP%›1>Âl¥`o²CSÅ`1š/Çif:“fÈY›9K®ž•.dQÛ†1f ¸f@ pS:´£™:#ÊkXK71\ÂÕ×Y­Ô™ }ÆÄ½¹q—æO÷– D`^õ~¾ö‚øæ¬Ðõ_ë’?µ|p-Û·çFº3èËÜ–‚ò 0Ú¯…»¾ŸÞ½V z>Kº;£™z¢½Ö#/E„1ÈÕhé>¹-k¾F]tZwC½zzjgEÛéþöêúÆòfÝ+ö%#±çZWëjûÞyyV¿6&Ï |û„ÏW:®íš­~0z´}¥žÓ I2ñ’òb¹FS·~™:“s`ô4•vàº;˜hékïEÛ£g»ñ¶¤ ÔnkËšXï1è9ç }àeŠA¼²­qïmöô“èÕê«zƒe‡ñr䎲÷v¼+«ƒÕݪk†X•÷T¨ˆ*TuR,õ¦Wb(m? çýÊÚþ   …®pͨj·óWAû5‰BdY“·L få¶Ï £]g=} ˆ³T“0·÷][9Øt" ×½µÉ;çNQò²]íçêL삪2çíX;²Ê‹Of©-ƒ‰¹ÿÍ ÃP \3@ u†¹|ìte¨¿ÔW ‰~»¨m27ç[ õ¾ #ÝL4÷(.>Ñœ¯3ÓÈ–•áù —Uµoløv]Â33}yúâyåjmã–mÅ…Åùù¡‘QcmP§À]Np @ °žãlcmdmÄÁ[ ÛÈÙÈYg½úNýÊœ±6߯Ùë\þ!fcœqÖ¸`á:†„e‡Þì>3êWæÎ¾XEˆïáì'Ƙ³ï9ùÆ…J‘˜ßøÖw|’^9uþâ‘“·OTœeÙËßý•Ê•wÿî'gOo,.;ô¡ÏrÇîv¬™@ ÖmŒmæ/ýèïþ¨TêÛ»û³C b |<Úh¸>=÷êÿ¥unÿ/}ÁÅ>wðèá—^W/ûé ™ù3ï†*ïûêó'ßzuæå?»P,ÛoüÓ4âÎ=9~f|þè¯=þË/öOŒ@1¼yÒÆQî¾}}š9øÎ›“›·ìÚ³—‰†FÆ\ÏÍLkÊK{£•@ °^CSóã×ÿø³ÏüƒGxq¡>ü2S­}ã?|ûѯ~î¡/~zþâ´Šª³yðÅOíþ¹'>øÎ+* ýÒ âýÑ¿u騩§ý+}cÃÙù`çØÐì¥äÐsßøowÞ÷Äà¹#nRØ@`…!ÊšÉÀƱ¬•Ô¯Ì2ÓÒÚÝ·ëÌΞܴª‹ ó™ÏÄg:«À½C˜5À:¡*Dˆ£R!.ö«J'¯Gžc‘A!ÍG`ýHÍò`_¡\4‘;÷ÁQmÌÌ_<<ÇÖ°aÕF‰(.[õF±R&¢±›/;½dì0Ðþø„ÙÚêQªX™ýŸU‚RÜY‰wó€ƒîEù2“o%ÉbóÌ»‡Î<¶ý‰‡WÎú)o T,–š:]8{æâ¹3W._xú3_š¸W³f@ X¯‡®±Ì&ÍšõÆì¹‹‡³¬%êê}BD­´&#Ö“¸\jÎ-.LÏ^øè8͹…+g.ìúôcCSãP5ݾ¹,IÙðÜÙKÆZõ’¿ñöIÀ·h˜öIÆrÒñzìíùsGë>U¨ i iK‚kæö’4šDä“ €O•{©ÑhhóÄ©·ÖF÷|þ™þñ‘öcq)¿•É-$óêE½HæoîÐ<ôþ›¯yŸÝ÷Ðû|¸óäm§Í2&äÉ ÜÕ„Y3@ ¬×ØØ{ßgÿæ¥GŇv?ôÔëqTìŸ<}þýÝ[Ÿúþ«ðÅçþ ‘,*°¨èÏ?ñÊ¿ýS¹G¾ú9É|\.+¥ÿþ·&÷ì¸|üŒunhÓ²f2¼y#3¿üýiudÈFîÒÑSWNßñÌ#ïþÅv~걓o¼¿ñÁ]ÇnpÜÀÏDoFµ¡xdªü‡ÿÓáÖ¢ÿÿÙîŸüù…mõe©}{~ßgFÞþþå_ÜPésÁAóÓŠZU¼ÏZÉÿþÛÿÊ‹¿÷ê®Oíÿè{¯N>¸ktû¦»Ù+Ú›yŠ>÷ô»ùƒ#?~“˜†·lœÜ³óÌ;½û?8ùÆ6²;Ÿyôü‡Ç|áÙ¯¿_ê—Ì·ê»?ý¸ŠÜà5ŒMNmܺã[ø{q\`æg>û¢ˆ¼÷ÆkgN5Æî|à¡Ýí ¸k ®™@ ÖˆLŒížÛMD ÝI ômè…OýVðËÖÓÞÙ6õÂý› "Âðæ/arÏÎü¿÷ýÜ€ˆ Þ?þõ}æ/uS{wÏ_˜ž=iÃî­£Û7ðè×>O _x à—ù„)Ùˆ|qìÀÇrÃûÙ¯MæÑ([ì#à3¿:„¥ØoC;Ý65º}Ïþæ×<üóÏ´ï+ÏènöËHÍ®°áÊ`ÿS¿öeô±yÿ[ÛÓ>˜¸;@»žÝ¿ôм¦_†‰²$Yš\S(–öî?°wÿnˆè?ùÿ& ²Uî^‚k&õ­®f¿bi¬£Õ‡žôFèù»,鑊c:òò[Q1Þþä>õí4Im¥ šû U RAoï¶l#th·í©^‘Þ+ÒUï¿öžÏ2&Pî¯njßÊ ,в k7Ù°1çÏœ¼|á<3ç¢ypÿcŠ+¦@pÇî ‚k&@ pÆïÛ6ñÀv"‚hp#kc£èþ矤žp£ÛžGU·ìؽuç}Ý=¢¡w ÜÃ×L ܳP¨B±ìu÷êðOõb«}ÅŠ}XV¶[8m÷{÷üíe(hÙ»µõwñÚ¾æ~ðõ~vÝ+¯ñCp[8ù!èV1s~Q\Uò%©2–Ò cµ2¢{eP÷Jb^ãnøzrÁ²C8ÿz¶{ægÀiV+_ÿàŽ4¸-C¢\Œ]±‚T¡=žxµŠFïåz$¼¤ »ÅŠB^½, zšV6•:²Æm¢§áãfĹº TIoºÕÜhíñuÚºçäå2_Þ(hùaWiâU ¤·¢ùjU¥\é—Uâª%äÎ_ê©âåõ‚«ª¦]l,ïdx•Ÿp·½3Û¥^µêó¢.iy–V¯«‡kVƒ€5;¦¨j¾m½÷z @mk~¼FþM<µ¯UÐüŽp£eUR¥öd“ö¯õšeá5žzû£‡ÚºŸ÷Œ€ú5â(yy¦›UŸ¼¼ˆ•8äã0&ÿM IDAT×L nÂ-CQlkE™J5¶Ö »Ö` í±NøZ^ƒe6Qr‚Ü60J 8!×cÁ¨3uK«þ)X¾Îø dµ3<b±BVÚ‹HGžœ19Oql10BT,0ó:Q0Èê²ñ¦]Í4uBFW‘¨³˜oi9DÒˆW#:!'p«0Ú.U^Mη‹—ª3Ü$+°BV)2ªFÔ0‘Œ*«ZUîŒÝ êHAêH•`H ƒœ™Ü@Ë÷xr²Ì^cZRG°¤–À¯LjY\û«ZGjLêH=!ßc;G7’ÀDÁ0WŒ £ ¢5+p£íÖa…¬Q 1ªFÅ"iœ•Ë•j_¡\)pÛSHjÚåwBΓ y8!2Šn‹3 È“5°JVÈåÍ'÷»8&g )ÈöX1°d•Ô™¬‚ [¡H¨×ã—W«2L¬§Ž>(œ'Ã"Gd 9!Å_ gr%„¹#G@VV?XѾA+pByÿ`ÚjLNÈvnÇ€¬’Ñvïä¤]¢|'l§8£0ª¹!f V5o°N €URͽ80ªy«É¯Þí¬€©½ÓY!t¶’Ë?BVaUóþ.¿Š9AÄyõ‘£¼êÛ>'¤B*äˆXÛÊoòn@È*rãv'@NÈ9éJ©­Ž;Û&ÎoÊuN›KÛæ²2dÛù­*Y¥ÈÃ:rW™ÕÈ ¬µÀ+ÈàzŽP‰·ªJŒŽÃ©»q{5×XSªldÚÏÈÏBgóÝX XÕ5,Ô s\A¸¶ô\¹ ZãˆÈkÑ™¨V*ÆÎx†I $KޱžòÓ²€åÎú5X”Y(˜LT-—̪Ùv˜³L²Ô¯"?0ªªí— €e2¤ªV³²fÄÆ’†UŒÁ5uÍàs_Ü÷—%"f>föüŸÎÓkŒh íúHFDÕ Í5§4yVûjÈ1Ê4uZŸú‘¯~jiÓ)íïÇÓ/e&B߀IŸ;0ôÞ&)˜¥Ó6DžÜÕÏk[Õ ªÔ±ýˆð3m7M4 Ùç^yì;{¤ü,ÅsßÍú7y"Z8ßú…ÿ~Çæ­#ožÆh”=õ«ïÿ翾ӓ–ÁÔ7§{Þ&®ì˜œ§íG4~xùsÔÓÓ/ùmq®¼Áû?Ä«jï©Ñ;¾5/“ÃZ>£î?>¥0¡rû_“ê¨4ç|ý¢Lǧåâ¥Ü Åø¦É¡þÚÎǵ3Æm¦Yyß}=n“L«6MÍÀ$<`Ø™G/éØq)}–&ÏhyD4vOþ8K~d/pÿRQOï6‡kfrØÌ.€†ªæØ¨}¾Bç·›ƒ0•¢ñb†ª|nÂdãfjî5©çþ2_˜4ƒU3ß4Õ¢i¥&“ë‘31¦xÅðÛ€¦NÉÓ?ô¶°º©ÕáM2yÔoŽtä¢70­ºôW/²É&Ožn¶²Ï~ýÅ5ü¿ý£/þ¾@d© Ž/lá`6ðß÷ó³^R?¶ÏüÀWGýÄô­_ö• bŸÃð4žzÉgú'|cÖo|P£ŸxÓöÍÀÆ•lkÎCQèB…ØðôF±‹—½f~p‹GR|×G›Õµ±ç !QcÊõÆ®cGYŸ?¯Ïüл¢! :*¦` (”D™ª xì5ïïSo#h'pŒ™˜d~h‹Ÿ<á+CBLiß7!­yïbª_ñ£;eì°ïŸðYË7ç¼+pmTêW|ÖôÄ ÕÁ)©_ñÖ‘x)”eqZ†6ùÅ+Þż±Œý¯ûê€.\ñPôûÑC¾Xó…Š/|†Ú^y&ø¨õ~^R]UØF 3<;½¸æT…|ÂÍ>]Æ7Ýy#ƒ½\¯Ì-6LDiË׳ˆo«ƒ^Dïß·ãÁÇv÷ºd²4[ÿ0 O—>õý [´7ÒZÕclÏù"Ã-ÏÜ”j¥oþóoæÙ,ɮב¦ß|ò›žf(*_x”‰È:÷Ö_ýÇßz覕ÆÍ”–Þ:9‚mÅï™;h]‚âøÄô“‡÷yòÏìßö?ÿÃÏ¥é* l;k_úþ»òo˜e~…Bªb ’ ÿ@Ò$÷-°Î $8úÈ¡ÿõ-.¨±Üø&i»Ð½´:y ¸f@ ðñá½x/Dd ‹JþBqÍ¡›!tGQ×êéò÷‘j¨ûª3Ÿà Ã-cÎ«í±ª¬€¯;ÛI--›à­XÛž/‰#"Ç^TyôŽø X—S^žù9jW1òY«Êœ.ƒ½¥‘½,«Ï"×þ¨%5¹YMg§éÌFé ´iOQiÏR1jmþnSYaŒ²Qc´3„U«`6ù U2 #dòЛ|ò‹éQÇâz¬£FÈåsŒüÿì½Y$éq çîÿ‘÷U÷ÕÕ]}N÷=÷ÉÁI .R<„Ýå_´&“™Ì¤éA¦ÉLoZ=I&=hµzMW\,A€$°$`p æè™î9ú¾»îª¬<#âÿÝõ™UÕÕUÝ=îšA––™ñ‡ÿîÿáá¿  ïÝ¢gÔ$Aém¬ïé}ô7Å’ì(+ÈÛ¸ÿ˜Ð;v„Ñp07(ÞbJ_†÷ž!1q”8z€ Þ À3pOcqCþ¦·¨Ä ½Ao1­±} ³@œ›Ì˜½˜„ "#‹7àƒ›L&=‹³@nª‚4:ÉÛtú„`,øvÃtÑö´ânBƤ§ºÛÄ— ÷®‚û ï ðz­mH{‘V΢±à{ÚŽÀ„l{ûu„l(mèÒê–žY¡ˆ¤5(‚ÈDi•y‹©ù3aü% éNHíОÀ ž1¢¤µ‚ÀD(„ÞZHõM 7=;MÒ €î//BDDðп àú2A >è©\¯¨`Ðß¶ØSuo,xè“*$ZdZ?…Åôö>Þ´Q0ô€n{ç‹ƲÉíV‘0’{kŒQ%õL">w‰÷ìý'b:Î(.`î*vƒ½ambE䎙-Þ¸¹Éu½`1ö^D̆2lŠ¿íG¿H€`˜cF@,‰Xô^ØEQ¼­kÆ[ã\"È@·, DFÃhúktÈ"›|lÄõÊ(¬¥(Š¢(Šò©Æ’Ñä Š¢Ü/,‘A²:ÙT”»E­EQEQvsÄŠH„DšhPù˜5 ‘…¿õË¿O¼K?¦Q¸‰žÚnúŒª½Š²›Ò¯‘Ñ!áâûËxíÚëó~p…ú±?H¸ÑîôÛ”^c„ýwEù£ šEQe÷†Øœ$ÑÂ<Vk”É€>æSù˜&{¸[ï´Bk‹™|;éÀZ·ÕŽº†h°XmvÛ‘K˜}&˹b;ê4¢vhDÌ™n—s£¢Œº¼Rù´¢®EQEÙ½ ñÂO|ì¿þo9Š\«©!3ÊÇ5ß[i­ÝX]ü³W¿±Öi&>DÌ™fÔiE« ì™zùàñ_œ'rñZ§õõ§>fîâÉk熊Õr®¨~EÙ•NCVÛ«…°ðü¾çå×­Ë‘üP.SãVÒœkO<7j~tpêű ÿñêÌö¸¶sm7p¸&,XÏkâ|šÑ\3Š¢(в{U!km±˜ëeœALŸLs7V”_ˆ]+ •\±š/ Hì’g/>»ïØ‘=,Bˆ†Œ ’Xc,™B¦ˆhˆ€Ö³ÒôsÓ¨lå¾öRÍWÿà™?Xl.þå›)"„„€éû¯…Ñ‘¥ü`¶5ß¹ð¯îyeœ½¤)flHëe'B"B2iWˆïÚ®(Ÿ&t¨(Š¢(»5%6¦°gzõ½w—~ùó¹ø~ëÊåhaÞ5›ÍËÄû•wO 1*%åAÃ"Ã¥š€Ì×—~~þä‰+"¢cï¼÷ÌË­úJkEÒGÔÇ>±Æ0ó•åÙg/ `+ê,6V˜ùƒÙK,rme®“Ä×Væëí†Î¢å~vˆóù3sgžŸy>k³­¸uyùrä£ó‹ç#­´Væ×æ?™F'"Â",œpyªT¿Üè®FùÁ¬xp1³B{©Û\hG¤q£)" ï-³ç峫>áµÍæ\GåS‚ºfEQe·¦ÄÎM~í÷gÏDK‹Õ'žLê«Ñê2Çq¼¼,Þ·¯]ÑT(»ƒ!óÅ£/œ¸ò!€Ý{dl¦É=21óö•žØsØ3Z*Ö<û÷?šààÈô™ùË„” ÃNÜ]jÖ½øùµE^lÖŸ,5W[QGÕWQî'•\űûÉÙŸ<µ÷©ŒÍ̯Í'>Yl,&>iÇífÔÄO`Ö\Ü`¶2]*Žå+Ó¥L)>:pì?9È F ù¡œ8žùü;©N—2¥°½ØiÏwâFܼцæ–xi/tÄsw©Õ#M ¬|JÐ\3Š¢(вkV Jåé¯ÿ€çÌÀ ˆˆHfhH˜'¿úÏÄ9’² °ðDuxª6*,üÌÞ£ÌòÒ㩚ß/"’x÷Ê¡§b—xa˜o,¿|àø@±Z+TDä³GžcöOMa‘'§¤·ÉU¶Šrßz ¬Í¾zèUf~næ9~aÿ ,\Ê–R[þÄ›¥è¤3(ŒýÅS²Þ®÷MžAb·]Ó EcclÚL!0ݧ†EÈ'ìâvâÀ»Äß¾U‰ºÎ9¿¥÷p¼·e}4 ˜öeâYÖš¼²ÆÆ€×hE]3Š¢(ʽ X$Œ£©k`ßÁ/#—öŽÂPEdéh vö°ç½Çªåt–H"ó£µwŸ:ðj.$–¹ñJ1÷îScž)ä@$ úݽ“¯ bœøŸþââóOïËdížJÙ߯'!R¬|é‰õa2åëµ3G'W›å³¡ ¼ýâáÑZ–¦_.fQ¤KĈB°6ŒlðÖ©x’fuGÿ‹ Ô‡Pînˆ"­RþÜI$<– GDؘ+SCZ³y¤˜Éfü§¿y1´X³¥0öu—ºS'W ï¡J¬›|²nå@ns©ðÜÑ=scåj±0X-O ”/}Àô9Ï̉‘ÁJñäÓŒ¡|6SÈfæÇ*`§GÎç2áZ«Ó“\&<\©Á•6€C\¶4 À‡ï«7Û,â÷ÇΗKTOì¬9hòj5W)æüv<úùç’|æÜá)h´Û…lÖZ™¨9ÏC5C4\«œA7Ž«”£u ˆh.Á¥áÚ;Ï  µR!0FD2™YÚ…ìï‹—8gñœ¦îB$ÂÄùñ¡ÚõB¥˜GÄÕFk¤Vivº5õf{ÏèÐår8R-G‰k´»a`kåb½ÑŠ’Ydt Ro¶kw¹Lf¥106X«7k¡µåÑÚ‡î­ +Í*3WË—Ja>›ÉfÂß ö—Íñâ#—ra®Þ®o©)?–ÝK§†îX×å¥ál¥y%JN:‡ºíf;u E‰KÈCÛ§· ÉÅÃkAܱ²g+ ÁƒsXI'?¼V‘Ü€4"‰ÖA"2H/OíË™¯‚€ˆ\>ùîµSï‘! r­ÜÈZ«û«?eID‚À¾pð™Ég¦=û¡’÷¼ƒ_†÷îûÃ?}UX¶ ‘ê‹ç.½Qº¹Q„‚8ûÆþ‰¼¡v>ƒñÙ±aÄn'^øþ¥/LM–«9ïù6é'D$_.ª¥tU9 P®Q>{`x¡•‹Â@tpòh1€Ú?Íg Fò€€Ð¬o÷˜i@»„°³k¦Y»MhÑV:ùìùÉ!$ìd`Cׇ«Î®O,D‚L8ñÒ¿¸xÕ™­SЋãƒnvvðE>ú-CF*v†ï‰póLFÎNž¯†sÙ±\6¬”Ρ$DóCåÓ$KÝèÑjñFƾé“g+ù4þ(ʆÃӦߋ:«Î}îÎhқςƒ†¬¡y»î°£6@LQw$Š’8,Ç.qI±Û ®º:DQh—ÊL"k¥ü[3ãmï¿VÊož´MP§ E¶A–…sdW(ðÙ:Y46É[7A›Œ#jÛ‘ $»F6kìÙ@òÒŠ}|®Ǿ¼µº —+¿<0‘§íIîE•â©Rvï`e¶TpƬv£ìÊ‚¹ÑÅ5C‹Û€ åëeÙ:oÂ$)wÛ£]7xfßèµF±Íü;•Âkû'†'F«ÓcsõÕŠÙ}¹Œ'j”roìŸ÷ KQ”ª½%q€”:ಆòÆ,DZ˜ÉgS-B:ŽE£‡N5j'Öö=U¦3Íì@õäÔð‚w´q§Z*AÐ-ßÊ‹ ªôLñòØÀù|x£Ý%D‰*a°Å»F@òÖNæs–²æ.æc^ÄÕ*' á­{‘Vµt­V˜..WóSù|3q“ùìëV©½93ö]3NÄT’|þÍb5 «™à|µC£Õ-l°Ðí6+ÁPP‚•€XÀ!®Xœ³ øþÞѹv—AJ£ƒMïg*…⺙3ç_>YÊŒe³†Œ ì¾'_ZkžŸN—ºÝZC7Ú¥„¹[.Y¤˜ÿ8cL“ýãW-µc «µâë&ŠÆÈx.—G€Lp7—yoßX7q]ÏaÒ·Gƒ`‰Úη+¥JÙ±\ot:ûKÅå(ÎÍv»q­r2Ì mç£8oÍX>7ß)µœK3Èî/ç»Ý¬5‘ó¥0¸Þ.,•º¬¡ý¥öŽg³sÝ¢ÙS(œÈa˜ LØJE^Úsq´86·zŽnö¸yHÆ #tŠnЂܦ+‚âr5Ï ~t• %šŒÚ.!@×9Wq ç“{ “s'›YÜÍñŽ9?Ø„ç«B‘(SmÇ$_–V,Ýu× 3âÀÓcϪ""žOœðôö“ °X^:(7D¿ºk¬5G_=øÄó¼cÙÙ5#ã“SÛø ɘkï|xÁå|lzñ_"ˆp°g*»gbAÄ3°æVÔ5£(Š¢ÜãXNè6Ã2ÙXÞrç¥F¼eLfû{HE¬g°îßñ,³Gp̉ç;椑Íþ@P ³aI+!‹eÀsº§?-;þïï‚&¼eÝzQ"’.'ÙNæÀÁ|ô!)! l³ ‹e¶ÌFEŒHZTÃb˜I™-o,F@`φŰ@ºRŠú£Ý´ttSÑ{‹/@QÓm a#€"Ø— ŠÌóŽ šú/êKló:&ì‹ncl ”OÏ~ÇšBÙÖ!‡" ¼“QæÀ3‰aaL¥tÓZ¬mg’žt½.H$`AfaNë‚$Uj°ÌÑ0§êm=[êé¼0H–…$­šõÿï•D,2”^½oعXfJ €È,›Ö¥Wg™Ó©¬0=­dH÷Ãq#Ös*™»qÍ ÈN§_¥¢³ý b ¼³e¶›,‘XHØz±=Q3Ã&Ó°ÌÖ³1éb%Ù¼  úUÉ’ŠNú š€Xl*ydI# 3¥e-3§ÖÔ;ŠaÆõÖª:ì×—fÓÛH“¡¦'J¯‹ÖÛaƒh„í†AÒ ëÙ¾/ÀþU¦¾f ‚ˆ‘ôÛ´ÌôebÓëíi ˆa |*jÚ¢ÈLÄf‹kF€ïÊ1 (÷îNa@Æ4øV¿ÌzWEŒÄ©ÒÞ¦K%|ðâtA“l¿  <{çfž­ 4ÂäŰÜìšA¤Taî>}•ˆˆÏÞ%~'§Ìfï o—ל8µ¬ž¥·8—YØ €zd” R(Š¢(Š¢|šA¤Îü¬o·Q¥¡(Ÿ$ㄤµ–ëÓ¤Ed¹>ÛÚínµÍQ”>êšQEQ”]ìwɲ´ÃEÙÝYRP`\ûÎ_µ¯_!k{{­M_ˆÆP µh4æZQvËF]œD­öCóp4ô>ùÁÏÿbnéÊÕ¹sÖ€ˆDAÝ4ʧí\EQe—‘Îýdumv|äðôÄc"šfPùgH˜Ôë×þæÛ؉/ÿe³hìÚÙÓK¯ÿ\ØO~åkñêjãÜiN4fâK¿½zêÝ•wÞÊM˜Lføåψw*BEÙ|œt­ÊØÃ´Ðà kȬ6ß9óÚÑ™g›íúÕ¹sû&ÉyÑ%EʧšQEQ”]éqÉ\¹qª5?ò…¥Õ«íΪr+§BZ{åÛY{âÉòÁ#3‚÷œÄ¾Ó~åÕãÏÜøþߺf#ZXýÌZ—/-þâgËo¿1ö¹ßä8jœ;ƒ¤ª«(»bÔê¬^Ÿgæ‡l½¡€TKCWfÏ0ûVg­ÝmfÔ/£|ºÑ¨EQEÙ¥!v³µ428SÈמ}ìkžFÍ(utôO IDATùâÞ?úfP(RÔ?8…HIkmá§?„€P˜Ù”ËaµÚ¾q-(–‚Jeèù—®|ûߥ?‘›ÞEy0¦J”>»íaó[6Ú{áúûíns°2JDÛæîU”O 5£(Š¢(»ƒX›iwVAd~é|7jzvà}" Þ'¢“[ew±ù‚[kÄ++Í‹ »¸Pÿ½}øÍÑW?/Þ#öž#%"GˆØŸG"á8Žcá(ÚòX7EQî;I€w¼sÑyö3“ÇN_z{­¹4<0™¸œwéSž¼ºi”OêšQEQ”Ý@„'FÏ.œ{ýo_¾~²ÕY}ÿìœß?ûãv§~öÒëæ¢.qRvO!½ý—.}ëÿ¹ðçÿw¼ºÂql²Ù X¼òþ]óüÙÖÕËõßfñÝNvxÄärWþê/—O¼Aa-.Þøþ÷8Žo|ÿ{ÑÊÒüOþ©;?‡¤£JEy¦Êìsq|êï~’DñùŸŸˆ:s¯½½zcá×vi¡Dq‡Ù;ŸÔÊ£«kó–yçôOœONœþñZkåêܹsWÞÕ”ùʧ ]Ф(Š¢(»2)æŸ}âw½O¬Í ¹Š5Á¡™ç›Ý7õd`C œQvO!½¯=þdiß~°¥RaÏ4aåè£Üíš\nè¥ß@$ vnï7þ›…bvd´;?¿zòí°Vyõs#¯~ÎæòCÏ¿D™ŒÎ(Êý·Sæ©±Êø° ‚G>÷¼ ƒ½O ²Ù}Ï>j‚à×ñ‰Úbmø»Ÿý³´Ës>ùÆÿ•!cLptæ9cì£ûŸ ‚l>[`mU”OêšQEQ”Ý”f‚<„i^ɆEÙx/húCe—AÄ R1ù@˜l(“íël﫤±vãï¿kK¥½¿ÿLj”Ê ’¾ÛbQsÍ(Ê‚¬¡À‚H¶T‘°‘L!ÿkíÊÏe iùE8—)€€€¤;sÙ¢ˆ² Ý¢ò©B]3Š¢(в{Ȧ¡fºµù]Qv]#eëÆÇ ¿øÊÈËŸÞœä"ý•úeåÁÛ©l2·_÷ËÍå_ß–›.M›åS‡ºfEQEQ”;M¥¼¯Y9EQå ®EQ”‡dÞ$ȰsB@AD€zâ>Ú_#zc6ÿ7ä Év9kñ^ïs!Š0 8"OÎôö0yéonûQÏ>}ÄÃÎðÝ?~T˜‰ /YgàV! ¢ Ýú§L$ˆÀx2‘ô*Ñãv¥Š,Ô‘ MïA &±…®Eo°ãýµ8‰úi/ÒqžQ" LõF€׳¤_0"@b$ƒD¡Þey‚Nˆ-‡þ¦„”C±³.± ;›ÄA,(Þø$ˆ'˜8ëâ qÆ1rb“’ô°Ä&I{pdDDî˜YX„¶W]gzZ´¶84] 19g¡ƒ ^2©|pÛd`H<‘7Æ2¢#b$ˆQ" ‰éÛ "ô†<&òÆPß½1žÈyÍåB(é ÑzÙÐ4èý!":ÞTL[ì„H€à ý®Ü‰&ƒ‘…N€æ.2[{È@·_Ô›ŒH ¶Ð 0²Ø ²&Ú!&}ÿÿ@b!1Ø ÀdL‰Å®k±`1Ð`@쬥 iU²H,ÐáTüL˜Ö‘ô+HPb‹1Bä! Àì³D-³Øµ€"15ež} ‘'ã‰@Ð  0ÄØ`°K‰t…CkÀ X„õDˆ‡‘…n€b ã!²Ø 1 0Bè¢8€®Ã."x€Èb ˆB‹í¢"hÀDb QN ²Ð 1 ¸Õö0t€1àÍ6%Ћܶ©ô÷¤‚,²w—¢vªQm—$Î=Ì=:‚7âÍ]ÉŠQ˜xŒ‰s܃Mc\OBÌŽŒCØÔ6¹8î.­™L`ÙBY(Aº}Æbé ¤3ÛfÅþU3³óÑj3iw!=ƒˆÍ†œ<ÌꤨkFQEÙ­1ˆIÂêÜ82;ùV&¯_/°¾õÛŸíº»½û-Hƒ‹ Ç>ø ÷äQ&X˜/s½ÿA&´ùCûä–ÑdTðB÷r žhiphæÂ…J£‘yôB陓''‡ ²R/„I^x$Äøû‹å¿]¦ÿrâ‹ ¹‰oßèÔãC_Žþä÷ÿYϰ¿Rüï^zrñüêŸüU—€ê“.5‰(Ú@®\ÍãŦgF@ˆl¢7' &JÌpŽ»ÖBûVˆÆŠKY_Ï<}¬²¸˜-È [µÿâYÍÖ2û 1ïàÞTáé÷GþÏé±§†³-öRÝSÚûúÑêñÚ“§žþ¿Jq<ï:®8š?|¦>v|prpê7¾û9×ô¥±Â¡3+ƒ3åúÕV2LªÃ;f"ofÂ-~AX˜ì½÷Ã`û÷^ž|tàèÀÿp¤ô/Ÿýé«nÞ'Šòtö{\¨åâñJ§cºåùѱ-õ‡éJƼU´Ì¡äle¡9W;¸çÉS§&$Áã‡ÿp¥üøw—Šã”="¥æÚ£ï¿oÇ›­ÉxÏÑÎØÔ×)A>“Yi6Ed¤V Ÿ"¢NÀxî"gŠ­š‹ ¾]óoî???Üé¬OXD¤˜ËNŽ µ/\1Džy8k¥?Ù8tqáÑŸùÖé6X2´çùÑÙ÷Ö¢ÕôS]XÂr08c¯¿µ†öÎÍ'<ójù™¯¡ÙêœÏ£Gƒúl{ôpöÆ»Íñã¹Õ«­™àÀßÔ_ý¯lð¿®™Òù•8= Ì}§í"Îeó¹ÅÓkpøK_r®1ÛŠÖ’Â`vøÙìIÓ4y ºq©‰ ‡ÎŸ\m$Îù+Ÿ›\ÚÅd¸Ò /_–³åƒŸyž†ó;ßë0õk­ÂâÚµ¦°ŒÍ¥Â`tô²wqä#Æ}r­ÐÁŒuc¥¢T——ï½LCîh+ €©$ø\Ønýö‰ÕÂ;ÔZìîûìxm_ùÍóÉÍÚ°`›sɧ²×Þ\+Oz@X»Ö{"¨_iY»v£5~<óì[kÃÇlÔŒ×Û™RP›6+—›q31äla¨³6ÛªŽ‹íl5ÓšmW÷ÙV ý†Ø¿h 챫W;ìdp&óÔÏ×rƒ`ÌýONŠëÍ…æç*И-îNa ¦Ëa7 “ÛB€ÙÆÕ®ë²pä£ÈG " '1Ç1ÇéÇØG1Gž•›¢ìRŸÅÝ•µ%Fí5å¡FsÍ(Š¢(Ê®Œ°[ÍÕ“oÿfóåGñ1êŠò 1h>Xx÷ÇW~€€_<ð5CÞ[xçôâÉŽk?;ñJÖæ~pþ¯§+3W—¾´ÿwçš×O/¿gÐ&㑞µ¹—sTQ”Í}ÇýZl¨(Ê'uÍ(Š¢(Êî ¯éÆµFÇî;ðÌÂÜyï -èäVù˜ ¤]þûß?ö§„û. ƒHÎæöVt’Ö©ù7_˜úì@nèó3¿ýîü›ï-œpì¾rðøï?üsD½{¯(Š¢(÷µ_V(Š¢(Êîà]œË—qtâP˜Í÷ŸÒƒë{ v}'ärC{Ê3„¦•´.®žÍØÌ`~”… ˜)3ˆ¥ “´ÓÅ› )Ü¢·ˆš€FQ¼Ån5:EQ*Ô5£(Š¢(»D._]˜»ÇSo¿¾<Ûj®ŠH«¹ÂÞ5›+Þi e÷‘¡ÜصµËçV>üÙÕ:v¤ÕŒ×¦Ê3«Ý%'^€EX8$öñrg!òQⓕ΢ˆ¬t–»•ÎRâ»êQ”dª"ÂKõi4ëÌ~­Y“X…£(êšQEQ”Ý€ÙOí{Ìáë?ùV±4`lpáÌëÞ'ξÑé4®_>Õn­êPe×ðâ¾zè÷qíG¯_ýÑþÚáñÒÔXir_õÐwNÿE%[ËÙüÆÕ¡ü(äƒÂdyïGþáÂß¼yãgµì@#^{ýúk '¿¼þZ#ªŸZx{¥»¬Ú«(÷ ƒL¥XsÞ¿ùÁÏâ$zÿâ»Q:ÿör}AsÐ(ÊÄæšQEQ”]>öyD~ü鯰øÇŸú->òègDXDSÏ(»5å)e+ÿü‰ÿ ¼¸W¦¿(Â{ÊûžA„yZ@@Ä x„м·pâÈÐc"°­L•§§ÊÓžý—þ fïo±ôBlE¹¿v:\áßzéëÌþÅÇ?ïÿ¼ˆ°¢âŧnDϼÎåAÚiÚAxŸš›_WåaB]3Š¢(Š¢(Ê&‡ålµ’­õ'ŠÞ¥(Š¢(÷uÍ(Š¢<<³§ÛezøU²@l~ú ößé^Jq{ûçê½De£Œéæïý$(ùÚ7. Øó¶O»Þ¾<ëe¾‡ ²c­1#2¥ÿ/ ˆ³ˆGð´£tÑ!#2¦ÜAFÁtg_HÀ›^éG¼YÖ¯31àn9¯ $<#`O˜¦è¡'H™€ðÎ@ºß#€¿ íå»ÓÞ[k (`&`JE˜nn/N`DX×ϾÒöþÚ0‚àÆþÔjÖ·ä¦Þ¬lé÷ýàÆÁ[®w¸L˜˜ôÐxo0ñ÷–iP6žô~‡ç1¡xÂõ¿# ît0ú •@GÈ„žRõFHÒ²`ª<éNਧ{©½xp #dìUßFE§U ©¤A…6uS램wÄu%¤Þ需d@îk[ß¾d½Æ)µs‘õ×ÿ[FH ˜ÔR 81!ì±g\èœé™’ïYVï`G˜D‚€À›ÞaŽ6Ná 8Jë«'.ëLjc¸¹½cBîµ17Õ”ìiºÈŽ­€zô>B×#p÷PÙÍÜ"û$òñzz)ÇÞ±Û¡´âØGÞûMWc Zº©ÄHˆ"ë]4¦[Ä755(€ü‘;qEQ׌¢(в‹C8¤8 o3 –Áˆîmô†]ÂU :„qÅbƂ툥Hîáˆeh9ví"®Yð¸P`W,&‚<¼Â…e0Û½·ábËÜõì@À4 "K'q2y|4ÈÚ­ÿàÛt«w›Œ‡áÎ=¸f$õ¤4 ú[¾@àC×d˜.ÃÑzíɳ™‰\ö©FsùºŒå–ËDÈEîèØ ¤ž¬Bðž;µj¾’Y«{ÏiI»Q$9qâö5q±@Ü”ˆqD ±›ºNò]÷ÒŸËKuÈôÆLa ¿ü¡ß»ÇÔY˜ãà矆=‹ñ g\¥ââÄUJIm!ÙÓÆò´{ô’‹b_­Æ•YIF–|®ê¡Kî<¹Oáâ6ó>ì®X ¶íXËtžu2Ê£+\r¾Zò¹ÂêÄj·ÒiŽ4[Å6nl!ÚúÇ\…dûAÁUK«–€q9€–&l¹#—¹Vë "\±hƒ ‹-C«I'_XÌ\³ ‚d°ïús‚-C](Ç0ØÀá’ŦݔmW0¶˜7¸j‘ˆ˜±CnÇ~ÿõ¸²ˆD €„°]p%i·áAçë¡lÖŒÄöÑý@ì=ï7qt–ÌÖƒ…ÙON¸‘Užèºà*OsRZàÑ‘ø¥Ó0| yþ [ÛÿvÓ“2Îî™ó.q®Xð¥bRž¿'Ù%q£kI§ãŠ¥db²­Ú €ÛµöZ»(T·¸P‚Ð%jø¨›hŒ4 9D+ŠIk 0wðº%rƒK¾TÄdxEDüdŒõ¥gW\±ã¸”‹ øÐE“]@ÀiÅbhA \(dE$ìÂ|Ç_Œ×š¼`DâN[k! M&O¯ÊŒ‹í…¤ZAÄdb•§÷$µ%ƒdªî÷FIpÉMŽ»N7™¬S6뇆’ÚbEl-e2¾Xp£u_pãuŸÏñDÓÖ’‘5 v^äá!W]aïýèH,çL>»gàX&Ÿéi$ N϶kÕ,Ì··T+³¯Br%(,[¾M6haÙÃŒruƼ sW35öz³k~™Z¾úåCŸM|²>`á¡â`Æ„·öd±ÏMØ[¤¾bƒ'϶Þ=ߤþD,™Ì`Ǻ"VÀgie€›áfuÎd%õYpŠºfEQ”O.l¨Ëïx¿¨ÞÓÐ ×,]Î@Œ@€k†:„CÊÑ6^¢Áö½¸f¬“é ­ó8FK!& æ\†\t=]‚¼ïŠ+ÈÞšà=,´gÀåî:-FDó!AÜB>òùñ·¬æHˆ–ìú-ñùûB…DöÔå^¢º·àp³Ó9yæRÄhø ¯Âk“‡3¥b1ŸÏ—ò7®Î}—ÇJ`ž°7ù* ÜŽŸÿq`pyþàµÜUƒ”Î߇Ç*ÙJp½uÝqÏÙÖJÚ\òÑ!‰NJ;áìöÖ ,¼‚#hXˆe Ñýâ·l0æÇ<±î4À©¥öÿm\ýB·sYÀ'…CíßãêWäè¹vþÏs¹Ã‘od2ãæ;Qù~,~ñ‡1×s¹½µ_ºò3Ö I^I®>û;WXäÙ Êfo €6,]ÊPf{Í'2Xl¼ñrô™ýù—ßKìuLEG.¼|llÿͯFk>“ø°µÕ—aÁI÷'5 ^ i!¤È@‹Ì… í 0!š^ŒðŸ|ö€d~Û†.eÈ"¹€VC¨t9C–ÒJ¡Œ¥|H+NXÈ…à±3´ÀTGü*  ®A0H³-óú#YDK!ZK—3dPœà»«…]Ÿ<ñF~‰@½3ú{ñôkíø⃞űØW<Ö™ùGÂðŽG{Ždì÷:cÿž0ØÃ’Ä•g£ÎuWy<žyƒ«/Å\éX{èÿ‚½Ou>ÿÿÊ¥?aI¢Ò‹¾úhTüNì›&3dF:ko ãdï×í^í$Kaf*Ê¿8+7r¶Ì^X¾ž¹&(t=C‹1E׬yú ²¦Û<fǰÛ>À®ò”P˜ØšnÄɪˆkGÛk9ô壯á5 À¦¡‹ÊYÈ'Õ0‹Â’-åº*+ÑÓßït.¹¡?Âáý¹¥›ª :í÷ýÐW:{ÿ6›Ûˆíö9?ðÙnó6ùvçbR{µ3óäò\”Ô;  &…ƒÝ֙ȭ”§ ÝÎå¤p¸Û¹d‚Z’,GÙñn÷:›¼LÎt_ú‡¤t0n]ðœ¸ò‘ÎÔß±-xäÅB-Ÿæ7øÈ;«åQ;pay‹kF¼+»©ÌL.…!ám*žö1jf¢» dªF ænÜì¸à‚›{ŠgÛ@d"OéäŠXÒÄDL©k†˜PûkšÒ5 ½²À¦%è²€ÁVç#º<ú\ÀètoÐe!Ýop9ô„ÀàCôº,z . ÞôN}GiùD•VßNž1#HCb`BoÁ2#1ôĹÕÜÒ…* ª$ ˆ‘ ψ ½š!PjG"›‹”n“lY”„ €Ò[#}³"³©fEz?ìýÿ-ºÍ9‹`{•æ ¸}o‘"ÜÇPAÁ[tYÄàÎÊÎ=­¸õ`.@€·èBð\Þ +¸,R¶$¡·à ú :‡&€Ë¦ö‚Þ ¸\llÒZTù°W©„ ‰©/a¸Éùç- A }("à-ˆ2è,¸ÔÖLjÐó&÷ÚO0,D‚‚ ÑåÀ`B—Ê"„@¸,¦Rò!¢Ë‚³èB]R“q¸\0ìIÌe2€P.DoÑØÛÐ…2¢Ð[p! bZqa·õ¡[lÐd‹r³F˜@ ð]gjÌÃÝÈ]v»ì¨`aö|÷­ó7ßHqäÁS†)³qy„ˆ(”^s¿ssë/Ī>ÊC ©EQEQ>µ B·íu•‰¢(Š¢|Œ¨kFQEQv±ß5DÆ iÿ«|Ì ‚±h,Úþú»Øª'd0݃¸ñ­±H`,¦ Ô{׊²v hȤ/•†¢<Üè‚&EQEÙ-®<Û®¯U'F†öM kÎåcšï!´î½×–ì9ôL%[0H°xµsñT޽4D|áäš1(Ç?7´t½sþÄZ©ÄÏŒ¥Ÿ~{¶6–!O5D@–nDÃ{rÂðÞkËÕøÂ»k“‡ ¿üÞ\s5>õÚ² ¨Ûö?úÖõ0GŪ%ƒê—Q”Ûk 6£æÅ¥‹Ç&ŽÍ­Í©@åáF£fEQe—Ù+×çFîš™˜ÑôÊÇ„÷|íLó7ÿÅ1†Î¾QGDùùwf;M?4‘<\Þ“›)T†2«sQ«î޽8PÍüì¯ç²;¾¿ Ê«(»@`‚¹úÜkg_{vß³* Ey¸Ñ¨EQEÙ%ŒµI7öêš‹“tASúΞA'»Ê®ÿ‰Ð9NºÜ\MÄÅò‹ïÎí_ͼòõ1²ˆÀœ>: A@â®`@ðN }`®°WV”û‰ˆdƒì?ÿÇÇ&Žýë¿ÿ׉OÒMž}ú­®oR”‡ªkV(Š¢(Ê® ²yhfjþÌ¥³?}ûÜÏN4—V.½õ¾wîò[ïw­k'O·W×t‰“²k}iàgÿaögß™½úaÃÅŒ¥ZðÞkË7.´oœk5–ãÔów|¡Á‰Ì»?Zz矖ŒÅÆjrú—+>‘׿7Gþ⩵չhîbûÌ›«dT很õNý?øÇVÔ:]Eï%]è´þÕÆÄPUXQ›ÊHßTA2ŠòС®EQEQå¶“C/šåWQEQêšQEy¾}þMF¼çµ ˜ôn‰'‰gϘX@Ùö<÷zïÁºô’‡gâô¬÷œkýG¹·/éñr‡Ýº“Aœº‰ !¢7 Û]«q@ Æ ÃzÕ’ñöBAãÐÀö5·¥ø"8îÄQ!“é:—xßHâ|AôÈ}± €í‚M¶\'¢ mƒIÐÆ 6Û$Am‚ƒIÐvÁ8@› Æ`°]0mä|ÜøÿÙ{÷»ŽüÎïû«:û¾}ûÝìn6Ÿ"EJ¢$ê5Ò¼%Ç3ž{<¯;qâx½‹ A€ `±,$,‚ìn`$ÁfaÇ»öÚØñŽc=3Gó²F¯‘(‰)>D²Ùìç}œGÕï—?îíf?n“MŠ¢8œßÍæísÎ=§êW¿:§ê{êW•¥©K×ç&Žcc7O{™ÃxÚÆuÈncbGð &Á0Œƒá~•‹¶–mÎÞ1V=ÖºÕ„Wmbs²þjò GäAy¯|D8PN"‚uÎÙÊr0˜à,yC΀»×ÊquÒO¡Õ1àV¯¾šJ2&B@‚qä$éû½ d°AŠÜwHRX Ùz0‰£ G“u2²Aë´É0 ŒY=2GàÈzØHää¤È:XGpd$ ÙÆ÷IG×¼9ˆâ5îYØ!óNV+$Y˰9l‚Œ„aŒ!ãaIq}²Ï@ Чj ¡ C˜ÀzFÐ!cdds RX‡ AAJA×&!Ân•Iä$9)Y‡ '¤0ANÝšh‚¼W+mŽ GÀt3â(È y¯à‚>·xëÈ:²9‘Ù˜xOä°ÔvsMg¶¿;3C Eï¬ Yg­³;:Ø‘ñæ'hØZ–É[ïúj‰Vo…(©z_°¹À09&!gMf±ÞŸD(ú?E¥EQåŽÐe€Bê÷¿Ý²Gqÿª»GòÑ› šðÚO²TÄåþç¾ðPÚ…'²¢õµÍ'´Œ}§9<~3Y æJs>}|O{‘¹(Öšæ'|§á‰ÐZô\ˆý©Ý<:„*ZlXnü"–Ò¼óGŸÔ‘ekàËr 5CÊ’ï 7ÁGh줛ú—×fH”:ËŸù—î…T׉C¡üû}»Ý…ÓŸ™!ºO`Ø¿~oö"ücû0flJ ÍJö§ØXÌÌ_[ˆ5æùò—™¹»hT… >ÿ_9?Ýžm0à'áJY¨¥þËa¥Ì?» c²–i4ùÊod÷ìI/á|l4y}T&ùÛ‡Ò¯9J“¤Ð¨'gæ{§y`(ûÖDz$ËGÉé™|f²ufïƒO<ø[¿ú”s…áwþÏ÷î˯›`C%OÒC{Žðz E@†x­§¼Û¦ÄK¶Ë¥sËn°åÞÚ'ùn.i†×õ“A@må m­ÊqüáC‡: KKƒ–Û >u^FÑü¨Ï°DÌçÆóç>–70É(ZO±5’4¸Ýòn7Zð¡•ž¦s«é’ÔXBðžÿé¯üüüõ·ï?¸Ým?pÚWŽøKÇ|+õW•)ølXZo y–|7£+™Y`²ÔúÑCéÅi21ä¾/}½”¬4ßï…ÀD`J75‘žܪ£mÅ;ïy ý;»õ`öœïÛ]™Ïg¦ÒS#îàÞìܘ›O¾û¾2™|õKA\=rï”›™J¿ûÙ,Í¢Z%¯×’³{øÇÊ.N K:¿˜´Ú…º?47pý éqi-ûÜù|‚ùü.¿\Çhì>i » ì~çã³Æy˜ÿà8EQúîž¼Q'¢ôÒ!@ÜÞi±+ó…é¬Õ?íQ\Ú£q´>ì}HBÀ;kÝg‘¯?“..»ïõcÉür†TŒƒr)¹x$àpòr5nQzùÁüð¾ôÜŒÄQzeÁÚ—œÎ÷LeíNrå˜)•ò‰‘üâþ¤Ý‰¢È– A¹œ^9’ds£j9]içZ¶°„8âgÏ~"ß5–ÍîñÞç»ÆÓWªTˆ¥1ˆaéêÎ$ðF¾ÿäâH=:3=o6ê9g9Lÿúá§2—]»¬¿ùÊHuüÕuu™ù¡ùï~ø»qïäxÏþðÄáOѧ~"Ô™Üñ/}näçž\"¢}?ûÎ×[A‚%Úmf{~>»Bë´<)†Å|ð(d:‰¢ÒŒ¢(Šrg¶ã@Œ(»Ö¸‰{S­6à‚ˆ¥r,_)ô{õ.3!¹¹Lˆa/1$î™ "1„ÀÀ€ÉC8 €oâ½™‰näx‰ ×÷b¶9mLV·åf,/àÛ…NÿAí‚ät"I’éJ4’f YÔdÓ´ b‚ëŽ:êÎ`0X©òj j”Ê¥œ $¦wZ^*1Š’‡ëO,Îòb í¢4f‘jAËðV²ˆKR,pÇHT”å’´ ðFšI¬” ²T’v‹—«—_•f‚8*3âfbà ÛI£~vêº.oÓØa !Êd!Ò@lʰ^›¬w› œ¨EQ8fÄàØ ,¸‰\ ­¢Tb‰.ˆ!’â€RÛž%Ž NX qoHˆ TË>äpY - 3‰;bƒ!XíЈˆÄR1Ä,².§’tbY*ÂØÒXšEYb˜÷[šñtb^*Qp}iFœ—$ê{°x–NAVВIJRDK«€$’Å\ K%‰‚«G¶cÉBY)rˆ)JX¥$‘´ Â"+EYEä!›kHA$@ h‡’‡@¸Ž¥Z/^=¸‹e¥(Q†d¥(t X±±t Òfq—ôóIH&hC55XiyÉIKÈR™#+.e¹$X–JR(‚ˆ—JÒ‰¥Y”<’¥í^Å‘&d).J» +Ei‘Ä‘p,Tà•¢ÔciÅ¥)d%ëÞT¥YNAZEq^:1/•$áí¦A­‚¯ÄÜ*x³± 2ï}Œ¡BîíµŸT$ŽÀб3׃ · -øìØ¥Qú“’5”˶RÙp_&¢j+…0áaó…¶³+f];ƒ…}èŪÿ(*Í(Š¢(w¶:s±â=¾L“½ö÷ïÕœl Ú¤/POvx¯¹éôìü´²³¢é_ž×Þ-ë~¯;š’kˆéíÝ‘D˜¯NKruÎIÚœO#´õº˜Þ{{×®n¤ÛKI/Íki[ÛhDHX„eÔ´‚n¬ÔÆ4ÐöyÞYv Ûš®o܉È:{¬]bÝÏÎ&ë”2ÙT¡ÖùµlP7º m,â-ß%ÙÞK¯Võ»žñ7‹MÆË­›‹º{•Õß×·~¯ÄûÜÍÞzçYï3ë¿ÒÛ¬÷+#êŵ“$›B6•цIW¯zr7ñ Ùäê«Iêël²}%¿ZI·œjC¦¤ç7´ÑÚë?ôùÙhí¶¬å«_ÒhK}ëþ)Ò›zÛr¦ÝÞ”U« ue PoÂøkù¤ÎlšÃ˜ DÖU^½LѺlfRînŒš@QEQå§·-h̉S¯¤yBÚgV”; "j^i^zý;]š^QîrtÔŒ¢(ТܾF¶5–qìÕ Êˆ1ÆÄóæ™×¦ÆfŠC0 °÷Œµ‘s¹5–Ètxö† ëÚ½Šò~#"ÅZ1*E;™¶IQ”ŸhTšQEQ”Ûµ³äÏ^|öJséž±™O~ŒtŒ‚òaŒ9wéoüðÿ+Ä¥ûDFÞxçÕçO|/ÍÒO?ùyÏü—Ï}ebxòÒ•wý³ÿù׿÷ê[/T­±OÜÿÑ—N>üð¥bYÕEy†Ï/^>yyÿGöq­pŠr?šÕŠ¢(Šr;ž¸d^9÷æÌЮø‰/ÖÛY‡T›Q>¨þèÛ/|ýW>õŸê‰Ï‰ˆ÷À†ß÷‘#ûxåä ´ꞟÿè—Ê¥ÊìüÅKW.|é™ßØ=¾—!ÚЇîÿX±PR]FQnOuÕXCEù©h(ª EQåö´®“<*× ÑC»W åµNòÚoE¹=°0 Q T3»ö“!¹xåüÂò•,K™Da‰HDYžFAÑÐÀD&tg']çºêÊò~>A¨§æ®þVå.B¥EQE¹¤.,]f‘ï½ýò\s¡“%ÚyÂ"­¬ãuöå¶µÿŒ%²í¤µ°|åÍ3¯²÷žùÜì™ûÁÂdyúÙÿRæ²j¥þ‘‡ž>7ûN¹X¬ ôágXøKOÿ†gÿðáÇE„Ó‡uä—¢ÜâËàÌàО!ayò·ždÏ÷þ~ñrì ‹°>2åîA¥EQE¹]lˆó~]÷Øpâ×>+Êmƒ…Ù¯Dxà½[ÝyÕw*Æ¥KWÞ-Ä¥C3GÜêaݾëºÚCT”÷éÁÁÒ.ôÎ'k¿E¹›PiFQEQEÙ"ššÜ5<@ÇÅ(Š¢(ÊûJ3Š¢(wOêûÞËÀgñÖMƒâ˜sÿ¥sßÛ<öÌÂ~5¥Ž…ˆðêY¥ À,¸©Ø¾Áõ~½0äfò$  ±€nø$ k$µ;+$K×$àuÛeÛ"01„…=Xqì=3 3x­×í¸Ï YH "ŽY"½"w‹Jhs˜ÀDBݽÄ! !"!´v€ ÀÔ7#ÂL Ú8ý¥øþÛõǼ*1À’AïÄtµ`zîE‘œ ;ñ޽@ÄùkT8Ï옻.ꘅ‚˜…z“wöÀ€a‘^z†ŒÄ/ì×UQt­L݈t¯eÖVD2Fˆ¸{]Ào´@÷b""$0ˆéêüÐÖVé½·¿ö¡Ý$&a€»÷ énˆé}èÝND@„®“lHØU/¢5?é~è: A„½À Dݽ0‰fîfvµ6]?dƒW=@·¬Eij¬e7¯öì=zE¼1«´æ±"†¬¥°—à®Gaõ6&~µÆæÌ3 ]­°Ò³ˆôÎ "¬ÖéÕZýZµL·ÞqÏ2ÔKÌêöÕúµ¡fõ*×útö’ºº«ùºÆ Hnò¾O¢#¬nä1"Û>”…×=‘/?é†%Hïþ@±ô*ð:ƒ:¢ÒŒ¢(Šr‡7iD,»íf,²«^o”Jrãr†ˆ U«{¢¢´:é]áÁ‰‰r\(űliZµkEws DkêöÌ 4†ƒ( ŽŽÒr{`tóËc© T ¥Æ&l`oB»š°;žj·E3ƒƒ†L! ·5™~s1N Ì-ͯ{ãs£ ¥Å4Î6ë½uç£ldbÈXS©•ºZ¦Ì®–³¥nWX6ö™£(âz6Z7Ui-6ëZZÏ<=°k°ÚsC•rG"’º¬IJñû&°IÝÔê¥{KÅКÁJ¥E"ˆ ÑÞ#ÓKn£|ý%}è:CËYµ•¤MfÉ*¥öÐ2>ÓÎàJR‹’(-Vm§±’VÚl}Rkeq–U¢Nc%­Ô“ÁWÈ6µÃE¤ºkd±áâBa–¥Ýå›+»FŠõêVµn¤Z­DÑžÁÁÀiîÏÌ.x–|”g^¤Ôðbˆ}1÷Ïb* =2~ßxuÔ;ßÎ;ŨØ8z¨Oé3À$Ø?32P(\8ûnäåÁ±ñjΜ»b¹0<9Ç©ƒ¯Äñ$³¼Q«OÔë÷[c¼ó³ç.DÖu7T‘‘ÒX£\¶Æt;dQ`÷Œ '®µ8\«WK‹CÕF¥4S¯M°ïz²÷þò¹‹…\FF£û'& Q§Ý‰“«BH…i1ètWzK\B å³bŒ! Q!Œ“<•[4É‘5ݨ’+ M'ƒ•l¥•:Y›ˆ*qe9Y&1¦ Ú0ó¹…M‹­¤Ñ§¦0s^íá¼”ÊPæÊ)]^J[ƒKA)Ýߘm͆A˜ºÌ{/µ‘ú`Å¥ƒautp¤V{q…”}i$ne­R¶–¤^8ìö‡qš`z`—%cˆŒ Åñì»ãœ}äò((Ô î1T ¢l¹ çzõŠ(¯t‚I½Uª…JZqåD‚€KÖçYn—sX²{Ó,\ŠKgT/–ŽMLDA°tyΕ² dE„K‚R6JêçRi奄c×\Ê.,£3¸Ì•¼ÓXÎê‘1ÖûÄW37ءРei¹•·}=KM«“7ãšÉ+íl Dm‰"[òA™Ò¬™W+iÒŽªÄA–×:¹k# MLy½Ã•,¯·ó¦ÆÉàŠ-y¸MŠ?IAŠ´q!’ìDsñYQ¼UufB‰$îó@‡Tãòt}T®>âyº1ýmTáˆ]ÈqÆ´&Û¨‹PT€Ô•fEQ”;·Uc„‹Bÿ¥4÷_8~\D<ßðZ›ŽùcGŒŸ»’8}{Á à¿ûÂ/twmx—,ÂApâ¾ýG!µm:‰¥Ò#¿ýŸ=±š`þñ3?û×ÿì_>ñ‰Oþð…Óõfâ™=~¯DøÓŸÌû#@dí{Ìó޾È"ûÆÇîÚÕ­p z#ÂpóK‘/>öØŸþÞP£boXE ”u~ùâ%{$Øtf"ðC‹Í0øÂ‘/¥YzèÁýD´´¸Fp8]ä¹VÙ8ö!6´_Edxt°s|ö£}¾Ð*¼|þ•£O­V……Eldãoâø3ÇSƒÂ ÷½AKk ŠÕÓÇ‹ŸðbÛ7ÓòÔ›c/…ƒ¼1þÒÑÉ)Ȇ ;wôŸþ'í?Ú[¯ŽW‡ßž? ´Á—îûØô=÷³÷{6ôÌý¼pæÌoâ“ÕBD—æ–ÿ‡ùÕ¥f²Ï·ÇϽåL”~TžCÐiϬt¨%N>¿ï3ÚûHwÅhŽý¾ÿúù,Û\åà¬gƒßþ‡Ÿá/þÇ5ÚqÿøÓŸyùO¿ææ÷Ú=0Sþã×ÿß&–ïóS.IŸÿ£?ßÿØ£ƒ3“¿pü8µç—¾òßþOœû¥Ç’‘Ç~îO&νë:çpµúŸ<óÌÿöÒk2\ûèèð+ÓÃ?31ú›÷ì-Q²´òÕò¿f+­?þÔîãGE0ûæ©×¿ñ0 £Îœ®Ÿxýž×±<ܯ>úùçO\üV)([²‰ïĶphðÞ3ó¯¥>yï·! FDäJ2[«ŸzèIwßÒ8ýWŽ?ùÆìó‘?6ùôOÓ[jšçˆÌîêž·—OÎT÷ž­ø7Ão[ÚÜ.õâÊ#éHytÉŸÍ÷Ì/ {;WdåeüùÀÞ¿ÿôùØÿüƒ6]9µp¢ãÛûv;vä+üû?sèKÿÃWþ͉áoØ>z°<õÂåÎT'Î{Qb|äøcÏØˆˆóþWù%"Ê}þ;Ÿ|:o¶¿ñÏÿïñÙæì}~>¾ü‹3_~tæ!@‚0|îßü -¬Èð0DL„ÙÃ'‡*CgÆžw•i‚¼³ü¶ˆ ŒJd ÕšéÂ|{n)_:>öø/úr’§÷Œî¿wüÇî‘}{Ÿ8xÀ†Áþ¯ÿN•аdÅœYöŽáC{þyôGËÙüÔhep pâñg ¶85 Ã'v¿|xÿ؉³\¿·UV²ÅV£peæ¤Ùè ]™836ž™óBûü}#^¤Ù‹»/\n_ªDµz4PÎ,Ÿ* =·øÖ`q8âœì\û2€pò£—~m`ˆ.íz3õÉ鱓ſ¯ìjWŸÚxï1†§ 7¬Ç¦¥¸ ;#8Ió´›)ëªB×׿¥düCayË»£»ïûOÿbïQ±ªÎä>ÿ‰Îs‘ó¡d1ˆ„ýÂDØ~4\IÖK3"C:<¨cg•fEQ”;»)wÍ@ço~†ï9gƺ¶xæÜv©°Ì7ÙìqYÆ«W!Bæœ3”{ïVÛŸ~uÖRçüM™èÆìÀ›´§¿;_p>–›)Íг˜m¾é –\îED|OD Läi»V«°'—ûÜ»yæ²ÔeÝè1ñ’“K}–ºt»È71^¼÷™s,²¦U1s–9qØ4öœ„¬Œ6ÞZ‘±YÛnØZ[o×¶o­IúŒ6òÎGž'ÆKà@@ "¹“~%ë¼÷Ì™s©s]°ÀÖ“°!ˆ€Ø X<ûÌob²~>C€rçp™wž"fv¹1³cqÎ9Hæ}î½0“¡Ô9gŒÂ°Ž‘åN¬]“áX$wÎx_ð>ð>rž<ç«Æ'¢Ì9oÉÆ §¹‘Ì{^7zËk|`¥«î‘8'ëC!k}h`áL·,®Ôtý,Æ ¶>4&`'ìÄøŽŒ ŒXq oä­ñ¡!CÎX’³†­q¡5Á§%b G$DÎ8Cd¬…á2O®›…кžØ1ùÜç¹ë""&vÎŽÄ’sž8ïZ{m.äܹÔ;GC$†Ä8öŽón…so±ä-±1> o0>ò–È÷~Œ·Â’{‡u“.{Ïl!&øÕH"€Yœcã­qaCLÖ‡ÝÊÒ­)Æúºu†<g Ä àñõœ1Æöꔌ·äm7µÝ?A†È·ÀDÞ’'ÃÖx ß­¹v˽^`ØæxB ·}G¯XûÕ;~†tcûìòâ²<•»-ýˆ=¬ë7 r5ê?Ê]ŒQ(Š¢(Š¢([zÑdá (Š¢(ï?*Í(Š¢(Êíìî²–Œ>•;ÖE‰,™À̽6ÿêŸô©7–Èö™£WQEQ”[…4)Š¢(Êí£yêí¼µ'&À:0[¹ãX>ÛLÓâPÁ„&ˆ-]~m å±"‘ 4Š¢(ŠrëÑ·vŠ¢(Šr; cš§O]~îo\«5ûíoºfÚËUî,¥• ­³Ï½ëwê›ç’…” e­|îÄ<;>ûÜ…l9WŸUEQ”÷5£(Š¢(·cVÞz£v価‡©>jãXM¢ÜQaå|³6UÙõèØð½ƒKï,Ëœ„å 3Ÿ¦Ksó'g>² Dí¥(Š¢(·º¨&PEQ”Û×ûÈÆ1ÈhW¹c±±íNüö×ÎV'Jüúáá#CÀ–uxÔ…EQåV £fEQå¶À\Ù»î»ß1A°øê+Ã}(_^ª>²tâÇ•=ûÒùy®îÝ/7»\·¢¼GDP™(ŸýÛ …ù‹/\®MU„%(ÉBzùÕ+ o-vnÍv*eÎ9]Ifj—^š?6BVÜEQå=¡ÒŒ¢(Тܖ~/sußÉólqaø‰'ãÆ`¾²d€ˆt‚ò»¨Ô&+»k϶'/ ’Å´4\œ}yÎæÈ—˜À°÷„î,I"èøkEQE¹¨4£(Š¢(·ú‘û@DD<$Ìûá°V Cf”œÁýõ¡u@Pˆ!2ýäDO6€€òXIXƯš¢¢(Š¢¼WTšQEQ”Û‡x¿é³H÷·öo•;ÃEy/J×Qû9ç5v)Š¢(Šrƒè0TEQEQEQEQ” 5º`‘ IDAT5£(Šr7 ,œeïßj)ìýcm˜¸5s‚ŠˆKRaviÆ|g¿œß.ÇDÞ67ü"D&¢m‡Òð6Kã0ˆq­IkÖ¾¸%Ib®[p’íŽés]ȃ<„AÈ»9[Ýî€îF¾º½·—A®9³5B ! ÀrM—£­‚÷œ7ÛΉwN Éêž;'HÒ¼û§Ï2aŸ»Þ(¦ô³s^ ×IØy/^ ¤_„È“‘ÞÏûŠÀ'åžW·°ÏÝÚF@" ×+ 8ô²é@®W:°«áºóǼÇ* rè]Ô÷.×-Sr 0àº5 å€ï%ckznÀ@~µ˜ºßz·ÎaÖœ\@9`V·Èê©ø9piÆÎ¯žgCñm¸ u¿ê6Ý´ùu—àíë)øÜI( H/mkµÆ¯æ¥[F®gŸ«µcݵÈ2€Y5{×’dÖǯž„W7züº‹òºcÖJp#F`DŒˆ‘Í7뺛[õ€¸ËŸéoÙ›>þãÁL"t·­fDŒã…XÀL^ŒgZ_!/º*œ¢ÒŒ¢(Šr·áD úÁ_øLP,¼q1ìýôÃ÷ „×ãôí“ÈàâBàÆnM¦ª•'ÿѯÕw=þ›_¬É©Îƒ®®ÏÎR³¹çÜùBho¦aNneoÙÒ'¸]°Õ>RRs’Ä‚ûu~HMBBPnìоõûŒ=G¸ض½OjØŽlÞ_ñÉ'àëW¿K_Cò8²HAa .Á#yá0ò„‚’²p é!¸Ñ0’Ù :!ÜØÖÄdWáòP\jD…V¼ÀÚ `³m}röªä¥!ðÌ=3OþæÏ y)ÿgö¥bá:ð~‡Ýˆd”øs¿õIÁÃ_þl¥1âƒO¨8PH€|÷<ýTi Ö­¡"UJÿo~ "§^þž?‘šC$výÅÉ0,,ì9w¾Ñh5šï6–ÂÀOËjíˆËÅ~ûþ⥯Ü+ÌÔÇG|úcÝJ*„Ë£~nyÈ´Y-S‘íFç8Âdà2ØÙ4’.»fU!‚Î Â| ù’‡ïF’ÃpãH’Q€¢SG4‚|I ´¥¦ˆG¶A "ÈjˆÈSÀ ó$‚/!¹Ñ’"|†| dûà«Á¢ó(ˆà†Áeä»à‘‚©÷ͬˆ…èÑ_ÿB¹V›k»ªM°÷÷|ü‰bµÒ“ Ä ›A6€4¥x’ ÈgÀ!L yY in|»›êáO}8þÚWä "¥°Ò«5RBzi ù.ø$†2lIn’GNB H[ȧ ca-’ò=HCtF‘î  Ù_Ê@IÙn$1L A²HAD>‰Œà2øtFЀ/¯¿{SüÆ`4T/œÏÌF¹Ùæ.h”d3™—Fßµñ¤v®¯{û¯-GÇ^ ¢`«§:ç§Ã ÝuÅB£ð걑8 „¥0<¸P˜ë¤fƒ2ƒbä•P§ÌWTšQEQî\mÆÆq}÷Ôû4‰¬ˆT†¸þ|(D@œ¦æ–$C`£`ôà^ˆŒì›éΛ{‡ÚŸNÿ}ç•••8¼™§­$‹¥ïX.ƒã>—䲂íÆ?¸Àš¯bˆh¥7Ââz„É-m£q o¼Z7_‡gÃ×à† ¤7?—Â×á:ð5 „¯Ãçðu¸Aø:ü¸ØGš!)í‚Mc›lB`K~[i¦ÕëÁtg°-y'@¥^™ÇB$7*"]ë¬Û$C®“ÔK.õËí¬|w¸_ÖE‘H/jývZÝ»~;ñºÀÙî2²Í¹žwЦï’@D„Ù$¼zuZKÏNËf6Ö`ÝÒZ½±]Ô§ç¿Y9ôF¸ mBkþ³5°A„™x]Åßr¸*åÐúâØøCë‹f“ F ÜÈh5ÙXèXw ^5¯l(À5¸º·ß9I ¹}¶î›ýpýUäj”Ó5KY˜aÌÖöØA6ž–{^ÔÇÈÛ]hSéltÒ«©å͆¥íÊ‘¯Ö© fÙTÐ}“·É8Û¤œ˜-þhd§w}!Õevúô3"¦Ï}—ô¬xwÉ3é̉\ X¥â F3)w7: °¢(Š¢(вY—I–W–Î]ÒÝEQå6 £fEQåöam"¾ÎÄ=ŠòaKD jÍÎÏ|§<Òˆâ¸;¸‡Ùë[kEQEy?PiFQEQnÂü£oýÅì¹³{ï;vàÁã:A¹ã\Tä­¿~îÂË'&ŽÝÛ˜Ùe‚€@ßÿ½?tI:qìðÔ#˜Ðª:£(Š¢(· hREQ”ÛòĵöÔ+/Æ¥ò3¿ö›Þåíå%"sA¹ƒ kf_=é²ü©ßýM€–/Ì‘1ÉJkìèÁcïçÞy·³¸L:Qˆ¢(Š¢¼ E5¢(Š¢ÜÒ¤302fŒ9òøS¥Z½7ø +ШL£|ÐÈ¥ietPDþÌSµñ@|–;vòüó?n]ž'Zç¨õ[EQE¹U¨4£(Š¢(·‰(.,/\àì'ÚËK.˸,‘û×ÍÅ…ßnéÊœ†8)$,ƒûvw–¾÷¯~ÿÂ˯Gå¢KÒÑ#N|õ[oüÅ·]’¾û«'¾úÍ¥óçß>{úoÿÎgùÿäk>wä¤(Š¢(ïXQEQn"R,Wžúü—D¤+Á4žpü™Ÿpÿ‡?Þ=F ¥|€.–‹÷ÿÒ§×\tìÈA>õOW"ˆ«.:|p€ístb`EQEy¨4£(Š¢(·¯ë»éƒ¢Ü™>zÕE×þWŸUEQ”÷ hREQEQEQEùÀÐQ3Š¢(ŠòÞÙfDá&ƒ=²ý7彦RÞ‡¹Vf®³wß×OœÐÆKÒ ÚuÃäý Ç¡[lXº5E"}Lþžœj}±ÈÕKÐu ³êá²VâÔ/ ´¶ýêa ’§ ý®(½7Såz»d5×$Û'~'n"}Î/ÝêÀöy'êZ˜^žH@†°^`z}tb^ß‚z+" ‹,Ö u†®ÿ A‚€ÅB,‹õb–%`±,†%ðb·˜”X ‹abYŒˆa1„ÐK¯Ô˜ˆ%` <›nÖê9Œ ðbF„¤û»w­ëŠ2$¸Fñ`XŒˆe± ˆX#bd°&¥ãz>rõàµ3wmbXx ºæb |ÏJ†a{FƒõbH Ä’ØÕ]ݯ˰žßÝ%–aX¬Ë«ßZ5E×¶Ý]´V‚[²m-‘,ÆlpSÁosì­©:³ÓÇ@Cñ]jÀµúÀNÎÓ¨:îÁAžo–,–hdøüPip TNÌ<@ …l›Ž ÉÌ’ØžªÑL ùæÃ_˜ª~qvß;Ïuö¤slÛˆ÷;’(Y‰ßÝß鎘èk±8ã#¯-gœÔ®Uˆ(+tŠn«:Cžì»±}©X.NÕ_¶æÉò o•-üHü¡Ñs£—g¼™«÷4ÿ¨æÙNîù?~Gi—ö®¯µ…ÎEý<Ð Õï¾{»˜^#9’}ËsO>›el)¦‘ÁæÜ|wò¨T›çÉquE¥EQE¹F~úÞˆŠ1Ü¿gK‚@`oÜ XÀôëwØ’˜>×cCL†Øl7öƒ-@³å½«ßAß|û–ý’ÚCBBÔ 9¡µ êE^¬bkCb¶ Q1,$BÝÁJ"×6ôÎrˆŒg C¼¦€y ºãp$;/ ÃD²ýx€ a«¡_#vMŒˆX‘ûZøƒ]DH ˆô†Ï°%Ð=3[¸œì(©×•f\H"ÆEÆ„F ]ÿ·r¡1ùиÈ!’‹Œ·äbcì–Á\F|`Ø’> oÉ[K.6½øÞ’DƱñ–@€íŠ ¹È€ Cl‰ uOrݦþUl}Uò¹Ðø€ p¡ÀÄèþXH¾æI`VQ/²I>$o‰ \l$2Ý«¸ÈxÛ5ù€|@ ! ȇĖ\h\d|`Œ L/µ–|h|@Xr ´jÛÀøÐtíæBÃfs{/âÉxKl×W+ÙéÐ@±#b}NîD›Yõ¤þ~s7f˜ °$Âd]ºBÈQHAG!‰ˆ ƒkWLEùÉnA« EQEQ”ÍmD"k´¡¨(Š¢(·å±«&PEQ”Û­¢¦PîXíŠ2§f¿õÖ+¹÷†È¨Ó*Š¢(Êû‰4)Š¢(Êí£Õ^t>£b!ªˆÎ…©Üy,'í$ÏJQÌ,‰ËA˜k-{‘b•ã‚Ê3Š¢(Šò~ ÒŒ¢(Š¢ÜˆÌâòÅ×NþM¹4»ìCOA¬+•(w’‹Ò•ÖÊß¼ýJ%..%­Ã£S†(ͳ¿~㥱j}%í|üÀý•¸(ºBŠ¢(Š¢ÜjTšQEQ”ÛÔï½xùäÄèÁ½S.,_ ºŒrGaˆÎ.^«6žÜsïÅ•…¹Ö2€ÀØB²ÈÛó—žp‡«qQ½VQEQn9*Í(Š¢(Êí<çqX™¡if'€é.?¡bòÁ♋aÈîÆH’gsd^ºpÚs|úÀ|§ ¢«ëR‰ˆ!bD£(Š¢(ïXQEQn µ‰s—^]\¾ðÝþxnáìÜÂYž›'wÉÜÂÙ,kß•K¢*?1*2T®ž¿4Û\úƒçŸ}ga„¥N»—:­ÓW.%.gþr3ë,vZ—XøäÜoREQ”÷ŽJ3Š¢(Šr;`á]£‡¦NýÑÔø½…Bu~ñ¼°_Xºà\ºÒ¼œå]Gù@]Tf#†wýðì›÷ŒLŸ¯6žØs¨•'³Í¥¸¡Ý<¿|¥¥Í´s¹¹Ä"ï.Ï{a5¢(Š¢¼G4 IQEQn´æ‰°@íû3ß³ïC"¼o÷qÖÊλöÛµW "2\® äsG[¿š‹°{`„…?¶ÿ>Ï*Í(Š¢(Ê{E¥EQE¹}0ûµÏ"~mK÷³¢|àl”Z€Û✲úKuEQE¹%h@“¢(Š¢(Š¢(Š¢(Ê†ŽšQEQn)ŒŸ¶¹läÅl][IºÿE&¸^]¡îÂ_Ý߆ؒ³d yc˜ bKÞ’Ã5&:’ÕiXò¶ä 9‚0‘'Óµ- ‰ˆ…3D†¼¥œ` ¼¥Ü#x g¶‚È[ò†X 6à ñ– B䉈Äcr†Ã‰öxCé9/y¿þRh†„À×(]CÞ/† '`O½Šßu`é&éZwK!ˆ¬y;A,¼ñbbÉd,yKÞRnÀ–rƒîŸÞ€-yYYò†¼%gÉxCdÈÙ«?Þ’[=À2Ý¢ï&¤käî^¯žd³•„ûß‘D¼£×½":ŸÖÎnÿž]'ëë§>wÞù»o5?Ͼí@‰óÎ0Œ'òðYî:)kŒ°†ý**Í(Š¢(Êú«~T|øÓãP´Éê;‘­ â½JH²CL7cŠ\>³t1ôNhCGR—hf(*nê^äŠ ½ÛÚ¤S"!Ðæî'AN§ûŽqˆˆ¥žÂnÜ= dlýÚš ÂÆŸ›B¥‚á­‡ˆ$1§ázA±™…Z`ðofñ‚6›Ëb,›Ž1–if€È - %B!›9¡º˜92 6uäÂÆ½üŒkìòõaw¹ÖJ±ÉþºÌÈ›Uó‡q>vìtÎ(ïš ìQðÚð‘Ѹ–%Õ¥+NØÉNüÜd6¼T¾Æ!9ÂSÉî)Õ®'tм\s}JÌÀ"=Än¬“uZ~Tdc«ÍŠãd»³‡/”— ƒÎZˆ l˜¾Õ9ðòR±˜Ûy©^fGæB\i¶Ž'GÛH3"(Um{Ù_wŽja©‡EY^J >¼'¯fî_>µ´ðÀâ…ähxj|×Á¯wABeŠç–W@Ø=Þx7ª¯T†C?vEÉÅÊ^S‚|Î+í‰F¹ä½¬´GÆlnwu‚•{þörçç¤PòóG—Ï´â{ßXy4mçQ:ýˆøÝíKÕ¼ÍDWF¢7†ïo)O$£Så|~4wpöðàÌ®IkƒkÏë4ï¯$ñýÔ·.‹9Ù¾glÆŸ9\¬™@Þ<}Œ¼i5Ç õ¬\l†¾¹¥V§øöÊøÑk^£mÄÔÂî¶—_^~À:aGCΆ~°øxT°×âÒ;‹#ålêG­'öø!^2i;Ÿê ½»RQT°dÌ•æøJ{ìÜJm~©µ¯=js3ß_\nU‚B9ˆ/®Œîé ¿»2X‹J¡3ÖÚÅæ ÷Jéµö‘N2z¶UÊç£?\|´Q¨Ì¸Úôz ˆ±ÓçA@×Y×U3ª5míÝÈ.#ååØÖôQy]†etïäS¿ócL¿*)Õ¡»,Ë"rïøß}üïY2 Ê–WÞl?·4Ь–}ø©A7ˆÒ;01*:õ¸¢ÒŒ¢(Š¢\³mø!p ŸžLSl“©ò;‘9ÔgàLé´˜à†ÍÁ¸M,®„ì¶Ê%—0Qˆ¢Moõ 2ÏÚSw:Ô¯dˆO¥“9¡IPÉ`yƒ†QKò¶G1þܸL—ûŒñ ‰9 6|21³ ÝbD<¨Æ4KÄB1—… B-26—ÉŒƒ¼˜E1˜"Óe1Ãlæ`’~ý“ÿÝa75äÇÜé+3õþ¥C¼"Æ÷¦F±qÞØÊCŠ#AWnÊ}i`æXTuiyyÞCrÚ‘ïŠÉm8[ì 'éó ñN%ã¸ðºçJ ~¥ìû K±ðƒ’M‹Nò¼ívS"Š’m[xÇÅ¥¸Ö1¶+›H¤o¦Ó¹X©;[L¨ÝôqL•›¥å¦7ÛH/Ì2]ŽÎ.fÆÐuû““Åç—ò¶ŸrÕ¡lqïòÉçê‹ç;CÕù‘±ú÷’CÞÉ  N.&dð!_}5ë ®ØZØø;_ÍR4·äÖ“åâÚµ]i”å<ßâÌ^å0ÝýoÏûÿžã’Oö¬œz«öø7šC+ËùT:dá':—ʮÆæÃWöŸ|¹q<.ž]r\ /Í ì™³uÞo¯¼É"×/¤ñvÎ  7Ú»}åÊébÅ×*a$?r» [Íò=öì@q%p­È-ÎGoµFD¶4ÔAÀA5î^·ÍÅ.Ø}¾>š+?[¸w D£a0^Œ¾½0¼7¶e3_Yiú4“¤Sz­Y'B™­ˆœ]IóvõµfýÔRÖéTmFÚÙ;Ëé  Fâ` ÞXé¤IåDsp¬ÆÞ–.¶rù,^nïEV}µ]m'<™~méðT)ú„«¬·€™ñó´0²µšQ©e'Îï`à 5JË¡u:ÝùõTNšÙ½k{!ƒÙßUò„ˆìžÞ?:À’yëòÛߺðìÙJsªVßûø}Òખ*̬g•fEQeêŒòÓ–ib1ýß ˆoBB²M—΀ûv „À×´1à^tÊÖÔ^? I`®¡³õºbV•Zý°šMáKW#‚Yý½M2†õ0 Ë¥k„Y ­»¬@ØVãG¬p7æçÆšºaHtMùfÛìg9Ù¦Bñªõs0¹^W‹• !މ#‚%c,ÿÿíÝyœU™7ðç9çTÝ¥÷tw’NÒIÈ @X…¸!* ¢ƒ£ˆ":££‚ÛøªãÀ«ŽÛ‹ã2£3Î8":ê(8ã2ƒ¸:¨ˆ"k @ ! =ét÷]ªÎyž÷»ôíNo ‘«ðû¦?ý¹¹·êÔ©§NUßóÜsêc kÄ’a™¬ªÂäHb–é23Õ%…)æ13«2KmB“2«¨#1,ŽMl‚a¶$ÇÌ*Ž‚²DÌc*ÃjY,«%±,†”•˜„L &%V6ÌsÈp¨ÌR2Ê•×Èiˆ9®.U#J2}î˜i¢9ŠcòfbT­¨åÊ~‘X®·9e&²SoIkHG·ëH¬¨QbևؘˆÄ±dX–˜ƒ%q,+‘f²ÌD±8Ç’á`Y,såqÄìØX’ˆƒåÊok™* ()Y–J„+;’á±ðÄg4OÜ„1¡éhggžl÷Ø–Z¾IŒ XÈ s ñ¼Çדn Ð45ðø1Ö3©JÀ·eR3UÝôë_íÚ={ÙÒ¾U«Tp/CÀ„&€Çç/®µ6\¶ö¬½[¶`Æm£fÌÃ{öösLkw÷‰/|¡„€Q3@5ð8Qu™¸08¨ª{·l)ˆ÷D¼'Õ¦ø €''¤f*2gùòÝ›Zwã÷¶¯»§pàÀƒ¿º9¤é¦_Ý\ÜrÛm#{÷bŠÀ“&4<TµeV÷‰/8?¤©ËdleÛÛŒs‹N=%Ê忝^í2 œxBjàq£™–"R"R͵µ©j¶ò»µy€''¤f?ù—ÊãÆßð$„{Í4 FÍÀQ£DeïåI6„UÓ{¿¯TÊ»©þÚÆ™8Š¢qO QBê E• Šï4LðáŠKÞñäñ×Ô‘ñ†ÙxÓ¬.Þj°ã¶¦ì‰„(Ií©R µç+¿µþXGO¼#¶ìLêØ[›:"5êX&ý¨Éú0Z YQM¬1 IDAT"2D<>t’2ÍøÛÌE´TL§jéÊš:žAû™¸ñ¨R)MGTˆIHÒÆŸY¬lýdÅIR-yk­%UeÕ4öC±gk=‡a –r$…Ø3É-¨ETŠq&5–$ea–ÀA”ÅOQyËÁ²*ËõíJ)ÖJõÖf‚pÈ9)Ç~0–4 ñ”£P2!QM")EL$Æ’’U’Hб&)Gl9Õhˆ´X‰](ÆšD¡K)bqFJ¬ª*Fʱ¤‘”b)‰zç‡2¡3>ô"ÃÖ‹•ĪZmhi*V¦hŠcÛ¥y — x²•ádxi{¦]T@jàðò2±s¾öDúäÉΰR9¶Û{ÛŽq¶åWÏ=iÍy'­™|e&Õ{nüÙ_û®ËÆc3¡oÍqOÿÈ•i9Q‘q›ì9ã­ù>•µD Ý!±mÇ®kµ¿ÊŸ-u³Õ»îç}Û¶þ™J|øG—ÙêÀI÷­èLJ¤4Øî³~ÚÖµ¤¡Jj´Õù¬.´!G*VçºP Ííq~• =6”ŒöØ FæLXlCjB je‘ ldÖøìŒR”qw½ô†ÅmË“ö…뗯˺\PìÂ9Ä'šß°"¿yÚñ§:›­´OŸÉÿvž¢“ZÃS‚u¶ò•X*¶óÄÛç®Ø–¦AÃDÉ´9ˆþÅÝWüõ¹ª“MDc›™óÜãYç’öO–cªH2™b¾EyÌRªšãËÏ=wí×o¸y{a¾Ì;Õêž¶6m ª¥|ùgϤS„Â8yÁK݆·Þ~«Ë:Uµ‘méšsÁµ'œö˼ËG6.úBdâþîã“sî/¤Ã7[…ýàܧÿ(·vû¬U—QXÅ2›uˆd;iÏ4Ù1­Ë7tÌ y9š®Sf—νð«™xoÛÂ’râ¾úÆ8ró:õ ·ðà’Á݃óÊ}[{æ“D|É„›æ§Ý¼ßuäUµ½Ë곈‚ÉÎytÉ›?ypožC¶eõmk>ô÷›ëŒ»ºs=#ç­ë]~ÑqýÿÝß{R!I$éë\V>óAVÎF9UÊæõ¬.­} _èï9É›/înhÚ:³Ýmq«Ü)àI—YÒ³äS/û+))&üR3G’ y2¾…âI>Ö)ßQre RbֱɥÊÛQ¥‰ à)ëR)™sÅ™ìæ”Û¦p“КfIªç¦•‘&\{̤<ñâzÈ®³O°Z9†3þ<¿rƒ 4 >J§Ó„1Ñ©‹WUeÕÆh+“USy@jHY+ÏLZ–V–Ôé÷EIªZRS9L¤DÊ\Ýb%&¦R&®l¨Zê†*££µ­“‰*•¯ŸD4n­†³¦¾úá7öiŽð¸8F•iL¬I‰xêÅ£ÇU«eqÃ8*®EÞTƒC†È(±V_åhV;ö°V«­XiµejU­5e­7×jiFÕè¡WŒ†EÆ>©tXm˜öʧOÒ·€Ô <îï>kÈ Þ~ò´½œ#íóÿžÞëêÌÒǸ!®viF¹Y¤þ »:.%£‡µ®Žy<&Õ0q÷z²fZMm0Ï ºãËᆊó˜”>Öqýû†B+©µmHrŒy'?kxfí£½è˜Ö‚ÏÓ÷-y ­mAǹ¶×•()ÉzކŽGs*4îñhG_âÃa~ÀÑÛ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3Mã€ÇH‰ôH×)§ä"U‘ê“Þ‹G´A%ž²¦L¤¤L4v9ešrÅúv'Á㫤Ld”ŒªQ­–ÏJT{`”X‰UY«Ï4ü·úäÄ‘ ±ÔLQ±Ñ×”T‚ª©?)d”¸V}üÛ…Vb5Ù«A¦xušcV;ª\«ˆÕƒˆìè3“…›ë¡žNe1•ZT=ޤ•—ttëZÛ¢K-PÒðãeRíÐ4IªžZiE•="%×r*Åêh$ŽÚ±k\€k{$\û-è:eÀ¸ÒxÚoumòÅÉ›¸’ï¦Ôóôgƒï"Uò1qž4d[wÏ¢¥œÌÍè0Þj˜Cªd[É 1W·n[IÚ(Ì¥Xò­ M=P˜EÒN’’7jc1ž¤…üR"kS׺§ËvvR裴H¡•²Úl9&RÒ@¡Â’uAŒg6¬IfpZgIòS¥üB«eõLÂäÉ÷Eº<9o$5ÁÛà)Š$3EÖlw_ÈäEUC‡p%!£ù9F™IŽ|?iL¶B¥ýÚ(O¾›BŽÄSè$?›ˆÈdI‰¼Rè¢ÐKÞÌ"2ä‰<“ÉSè Ÿ'_ª®ºˆ"2–‘*©#ßC¡|…2IžüòÝ$qcƒSâ?TjKw.ðÖŽ>/*³[K½éÐLΜ˜ØLvu@jޏÎÁf†[Œááþ“_ü”oýŸÏ-^°jí±ÏòâkÝr ÞO¼IßMÒ6Qw±ƒ‡çëjÞ[O(Kä"攣Tê$eš·­”-‰NÑY%¦´¯Ú_ÕCûä½$m£ý-&7gïšeÚâ­^‚Æå¶ì³ø"çöä2wÏÊ,ìô#娯-³~VD­¦äâMZðñü¶Ì½]±¶gÖì²Ü!}c%"*ž@™nJ»©DE¤J¾câZnÙ2hž*D¤ª­mÙÓÏX´{`ß™Ï8®\J”(#é);n›]>a—_BÞPšLÕ?¼¤#?—4ž¶Úµ?µ–'*‘„°äÌSâû÷û}e <.&æí ï›"5S¶a_¦Ç¢¤Qä‚ ”̧R‰¢˜¬£4!c)™O%Gi2Už"î rÏŒF˜VR¥Ò0I†¤-·§Ôs÷=u®)¤[r®Sy))ç¨ÔIÌ”ôS)Kœ#ßKåeR2–JÅÆì¥ý”¶Sð”vJ“-‘ŸKʼn¢¨(ÝëdzÛU„ʉúÙ,ܱyN|lžXYSãgSyùnÍú`SCÎhB¦ßi#ŸNrì”ÔP²€ãÔhÙ¨gõ”,&ÉrÒp¦ìBÁy/¾D¹(í,n,´~EÚaƒªtµVÖJJ¨¼ÌÊ-,)ù*­"ëˆòd[©äÈÏ¡ÒJJú))“JgSb«%*wP:ʆJ=”ö3%]TšEš%n!ÍP)Oé|*GäZÉ:²–ÊDJš¡d1¥s(!ò)ùYT:–\;I˸ÔLw²c}|»+ÅÆŽfIŸZ -JI¤f~TÃX~ AEÙ‹¦Á§©~ÚÍ:{¨á%™²Û)•ô†šñ ‰™É¸™4ÑphFƒU­’Q²ª¤jT­V§•8U«d•¬ªSª%gòÞ^Þªj"ABm²˜vµ•Õòg:=JyªÈ‹SLR3b§(™•L%1PŸ2ÃõI+•rm¾R˜4ó¢:ºðtçAmÊL¨<¨tRbÑÊ®ýó@js”*ãYÂè¶´>§6IªÞÎI•I¬huBS}£Ü*ÏkCbÎáãú<©ú…Hªó·v`Š2¬eåÆùA sÇ*1a¢0fú^ãïÊT&’†*ÕÃŵ˜Ô&ýUþ[?}ˆ‰…*ƒçÆ´ŠúœàúÂÊNØé˜9c¬¬lfV˜øo:BÐ,HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó8„`BÌÌÌϨªªÅM 50fÙ·oŸsÕü‰÷¾··7›ÍÅ­ 50fÞ»wïÕW_½iÓ¦L&S,׬Yó®w½+—ËÅ­à^3õO¶?Æ!­ª3/…Yx¢BŒzÃÂ<ÙšbH‰˜Ø[ÈÈtûÀ$†u’Â…I_QÑH”B UQU&"ïƒ(… !¨*y¯ª¬B>¨*QQö^& Sb·ì-§ÖxË©e™üíL9ñcƫц¥YÉÙ S0$æ¨LV&1ª<£ÖcdÊå&;ÞDÄaê)1¡(&µœRFS«Þij5ušZ£4åZU£j§Y¬¾d°šZJ­*+ s`±êmõè“©,C• x£Þ’· {KÞª·š:J­Ö‚¥`8X¶1\¶¬Ä¬Ä…(u”Z#†+§U££Þ’Œ6%%"Ùá›ú\ åzi yGÁ³†ƒ!e1:“Í5n×[õÖ‹1”8JzKÁPjU ¥Vƒå`¨ò¤·ä-«Á²¯ÄÊÖ–©=öV½¡J(ª¿-£ÁV”5 †‚UoUXS«Þ’PNDEŒˆÑúÑê¥e&=C.=ðDä˜cŽyßûÞ·lÙ²8ŽÏ8ãŒ÷¾÷½³gÏ‘£¸ŒšxLy™($ÝÃNVyD™áWšIï†Unnëuñ¸Nvï‰NÙX^¼|›•¥öÓ—mÊÆ«¹릥~aVÛ´ºAz`eº¸U»tâ*( ­Øx°£;Ѿ 2>‹· ÷h§.äÚò:¿¿ëÄã²sºdV¾e÷Ž}Ç®hØ0Ì’®={åonüåI«íÙ±/'g=­Ç'#]™ÓNîyø¾­Ë—¶ìß$ÊÔ½Ïñ®XNœøUè¸ ¹dE ë#½jxÍ:i »»úû‡îß· ´»cg7-yx¯â&#”©uØœzG®8tjÿªþÙÆ=ûWm.²¹¶\kW®÷Á¶cZ2O¿¥µi±TbM Ý Í¬GRbåZÈï^t ׿¤Ð¹5:¸¯mÑÒ!q=ÃdpOÈæ3ùö\¦%3çÑ–yKrÝÛò­99kÍÁý”ZVØ“îÉ÷“i}$Ÿ–ý¼lüŒ_·uv¦] JÚ?ZuIÓ_óŠ}wÞ9çáØö ¼JKÿ¢;¢5¬aº} [Êü<þlÀï}__ßÇ>ö±7¼á W^ye.— !ÝM 5ðØr3¤NRV">¬Èǰ Íô³—(çõÐ~õœ-i,éÄaŠË†•”©«0ÕkÌD¥ŒN=L€ˆ2å`ƒNØÏŒÇUI)Šl6ÃÎ’Ég$“±Î"miÉöÙ¬‰#¶Fã\4œ”­1Ù¬sVãØXò-‘e1“Œ›iô¹Ÿ)J~ÈGâ%õ.ÕÉÒ -££f”Ø¥œ)×Gø¨¡‘öà3ê†8Sfò|´>Ògå¸Ìf‡Ô;-ÇS¶'ûñƒš*õ”Ìdmމ)VßRÌwfйÁÐ’¨Õ¸hrC6öÆÆÆ­s&*1•-—ì¤û­ÊeÃ%3mj†‰Ld3Ò!‹qÄI’ó™¢É 9%C\²,š! eΔL~XóêãrÈXŸc Ùú¦ÄS¦d2å`JÁC¢d¢DZö¥FH-…œ¸”óCTLãr ¦ ì*Q±qbsCêÒúà"Cäf2fÜŽÒ©ö7[b,iDä”8[ðyï3E3l|ˆŸ)û8ÃqùðƧálÁÐH..ÇÎsþ ±›3&›1¹!%œ6Ù’PÁiâe JLŽ˜Ó6qI²#ì‡L¶$b_àdÈdÕd‰É ÛL™³#&“1.kM¶hHÉe &NL¦`lÙD)ç‡L. 6踳)ÛÙáLdËÖŠmLúŽF‚™Ñ©“DSŽGøƒÎÎäóù믿>I’£ž—AjàèÐ?„Jð45©˘ ¥ü÷A'HŒTf{Ô^Öú³4š-m4ºüÔßx LÄLLZ™E5n.Õ•—ISéjÆcÊB§#7Í>~»«Sˆ•vSµ:­D¯ZOY;ž¾Ž¤J¬õã¢õ6׸neÒÚ±«<`eÖúЬTËÍTÊÑÊ€)nhªcçÏT 9äЙTû±¶öÊÁÊ^TëZKxI£RÖÊOm¿ê±ª½Úp PÃKõß ‘¤±§I}ÝÚ.põ)74jxæÐÓI«q\ãåÃhéJ¤oöTËåòï©pä­šÆM;<àˆp}VzSÚØ¡ß<‡@áÈZB÷£÷GÀZ™™*ÿŽì’Yý=ƒhÃ’•…kªŸ†ó˜k𸪎Ƹ±ÆÕGLµr&«du¥q…s}ͱU·ºRmÝ1º×?sçÑœâbÎLwVUª”6£–S7ž°Úp &Ø»#¼„rCýyú‹m=r‡V¹q­'F| 74ŠÊPˆZ¤¹·ÆAT“dP%­Œršvd{ÅÜ0d¥ãÆG££bkÀcl4Ž©#ÒJs[ÑÆfPÙ÷JáõQ?õ7&Sežæ½DíªŸl• ií,wÒÐ…Œ®ï[åºÆˆ¹Lt÷î±ãÔÆ½9;tÉÆ'«;PMvHëR¢ v¥60mÚ 8sCÃ<gþæ1w¾Ú¢w¤ÊÆWã~¹ÂÈšuÆÚR©T*— …Âѽsõ ÿÞ‹Å(ŠT1höH‹ÅL&ƒèÁµ»ÒðŠ#Ž3óG6œ“ J¥rðÅb‘ …#;q˜9¤š”ÒB¡ÄO{‰+§©«\`CžárRJÕ—¼/ŠiC—©Â¦6•´P,¤âCâ‹ÅbÁV+œÚH’P,– ™‚èÄmIÄËå‘BAÇ^Ø­s‰OKår¡0"A*U*Š¢> © ÊI™ŒKÅB¡@VŸøà‰”ñÅB1MQŸ¤ ±”Ë%eI|Rñ>ŒÛýà(%I‚÷¬Ì*¬å$) ÓÿmbW.&I) … )³)‹2iÙ—“Râ“4¤#…‘†£Òž“‹Å¸«èK¦åT_(R;ÁÕ#µ.$)ùP, qAt4›Rò)¥~¤0’ø ÚŒ5¶\*sb’RbSG • ¥$¤ž=+ià@¬iHISV?ÙÛI!¢à™Âôß^¥¤šzeïÉKÅ4MŒ×Ä'ž½†P*I=)y5b<1'’x)I9M=¥ž¼!ãÍKˆ&’$>M½÷âÓÔ‡„Ki"‘)‹%›’©O=‹·”„td¤ >”J¥B¡àËIPï •’r¹H¡œ¦T–Ô'åòH¡$LqR—“râ“B¡ü‹ITSŸ¥!$©*{ )IÊ>IÓ’ å$Pʾ\(&|³YG©ªU•4Œ BR,SM=û$$å¤L Cž|*i°¡ìËÁøTL*JŸ¤ê‰T%e ž|LªÞ› ‰¤^½goɦš²°'Ÿ„Ä«O%Ë6Õ””Š¥¢W_öåTS¯¾”–‚ )…R¹T¿ÈÔϾ$IHuÌ@ŧ^ÔŒŒŒ¤É”—/&ÒR©X(Dë{ )‹Î9¼]9â·Êq#zG|…Ç[å'IôŒ™æVkÎ9ï}’$…Bá1Þ€†¿õ­o¡‰À–™wHšáiË%¢‡Ð!zWvÆg%õ¥þ‘ˈ„ió2Õ läT´±ËT‰ž±Æ8§¢Áû ï×âbWÉ;8ã‚xiX&v±~²¼LmõH‚ÈDö «ÅQå;“Ùpb­MÓTEãL,ª£”˜)M¼uÖ£*ÆXï½s6ñé‰sYUUUcLåÆ5âCð3 agØxIjÿ5±Ëñ ‘OüÑjÏÆ ¢ÓuAu†9õédËÅ.bæÔ§2ö˜2Q좲O'-Ù8g\à¬SÕ$¤&>$û)j§¨¥:ÃO+w¶©Œ"ñ©·l¬±ž‚1†…¼÷Qd‰YªCYHEÙUc¨2¢jüÀ©~ÀOL,ÊJÕ:—–CYXÙ"–B’ÆQäC"‘sÆ5| @–’æ â§{sb¬aæ ó2ÕØf ÛʘUu¬Äª“ÔF  ¦Èôe£ŒÖS>©d…\ì˜XDTÕ:[ +)3KcJíf1¢•F[=‹jGŠ™T¨2©ÒÊ?f•j©Z&)¬³Õ£Ì$A¬³ªÒpèÉ9W­ÕØ, 1%åtú ]äB£õ¡þæ"zˆ¢÷‡ 2 ÀûÇúþgò)ü>¸;w" MáûÀ82®Y··iÓ&D )ÜwÜ(4oÛ¶ Qh —Ë倦pªŠ(4…A𩀦Aj išh¤fšÆö&ÎgŸ$IPŽrY+¾\Nùž'¶‘cñ^m6“/•R©¾`\&ãBš¤^ŽÚ~°ËfÇleŠˆb'itò=ÌÄÖH©˜è˜ýqq[}FCR*û#û‚+ceñ^]m”‰#Ö|à(6$i©ìñEZOD‡9jÆÄvó?äóù¾ûŸ(ÅÙ¼ÿÊé-_yÝ~c¬µÎZk 3»ˆnûú5ÿsOÚvð‡¯~ZþâhÉÅÖZk]a÷ÏÏo}ѵ?|PãÈYk«ë&"æÚÿ¬µÖ˜ÑDHõW[’Ø[aL”Ýÿý׬ͿìÚmÙØŽ>_Y»V¤5†ÙFvÿ ÿòÏ·f"ã¯peãÖº(ïùü_]زæÓ…\\ß<[³ïw?xˉùü¬¶|>ŸÏ·täó-ïù™Úȹz \Û²­—9¹Jõ­µÆX§Ûo½ñË¿Üì3õý¬¬Åáþï¾î¬î5/¿â‹7ýæªôµ,zÉM‚[<1標Z~àg_þñ/ÏyþŠó°’k’=[6nÞYò”霿|Q×Î ?ùÀ_¾oÑ•+N~é9* ïÝpÇÀÞ$·hÅòŽÖ…äÂcw‡=Ý»e0ßÞ1¨ù¹Ç®œŸ Åí=°cHZfw${G:æ-_8'£¢Ì” ï|ø¡íCIˆZº—·¼C†ݼeûî!“ŸµpÙŠ†Iˆ˜­&{¶=¼uÇ Äm –®èkuax`ý¦í# å{ú—÷EüöÚKÞõŸ—Ï}ö²³Å·Þ¿mo°-}Ç,îëjóû6ÞûРË%»KãR!*Ô¾äÄW}üúóÓßþò¿Yyñ{^õâ5³/Û¹ñîG‹äÚ._Ü“çGgÄ'…”f/=qq§© ‹aÕ½[ï}dWÁ“íš·lžÝpý¿ÿ݇ü+éºp¥Ý<àæ.YÜíZÇ.íëë}è¿~øó;‹oûèŸÏ½ÿïûùò}åŠãÚ¬FÍ<¹#Z+³òiÉW¿óËs×¾ÌÆdŒãÁoøü»þâßô¢µö–»Ý¢s›û IDATÛ?óîÞ_üàT.Þu÷¶µyÛÒµî'×\uã7þjÝ%×Ürõ3¶}ô¯ÿáM×­]±óËϺàSç¼á²îÍw_ÿöÏýîËçùï¼ýoÙuüó—Î+ûúßyíOþ楳ƒ…ò×]yå÷ §Ûù­ÏÝõξó¢Y·}øÍWí=å™ü“›Oþð5ï8ÓYKÎÐÞ-¿ûäåÿçþþ§´Þô?óß}ÍU{û·>ñÚ·Þrú‹{×?0ëßzõÖL´{Ãw?ºh×ÍŸׇî?ù¼ž‡œð–|Ç™7}òõ¯ûJù—œ²ã77™Öó¨19£b;çžzö»îÃDKO8ó…>Ϭ»þ’]ºiÕËæl¿yþ›¾ô­øÎÙç¼ñÙ—¿héÿ~æóK®üú§Þv~'§Ê¶¸ë¶O¼õíÌ:mÞÞïýªý²«ßØÛ/y7ßû´ƒß:çÊc>ùû×xîß?y͇ݶõ;‰~ûýo<¸ëÎôèÿþ÷ÏÏzÖ™=yŒšx:‚ԌҼ“ž>qõ·ï_Ûcs.ÒG÷ëÿèßõÝ{®Xºï«9çm_yÙÆ·>‡þvÝyò’SWÞC¥ýó=÷cïºôŒ¿ãÿ½þ>£µZ¬á(ÎÍi£•ç¼ó¯úný³/n8x¶þä¸7]õÛW?ò±o_¿/;"bbM†7÷›w¶¼ñ/Ï{Åe¯oms÷ï‹_K.¹ý—ûÓÿdí ?»àؕΑñÃÜúoÿ²ùyÿó¹÷.¼÷ŠåŸ½ñìEðµkŽùØOÿéÅ·üàG>·ò¢ Nx÷Ú_üÊwÜóÿüÕõÿ¸ñ—OÝüÍ7¿äkëž¹õcÿ´ýÕ¼þƒó§ß}×Í÷2JE%¤i*^ˆ$xŸ¦Äs.ûÇï­>uÉ­_zûk¾x÷G/<6ßC§½àüW¿óÕÒ±ñ9ßþúEŸÿ‚> lKƒwüËÏ·_zÕ¯yîëßÚ’ëîH=›¾ßûú׿hÉ-ÿM]ÙÈ0qÔBÔ½äø5kŸ·â+·¿âmï™wç—¿{ÝM—¾åÏW·Úà‰çðS3ªTˆ–Ÿþ´Ó_Ü%WÞðÑàœ)í>pp€fŸ±º¯·5³èøgÑçwÓÛ{‰\&[Ë’Ò¼U§­\Ì=}Ëé·ÃB­Õ’HMfî‚e‹ûZ˜ÕO‡eð®Ý+Ìëï_Ù½†èWZÝ š\çYïýÄ ßññÿû–´÷¬ºâýïé8ø0­ßpÙ‹þ›Š[䘧÷ ±%JÓdïz䦷\tS&ìèœó‚GnÙ4´‰–­Z2w^×s_õÚ`ò|»’‰2YÚ»˜‰>ôÊç·”n.´ ìùÝý½m,]´`¾.š=/^§•ÛÙI˜è^½ÄlÂŽÿ¸úê„láÑÛ©ç9JªBËv÷ööô­ì¡â¾]# ³Qñí ^pÍ[¿û·ÿú·7}…=û¯>óþgÆQ6Ÿ‰¬3±1•Q:ì"3i6×’‹3LQ6IE³šžXŽhBSHÓ¨ÿ¼óþô¥ÿyéî1ž›íé2si×­÷î8㘽¬ÿyY.¢ÂÈÈPÙ )Q›J ">t4ŠŠª*‘Rë ­ƒ?Ø1ðèƒÞMäêsxBðQÏ3ÿî†ëþ{?ôò—þל·ö8:vùÿûÜkæ¤;öÛyÇwmH¢(ŠÛ—Ó‚§^õ©¿<¶åÀßµ€¸ótï}›w­Üó³o|uûš×¾Ú*”†ÓζCôÆé9­öº•³ïüäîíØøÐ¶müÐέ‰5âK»6o<›·¸·ÝŽ¿Õ ;»û?>ùùÿ8ñg?ýÐÃ_zÃk¿\L„M†î{h×À£;Š÷ï¦|Wok¤ê•XSâeŸýùåüÐ?~Λ>ðµç}kYDtàÀpÉf:hÝ®½ö ì¹m7Åy"UR"­û¯ÅüÆïÅ|êC/ò…}4¢¹e§]úýï¹öZž»ãûNÿß]qÖK^ñªï¾ó/ßxË»nµW})ÎvžD;¾ð…ÏþÇi—þš‹ûÈU¿³gË}™sÿõê Þ~Ißåïóà†3öüd=u%¥ýÛ¾þg½ÿ¹ßØô¶çvF¡– {ˆŠ‰—_²z}ý'×üó5Bþ‘ÿê¯ÏÓI;~ñýkýonüÂM¼÷kOí㈭-üâüMæy—­Ÿÿ싟¾zöþõϤ~à3KûÿìÂ×Ù—}áéæ9r/í?¾ìIÓd'‘WŸî¤áhðî÷žù‚‡>ñÍë.{N—zäfž8xÏž=‡³¸á‘‡oÙ08剋:\ºó¾Û>Ð6kÁ²• d×Ã÷=ðÿzÇó:Ê^™idß–›v–¼¸\çÒU«g»¡­ozd×ÅmýKWô·®»çaé9qÍ3°eÓæÁäú–¬\<§% n]¿qûpB¹žþ‹çµÚƒwÝzϰíZvìÒìà–õì÷,Z²¤o¶ßyÏÝíç|g %i_}œ÷ݵ«uù‰ »#®dfØòÁÛo¹?7wɲ¥sh僚Øá]ÛÜ®¶‘ýÛ‹m‹î¼ð„ß¾òƒ—ž¦+†Ù+Ö,e½(“–6Þ»õ@YÔ´ÏYvŠ®½<¼yëŽÐ~Üš%úà=¹ù}¼c÷·ºkÿöì^xúéÙÜ÷ÀÁE«Wv$›n{ í_²b~w¬6ðr˜©"bã ‹Qbc­aU‘ dŒ1†‰TEDT«/Š3“†ê"¬AÈXÖÊ2†U‚±Æ¦­¿þÄŸ¾mÝëÞ}Iï=Ÿþ³oêçoøÎËPZùþéZùTÙž²±Æ0W·GlÝŠa"e6ÆŽ©˜u–UE*epc‰Ö0U“Zy5ˆ4¦CØ:KB½dU!e¶F†>3kÁݽö£o¾¨GÒBÃzµÚ©JR ]©TBEÈ0‰ec «ʦ²}%c-ɸŠÀ¿#˜Ð$>Ô_ÿâ ‘ 2f¹†G!"¢à«Ë„jQ‚6³W¿êƒ¯¹ú‹_ÿlç|ú_¯¾h1'‰ÔŠ;´üÆo-ÒúÿÆ-¨ã+¢Áûч2UµVÑ WS2«Ï}ÙsJ³;ا^ÆÍ;WÛÆmV¢¾«ÕEUjÛ­2<‘þ¨™ßouŒ‹"g˜ˆÄ'‰ÿ£úÆhæ(“áàÓ÷ƒ€qXÕQñIùu€ˆjZ*¡IÀ̹(Š€¦p×]w¢ÐŒ/chƒ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4HÍ4 R3MƒÔ @Ó 5Ð4ÿÿhr,y’¥IEND®B`‚uftrace-0.9.3/doc/uftrace-dump.md000066400000000000000000000150061351236475300166520ustar00rootroot00000000000000% UFTRACE-DUMP(1) Uftrace User Manuals % Namhyung Kim % Sep, 2018 NAME ==== uftrace-dump - Print raw tracing data in the data files SYNOPSIS ======== uftrace dump [*options*] DESCRIPTION =========== This command shows raw tracing data recorded in the data file. The dump format can be configured by additional options such as --chrome, --flame-graph, or --graphviz. DUMP OPTIONS ============ \--chrome : Show JSON style output as used by the Google Chrome tracing facility. \--flame-graph : Show FlameGraph style output viewable by modern web browsers (after processing by the FlameGraph tool). \--graphviz : Show DOT style output used by the graphviz toolkit. \--debug : Show hex dump of data as well \--sample-time=*TIME* : Apply sampling time when generating output for --flame-graph. By default it uses the number of calls for each function. When this option is used it simulates sampling by counting execution time at the given unit. So functions which ran less than the sampling time will be removed from the output but functions longer than the time will be shown as larger. COMMON OPTIONS ============== -F *FUNC*, \--filter=*FUNC* : Set filter to trace selected functions only. This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -N *FUNC*, \--notrace=*FUNC* : Set filter not to trace selected functions (or the functions called underneath them). This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -C *FUNC*, \--caller-filter=*FUNC* : Set filter to trace callers of selected functions only. This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -T *TRG*, \--trigger=*TRG* : Set trigger on selected functions. This option can be used more than once. See `uftrace-replay`(1) for an explanation of triggers. -D *DEPTH*, \--depth *DEPTH* : Set trace limit in nesting level. -t *TIME*, \--time-filter=*TIME* : Do not show functions which run under the time threshold. If some functions explicitly have the 'trace' trigger applied, those are always traced regardless of execution time. \--no-libcall : Do not show library calls. \--no-event : Do not show any events. \--match=*TYPE* : Use pattern match using TYPE. Possible types are `regex` and `glob`. Default is `regex`. COMMON ANALYSIS OPTIONS ======================= \--kernel-full : Show all kernel functions called outside of user functions. This option is only meaningful when used with \--chrome, \--flame-graph or \--graphviz options. \--kernel-only : Dump kernel functions only without user functions. \--event-full : Show all (user) events outside of user functions. This option is only meaningful when used with \--chrome, \--flame-graph or \--graphviz options. \--tid=*TID*[,*TID*,...] : Only print functions called by the given threads. To see the list of threads in the data file, you can use `uftrace report --threads` or `uftrace info`. This option can also be used more than once. \--demangle=*TYPE* : Use demangled C++ symbol names for filters, triggers, arguments and/or return values. Possible values are "full", "simple" and "no". Default is "simple" which ignores function arguments and template parameters. -r *RANGE*, \--time-range=*RANGE* : Only show functions executed within the time RANGE. The RANGE can be \~\ (separated by "~") and one of \ and \ can be omitted. The \ and \ are timestamp or elapsed time if they have \ postfix, for example '100us'. The timestamp or elapsed time can be shown with `-f time` or `-f elapsed` option respectively in `uftrace replay`(1). EXAMPLE ======= This command dumps data like below: $ uftrace record abc $ uftrace dump uftrace file header: magic = 4674726163652100 uftrace file header: version = 4 uftrace file header: header size = 40 uftrace file header: endian = 1 (little) uftrace file header: class = 2 (64 bit) uftrace file header: features = 0x63 (PLTHOOK | TASK_SESSION | SYM_REL_ADDR | MAX_STACK) uftrace file header: info = 0x3ff reading 23043.dat 105430.415350255 23043: [entry] __monstartup(4004d0) depth: 0 105430.415351178 23043: [exit ] __monstartup(4004d0) depth: 0 105430.415351932 23043: [entry] __cxa_atexit(4004f0) depth: 0 105430.415352687 23043: [exit ] __cxa_atexit(4004f0) depth: 0 105430.415353833 23043: [entry] main(400512) depth: 0 105430.415353992 23043: [entry] a(4006b2) depth: 1 105430.415354112 23043: [entry] b(4006a0) depth: 2 105430.415354230 23043: [entry] c(400686) depth: 3 105430.415354425 23043: [entry] getpid(4004b0) depth: 4 105430.415355035 23043: [exit ] getpid(4004b0) depth: 4 105430.415355549 23043: [exit ] c(400686) depth: 3 105430.415355761 23043: [exit ] b(4006a0) depth: 2 105430.415355943 23043: [exit ] a(4006b2) depth: 1 105430.415356109 23043: [exit ] main(400512) depth: 0 $ uftrace dump --chrome -F main {"traceEvents":[ {"ts":105430415353,"ph":"B","pid":23043,"name":"main"}, {"ts":105430415353,"ph":"B","pid":23043,"name":"a"}, {"ts":105430415354,"ph":"B","pid":23043,"name":"b"}, {"ts":105430415354,"ph":"B","pid":23043,"name":"c"}, {"ts":105430415354,"ph":"B","pid":23043,"name":"getpid"}, {"ts":105430415355,"ph":"E","pid":23043,"name":"getpid"}, {"ts":105430415355,"ph":"E","pid":23043,"name":"c"}, {"ts":105430415355,"ph":"E","pid":23043,"name":"b"}, {"ts":105430415355,"ph":"E","pid":23043,"name":"a"}, {"ts":105430415356,"ph":"E","pid":23043,"name":"main"} ], "metadata": { "command_line":"uftrace record abc ", "recorded_time":"Tue May 24 19:44:54 2016" } } $ uftrace dump --flame-graph --sample-time 1us main 1 main;a;b;c 1 $ uftrace dump --graphviz \# command_line "uftrace record tests/t-abc" digraph "/home/m/git/uftrace/tests/t-abc" { \# Attributes splines=ortho; concentrate=true; node [shape="rect",fontsize="7",style="filled"]; edge [fontsize="7"]; \# Elements main[xlabel = "Calls : 1"] main->a[xlabel = "Calls : 1"] a->b[xlabel = "Calls : 1"] b->c[xlabel = "Calls : 1"] c->getpid[xlabel = "Calls : 1"] } SEE ALSO ======== `uftrace`(1), `uftrace-record`(1), `uftrace-replay`(1) uftrace-0.9.3/doc/uftrace-graph.md000066400000000000000000000200121351236475300167770ustar00rootroot00000000000000% UFTRACE-GRAPH(1) Uftrace User Manuals % Namhyung Kim % Sep, 2018 NAME ==== uftrace-graph - Show function call graph SYNOPSIS ======== uftrace graph [*options*] [*FUNCTION*] DESCRIPTION =========== This command shows a function call graph for the binary or the given function in a uftrace record datafile. If the function name is omitted, whole function call graph will be shonw. If user gives a function name it will show backtrace and calling functions. Each function in the output is annotated with a hit count and the total time spent running that function. GRAPH OPTIONS ============= -f *FIELD*, \--output-fields=*FIELD* : Customize field in the output. Possible values are: total, self and addr. Multiple fields can be set by using comma. Special field of 'none' can be used (solely) to hide all fields. Default is 'total'. See *FIELDS*. COMMON OPTIONS ============== -F *FUNC*, \--filter=*FUNC* : Set filter to trace selected functions only. This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -N *FUNC*, \--notrace=*FUNC* : Set filter not to trace selected functions (or the functions called underneath them). This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -C *FUNC*, \--caller-filter=*FUNC* : Set filter to trace callers of selected functions only. This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -T *TRG*, \--trigger=*TRG* : Set trigger on selected functions. This option can be used more than once. See `uftrace-replay`(1) for an explanation of triggers. -D *DEPTH*, \--depth *DEPTH* : Set trace limit in nesting level. -t *TIME*, \--time-filter=*TIME* : Do not show functions which run under the time threshold. If some functions explicitly have the 'trace' trigger applied, those are always traced regardless of execution time. \--no-libcall : Do not show library calls. \--no-event : Do not show any events. \--match=*TYPE* : Use pattern match using TYPE. Possible types are `regex` and `glob`. Default is `regex`. COMMON ANALYSIS OPTIONS ======================= \--kernel-full : Show all kernel functions called outside of user functions. \--kernel-only : Show kernel functions only without user functions. \--event-full : Show all (user) events outside of user functions. \--tid=*TID*[,*TID*,...] : Only print functions called by the given threads. To see the list of threads in the data file, you can use `uftrace report --threads` or `uftrace info`. This option can also be used more than once. \--demangle=*TYPE* : Use demangled C++ symbol names for filters, triggers, arguments and/or return values. Possible values are "full", "simple" and "no". Default is "simple" which ignores function arguments and template parameters. -r *RANGE*, \--time-range=*RANGE* : Only show functions executed within the time RANGE. The RANGE can be \~\ (separated by "~") and one of \ and \ can be omitted. The \ and \ are timestamp or elapsed time if they have \ postfix, for example '100us'. The timestamp or elapsed time can be shown with `-f time` or `-f elapsed` option respectively in `uftrace replay`(1). EXAMPLES ======== This command show data like below: $ uftrace record loop $ uftrace replay # DURATION TID FUNCTION [24447] | main() { [24447] | foo() { 8.134 us [24447] | loop(); 7.296 us [24447] | loop(); 7.234 us [24447] | loop(); 24.324 us [24447] | } /* foo */ [24447] | foo() { 7.234 us [24447] | loop(); 7.231 us [24447] | loop(); 7.231 us [24447] | loop(); 22.302 us [24447] | } /* foo */ [24447] | bar() { 10.100 ms [24447] | usleep(); 10.138 ms [24447] | } /* bar */ 10.293 ms [24447] | } /* main */ Running the `graph` command shows function call graph like below: $ uftrace graph # Function Call Graph for 'loop' (session: 073f1e84aa8b09d3) ========== FUNCTION CALL GRAPH ========== 10.293 ms : (1) loop 10.293 ms : (1) main 46.626 us : +-(2) foo 44.360 us : | (6) loop : | 10.138 ms : +-(1) bar 10.100 ms : (1) usleep The topmost node is not for function but for the executable. The left side shows total time running the function on the right side. The number in parentheses before the function name is the invocation count. As you can see, `main` was called once and ran around 10 msec. It called `foo` twice and then `foo` called `loop` 6 times in total. The time is the sum of all execution time of the function. It can also be seen that `main` called `bar` once and that `bar` then called `usleep` once. To avoid too deep nesting level, it shows calls that have only a single call path at the same level. So `usleep` is not called from `main` directly. Running the `graph` command on the `main` function shows called functions and backtrace like below: $ uftrace graph main # Function Call Graph for 'main' (session: 073f1e84aa8b09d3) =============== BACKTRACE =============== backtrace #0: hit 1, time 10.293 ms [0] main (0x4004f0) ========== FUNCTION CALL GRAPH ========== # TOTAL TIME FUNCTION 10.293 ms : (1) main 46.626 us : +-(2) foo 44.360 us : | (6) loop : | 10.138 ms : +-(1) bar 10.100 ms : (1) usleep Note that the 'main' is the top-level function so it has no backtrace above itself. Running graph command on a leaf function looks like below. $ uftrace graph loop # Function Call Graph for 'loop' (session: 073f1e84aa8b09d3) =============== BACKTRACE =============== backtrace #0: hit 6, time 44.360 us [0] main (0x4004b0) [1] foo (0x400622) [2] loop (0x400f5f6) ========== FUNCTION CALL GRAPH ========== # TOTAL TIME FUNCTION 44.360 us : (6) loop The backtrace shows that loop is called from `foo` and that `foo` is called from `main`. Since `loop` is a leaf function, it didn't call any other function. In this case, `loop` was called only from a single path so backtrace #0 is hit 6 times. FIELDS ====== The uftrace allows for user to customize the graph output with some of fields. Here the field means info on the left side of the colon (:) character. By default it uses time only, but you can use other fields in any order like: $ uftrace record tests/t-abc $ uftrace graph -f total,self,addr # Function Call Graph for 't-sort' (session: b007f4b7cf792878) ========== FUNCTION CALL GRAPH ========== # TOTAL TIME SELF TIME ADDRESS FUNCTION 10.145 ms 561f652cd610 : (1) t-sort 10.145 ms 39.890 us 561f652cd610 : (1) main 16.773 us 0.734 us 561f652cd7ce : +-(2) foo 16.039 us 16.039 us 561f652cd7a0 : | (6) loop : | 10.088 ms 14.740 us 561f652cd802 : +-(1) bar 10.073 ms 10.073 ms 561f652cd608 : (1) usleep Each field has following meaning: * total: function execution time in total * self : function execution time excluding its children's * addr : address of the function The default value is 'total'. If given field name starts with "+", then it'll be appended to the default fields. So "-f +addr" is as same as "-f total,addr". And it also accepts a special field name of 'none' which disables the field display and shows function output only. $ uftrace graph -f none # Function Call Graph for 't-sort' (session: b007f4b7cf792878) ========== FUNCTION CALL GRAPH ========== (1) t-sort (1) main +-(2) foo | (6) loop | +-(1) bar (1) usleep This output can be useful when comparing two different call graph outputs using diff tool. SEE ALSO ======== `uftrace`(1), `uftrace-record`(1), `uftrace-replay`(1), `uftrace-tui`(1) uftrace-0.9.3/doc/uftrace-info.md000066400000000000000000000055161351236475300166450ustar00rootroot00000000000000% UFTRACE-INFO(1) Uftrace User Manuals % Namhyung Kim % Sep, 2018 NAME ==== uftrace-info - Print tracing information for trace data SYNOPSIS ======== uftrace info [*options*] [*COMMAND*] DESCRIPTION =========== This command prints metadata recorded in the header of a given data file. OPTIONS ======= \--symbols : Print symbols table instead of the recorded tracing info. It will print two symbol tables - normal symbols and dynamic symbols. The normal symbols are from the executable itself, and dynamic symbols are for library calls. When COMMAND is given, it should provide symbol information which might not be available from the recorded path of 'exe image' or the symbol file in the data directory. EXAMPLE ======= This command shows information like below: $ uftrace record abc $ uftrace info # system information # ================== # program version : v0.9 ( dwarf python tui perf sched ) # recorded on : Wed Sep 19 17:30:39 2018 # cmdline : uftrace record abc # cpu info : Intel(R) Core(TM) i7-3930K CPU @ 3.20GHz # number of cpus : 12 / 12 (online / possible) # memory info : 19.8 / 23.5 GB (free / total) # system load : 0.02 / 0.07 / 0.11 (1 / 5 / 15 min) # kernel version : Linux 4.5.4-1-ARCH # hostname : sejong # distro : "Arch Linux" # # process information # =================== # number of tasks : 1 # task list : 8284(abc) # exe image : /home/namhyung/tmp/abc # build id : a3c50d25f7dd98dab68e94ef0f215edb06e98434 # pattern : regex # exit status : exited with code: 0 # elapsed time : 0.003219479 sec # cpu time : 0.003 / 0.000 sec (sys / user) # context switch : 1 / 1 (voluntary / involuntary) # max rss : 3104 KB # page fault : 0 / 169 (major / minor) # disk iops : 0 / 24 (read / write) To see the symbol table, one can use the `--symbols` option. $ uftrace info --symbols Normal symbols ============== [ 0] _start (0x400590) size: 42 [ 1] __gmon_start__ (0x4005c0) size: 59 [ 2] a (0x4006c6) size: 19 [ 3] b (0x4006d9) size: 19 [ 4] c (0x4006ec) size: 49 [ 5] main (0x40071d) size: 19 [ 6] __libc_csu_init (0x400730) size: 101 [ 7] __libc_csu_fini (0x4007a0) size: 2 [ 8] atexit (0x4007b0) size: 41 Dynamic symbols =============== [ 0] getpid (0x400530) size: 16 [ 1] _mcleanup (0x400540) size: 16 [ 2] __libc_start_main (0x400550) size: 16 [ 3] __monstartup (0x400560) size: 16 [ 4] mcount (0x400570) size: 16 [ 5] __cxa_atexit (0x400580) size: 16 SEE ALSO ======== `uftrace`(1), `uftrace-record`(1), `uftrace-tui`(1) uftrace-0.9.3/doc/uftrace-live-demo.gif000066400000000000000000013215761351236475300177500ustar00rootroot00000000000000GIF89a›¸ôÌÌÌÓÓÓÄÄÄ“””—˜˜?@Akll&'(¼¼¼"#$sttKLMTTU¤¤¤€€«¬¬œœ³³³ŒŒŒ__`ccd·¸¸„„„Ÿ  ¿¿À§§¨ggh‡‡ˆÙÙÙ!ÿ NETSCAPE2.0,›¸ÿ„©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·Ü®÷ ‹Çä²ùŒN«×ì¶û ËçôºýŽÏë÷ü¾ÿ(8HXhxˆ˜¨¸ÈØèø)9IYiy‰™©¹ÉÙéù *:JZjzŠšªºŠàú Ë:K[k{++ûŠëû ,ìÆ[0Œœ¬¼Ì¬dÌÛ-=M]mòk­½ÍÝÍ-ë->N^>Ë» m¾ÎÞîN Þû>O_o¿ïz¿Ïßï?ö,¾ <˜–@u:|ñ…«…Å"Z¼ˆ1#†|ÿÇ4zü#Ç$Kšì7ò¤Ê•,ÅK×2¦Ì™ÊRÒ¼‰3g*›:{úü‰‰'СD‹ÒęҥL÷PLÚ4ªÔ©j^¤Š5«Ö,B·zý ÖÒŠaËš=«£+ÚµlÛ–Pë6®Ü¹àÒ½‹ï«§áòúý;×.àÁ„µ .Œ8±Rtd;~l4ßÈ”+[¾Œ9³æÍœ;{þ :´èѤK›>:µêÕ¬[»~ ;¶ìÙ´kÛ¾;·îݼ{ûþ <¸ðáÄ‹?Ž<¹òåÌ›;=ºôéÔ«[¿Ž=»öíÜ»{ÿ>¼øñäË›?>½úõìÛ»?¾üùôëÛ¿?¿þýüûûÿÿ`€H`ˆ`‚ .È`ƒ>a„NHa…^ˆa†nÈa‡~bˆ"ŽHb‰&žˆbŠ*®Èb‹.¾cŒ2ÎHc6ÞˆcŽ:îÈc>þdBId‘F‰d’J.Éd“N> e”RNIe•V^‰e–ZnÉe—^~ f˜bŽIf™fž‰fšj®Éf›n¾ gœrÎIgvÞ‰gžzîÉgŸ~þ h ‚Jh¡†Šh¢Š.Êh£Ž> i¤’NJi¥–^Ši¦šnÊi§ž~ j¨¢ŽJj©¦žŠjªª®Êj«®¾ k¬²ÎJk­¶ÞŠk®ºîÊk¯¾þ l°ÂKl±Æ‹l²Êÿ.Ël³Î> m´ÒNKmµÖ^‹m¶ÚnËm·Þ~ n¸âŽKn¹æž‹nºê®Ën»î¾ o¼òÎKo½öÞ‹o¾úîËo¿þþ pÀLpÁŒp /ÌpÃ? qÄOLqÅ_ŒqÆoÌqÇ rÈ"LrÉ&ŸŒrÊ*¯ÌrË.¿ sÌ2ÏLsÍ6ߌsÎ:ïÌsÏ>ÿ tÐBMtÑFtÒJ/ÍtÓN? uÔROMuÕV_uÖZoÍu×^ vØbMvÙfŸvÚj¯ÍvÛn¿ wÜrÏMwÝvßwÞzïÍwß~ÿ xà‚NxᆎxâŠ/ÎxãŽ?yä’ONyå–ÿ_ŽyæšoÎyçžzè¢Nz馟ŽzꪯÎz뮿{ì²ÏN{í¶ßŽ{îºïÎ{ï¾ÿ|ðÂO|ñÆ|òÊ/Ï|óÎ?}ôÒOO}õÖ_}öÚoÏ}÷Þ~øâO~ùæŸ~úê¯Ï~ûî¿üòÏOýößþúïÏÿþÿÀ p€, ˆÀ*p l ÁJp‚¬ /ˆÁ jpƒì ?Šp„$,¡ OˆÂªp…,l¡ _ÃÊp†4¬¡ oˆÃêp‡<ì¡Ä qˆD,¢ˆÄ$*q‰Ll¢ŸÅ(JqŠT¬¢¯ˆÅ,ÿjq‹\좿Æ0ŠqŒd,£ψÆ4ªqll£ßÇ8ÊqŽt¬£ïˆÇ<êq|ì£ÿÈ@ r„,¤!‰ÈD*r‘Œl¤# ÉHJr’”¬¤%/‰ÉLjr“œì¤'? ÊPŠr”¤,¥)O‰ÊTªr•¬l¥+_ ËXÊr–´¬¥-o‰Ë\êr—¼ì¥/ Ì` s˜Ä,¦1‰Ìd*s™Ìl¦3Ÿ ÍhJsšÔ¬¦5¯‰Íljs›Üì¦7¿ ÎpŠsœä,§9ωÎtªsìl§;ß ÏxÊsžô¬§=ï‰Ï|êsŸüì§?ÿ Ѐ t -¨AŠÐ„*t¡ m¨C шJtÿ¢­¨E/ŠÑŒjt£í¨G? ÒŠt¤$-©IOŠÒ”ªt¥,m©K_ Ó˜Êt¦4­©MoŠÓœêt§<í©O Ô  u¨D-ªQŠÔ¤*u©LmªSŸ Õ¨JuªT­ªU¯ŠÕ¬ju«\íªW¿ Ö°Šu¬d-«YÏŠÖ´ªu­lm«[ß ×¸Êu®t­«]ïŠ×¼êu¯|í«_ÿ ØÀ v°„-¬a‹ØÄ*v±Œm¬c ÙÈJv²”­¬e/‹ÙÌjv³œí¬g? ÚЊv´¤-­iO‹ÚÔªvµ¬m­k_ ÛØÊv¶´­­mo‹ÛÜêv·¼í­o Üà w¸Ä-®q‹Üä*w¹Ì›m®sŸ ÝèJwºÔ­®u¯‹Ýìjw»Üí®w¿ ÞðŠw¼ä-¯yÏ‹Þôªw½ìm¯{ß ßøÊw¾ô­¯}ï‹ßüêw¿üí¯ÿ à xÀ.°Œà+xÁ n°ƒ áKx®°…/Œá kxÃî°‡? â‹xÄ$.±‰OŒâ«xÅ,n±‹_ ãËxÆ4®±oŒãë¸`!ùL, + æ Ždiž@ ®,‹¾°ØªÂßæ¬x/ï-_¸ª™„T$“ËQ¨z*£)juä( ƒ ¡²$Ny" 8LÀe-ÚH JÄ"nF«xXYg:"PXrhŒWQ:†[_Q˜;# ,–r$ j+ BO_{>3 hªPt±©%‚*°CTF #‚ p¸Á”ÀZ"* oË>º6_ ÆÐ4@Vƒ²Âž|TõŽÁ%ðöZœ93èCQÜKXâ\†%…!ù(,D!ù ,)    Ž$œh ¤héŽéʦï;ßgíâ·^Þ2À¡Bv¼€‘‘dã/I#%¢HjΊj¥«ÔôsǰSP]ÜŽÄYm¸KæçhQÙü¦§¿xqT^(kUoy,‡ˆ"p…ƒ$ ‚I%˜Ž*% ’™$ W ze.P£¯€>r¸¶º»l13»¼@-Âm“¾IwưÌ_!!ù,7  ¹ Ždœh* eK¦0ìÎç§³{ßy»Ç=ÓÅl¨UÑ8d-Mçò¨:‘ „Ä Y˜Ñ‘•HœàæÈŒQˆ•Ezø>5r55qBà£#~>?H#f+ /;H# ƒ's?3}"€•3‘P”<w-§©¤"†o¯³(§'06"—_¬VO½STI¥EÕÚ€OªaÔÒ@Ô‰RÜQ!!ùt, è`ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿&xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~ÏïûÓ.‚ƒ„…†‡ˆ‰Š‹Œ†‘’“”•–—–˜›œžŸ ¡|𢥦§¨©ª~¤«®¯°±²›­³¶·¸¹ºpµ»¾¿ÀÁ§½ÂÅÆÇȇÄÉÌÍÎÏkËÐÓÔÕÁÒÖÙÚÛªØÜßàá•Þâåæç‚äèëìíoêîñòñðóö÷áõøûüÓúýû'° Á[*\˜*!Ç;9ŒH±b$03jÜȱ£Ç CŠI²¤É“(Sÿª\ɲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ J´¨Ñ£H“*]ºåÀ„8á ÀQ ¸DµMè˜5jUËÐÊt肨.\¨@Õ* ¨lYr à•µjx+6 Èž=Á±„¬mQ X0Õf¨V0˜@án[#L°ñpTÁ]÷¨@‹k#ŸPmsï ÈFÿNPÀ»w_.´w°^¬v^Ù#¸® 6À ¼Gus ®cøëØÈI4§IÀtÙÊ"—½z"«ƒ PmÂØê‹Àk€ÔòT ðt@ì™ÐÀÀvò‰àÞÿ A¿p`Æ @Ð_ ؃j<0€ëÍFƒ Ö­`œ õ%+ÂàžŒHá{)`tFˆ‡$dAƒú(BwÞ0Z 1θ"X€À{L ÀÇ=V4¨b R —d&ˆm•cÈ)H@y&@dXQ%€dZÀ•žó`Te àá„pAš@‚\P–p™ðV¥Qq@Bˆ<ÐU E@…58iƒQa6A…µÂU–¨&´Xvuéºh Ÿ†)¯>D]%ÀÆ D W‚ˆÂ€ÿ¬s"¦lkˆe äˆr:,•h`€¸e±ÊB¦e)º€Tðìo i½¨@Zv)>" ¬ªÉEå&o†å!½`l` ô…@wSŽ €¦Ü«_Ç"ppš“î!›ä©~…¥hÖÐìM†­Í `Aú+Biø8 n$øšÂ‹'ìµpÃ’Î`r  L€@LX¹ï¾•€^m™h„@E³6› \ JûÈ4’`%°Á €¨«ÂÇ„,ÂÈ$ÄÀ 5¬“ªÕÐÀJ ¬ZT$ï•y—@V¿@…0‹c®pYâZ.‚ÿè @žÇI³ P€ Žàzåûg™¤¤™À*0UM¥¸Üy£"¯y–] AY›±WdÁ( Ñ¡7ž Tå ºÇ^ü*ή*%¯v«‹¤Å«i{ƒ x(å¾LUœõÄJT:P0e9.m ‹†ï9N¥"@P^QÀ[ü7NØèmU(žÖ!²a`,íî  0@n ŒŠŽ™y[̬f(¦Ö;‚Ò”HKà€ú«‚ ]@—(^Û >dP*j>.3&¤, °êSA#Û4PÒ'.ʽ¯dV0—Â0Š ðvã丛\´@¸O¹Ž}u¾ÿ)›–Zf ¿‰Ê ,…$Ö«…ý<Î?;Y¨¨@ ÔMŽ»Üe‚é& Ràa@ŸêZ"†¶ÓôN J)5 Z 䔋»L<‚ê4' Tz¶v¼ÌmýtxͪËZóíÁ^Új‚lª^A¶ =U¨D`ˆž&”ÄW¸z8;ö»³é²”Ôjû‚”ƒ­ffq-9ž‘.«Ÿ@=×±âÑâ€ÇÌ7LD‰pô€ ÝÞÙoeùƒ# XdVA†6Ôcõ;¥>îg¸†‚,—%Œ‘¥€¥ÚÃ¥¬ äÕ†7—þq!lKãW,RXþ³"/æ­ä&È2¤ÿ–LpͦÝ*70 Ô  tà8ñ:“Tù¼e=\ŠÀ´³Cö²Ã$ë+ ¡Ù×Îö™T_o»Üç¾´w¹½tÏ»ÞCb÷¨}ï€<úŽs) þðˆO¼âÏøÆ;þñ%i&` OùÊû@òe€å7Ïù˜FÞé¼èGÏ‚¨€^ò¤O½êG€ù²¬þõyç£AKßz³Âþöd—= $zÛãþ÷mÑý jï{àß(ã¥g`ÞâÿùHéÎÂ[Ct® ÷€Á>ô·?”MBP•“‰ó¹O~ŸDk*—ÁøËÏþœ š.é¿Z°¯–öÛÿ&@ºJüayÔßÿÿ26y3!ϳ·ë€Ø±) '¼W| %¡ýÐP¬W{¸+ÁGPPá`¨X‚&¡{Zõý×L&Ø‚#¡{UE{QÒ{.XƒA8º_Í÷y¦aƒ> q²g0ÜÖô%?˜„\€jå¢,d‘7Ö$bÍtzJX…X`hú‚ØzVø…W¨`êG‚`X†R°*˜}¡g†løhè؆rˆÂ…%‡s˜‡Z`z˜§‡~¸xø‡‚8ˆ†È(i‡¸ˆ0!ù,)L Ë Ž$œ¨€®A鎫ʮï;ßgíâ·^Þ²˜ÏÄc aEÚT›¨%Ú!:‰ÁÃÈMƒ'°‘8 N o2(z"@B†S|QÙi%~w%yUT-nŠ…Mn ‘U`bQ‡‰$‹"ƒ*¡Px'$’a8mo¬u¢d'giŒT#Y y §w5 oÉ“5i§›3"´g{¸Ì gH3*`V e  &ÔÕKM2R¸OT!!ù ,7L ¦ Ždœhš–,©¾§ÐίÏ-|㦮ò½€ÍtùVEÑ™Œ-“JÝðTB@&ƒAdˆ.$Çà”¼O‘áDè‹3@в«>Š'8_T<„`Š_2‘S:"‡‰ƒ)˜H€‚4„w{}Dj'nhŸL†cˆ·r‹UWY[n»PÁMB0SPs¥ÂÊÄ_ÈtNÏÌE‹!!ù ,FL ª Ž$œhhéŽjœ¾/ÊÊ-]â²¾ó*Ÿ 8Šd7[Àx$æŒÎ§©b•…Ä A`4££†¥AÑÓˆ8"Ææœ^§3©WE:u"„@I"eŠ8Iv 4…‡‰—i"‚’=wy.}"npt¨ (”¥N7WY ^h1¢jL˜PTAŹvÇ`ÊÎÇÃ1LÁ<ŒÏN!!ù,TL U„ËÝ ‘›KÄ;½‘n®xšHJâ“+Û¾LëšœÊ èï9Ù€:¢ÌøBŠ,´J²ÙŽ Gê3ÆN±Uî5W¤jm;ëJ‰2§½ÑìOíA{ !ù,cL i Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo ‰EÙJ×*Ž<§m‰ BWÎ'´™ÜfOÔÝ÷GCG ÖFx¥SkØ”e>ÖÃ@©Wßîö­,xX|y~v…Cu;„]‚‡€=dU”[!!ù ,qL Ç Ždœhš–,©¾h+ðÜÒ§Û&¾ò®€.¥€Aß 9Rî˜Î%=$‹¡0 I”Q,Ê0ƒ@úÄhFEØÀhPš†¨ZVÓG Y{9>p% ƒN} % D/†% j•…f™$›V|Ÿ‘“8}ˆ$ ŒT4c}u§ƒc5W's wJC}ikm«„?f]_ažX;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù ,«L Ž Ž$œhª–쨾¨Ð¶°Ï,¬ã¥~——£óXÁ¡É˜bI""óÄ[NUQñe£ *¥ëŠ5H$P:E®­mà{\+ºÅZòÍÜÃ2rx[>~t…+‚|F‡yWŽ„)]7gjœ’FŸqYL”Y”?¦z©dX®°uг€²U¬F!!ù',¹L¼ ÿ Ždižhª®lë¾p,Amß÷¬ï|ïÿ:œÐ,È$m(T:ŸÐ(‰)ÀI¯ØlðV t‰€C€ -—.†ʬ}EbòÚŒVï"ÌÆж†Ç{eû<ˆ0ƒÀ…:|1>‚ #Z¼¡@ŒŸ;ÆÓXУȑçðQÔH2¥Ê\ 3& üdÚ¼ibßÉ8{úä@3ßÏ¡DïmX4©Ò4).}úô(R¨T‡J­ŠÕ§ÎŠY»ÊlÉÕ«Ø”AŽ=;ò*Úµ ` 7"Ø…që&Tk7¯?¼zûÎÓ¸Ó¯`y|V7wãáÅé 3~¼#èKÈ”#›4[9ó Çš;»p©Ø³èÏGG›fQ!ùV, l+ å Ždiž@ ®,‹¾°ØªÂßæ¬x/ï-_¸ª™„T$“ËQ¨z*£)juä( ƒ ¡²$Ny" 8LÀe-ÚH JÄ"nF«xXYg:"PXrhŒWQ:†[_Q˜;# g–r$ j+ BO_{>3 hªPt±©%‚*°CTF #‚ p¸Á”ÀZ"* ×oË>º6_ ÆÐ4@Vƒ²Âž|TôŽÁ%ïõ-Μôˆ!‚(ì!,a.ÈÂB!ù ,)l ¢ÈIi¸8ëʧÖBÖu_yÜšZ±YèZ°8Kµ}›«>=Œìȵƒ€¢¸(ŠÆ€d XNšgTŠT2Pl꽂·d««¦¿Ù0pÓUØòÚÛ¯õögA&   ƒF 9 Š I}9C ˆ•1xhD…„%Dy%+¶±;nDBz¾½¼ŽÁ<!ù,7l ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù ,Fl  Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒV‹C$\ˆ,’'X…# ›‰$ ' qS2.'ceƒ=€@Aª¢¹rµ8´¹q–¸¼rÁ³;{ǽ!!ù$,TlW ÿ Ždižhª®fà¾pÌÎtm‹qß|Ïë‚WÐå+SºäqÉLê˜Ð¢3­ÞCgÐÊMeÝ0ê»›IÂ\6@’*€JdF†Å#A/8R &„ ˆ6d/m1 #.„/' /œ$¡.‘l#n ˜"«"š$. "$w§¬i1C“£6ÂÒ# š&Ž "š¼^­“7 $å'±¸“p4kS$±žT8 FXQ0B J(˜E+W"b}KkœC Æ‘  ’)WɱöêM ô0 r„%“'¸pfäâ¤d(–‘’WS… ë©æÉˆXûN”IâèÁó꩸ÄgK 'B‚p®(€nRžÅºÓD:uIÖüL‘034 (3m8Æ.Kàà‘ Zixá&ªÛ‚ô46+"á&M”H(éB {*û)iéØ-> 0  yµD >XÝ ÂÄq¼µ¸îŒïžÅL‘Ü 5'Å÷NÞ8ó*0D—ynK$ê\Vº!ù ,œl à Ždœè)¤Aé’lŒ¾´,Ó¯ã®Îò&ß 8‰Ö*µDŠŒ'g2¶L˜Hbp¡`•Ȁ P•"t,q DÅé¬êx…Àá¹ÆÉ1|6U# ,B"'ŠSF"_#‹L? '#–P-' % ‹v?®§+¡—Œtfª¢wg[Âr«£7cf …³¾‚-NÜVÞ}H¬RµJÝãâDäá2våP!!ù ,«l q Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo ‰EÙJ×*Ž<§m‰ BWÎ'´™ÜfOÔÝ÷GCÍG4+̵z¥ÌÉQ(0|ïÑáÄÁŸI{}B# |~q:jŠ'Œbp…nCXpl2r]SU=[!!ù8,¹lH ÿ ŽdižhªŽAë¾ï*Ï4ú p‹×|¯æÀ€oHq±¢’t!—ÐUMˆâ4Y5 †"rÛ=}ÃÄé¸ìk·-’$(è‘!0(9#SY5pq"-.r|% €#-– <7M"-ž |…{}$’my>‡B“$ z®¸% nic¡º%°«¾#¯fÃC9Å. -²’ "¬‘ÒÛŸ‡ -ªà-žÎ­ÐÀ$Œæ†è£ìÎïá$š‘8óf‹lÚÄykOÄ r±ÞX³&B—eÀò}±`ÞˆzÉØò¨ ˆljœ&pÄ…ŽÒ ¯T:TØe/-E z°q–Dñi¤ÐE‚AAù ˆ°aÃ>)3ÁѱCÀƒv( ˆ‚„/ëÎÁaÆÛ2Mнíb-ÈÜ*nïBÉ«W‰“)}—ð L­ZŽ!ù™, l2 ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›QŸ´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡{.ˆ‹ŒŽ‘’“”•–’Š—š›œžŸ ¡¢“™£¦§¨©ª«¬­m¥®±²³´µ¶´°·º»¼½¾¿z¹ÀÃÄÅÆÇ¡ÂÈËÌÍÎÏxÊÐÓÔÕÖ½Ò×ÚÛÜÝÙÞáâãäàåèéêéçëîïðÐíñôõö»ó÷úûü¦ùý Œôo ÁƒýLȰ¡ÃW-JœH"‹Š32\¨±£Gr?Ši-$É“(‘ÿYɲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ J´¨Ñ£H“*]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯`ÊK6Ë€"  £C€·.p`¢Á[º$*¼á­ß*¤pð6‚‰~+¶ ‚‚âÄJ(X0aÀ€ J`x‹¡µXxü-¤9 ð23¤°@ƒ·‘I8–0bÂ݈ñ’pP AÀP;Ûoî © —0@Áx‚¹{ÿ&¼ìôµ"F3†áöñ„ì"¶Ð€oêÊM”€âæÆoNqŵ°ßñ‰Ph[Œ–˜ÿ¥‰€Zj¡Àžbd“l©x}%ì¦]¼q€p4ðit1‡Ÿ"@GÚ%0pŸ_’àˆÀè â‰ð‹äØ€€Xè©'{#,@ DiÀ~’ A}7‚\ry@v©@|Cr‰Øk\–pb 4€À~@°_‚ðY•W”Ùå™bØå— tY kQ"àÀº$Aˆ)hZ¸u@r8Bw#œ8€‘!`Áx9úŽŽPæ†pY ö  )l"Üh©˜îÀ"$0€ n…è q˜ª¤„{‰Ð—t#8ÀªËx[)Œöëÿ ˆÕã[qp¢°›A÷ ŸAÆ•Z¢ÀAœÀ &pL‹›Â†õyXk¾ˆ«ŽáqkB}>2ºsàd~ž©tþÚ°®¾:^[ŒKºÐ À±L*Ëï¶t«pØE`µ`²€XºŽ<Ü[´nFÀ‰qh./¯°®i%„<s‰²t¢½(à+©°ýž%¢p¾!ͨGj‚o;Ç̬oF-1‰b-pÁØom\\€­B°%<(Ü[Ú.™,Ë’lr%°hÑ%Xër~'àçƒÚLX„w†Ñ³ ë¶k»%@‡ç‹NNÂ%°½¯Ž ‡)Ñ/P­ÿæ’Kèæ_:ñXsÎóÚdpm#˜>wÝ$ôÕ1 ¨™ö¥å_«Ââ9`Â[ú­ÕÀYñ%Î3àŒ³ëîÜvfüRå*(­Û¤ÚY ¥ÿâÅžÇS_œé— œ~Þøæ=÷áë*'û¬Œ±°#àm¯]«9ÝO›¾d¾€QK-^ë[˰=xÁÍW Íæ‡—/ èòÙq¦×žô%g8i˜…¾Æàhsí³¦œ$¼8†Zç³ ´7´·XÈ})ÌM®¼Så Fv2Ø I°øñ/nÈê Ióòà@ZBŒÉF0Ή¬:Œ³³ ªEcÎûñPð%ÿÇ•àMZ`K5ÂÐЄLÜh„©¾Ì+t W³ÇÓØ…sŒßŽP£1ÂDìnb¦Ì²Û=fX\Þ­c¼ø¯s›  ÓÅ‹álWXR\Q03æ…z"`áõå¨1¹±úJ!c°Á¯‰ÌŠ)] oÅG^ú17-M³C²Rd|sA,ó—ÇÑ)hŽ„’›`¾ÝæŽrcV ÖÕBŒQ€,q$x1½˜+Œ^ø¦ ªÈA|p•R3ÁKÒ˜¶1¨ÿ‚¡U÷ 'il†`‚¨G½ R€²O²¢I˯P>o­#ÔK©×€Eá² sÅ$¼.ËÛa技SL`M0Ô“1ÌTˆñ—=³è+ƆÅI*¢S•™±!É8@φ+è.QÛEÖÊðvÈ,âSûàžPÖ¥àMnÚO¢Ö›Ä°Š±¼"ø»%BMQô ÀmSÐHŽÉ‹êl÷¶7Ö«‚‰S?V(ƒ«b"qKU¼CŒX$+0ylÁ÷ÔbXNÇÖÀYŠ9;I±¾d^g¨ ðv\Œ—óy ùª P’6N'ŽDš±†BR¦œW/  Ì*"ÿ‘Šø)¸E©y³yS#í vÓ‰öŠ™p›¸ª`Nq™Ë½ p% €o!6°‚~ê$lR±«xžM}&S™ËðÆósï28°Ù:1®™ðJNdj;?À2À@}ÀœBÆ:@Ö‘@¢/½Åè¸:g¡€É¨7ËïÜèN·º×Íîv»ûÝðŽ·¼çMïzÛûÞøÎ·¾÷Íï~ûû߸ÀNð‚üàO¸ÂÎð†;üá¸Ä'NñŠ?aCo¡òJ™æà­oÁò.ðS½ˆ4(oª_0 l0`ØÓ,-p.Ð÷›£q,ÜfÈÀÉeÐ <;.:¿ÿp./iû“@†¾V§RF€2àãäLqÀ¦(, ÔBpè«–ç„ÏI l•˜ïÐ òKºÍf0ÜFÓ4@@¹S%'=Rm| |4C#¿ôœ0^·ÿ¦òª a49=Â^LJÚoˆŒðùÐ-€@@‘#ZÀ{@Ø'=‰©ÀY¸ jgðbN©þ'ïK{¸¨?ˆ¡@dd$ìÔÒF9 0|¢!¯°/¥òHÀ¼œTâÁ†(¬ÉŽ_o~4k+p’"»ðwòƒIî¶©Ïb#kÇYËcŽù®“E;³Ò×ÀúJ}G }ÿIdG.憓e[9ð Ø,ð“ÐväÕ-„åDÔaØíg'by,p úg''IÂ=Û“yý—“j!à+µÁ\ 0t p8'u)£@lq•‘ Q9¸ƒPÉQC³A"f÷Ö(°(ŒQ8@ÂTŠQ%Ÿñiì•(_Ò(àö¡ö*@øã.…0Cç$€Gå§¾QS?÷ScªÕKÇñ=çT„ÂuB¿d2*n¡Þâynå4€H ˆqrµWn–¡x«ò%ð„W €‰ v^s°u¦X4÷1ÿW¢&EhöR[`Š\¸….61œ3Ò}Ô‡ó,*`x"h¿+ÊaXDç&€,8Xp çuŽaŒè}»3ÆÁrRÄèd8dgUH¨þ¢4ª·ZCÄ “qvH}§DO`Ta–}á/›ÑiÌY_r™¡ûT'S"`(“À)DMŒµ(”z°‡D€' €Ìä…o‘,’ƒ‚ED86;H@ðE¸ˆ¼±!n7ŠÑD'@wd~MRäó vHºg„ñº3#k^ïÒ*´ã$Ú4!pát( _ÇÿN wtŽ3-ÇH"„¡d³:Æ7ŽQŽž‘/ð%ü§7$¥£q†$p \˜B"¹:—v’)‚*@@Ëè’ÜÂ?Ï‚{+Àw¤‚¶Òi,ck<™8¹Åç(z∞ 1§ô+";_˜  UŒVyx_)Ò±š©µO¹ò3i1›Áó—ò´Y#°(ŒyëRÕ3tx“( ³-û™åSg8ñ’0µA˜-€F2¨ p4AIb5Г[’‡û2 ˆ00™1ÀŠÈ™Qh=Y"Ï–¡i*Ž!mnâHR•ç‚©i®éš„¤Yr‰U#°.ÿЏ‘ÅÐ&ü¤–UYŠB»—h¾HÃ_ê ™}1c›1ñ’àõ6P‡+°(Ĩ¡…‡ ºZ5¯vä ¬6}¡ˆ8Ð"['Ã,N‚‹Ò–=vŸû(jDü©žµ)¡Â¶.ü×ÇÕ:P(’±8’°u/fRÈq Tu‰7ÂÁ– ¨—ŸÕ¡åü68JxÓ’¤ÖVk¶{0À9æÙ¶‚›+ð¢/€* Ô›t3OÓ¥:hú?uš5ð‚P0¤¢1¨!ÀJYÉÔ|i±põ‰¤"ÈME“Ž%¥+à‘SÚ¥'v2üÇ?&ƒœÿ+Ÿ?Á†%à†:€VÖG%Â_4 §¿Ôr˜i«{ª›2à¡Ú›e”0Â**x¬6•0ˆúXÙ1ب#êg*JZ©ÊY‘–ù‘ ª&P—„aJÈúL£¡i9tÆ!’gȪsš)p hY8ªf‚S˜¶–3¹ëú¡3ÉW50”6p%`³Šh-h‚p0rÖKÌ ¤W)¤P-Žú‡a9;‘­¹c©ët¡Û#‚ÿêg $ª*—1ü#’Ý´!'`¸/hG$©4ô°ÃQjÈ;µ!Ú’0krÙu×Z0 úS+”À*ù/43ðZ©6ºy(Iÿü÷¸Ô¬3 ¨ýX±E*šÔKñJ£ó µ{Öû‡4À·3KÊjÞ"ˆà» ›¨š-à"gšÃ}yó;#ʽ>ëìqS¦èu½‹³ M`=J‹•(¡h©§s%VЦh©hä´Õܔɸ(ýgZ"ðŒ1~ŒíH$ØØ-é>4´2 « Ž A+@Ž!ÚÝ,Ž€s®6Ôýbºö$ƒ )´aµ¦l²»ÞT°™ü$ P¶¶X@òsèdÑç«£m–nxCܦû%`3ÃyPi‡@­ÿÆ]E¤Èºº¾Oý½ó-mš¢§áûB#X”gÇÑå9bÝŠŒ;@Ø2P”G©wyú~½tO •<ÒŠ`ÓÈÐS°0NäD£a£Fý¶*E:@—&pÖ7 RXž–Å"‰èh9¡*`ëàú—>ü(˜ËZÏ}ëì]4’C8nîîZÌî•ç§AºšÉÚ¹=ëãòž3DšmŸcýÂí¾í 1\-à$Í–ñÞëéÑ2ÚÑ’@ï;"\sj®œ®+ðïQê±Ë)0Íùœ˜ìžc×É(«"xàͱzŸ|ýž¢¾ž‚ÅÛŠ'N'/@$ˆä%’àž¤ÕÿÛØaô)w‡NÖì„5Ô|¶© x"mÌ[ öX\[ÊU@·uª(B¹yô°“î]«ÅuGÚÊ*“ô>ó$@¢¼ý­ @lqê˜tj+Ú¢u®Þ-£•ÊÊŽaw;÷¬Ì®Yü‡‘_ÊS ò(ÀYç" Ë|œÐÑé" Ë\‹Þ†7å,â‰î¨÷ßì+P¦=ñåPÛó¸¥÷¯dFÌáDÛæ‚OëRl§~Áë ^çð:~º0J§óó]Å-ˆÏ˜l„²ŸÝBÎ1°ýÝú¿£/0ò°Ÿkp›×/)2EÏõ.÷¹Q™®î§ Ô-«ÿ™ €8’¥É“¹²Fy—IÈúÆ¥`D<ÉÓ™M«ijÀœÒ) €–Ô%`)A{$L€R…³"²¹´-°¶**!ðˆYÀ¢Y?8]å5ð"&*ŠPÀ‘ü-Q) UÀ(”Ù&0 l6á‰*¢D,Šh8”@ع ¨•€Ž4àźÀüŽX"•(1µŽD%3“tí6ÅH˜L”ò4”Dh×J°POe&4,¤të¶4B·€ 7eÏ›(T7ó'“óHe¬@,(•Ø'âA€#¤}áŠ"†}FÔ)ÅkªE(æ,jô€DPEÿ(`ÐĬ ël`ªWŠ$ê8\¡„³0ýš¥K`jÄP ¾]œá%j¤ÚTAˆÔa)Zd«:¢‚ŽG´ srIMeF! KfÂMô-‚ sYÐÀ…‚¾Ò ôz¡€}| /Û€ ÝüD%ÊèðhaàA$ x‰hU26!¨“c)_“èZfÁ›ã ëëê(©ª;¤žå­P]°æÍ(0À|&lQ³"¤ ƦS¿0¼“Ô9òé08Àª–˜¼"nYk¯Óü,­/€ÄÌ,­PÒjÍ„1nõ÷|½" %Àà €Ÿþç€qÐAmÒc c…{ã:ú0w6š¤k³Ø]"¤¿zŒ4­ÈÄüXÀ€}ȆL¬ÁKb2‘”€!ÈbÑðZ‘¾¦ma†Û©?Œà)1WiC8脜,[¹Bƒ/F‰ì["ªá"nè#HÀŸëÔT€‚zÿ’ý¤ ùÀÔ`.0Ä~#èÂ[€1ùÒß!Q4wÄl+X°XD°‡$ÂñLV¡¢"¬Ø/±©f"8cv‚ d 'J£,d ¶¬E hi†|ôhÊ{‰PFpHx”G€:Ž 96Ò>ÖÐ"i,`€jHǬ‚È*Z8‚ž(fq øi©¢ ŽWT&A ÐJ)…-d «<%7CÆÌDÌ 7êÜ»Ž`•kȆ‹à–™ºM줂‹Øf5CTÏ—ñB;€'¹µž¤£l- )íÙ̓ˆgÈÄ+¢¹ÌK´€8é!a=iAO°Æ“ ¤¿ÿlÌýÆ<1Â/ .g’ðKÏØ0ôéÈ&Bk*…VÁLIlÀÔRDÆÄ(Ѐ(h0Ÿ4âM øLCÚÏz}ô $ÕÌo^ÄÝŒN@äL?9r!¢0ªu f3ͱ®Ô¦jeF*Á Ytt˜@Ç,a‚t´*3”!<ÏÕy’¥ôzA«˜‚P [ÝX8©Aô²* „$± ¤u­šUÅ7÷%™-`T95P):F™5‘E5#áÈ`‘ªƒ]'@±Q'zaŸ«5>Áš™sI®M ­ ÓÍ"×`´-™d.zƒ;²E* )¤tY ÿQß´¯G`§ žlEÙȬ5KȲD;RF« €lL6¹òUnû‘Ú¨¶x£.H’Z؃¬•§*@SïV™@$È‹ÒôVè-A& Ö×Ð.¢ÂóݰpZòâcIÉô0‹Ð’p&Ôkü×ÃÁËUÂòL ƒÅ r·ÏÄ„ÛÞí—³5æ0‘½S_a2 5ª))*ð  (²Ùhã‹›è†75£à‹;h`ÙÂŒ'²Á@7v©RÝš×·1p ‚ãã±Èr®§…‘¤ÝDû‘HD’HE}Íî!¶»#¸ªË“~ÿl•SÒ$ ›É,°¹ÇcPd ’w]tÎEö°T1ÕB• z²z§»tµÎwrä2Ê¢Z…Ø 6ÌmÙÀt‹À¯ H¦ÃZ#`Ø™Ða‡,êù’ºi´N†¡Æ:©ÄR­ö³z°„E Sцfƒ™‚Ðv·m9|r~½ÜÚ.Æ‚:ÀòªžÀØÝîÇ­xf3ÀÌuò¶P£“#Àþ6;<â'·'nñ‹c<ãß8Ç;îñƒ<ä"9ÉKnò“£<å*_9Ëöîp ˆÐg¨¸ºRC£¯­  硺[P’d+x‰=d#Ð[n·o«Žÿx­›ìdG;<¸©=—"–¨àY€W$€0Àsؼ©mkå'8²t¾ž"—ßq½l‹ÀÛès‹öK³'9îÈ{¾é³øôc!xO;b4O "ÐvH`“B{T”ׄæmÎ?–ûÜ;›þù€ OxÆF ÄC|Ø t¼ÕÅô¦Ø(ÁøÉp¬¡áÇ(ß·¶&‚„E;aBH/Z'À…rí(_UïõŠÕÞõê¥B¹œP†WضçÝPÄDü”\B§‰0ž\)Ò°Ü£P÷Š` ×DkZç›,…yñƒ!Ÿ~åÉî^³¢2«®÷pÈÆ^àÿ“ñdR•Ô–”¸MIG<—ž(I!¥WHÁƒíOnÑ_ÞàH±’ $À+M,‰À?¸MYW.YAPd6Ò×éKò5Ù=WCˆBlÈyl€:&ƒü] ZÞ„ŠÜX||Ò9Ym^‘€°ÙÂí šøLÌI ~Õ ¤z”°Y ‰YéüàÝT_ 0(þÝCOE‘B69×(hËmŸG!ŸÐ±€ b!Î刎Á̧ùAÄ×ÔðàÒM²€N‘>QX˜ˆJ0F! ÀR5ÔáÔ šÀ V\! Ð"¥Á±©aXÙ64ðÿbÝd f¡ÌBIÀ\­ˆ]éÊ¢¥øýº± k¹`¾¼ƒè¡(òK ÀÀJHÃá­PÏIA;ÀµâÚ ¢ÐTV©ðPz]iâiA˜žSºü¢v#¾|b†â¼ž2HÆp‰ކtA@ß4¦Í+FÅ5Nâsi"WI†÷U9`—Ì9æ\:NRG•"Iè# ‚óTÁ†0£=š[žÁ}Ù’~ÝBžÁEHž­Ÿ…ÏŸH¬`×Ù!Ř$d VdD@êd‘[: … ¢ Í^ŒIüÝ%^R£E K¦  ¨ˆ°š©‰ ¬=ÖiGÉ\t"Œ$¦žÁÀdñœú±IÄd¸€£çHÆ"HŸfæ%g: üå!Îå¡ÅÕ"ú&Ô|›@eÏ(&¹ 'ÝØÛ½¡¤"ä×ä-gÓ¼ÔÈÛjRAk2g*²Ô¶‚4´QÜm'ˉ'ÔÍ8@¾QŠ©Ýz¶\{Úg~~êgúçÿh€ è€hè"h‚*è‚2hƒ:èÓtçÓ|'AFÐÊ1š@[&¤3'>5‚|–ڴɃޔ-h’r: ºN´8ÝèDîP]Ð$Aï4Äï4SðæV¤-\ÀHàA¢‡š@uî-*¤'‰ÆÅU6“ݽÞ ˆÞ¦~øp!y€HÎ\9&M!$(ÞÙ e‡a)dLä-…’–hÂ7`Öÿ ôˆçNÙè ¢jAêå&‹°)9¦Mó)Ÿ’C” ˜§"$§š–¨ýåÔ ùÞ ±"¤Øð!Rñù†‘—"Í+€h*ÌÔeJIåTf&£ÿ”£RÁõ!‚#Ž@å8 ‚4øYÅŸŽ$RÌ1ˆ‘ŸR¦ßšøŠý¤Ã—ŽÀ<'Éü©*g±ª„"è_ŽáB­&+ñàq£Ô`•À@dRŒ…Fú%ùÀ#€Àä3r+"4ë³þ„^þHˆ´’x €`Eé Î%.éR“—–²¦§M©˜Ò 6"ä´ö‹ÁJÊ+?0©/ñ†…8k=•]!ÀN2aðqÍ@á&¶`Ú l† knîÁJ6ACÊEŸN¬G,ZîeCm%_˜DÖ)ŒD²Æ ÁNI:ÍÉ–@6 ŸË²—ˆ”j ¼M6MHÿíÌ–S´–I¥åBì5@öñì54ÀP•AUâabS¡åñ¡ Ò:ƒ°’¢>ÊtÁmRSUªÕÒ,Ö6%ØÃ,²@#ŸÝ•.ŽéàêT€§´òêǰí «}¤1ê*»fìÌèG4â-[Õ¬gáhÚ–@iqB‹`d–vÕ@ÄúLã–Ýãš@äZE}nm=š<6ífî@çê#кe 1.¤> äQèÓª¢" .Lx^ç^[îî‹Þ6Á+ômGÅu¤H’,"mÓ°.hhJš"KÂeE/õáä¾ãNí¬UHb ødðq )QšÿüB¯ÉîæI¢ŸÊb( D-™>íP%üVoi$™VBjE¹†W†Þl„ez\Y–‘e_qjŒ/Ó”ïùæEÀ%ìæŠ I3H¬Û‘õ>žßõ%FÀf•– Yˆ ™ÏSA'ÍÉ6Lê„kêdüÐ@ºVÒdN…îZ_ªº°Âp4˜š¦°˜žÅ™fôJiªÇ©Ø‚ö+®êö ¨ê–žÄl®gøÜ+Í ,ðôæSAÅâŒp¦%õ¤ÒÀ²RÁ¢Úñ›¨ ¨Î4ÌÃÐÏâæMW”ªüHcdç +—~¨'tšÌ" ÀqNàa2 'ÜQòý0rÞ CLVÿ€ŒöШìŽ2âñ+Ër\Äò,Ûò-ãr.ëò.ór/ûò/s0 ó0ó= È%#rÌïß0À….°@Sxè"ëÌ$]Ä,]›|æC<] Œì±±ÑpÐhˆqlàhâ¦h)ïh›ô š­@!T.JÝ»ÚlC<À!(o…“Ê)ˆH©jæ¦])àåh"Ô2ÞüÀ פ© à³9ã™bf6'(½R›æqž´èmX6Ј‘åéIPÚ&á$/öIq›½/¢öCù"¨@[ê ¤æ)¥ºÇþ¢G¦Žé"-²× N·ÀE×m¨ÅDòœÿâƒê´«¬¶îÝWÿÒ‡_ê À¦ù*K⦴ÚtHÀ«(kEµz4eµï;îŸ>bkWõ–5´øÊ3Ô8–TNŽØ”lÒ=—Ј̊À»«-Ì6¨@oS+u |î«PFö! î’PŒñ2÷ ëR ¨Úè@%oTJcËj§T×5ƒÎõÞÚÁÅêÝVT1p¬ÇÖl;ASÛé1ñüµÙÄ´=[´fÃêxl‡ªÏMµƒ 4 eåCÁ‰D…ÂfcFóÐn®ŽiŸnªyu:PQA!˜YC÷îfmG1âq#E™Q1ÚQ%Õ%2U?Šÿd—±áˆ÷×ý@ZC>ÿí¼vN·}Övÿ7þ–-¡VŸZ‚8öµvmò†[sŽ¥ËüÇr³ˆ+Ç*cSÁ¬€]<«@W—ï&¤D—>’ÇÊÎsíN€§ËC†n‹‚–ïàû-à¹{w¹=äW-l¤njµ÷Æ¢é¶ï”KÁpKM€;dyÇÕú:;2Ìx+©Nç¤QÔïTœ9 œφ‰Q¬Xžm±Qk8áp¸p-ªUCr¯ÀL*ðQÇuÎv‡Çf–Pkó¸X"ZYRƒÁ Â5+žFØ1  $  ÊÅ„å `]†)VRàç?EŽÿÔºÅ-¥Ê•(jK¢ˆ &H52^ O X€…-ÀK–D °â”¹‘O.]|†È(~î•pŠ FÔOT I£„ЉÌ<ž¦Z)òB¶,’xÊyõ–‚[ͨðeÀ¿%q¡, 8ðŽNbŠa¢sâÀ>ìž¼M’M°ä©–ˆí¨Ó ^mæ6z院F[›˜›áåB×|$ö…¥«àÍ>ÐaíBÁ›Å¥;H}‚&&2[¢•ÇòäåÌ_¸,,öð^¬–XÇÉIG¦Í»»; a"ÌR~jk`†ÁïªS,=QºÁƒêã‹äºÄÄ Œüc^@•°Û =Xÿw—PÈ7@}ì•p“4€@ ø@_'5á]‡“=StËPœ‚'`ÁïxÈb"G™ð^N • Xdw‡&ÔxßWç˜`Àp ^'\ÙqI4¨…` AL0ÖŒ; €Órå â¡\‹^®"†ÈÁ …â¢Dô%s–))e9`™`O ¢ #b'h´~sBè1±²ÙaŽ*?µw‚Zg‘œ"j‰—µÉi.Š@Æa|@›¨¨g§ÞíA#€Q¤‹#'|–¬&°Ò§‹?ºs†Ž¹Z…­]<8kø', ¸^ô"G©bjR›ªÿJ­aRvéL…>Öj–Îe[­dAx»¬5ŒŠƒ)D@Š¡Ùa¥TÔ€§iº@/¢TZñŒ’uš`›$œ{ƒ¼ÌPo†Ïí]† ±¥Š . 1x[ xÙÅWB0 pÄFâvpÂÆP€É±GÎfÜБÀjD‚ËTÈrŽJä ²œ4[„u @•cÈKŠÐòœéÖa aʱÓŠLu ×~êˆ$0Ѩ$Œ‰„8J´pÕx°) í‚”‰9gZîî¹ï roB vWáGƒ 4p@»ÂA_[8–‡ÄÄ^`W<Þ(€yæLíM·ß$^ÿGèõIxÃ0à+·%¯%HÀ"pæ]ÂW¤jà&ÁÞà iÈÏ‚@†°§FûÕÏbÁ‡¨â6Üó˜™ø‰ ¢ÀxF @½ãD }¨`ÄVW³fOc(C†F¹/LÃé|Å(æé„RÄÔùªÐÃ*j±ì2ZzV›ÿmqŒ©{‹üöEÌo";¤BúÈG}ÍL¦s5âˆGˆ™ƒ8cT®8…% „¼ÙîrVB8pv…l¤#«˜ÅG>Ø, ÉLj²oܤ'? ÊPޱ“¢,¥)O‰ÊTªr•¬l¥+_ ËXÊr–´¬¥-o‰Ë\êr—¼ì¥/ Ì` s˜Ä,¦1‰Ì1îñT[ôc¦ðÉc`†ÞÁ˜7†)øw'p`QI@"p0„àXDÁ½ó5€†g˜ ©ö–÷Y3 ë|@;)  `@„Ä ÊPK¨A$C5f`" ³)“é¡\àÜ| 6€É(ÌEÿ‰'ø S™•ì]è,锉e¸5èN s¬Öãz·Ò,´‚Í õ.¡ã™*{ÌLÁ–N§£dÆK]bš•…Q)¨%£)hÀ"_‰6µ± œë]n€˜h®q+Ž̳SÖ;›±,VˆuJ`Xð†­UµníÊÑÂЀˆæPa •ZP…z0$ÄfÔÄö&› H *K„ar$FŸ·¢\”Õ ´‘å|¥8‡QA§YG…ÃR_]Ù/F&û°vQoUØyÂvV «ðŒ§Ö)ˆO´ïq6v…ýÛùö˜hÅ £ ¡û ˆ‚PÝ€ hÀA ‰Pq(d! I:9”¦¥œµÄ`[Ÿ&Aš@5YO&‹Í»õéÔü_ÏŽ9IªãnÍ” eaH`ôÙ8n&Ùñ܉M©ä‡×ö À|t³S«e?—  ,5 ž„5­RÅ9ú& ÿ[(+Éó]Hl£rzƒp¥&þ–¨Ž>1#-Q›ÿE;¢O‚ϼC Xg ʼníù³„–²ÎÔ¥|/c2Ž5U, Rš¸}Ò Eì–Ö•5Ô€Òô¿«ð¯QŲ&NÛ<íκù¥QІ¯ýåÞrÁ™d+Ú’{^Ð]Á^à¨çúËãNÈÓ+ž®’{ïOèWǰÜ6ºS„¥LýS³[¾˜¬tZÕ¤5eÌîÙ&«•9e9Lý°C ¡¸uÖºÏtê¡ð`ܦâa—½¡¯î„ÑBhÞE7ê‘öX¡ðci'2v'OyŸ‡(á3Éténtÿq&w&0(Gh£kSvÃò6µ27VUW¼EV`¯¦¶qhT8êA8†3ðŠsA øïö*‘Õe 9™“sS ž³w¶¢C(÷·!ùe›7w^ö±#)°_.p;I ;HF¾“]‡ ¤<9%1…&ƒ=x&vRlt=#‡?úB{­5r"–3Bä=8•:!âChäペ2|[ÖC 0?ïƒañS?›ðhhHmßÇ?9@~¯¦‚pD@ÔO/Q=$å4P¤²O¯;èy0”5f“sæåA àÀOšH†µ0\ AŠ'Dÿö÷Bg`N)`f Ö1FLª% BDDeä•ßÂQ4÷U„RÄ‚U|V€Zɸ]„_”bpOÀ\fƒ¾ÀPøwá efÆ}ÈŽ´Lä¨>Îd‹YV‡é¸ +€!XHO%ùØϨº@I–ÄTý(mÂi)I¸ˆ É é ‘)‘I‘i‘‰‘©‘É‘é‘ ’!)’#é,ÕGZðŽR ›4Nê£0àÀ&àw$…Np@ä¾c5à@ð‘( ±øj gábF°/POÿíôN@²O90/É@ADPP A‹z³F ¨]¯¤Fºƒ~UÐyÊò–V0 B1lB9i5<¹  @“È•P¼Hzzf…o`¯€§+ƒ×+Ðz~·uëµq“`HáW`LXìIíǾô6ï)òûô»—0à¿;£±D£ô5ª«¹¯a¡1ž­‡0y·&À3Œª_]¸2¸w¬º—¤½ç¿ |© ³¤C,,ê¢+qÀÂø»»6¼ x«[Œ«‚}oLÔ·|Õ Ø3ÿöi¾v~ã—{ ±x ~ÑE4qá~.`}A´ ô·=LÅOP§fŒdEáÅ6BÉ¥éË¢ü· Tš£Í1›*U›/ç—Õ8-—P¤ ]+63¨8ûrà–W"È`‚@|l-.x¿Æt0ƒ°9HW:©ƒ<(ˆœ’Q`Å›´© «’qÌ)ƯZ“ôª»¹Ð©^â;†#…ÅrÍ|75wÆ…ÑÓBÅÜ<`x8ѳ¥€XÛ[[HhÑÐ]_°†˜ù†-´¡bÛ™±TЪ,Ã’±Â.P©ºÅDª8²š±5I«Û°šæL‰È\9…ÿLàš¥3a CH‰ Í=+&ä削!TT¨%™Æ"Љ©è:«(n¿è@¯8Có!–¸ÚËO0К”ÓUPš@ÂÛyÂ(°Åa*ØhŒ¦`°3™nšP¯$Y"gÍ;G‡³Ô"-8YÇ¥„t™Å™L5jä·ˆìÁ"+q®,i+K°ëØ^ÇGÍ„’àÈJ}«;Ã(1 `Ù¬Ô³ÝÚ§t×Ô’¶½MÜQtvÅÜÅýËÉÍÜÍíÜÏ ÝÑ-ÝÓMÝÕmÝ×ÝÙ­ÝÛÍÝÝíÝßÝÝëx’YоüÛ™ÄöÄoù)6½D6™&eÝK?”äôÖÌQÿÓW !PfORé0ìtAWÉYùÔþPÿíS`C8T+eYÞvmÚžd@yr§sóÞO@¢ÀD˜§KRàƒ5ÿ‡ƒ‚gn1CZ’965¥-›#Ž))šY‹ÌFÙ£WT ^fŒâwÇ€5› ­ãF7¼Ç(0»ÇáûÛ§G+É©VË9͉pµ0Ñ)å—À®yUÈ:$Û¯Tô=¹­„C.¤JwLòéÉJÅ2×7;E`zê{€Ú×Þ¡ÒSYÉe Rž Œv„ JZ³âI°Ü¥”„SÀZÐñÈCÅÛµ´Æ« +¶5È~¼ ÅE¹£’Ÿ¸•ÀüÕfÿõ¥Æ¥æLÙL.¥Oà¹HŠ.§W[pzwäQáÄ«˜%àÕ:EäÕ!ãŒÌ`ÿÜ4ä²äÃ9Ü‚M·¢ªê¡§´rìѶV½Lá_šÙo¾ê>’Å0:qåB©«jì’ T¯¤²óCà ‹q ¿ðë~be^ì²É bŽ¡†K½ÊbÉïcpÓ1íÌGì’ìH˜íϵñ¬ÿqë-á18¦BO`­l6OÎ¥Ö­’VFÚëšôèz3ï_!Œ· ÜF*ïüü~Kÿz  oF"‹¦`¸¡icW0¬×Ê €±Aån&ËžVYNÑ?knÿ#Õç;Ù²”æûçe‰!¥oj;j2oK•Q´.ÄÆžÁ|Ep7zžgÃv~â°t÷ÊVû X+÷ZËd ^ #Î3Ü’Gp%ŸI'ßeÇ7%}U“.¹n^Lƒ»mr‹&bOÂ(Á¶ àÔãƒãÍ5àö“»–«½EͦӜ«Gz} 2ù|ÿ¶¥ëÎÍ0:.K„ÿÍõ}ÜÂö;\íKÈ«3I@°‹vXø  âL€A@íprB’½Bvre®r 9²iãK.µøÒ"ø’ô %´ák]ÌoçÑÊ.lþKD÷¿†Á÷'äà róQ‰ ßÿ<êüR×À  Pš'šL0©¯Êj— ÝH*ó'& 1 ”CÔP%7°gª!‚R«Ö+6{ÕÌ ¥J8  SäÍš0jÛî7K¯ˆÉž^h¼ñÚƒá)P–¹6àck 5yê×úyn(ɱ‘=ú˜×œ½g-|<ŠYC€xAÿ%K?Ö)x…@(0A(ö„`bEL&º½àÖMïüRà‚%æÁ`ðP&"Xƒ 0@xy'(°À 0ÁŠp PÀŒ @IÑ8@A\\ÐV8á!GŒk$@D^íן U¾e£ <ÀE=!+¼™¸æ žÔ~Ø#†9€‘04°‹‹ðw#="Æ&¡…zŒg‡Â’‚¯(úhEw8—‚&ƒ¦@’rjº)§0ð¡¥:"AaÑÕ†š¢ª‡^›½°ç}šL¨«Úz«o€®Úâ¡©ö:,wTð‚ “ªàãrÄ:û,´·ÿ -´‘«B`R»-·ÝÞš ·áŠ;.¹å*8­¹éª».»íºû.¼ñÊ;/½õÚ{/¾ùê»/¿ýúû/À <0Á|0 +¼0à ;üp¯ºò­"ì#¸Ï~A#²nª@†xàA”x xà¨Ã`@‡Šà Tœwù2h ÍûÙ )/*‹EbÎ8–e`A1¿£4î¼QVJ€Þ"¤†uñn;‹ÀÓ™3 ÆÙ¬L0ò/DIÁÉ)¯\ŒwO( r”¶"°žv2ç§wÝY#IÏ×Ôjh¢–L'H3%ØeÍy¸7\2÷‰ðów\Ãá5´Øÿåý’$¿ AÚq¨,Àç%@ÀÐ*³,Ë]W,à°¸ÎŃsiÑ€j©ò‰ †’ðÞ»¿wJ_ni`ÁaàtÃ;@u¬íêZ(û·À Ø…õ=šË9´.]ËL•4¤†9¸ÿÙܬdÎ!ÞÊ<¢[ùÀOrbņ€#fháUâÚ€)f!Ý;AHŽ‚)“ì.iJ>Ìçô= /’EÑ£€|¤k@Ù"Ь+p€vø, P„czðýFâ. + 4Á(ä°ôðP!_0ƒ$Êt‰VŠRG…jÁ%C£‚ÿth £`à ’QºÌ5J\Í‘…< $  ¸ÀŒ X…Œ¬~t‡ã–׉/Hœ¨§à˜‹àõ+Gu™šx‚;4î šÔ‚›¦¸šÙñr™| ¦è7Ñ€9cã:p ¸¤V«àÇë¸õÆXDÀ_lF†EÂàa3ä[Âöw<`LdVf2ˆÌFQœ@É0@ŽÄÜ”+ŽÐ,A(rHÆÏÄp+Ò|P@§B™$¬!4¤¨Àÿ¶ˆÉ6˜*`š Å„(à@òJ„#žbØfÈ3TÊ]ÑÚ%+ÿ©ñQS#ø& ÚW;§@Ó}„ <ÐI,8aà̘¬ , 0ÿÖ n±Ôz4²Á…E¥"Â2ËÀ‚‹XHЇÖP«ÂCIiE40ŒNDh@føÓ'FáR\§°À_¯7Ø¢À$ò+A€©ÀÛwÂu0#Î|©“ôpy™ísCÚ?¡º&Ëi:ÔA^d²ß]â3ד˜Í‚P°¦ƒ‘&#¨ßùªU/Iàø`Ç÷8UHø,,n•/¸[pŸp`9,ø pûm\qèÁc¡n ñÀŸN4 Õ :¡KÖ€2‚„µ&v‡(k․ÅÊ.Û$ {‚ȪàÛqQÚU2¨Ëj£¸l ¹Î6Üb‹wÛH*<ÿYnR¦åLáPÔI!Éв¤ã^Œ…"<5Ê@È·§ ¿ÁM ÑFL í 8ka%0-¥¢º9#®&l‰ÙXQ!+ žÝM]Œ¶ö–ʧƒ°„q°úYj\ÆJ±àëÒYG#þN¦Þ@–?䙜™ÛÀwµ6p Ƹ”yèkBaÑ-[.D;³C\K“aÐèAŽÌ ®?RÈ­bäÛHèH¢ áã‚kDÂãPK˜µ@;w³³ÐÁh¨Û‰.ÊQÎy츳\a¿J­d|‘ÇÅ÷¡ll¹¾©®ÇˆãûIÂêNÝÁ‹¯ ž‚§4¶ÿÑ®GóñMÆ= /=’cW<ù z°çh~MZ o5ØáË þAÑÆ6¶Ô ½  “ceSgEûÈ`(;xd(å#ÝeÑË– ;‚¸s¬cÇhÀn‹ DÄãð·8µF0ê{fa—EÓY°Ï/ðCñ8±p áL´¡…åY°(´0ê™Ò´ù>A"Fa›˜ë¦YÍÄC£Þr™œ6xÁ«€õŽÇ˜&µ…åøy¸“‘ÒÜ“5G øð#‡å³à¥+ID?×(|d´ü0I@CW;Úû.ÕkÁ¯li_–OÀ@öQ²®«ª Dúã‡Î‡ÿµ˜µÄ[ðÚ°Ð Àsý d“ª ®ðÝ­ €Ö¤Ÿ¼u vPž#ˆÌ¾K0‘  <®T à£QL؈ba,@§õË^}àÞàšàªl Ø þ ²‰!ᢞ&¡.!6¡>!F¡N!V¡^!f¡n!v¡~!†¡Ž¡¼H̶  éeÁF 퉀˜• &ˆàÓìÊ $Ã@i¬AÆ‘!»|JP  í-Öõ ÆÒA>ÍþÈq„Õ@‘–J RÅÚŠ ,Ö“†öX¸DŸ˜[µ À˜ šÿ‹²Ôá‰@'=Ž ÀÔýÊpÈFæ™ÒÉ¥]·Âÿ•@L@”p€'ºBZÁlã¥âÀ…[8ÏDÏô`ÐP€ÆõäÚ×qOh …;‰O¨å¢úy˶µÁ¶„ÐùBüÁû1£»¬¢LPq¥vüVHÌÙ/pP¹À‰cv‹›hÁ9ZÁ€Ÿžp¦€KÌ ;¶ ¾ÿÊä»<$ôd1MTÔ7à(‚:t‰ <”‘nÎGBK@_:¾š CÑ(e+ÐŒŒ+¨U^¥3J[B4U ¬$žQ‡9!UåØH‚VÉÊZ¾Á%®Ê[¦@Xt"‡ð$‰µe<àå¸aöe¹`åhÖ¥ÚgÑ`` i=¬í†¨–? f:Ë TúÜh™Â-Üà zÛ1>M€¦Cf_   & ´WYVèÉÐWO$Êà—fìW%žÏlËdg\>ç>º‚DØ@ÕñT|¦Õ%Ã,£p MjAŒ•µÀr˜BdÃkyÐ0JNG^Adªÿ p@ÁmÆš˜)¥0Ž'XšB$äzF q꓆U[™]ÀCäTl|Ú˜qÈDù™®ý#·lçu¢qf„Xºi( $@T6¨·ˆ¦#pfkš$á±È­¹D3Üš‡•Pn ˆ~Xwj‚‡€'žÍ\؇¹h´´'(ihYâ#º½€º»…ãÁÛu¢JŠÊ>A€rBnš%‡‡Y–u'“v Œê[¹`øZêÜãbfÉ9Ä&[ŠËÂabi àäX¨é.äé^–皆æ_²”@gÉÚÖõx]k„]ü–l,@Ù ŠžBfvË—Â@˜Ò(xƒ} ÿP;¦tÀBL&긴) `Þ† ‡–\CçMN€ìG¨å–îN—vÊd"„@HD@„dÀSiSJÞ¥rÕ(–ˆÀÂ1¤«n ¬ÂÈòÇ!€÷YbÙ‰ÔHˆI$¢ß~ZÁ¯rJ°N³Ê%€L¸šg†zÌôfLkµŠËµÚ yèÂHÊTJ,‚ 櫃©¬ªXàlM*L«¬,©D©Á6c  "`¹îѧŒ± ËK~FvD€Æ^ìš"áÁXË d‹zrSÕ,ÊÎì ¤+ÍÞ,Ú,Îî,Ïö¬Ïþ,ЭÐ-Ñ­Ñ-Ò&­Ò.-Ó6­Ó®‹Rÿ >ì¾8@ÀêATå˜Aáaº %ÀV¹A•H ØEë@ÔÔȪM î†Ñ¢D@"Þ@¤ Û¢-™˜ÉV\`ÇRΦK&^ÀÐÖv‚Z(Öá³BÌÞx«z€]ÝXî˲žnE+:%,2&ùhn:0fÆ®ÖàBAáš /zAô¡!Pëj#¡àíð\¯zA¥ªU»ª@T©ö¥æ¢8©¸E@ÏXN£ è@Xö|Â6ï}ãøp•òçÇÎKmÂAì¢c¢±À:Žà»‘éo6ï&”ÀvIŽ`ZtÝ@Èåãò<(øÑã¡ozšÿ€ÈÍÊ>öc>D.ºn¯¼„ªpmCªžƒ Œ –€, 7†EFA‚ûbZ{šua\QR^ADjrÒ“F*Öboš¬n¸„¤5”Ž DÙÉh@ž¼'QAäSŒûÞÁDàh èÀ0„…sÜ,=iƒ)­ÇÉBUöÚM® †ÞFb&-ìD °Çö‹PJQ¨l©(F`ˆ†hž @%ijf‡Â„ã8•ÓnVA%,Tyœ ¦ÐXê™ÜmÚ‰@=…à““¬?q¥WRXrÛWr @"7ZÞ€D=æp¼ôÿ)W¤QG+$ÇC¸‚ßœ à1ÂØ”2Xh¦Ø)¦ <.`Úavœ.3È"ÜæR0•å jqAª9)@.›œdGÞþä8ú‹)÷1qäÚ%ëæÇr&¨©Á\‚+ÇŽBjÊÀ:@§•Ke/ÈĄ̀0O±I iyÑïhf^in±Ž g®¦w†¤–ðv*—’2¼\s™úb ³$°$½¢ŸA`(Huñs>÷Bè%À|¥ïÄš¦©fè9F@K±µ—xAtîbî£?‡Á>Š4íu´dåÖtæà¡Aê> “‹ÏÚB@.i ØÀ¨¼2Ì­ÙrýfŒ.ëÿ@§ù²Sã³Dó`¨‹ÅK÷¹Åç5ݘª²Ö¬‘l¤(û*B¿‹BÛð¤œB ¨¸…ì:Ì–uŠnq”~Áþ‚´`0u$ò<Ÿôr4Àšµ™ÂrU#v„¦/í€/è– —ÀD Eœõéõô¸(ôß``s‰ªŠ`'vNâg3èÊ~TÂ:¥˜Z·‚ibœÈ(cË¥Ø(g&‘Žb´e«aZ»K÷63ô ð‚/)O×nÃ<°vTé£ö5dtOôs S§’vÆ¢n”îã¹}Nu_i:–¯~¾ðo·‹f3îݰœšpëDäa¿ÜQ Gÿn™}5dÉ/ ´scŸÖú¢#`ÄÄLø&ö5£½)UùÇœ¶€ÍÓR\o¢I5÷Ëzã‚6[Y9"vD‡FÌíæÎ¢vµ~]_ˆ˜zŠSoýÂÒ-@ÓuÉ@]~å¸eq‡¹â£j pò€B¥¾`dꦊq¿vMz³KpÇèGå+«@ª"*NGÏ‹ßõÍðÉ.鮸²|yz8^{é/p Æ™‚S¬Êq tëßq-æê5ˆ³¢wÀLæƒ@È„J\3hÈdW’s—°)V1k9Înºa‰Ÿ¸RðÛ~‰zI‘IÅQ_Ô$.}CÕšSÁÙvÿe÷ηfk¤õ˜ð‡~烎"f󩆩/»ÚCì@ù!lê0°p»Š“·ÞÓ^V¨÷J¡{ªìsˆqRl°ß³)Nà^à«g¬?L«è ³¼“²7{1Dm†‰Ãú ^áÈ® ÐT¶s{Î.yF†9ÀÔ¨»ª¬¼×{¿Ð»½ç»¾ï;¿÷»¿ÿ;À¼À<Á¼Á<Â'|Á{{çÂNÃ@µ‡‹ÕNFÖrW×Þá¬ÿ Øâ-ƒž­ÛBm8‡ç•àü„öFÍ-ÒÔíÝ2zøµm¼EÕðÇù.%>üFE<›fâ*îp uãB¤|wv¸+5߸`åâ*æ’ÿ<»{‰lõ"|î+î‡,úÇœ{Z2?Vo_¾ÓË çÅðž†ÏµEÐîù*̈÷\07N”REv]9ow_ó(¯ôPÏ®@¯6yþö™õ¦y‡ÊfÀ4y|/ ×®ø¡}#]dPKÏPT€ûÖ'Cic ¤ÆþöîûîµhelÜ.ç§Nã9Àôi! }¯"¯áóX/.K £èž¸ÀåGhSe-Çó}ºE û ”pL$ W$™E±§™uî ÏC‹0Æ [Ãf×ÉXH²×¾,å“ñ¿Œ¶ñ•D„}UÐî*Žs°`Ïb)Ù!öM{„¸¶ÿïäÿ"yôƒ ŽdÙA©®lë¾p,ËŽ$eè–eÒB:¼ª±*(ƒ€p°"MX%ðx¡³¬vËífOцè@i(aa’’!PM‡åØM¶G i$ jk>^h^s /wŠhj oq"s Ÿ  ‡*eŽ$f°³´µ2~/CE9 {¾&(Ã.sD-W¶ÍÎÏ+ºmBq¬1e)K>©¯$8Ãx.` }Ó$ž#Òʵhà]eWL/hÂ#ÚkÝ|#a!I€$ µ¨G ´‡µÂÄâ¯ÆÜÉ#G Uÿ0‹H²ä ic˜<*–e –NPõ£ÐrYXpÁ .@‚DHË8‹‘#—…Ô pè:B›¸ä„¢ÊÌž$bBÁ©¿ó`y4I–äÏU©C"Õ†V4c$AW¶®Ý(@ࣔ×;±40ÝÕ  `µÑ”¨ZÎ`‡í΄ ·õ2…J ¨,©B¢ó¯  Çýµ§k{üe8ËáÝÛ¶$GKB‚©üTìlãNÜÈ‘çÍ”o`GÜË g ¿>Õm7ÂÀÖƒè.ŠîE›÷H«Ø€%ŠHE „ïú+ʼ­ý<¹K„¤BZÿ%¡ ¥¨0SXŽpà’Æy_¥Å5%¼Aš.ÀS]9,ÜÃ`dÚ‰@™ tp Ôiq]tÒNXŧŠS’ áIP(‚6~µß,á‘0˜Ë.*øÖb‚%”Qã „øˆä•µX×Ö‹Z,7‚oˆÐ d¢0bb:"™4î‘°K1ré…—"VÂLý ’}6­±'‚pFÀŽØ†å¡"è¦gAŠ`dÁwÐ-ˆ‡è¥\ìÁÖ—}fAu ô(f™¤ŽXÆbŽbiŽ-Ì5ÞˆZ,aez%&àŸ’j~òZ¡WúÕÒ¦ÿ)Z‚4,¬e£zî4‡V ÿÑp+±ˆvbŒ4–úS@ÙºÁ<;aä‚–j€ŸBDÅw¿¬àjœ0v±³hFuj·è½îA‡ìz®LiÀB°üYHí‘Jº€ìE5¦‚ª0 ‰ +fv0’PDІ³JD“DWœ$™ 争¾Y¤RX ,`+<€™PÁ4:ƒ<°H£Ð›yRÕ„D #«Á€É:¢°€/Üó[~ƒ kðÅÿ%ü,£=à 0ü®ÀT‹+¤BÁ Pˆ‹5¦H—) 3W™èLBÊ#ài÷ |‡‚6431€A•:²™#áĄ뒺ڤ֭«ø @€ÝÃbèÚÿÉËÀPþ蘄âìÚ…»@H2œ³b`ÙÇ!³`ŠEpÀÞ7ÉMÂa΂@ƒ`À‰"4b´S0íÎr²;! H_B㤠,ƒû®³„$•‚êȰ±—elgŽ·€o€üÊ·€¦Åº$¼4'kŸˆœÃ™+ûÈ@‘3 `iÂÖÀ Zð!üàˆÜA}]ØÜGˆ4ÿ…F1À68º0câC ¥‘«½°…©8Î vòÀÏ ê†@ ¢í"Â! °С *ð;#:ñ‰P4I£HÅ*ZñŠW\ ·ÈÅ.zÿñ‹` £ÇHÆ2šñŒhL£×ÈÆ6ºñpŒ£çHÇ:ÚñŽxÌ£÷ÈÇ>úñXŠáÙfH&fyaŠ ÔÅ&`»* ð€nE@`ðÀÕîˆ \`µk“ `ïh€´ý A ÀJ´¶ > ‡2h€0¸ hA­L#ÿ²; @|ù)öÎHà°â‚ˆ P¢zÍ€€6eŸQÐb’ÜnEKbR“Ðß"9½ØµLoÛBÚÊÔž •‰›Í*S;/eÀ.(`Ed*Þ|7ôi£AzCådH5C†pšü“-N0IHŸÿ^Ȥö <0“›.U°8”€ÛXǶ@0Àlà@^‰F:À¯ þ }V‹<Ž€‚GÀ†Pg/pQ@µéô¾XÚÔ g "Ä,uT!yA!(±ð@¼Tø‡‹’b]°€¢)Ö6‡HÓ{X*°¬}ÖêÎÊhÑ™¿hjI´ÄZ?·à‹1€(m»¤t¾5‚À°b^%BN!§Ui†´…LyP-à) €À` ÐmÖ³ a=é ÜJ $á8 «¦к‚ x`b܃7E&ZЉU˜D·°&g=‚wH@ àS V Bÿi |ì\!FT"À@EÐ:¨®²[€èÇÖ x ­Hn   Oˆ¤$ç+IŠÐל*iÌ €ˆ6„©x€@«1*yà« Ä[*ÆJh×\€m. $Ã<ªªb+“¥ƒ¿à`è6Ÿ!‚@»kÈt}·!â% ymÎ6’Äð^ð€˜R“5ÞÀ(ò€¿rÐd%ã+ÉÍ)À{sÞ¯mB¿Ã{˜´UÄ»,îÖ$ì.ZV„PÈda8 r’ D.Qœ©bˆ Þòf)N1™T\sU+˜WÜZMê,fñ@UaÖ˜èÈšoîÿÐàífa)‘ìï’Gð°Ð{ªÆJØ•…ƒV%3{È0ˆ³C‘ ˆÏA=¤F8«€Æø‡’ùˆàÊ‚kä‰i‘â®Ð@ô*08\Ôƒ›t R ƒr*6ȳ-M’l‚ x°vÏ)QR$``v¶àix[¡Ž0©×Ñœ¡4ƒgœQÜÏÖ•#*Sé„UljY¢€d»Ö\¯HŸ·Æ×)ºñüê¶sÀه~v¢+Š˜HÞ•hÈ:ð€  ’Žf`^öÒ—?úƒ›^º…Ø,PØYд@ 5|”ª”àÞÓ]ݰÍÐSª¦F`³Ýkb3ÿ›<é²#,…îad˜f5‘# îgŸÓAº€¤»V¨S(Ñ88 ‡+4¦Ãð v[ù–×½lxGpáEªã+Ðj{˜€{à³¥y¤Ÿ¾Á(em(DÌsæ-P;aõYP½•”xw’¬‚JK^ Â[6w[A(×éò”ëz°¼öt”ڸΣÀS‚æ"Ëà·v‚ ¼ò[í …ìãNáx*Ä›ãÇÈFX9/6æÿ?bÚ7·uVlu@Ö P }*Ä}¥Ç3¬²»’-0w”b%;B1=ÖÕ<Ø…-‚âT5^zô Ø·uʇwþ—I×<?¦l”Wï'??PÐ-Ð(àjÛ'j;è}$`b#°.L÷.\o^Yˆ_1N.pñâý2SÛÃoB27´\Z§YdQh̓’D[¶%ÔFçD)µ+ER(;? pXl°ª$EÃP4&@4¥À„¨.ƒH43Ýa3ÃJð†+€x ãg àF“ˆOE2R%q õ4k 5ÿÄ{^à{±Ãg1"h”h /¨‘wup ŒvyÍ€dcHMañ¤ ,27¤’!Ceâ#óT&æ—x~ÓÍQ ñ8ØzÍ(‰C8>bñƒ^‚P“ã8—p „‚äŠ\Pi¬ ³øq`c?6:¶hRCE‹ZRÃG@Dµ“qc†¿ÀJÐ38·Ô&ÈH&Ê?ˆà3°<Íá<pM¾„„’rmÅ;ªðKK?^x=`ÑDÂaJJÀL atbaŽ „Žû˜dýè íøc÷5_5¢_2#°ú¨Á¦‹€dA–XAªØ¬È9ôƒ}ѦF vCùBÿ$½È9ÕôL,¹>.ÉAN¸Oéö×E0f„Qy@‚äBÒ˜•µ•íSMicB]` @f”maY–x‰II-Ò0p—y˜‚i{9˜†y˜lT˜ˆ¹˜ŒÙ˜Žù˜™’9™”Y™–y™˜™™š¹™œÙ™žù™ š¢9š¤ùFgIHL`|˜Ç–d¡k¦‘HòH69ƒÀ¥†¬9˜P°"U© À@`3×AŸ”·´7mã‚u£Ó›* K¼J I Áô"º–_²tL&%ʤ *y,ÎM`øÀKMñ ›gQ‚×àt^)ƒºÈZÎðu1 x´ùE…ÿt»9’8dj*Á9E °Œ(°]S&EŒ©™P‚Ã+©šY ˜ÐÐP00}ìY ÅQuN·9ö %e¡Wdc … ä°‚&=¦a ×Gnéyˆ•wwÖXÔ€%æ€òÇk%J;Ñž>ÑYnZ¢uQ¥µV3©  ¢Ç€N­õZ[Д,`[¸eFmÚ ÿ‡(h'3á|G"§~ד\°°9*Ic™'Ô5³+â~$Ð]íI¥áe$X²¨ååÞ%êuíU, _7I›Òj›1£çõ_[U|—zmF„bä¢Íà%©@§n"S–¨‰âeÎrPìe9e&¦.À€¹}Þô["6$YSu¨§®%¬,ænŠ0Öh?Ii5ÆYƒ¢c5F ¶yù8'dàšM–Fâj @Â)˜A½¥£×­êrìÊiav¹¹Ž˜§Y€f“\lš€ªíg ze ¨ÀXYUž"°}Æ5Ñimñ5hSgRi8Ÿ’$ÿÁhæ ‘‘ö . ŽjTª¶0<²„sZ¨:H';/Ç.§V®÷¦TÀjL±£4²FkиvÙ &x¡K;©2”µUlÇ–lK«¢V—_k(mn£Ú†m«;2™µ'Jh7«ëEÈ–€ 0yR¶”òª¬àn¶p -€ófr&‚s;÷67£Úod£z+´‚ËÚ3I†p pfÕÝU¯yôwuÑ5x!rµq5Æ•ô¥e¤µj˃`¶W;g´21U +)[/r3¨³3Іĺ+°«”=—?‡{ t’ŒþÚ’‡‚&yÛàtÿ,u›R©*ÀÄ[ujˆu%Ðb[àux(JO)ÂkEk=I@w0%“a½%Û gëvß1qWf·º’u§:Wy·wÏakÇ'ê–HÙ·$q<‹ãøéSGh܉d!eyëÓŸÒáüGª•Ë@…üÊص_u§ÄÕ½(RSLà²'¾£Dv±§€J{ág{<2Â[»ˆŠ(°è19|iüp—ڴܦKŵ%}øX«U$½]€sše¤7XE9"ÙÆëJl‘ª{v!\d—~y³~»XÀú[ñW‚(ÃÑ6ÐúkZŒ¸œuÿaµÈ^¤Ç Ð{kJÜ@jÅ3pDeF…TKÕTÁ¤QµÎé ¥W5Âô<Ö´@Û²¸V&Ì¥gEE¿u^ú¥’ –4Z“*¶F” ¡%ì¦åp7xG .nþ.á!3±a«:ØÅ‚\°\xÌê•—«1€¾"̾:Àª¯=xõ 4= Ý(ȶ^®IÕ$`qüEZÄ&aý ð÷+÷¥3°u²ùïpûñž 88ÐxÔì1ðì{Ó]œWÉkÐÖéjzìÆiîºW~v.\up0jIØ)ûšò©èÂU Þí @«pÒ¤IEbRš”d›V’”óšà°’¤3Ÿºœ%­ oÿ5ïd¼ñEêïZ’A’¯ d·&›”Ì«bÖ² ì2«f Þ7;*9 'O Nó³³.Æ> 1ŸQv­+H+h$«‘äj}æ5±ÄÊp<ÊZE¿Ÿê­ÀNÐ3h–÷$ªãb$ñ(ê8’3‘ «Ð©u‡dËõØÞ+’/)#/(ö°P k2tkk’@8ð¾Ù³0Yþ¯‹ÄV…;K¯‘ä P_¿ ©¡ñårø*ø×"IõºûƖ͆›,¬Gl¦3 3^úo¼2”ƒ¤><Ÿ ú¢›O3^‰z.òFÒ$èÊæ+“¢oÙ» àoÿ*Ók“â[É €ˆXH t"± Þ Þ Ô³y>„Çæ“xT±Ãç)&”ªÑÚÉâéý‚Ãâ1¹ü¼8f/$èŠÀ1(œÜBÑ!°€9¸­ Ä(¸aLLTÀ Æ08JT¸=È ý9IhÆ`4<$4õ]À4P” 4 ¸&DÊnX.‘æŠ4 uÔRx8aIHÀ,ŠåÀäÜÔÜ `\äY IÇdx@È$™+­8uó²·»³£©¹'ì1ÎÍè $Hîš)tH™¢ä¸@ ‰%J,ý³'¢M¨®&,û7cA€‡"8ÿžñ)dŒ[íµCPÀM=IQ< ô’ÂR3ÑD 0€A "­!/ ·#èĸ@NÒL//c¾‹*uêŒxQuð D7]U(‰2 !Dc4p€¡‘›¬k(MhèU†…«f´¹lçYd€QHb7ÝÀÅ«ÁX^äLÀpͽ0˜¼¦‡M7 (P ˆ¶DtÊø††RÂe2©|™*íÚðÒ\õã7@2ƒnàle)œ¥æ0cpñß’àZJ€ª}4ì6×Wíe}¿ña’]ãèú,5ÈYœjMž0ðàpC‘¡ZÜRªé=¬g›ÿ€Š!Ç}¼Ðc&tÓG\"7œpz!‡f”(Wa†áP.ƒÉð×lu 0] r¬V ˆÞ÷OvãåÂ@¹ò %xíÝDˆxà §8B~©µISá¨#OBù…UO8P@®&Â_áíÓR/œx1Ê [¹Õ\†N¤·ás•XâÊe ÈáV %²Á¦ îf114çä 0æRž$uõf‰R¥ È™{7ät‚ò…XD‘ÓéM’I-)Õ¡QrÊi €Š"¨ËðáF‘ Lp€ `€+„Ã_4¡@sd‡ØŒdpDk PÈ™Dɳd9tæÁúÿsà †ŒZ-r…PÐ…Īe[] Іnâ%vÒ®ƒ@’ñÍ·£4¼çlœ òy€(~¨Yš"­ÑÆS»< ¸rC¸É€¡„ÌÐÀº&ƒ˜k(€Kÿ`aKül,—è&2 +! ­->Ð)laŠÅ(è u©[Ƹeñ~„M9`°Á¥;õA&þLÕÎ=\µTK¸×ÂE*`’ÀBh.?˜ø§Íb¨4ÀЃEZ˜mWi“±l. GLg&Â~ÂÀ·¬§ #Fs çÞœ®%x ÿ©´ýÌ(jD°EÚìŒ(Ø`s=ûa 9/˜knµì³Ó^{‡vÚ.U ³I²¶í9@œ»ñk _üñË3ßüT” Aþ:?|Ý‘¹ì¼Lµõ[äZ}óZx¾øç£Ÿ¾Ã(Ÿ>Ée½ïbð€°æaÀúºß¼þü÷/€ ©2¿0$àl* èÀB0‚28 +hÁ b0ƒý£ ;èÁ‚0„"! Kh¢0…*\! [èÂÂ0†2œ! khÃâ0‡:Ü!{èÃ1ˆB"‹hÄ#"1‰J\"›èÄ'B1ŠRœ"«hÅ+b1‹ZÜ"ÿ»èÅ/‚1Œb#ËhÆ3¢1j\#ÛèÆ7Â1Žrœ#ëhÇ;â1zÜ#ûèÇ?2‚$! iÈC"2‘Š\$#éÈGB2’’œ$%+iÉKb2“šÜ$';ÙÁ” `8žåS&!R¢r‡¦e*[iÃU Ç•²œ¡pB™²YâÒ‚ŒÁ߆KÊå2˜Üå ~ÉAa"ÓyÄÜÌ*m™Ìgö¯J…À2˜ÐÜfî\=Þ4beŽ-ÉÉÍs./´ &¼ç…l¢3ž¶s–ixÊ3ŸV[‰6ì9Ncê3 kC2üI†r’3–]è“<Ö‘>ðÒ ød(Em³µ­=Àu½hE;J›TàUnÀ6Ý€ÐSz4¥SaŒ,PwJ”£*i;ˆ¹ ’þ’¦:]Lx’#3€’•;ªäèá´™D]* €CìèŽ&ÊÔ«Êàø‰# Ím4§X++@€ Ls øiLËyÒc’U§ƒUãJÖ¹VU¦v½kÂþéËZ*t¯q]k1õ*ØÃÒÕ°ˆ]¬ÞšPÆBö u,em¢ØÊ.4!ù8, 2ÿ„© á.ž ¬Ú‹³Þ¼û†âH–扦êʶÛ?îL×öçúÎ÷>ƒ ~Ä¢ñˆL*—ÌVÖŒJ§Ôªõz}N°Ü®÷ èyŠ×ì¶û '›?±´ŽÏë÷|ü¬%Ó7HXhxx0 X¦8÷è€(9IYY%‡YÖa'ÁIa *::ƒù§ØIÊÚêújqªI§ k{‹k)똑 ,Œ· 9Œœ¬lµØl ´,=MM´ø€Ú{\ÍÝíÍÒ(‘­àY¾õ®¾îa:K>aþÉN_oPüø”vßïß-ëUóþxÛ:|8ª>FðX ¢Æÿ’È0*ã`\!18š<ɧQ3‰¢| 3ŽÀ–cÚ¼Ùå-Næpúü9E§—@‹="’fãL›V!ê4ªT%h´L½ŠõÔ¬\»ÎðµÊ«Ø±dËš=‹6­ÚµlÛº} 7®Ü¹tëÚ½‹7¯Þ½|ûúý 8°àÁ„ >Œ8±âÅŒ;~ 9²äÉ”+[¾Œ9³æÍœ;{þ :´èѤK›>:µêÕ¬[»~ ;¶ìÙ´kÛ¾;·îݼ{ûþ <¸ðáÄ‹?Ž<¹òåÌ›;=ºôéÔ«[¿Ž=»öíÜ»{ÿ>¼øñäË›?>½úõìÛ»?¾üùôëÛ¿?¿þýüûûÿÿ`€H`ˆ`‚ .È`ƒ>a„NHa…^ˆa†nÈa‡~bˆ"ŽHb‰&žˆbŠ*®Èb‹.¾cŒ2ÎHc6ÞˆcŽ:îÈc>þdBId‘F‰d’J.Éd“N> e”RNIe•V^‰e–ZnÉe—^~ f˜bŽIf™fž‰fšj®Éf›n¾ gœrÎIgvÞ‰gžzîÉgŸ~þ h ‚Jh¡†Šh¢Š.Êh£Ž> i¤’NJi¥–^Ši¦šnÊi§ž~ j¨¢ŽJj©¦žŠjªª®Êj«®¾ k¬²ÎJk­¶ÞŠk®ºîÊk¯¾þ l°ÂKl±Æ‹l²Êÿ.Ël³Î> m´ÒNKmµÖ^‹m¶ÚnËm·Þ~ n¸âŽKn¹æž‹nºê®Ën»î¾ o¼òÎKo½öÞ‹o¾úîËo¿þþ pÀLpÁŒp /ÌpÃ? qÄOLqÅ_ŒqÆoÌqÇ rÈ"LrÉ&ŸŒrÊ*¯ÌrË.¿ sÌ2ÏLsÍ6ߌsÎ:ïÌsÏ>ÿ tÐBMtÑFtÒJ/ÍtÓN? uÔROMuÕV_uÖZoÍu×^ vØbMvÙfŸvÚj¯ÍvÛn¿ wÜrÏMwÝvßwÞzïÍwß~ÿ xà‚NxᆎxâŠ/ÎxãŽ?yä’ONyå–ù_ŽyæšoÎyçžzè¢Nz馟ŽzꪯÎz뮿{ì²ÏN{í¶ßŽ{îºïÎ{ï¾ÿ|ðÂO|ñÆ|òÊ/Ï|óÎ?}ôÒOO}õÖ_}öÚoÏ}÷Þ~øâO~ùæŸ~úê¯Ï~ûî¿üòÏOýößþúïÏÿþÿÀ p€, ˆÀ*p l ÁJp‚¬ /ˆÁ jpƒì ?Šp„$,¡ OˆÂªp…,l¡ _ÃÊp†4¬¡ oˆÃêp‡<ì¡Ä qˆD,¢ˆÄ$*q‰Ll¢ŸÅ(J1_!ù ,)  ¢ÈIi¸8ëʧÖBÖu_yÜšZ±YèZ°8Kµ}›«>=Œìȵƒ€¢¸(ŠÆ€$¹œ4Ϩ©d:¡*Ø´kýjÇUÉ5E{±`à†›¬ã5w^ëé%lA&   fm F Š I|9C ˆ• wgD…‚%Dx%+¶±;޼´bD»?½Ã<!ù,7  ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù ,F   Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒV‹C$\ˆ,’'X…# ›‰$ ' qS2.'ceƒ=€@Aª¢¹rµ8´¹q–¸¼rÁ³;{ǽ!!ù!,T W ÿ Ždižhª®fà¾pÌÎtm‹qß|Ïë‚WÐå+SºäqÉLê˜Ð¢3­ÞCgÐÊMeÝ0ê»›IÂ\6@’*€JdF†Å#A/8R &„ ˆ6d/m1 #.„/' /œ$¡.‘l#n ˜"«"š$. "$w§¬i1C“£6ÂÒ# š&Ž "š¼^­“7 $å'±¸“p4kS$±žT8 FXQ0B J(˜E+W"b}KkœC Æ‘  ’)WɱöêM ô0 r„%“'¸pfäâ¤d(–‘’WS… ë©æÉˆXûN”IâèÁó꩸ÄgK 'B‚p®(€nRžÅºÓD:uIÖüL‘034 (3m8Æ.Kàà‘ Zixá&ªÛ‚ô46+"á&M”H(éB {*û)iéØ-> 0  yµD >XÝ ÂÄq¼µ¸îŒïžÅL‘Ü 5'Å÷NÞ8ó*0D—ynK$ê\Vº!ù!,œ  f Ždœhš–,©¾§ÐίÏ-|㦮ò½€ÍtùVEÑ™\¢’JaYtž k«J¹V°S¼$AT ãR6:§ F¯Ž,Ý5ÃP-YþËãïc~€|u[‚eˆGtDŠ(^6ŒsŽ:!!ù,«  Ç Ž$œhŠ AéŽjœ¾¯lÓnÌÊxió=XjANñw*]Ns62ÂÄ$’Ã"Ì=-c¤¬Á*)O["E`h  áp"zo#"`…Ch"w[VŽ6,"V $ "{MG$ˆ ¡S;"6ªg<+1[¢-W.‰2²-Y©%G¿¢r . s ¸~x.ÊÒµ6ˆ4ˆ¢A…gKàª{äÈæä¸ç˜àëê«£ïÁ1!!ù,¹  U„ËÝ ‘›KÄ;½‘n®xšHJâ“+Û¾LëšœÊ èï9Ù€:¢ÌøBŠ,´J²ÙŽ Gê3ÆN±Uî5W¤jm;ëJ‰2§½ÑìOíA{ !ù ,È  ¡ Ž$œhª–쨾iÛªpÊ, ãe`×¾XÉ@Hœ"Ý«„‰Ë$TJ‡@¤Ñ³¢J”À"网¹ 0è€ò ‘‘dŒ‰äQ ¦~KgikV%hj]l‚‰&:‡ƒŠ(€+‚„V‘.r›™/€Ÿ“šŒ @f#ˆd•UBª’Ž‹°œ~^<²·¸¶¥»r†»q¡;ÁrWÅžÈ'­–¾Ã/!!ù ,Ö  ˜ Ždœhš–,©¾§ÐίÏ-|㦮²˜À‚…²ùX!Ñ·*-&–%óÄëMUWÀ˜âbEª¡u:*d$ 嘉TkkÅ/)(~“Kt锬®TxnW2%}K^;|ƒ`]:@€r#ykG‡’i  ŽW"i:¨{Y”Y„[p²±²“€¹º©¹:\6¼¸Y ”!!ù8,å  ½ Ž$œhš–ì(¨ðÙ¶q<³uðžÂ]æ*€!ðWÃñ(K.u@a@yc6ÔYl‡œ6“ÀdѹÒe:8EÊk@z²ˆšD$§cH^qfÄÕÄ5ØÙGÜž9ß}Ü–AäL=ÜÓ1!!ù$,ó  ÷ Ž$œhhéŽjœ¾/ÊÊ-]â²¾ó*Ÿ 8Šd·ÓÔ°Hƒq$æ†É)’I€5gŠQ%h U,‘–áZ,ãàp~)y # ‚#( 6Dk"x ^™yvaT" ¥»Jz½:‚" t#¬8’\i0‹Í†Pª‰CÂÀ‚K.P ‚ψvå±x1Ö!‚B!ù ,  à Ždœè)¤Aé’lŒ¾´,Ó¯ã®Îò&ß 8‰Ö*µDŠŒ'g2¶L˜Hbp¡`•Ȁ P•"t,q DÅé¬êx…Àá¹ÆÉ1|6U# LB"'ŠSF"_#‹L? '#–P- % ‹v?®§'¡—Œtfª¢wg[Ãr«£7cf …´¿‚-NÝVß}H¬R¯>bâ˜êÀäàQì>!!ù,  ‹ Ž$œÂ©®géŽl¬ ï+§qíʼ^ò2Ÿi aÅÕQ”T.›ª%€ÈµˆÆb2HPÐ+3`ˆ°a#²08  º™’w<«xÀØÂCPCƒI4XƒzAŠx+ŒQŽ?€“vMC‡‘’L†˜–H„O•G1VRi­¨B®§«ª¯¦G2!!ù,  Ó Ždœhš–,™ ‚ж´lt{«BÎò7Ÿi·ŽˆE#9S.™8g †$9"ƒFA DÐ(`q ‚,‹QO"ÆéÐs6ST¬yO;T ' %g_‚U' %kŒDvp%j‹/;r=˜“m6–‘¡L=†ˆ$ŠzU}$r¨'o2qwa#ex™°•#WY[jÆœ9’`¹A4 g¦”Ïc u³G7¹#'ÙÚ¸*Èf ÞÎ@bF¿RPNî6B!ù5,-  š Ž$œÂ©®P¾#+¯0,§sýμ^ò9_L…ëŒEfü€,‘ƒå4AiG‚`Y4Ÿ×Ó«òµ¶fÅqyŒUvXç%r,¦è`x$zW€fPykv(†‹{mb…w2‡r œMœ |+E—›@£m" ¨ª‚BWiBŽ@´µ°>’n¸¼¸¯¤¦´mŠ´¥P!!ù,;  U„ËÝ ‘›KÄ;½‘n®xšHJâ“+Û¾LëšœÊ èï9Ù€:¢ÌøBŠ,´J²ÙŽ Gê3ÆN±Uî5W¤jm;ëJ‰2§½ÑìOíA{ !ù!,J  i Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo ‰EÙJ×*Ž<§m‰ BWÎ'´™ÜfOÔÝ÷GCG ÖFx¥SkØ”e>ÖÃ@©Wßîö­,xX|y~v…Cu;„]‚‡€=dU”[!!ù,X  Á Ždœhš–,©¾h+èË,ýâ¹nŸ<Ó¯¶c¨ƒÂ¥[S¿„aÔtžâ0L¨Uàs9rœ¢°øD)N–´0&5N9ñ% ³IOhjt6d  zU~0R`'CE0Ž”•4‘X  La‘m]SM§$ ›­u# ]‚MC®$±¬:¼#'SœP»µ$ƒsË#F„A¥ØÀÛÐU}Þ|0ÞßÚÛ×âÇÝè*–(!!ù+,g  U„Ë,âi”JYs¸ÑéÅ%ßòlá42'šškVB+ЂsW3]ïµ{úù`–[K0l%?a.³EOÛ«gTfIšiw+¦Ï¦ø{Õ¦¹Ð3µ¸!ù ,u  ¢ Ž$œhª–쨾iÛ©€Ê, ã¥~Ú'–“œ 0Vzœ— òç ’ ¢W½‘*G®kY…1Yd¤MÉQ!#™d3ôÌöµ¬•Îi\k$€j]†}+„h‹Œ4ˆ&p%‚‡•.—„ž"UKˆŠ›U”c’¦¨–ƒfš²œ<¤ ¸Iº¸p»¹*­qÁpÅ»ÇÁ¼T:Ë0Ä!!ù,ƒ  – Ždœhš–,©¾ÂÙÎoÌm«8k¿,Gàáû­JB¢Éˆb1&”b`‡¢Þz.¦ ;JYy¢BJ™ÕŽ ’Ìd(eÙ˪íMîj¯¤¤ï[£·m1,penH„vF‡u":@Œ?~q†yˆŽw"ik¡ r“F¤ŠM\™f®¥š±^§®wx\¸±²¦·S–ºZ!!ù5,’  à Ž$œ€®héŽì©²ÂûÆøi»9¾—«YN4v½˜èt´%YDAóölN¤ìI4jsÂÀ2€pD Jv\Š˜S1X·uï¦@Dl1B*c$LWwc% ‹m] %“U]S"“aƒcž ¢wn'–$˜šƒCyŽ$‘›\y#‰^«l }¢›¤Po˜su‚ºEhj0Œ?Ø”ÚlÈ)VÝÀݹIäå=ç=„nÝß>ä«!!ù(,   ü Ždœhš–,©¢‚ÚÎoÌ­ýâ¬.ó. „ÙJ Ê% FÂ@l¤œ&ÈÉ"²ÅV€†–€gô$¢,C€XßäY$Qÿzoi#I v#) vs"r “”:~ \T k©Z $¬Q¯"%•/¢'®"‰´¶R:¤"¨ªÉ>—™L Ÿ¿Q»³(’ÑÁC Ä™† Šk UI!!ù,½  µ Ždœ¨€®eK¦k¸´lÏt{˹«¼Þk—‰'ã‰RŠ˜I''2P. ÁðÂÞ‘5@Y–PãtP‡0Mœ$@yî % ~L‚Qu `;„?7•B+^¢³y¶ª…š¹·Hu¹l޶SÀÄ«Ád!!ùw,  U„ËÝ ‘›KÄ;½‘n®xšHJâ“+Û¾LëšœÊ èï9Ù€:¢ÌøBŠ,´J²ÙŽ Gê3ÆN±Uî5W¤jm;ëJ‰2§½ÑìOíA{ !ù ,  ½ Ž$œè)¤géŽlœ¾/»Êíâ²^ò1ŸÉ†€(Q„œ-›¨% p#:‡ÂdxpGàMT@ PðT…Q†‘!À0yÕÍÜ¡: 'k€"g)„P- 'ƒ…)yQ+jwŽ%˜š@ %©£¥%t¢€ '"‹¹ª6d( }±¸™m  q'Ô£O×FŽzÚlªURÛábQK›<ã†ÝP!!ù ,"  iÈIk¸8çÊ©þ—ПŽx¢–ª±m`º°çnµtãùŽå:Y‰Wó]€c©š ™F¨Oº£ºDÀP5›q¾¸S ¢P8p”ƒ¬pÆx¿u€ÛÆ/„v¸¿…G`vE}|{„CZV4‚7!ù;,1 H ÿ ŽdižhªŠA뾯°Ît}Âøkï|šÿ½ &qÂä®uüµ”Й“銦 Gr ³¢,–[õšÀ’ñôh>‡ÕT ¹ m‰à”" #NKdO-w-{}#xœ‡ˆ"™ -z"|ž$€‚%`bCˆ -¤#$’$™¯$hp\»%- #«“Ã#o³8MU % -ÏÀ#®n²AF ™&„Ã|~­©#±pØHë%íá¬ã”`U;G¦mÜHx NU€"$AÍ\Zµ’-Ã5‚Â6…-¤‰(fíZ—[rz‰ØÕkÄ‚ˆ¡2á Àc9ØÈ´!×)y$˜=lÀ#‘ŠB–<¦ˆQ§ •Ðöb y#$´¸ð D)´F À`GCž 0$¡r&@ÈÔBjSÚèE÷£‰Þ6ÿš ,Ø áÂP#Æédqb¼÷9^:%!ù, m@ÿ„©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J9ƒªõŠÍj·Ü®÷ ‹Çä²ùŒN«×ì¶û ËçôºwbÏë÷ü¾ÿ(8HXȆg˜¨¸ÈØèø)y'1iy‰™©¹ÉÙ‡è*:JZjzºŠºÊÚêú ¨K[k{‹ ;›ËÛëû <¸L\l|ŒÌ5œÌÜìü̺ =M]mÍ(}­½ÍÝí–í.>N>^Žž®Ž|¾îþÛO_oÏ9¯¿ÏŸ˜ß0 @:ÿ<ˆpLÁ„ 6\è0¢Ä~'Z¼ø®"ÆÿÃiì2ä´)$Kš<‰2¥Ê•,[º| ˆÈ™4ÇM€3§N1{úü 4¨‰Ds =Š4©Ò¤Eät`©Ô©T«F)ZÔªÖ­\»âÀú§×±dËšývçÙµlÛº5jÚ·tëÚ•š–çݽ|û²Ì Õ¯àÁ„›ä5Z8±âÅ<äâtŒ˜±äÉ”W[9³æÍ.Gå :´h`>š³çÔ¬[/^í:¶ì½°gÛ¾}6­\ܼ{s­í;¸ð£q?޼§\Èz“;~8ôéÔ™H¯Ž=»Ý‘µ{ÿ¾ã:øñä_pÇ\>½zâ×»ßù2üùô5\P?¿þD™Þ`€øG”€î×Þ –W!ù/, ,z€ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Û˃„È Ä:'†$# )&š›"›š%  %%®Z  zµ­#• oº " ¢$Ÿ#ˆ%™‰$   |Äʺ—% yÊÎÐ$Òwð@|"´0¬ ë"“ŠŒD8ªõ€›‰OÉ¢} t.~®m26"߃" ÄÚB뛀[¹tÉÐkÓUm†ÿ颈,?ÌØhæ.À4 Ô2äm¡âjM(Á “¦“$žÍTx3žSöDðƧ8pM?%h Bƒ³ò$qÍѽ âÆ=`€Ü¸ÈÍ,n 4@¯*€|þIݨEï]¾wƒ‰@0·®½{EP!B ”k$ ïž„Ëé²&h:p@0¸Â„D‘5ˆ<±7¦G ÈôÀ@€%PÚzD¦×O£Ó€U V4'_£7¢Ý±d‡¦€ñ´d~Rк¥"“b- Ã^*‚•8¬#`A“é- ºì4Vo:]ІhÜ¡ÐÒÿK1‰ðÌ3‰ðN=È7Ù °¤—‚7/‰°6)I„SSSÒ¥ø‚u¸ô!Ã'”ÐF`4YäŒ_ Ð@]åÉ€,ôw+âñˆd¬ “a톑*ÐB¤ ½”ó:%x‚%4¸\1y`4á˜^®Kš&pxÂ3kV; ”éœM*æÉÂôYWŸ× rŠ)°# !Mãà @’ÇTX‚g?‰ ÔUdþàYœ!¡Ôd%#Á'×tjB¦W† âœj†h²Žà& €d÷ŒŸL3¡7—¦á ·’ð#žÔbЮ½ÞI¨žÐʹª)䊉ÿ‰8- @£8’££(×âÐU+´Û§'ðeCõõÑ€˜Ê»*d ’’ ~jЪ˜©­æ §| À„b©Â°*k«¤$üv° ;íÆGP•83r( ž%¨-·æˆ]£ Éû’ûž`Û¤œ‰ht.T¦@W«ÉöKVÌfèTKŽÃDߘx¦Ì„ªÛÄ¢ŸÖ“m 5RKˆ,ÇdÉ ƒÈ&x¦aß½:(ˆ €FŠebá3¯àž h=B[ñúÁ~öN‰¯zCžÀíU³!ÚÒ:rí´®ìfJÑ„¬ -lËS\ôÿK¡^ €æb?[vŠhãWI„k?=‚No ¾­Ü  ps¶Í9} VÒlB¢&ˆ#åÎóý¤ß½Ô’0ô Yò¨ih£•†Á#ˆ¹kVvNèˆ/`BÓ$Y^ú×"&ÀÍ™«Cûº£Á²`í¤ ÛÊemæÀ)Ð!>£s:Aðü¶¸ÞÀmp:sÑíö“¸/ä¬y#x–^u4ÉNA–Ó¾šEµé¹@|' öº”lÏiª`_û¤ Là pa&.àB‡©€m ‰ÐÉ<è­­%@\ˆE‡ÐåÁ­&¿+¼ä”žy]ÄgÌ[¾ GÁÅ| ÃøYÓ>¡°fŒaK ßÇg¹ÿnˆî43W£Â>Å(ß°Û p(ï¨p­ê! t;‰Ôbw§+" þÖ6ÆÔ±„…«ˆMè…#ž€UŽ«"bņat t½ó„ÇÄv YÀ£†È˜I®)šQã˜>?7ÆãGä@†”d0¿dªw©*]’äHvAc1J¾ ²]Tä{Á¤MnyŠƒ ¦h‚Ç™‘Ô»d Bò(ª’u›8Øô¹b¶éŒìˆ+rtÂ@†Su®¼2(ò¡VÎQv#u@ÈCi30Ö·uQkG#ÆÈ'Ï@ÃÐÛí"š(KKå‚‘†ÕÆ3ØÌæ ¡»Ë@4ÁT¥Ó¼““ºÌ¦6·ÁÐ&G—ßg2™€qcvø!iµéS˜ XÖÀ!›Ø‡ æ¦ Ø%µ7|9ý J!«áŠâÊçDHÐÕy}ÕÉ$a-FR’£À“ ¢Ñf êj’×´óš‚S€Ò6A(Ž ( ¸bKŽbÛö䵊ƒciHZ>b…H¬ @ç²ÿÃÆŒNð¡ŒNó˜"€¬GQŠS¤b{•g¹ Ñác$b D$€ñüŒo8Å0ð’ÛŽ)±Œ¢®´aCßE¾ìÆ9Òa!ÿ*¹É°„'Lá [øÂΰ†7Ìá{øÃ ±ˆGLâ›øÄ(N±ŠWÌâ»øÅ0ޱŒgLãÛøÆ8αŽwÌãûøÇ@²‡Lä"ùÈHN²’—ŒááŽq ! Ät I&ß`^°á"bjdÂ\`Ø© >i´É8hU (« {^˜È—eÐ äw°PZ"‰ ðp@ $á0ÎP@)sŽ2ðŒ)ç ÊísÿÀö&,Â>ø q‚1ÿ9ÓDPq€X1½à…›­€Œ­šXˇrwÓÒ-HÌY"%àh@zu°H´h¡f# Ç¥Àk*‘=Ÿ€Ù7àZMíç h¤ØŽ 3o€Œ+ÎÀ38°.C`pÀ¸”u m#w>Ò@À×è¤ *ÑëüºlÁF-²s„Áp@*2ö4ûí tD(=#îÛ…Vß`¢ŽH—‰Y6EùàFò½~S¹Ìn øˆ­qPÚ_¶²˜D 0ÐÅÑCAÄ'Û\è³›9`¼Ü·Nÿ„ÍѨ-„èümô½ë~×àXRàƒ,€cÔ)snÀø<€ø¨™ZÍL‘€8Lìd'D0Ò“Tl€¡uQ šIX€Ï‘¨ A±XP½¡iýiüÕ%}ß²ƒÎ[cqÌùC®nÁp°’󓢺[±a ~—0ò !ç ºmƒci|3?AH^.ŽÃSÑê5ø7ø £hÄ(†iZOˆ‚8¯°ÐDš„/‘öqÎÀ5&ýóà¹p”- DëÑÞ-x†â, pY#¶÷ hèR€gÀñàdQ=¢”¥‚Y3½ÅöÃIU:ê”å#qØ`ÿf'z›"ADZ œ0ðx33èxptI¡l%fµWrõh¸ƒªà HñK™°™’ª ÁëQÇñg& r'  ×F×FGnpp÷9é—V,8Á2”ÆTÒt'È2M¨b³7XÑž&] Ãaòy³¶ Æ'¤gJ¦×"äÁ¬W•`o‚ð›V9¥THç²çm4 {G Ìu èAB7ÁL¶ôTp ïñ ¨W÷wtaN“Ó„,‡†Wϰ~‹b`QwK§,sˆ+6{Ç2äæ  Z€&``Çò·.8†ÿÜd†b·€¸|¯§âPˆ„ ¯'‡»öt4€uQp8§A|p(•3gI0;¬°Š0§‰Z’`Åi—èG?’H4ÌåYdøz0·^=6…ub Ÿˆ‰M5ŠÙóyø†tc8&Pàø€±Xbñt¹ˆˆ…V$y¸W‡¨ÄhFø‘ øñ!#3;MEOçÕ  j2uûF~$_&PsU¢üX„’HpߨRõ/ЈcS¸5áÇVVÿ¶s,8mhD+%†-i+~4{ggH½ÐŽŒš4WhŽdYu'—up(™ ŽöŒ5hH™RLÿ‰^ f6h °hàÖ‘9Q ‰1gž1 RLÇ¢gôÇÄ4dùW4èyš”R(ðO£w“Y8áÀÒ80÷HeLÞå(Žù¤‹Rg{43`‡FpŒ§‘D•¯àƒˆ•¢Y PF1jUÉt+øx¸}©UŠi©WÒ–»—èôŠ,ð ‡c–§K‹é»¥ ÁÂE/˜0†dèi`‹5c†Ntñ˜C#™”ľˆ&çN •˜ äð!ÀÈGXlYI gˆ( ¶—Œf…¨ž B’ºYz‚É”©cÆ ›½¹G Qœÿìˆp1Ç×ðVH@«†…t˜œ¶Ã O—.¨%ãÙy{M9Œô•¼&•àg’ˆ%pž))Dù•ó9¢SxÃC¨sÊv,’èY-q×aÏOZa'©b ˆ¼P”Çé4ØfC!'ä™chCÏñœÁ9Wa,×;jÌç—6z–LÉêžIÄÃ/ÊqkVšBÓ¤ÕsžR@Ÿ3ÜÇ•y žPe„€ØŸ[¸Ÿ¼ŽycÌ& Ï@&À2–YQ&0U\$:2“6n|â¸'u! N9Ù @“ñ ¥ ú!ÁМu±-á‘AÿÂk”±m½!×`UÚÙ¡8 ŒP uÙ59Ò9(QÍu•* Q€Æq î"›ª©¢ P` QU}Ç¡uUÅ ûó¤… UqKÁò¢Šé9üòŸ)Ff©©q™ØZèd¼)µ ¥+ icØÄ¤13Ðuñ7–µÀu þÁfš°SÛyešYœ‰¼ ÃgPfJ°~ô…£ ðÄ—÷ž- °0gÃY ¶)‰(p4©¹W)ð!“78c„q ûõz†ª®’Ä®š€Ð~™=I€š¨Mj˜€gÿ7 ¯¨‘Ø`µ0§ û K C”°þV¤»÷”]¦Æ2v§P€h—^$Š  _6Àˆ\7ѳPµä­°Y“½Ì' €è“ ~»¨ ð¤¯u è4Ÿjeñ„µn@¶6°°G¦xöˆm£¦(°š»¹u±h‰)Ð~¶êkf«dt‘’ᎋáf5{…©-Nf»®« ˜) kdµ›¯OVG$I|Ú»Î[Å[dÇpv%nÏ›½\½D&ºÚû½u€«1pFq¯½WUr¾½W¾àÛ¾îû¾ð¿ò;¿ô[¿ö{¿ø›¿ú»¿üÛ¿þû¿ÿÀ<ÀŒ¿ûQ»e»d¬Ð¼.€eZ†¾Hæey@ƒx|RŶJKi Àùõ·\ ÀôrÖzv¦_#¼ÀgkÁph’€dhJq¨¸°h–â«a–†i<@ˆû6i. iRÕiG&ZÐ£îµ  kþ: »GQXœë’P|ZuZ Pkƒ÷{0š€ÃJ2¼1À½®Ÿo#Á+ð’ŒãÀ9¨Ýmc6pi•ÈVª`ªw¦]<aÉÄRð“5€U9„æÀëÖnä¨<š@opoKY«f hìFàJ(Чh“¹CÖ ëP­ÿLucЍ+UêT±™Wì ŽŽ\Ÿäq G˜•É›ü¼Bj<¡|.w‘@lc±ç‘3°’ÉbÊåò·×g;¿˜­˜©{pbit>¥JêÆ0 DYºùùË™¡T vwö³ÙuE €œ¿ÔÂT»ÂùJÏ ¦"Ñ&{[]b_º¬­ýPYçD „RËyX2y šbל]tªyQ{Åòʼs¹È”ÍâR zߪ-8„œ˫˕(SdœÐÁìà ¢e¾$£lCiÎuG„KJ5Å#På'ã}¶_TŒ( 6hJsà˺ ~‚ö(‹~Áâ)ÿyi6 Ç­sùÌQ§RdhtÑÅÜдÊŠð¨Í×f“Qrü%à øwyP- Ï%z™Œ¡^*¸ø(2hD½RÀÄo¥n"p©eD­€Ø81kRÌ,I_bwF‹€l)#z ÜÆ)-LØÊY¨º&cS¨Í «|Îÿ4Vw^›v4 œ HBy)†,i86½…½Ÿ’z™êc5 B’e U¬UÜk)›¤{0¶'Õ¡Iƒ€@™Ç¬Dçl‰â,Úß cœøDZØ.ÍÔIJóÚÂ2òåv3 Û®hÞŒ×/0‹lmª¸›ˆÿ¼Ü\ªÉà ­´¢§+ð!äšàlZ±Z"Íf´/òjÏÒ›ý9šxŸmœ³:6…çfŽôÍè Ëè»?À Þ|&nÇÁlµÑi-.©9€Ð+%Ðß°YÎó°à|­°³{ƒÑ¸ ˺¶j¼%ðÁ!¬|Ðl@~‹&J$ÃUÒ©¡Ýám’-šA6â¨ÍÕª½³Þq‰pÑ^ªÑ³“K[ß-§Ú2Óž7y‰”³ŒÎ]*»S á* „²òõå÷ N.Aq&L·É+ÙÛJ ƒõxáŽøåæüâ ¯9ÖÚ =äÛÔÕGÖhd7 †ÿ‚9Û½a˜ˆùÍsÎÛèD z‘©“‰@.Ü} €ž“SÒ°Ðl$ð–2 ž]æé[Ý'0ᘾŽ^žá!¾Ž Nc¾Å¯nëQ‡`~;Þ8¨.!ÁœÎ)ç60âàœ^aë×¹Á]ž›{ ^EÞÓùQ”ŸbþÀè´ïÝ´í‹¡héò™õÎñÖ4†ààÌÑyÎWéîU¦NÍ1p ,É»E¼ Ý9Ó§U0¡ˆî{­ëBN×BzÃ{±Õ“èd$*$\~Ž®¢>»d€Ù qÏŽ@8Z paŽtöýSúRÊÖ XJ;+’ëð®ÀŸ;ïEPÜÆb,žAÞ‚èÝ4/ÒEÃ&sš'?<ƒ­ uu.?_(lz;›¨!þ§6Fǃڠ³Ö<¾Q!ŒªHHáÇüà~s—Ã']•z˜ªÈAãz›põýñÔÚ ¥ 쮪Z­¯zå1U³ù*¿ÀS0á€÷-qŸØòì ŠÄGóFü…9üM?t¯ œÁ•$ÀT#ÁpŸE™ëQŸŒAâúéÕnbæ*_è:Ú1-noMaó­»±¼U¯Ø÷ Aÿ‘k8‰ÄðµÄà]8^µuÿ- €8’¥yŽÈCÂ#äAË›èÏPPBÀm×ûMÖe³9”,¬–޵ý. ’4Q$’Ìë"Î`LŠW`âdœ-ÅðƒÔ+Ö:¿ïÿ "`¬\`|¡ü@DLID”4,D¸Ô¨a¸Pp"|(°Ð‰48tDð\„Ê´ÑÚð$l–LJ&Œý²X@³,–8lÜ’°@OŸ4<è\tp®\•ü$¬|N,X ”œ§'YBLL¥•NèLP8lá”x À6Ä*™@@Á 4òB -üQ˨q#ÇŽ?‚$4cBÈ’€šÿ=È(Í$Ë–._ ™APÈ”uV|ƒ©s'Ïž>iÍð@£ŸHx@ﵕFŸB @à2¾à ‘3`œÔ®^¿‚­3cJ¼°£$1æÔ,Û¶@ÕÅ žœnïâÍ«wo kùÆkáF T ¬x1ãÆfÿ:Ž,y2åÊ–/Ÿ€ìç@‹ÎŸ` øöù3=oèH]EÇ\Ì®_ÃŽ-{6íÚ¶oãέ{7ïÞ¾.|8ñâÆ#O®|9óæÎŸC.}:õêÖ¯cÏ®ýåXe#Ë™bšß_ÃoüQE‚…§]Êq;ýëA3d(:¨lîfÙ€|‰$€Hðÿ¬—P¬( •=©ežWá½G‹.!…]ÓXÔ†XÕ—bt#Mƒ@$“Ø#B#“ +ULòÀ{ôH2á(©¤aWL@RFȃB<HHy6ªås3`HK$X€  hé@„ˤÁl‰w%D°¼à£ͤuKy¯5 C‡Ç8’QR:¥-·è1@“2$†€x°¥jÀF+ȉÔÜéšÔqÃ~ A £.Çâ-é÷ÇCã¡PŠ%PZÇ¥M )È X€W,à‚~ T@A&î,P g’쩃ä"EÍwSÏŠÿ*©×G¥Ê bQkB„G­qÊê ¦šùZg­+ʱ¥…ú¬ø @²X€c M¦À¡$X4bµÁ`[°p¦rC0d¢/|Ð#03s°'a¹uÞ‚nEÔP"Èäd øƒ€/ŸÆeï ©)BÄ œ0ÁuH‘5 œóoÚÒ‚2ëâ+·CDò ±þh.|óá©3ˆ À F“ç´)ß[e'pöícQ#³Îcï†ð …€&ï+„8ÕÁ™B =§Òä1Ý)%"Ü€PMu䨮´0š©IuBªLóƒÍdCn›Ù‚諼 1 ¬ºçá¼jÿBÝ–Þ MÞCÜðøßÈÁ*È'Iƒ÷°pï«ýr%‚/1f5´“ èdäÃÇÆ3!ÍD;2—ƒAIî%|ä&1-§Ó$ß–¾÷ÓUL0”:ÌNá&(KîVÀhýŠëX_?l“2Ö³R  Nsƒ+s|Ý f…·ZâVÛ³‰²$ Te Â3_í G‘õ•À"Š£¿hAl äyö¡cðˆp•€3ýg ••ðŽn«Þ¹ˆÔ-°{ ÊŽ ÇÁ{]q%@§šVÁ[(€î#!c5ª }Ws£)˜É! !lÿÃ#)óij¤mm¾páÓXàÀ°GYΖ…iÀ,_p€Y’Žyûiä ĸºb‘Ø‚~ ½ÅmLf¤NÅ+Ž@ —L˜µJéM¼èR€Á ä‹dÌlÄ(ߌ~!B ÑŠ „$ë¼€w±”~2P¯àG¢˜¦:I5iÎ:ø Äö͇²%œ7ÌÅÿ4‚s#É(Ÿÿ’Ѥf,r˜ÑÜXTǽzVÉþy@Cö)‚Ê%E}£ @Gl T”„(O¥"ÑÈÀ3C°‰63:P´§JÝÉ}$PÅTèB5¼_!³'LBôKKÝ*Lº—É„‡Wí 1Cø›‚xH U®Âux™z¿¤qÍ”àâêWÈ•õ¯‚lmæJØÃ"6±Š],cëØÇB6²’,e+kÙËb6³šÝ,g;ëÙÏBë„*Z‚f­+Ð*gŠø‡$ЗôŒ,Lcâä,€&@ê;xÀ›Iºû °Q Ø-ü‡Hl$¹Ô% ˆŠÔï””k[Lµ¨´Âª FL\ÀÒe,©=ñEsÿàâ-n²g`v³nârSª±„±n/ʰš¡ÝP,ˆü‚D4ª©$X[H`àØf-ŒÔ]{òA+ýýÔ²|ÞAaÕw{|$¸":2ŸØ´P©L4¯ÿ!@|,póáCå}UʶØsA® œù™l:¾á(¦ µŠ båªæ ¸8±¦Í&aò=M‚c%+ãÔ*!ë+µ°!Å‚/žÊçQ†:·€J …#:FÐH› +ud0BÖ%¡µ´Ü,E5ÑV†Öô/pÅÌ$´6M¶²í|¶P¥’uçü×Û¼·ÿýËÕ$©¢»Âí!¬–k-€Þ»×ÁbÚõ 8VlO XâØfw”¶|‚ÊõnÕX•ÐlHD_»ßRù· Ý|9øüà} ƒ'IDÑ×Ô¨ÿ€u[à®]ºÖÃÃP!+¸zp· >¨ƒôÜêdz Pxëu§0T`‡aô=/ÒBÅP9z«=Nå¸onÜ‘×z:ùdwâ|ÈbûôŽ-¬kÒQjºœ€MÎöh º™¡í0Þôpó S„½€Á5¦ö G‡{þZ Ï`ÜÅ?¶à­¬ˆÄÚ§·ú²ÇÓ+±³·¡î[IB¿í"íü!;ø>›Õ&oÿ:˜±,, à2—–è¥#€yäÖg»è;±H“Uïí\‹À®9ÿ¡UM@˜lI# ˜Õ¼8”øÑß Â89m”FmÔý 1¼ÓЉÔWÄd@RŒ%ô“ðpFÐŽ,Õž$Ã-¡@Í ÂBàÞÑ]ÂPTX”°UF}N2hàF}”Âë„/]XCN´œñÀœ ÁCô•PÀ¼@<€’EÈøíÔ ÖùéâoÈ||BÞ%Š¡r4•±†VþýJ†@ ÍØ[FdÕªˆhUÚ¡€ìL¦¥Ø¼ F°Uø( Jbà¡d Æ- ÀDâ ì•èÞ$‚bfè_(’¢7)^)¢b*ªâ*²ÿb+ºâ+Âb,Êâ,Òb-Úâ-âb.êâ "e¢ÙY€Ð@ ÚµaêÕ(5àÃBí¢µ~ô_ð‡LÀoÈ€ —ú ˆ‚d)ײٱÎs!Y¢bŒÅ\€6£ <™œUVTZ9^âEHH@>c[a ¼ˆ$°1¼Å—XÍ×ãá£ë¥c`<Ä¥™€ ŠKv5ŸÐ\¤ ”H4­Ž(±R?æÑ²B„MØ–tÉ1`ЉïøÅœIš¬ÉÓ¹ œ<ß¾5dþ½Æ lâ½e$—ÝcMñˆØ5dW¸¤)I`  CÉ=üX£À«ÚBJÒMÞÿáCA B<&#–)I\@åA•eÄôäQêÅ?NÚÇ¡Žä€áUe!öA%zEv%ƒÒ©™›€2ï%D O¡5"4„Z.Æ?ö ?j$¦LüÈ%˜áVƼˆ D@@ÙRŒÓÁã@¬`=ìÞ'*JJ&ÐýdÄ)¢bî ’ÔÂdÂ.졪%Í'•@ÐAŸP¹†V6ÞÿÁ€fÕÀ%À\MjÚ£öYº¦:Šd 49Y’Ð|äîI¤Lfe!Vò…oÊÞ= ”XóüILÀržÀ¥ 26gXü£D‘ù±Ê©Æ &5UR¦U"wîÿÅDÔí5ÝÄ„! äÃ" § ß4„r¾çWħXU ~Z—éÍj@vú'œâdx'õ Üå”Çþ$åãåÄ‚(4(@ ía„zlòÁÍ Ñå‰ÀÎõWôøuñ§vž€êEˆúŸÀ-# §d¬)Š{0dR’lMAì$ŒJès6”äq x؉ÀÕ$CÒe|¨di\‚§vEƒÖ5ÃMݨúÙdRé›úR¼„R©OèœJž …¦~ÆáÕZv(ØeX”iª)‰J^P @½l”ÉMƒŽNéF…Zzb Œ^™Þ$QkVŒ †)%i^\Ó€ œÔ}Î{„ÿ‡9jLõ^X4øB RªY¨%UÍñ½)6ÕšònÚd¨ Á˜FÆ¡nè™J‘·œ€NúX !}ßvyj­Vi¶a¼±ÍGŽÅúÍ-ÙRüÍÒ.Ñß/ÁR¢EfhÚ…æÿèÚ‘^[®Ú°J!$&µFTžþ∢Sõ—$¡° A¡‚…wŠ`?éÀfŽ Š&¼ÐjUj^Ž”Œ¾Ø´Ú+žZ«­ì`À–›¿þÂzÔý#e ìFuÞãõåBüe´:ãŒjŒ–%Æf,T¨å]ÕmÇL£äÉVdD Þ¬­F£S bR@×ÒŒªq,©Ó ˆh 9ÿfÑêD/‚UikvpWâé ÔR£‚ŒXÕZ- ìoXC´æÙLê(#ÚgÙBÔÙÊmÝ~ÝÚmÞêíÞòmßúíßnà îànáîá". ä JÂÄjÓÞ†JUA‘ÖnŽ€K…‘Íòülßa@>Ä­áÞÇtîT£9x,ˆic—‚0Hó¯¡êHÁ2›››øË‹î$»R^•E¤/êüܧ^Lt)‡'1¼þƒ %é•B0Ÿ¸pWjfÛ¦sívœ‰²i8pé6ïç<çòrØs/[ÛíMŒœ ¥%7發HÄ&î?ú Þßò=êØ14o*ÇSÈ'û×63ª¦usìŽC(´­è€@ÿ­ZFÎA^éÔêIo äÖÆCŸÀC,£ÄAò²‰`f¯›’ˆ1»ÿ1ü®Y—ög ™.!’üè1¿UóqõD =4³&DM§ @15´ñTðÛ*“*¡ËÍRü¹%€+Ù¸ÚŸÐu¯¼5m¨tÊдå²!‹PìU€°!`]퀻§à款žñ»ök˜%;mT¶’è°ex'ôÓ?AˆÂCX¼¼ÕÎ6i¹Å2p´ ¼õç,9d¡ÇbTÈrö¿v1¡+íhW†wÂ1 H·C AÌVÅä]aÓÂmwt\KlŸaùl¤Òð tM2·ÒŒ`*ëí75wu,é4„û¢\“ãŠÇ¹ âýÿ€ïêÍz: Œ­y7Ç{W‡5°p§œ G¼-t8rëƒKøPOx…[ø…cx†kø†sx‡{ø‡ƒxˆ‹øˆƒß}û¢Ö¢4¶€ö6׃²E×Aׂ¨7 #&Së5è>Ky\o*wZ¶@Õ8[÷;¦npµÁ6ºQ7W$×r±@“Ñ.[‚ÇϰcXbÍQø۰c,€ìÂ[- G—PÔ.ûFØM‚-í‹ÆŽù$ÈÑNNÅó$ibAVïAZNBr 5ôµX ÉÆ–°*[´šMG¯ï¢ý:ßF$D@ €¦2$)°¤2ÌØ{´ÿg·‚-Îtü† bÐ/Jòƒ†ùN*tØþÆd÷‘MârŠŠ‹·e˜WƒžÜƒh‰i¯5q]DT(ŠS!¦×ò,Cxð9V—‡ðÐT×95R‚ó+3e»Oaª ÙWªéj¹p 4pHAFn‰%DÂÆ®ðy§oLñåf{]Þ–Y™Aa{mÂLù;³èBØÕ-¨¥ †J³d’;–ç`3GoO‚~üp/{X;”O&8Hgs.±T|tzDqc¬@ªüÀ¶š]”h¿wÐ!ñæLƒÀK%ÅþOùj ®ºÛ`rU729ü®Sø¨,ÀÖËâ”lñˆq Ãÿªè<÷Tè ³BSª·ÄÈ›€Q¹9f<Éæp‚ŠòA õë uÄó†Q 2ð€f!Ø6uqæ7F¸y>G1ïÊ.eX MÚ§x˜4€”He³‘˜½‘ÛmÄ„Â2][=ÑrŸæ¹þãþÀ%>˜'õå•s¸ÿ¥=<âHÁ‰¦E¶®‹œÆK×öçúËÀ2X '€ˆ ˆ†!ˆ4lSç)¦ÙHqR&IŸ}1ÊéQåôh]BZ!·­ ["Àqã€×ÖÒpR˜¨¸ÈØH4€0årW7²ÙB¡³€Fƒ@шŠä“ÊÚz$é…vôp@¢ðwkšpà°Õ…;;bðw2@З¸6‘8Ü’•çBQ&Vc`Ââ(°ÁxàzŽž~óyBÙrHBd¾Ù™ó6K“E žëŸÀså„‘ö.=m#JY£! ™K;ˆ}16¢ dNPÜòÌÙªÿ\x‘å¨þ||1G^Aã00§ÎE’ÚMz¯½k¦pìif†6 4EàªS _܉µÍœ]#°á1H ¯¾lD¼1qX€}’Âà`å‘…Ž5髹-ÌYŠ#f¸šŠÊe=Œx[±5$U!N‹L.@¸ÁÀ„Á–Ú˜P¡ÂÀ«‰K×Àv™DdÀ;Jp  4)ؼãR{`»0±{nEš[8lQRŸ PNålV\#D¦«gz£'ЩG€z(âMÜTÐA7Ï QˆÞb—|[ÿ·g”¤à"(À=ï5ð‡?"<ÿVE¬=@qmQ EpÙW…ÐU6(ÙaíãBP˜Ã2A$Ý"†ÝÇ¢@ìdçÎvŽ@W#8FƒØ¢C9|™ß ¥LÓbNPD`Äýà8.1@SpÇZ#<@RYðÇ£00Á@e\/åÊ}4Flp†`3ƒ:¬1^"’@ œx)K0 :¨SÕ²ÁT„ÂÖ¡ºŠ"aŠPWd¥­¼HEŒ•ÀaDtÚgQ_`°(¤j„Âb£ ÐÀ©ÆÝf©@ .v‚(44yâɨ`# %°Û ‘xD.*HÃ=‹íë…_%â­ÍŠÿPe{e Ñž{$8Øž}4‘Ci¬â*‚ HAµà!ÁÄr&°§^C"—­•ÝsŸ¯ åÙ6VŽ›üq?Š€+ , D(€h$0À,›0 0£g¿ CQp±I€Ò³‰”ùGÛ“íµÊ¶÷· ýø­MõLô˜¶ðF¾HÝa•ó1xå•ïŒ-ü5bþª0ÛÕ„ vØøÉ,6X)nÙjWEÖ<^Øû­MwÝidâ®v“€@!i!+îMxNk8—'üýFÜ…?¾·°EA.g ’6嚣RËÂ:Äÿ AÝØ,¾y馟Þc樯þ¹˜Î0Ázì²Ï^÷à´ßŽ{îºï^ºê¼ÿ|ðÂO|ñÆ|òÊ/Ï|óÎ?}ôÒOO}õÖ_}öÚoÏ}÷Þ~øâO~ùæŸÏ»äˆC. Ó ~WñØÃO›¾‡¦yÐÒ?+_0€jfÀXP`€<>Kéb•‰téí °À2v›ÍÃb&H_<&.eà<0¨:’«¡‹ ›üâç \à$싦ZüýB†/h yÕ€@ b p€’¦x-Q­Ò < !åø5²õ@Ka¨.[;k~Оÿà¦ì‘bUæw‚¶`ŽKƒïÈGF"5f]ƒÇ x ŠÊ°AI΄˜ö¡ÀmÁ;R’ p¹$ˆFÈ̽à#ªª*Y U©Ê¶Å6@! Ól”…0*˜ƒÕ¦1Uìë@6˜h0ïë_åì׆î Ž ’%¦å,ÆNY©‚4BþN£`ÕRòޤ1$eXPPäȶ…°xŽ7rI'T¯!Q:39› m‰-Ƥi­ ±hp¢^Õ Rñ°:Õà GÐ ⸙rQ•lD¨@Íypˆ”‰lÒ‚<¸C¥603ÿRàz!ùàÒ5  bš‚8¨Õ ôDÚb‘JÙ³ (#s·šJ4S…Œ54 b”˜éiBûƒ‚$£•ÂiေÍÓ ŸY¢6ú‚ -âà[€ßÖå·táÆéZWI÷ifɱV«AP-ÞùÐz¨ç¤]x§žÞ³¶µFmÆŽ{hõz yH-e!‡p¤[¥‘%& @#M g,i©)\ZÌ—RI&¸Èyib€„ð™dE Ës E¸OEï#Ðc€~r| ÛCEAQ“ü§£láª3‹y—2ÿžÀ“.wÖzj1 *;¡’ÓzsÚ:š Å ¾ënVŸy"Õ(Jv3’ ‹Ê؇äRàòåìê6nBAQÐ÷E³= Ñ¢WÖó¥3¡{'_ÞúÚÜ>sß1 ]ꂃÐ/´†ü¤¸uFò^ÿ" “WÔw¡'0¶U:ÿã2žÓ09²Pˆ5ƒ1Ã1-à1@¡@2ua2)UQç,ÓA €Üõu8@3D R¿‚QÙÒ3ù4ã×lµç=ž–4X$cMƒR*•#SãÌ¥r'ø(Q0{èT8¶9lTKN˜m³pC7sC…§“ ÷×njƒ+dƒ[àl[86Ù—ŠC7c†\ˆ}›#HM˜‡€m¨£'S%:Jg‡}ˆ8臊€®s!°ˆ‡=eˆˆ‹Èˆ¸u€èˆ‘(‰“H‰•h‰—ˆ‰™¨‰›È‰è‰ŸŠ¡(Š£HŠ¥hЧˆŠ©¨Šÿ«ÈЧ‚h†–3…Ê0 C…s2à5à8ÿe'4xŒ0+0°¾‚v0ð˜´êb_»dA3„5fÔ€Ch!´°]7R`J¡†8ÅÅ)~Ê& JÀ$56‰›;A§[@hpª]ú!c®`šªIUM•Fz"b_–›'v«%9v pÏ #ªX'«9 戴úùA°£—»®·²¨`‡¬ÇàŸÿÄ‹‰¹ ¤4À¤”šŸ*x—p®3F5$Ë®bjkÐI¬š‚ðÔe#€l=dQ”vY$¡Rs¼Ê;ò°:Ážê£ÉyY¦‰pЄÀ8­P`£O5ÿâe€°E"²Ð˜ïP²hW[»v<¦¹feÈà}8o×5hæœQ0P•vãêoæ™:b»;`‚;p+ °8`´‹À›;fU*›*Œ;Ô •’µÚ¶]]K“›²dkhžÉ2(ð«§Â¯“%lBègÎÇ3k9{’jY‡ÏSdQ ?[¦PQ(RQ(‰*'¦û @¸z€±8P—1%±Óºº#P£›c„“Úù‘[¤7¡4mÛëò¼ÔÉVÖôš¶CGc¢kb€Òû–lúšºç =ÚÔpÁÊ~QqŠÙš½ÛѼًOµèP—%šr{u·8ÿèÚ¼Uã¾!,ÖkÀ‘½%·¶à *·¶ÊoâK·:€§¹SPç›/{[œô±Åyœ¿6À¤M»  Ÿ|­9¥‡Qnñ+L¹v¦X7ZgÜTÙa—¸YÔGJᦿ£¹³Ðƒ §‰šP€¡Or¢<µÜ !¼c†;ŒÃ™¬Äh»|Ÿ[L¯w±·~¸¶·å¨!Æ.%¶•I˜ç&öˆ§^ܪèöaH€½³z„¢(ª‡$¸EE`œÆHÁ90Á¸£§¥Ñµð¬‡|/à+zË]ˆ;ƒ»ÎiÅÙ‹ÊHº¸P£Jœ ”|ñ€ÿ74—-}wªÚw,ݧ »²Â°ö²|é}üWÃèƒí±]Ù-ËVÈ7 ˆÈ“ȉ±3 ¡G]âŰ©Æû¾»«ZCÚš#¤ˆ³¤MФ¥ç`“Ëì ¤Œ¾Ñ‘%‰Tu})ÀÊxê''‚™«1¤¼²€¿•¥D6ズAma=;pA'@“«ªOM-5{ ³/íÓÿ#CT+x@8БzÎâ9.]˜Œ=D×h‹&(Üx‹ô]"ŽbBQ鸎Gü<{ CTsg…؉;eð1¦ ¡D¤Ôé€DJTvÞ3+I…Õå,}â}—}Ó‰ÁÑ‘@}ëãË)ð¬’x0’)0° €;w²rðÈNÅegQÝSô%¡ÑX!HBÖ= xc˜…góÉ//ð!jÙÿ¦ÈbÓÜô àI 4X£„¥4``0M#—¬ÔDi–<‹Íƒ5‰0ÞûË`—«TÞQ'÷aLÈäÞÛC«G†ÂÐä¼·lе¾j£Ãi™zÐM Nª©aïPÄå9áÌS[‰ Òè¦=ô™™{~³¼Ç=)ªOß=§W†€W¶ßë]T˜k … 0Ï\ÏÎÙ7{ô5¨ë×Çݦ3R ‘pk®f&e2„/ N>V5—¬wÁ½PÅ]<-F_>puU ˜} èuI‹Ð®a ̰´LèóÄ`§‡bþ·½¤^ ÿ~Ðãð…~V9÷þöÁ5@žSjið‚ÿí±ñõÓîÍCdF&ò< d̬&ÑIl¹@î èU7ó¨óWf€.|5ÏsàÙö"lY´ã„ÜãËóãѶ)Gg%AèGa7¦jâŽ=zFÀžµ/“6’ä#€ìC€hh›ÃòíªÓââm$ioÛ qËé3-ÁŸŽ;CŸtv}4Ç” ›O¤Ú"J®=WÆ{e½(çöéÊódïïÿÄkœKó"º7)±Mô¾0ô Ü2V¹BU1Â_º¹OØÀOdH»R1M ½å³èµ,ó ¢n\5Î~eÎ|Pð&ò6ù毢 roÛ›oß›ðÕùgŽwÿ ;Ž÷ ˆ¢,£Èš®-Œ\Û…ië-ø?0@ØEŸ¡¨\2›Î'4J HZ¥Ú38 ƒ€Ã Fˆ _8` TEñËŽTúè›a–ÅJÒŽBDÓ G‘CÀ^‹ä$eeÔ×àÎQ@ÃM@AË‚_ŒœŽÂÄ!SêÞÎÐÝf¦ ‚©å.oïŽÂÈæ\‹CAAëDÀJE)Ñ ×H'L_@ðÓCÎHÏ[ÜžÝäÔµ·Hã±Mƒ¡ì’Ö"Qã#eƒ¤ï>ÿe@­-ÕZ¼Ê&"Õ´ZÚuÇ$¶~xh¹–L"ÆŒJ EH‚€£Qèÿµ@ð…_NDÛÒfÂnycùD; |ù&ÂÀ† ÙL0Ê8H|`€ƒ Çƒn*(¨Z®Û6`µZµE«ZXÕaÏ’>j3jH*€ŽW‚5(ª E„]¶Eèêõ舥 Ö.±ºtMUÀ",nÜØ¤ž ¶8àC/ŠFA(n!­ ,UQh¢Y×áèÐ@RQfR È?Zyƒ5øghP, MyÄY|i¯„Ƀ Ê·ù‘ <Ž‘{2> FjX»aˆ‚P\‡!Xw`Lù÷ýDpWÃA<üg4Ï2䂊 R´â,œµPµ*Û%Z0“ ÙÔŽÑýÃׄå#¯B[b€ô  PŒxª¾0ºÄ”«h,àÀ<ÿl@Ìô©^@—_lÍ8 ^}%g“tlúèèÁ00“3è¨SÙ1ÝrÚ"D°œÄˆ#•ÈJê6&I Èôéñht€.‹P0†`@ñPXнRMWB”)Ë›x& ^x0ö ŠàñLTDÄvN#®î§k&¿P¥à7±—N.r» À~õhžpôFª\MIš! /àVBh€Ðà³ÀÑ–KŸ¥“mAM( <Ð R90 Û  Da6üùÏ-Á| L€ÀâŠ;(Ü0 8¸ÜŽ ƒš‚/[U^¸Dî |‚ÿ<À¤. ¸À}:µ„Ä«n¬…—v/N,@HÀé°<@ðãâàéªs£ñÁ×Á¿#±®w¡I˜úá3­)rVðEC˜t/ͧ? PKM¡¥K¨Mh´GT d T%€è$$@Lg܇BKJñ`BŽ¢À£L{¡3ÇST´#[¨+Ž Ç@M=u øSçS”Z´= ˆI@¾@™?À&:™É²Aâèh d½A@ÌÀª"°ÌdvÐWëD Ï•(´ê¬ÂBµK¨¤öšžÄ½çè„áêò;(pïQEpë½G xѯ*ØÎò°³uÃMÍÔh‹ð¢ÿ=5 ³(Daz=¡7’mOt² ÅCeÂt»`]w”€­¸ ‡hÝ·ƒMbª•:Œd{í@õ¤D-]+ɈoÀxب€[Læ²ÄÚþ%[Àë»Ô”/Y3¢(© ‹ô°4ì„ð q|7@&@kh©¢K7–#À“·¸ƒ{BÄ |ªæYhRV¯A f¨Ó `ZX3´L_s¥pT¸ @$dIv+3¹ æ žÉñÿ£rÿvÊ?r ¤Œg"T oƒûo¢´¬‰7¶Íy~š|€T¬wÄ`Ý‘»[wBBÌ¥–ó@[ç<÷ÆÌ+íN+ªˆ úË!B%zÐkçiPÒ»à–uÐd¦  ÁîÇÀÜQ‰zÜEA¢¤…0‹ØåfÂB@Sb¤›çeZn@ ©À$»«œc`?Ç“êò‹ÀÚ1ø Lµ.ˆŒ^Ôi-”&‚‚A¯Z4€¸Ñ ùªïÌ£SåèÂGàJѲ²Éµ‘x#+ñ“ƒ›·í„Ÿcåšñô6 ~–òzô·¢¦€CÇ”h*ÿ6` $icŒ<|2\GP¹ö#Œc$AI³…²p§nôaŠS bÍ|Ób_à0LdB8™ 8a@b·+^D ¼É£ðî%³ÍŸ¨RPjðÅ/V9JÖÇÂõ?ú!@O”@Ñùìî½É;¸Ïm!1*šM—¶¥Ç×Æí¨ ô»ˆåÐ)¶ ¼'>8AlV0yÿ`¦t†thð µ›¢aiÆ—°bHÄ~¦´ÉMx±m ²Å[%?¨ÈŸ¶@HŽÊjhš8ÐŽK2§AüOm=&•Ùy&HtýbZ=ZïudtôDWŸ£ü§h´ÿ¿³ÙBÜÈc=H„ ÃhŒŠ™šRä߆tòHnøüý@‰4‚ÏIUŸ¥ª}šmÉ( ‘iAãÍXâ(¶ h%“ =½‹`”DˆUÀ±K¢ì]¥@ß©J ,˜x (î Ð’JĔɦñ‰šd@Ë8ôõ d`’èI­UX²X*!á Œ #ñÙÞì’`^œDŠR,Ë,@±u¡®…°QJºdLΡî!±L!þ! ¢àø¡ ¢!""&¢"."#6¢#>"$F¢$N"%V¢%^"&f¢&n"'v¢'~"(†b´€ ú‰ò›ÿ"Ÿ8€ÀøÀÐð‡X†Î}])J´Q‚zȬ‰"FÌd@ê)ÅÌLøFÇ|̺´€ÈŒ¬dU@øÎëAËèØÏm`¦¸ÁœÑsÍ@,"›lÃ{Ø Î €ÎìGl_T—×/ ¢*AÖÁê4_í½ÍLÜ ÀßT#iåͪàÀ J0Á€,N–ký×ÈÖR” [<âðá!h€ÔŽ^ˆ‚îðŽïÄäÇõO OòðܾI¡6ZJ»•82Á6õXÏ-È€;îPÁDR$FÁm™}=ˆ5ˆ—N8ÕÆe6Ò*Æ ØKÒÿ#è+!d¸LBjõd!Î#4í¢´$$p¤_¢WÒ_­€e”éŠîš]*–ª$‚•x¨ ì$ˆâeÄ<²Á§Œ>.雎¢Ò:Äh¹‹t&BŽÒg–2Á–~I—*e8zçøü'P­[ÿÜÑõ%ô@Û5*·8i[1R7ÙÜ êgÚë½.hœf‰£ ÜÅJ`hP ‰”Ò¦®‘†NJ~Šá ,*ÀÁÌåÌê{|`’…Ói€fÇvK¾ÆÉžeh¶\ >Ü 6Ä­ÐæŒÿ£)–I›$æµ(@7î%줛®&½:­±â¨œ"ZD¶ˆ³.A7¡á›Læ|-ØÆm}µl³ìDÚÒã0j—PÀÿÁ­Üþ-•Ñ-à.á¶ãÁ.â&®â..ã6®ã>.äF®äN.åV®å^.æf®æn.ç*®ØÆL¡X-²°bO„)d‘ª±µ!-»ºªz Q{,íŒ~Hmo¤d.’,!0¾ÉÅ ÁlL2–Í2:–œã3*ƾôËeèÀVm) 7^ÁÄDÁ€Œ¨\Èp@hÈÐe7±¦’|Jþù)·ØYPirŽA?ZoëÎèáªÅÐÚ`¦”ÂBZ9È>þÿ@ûލnÑ:¥îê AL€ÌýàdÁܰogB×JÌšï¶pDÐÆ¦IöƒJ¬\ dÀ8 ÝRø ŸD+\$¨ÔäíäŽxdÊIRÙÌÈð0Ös>ÀIfê…®,up®«+ø¬Ä$ œAÚͰ½žQ ‰I˜É‹ä¤³\åé~©,à ċl|†;DÀ¼H ¬å/ e¥½pRv&0Zò0®$¬1)¨ƒœ±©²œ°*ÉœnË'YAž:ÁXtÁ·Üh1V:’6– åø è‘ãÞˆÂäû"Y¢J Žìé¸ËZÂÂ+ÆÇtÆ€(ÿÈԈ J 4‚oé1^†œŽ´r]N²õÄtв0 ã…º1˜Sžá%µFo7AfmZ(®±8€0, M3df†s0Ggà€»€¿Â€!h& ìqkí>3½ò²@D(}°8Å ôA´-Ð „ LAhóhfEcK²R”æ<Õ“j¢èŸš3l¿³­üê&l³×ÐEQäl2?ÐõÂ@¹"TAT’R°È©³²PÄ6üA<;?#:œ€(¼“+e/“” ð³"‘xM4/˜0QÙðrÞ-0œêëgCëpÄoŸ.ŽNc/'´:ÿ!tÀ¸’ÔÆÅ±Í"3O5I' -@\ñ< h1åÖÌ´Çdƒß4 Qdí4£—ì±gFûÇ{þ(è&÷ê±p¨£®à€VYÆå4kTh±êª^uHGò²POœX;¥êD)³ARÂè>k§MØt™ÕcÙyù­ زt9¨—Z•Xn™ºÁ®j*Ÿ&‹D6àü*½©ö{=L8ëZ ³¾*#3O ½´2< -ÓÉ@ˆöø³MÕ^Š3‘¾Ö¹½˜'•MÖXÌv‹®±ÜöF£ØÍaÆòwÁ2`5Ñmµµ°ófòTJgž9ÿŒ)¥^LAMA·«#?HTMUÿB\ ^ÆÊÝ^•z0vµx yS4fFŽ©iIX)Ä uÅÌ„¡øU¸q_ /[†o3^n€ ,¼sÀHt¿Úq ƒfÅ\­áåfߦbw ¯-Á^Ï­²À±õZõn÷'hˆj ü¸èvc‡|;¯|[ËŒg.«^ÀM¸ø¼Æç„ˆzæ}{›Gä1»Z2pgÉUê)\*¯±C7A K…{Âxö[Y!p, ¤ÂÝdÕcwIÂIKP—ê*ƒôA¯¹ÂÍôfÊÎʵ5¬`™+xŠ÷,uqø…²ùOåwùQÿR“«HçeyÛn}¶‘àÉ;|‚ã9çy”8ÒE GæëÙÂIpðJ\i%ÿ2¼]bñÄÜ}ïP…ûñô]–qØU+Ië`…¶rÅàykU(^¸"æ&K3µX4´ã»jE¸ck·bGЉa¨ëâHCKîJF¨ÄYlÿbg0xhiøÞtü€Þ¦6%ß7ç¶¿ŽêÂ;,\`œÇº²ägr,¹8G@Ç!øÀj”9úçÂw]«~GýþÀ¶iµ¨Ç„ЮÓí;¿ŸÔ2ˆ¸„¯Èê]‚7Aý= $¼òý/ÃÃú”º¯Rð‹„FŒÈÿÜGN!”¼GÐÿ49zŒ¼×`çtv®™gz¢tüŽAt"-†\rÆ¶× Õ 8Çˉš°ÉÃs*Ùã sO ®=Û§ÍØ†n·3"Út±¢‰ò=Îù!6§(EL þä"=äO~J>å_>æg¾æo>çw¾ç>臾è>é—¾éŸ>ê§~~áßóï„ 麢õв¯.ÂÛ‡æëvc@ÓA†Ô®ˆÅ #Æ(`œøbï 1ïŽ /È ññ’L@ãò¦Œó^ãu§bÝÏÊôVï[P´êFg’oiàHøÊ.aÿ”[ ú^_â;ÏŒ –Ô#ëÿÎ/ÿýÿÀ=â¯>‚@ ŽÁÓ(:‘—¾¯SÂtm‹v®ï|ïÿ@X!€Ù!"ÛÐd5+`ÈY‹ 6(eU·à°xL¦EÀpÞlƒEíˆCrD"p0}e‡=Ndg ‚„†( ‚"j( ƒ"0{.:2ne8ˆ³´³{_`K@ Q 2T9 'µ`pÁ"¸ÊÑÒÓ(Ük"¾A”/Î 52š’(ß×ÔÒNIb2é4—0pw4¤á5š­9^’¥® A ÄÂHÀć”<º@£A @>ƒ@$bÜÈñ…`ÿ,ì e¹q.¾h`Q9¼Ì‰‰Í?(ìi abvcbnò`‡g6þíHÆS€ŽPɘ2¢À‹©$”04P`€†>S, iÀ¢1kcñÔÊ-óòÅØv?4¾àU%_+Nn:Dó…Í~ÕFè)%F‘›q{| ©C/ ¥®À"Cp®ç¥B‹ˆ !C°¥yH&DNœ8"Tž²X6¡.¬?£°\c¡mÝÀƒÄÐÀÀ‰a¹y8¹9)Ê)ŽZPÅQˆ" H@ lÂ)¿Øƒ¡‚ Y s@öíÝ{¬Hvµ VK5|¼ ð9taƒoÿ¨ÑÀGðÐàTdô°e€A4 À„V¨@r9HCúç! ñÒrˆõ0 õd1Ö"{ÀIuÈð%ÇŒPÁŠ·›6††;%Ð[7êàD‚:œÑ—?-ä·Ù}Ø„QðXÃ.¾0 Gñ·Öo5p(ÓXR%Ëtø‚oÞIé¡DN­Ö%ƒ6|ÀrEMQ 2Ü@`ÞÔXŠeDŽ" Ö[¬Æ7D„ƒ@¡t*  }6èI'fg=†SnzH%ˆVÒ0Ätb̓ {~Ù& ùD¡f>o¡æê* Åœ@ØÙ@¾LÕM' €“ŒÎ¨º,ÿZ zS +LP£M|"F³E½pi u›C—Ú$Õdfž†¥®s!ô*Š¥¶†éÇÐp^•©ù)¦ô‡+»¿€+‰@œÊ)PÒ 0#¯Îþ m‰ì!” †£[8ìWÄ/|4AÑű°¹ÙÀÔ ìÙ¨ zÙšL]ÒÀÁµ½K šÁýë2ÀN=lðËÅCJ·R\ŒËMto´¿é˜Bt°‚cf‹¯MÃpű_À({ÌËdÊâè×Ôº?s³Àñ¾0Ú]&'Øù‚IÃGKF( ü xà$÷àsÛºÂÀ]\hÈ ËÕÊ"®ÆB M%ÒC©zÿÚÞªaå0L¥ÁØšô§*«Í™ÌˆstË—=1ï‘òÔ›ó²ƒA«™ÁšïPK|€ÁGÄE„˜¼ÀT¡Ó£ëqnkZ˜àJ,}u‚½ÛùÎÂ¢Õ p}ïÂÍ•C­Ò`Ø«Rÿ:AÞ™ûPà ¡r†4¬¡ˆ™ÁÉü „ƒq¸ ·l jRÇÀV Æ24ÿ  € b °kíA…SŽöÀÐ¥+VIô²ˆ…&45^¤a޹‘ЄLB¡ÔQðSlb4^—7­”À@z`E²Ö‰ ‘kB=jp(ôÈ Õ ˆ‚œK=jôae‰|š‚ v 8÷Œ`HBä,6‚aŒñ”ÎÉp…‹µò»cA«ºd¦“ÅL”ú™IZÀŒH¦jPš àb¸lr˜˜?¾à TaüdålNA›Ùa1 ‚ hâ V¹ `8@Q€<. Y  À»*Ó•€EjTë@40€ ès cÏ=á3‘\’`—Ì;¨´P ÿég4`Ö,3•k \y'X¬g(?På¢ÎgG¼ÉmîÁš©LsИ 3¬›)ðÆÂΦìê5uJT™‰™=mJ³”‚!£EEZ†Š UWÎjT·*ÈÈÉA£]Và pu§ ÃQ Ó¶\õ¬p«\Q@̹~¨H¥±O»úõ¯€TKØÂö°ˆeY]ËØÆ:ö±¬d'KÙÊZö²˜Í¬f7ËÙÎzö³  ­hGKÚÒšö´¨M­jWËÚÖºöµ°­lSàUòe2¬ªƒRN‡(xB@‹¦U x ,ð7­ãÝr¶œçLÿçÆ=hà˜'ÆÔ< íkŽ”Ì¤î øî&pÐÚ :㢠H`ÀÀŸÀ*ÐMœ DLÍ- +@<›ÚTK} €_ è#ðüR ‡aÆ=øj@åÖÀÍUUY\ñêŠl¶ì䮯‚ÿl T¨b…©K’,@^hVE‰¤¸²­D‰7î\Ða¤xÔÃOTÓG¢Vò¬"¯JÀO¥´ú*ʨ$ûx±2d-D@h@…a‡aF5ƒP1"€Kõ©_`j¼ p2"! þÅ’$(N–Ï2/ &†ü!=ñQ‚ ”üÉ'<›“†¹î!.ÒMäÚâ[òl" @ÛIÀÞ©×À¸(O94Rîa.5Œ@ÂýÔàØ@Îß•\xŠc¬Aÿƒ±øBqßšÚµe‡R‹ù*çœJÖßõ»Ï#Mq¢^\J>ãJ0²0.žŒ‡'@%ˆÀ¡ñ€Ëz¹khnrP\ŒìVe÷@É!w¶³+hÄ1NŒ¤mƒ Àq˜°tT0bLÅÇ'À"œ¿Ótú€<æAÂÕú÷hGñáÁ–2£¬@:mTßã[÷õ-èqŽ2<ë(våå5#ßá¾Ýg*Ý;è0ÞAlÜìÒËÆs†ïã<À°n[ˆ@Gmg†Ú¡×€h>Tàÿé¼¢âF†=ƒAFBAµ©gõœaÞ ÛzÚÄìƒÁÿŽó#Ù·Å›g@½±t? -ðN PauP}ç†|: |Z&oÞ°eÆG6GqèVæ}?'#€ %U0$@$KRJ–÷PŇ#êW@+Ø~¶âFYT I—šr:úgdg¦.÷BcQ€=0€-8C¨Àwq!p¢v 9ž–É×€îe\ÐÐÅ…k0à Ñ$° –\Ñ<Ñ+¿Rd…ðNc˜,ˆ(£PEÔ@p5d-·8öܾ|D‘FG„ÎVBü×þWL]b&Ëa†eÐaˆ¢†›¨žÆÿèr`v¾“Tô@Sè‡xbR=>’¬A æ 8 GŠ1$UNg¬„1žHSGÈ‚´ñ”Tanãb2*T„Ï&iZp‰ÅÄÞT‹Ó`ÔX Pb<0ŠRá^¨ɵ|[Fׇw?`Îèl5DˆWBöÁ6&pîUŒÎñp;@ˆSS5,†~6ˆ>Ð5ô&_[¤bÒˆ:€:iƒZ\¦S4Bµ88‚ð‘ ˆ»!‘êf•Èɸ§È©ˆíØ·-¯e¾0A·ƒbP}áU'u¶sy(¿9²9£“& #”p¥Óÿi„YuI(@ïà( ?TÁ„•¡ ð¨ (1káiõXë¨eÀŠ®(  §>“oo¨+Г̃3Í’9¤`oÇ3=´é·’g¸Œ@À=óGß>÷çSyûAT”P—<à„#à•6 >Rg@cP@UÑ’_ÈŽR65e8 ÜS¶6?Ôä”C#Y;îF„æ‰+±˜Y„KÅØA€Ù(J"45&ùoÕð†·˜UùÚ(Hê œÌÙ˜$=÷œÑ@š†Ña\¶šk) àq3UDU`f±‡E¶ @hðKº8‘•·Pÿ™Ç&ZÀE^Fb`F(‚FS7]àƒp´@!ƒÃAv¡¹·ÂGtT‘‘©S1‰L6¡xtI×(G’Ph9–ªè áâI eg'8$PçI1ölT¡ï¢8í62JЬÅÈKï4„Y˜qéµTc²a™U+úõKTLÐf{³‡8µ7¼DÕN7)“øô¨ w²O¨@> ö[vr~g¢=°¦pT,ó•¿TdTƒyp p›XJ °Ú±íõýôO¿Y5`§‡š”IºW÷ô NZEµ"Qµ²kÑW9m•§[:ÕöRÿ¨&¥X à ²–r}ç`#§a$PƒÒÀ€”9[º¢™tdFT á`q`Ðaø—X°eZ©«zv ¦¦Úg+Щ–x¥3œ.“Ub0‹Ë*Wi·›Ìê&µV$@­=`­Au`P7§ráVjµÂjX"Ø­áZ¯VS½5Òe¯üÚ¯v5þ°;°7ð©{°›° »° Û°û°±;±[±{±›±»±Û±û± ²"«Œ#p¬p~ªø”z°%\­zšô¢yg°¯E50rð´©Š£ûã?_gb„pG&ëäõ§•^ï^8_q ¯ÿôe v @WÃHK•M•²ŸAßõƒºá“#­³vTfŽd€a‡‡&³k*bJã³…EcåÃ`&æ°Ua„µò£rÁ«> ™,Ð7RJÈCA–,&s»x•È  p‚ d+a)–'çj«V|‡eY·]¯(€’‰Õ¨ vø´x{,)€ú ›¶B·sD»ìâ~aÐhæÐ+à˜à_×à ‰6 œ–r÷h^ÆukC³1E»ì¢n[jÓ‘b`j±·W©¶o¬ön ñj:0–GU`7#cQ¬1—_†µ6œÿÁ"¶ ilvPÊæy¬ñ˜%d®<€®êp3àj¾  x}nâVäöi;K«ª¦KàHð–˜ )š%fKJÍÈa@e—‘Â@!Fé^ Å_J‘j}¡ÚábúòzTéµÀq,Ü„k@ôº*  'r@Pƒ—nŠr¯ºr)ÇŽO1«@s¶7:·œ ¨B>GYsÆ9ù¨Âàz$$I‹u³À ©¿ýG‡’Á}Y'qç3½"ÄÍš_TŽ ø1Úxi}púШÍU¦–u§pÛ\°e}×oxQÌ%:YBEa²ö›|›I”ÿÄèy GŠ¢— ìQzïÁ}µzgÑz-¹¾Š„{¼ÂŸ’¸gIÙRPP÷[9Ð{‡ §Á7|‡ìšÁokš,z.š«GY\°¸6p}'XB÷ĊƪäA6XÊëwÆePÄ™1#)V›Êø”öW ’8q8å!Úª;y ÇË3 º¬Ã2û€>&$']è’‘ÂçÀ2‚|0‚6P‚“‰á[z˜»:p$,17cI\˜ãÛ=()HY–-¦‘®'¡dÀë‹ÀÔ ÆòÌ<ô¼­«FòÅ®†C…tKXh M:7'Ц9†©™-iÈ{Éu½……bÿלg€±›QlÜTpä,ÂbAH;l$Û<ËîìBþÁDÑš¿Êð­·Aa¨òÓ¡ƒ¢6ð’a¸Š^Ý–‹S(jU—;Ê«¼…$Ñ MÇ>ÀÆ=z ƒPrl"ñûŒuý Þ×ÁÞéœe­[‚Elý9 u»O¡ʼ7‘œ‘)`Íb`Ò“0¦‘5,vL”Щ¡l”°Ñ<ÀÆÄáàMO­Ñ>&_SÜ06&i.IUËVJ½± Ÿ„)! ù79›d@ é ª«í[§³ì¨Ú(ÀÚÃV“ŸÛ!d,Œ.‰Øé‡ºLw9‚)0oÔ­ÿ[}Ÿ3”B9:_©oÕèÌ-{ÎMNŸÝ„ó\ÏA ²ö݈ŠÍ–™ëžvÃ%2r:žWÙ^éJ܉­¸|Þ,œžʳ/Þs ŒIØíœÇfÝ2Pâ‘àú8oÿ“áXÑÔÐ¥™DM–ÒðÀQX} \°™@:0à:Õ:°/íŽ" +õؚͪ=ºýÞ„Ö˜ò5y`x|Ò@¬Wp–j!Ã@MÛ òá2]ž éùqÅEd!=’§2Ö26!Q}3žºÇà x5 ÖQ œ°j pšßúmÍ¿Š{utHsz„b€š¡ÿ?¬ÇþÁÇŸÁj ¿{42ä4|eÔ=¾¢àÌ'×¹k«×ŽE£,0oð‰§AY›¿zB«Än§ÄJ®Ç2nKŠJrS+L¬ì™êŒ›ª¡ï\ê¸|êfbD*PÚ:üp·Š¡•ÞvJò:Ø¿ØyÎoþ2:ð‰{J?f&ìMyD–”¯xOU= 69eo¢ÿίÃËÿkv ó¬ ‚C05€º²í ƒ£"D «qc PÇr¯Øìgù’Ê%³é0‘g3HXF†Ãë0FŽËMhH"æFiEG"`i:jà7-¼:xL´¨H¨NRVòQ08BJ*NY†ŠŽ’–š†:¤°äÖ-°øÝ©P\´LÄ®ÀʚО ·D%¢1…µ ˜@¬4¸®´ø<¯qàé‘ú•rxD+D@486@DTÇ—"Dx¤¯Cx¼3GËÿ (Ô ^€nøÃvmW‹'X lA¦K!™T(¸ÿDXp‘R1QP,$!Àƒ&;ŒdQ'“<{þ!e!À#S.ò„ÿ.÷ÅÃF,¶„M¥ÜPÊNí‰bmbɲ€ °…|(‹_9óSfPÀ€*Ç_çYî0BsQÒ€ jÈ„„lˆ?É‚ ÆLÒd7\p…ˆ±àÐv,yä9NòF­ ]¡`vŒ7˜psKD1g.XÑÁ *±ài ’RK¦çŒ Q À@ 5À˜|Ì–ƒ_1ÒmL ±ÔŠ_)aœfHèÁ™Nàé€#}µBArÚ)v/qG‰“7$ màò O6yd©[:a%ñeYÆ)ùU"§ ô„ 0¹„C LªÂLÚÜ4 œ£”9Ïÿ…g††A ›4`ËN(¥ŠRÕÌ« õdÊ¢[’ÕÓ ³…JH«É# yíÏzZ¯½!à %ô p °b½DÁ¿5 X–ÿù °Àx»„¬´® Ë‹ßC–È9'‚ 5ê1™7¤ë›B™¦lN§Í—1x!|šš+oJ­­ Ýf‰ÁÊ} â’kO^äLÏ&)³Ì÷Bµ% XÑI!'Ñ„eY÷wä ÔqÑI{)@™ÐTLŒ¥u€I@ÉI +þÀÐR¶L`3$À4QÇÙ&+ʲ£„'Y¦T( Ôb.,]Él玻³Õ0 ”w’ÿÿÐâXÔ!ˆ´%ÿª¸Ô§£^H'}VÉK¶a·Lp&Ú Àë-´‘A•09¦ö3` KA\n|™h,ì”j 0\àr¾ 31² ®< 'Ün‰W²'ó6 8K®Ê8)$JW¬-9ã _#úeâ éø©ãŸ¿,6<±64¶JEKØuå‚aýn$ÚÑ[¯\Ö\íky+pˆó& H Ñé›®‡“yD$‰¢Ÿ0Èž0r ˜ÐÑ8G´$¥5_<0ê/‡PÛޞ°ÈxáMhƒe~;!¢éŠ%Æ*’HA”ñGìZ°“,>U£ÂÉÿÇÁ#n¹ò€ò¸ò©`>øPfhð®eÉs,ˆáÑWŠ Q‡zLª¨ì ./Zêð4 ‘|†!'q¿¡‡P˜òÄ8 [€Ï†ÔÀyeøo!pôâSÓºP ‡sñ0! gã¹ðîí+š i8Œªrº’ °¨€_sK‚À(  ?g%OÀ,°†€1¨@2Yˆ^ÆFa‚GÀ0F[ ”#k#%^Â+˜iLt0ÛùŒ“<íüe ðËé™…ž( \(Àh‰o˜ë23')Xé¾óÍËHò¡Êqt ™ÅÿÂ]b´Saòš’à¤b2…£(ix¼Ö¿„L’i âØf8á½$” a%GñÃŽGiP !RÉ ?”›Tæ ñ„â6úÇS¨ îF³Îm²Æ€ D«_Îp‘‰Æ¯¢&ñÀR3jÖêl”£VSÁGµ€ÿ|.`.ð‘üÉ1o5AäZ‰ð$L Ø@ÔáÈ" ¨ŸŽ(&;å¨c*Ò þ´‰‘ágsüY‰t€$OaPóMn˜€T#@˜ª®`™íW\aœÖ G¬úINiÏêÛß× Ž .'E&8”Â!kJ\ÿ5w¹Ï.u[¦H€¥E@$  rÊ&{S³BYŸ°.IU/çõczÛë^Ô1±£ÀÕÎ î^Q`ab¯ ÐÌ÷ÖÅ¿¹0 làߢÆvM€ÛìàC8Âއg'lá c8Ã>ˆx7ìáƒ8Ä"1‰Klâ£8Å*^1‹[ìâÃ8Æ2ž1klãã8Ç:Þ1{ìã9ÈB2‘‹lä##9ÉJ^2“›ìä'C9ÊRž2•«lå+c9ËZÞ2—»ìå/ƒ9Ìb3™Ëlæ3£9Íj^3›Ûìæ7Ã9Îrž3ëlç;ã9ÏzÞ3Ÿûìç?:Ђ4¡ mèC#:ÿÑŠ^4£íèGC:Ò’ž4¥+méKc:ÓšÞ4§;âÌzÍÓ¢^²d¤šÙQ£úÈ >Rª[=d‘ššÕ®žµW-ZãšÄh௠bYäæ:ØÞµã¼æë[ ;Ù&6%l]aeC›À€4Á.@€¼:ÁÙŽ6·Ý Î x昅Ðv·ËýÞ<‹Ø(¯ŽtìX›;ÞÕµE˜= rË;ßÁaì=îUKUß÷mýÍa[<á5€ "à^·ß Ÿ¸°Ñ<@·.¸Á±9Jñç*¶Œº3gƒ<åùCƒ¢²Él£\å2—± ¨˜Ï<çõR·anÎñSë<è>w‚±›åóX¿[èJ·N{Ð#|‚Ä—nõ”s'hxoÏ…ó«ƒýÐ €]o“Ÿáa_{@ îóU³=îòp;~j¹ãýt§ú×óîwï¡"ßöß /_ËÚðŠHÕïx Ûý§Ÿ<äÕNyLJ!ùV, z ÿ„© á!›´Ú‹³Þ¼û†âH–扦êʶ\ ’K×öçúÎ÷þÁ† ñˆL*—̦ó™‰È†ÐªõŠÍj·ÜqêtÇä²ùŒNO‡SËçôºýŽb»;`x(8H8¦÷æ÷P¸ÈØèøÈ2 Ù&¹• ¹ÉÙ鹩Ú¶Ó§ø‰šªºJz(IŠùÇJ[k{Ûó:Ú!;‹û ,ì¡k‹9œ¬¼¬\ŒˆÌ-=ý9iíaJD½ÍÝ-8ù{,ám~Ž^V !ŽÑ›/ïäºë.;Ÿ¯¿¯ã|IÆ¿ –ÐeÏÂ;ƒ :T`Éß=h+ZäW €+ÿÆâ»2d:6”Ú8hw!‘,[N«d-£€q\Ú¼Ù,áÌ8{ú¬uˆW©š?‹íôÏ£L›B¹“¢Ó©TS-¬Š5ë£*Oiý 6P×raËš•“hJÕŽgÛº} 7®Ü¹tëÚ½‹7¯Þ½|ûúý 8°àÁ„ >Œ8±âÅŒ;~ 9²äÉ”+[¾Œ9³æÍœ;{þ :´èѤK›>:µêÕ¬[»~ ;¶ìÙ´kÛ¾;·îݼ{ûþ <¸ðáÄ‹?Ž<¹òåÌ›;=ºôéÔ«[¿Ž=»öíÜ»{ÿ>¼øñäË›?>½úõìÛ»?¾üùôëÛ¿?¿þýüûûÿÿ`€H`ˆ`‚ .È`ƒ>a„NHa…^ˆa†nÈa‡~bˆ"ŽHb‰&žˆbŠ*®Èb‹.¾cŒ2ÎHc6ÞˆcŽ:îÈc>þdBId‘F‰d’J.Éd“N> e”RNIe•V^‰e–ZnÉe—^~ f˜bŽIf™fž‰fšj®Éf›n¾ gœrÎIgvÞ‰gžzîÉgŸ~þ h ‚Jh¡†Šh¢Š.Êh£Ž> i¤’NJi¥–^Ši¦šnÊi§ž~ j¨¢ŽJj©¦žŠjªª®Êj«®¾ k¬²ÎJk­¶ÞŠk®ºîÊk¯¾þ l°ÂKl±Æ‹l²Êÿ.Ël³Î> m´ÒNKmµÖ^‹m¶ÚnËm·Þ~ n¸âŽKn¹æž‹nºê®Ën»î¾ o¼òÎKo½öÞ‹o¾úîËo¿þþ pÀLpÁŒp /ÌpÃ? qÄOLqÅ_ŒqÆoÌqÇ rÈ"LrÉ&ŸŒrÊ*¯ÌrË.¿ sÌ2ÏLsÍ6ߌsÎ:ïÌsÏ>ÿ tÐBMtÑFtÒJ/ÍtÓN? uÔROMuÕV_uÖZoÍu×^ vØbMvÙfŸvÚj¯ÍvÛn¿ wÜrÏMwÝvßwÞzïÍwß~ÿ xà‚NxᆎxâŠ/ÎxãŽ?yä’ONyå–ñ_ŽyæšoÎyçžzè¢Nz馟ŽzꪯÎz뮿{ì²ÏN{í¶ßŽ{îºïÎ{ï¾ÿ|ðÂO|ñÆ|òÊ/Ï|óÎ?}ôÒOO}õÖ_}öÚoÏ}÷Þ~øâO~ùæŸ~úê¯Ï~ûî¿üòÏOýößþúïÏÿþÿÀ p€, ˆÀ*p l ÁJp‚¬ /ˆÁ jpƒì ?Šp„$,¡ OˆÂªp…,l¡ _ÃÊp†4¬¡ oˆÃêp‡<ì¡Ä qˆD,¢ˆÄ$*q‰Ld_!ù,)  © Ž$œhhéŽjœ¾/ÊÊ-]â²¾ó*Ÿ 8Šd7[Àx$æŒÎ§©b•…Ä A`4££†¥AÑÓˆ8"Ææœ^§3©WE:u"„@I"eŠ8Iv 4…‡‰—i"‚’=wy.}"lnpt¨ (”¥N7WY ^h1¢jL˜PTAĸvÆ`ÉÍÆÂ1LÀ<ŒÎN!!ù ,7  › Ždœhš–,©¾h+èË,ýâ¹nŸ¢IJÒ üj;E’fŠº©xö¢Ài€xÅ–¨V6;CÇßꩤ¹b´6ìÒô›ö^ŸŽRe[~:x„|Zpur‚‡{% I#  =€Fžd#' "vw,(¨vŸ2Ô8µÐÚM×¶Ù3?kT­åxEµ!!ù ,œ  Ø Ždœhš–,™ ‚ж´lt{«BÎò7Ÿi·ŽˆE#9S.™8g †$9"ƒFA DÐ(`q ‚,‹QO"ÆéÐs6ST¬1_O;T ' %g‚av' %kƒUp%jŒ(o2rb#™z›6Ž‘“P=‡‰$‹£D|$Ÿš'œ*qyvxªP#ex¢”³#WY[j²;>’`»¥4 g¨ÉÒ" u}¶Ñ¤M'Üݺ¼"f âç/—JI6I!ù,«  W„Ë,’<°¶9­ÆÒiÆ%_*ãU'šZ¥À ÊÚË–ô#ÏtÜúõ¸Ïp„;Ò”+&¤Ô m° uymfOÎÔ ÝHÛQ×Xv…9DmûV×â§!ù ,¹  ¯ Ždœhš–,©¾h+èË,ýâ¹nŸ"N€ÀƒýV!8ê‚BQ‡TN©ÀdôŠ…“AbÑaoJ‚ŠbN9kP1 Àœ¢sV˜yzP % ƒ'oU%‹Œ4^‘“•T˜$’”zPRžš¡„C™ TG¤­›OZK#Ÿƒo6°Z¥·§¢¿³—<.©ÇÅ0ÊmXͳ£ÑÁÕÉÊ5œ×n0!!ù,È  ¹ Ž$œhŠ A鎫*¿¯lŸ´+³v^Þ=,Å ÀÙ™L-™Àⓘ$YƒAdÑ6qE$Àœ&Ñ%z6‘ÁMP¯[ŽÀEAB˜Ó7El .PI, ’’†w-M—M< 'q9'‚7>˜„©;=y }vkm ]]ªac'¦(ÀT¤#  i‹MS1È`GÁØwÔ¶KJÚÝáQ×Bdk!!ù5,Ö e ÿ Ždižhª®l¼Â+ÏAkßxÎÒ|ëÀ ÐÕã H]јl:QË™€Å( íÉ…Fe…$#I°'N&óxuߤ/˜D ,VÕn–êh)y{|}†ntgxˆ„\41=Š*ƒ*G   9rŒ"uw”¨&Z//@b2±/8§z#€‹½&/ TAÆ º7RK’«‚­$È$±¥9 ¹% ÆÕ§’(•&yÔ#:ZH¼ëÀ(äÁ" <ÐŒ]}‰²µÛ&bØ’é0ã ŸºDß10, sP´(¿þL°˜£ IZiQx"ºðJÌó–£C /aD"ÀŠåNtûîD FQ&%q³ÅH% ¼—BB€UG `ÁdÊNÀJÁÌ4âY½Hb^³ he•·‰WÍ^$§Y [²d^qh(Õf^èÍúahÂ0¹ÄZKÌŒâj¦ãF¨çÆ,’ºõº®c{†-»6ÂÚ¸—¬ÆÍû6ïØÖXÿ–Í+!ù, /@ÿ„©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçº8ôþ ‡Ä¢ñˆL*—̦ó J‘’©õŠÍj·Ü®÷WýŠÇä²ù¬ £×ì¶û}UÃçôº-¿ë÷ü¾2ï(8XHxˆ˜èe¨Øèø¸Ä9II)Y‰™Ix©ÙéiÇù):ŠAzŠÊšÊÚµê+{;k{ÛS‹»ëªËû{ê <ì)L|\iŒ¼ì¨Ìü|è =í·c}­½ÍÝíý .ÎPn~~>®¾Î¾€n.€Þ>Oþ~P¯¿}Ï/ ÀøÞ <ˆEAy :Qî_Á‡+jðw/žÅƒ#,L×1¤Èè$2‰rãGs)[V\YῨÿͼ9f>œ<õéì t^I€A‹ŽÃHÔ¨Roð.}J&Ô©ýV  ŠUÒ{Y»Úøé5l °bË*ÄgÒ¬Zd׺±ÕàÛ¹!ÚÒ½{±æN¼|14Ø7p»‚ 7È(×°b„;.!ù`, ,+ å Ždiž@ ®,‹¾°ØªÂßæ¬x/ï-_¸ª™„T$“ËQ¨z*£)juä( ƒ ¡²$Ny" 8LÀe-ÚH JÄ"nF«xXYg:"PXrhŒWQ:†[_Q˜;# g–r$ j+ BO_{>3 hªPt±©%‚*°CTF #‚ p¸Á”ÀZ"* ×oË>º6_ ÆÐ4@Vƒ²Âž|TôŽÁ%ïõ-Μôˆ!‚(ì!,a.ÈÂB!ù ,), ¢ÈIi¸8ëʧÖBÖu_yÜšZ±YèZ°8Kµ}›«>=Œìȵƒ€¢¸(ŠÆ€d XNšgTŠT2Pl꽂·d««¦¿Ù0pÓUØòÚÛ¯õögA&   ƒF 9 Š I}9C ˆ•1xhD…„%Dy%+¶±;nDBz¾½¼ŽÁ<!ù,7, ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù ,F,  Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒV‹C$\ˆ,’'X…# ›‰$ ' qS2.'ceƒ=€@Aª¢¹rµ8´¹q–¸¼rÁ³;{ǽ!!ùq,T,W ÿ Ždižhª®fà¾pÌÎtm‹qß|Ïë‚WÐå+SºäqÉLê˜Ð¢3­ÞCgÐÊMeÝ0ê»›IÂ\6@’*€JdF†Å#A/8R &„ ˆ6d/m1 #.„/' /œ$¡.‘l#n ˜"«"š$. "$w§¬i1C“£6ÂÒ# š&Ž "š¼^­“7 $å'±¸“p4kS$±žT8 FXQ0B J(˜E+W"b}KkœC Æ‘  ’)WɱöêM ô0 r„%“'¸pfäâ¤d(–‘’WS… ë©æÉˆXûN”IâèÁó꩸ÄgK 'B‚p®(€nRžÅºÓD:uIÖüL‘034 (3m8Æ.Kàà‘ Zixá&ªÛ‚ô46+"á&M”H(éB {*û)iéØ-> 0  yµD >XÝ ÂÄq¼µ¸îŒïžÅL‘Ü 5'Å÷NÞ8ó*0D—ynK$ê\Vº!ù ,œ, à Ždœè)¤Aé’lŒ¾´,Ó¯ã®Îò&ß 8‰Ö*µDŠŒ'g2¶L˜Hbp¡`•Ȁ P•"t,q DÅé¬êx…Àá¹ÆÉ1|6U# ,B"'ŠSF"_#‹L? '#–P-' % ‹v?®§+¡—Œtfª¢wg[Âr«£7cf …³¾‚-NÜVÞ}H¬RµJÝãâDäá2våP!!ù ,«, q Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo ‰EÙJ×*Ž<§m‰ BWÎ'´™ÜfOÔÝ÷GCÍG4+̵z¥ÌÉQ(0|ïÑáÄÁŸI{}B# |~q:jŠ'Œbp…nCXpl2r]SU=[!!ù,¹,H ÿ ŽdižhªŽAë¾ï*Ï4ú p‹×|¯æÀ€oHq±¢’t!—ÐUMˆâ4Y5 †"rÛ=}ÃÄé¸ìk·-’$(è‘!0(9#SY5pq"-.r|% €#-– <7M"-ž |…{}$’my>‡B“$ z®¸% nic¡º%°«¾#¯fÃC9Å. -²’ "¬‘ÒÛŸ‡ -ªà-žÎ­ÐÀ$Œæ†è£ìÎïá$š‘8óf‹lÚÄykOÄ r±ÞX³&B—eÀò}±`ÞˆzÉØò¨ ˆljœ&pÄ…ŽÒ ¯T:TØe/-E z°q–Dñi¤ÐE‚AAù ˆ°aÃ>)3ÁѱCÀƒv( ˆ‚„/ëÎÁaÆÛ2Mнíb-ÈÜ*nïBÉ«W‰“)}—ð L­ZŽ!ù, ,õ`ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨gJ­Z¯Ø¬vËíz¿à°xL.›]æ´zÍn»ßð+:N¯Ûïxü<Ïïûÿ~{€ƒ„…†^‚‡Š‹Œ|‰‘’e“–—˜T•™œŠ›ž¡¢Ž-£¦§y ¨«¬cª­°±Y¯²µ²´¶¹«¸º½¢¼¾Á™ÀÂÅ’ÄÆÉ‹ÈÊÍ„ÌÎÑ}ÐÒÕvÔÖÙoQÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûü6@1!` úþø‚B€ýL(4± À… $<   "R!@‚%OÿöȘc†.<~‰ØS`Téyg’) Fš ƒ0×À'qð’zð&˜Š!ÿ‹l®àSƾ'‚ ¤â#UVqûÂ¥" ;‚f4’pl –!0‘&ÊdÝ´Õpm”Ô²`‰ÝÖ*Bªi¬«oHôª¿Áb × F™Ði ™ê© PwÀ½±Êâ°æ˜p @«šÖ“+€]wÙ žýªãªj2WBnÆP‘{ÖEAOœÅÇ—{|&Üï 17V 8{Ûϸõ­[•yNž@݉* •m =†¦p kÞ €f/yª¡ŸµÀÑ*\GYJ¸å ”LÔªÚ‡@O0´_—p€E^Þ,œ§'h`OE·ð”’˜z§×&VxáYl§0ø…P¢”ñ7·ÿÚbÛƒ÷_e#ÙsäN‚ž™¤! ƒ3—@*°\ëT· @í>…ìÛÜÚ9Ö”9 ¬~û%ÝÜ ¼®³œ:> \Xйjtr€„ÓE6 „’Ö¡I\i‡çÂjæë¸I¶ÁÍY‘ð€L ÈÀ:ðŒ 'HÁ Zð‚G¯z•ÁÒ W“Gƒ Š„(\AB¸A¦ð…(0!Œ`HCùÉ0 5Ìá q˜CÞÐ…=„á³DþˆEÌà w˜Ä‘>Má£HB.qƒT”â³hÄ„‹œ"1(ÆK1Z°Œf¤  ­˜Æ3‚ÉŠlÕÍè•`á °ÅŠhÀ}'”’]-z(V 3õ5‘|`ð¨B+:š`‹7—±1€'XÃù"GD fIå ©|i„' CX)/¸¥q/èÂÄÉVœÐðqÁ‡)”r" 1S×íÀÀ0X‚e8i† °µcõ`a…4¤# 4‘šÐh“XéCÂ6„¡Y©$IBÐ!c&Ì(xÍ¢)@¸‚ª$ÔØf3züã*¬lâé¦ õÒi ¬FÒaL(‡¼(hÂØ"ÿk¡ºàµäAzÂ\&Äž ¬ €¦Iz«B£ø© ©¼§Æ©*XÚhBZ¾(˜Õ*ت®#ÜeL¹ºo°Ã¾P SÛÌÇž$X`³ÏZø"km†ãtu´KB+ܦ d®+’ Á²CúµëDÚfq²}9žðd ‡ˆlÆL®¼HpJëei‰eÃ(haÉ,,!hç1½X”B@t‚»6Ì2Õ(€¼0Ll‚e¦ ¨¨üdò@µL˜$ Ž@ò£æ‰ uÕ#5îu¼‡î3ŸÀä ÏŽp4šõ £Ó@·êm£ )XŠÎµz<°¡%Ø‚R¥ùZÂ8ÕÂZM‚Öï9 ÿ‚]=ÂLaÓí,Ù™ 7³Å} ¯Ð÷ˆª° ’-«‡S|ó©›ÂZ òú®àŽf¶YgÙ;–®Bµ¦‚‡ô÷‚Ò(üÜâ˜GaÕté9 Ž4t­,${¨äº•1W“9 rÁX?¶´#×l»ðµ‰ÍË$Z|öæ…•‹ij™¨¶92ü§^ˆƒžº€e´ä¹{'Оóž€Dh£ßø$5 @#%”ÄJ0xm ˜£Õ´T«X” Þ¶¿c«ârxʘï€#`—'®°1³FESx,Ì_Aºžä–»‚Q΋ËÜgF#Âÿö‹ Ô*Å8+ÕT4$ÁLH·W¼BÚ·s‚I• {½s™Ø…Û•àS€[`N(²^t`r]Z„ÁrìfW³Òb„²‡8¨4K2bÌ×%Ñ7Âu#H’ú’È4N•`-?:¡Œ¶|f;8 Žô¨¬c¡©rY¢¼t!QJ4Aà¤ØAÂà‘)ÐJŒÊj©jÛSä6™Á/ …‘qb5WF3ÒrY"å V éÀK—Ñ¥,Mp  m͵»u¬€ ¤Ô€T~‹Æs¥û©Á‘=Ì•+«©µpTÍ" ÒË 0ÁÍ1yÿyà«ÍÊf·H³T´œfL§f‚¶L,.RYYêa’lüÀLYT , eÍÄä “¡Ðm–Á‹^äfœ^0$TÐb!æfuÛie‚ªT "6¡Iªeä¢O3Œ°›Á”Ÿ|ö•¬W-Ä™þ> s?W#òm3d— Û¨µ…>í‚Ý<åå"@vL``9°ísÁG°m¾ ø‹äKdº%ãgËÇmàñ$ÔA?™ÈOúÒ€­‚Bþ`7Tˆ/Õ~Â,çAß;$®ÝM;ͼŠ!É€¡0KÀ¼$˜HÞ%ÅÕµvç÷V<ϧ^©€ÔB7BûbÂÈ+'Œî×ÕP¾Ýs½X ®3¸üY2h@y1 ~0xÿ32;4wÐså €1÷4¨']¼Rt5ÐzH`01 ‡€ ¥´$ b‘GxüPâÁ¿ñf&r}dÃÐò“;q$Ï&ü†o‘³}"`˜Ñ1#xu%>uLlÒsC„A€t3ñ&±p"9îWe°µDˆðWs˜s¸ãe4z6àÀv§h‡IÛ3  …ÓBŽz4`G`€ç ßÁFÆ#ÂWÐ`˜À€+hT0°U8D(r( :˜%=ø'ù„'t*Ð1éW3giÌt…(ð ÃÀ7UuB!¡E\¸?6—yÒÄ(ÿ§ º€ªq ° XŠh“MåÇ@Bd&‡F7ŸÑ u°'Ž 2]‚HïtY?0‚øÅf Å‚kI‹Èƒ#@M£G«˜4¥HGu¿ =+°â~% ž§ ˆú'7üg  ‰Ÿ7(6Eg‹)0¾È'ï¨éaçe&d~KçgôÆÂ(Eï! ïa!k´R?µEwe `‚‚GuÄjÒU¼fÙ’z׈„÷`„.C~Q€tM£…- k±L(PU+ 6dya´6iu4Éu^X¶`‡˜0NX(À”¶ê¨yÿðÆz ¹Åø)o1ˆÑ(ܤ‘Ú…°Æ‚&0Ñzvm%¹ˆ …’#0µfÌ`!ܤ+j¦+pÓ6ëg<§|ä.-p•냄ʒŠ6ÐÄQ‰.Њ1àOnÐ%(“;ˆPÎ'ãà“®2ŒEЕù4ÝP bRLxôVfé P?Ñj¨ðŒžÂ§A‡$à|,€ˆn)z¹oå—ÔIe’Vx¯¤0ðZ³ NŒùNêõ˜»Èi²Èœ—)4@“ÈٙĚñ\Þçjp8ªI¬ù²Ð BsÄJÖX›äCqnU‰3±ˆÇX’HHœÿXkЀÒ’ˆ37ñ˜6½v˜`+÷Ôé êT=Wãœ,P 5é„ÇQIY"T EG2 ªwÀ`½8oN·ð –Ž G]Bˆ¹TqŒrOŠJ‡P<ñD†›Ix¡A:ºÒˆHc' '‡ £ÏÖ§qÍP‡—pŠ0—Ä:d>Šõ ™×BÚ…àIN!Q½ö¢4÷øD4q®¶z¸•Jðž6Ÿxè.zHE:Ž“h£Ú¥-–Q—$2ÂI¥ŒgO\cÈWÚœ€sWÈ‘Nðk›ðnëÙ1t¹Prô‰Œá€+㦚v mTw!2p4yÑ¥ª…ÿÀq‹ ÿ&¦ëù±˜  zN/‘ŒQ ¢ªmÀ»&Pƒa™Ž§¿(§®Ç¢uZm>Ud9£ð‚¾ ?$T:”3L’@¨‰ Iès \'?a ¤–L±‡´‚ƒ=©P‚§YL0e¹‰p”¸˜Štj‰p¡i%Ê #ù™g·¥2€™2`l0á–®0ÿš bwˆ@£X©¬2ÐtQ@§_ù" `{?±ÜQÖz—‰P…-¤ 1˜:q{ ðpÚ#q°µ6¡ pœ"@ˆÛ`w4* e•‚±cÓ J°Ðà^‡©úÊD €ÿ ei‰0ˆm·ejY€›¡€_:™W‹fû„‡ ’Ñf»9 ã±µ0gç… p”󪱩ɬ{"‘®™+X [w#Õº§Å1àd[Æ\ˆ@[0á´œ9ÀÙ|㪠ÄA €áŒ A»”[º£5¼ «‡Ydß¹¶l¬*J»:Àw¨§œ„š³Å´º›°l¡g–i g|–»Ã{k!“‘h†^ªNÖ•Í A½÷AƼ×ËrÍÈÁày²¤Ê$¼Ý{bíy¾&ð¼ Ëuø”mê»cé¿È½ô{¿@År?q°°÷Œ·×¿ÿü‹¿<À\À|ÀœÀ ¼À ÜÀüÀÁ<Á\Á|ÁÄ›½n°½ yÀ¥ð¨¢ÇIÆ›]Ðdrð3 p\°ÙlÁ³-Ô¶ uî µôbfefgp›*V«B*xlG\†`g CÉ»g`y b…vr=ð‡‚'hoÒ¹u´[PY‘fž0g67òT»iÀD ¹‡Ãcžü U¤ö¦Ö3(Á{÷ÚOÜq€{ajžpLlMæ’P <”j –á·) 5[Wƒò@%—TÈŽ|ÂŽ›ƒJËpY9pÑà‚ÛÖmÏ4ªãæ4æ†n nðt„î6lÿoʽ¯UðÇ;i¾ô«ZPy·D½&ƒÄ’yÍ…<%c¡Ö‘W_ °”ÇWФŸ*ä° ¦µ†ªÇʶÇRË'@rIÅNrløL9I©;K/:$œYÚ\„Yˆs0œ;—¶kj»- ‰2+@“k¨tÀ„È00¿Epuv6Äslõ#VðÃ3Pµg›M5Á_Û°· ’^ÉÌWÐw0³€'ÄÌ+äÛ †‡ËA$°x9 ž/Êó™qAɹÙ9Y-›×y6ð¡)ì+ÀÍñV¸ž¸ÛÁTàÅÌ}‰å§ÌÄcX€Êç°Ùw}ÛP}Ä·ˆdŒ‚š®ÿõXz–·L;|×  gÒG+‡`¿qŠè×ÉðÕJ7 Ö1!m›ƒóh%Ð6.ÙóèI6éŠAƒ Að|+ %wr€-0Ð¹ì€øwK(Ñ«ìÓRP‹ƒ‚‚®1ÉAYKõ0Váy¤Æt ™›mÔ\†ç„+½:»¦1^öÁΘ©%0„v}Úë˦I „DÑ„8àS_B”«&éñ$Ö!w}s*=»½;«ú†½­Åkš«î‚@÷ ˜¼¢Ï/ÀÏBPUhƒ6­€d ° Ž9ŽÙx)Ú¾KO*9~»ÉY²|.$ŒhòL3ók bi¿aÓÿ.p‚§ö§a³&ñkÑ™òÒ*ÍÙñú×Ëܰÿ×Ò+7þ˜Óz`Š% ‹*K kyŒ"½§Ò¨-`!-Í(Þ›v)E´üí²/AI*ÀÚ‘s¼¸“²éh†âmåèßà‹°ÖÔîØ%6+0 ” ^àª9°Ñ-À.ËDç¹ùcTb•žÏL§Ý@  7¹ºi¸i,zÀ^” &£mM`}WÍ37r[ý<ñmÍ©äãb¿N ž…™0`·ã“(mªgh$MܧmÜS”|ë¡kK™KN9(Èí“ÕR•lÁ˜= âSà’+x"³ÿ¬öׇ €þG:q:ü¸ßço< šh㉘߃܂©…©˜á x$ËT¸MzÂäé|l“Y™3]é½+Ûß}ÕcžZ9@š`š „Ý. æ?@ê*P8ä› À6ÒoeÞ\‘|‰Þ-n!-~2ÎëAêŒ8Nî(€ )ŽxóÝè2€ê4:âÔ‘˜‚®ýN5é¡Ü9‹”áÑôQKUø|kÑÑ¡ŽÇS@æ,às ›¢÷Q$#-Þ /ß#Ñsº¾Ÿ+àñ+0}½ÍéÝÍ /7¬žv“…Ì cfÎ2£ƒÎ¡ó•Ü7°2F!¢»äÎ~¤ÙþíÿaâG@ðÙÃ6¯—Öí%2·õƒÞmŽå >°Ä…y𨘀ãý'`꽤ФLð¤GßRJ+¿7˜"À ÃjM+ ÌcÃÅ.Ð¥M¤…`:÷µ{eºXgZß±0ZÚ§€ÍŽÜ}l¹bæ?*&ÑêBY¶ &ް¶;^”= i3g_ãz%ñyþ-©MPÈ–Šßt™VЩnzÉ1Q’°F—Äȧ1€ª^±ªÂѪÃ@¹6BéÊÝ×0á¸J&á!ð«Ð&¬Ü1 Œ¬ÈzÇZI2>!ƒÒ-paØe…šw{žÏ}ð×’|ìèÓùÍ_ÿ¤[€%L¹®]°°1` "Ç´„ÇLͯ(°h<®ÓÆ; 82³Ê´°0VÔäÆZ ¤L‘°‚+*j°D©È8ßD¤µ™aÛ úÕļUA mØ5 ,>>"\´ ¬ø ®¡l0¼%,=,P<²ÕŒ–žÊH \llä0¹1Á””^Œ­Ð8•PHHdœ] g±˜qÉÆÅœ ¨•U ÐBnã `\ \`xá@HŤúa±0ˆ<ô¦hDÌs#¸(@1 @"ˆº@ÁÓ6:ÜXx7 †úJ°¢ † gâèK‚(ŠÏxÿ$zÈ‘ʖ2x°äB‡MÌr±(•``D7À4É@¿?ƒ¶ŠÑÂ&Ê’`˜°d½ØXð @•üDèFáë”r&k –DºŒ+w.ݺ@ÚÍËMȃ¸,õ,x°J]PékdNÂŽC~ä#žm‘#ð ©"—/ƒ-zÛVr2úœìöv4ëÖ3¡Hê:î &[~ž­{7d²YœØa[cÞÆ#O~¤QåΟ?´ Oƒ¦¡cÏ®wîíÞ¿ƒ/~¼ãîd ,IÿÆM®[·,­M%=ü<ÂÉãϯ?ÿþþÿ €X "˜ÿ ‚ 2Ø ƒB¡„RX¡…b˜¡†rØ¡‡‚ØlBñW Š©ÄœqµÍUJ<$=.5°@K¤¢Ž‘M–A–AÒ€2µP:Ü€8×}²I–<`ÁŒ+T@äÀe1M…åYs¼Õ6%7 LtÇ s¹À¤¶£›‚áõlñT)[ #Mm\Y‚08ðå×—»!0AqA;84 “Û0§ç›—¾†OKtj`p¬0ð©“`0`À§,A   %ÐÙ%¡ÜöŠ6°„˜,4 äCl`šì`qnƒÍ“brXÿäœÑpp Ä+æí‡¬EPqA\Th ¬ºz1 ÉVÆ’ñ Š<Ô¶Im©õÔÞzÉ X€0,0 T@ÁF-À¤9L »„‰ò[%le© “\¼ˆé®ò\>è$ ÐáÖ}ݦZ×5Zò¾½róëP¾qÖž<üž9àãVDìh!–LPË)ŸÙ’‰µÓjûƒ7jPM·,qØ­'ÇÐè%»ÒÌ ¸H`@š*4Š“0Ð }˜«Ñ8¤7έÙÎñÃ4dàPK8$$?ÄW£ÖjÄdL‚ÁÄäÜÃY{ËRK6£¢ÿd N"Áj¢wÑ%ÿRN+ßµ¶O+^»ÇTsãìjÜ47íÊpM"›‰YàyвAE—λÀ¼8d¬:ߎBdž¿Ñ+PK¥n»øG´»6ÒÇpF×%4pÖô2 k áRLPɰʫÄ<¹„/1&@_ ¤*¼~((ÚI”–¥>è«{K£(°7¾ ò€q{Ažõ¾`àyS°ÄŒÒd‹óu+mÛðb^=Åœ@WTÓ†±„Bc×cˆOC-$(­cG¨D§0hDêà®!¨EÞb ”É€N* pª€vhûÖ¡B' †ì;ÿLóŠ)&A‡2Ø2¼×Ó¡6PL™L¸"Â#Ú®|v¨W  ÐÄ gŽ1€   ¶ð¯f,äH@1~‚„1h È9B¤n=,[ÆÕ<5Ž©)ÕÂ#5È{t€¾°„qДÆ@Š)4”¿øÂv Ó«M%ÃJ°Q“nd6dÖ­?æNS¤4¢íà–yEªiT´D›’¸àÐuÏê–1MÖÅEüë–¾ì’W‚Çe3—f&K°Ém­“¬p‰—yASn£6à]¶Y:´(  ˆ°€Rêq2âƒ\e-^€øà#@N[Ž †ÊTÿÆ €R,¡—,Úa€¼{´R+Ø4\@fÏñ5Óx€ZøÁ%/#9 FÙ9Uöï›vgFq È&ôôŒ˜ðQ†öIÀÁtç0³ Mi‚©çKó˜Äc½£F²i \Ê„¸AY²I&B€jî«›]$)NHR‘H؃RKp¾@ðä) ¥Á³ê÷Èc" *ò²ý) úR;lnH­j{K ‹þÇ ¸Øzù&Ic¾]î€èÊÜçBW7À.u«kÿÝëb7»ÚÝ.w»ëÝï‚7¼â/yËkÞó¢7½êíkûóZB¹ßy¬c(Ö†"¼bRÁÁÆ'‰"¡r~ íC“4¿Åñ Û™ 1L!Y©&G20‚Û±€b@ÉV‡%ÒÖ H€3¡ }7Ü#L«WŒ]kK`ÛKñé Ûð,s'+ä©&\ðWóI'+ÈæÆUÈ1 ~l? Ò‚BY"Õ&[ý0€*.郃aŲ¥½THQÐsPj }Ù 0º™ UТŸx¼¨‡l%øT¨€df4#àTd[ÁªZ*ÄŠæ°®”¹EÈrˆÊGp gÛÛ(ÿjùM“@G\J±²RAc >e_.€Bíà΂"¦£éáìd„'\›ìM)Ú±Ö±…‡hÒs™„rY /×9 Û,ao%‘DàÄÜh,Þ‰_Çq‰¾Œt¾f‰hÖ®Fàø NöQ©$ Œ+x…åx 1Š ªÙ»iZÔ±H¥º{À² @€FGè ”žZ›¶mDÚ+°ßÂSLu—{ëyÐÈã€rÑìUB§§·ïÑPÀ‰îíÀû4eð=Ôß,ê± LJ”ûŒ¿ü Ôÿàþ4Ÿ¯È`°Á”LB:qP€=Z ,ÁIÔÆu_m]àÕÔ”S²ø\Kp¸ÅL‰,”_% jaÁ-¼UaDÝ"€A*QÔÞ‘£i@ áXûÂø-B æºÈ€³­D¤uKÛñPU¡^•-!ÁéœÁÙ\JùqC̸ž’0‰[d’Áûm„D.lÕâýžô• 4ÊП,})pÕ¾˜–Lha áôÛ™Û *áE€™¬e` ðZõ‰¦Pa܃q•hÀ¤ ÍMñI©Óý!‘¢˜€É$jbµ!}ݵ²LÒJÿáÃ‘Þ x!Ÿb’1!0á#F`® bãâ* ÀÅL"`-œD&Ü L಑¡àH hÁôÐÀ/.À’ÐÕÚÅÕ¡¡]@UEZ¼YK.Æb"ºÅ¦áÀö4ÏÄhÈ"¾aôœ…Âí‹4Ê6ÛUaÄ1&£Ù$!,;ûž#hÁÇ2’«H0"`­¥°ÁE=²@×- ïÿ²>“˜ NŠŽ#“²Ï@Öcj!B¢À8£‡ÁtÞÊ´^ôE£10—ŽK !U»¬Uƒ-OßûþðˆÀ8+V3ˆIJ ÔJñfŽ]‘o9õ´ˆ[5æ@ÝÀDN®AðdxÖÀ&׬_PòÓÁeL*åAÑ™S²<:D9ØY#ÁËM0ZÚî ØdLö0áÊe#€[œàØ8´Ýš¥0‡Zr…´¦¼æ·`-F†ªfÇ@^ênÛYT2í)ô "mÒïa.¦¬ðU‚ÕêPµ>þvá6«mõ*£Î3ÂÁÓZ~_KôžÆð޻߻Dlþé`€¢Ë8­{ (ú<¿¢ÛØåÀá?¿ETI °»‚@@xö{è+?ó«/ò‹z’:@¾OzòðCMw5À„`m®üÏÿãÑm3$¦€R-æÊ¶®ÉÑK¿FV4h„QcMªWa «[Ñ‚4G`̶­W·üz ž@øÖ‹³x%ð¨,àðÌL à á‘ó‚PçÖ’á!…áAõ¶Ò°°Æ†hS–9Ùéù™…À5zÔÙ€1Ê•pàb ¢Z`ÊÒ¡ŠsÀù¥4{ÂUb"jú31lõ 55j‘3Õb¥ú ÌÐRÀ•‹w5̾Rð0¾"xçR10à Qàà^Ñà¥PÔPÔp× Cº)` ¾Ní0@`޻젻ˆQK0.†P• ‹GÔ²ÿ¹ø8j„nZv±Pàk kèbìùTN ‰k¦Ðl¡@DiªüZq!²°‚eÀ.5§°œ„`ÍÏk#ÎÄЀB§^⸉óëÞU:ôB“pLŠÉŠÁ+“°cß"Ì8ðHI›u"ÉAddâ`ÎÀ‘JÜäq@±Ž;¹\³ïŠ!,lýTlX9s-„Òh°í\”ð²À倂Å`uƒzQº"0œžÔÁG¿š [Öœ‚&ÔÄp!N:†[ìöÀ"‹,¿i>÷äË»w@„@/œ[Ñ=F‚L÷¯¨ÿ’x/¡9ÿõJJØ…ZÆ€2y&H!› bE V± –*ïçpR8Ûp!á$ Ä1Ÿ Î}rÏ Ö0u0pÉDÀ™Ž— ŠØ·y)Nò"s,¾Çd`R´'†d¥Rá6xÇ…IR¶@%ÆÄBPÐCybÓ01Øn¼FǽÐXw&8PÀP`€~U|3"Uè8 Â08ÉTˆN‡Œ6ÞS@@$?zd"iÂå©ùh Š2Údªà@vÓ9À›¡juÔã$,ôç%S`Ò4 ¤J0}$ë®>½ÑÓ•A|”QQÿCâ0Á9I5–X¤ÕÙXã lÒšvÔ) ‚Ô**¶i[—ªò‚#Ńb¬6e¬E°ŽLX†›h+H‘¬"0¸f†”(Á­Ä‚¢Á¿Q°Æn´ÄÎÖ0Ĺ+ˆÎT= JƒÈã·nPªƒÞÅQ+0é®0d í2i2!óî\CÐ! ÄR!PÀ£NØI\PJ€C&Gst˜"ýggö$0 +8b1šô™V8TÃikâJÃG¾`E«ÃT nŒ#ªÇîy ÀŒ5–‡®&`ÀÝ[Ò½P3 7¿—€vóÌ8Ð~ €€ÀÒ"J› 1EgÂÅ,Ó`ÿ V;›0Äš_Ã4›‰N‘M”ýºYÑ –k9ã 8Áì„@°Ö¬é€Â¡ 0¹Êø·BDDž ­5 3ÜŸ@-šäªŠ·Þ”•œ¡‹ø(x7ëÚ<ª{ã Ãxü¾ÚÂ…éisqù@°,“—ôÇJ“Ñ/f^Š-¦q'LaîúÉ>0þI¬yÿ[ÅÇ*h›(ÁýbÛè†!2tà&{Ï™š”²¼MÊFŠZÄ=<€ðlŠØÀ ¡F`ë3\ûcBù q XÀ.àŽ §–cÎx€>ƒ pGpá<Ñ â'zç ÿà@”p@ x/rÍ^Ã0£(¬ýOeÄ@ª8€èÆ@° ,´­z‚ÇÛ¸… ¦{àú9& Ô#<Ý¡Ãv.Y»„‡]?  È!Šr”¤YîJÉ$ê¡ÃzžøÕ=Œìȵƒ€¢¸(ŠÆ€$¹œ4Ϩ©d:¡*Ø´kýjÇUÉ5E{±`à)HÖñš» ¯õöfA&   ƒF 9 Š I}9C ˆ•1xgD…„%Dy%+¶±;mDBz¾½¼ŽÁ<!ù,7l ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù ,Fl  Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒV‹C$\ˆ,’'X…# ›‰$ ' qS2.'ceƒ=€@Aª¢¹rµ8´¹q–¸¼rÁ³;{ǽ!!ùB,TlW ÿ Ždižhª®fà¾pÌÎtm‹qß|Ïë‚WÐå+SºäqÉLê˜Ð¢3­ÞCgÐÊMeÝ0ê»›IÂ\6@’*€JdF†Å#A/8R &„ ˆ6d/m1 #.„/' /œ$¡.‘l#n ˜"«"š$. "$w§¬i1C“£6ÂÒ# š&Ž "š¼^­“7 $å'±¸“p4kS$±žT8 FXQ0B J(˜E+W"b}KkœC Æ‘  ’)WɱöêM ô0 r„%“'¸pfäâ¤d(–‘’WS… ë©æÉˆXûN”IâèÁó꩸ÄgK 'B‚p®(€nRžÅºÓD:uIÖüL‘034 (3m8Æ.Kàà‘ Zixá&ªÛ‚ô46+"á&M”H(éB {*û)iéØ-> 0  yµD >XÝ ÂÄq¼µ¸îŒïžÅL‘Ü 5'Å÷NÞ8ó*0D—ynK$ê\Vº!ù!,œl f Ždœhš–,©¾§ÐίÏ-|㦮ò½€ÍtùVEÑ™\¢’JaYtž k«J¹V°S¼$AT ãR6:§ F¯Ž,Ý5ÃP-YþËãïc~€|u[‚eˆGtDŠ(^6ŒsŽ:!!ù,«l Ç Ž$œhŠ AéŽjœ¾¯lÓnÌÊxió=XjANñw*]Ns62ÂÄ$’Ã"Ì=-c¤¬Á*)O["E`h  áp"zo#"`…Ch"w[VŽ6,"V $ "{MG$ˆ ¡S;"6ªg<+1[¢-W.‰2²-Y©%G¿¢r . s ¸~x.ÊÒµ6ˆ4ˆ¢A…gKàª{äÈæä¸ç˜àëê«£ïÁ1!!ù!,¹l U„ËÝ ‘›KÄ;½‘n®xšHJâ“+Û¾LëšœÊ èï9Ù€:¢ÌøBŠ,´J²ÙŽ Gê3ÆN±Uî5W¤jm;ëJ‰2§½ÑìOíA{ !ù,Èl ½ Ž$œhª–쨾Ú¶gü®syï¹¾¿=Ó ºn¶”QH—dÊ® `qL£õÀ&ÁàôË(K˜±^0kVxBªdïcz$ '„dX‚%Q;N‚X,‘?IeZ%˜š‰”d›“@‹„#†ˆ‰z|#a¤z¨tv›ofhjlaÁD*Ef[_ÇÈOÌ9ºÔ3RÉ¥ Ø²×4ÞÕ²KÚ?UäFCN!!ù ,Öl ˜ Ždœhš–,©¾h+ðÜÒ°ÚfŽŸ¼Nº`ĘQôÛ-›Ê'T@*,Kd¯¤ T(ªZ•˱8¬¡¤òõ†«ª3lyƒ*~m"eX|xn{M€Ž,Cceˆ”#V–&Š}@‘ GŒ’—„¥œ)~KLS±w'¢‹Fl¸Aº´¯8¾¬R‰/ÁP!!ù,ål “ Ž$œh ¤géŽlŒ¾¯,Ó®㥼²%Ä©ÑÓ¡ÁaÑØ"!&¢‰Ù䉨++ŒŽéöô»ÉC9¥&ÃKæ;+Ïœì±\Úwxpm{#B‚zFobW\sq,e}…yŒntn j'›\]u( £d‰Zª–Z6+e­®„V¤´¸­«¬°F?¹\!!ù ,ól ­ Ž$œhª–쨾iÛ©€Ê, ãe`ë7žË§úýÂ!0˜\Æ’'S(=‰Ž“D*Ê¥àXL”C;>±ƒ€x.쪨€ž‹'sUH|%i Q(n/W %Šm;…Y’kƒdš•zXŸ$g¡Rž ‹:G{™$“¨Nª±”¬FV˜%§¬´£šœ¢MÇTRcP–ŽÍÉ<Ð'+ÔÁÈ/Ö!!ù2,l ¥ Ždœhš–,©¾h+ðÜÒ¨pÚ,­¯<—8r 7QDn?e©ùì)c$jò”w‡ÈH2‰ÀÄlfˆOÑZÖ¹½NéÖ«à^5©âX#Zy€Kƒ~\|uRs}B8?%xŠv$p…‡ „Ž# nŸ˜$i'a°cA‘²»c]»o‹Á¹ž4ÄÅJ{Ä¿È)†;Ìc!!ù8,l ¡ Ž$œhª–쨾iÛ©€Ê, ã¥~Ú'–“œ 0Vzœ— òç ’ ¢W½‘*G®kY…1Yd¤MÉQ!#™d3ôÌöµ¬•Îi\k$€j]†}+„h‹Œ4‚‡$•&p”›ƒfš.>K”Š–Uc’¥§Ÿ—¡ž£ ‚æ£"‘vB!ù ,-l ½ Ž$œè)¤géŽlœ¾/»Êíâ²^ò1ŸÉ†€(Q„œ-›¨% p#:‡ÂdxpGàMT@ PðT…Q†‘!À0yÕÍÜ¡: 'k€"g)„P- 'ƒ…)yQ|jwŽ%˜š@ %©£¥%t¢€ '"‹¹ª6d( }±¸™m  q'Ô£O×FŽzÚlªURÛábQK›<ã†ÝP!!ù,;l ˜ Ždœhš–,©¾h+ðÜÒ°ÚfŽŸ¼Nº`ĘQôÛ-›Ê'T@*,Kd¯¤ T(ªZ•˱8¬¡¤òõ†«ª3lyƒ*~m"eX|xn{M€Ž,Cceˆ”#V–&Š}@‘ GŒ’—„¥œ)~KLS±w'¢‹Fl¸Aº´¯8¾¬R‰/ÁP!!ù!,Jl Ù Ž$œ€®héŽì©Æïßiíâ·^®3œÏÄc aÅÕQ”T.eÍ% Ù ƒAÁ` ˜¼`@Ä@ L@¾‰ÇŠD€€ 'ö49 #gzT'x %kmQg% Ž{T{%•(o4'™$]_žn‘“œ1¦‰‹$«—ƒ…I g »y¦Uehh^¹E#WY[]Ì<:”mÄU/x’–nN‚ ÊH—Êg¡ßºYué¬cOIÑf$ •!ù,Xl — Ždœhgé’jŒ¾´,Ó¯ÊÞ¸i«=ßo&2‰“A¸ú‰±%lHT $ ‡R¸Cu.h@:¢Ib²ÈÜ*¥™Ãðvª‹ÉÇp§{^îîjl`{x0_6€yu„h,ƒŠt^¯Ä… ˜³¹fC\~ÓÔEÖL¨6ÙÅÖ6e!!ù,ul · Ž$œÂ©®géŽl¬ ï+§qíʼ^ò2Ÿi aÅÕQ”T.›ª%€ÈµDCd0¸* &ÔhDNƒÄà„CE–@Â02`ÚÓ±ˆXè€V)"z'a?ˆ„* HM4u krxT@5kn ,:¦I©­E"Œ# k­V9* *ŽcdCoOB+¼(QÑÐGÅRÛØU½Ú˜dGÕ@!!ù',ƒl U„ËÝ ‘›KÄ;½‘n®xšHJâ“+Û¾LëšœÊ èï9Ù€:¢ÌøBŠ,´J²ÙŽ Gê3ÆN±Uî5W¤jm;ëJ‰2§½ÑìOíA{ !ù ,’l ½ Ž$œè)¤géŽlœ¾/»Êíâ²^ò1ŸÉ†€(Q„œ-›¨% p#:‡ÂdxpGàMT@ PðT…Q†‘!À0yÕÍÜ¡: 'k€"g)„P- 'ƒ…)yQ+jwŽ%˜š@ %©£¥%t¢€ '"‹¹ª6d( }±¸™m  q'Ô£O×FŽzÚlªURÛábQK›<ã†ÝP!!ù, l _ºÜñ0ÆF™¼OÔ}ÞöŽ(‘eà™¨eN­òÂñ ŲÚÑ­ýà_(Zéˆ>¤M9cš4¸L31ž¨ËF¡@ ½‚b½ºÄ©éyœ­%±eÝ«î½ÝmûNêdÑ_ !ù',¯lH ÿ ŽdižhªŠA뾯°Ît}Âøkï|šÿ½ &qÂä®uüµ”Й“銦 Gr ³¢,–[õšÀ’ñôh>‡ÕT ¹ m‰à”" #NKdO-w-{}#xœ‡ˆ"™ -z"|ž$€‚%`bCˆ -¤#$’$™¯$hp\»%- #«“Ã#o³8MU % -ÏÀ#®n²AF ™&„Ã|~­©#±pØHë%íá¬ã”`U;G¦mÜHx NU€"$AÍ\Zµ’-Ã5‚Â6…-¤‰(fíZ—[rz‰ØÕkÄ‚ˆ¡2á Àc9ØÈ´!×)y$˜=lÀ#‘ŠB–<¦ˆQ§ •Ðöb y#$´¸ð D)´F À`GCž 0$¡r&@ÈÔBjSÚèE÷£‰Þ6ÿš ,Ø áÂP#Æédqb¼÷9^:%!ùó, l¾`ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßðígN¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•†/–™š›œžŸ ¡¢£¤¥¦Œ˜§ª«¬­®¯°±²³°©´·¸¹º»¼½¾¿{¶ÀÃÄÅÆÇÈÉ¿ÂÊÍÎÏÐÑÒÓxÌÔרÙÚÛÜ™ÖÝàáâãä×ßåèéêëìªçíðñòóôïõøùúûá÷üÿ \æb Áƒºò§°¡Ã‡/ŒH±¢Å‹wbÜȱ#=CŠÙ $É“(Sÿ"3©²¥Ë—³XœI³&(™6sêÜÙ'ÏŸ@ƒòñ)´¨ÑŸD*]ú2ŽÓ§P£JJµªÕ«X³jÝʵ«×¯`ÊK¶¬Ù³hÓª]˶­Û·pãÊK·®Ý»xóêÝË·¯ß¿€ ã €aÃPL8@œÂŒ¿ àÀà˘3C6± À… $<€ ;R!@‚­_÷tÉ.T>a tæßÀãn.ÑyB·W´Î0„áWAŽ»eË&z'ν;ÚÖ80NƒºòÌ… 0ŒÀt BÌOÞÝ·÷ûø½'QüøvØèa_ Ð7ÝÖH‚ÿvÕåçàƒSí7B$ °À ð@)È t'4p@Fp@2D€"``Š\$8 A†@Ð^}€ £ žà‰ ` Àu¼±á“P:%¡Š`€† p(yÂr)4 böŒ/è†Ý†Ñ€–;ÐA–Zºç½%`@‡¡)‚—$@p˜–  žF©è¢eL @• GA{ 0€v%Z˜(¸¨› h  A B™øø¢q€"*FP_Là0pf¦’à\ˆªa˜V˜(£È&»xŒ1F‚ré«k'hJÿ§&¬·b†)Ck\öæ"ôö™*Ž*‚¶n"ê™·*X[ ¹#@V¬» *«ï¾R@ÖìaÏj™¯“¼æ»ic(Öc Z²øBo²æÀPÀº‰ê¦®•†9o¯"4¨–÷bÀü¦¬²à5Ѐ0+@¡¶ÔVÛhZ¶;‚µ#`K\€%°¹ ëõ(è4`Á{Â>÷ó%hïÇKô¡&£¼òÖ\á(…Úý{˜Î‚|pz&Œk‚n¦Â e¼ÆÁm‚¦ @a˜°´¬ ’Ù‚¦Ú­5"'ÝõáˆóžxäþÏ"øL‚‹Ò’Àv *"0@¸Àêæ&ÞzÀ7ÿ¢y³ é¯‚—,‚Ó‰·îº _ÇqS›nöµ@‹¢BÇ@ÙÒC‹Œ›;¢þtÔÔÚ^u·W«~·Ç¯G/}¬O(û©Ûº #Ù&´µ‘~“Ð@Ã1tf¨›D€ŒÚ6hèÆåPú ۇئø$O¯ÿþ,,þó³.š€ŸÖu6KÎYX¶:Æ-ÚÅ@a'k‘až€tkFÈ›Ÿ ˆÒЋUÄB®øGÂèù?×ór" ™Jà{%8€g´†¿ ížrà×íœ K³X-ðªXÕGƒ)áhø+"ÀR!¬OKHÅÃÐz4rÈÄ'’@2r ­P Cÿ2% ÐSÀ˜º8À(À0•ÓNÛF0'Ã`I~ùê Q €-žq%pQ–Æc(Õ1¨ŠˆÜZì(™=@K (€hè#ÔI6_ZŒa8$¾•èD4Èß sÀIK9¢až\ð£KvoH’ÔÔ¤Û%ò–¸Ì¥.wÉË^úò—À ¦0‡IÌbó˜ÈL¦2—ÉÌf:ó™ÐŒ¦4§IÍjZóšØÌ¦6·ÉÍnzó›à §8ÇIÎršÓ ±äXå\PG2]€ÐeözÆ:A1&à$øDg>‰”" Ì?Q&3  d$ü4¶… þÓŽ&›ºüåš vk`Ó?oø+”QÿF:aŒ'ùJà€ GpŠÂöÐ)nñ_Œ,b9©hR¤ó¦ñm 8¶&x#Ò€œ¶‘¼7ß3w<~‚ïS<=gõ?gÞo›\Û7© 0Ì‚s¸ßwë7ÑcÔdàå9é>xã÷ #âïR—g<÷sÔA˜pcfRÛåǶ{UÏ22û¾!Ÿœ‹:åd\yQw2W´h‚uÍéÝd y¤.zy›GŸšSeƒ§u#o?vÄ߀ñ’ýr æutàá`r£) Ü ‘Í9nÍèJ äΣ>d /ÛÈGßS© ž/µê]Aéž ðFìç½\á€24Ú¹×ûÎ{8~þ^å&ö‡ÿ#f|90Œ•€„rÌçl’w0 $(ä P;ÉÖ,4äv+~¢DàFr„“! pr§·l#`ioWº±}d®&u'DE?ƒoû• ½†u8K£{¶…[¥"ªÅZ‚Ô.ÝÈ,Ù†f¸[®Ñ[Pæ2p$™¤‘’ÐB&0Z@¡õ±vÐ]“ä#ÖUh÷XÞ…¨Õ„âE]æå“³Gu‰9$ˆ5Uÿ‡±D&Py‡!bŽØ]$3x]XˆÚwXɵCUÍ"bÝc^øé§-EaÍ2ÆflR‹H Wƒ¢3qhŠ9¥| ”»Öƒ„'2‡WNµWP9;Á8•,`•f“†5( O¯fR®Adc,æA¤pŽZhgyu!‚Ptö_‚D–eˆ^5—Pf õ5ÙðHƒ†(óŠv6v Œ%*U˜(`WÍS$®QS|õ}š¤kyؙڹÜÙÞùàžâ9žäYžæyžè™žê¹žìÙžîùžðŸò9ŸôYŸöyŸø !¿bz‰r)8P8ÿÅ4> p­á<áÔZ2rÀiJ7BB…•|XÓ @"`"c@€›Ú›8"¡Qƒ$â Ú~ÿdcR¢±I]v°ú°w)…„$ NjyI”İò/Ù&—÷‚ÍU'IõÎS2P¤Í²1ñ/v‰¢b£kÌ2¡…át0ÚrhAKG°4:fš³]×xâ+íaF4*¢Ó…Š… pF‡b(ª%,Z›Zà/J•0ItzÅÒÀ¸âat'‚¢$°ÇGz,¾¨1  k!¦F°4G¡¦_„dä${bù­1Cl #ÿÅℾՓNêh2pª©ª¨ˆÖ§Ž-à"–]š˜ªšZdª2R£³õ˜Üdw"°›1À&Š” `¬Ú@~c9Ši"võœŒ€¬+ð¤7­3`(^ô¨. .íã«H9£LÐ`A24²˜÷""j"47À¯ƒ¶m$°ƒV€&sW ²IÆFÁbH"’„‡±1ºá‹Î7‘Ï÷#AwI®+PZ#ÀšÕT­(¥* v©ŠB4²"€†cy„ÛÊ8Éá¸Ú»B÷£ÔÃ…ÉC‚R,<ì#c0­ìÈš{¾Z4(œyùKO‚â¥÷':ÊüÈiökK…!Ê_*½‘§\gj“Ás„µ(ZˆÉ ð£""†âP"ÙÁ²É}ol…Ô…ÓÿU8Ah8,@‰âlÖ ½JKs.ëñ€‚\2"7ú,3=ë69{¾ËÛÍ•Æã*«(ý™õ©k‘o†ÌÁÆÎHÊH@¯ó=ëÁ7Ý8XºjϹJ–RBºkÎci:“q$ ±,ÀË‚ÃYÿ*â12ÔЉBÄ,@”‰MÑ\%¬”(J$tÄ@*ÍdÕ¡-Ê|Ãùº,ý6=Ö1D&Ä,È7T¥›ëŒÀ`ÚïÜÓÃ7ª|5VEÔ–Ç‹,*Jl‚·…±n¤Á£}Ð|/Èá±»£Õ×,®`(¬MÊUºü8Hç"鱟s§6ý7§ø+åü\Ö¹ÒfÍXÎ<ŠàÙ—=zýO|}Àñú×ó 4ñ ¯ ƒ”nÅÁE=Ž^ZË;cŒžBÐâK½î!b…3Çx%¯È‘­v–£‰½ÖDª3É* ²úåEíèÄ&Í»&Î+Ð;# µS£p9ã³q=ê"¦0ÿº¦pö4¤­]©~íÎÆ  ?ýÀ $Á·((WÖFÕœ6½[¹¨§9œGÚÌL=.^DØ{Š£­Tìm?wLa]­L±’n*…ghxk2ëÖ¨ªÑüœŠš+ÅÛ¬·ZZ'Sc²#H3œLÛ7 -1¾Ä¸"1ƒKùDpÐK§•Ç L=ð Z ØîÓÓ6'Œ9,ƒØÉwe®‚•­4ä~’a’ËmŠ”¦ Ä¼÷M¸zRiå­m';-ïe'žL~O”TFÎãP|’­5.6ÞÍG¸¼‰îÂEcc•<ŠN˜óýP˜¤ÚŒa˜élÀY:}<í‰ÿƒÝ]kT'”Ed~“c®Á¤ ×GdB1Ð.A I§JÝ-PV°p/ƒy¡óÈk2Â'~Z4±]*€ÚÍÔZA CZF/Ž'ÀX"J?‡b¡¾9'J€ÔÅ›»È >ƒ¶íø½á0`Ù ¢µbƒI `p´Í+0à TÛ-°åÅ Ï.…ë¯u]¦¾ ïdò¢²š¾.€ÔîÔ#°¶Í?Á²r½# C“2S"«†’­3ÎDžŸ`péoð«ÃMBˆÚÒ—Û7£NxÐîòTÀ¡°ób€¨á¢Î?$ÿ¬%ž¬³Íì<«‡aÌeðŸÿ9ð¥~8GßÒý¹NO@ßô+#ð¯sõ0` 4p×^Ï?Uß55ŸöÚö,può´4œ!Ø1÷u_÷n¿÷|ß÷~ÿ÷€ø‚?ø„_ø†øˆŸøŠ¿øÜ¼µoðŸ8-k,.Òõ‘9hªÁߤ ¿Û) 0¶°!ÏHWâþ™ì«€i& *$ðo$ª%à®5ÜçQw,BŸ½´“¿7úè=pÁ*àRî;Š„ìùzìT1}©Û¤„÷O-2ÓÜ¿aó1 ¥Žo=VŠÛY )x‘Á¯«"ŠÐ½Š±4¸†gN)^.oªåã!åt*Hÿo2’ t€ @Áà¨Há"«}ã¹¾ó=À&>ß#à †ÃÁPIÇ%¨­ZÒh§HL¬†#°­è5»í~Ãs–@!n÷Mß"°à)¸4Ü"&*Æ]­X1¸ÁÜ`X)ð4 Œ­$øÙ4XY,–þDÜUÐðHÝ lB8È¢Y6v攊˜ÎÕ »åíõTåêäQCGKO ŸHÜH`BHî¬^ÜX=«T%¯m2`Ú$ $D,0» Ù¡¯e?ÌÚ6bȘ1¤†Z 0C®>­hæÏ "|º@á ÿˆ¼·É K–ßu¨’€À½"/cD²ÑÔn;Y–ëÄG™k<(ð!Ó¦N¡»ÑG߃œxḢŠVš¼¹Qgƒ;e¬$Ð`…€|vØaic- W(°JrÅ.…¿ž¾ªâbåxªhðˈ,+¼ñéØ ä2H3@BÌýVYY€Ô X`U48\kg ŸºÆÀì:gÌKgQða£Ž>z.ü/ :Ë;ŽòVãª8àÂÁ ؆½º‚¬OÜ!¨» Tq %`!Â<šC6Î’g%Âå+V5Ñ‹p1¡…ÁTÁ7 T NibÿÉÐ X(àth4ø jâ@Ì€‰CÝg„;Ù·‚%ãÙv6‚:H×âp3ÒX#NWqM7eÅqX ;ôÁŸ –´”Š.j§w7–ØÖPÌð‘¢U¶¡Ðù¶Óö)€Ru ê‚J!¾ ×G<€æ4ÐÀ'¤õ0œw̰â бCs²@n)ú™ ˜8t€XÈø0èüðc?6Bé4zùÀqWÞ!]ÞðI•7ĈÖMúðb𗔆é!nűŠZ߀@Žè ¡ê€@›œè§é§CBÚápQù '`LJ6†ôq“ æ ÿ }èÝðEÆg%·Þ€(Ï ‘Çj’¢›.`ú=ñG7œ–”“•”ˆÀa¹wØEÙ­ƒê aLP¼o° hB6À• Ì@¬-Ð*(Á†i^ÇÎ^8˜f¼ pÑN¶áÈ-‘¼ÂFeè­uVÆBYáð '©‚¸;¼;„%)«´ÐÐP¬B#h²aÀ&Þ†ëë Œn§–l˜º¤ |·,&”ÛÞ ˜'L€tìTyX.EßÐW/Æ>Eî ƒ`¼,A@ÀÝ/g°wËÅàåOV”ØëÀ&‚ è£=!>D Í]¹åŠ×6Ül ðZVq-ÿh;ßÚÜCÕþfäaX‘ówä´6í‹ã«¤Ì¶ n_,œÜÉZA¸ 3DÀL|ãŠòN«œg}߃¶¿ñ€3;ë0|öÏ^¾ø„ »ÂTpø >x¦‡C…J;¿6Xev ³âÞCyv°-]í+HGù»Aö`¸Ã‹/ )Äæš¢±!ÌáUà“/îñ³’)ê‚7 V˨Ҽ (ê[®ãÞÙB˜ƒ¸n|*\!æbƒlH 8 órG 9 N–ø>q›£™î4]óà6KkØX­È¡‚þ$fY`ð„S>ž‰ ¢_äl†:§‹+ ÿaËX¹ˆñ` ø›vP(×àq›ÂP·±Àd!!Õˆ¸€N(ÀSs˜°srÓ!Û@Ž›Ý`÷† L-]y%Q“"-Îw äEƒc&4ñÈiÁ¾nF€±{ƒ: ßÊ@D/B¯4ô›¤WlâÆÆ1.†-f(T%,+³Ê””¾Æ`/¯Î SËH"€.( D–°3€ T'²CC ‰,`%e1ÀƒЋO:21!+V2\¸fG&p=*aV®åIi2 ÇVB ·fÑF¯èN‡yàÊ¡a¢½(ÿºÑIXbëéÊÔȼ‘sØTVæ ´!ê[&M%Õ±•°41šæÕÇ .gYÛ‰­7Tr N2jq¢<¹ ‡9„(<\Lñ“XÆÊ„õËŒ:š¬Áï²ó(cÐR³å¹Á'K}ZqB#l`ŸiŒh´Ò‡ ,g¥q¡€8’¾f †×›@\)i¼ô R¼hŠZÓÇIAv°ÓŽútšC#"Ä”Œ$2ˆˆ `µ8€ ¡Eî`I8Àã íñ2SX ØÄL:ÉÅqþŽŠwhàSr#´6MŸxÔ)A€ˆÔãCXÕ<40ÿ€èJ£¨Àn‘É1 \ " uz Ü"î¨;qê;‡zGÌཞîÍ\`?Èâ7¿úµÒ-i ¼áÎl¿v­ô¨%(lÀ ^p~µˆ™^˜ ƒA‹`cxEX\|‹Äf8Ä"ŸUsÉB«X¡Âq îˆ[ „ÄŒ:X„[lãã8hÍñ-PŸ0 W<2‘‹,¾9ÉJ^2“›ì÷à› •9‘)‡ËMQš ²ÜåÍ89Ìb3™Ëlæ3£9Íj^3›Ûìæ7Ã9Îrž3ëlç;ã9ÏzÞ3Ÿûìç?:Ђ4¡ mèCÓ¹ÄӵЅkáÿíæÒùTwÖˆt²‡ŽˆÞ´ŸœÇú €ˆD:p|d¨¬íça™‘œ¡0WiéBt)¦-«ñz5 x˜Ó–ókÝð̑يÓiõO| Uún•&ÀÞ8´€i¨‘LJ¹aƒ[ÏÅv¤ &8 R@ŒÙ§ïpÁ `Ð*þûhü~…T‰Á!ºîãyvXÅ74!Óœ«Éü¤7èmo8 ¹¦«Ð.äxHO <㉞' Ö††Íb±ÕÒAëíèO›B@äñ‡h è@->p*Tb´:à‘0±òÝ ´Éc#ÿÎã–¡»{½rºè{wÉ‹ÃO(÷@A]¾ÎÖsªÉhàÀŒÌš´4Ñà3[MÏöúŒ'=îk8l¾žö0—]i|PÁ&Í!?UWñÕSŽÈ«ôJ'RY0rÏþfÕR9˜2¬°6S¡èzs(]°%÷ÏŸyéCÖ”£¿´@Ùà’D¾Tô‡ë<€„´˜OŠgÄT©’<6ÁÍ•Nïé>ð7!` úã“Yô>p•6ì‰?/$XeÿÜU¯€f J”öo= ó@BÆ8zn}ƒ –•á‹Þ!‚„ü÷;Yù=8X(¢ƒüCrÆ„ÄÄ?&î˜÷ÿXV @@¦µ¥1Éä Ñ©ð ,ÜouÛÂ0úÁßݽÁY…ذ]DÝv0¨Íî1‘ö¹ŽœQðNXLZÁ¯q†þ–œN$ŠÈ©]Ñù@Öa‘É_+(JßL î”AïøŸ´ÑSôÔb„y0@G60ùñœìøÒœÀ¢y\ˆLÜWš!ƒi ±)Šÿà€t ‹²µÄb¡`¨ f±àNa>Å.)`äÙ ìXù4RÖíÜÌÐ á"ŠØJ’¦éÐFϱ;P‚²ZD\ÒJŒ ªÀ* ;dá!ªÀ "Í\ÿ›ûÝ0@#Ê¢‚9â`R(hRpQâÂ0gýÖ nb Þð}bŠ¢ÉeÄœbÊ©"Ç b4-ÚK½â,Rã~Õ¢5_¬äÁ6B`SY0€?<´Î¸4a)¥U1†bV™‡i`À  S—-£Ù b­€Zä Á¦cæUã?ÒT¾Á³‰F9Ì UÑÌUE]ö££!æ¡BS¨d dC•0fd€Ì<@gd@.4#, l¡?dJ²Ð5òL<mY†mmÇèomnœ#€=¡1²ãïÁ< `aˆdÖR„$ä@^ˆà>L£J:å ±äå K­áW îÿ@6ÛßSr¥ø8˜ðÚÐÈÚК6X!bç¹;deWºe(M5ámßCòц5ºÁ Á´å[fÒÝ¡ø,ÁÆ€¶Å fc^à`:fdJæ~AædZæebffjæfrfgzæg‚fhŠæh’fišæi¢fjªæj²fkrZ\.S£©%TæÐL¥4ø\hð™d)œKl ëX(.ÓoÒÛ‚ÚpÄXЈ°O­q^•ŽZvLå8Ø$g&ŒšxÁäÕ¤kq Ä4pÉZ„A+ c~Ýæ8€=èNM@R¾Xo€BÄE4%¥d$ghÿtFˆ_"„84¥!ü§8åcÓ®q–B#‰ð•²A}Ù",„…`†>8À'p¨·}cÏ Æ•ˆ è$°vÆ"†X@,:,Ϻµ)6‘J—œ'0Òe{6Ž„çõ hðg0i©£)„á œ@¡¢“b–/îΙØ P©ðh¤ðFl)ô‘úB ‰6…‰ÚÁáÿŽ+ì’"dÃÅhž:¤“ñ©ƒúÀ f zÜì§Tp\@ª¸T0hÕPšÂ°æ*¿½ƒ 5€Züe¨M)³ÆÏ§"‚§FÙ¶üêüP'šÄÖ<Ü\ƒajµ¢ÈeÁåaQAädtâ–:…׌ êÊ„×lÅ…8ÕL æQ<%3øÄá<ÃÁîDX…BI&© Ø·"EÈn%?€²â@‘fÂØÜµÁaP‘¸CÜÆØ‰ÎÆ!ÈÃH‘Æþ{$@ÜÓƒjõÌž Ô©YaLkQÖBl§1`«‚ ¶Ö@Â@H,ÕÔ#·þÿfdÍR¾N°b¥.«)\]ô{$A¼¢œp <­Äêဠ¨-À„ÉèZÚ½áXÎÆÔ†,…„aÆ_µÉÏÃöj€*°z,•hàžÌ¦j¢â€! FÍLhÓØ ¬©€1JäI âî„}0nŸDÕÌÎB[—p­  À³Å }T¨ºvGN*ÖJCÒÂî ë@ÁÆœÀDm:L-x‡;(€x8 {"RzܸG ß­Dü Þ¬R%`ø8ýÀ&0€ÚÆîÆ4i诘.YÂÂuÃê¶ ÝŒßb¸/Æ@¸N7Ðn4Øî|ׄhKÔÍ}šœ] ìX ŽŸÖ²Á°@Œh f>ÉiurIàUäáéõ>E7œ‹ÙpÅ&ú^ã¢dú®€í1eUXF„î(:îo•Ãû”áÆA íÑLTY]@3n6¤ÌYlpq-«¯‰µAhYUOSìo!ßýEA „Ç'¼¡ ìVEÕæQ.êñ\—ÁÊ=5r¶ØŸzp€iGõ} ö‘mìÙ04@(ÿ“X+¢’¯Œ˜×¡À.®ò@˜pwñ è8ìi+æ"$c*”A8³ô°Í $P7 Èl5,ìNrL‰—ÎÎlú+ M ÛÁaÔ˜i¬²thÅï¢ÁQÀz®©Ò¢«ÿÆ­çäÃDÉ„BL\´à$±YG7Ø-ƒ0S+ßFýàŸp,ã²?³h`SvCÞh$ƒŠ±^®B òøtùñl ´¬¥Ì@ )° ûõ€ÌŠô xœMêr”òŽ^‚J 7×]êÚNLÁ‚J×0˜³åiM´ú'Gçî[éœ@¤±’Œ 2$­®Á¼2…[t?ÿ§µr¿p«Î\4Vƒ/}M4_fÉKû¯‘þ ߘKlþ)/'dÛÁ hs³³ôæð©/„`·Œ0 d¼Ï6À§²+5ÆœÀ§3’X5š –j±DX®KŸÞ8a4åÔ{ðïü"B0585C@õÓPëÚ…IU£2Ò4WA3³s¡žÂ\óÀ«ÇÿþŠvåßÀaÀB@‚`¨É½õ à‰S…öHÓ×G;ŽÈž-íõ ôuBµÈ4'Ò`|«Ì%ZËŽ@wÏ6ö¦  ª=ÇŹ¡I&&Z&v6˜j"lå¿¥‘¶›v¸tV4¨Ý‹üÿ.CÛclK´/?mÀ#±AÌ b^ŠU4‘uqø^”´>Ʋ°vÆÊ®ê:wt£t`óp2Û×´@í`·Où4†ÿÐGsŠƒ7‡Zt`Ü*‘¹fS¡·«×zKk)Ã)ßx*Ó4Uß°}×Wrbñ Àª-»¶.#´TA°‘â1Í5c²õœF¬– ÞÀ H „ï@”¿sX{÷ÞÁæa0·ôhÏèQp\‘û ÒÐÍîÕK, ª‹vWÌJsu×HvÜbF¸ó0/âÀ<ë10zèy0ðñ$®íOQ}#õU@7¨My«é=<÷î24¼üN o|jè ª­Öu-ÀY»n<×f˜ê VdZJØáS—KÎÖ=äOÜ–èMf%C¦ü|65 ‡½JDÃ÷óâôŠO•Ö·×ÐËr£øq‡~:Å.ÀqÍ„ØOË®„Å݇pRšCd}€{ï1ku×›DĨ,fÕz÷PNmì]hÀð©à º¡þ)Ä~}™:h¸8À…·Ð¼çŒæ3LCV—ôÿadZ âH–æy6à #<îL×öçúÎ÷%d$ŸñhCH2“@ hЪ!¨j·¨EÀ ‹Çä²íà˜E-`˜çô:8 Pì|D>%%ÀGs•EˆX¢0p‘èø‰d°Pa– Ñ@ã·Ùéù :jZÇp€`ºÊÚÚƒp ç:K[k‹#EõYzÛëû ,N^n~Žž®¾ÎÞîþ/?O_oŸ¯¿Ïß¿Ž7e3?y8AÅÊS P€Î#.ü‘@çŠC¨2á§€¿‘„ÿT Ð$‘0L@b "0œ€á# þÈêdÀƒ E|°tÉ(æÌš7sšàÙsÊÏhÈ$¡„IƒGŽ­BÀË„ (6LIpáÂU Kš`œ£Q'Ä!‰wNÊLÙM¼xBG2ˆ8a }¦À- P$Áï倡h yƒ’™…XÃ9¡ˆ‚ŠHxåÉšá€`Q½·ß O’eSŽPå•@ðY\ ¸¤ްÈs3ø1@u' W˜@N*‚=X´`hºƒ"xA™£=܉¨”ðåqÉÄ>äy¨ 0¼^¡Ö° m)‚š]Ñ C<Ç,A+d ÕÈJph&ÿ*Bž{ÚY­Êg1þ1¨ÐÈ›¡à&·”®+îÀÆa™ 'c MdÊ“•SDp€¸7P €µ$ÀÁ”&eºC—=”bM Àk ÷f¦¯ý²@»¦xÝA,†â" 1ÎèBgÉ–°À#lp™º9€ 4ÐYEVF× v!L[ê²K©¥<4`â\ñ$41AàËÀc=Ô¼|¥¯£@\ûÞ½·Ú¸ŸõЬøc'› -”Õ­T 3Rú̇.ªÊU¼Ç½’`z:øžà08LàZë!ÒÄÇ'‰ŒIXú°æÁÌÈïéãàC¦Ð5hjÄŸhÖÄ;OðïÀ“Ûðj°»íM„ !mà€«Ñ­„6D¢£GA¸‰ƒ&Z!¼€ó1gP¢ÊFÐÿ``/\ôÏ I‡6Ĩ\‰!—Ç÷¾Îäì~iб  n=,™ÿ~%!FAŒd¤RF ÄXÄœ!×É8„Ɖl€à*ùF8–1|@$ˆ C·ºL¢ tÔK#ØxÉh@”"8Ò§4“‡¾ÀW+Éa'vh‚ý¯$À<éÕÑ/.$H$ ³G°ÁŠdWoð-*ž‘AˆXëR˜8LŸôå¹LÈÀQÙ¬vjAŒ`Mä 3aÓŒ,{uÃݱ­ws^âÒÆLh³˜‚4Á>E@ÌY>…ï<‰|t<°²™õˆdš P€ºiGQ€Ãϲ1}oÿhÈÔêº9†0ñ¤Ü Ú× .ðWÑÀGÇÐÒ(¶Œ.+7A.è( > F;+ ðT ”g³ÄðšÓd(?0 ªÇŽ{—PL€85ăÒ3Õ$Nà åÎê69/ @ X@Xöd€ o0hÃÉ‚@ uvÙ"‰Vì‰c-«B¦€Ö˜žÊŽ=¨)$ôH¸Ý³ *£ZÙz€·ò)sE@]«CÔ$ AЛ¦X÷¨)Õ©ú`ZO\XÕG‰ð/Ze žü,ìéI¶à ä‘\jj¾„á’€«·ý«e’4.V«ÿ¸éQsÊ£†$ 7ëí~Û-íæa*¡5&GúW¼F÷¬å‡kÿp¨Ø¶n6Á‚R~ KžV˘ÀKŒèƒá¬@˜»[)8\é¬AIyP%ûÎÆ¶Q øë_,xQÒ(cyàØGØÅª¹Äîï$€¥â­.p‰à\à¾ÝB¢ySI"è(xßl¯Åñ`gÌÔ/!¶Í"슰€'ý±“Ç”áYi‡uÀ&vy¢8Ek»züä0k#·ÐMA¦peÙÈŒðWJ1¡‰rŠyÎtND–Ù…ŠXÁ½uqç? zЄæÂš èD+zÑŒn´ÿ£ éHKzÒ”®´¥/éLkzӜ? êP‹zÔ&3•›V…C»ÀJ€Ø8à˜–Ôô0 uÐ'~Õ*`êÎB:\‹ 0+™58ŠŒi P¦Ë)m´ Ÿ«ò%<  êmìIƒFXŽS ?ë˜$r†EZiŠ©–Џ@0.IàtW-C2)0) X€€ÎÇeÿÂŒ%‚²D‚̸F‰(( ”D©‘‘0C¥‰¹3O‹È$ïÂâƒ(°yCf5?oØT+̤A€¸N#P–æGXfÁÄ\\I À{ Fqd¨”Minqò˜ À{ʕɀ$†7WIч$Àx>°˜­“˜c r„oÉOòU45¤X%×>—ƒ4Fyàe4@Ž–FktXÇJMs´“8Ô“ðV,‘i嬘DÉ9阨ᔚ|«áU™™‰•8AŸi5¹ËIš¡àoQñŒ=xkh`!¹eÕÖ‘?:ýJôcB«¥15’%À«”íWžÿ=QPypU@†YlvçœHÀ{#00 à…%ð{˜¹sÈ+ãb ½7ž ðŸpž(€A$0yãK?÷ž"úM58ÿÄ—˜Âå@¬y],…}¹~' HSÅi¹YŽ`Ie° Ñ)v— gˆWåF¡š9!Ø™ ¤: çÅD&’uæ‚×–§y–3àS#T-%RhdŸ:Ðd`r§RˆEŸnYˆ¡!uµè£5 KHà™Ø)Ðé ‰¤ØÂ‹$‚Mª$¥Š$¥\ð{~j¥žy…A¡ a(Iô¦3¦Óá&˜“9;pY3“Ywƒ= ˆÿ£“6à&ç(Lž(Z6VÒH…sgu~óh“­—§‘eb ¡tP¤*:¼G™ ÞÆ€ØY¡Áx¡•Ò¨–¬‘úÀæ8ƒoyŠš ›"€b=±¦‡9[6Cª!Bê5wŠÈ%7Ca=[š!–ñY§»Z½úz¿ZA"hÃÚ  8%ái¼‡p¡ P™à‰·°WÁ™Œª®=·i­Ž0©S€™Õy k5¦á .yÅbP.¶'V_Ð)ù’ãŠkû0Kvýõ_É ˜v)˜ú:pëÆªaˆ”Z°‚ªw€¸#gè|·E²¨ÿÝ9±;Ð…0´[h@š ùã1UÀCwàbkdk¶Z«hÂFTÖ<›64fa±îÇ{@™p·j;i¦6¨†Cxä m☓©ö€¸|˸Î0˜¤a Ú¸“©rK¹—‹¹D泙˹빟 º¡+º£Kº¥kº§‹º©«º«Ëº­ëº¯ »±+»³K»µk»·‹»¹«»»Ë»½ë»¿ ¼Á+¼ÃK¼Åk¼Ç‹¼É«¼Ë˼Íë¼Ï ½Ñ+½ÓK½Õk½×‹½Ù«½Û˽Ýë½ß ¾á+¾ãK¾åk¾ç‹¾é«¾ë˾íë¾ï ¿ñ+¿ó{» °D¿ùë 'úÿú뿦À¿yð¿ì °t¿LÀ ìQqÀ=¡À\.ÙÀ' Á|Rà’ü{ÀÌÁ½h¸7ÀÛÁó›¥ ÁÀ‰.À÷;Â-ì7AЈÐá÷œ!ìÂY„ÁxS· jÃ7lÁµÃ æ€ ÄL•0ÄxÀG\Á¬¹Ä×ÄNüÀÀüòÁ6›KÅë rñUëÃ\ÄÜÅ L3œ3ªMùÃgüÀR`Â÷> Üd,Âpœ¾;¬!XhÀy¬Çç»ÃyƒŠSÈú›²Ï~l¿QqÈþ[ ¦)Ë ¨ÂoüÈóËUŸ—>Wœµn|FœÉóFpAa‘%m Êü;ÊÿÅŒ,Ê­L¿¯ŒŠx<Á²¬¿´ldžŒËó;†DÌ˽ Ä[,ÌT¼Â\\ÌùKÌÉ<Ìl̬¾!!ù+, ¾Àÿ„© áÿd´Ú‹³Þ¼û†âH–扦êʶî cÐ<ÇöçúÎ÷þ ‡2š‘ˆL*—̦ó !c@ŠÍj·Ü®÷ >«‘°ùŒN«×lÞ 0øXiíºýŽÏë»ï¸‡NÞ|ù@»LEWÞîþNš ‘ž1ÆŸ¯o(û[o»/ Àj¦mj$ Â… £øòw!XÉ+êÐdð3‹ÿ;z,‘ €,Ê"üˆ2¥Ê o0Áq@¸#+kÚD™©[È V:Ýü ”ã"`'ƒ=*ph{5:}êN©º@P«ZÕ“gÑ«\»â“è5¬Øq¨Ž=‹öÙÌ{iۺͅÐÁÛ¹tëÚ½‹7¯Þ½|ûúý 8°àÁ„ >Œ8±âÅŒ;~ 9²äÉ”+[¾Œ9³æÍœ;{þ :´èѤK›>:µêÕ¬[»~ ;¶ìÙ´kÛ¾;·îݼ{ûþ <¸ðáÄ‹?Ž<¹òåÌ›;=ºôéÔ«[¿Ž=»öíÜ»{ÿ>¼øñäË›?>½úõìÛ»?¾üùôëÛ¿?¿þýüûûÿÿ`€H`ˆ`‚ .È`ƒ>a„NHa…^ˆa†nÈa‡~bˆ"ŽHb‰&žˆbŠ*®Èb‹.¾cŒ2ÎHc6ÞˆcŽ:îÈc>þdBId‘F‰d’J.Éd“N> e”RNIe•V^‰e–ZnÉe—^~ f˜bŽIf™fž‰fšj®Éf›n¾ gœrÎIgvÞ‰gžzîÉgŸ~þ h ‚Jh¡†Šh¢Š.Êh£Ž> i¤’NJi¥–^Ši¦šnÊi§ž~ j¨¢ŽJj©¦žŠjªª®Êj«®¾ k¬²ÎJk­¶ÞŠk®ºîÊk¯¾þ l°ÂKl±Æ‹l²Êÿ.Ël³Î> m´ÒNKmµÖ^‹m¶ÚnËm·Þ~ n¸âŽKn¹æž‹nºê®Ën»î¾ o¼òÎKo½öÞ‹o¾úîËo¿þþ pÀLpÁŒp /ÌpÃ? qÄOLqÅ_ŒqÆoÌqÇ rÈ"LrÉ&ŸŒrÊ*¯ÌrË.¿ sÌ2ÏLsÍ6ߌsÎ:ïÌsÏ>ÿ tÐBMtÑFtÒJ/ÍtÓN? uÔROMuÕV_uÖZoÍu×^ vØbMvÙfŸvÚj¯ÍvÛn¿ wÜrÏMwÝvßwÞzïÍwß~ÿ xà‚NxᆎxâŠ/ÎxãŽ?yä’ONyå–ÿ_ŽyæšoÎyçžzè¢Nz馟ŽzꪯÎz뮿{ì²ÏN{í¶ßŽ{îºïÎ{ï¾ÿ|ðÂO|ñÆ|òÊ/Ï|óÎ?}ôÒOO}õÖ_}öÚoÏ}÷Þ~øâO~ùæŸ~úê¯Ï~ûî¿üòÏOýößþúïÏÿþÿÀ p€, ˆÀ*p l ÁJp‚¬ /ˆÁ jpƒì ?Šp„$,¡ OˆÂªp…,l¡ _ÃÊp†4¬¡ oˆÃêp‡<ì¡Ä qˆD,¢ˆÄ$*q‰Ll¢ŸÅ(JqŠT¬¢¯ˆÅ,Ojq‹\좿Æ0ŠqŒd,£ψÆ4ªqll£ßÇ8ÊqŽt¬£ïˆÇ<êq|ì£ÿÈ@ r„,¤!‰ÈD*r‘Œl¤# Iº!ù ,)  · Ž$œÂ©®géŽl¬ ï+§qíʼ^ò2Ÿi aÅÕQ”T.›ª%€ÈµDCd0¸* &ÔhDNƒÄà„CE–@Â02`ÚÓ±ˆXè€V)"z'a?ˆ„* HM4u krxT@5kn ,:¦I©­E"Œ# k­V9* *ŽcdCoOB+¼(QÑÐGÅRÛØU½Ú˜dGÕ@!!ù ,7  ´ Ždœhš–,©¾h+épÊ-ýâ,lÛ1žK·Ž@¢ñH .›N#ôà%H"šDÖB6€éÖhàë˜ ˜ ÒX’–íM‹å[ó)¹«ªñtg0"#szM"q‡ymS‹w#DI"%˜’  #'4š W°t|H} (°¡P$ ˆ‘ÂKËŠÍuТO*¸HÍÎJÒÌÔ¹:Ø/Ö!!ù,F  ¶ Ž$œhŠ AéŽjœ¾¯lÓnÌÊxió4ÄIô‹á„-€j|!‰ÅYp¨\-¥Nj‹ $dzºM"ÁàÑ–“@PPPPÑp¢"ne %?;% ‰Qq%|I,Lz-q —’EŒŽ,y[ƒ…‡¡i<˜~"¦d¨”rtvx´“g'hެ7"]_b’››=&)›*Ì0oѧ¼ÑoIלÐÔØÔ»¢Ý­6;!!ù ,T  À Ždœhš–,™ ‚ж´lt{«BÎò7Ÿi·ŽˆE#9S.™8g †$9ƒÁ¢pAG˜Ó@sJ ޲õ$rœ8 €!ˆ ™":†„81DHT}%{Ox l% €_,“'k2n—%™v‹(ž3Q$œD=„†$ˆ¯Dy‰|~¯¨Enqsuq¦¸"b'³Ç;VYgwUR¾ŸR_Ý6žNÐ*âŽJP«FêæP!!ù+,c  W„Ë,’<°¶9­ÆÒiÆ%_*ãU'šZ¥À ÊÚË–ô#ÏtÜúõ¸Ïp„;Ò”+&¤Ô m° uymfOÎÔ ÝHÛQ×Xv…9DmûV×â§!ù ,q  µ Ždœhz Aé’jŒ¾´,Ó¯ÊÞ¸i«=ßo¥v¼"`˜RŠPÈUÓÉ$œR$ÀxV[€k–´ux«¢ëA0/cÑ“¨°°»o4€>MxL;iXwgL„}"[qGra…$\‡C„k$•yˆ $ ':< $¥–?" ' œ_`* Œ¯6#  e‡QQNŽDJ»ÐÕT_Ö§1ÚzÔÙTÒR!!ù ,€  Ÿ Ž$œhš–쨾hÛªÈ,ýâe`×*–8 Dº 1 — Ò—¼‘H£W=•(EŽöó’ÃX÷tG@׋ÈH2ʼnDò(LË4%hj\]‚ikU‡„&l1gˆ…ЉI‹–(€V#ƒ–›Œ.s˜’—¤S)›6§†ª™<¥²¶r­µ¹sœ¶¾¹¬š0º¸ÀT©½U6!!ù ,Ž  Ÿ Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒ‡0r$\ˆ,”'X…# ‰$ ' qS2.'ceƒ=€@A¬¤»r·8¶»q˜º¾“Ã?{õr!!ù,œ W ÿ Ždižhª®§¼ Ïlmßø8ï{îÿ?žP,UBáqÉ$yÍ(&{U_Ò,îÙÓzW\Úw| ÃÈh’;:(†d0ØXFˆCaBp(| &t†€9kDm;#0 0Ž$/t/$0¡ˆ[V\$n‹ ¥" Ž%¤­ p#"Ëk±¤8Ä%Ë& # ž¡­6IWÕç5 /ç/Î)™ &®fÕ+ P¸  Æ9²©Ø!ƒ„ %lÂwƒ ,I¹P¸Iá}íFXX† EtÔ0¾¦ àÀ¸x#*]P/@½#kÖIJvbAi¦`Ч0Å&LrVãi‚B€“C…’£§"†¤êfȨ–цI$, ©,·žÀÙ4ᮆÒ)@J®€©X0v ë²|a0ŽÅ[n˜šÈôâî\¼Ô&TÕU°Æ3 —Ôj‘ â74ðI@Àdr"„2Ô¶A‰ášæ/M3.l§ÉªD7™Ã¾½ž…G•*Ä¿ OÞd9ó%9C!ù,å  e Ž$œ(*¤e;¦0ìºqÌ­jŸx¹Ÿ«[ïõC ‰Eá±dIÞ3ÕŒ=¡ÑkT9Üj™²iRðMް©¸:§×ÕZ¹8ÊÅf<]ˆù;u€6‚qm„wKY|~R‹1q‚6!!ù,ó  ¶ Ž$œhª–쨦ÂÚ²o}Î4lx¹¿"Ãmö“ yDU¬¶Š§Xù´-QMŠIGàÑà¿¢†dÜDRï©Ý(°Efä·AD.;Wzsm\S†>fS‰x‘r‡&5ƒg'š Šo6S#¥n™h ˜‹š$G±:Lš— “y«`cfZ=¨EÎÏ¿]ÑPKѸ¢@Øp)ؾPßÇÜf!!ù,  U„ËÝ ‘›KÄ;½‘n®xšHJâ“+Û¾LëšœÊ èï9Ù€:¢ÌøBŠ,´J²ÙŽ Gê3ÆN±Uî5W¤jm;ëJ‰2§½ÑìOíA{ !ù ,  ½ Ž$œè)¤géŽlœ¾/»Êíâ²^ò1ŸÉ†€(Q„œ-›¨% p#:‡ÂdxpGàMT@ PðT…Q†‘!À0yÕÍÜ¡: 'k€"g)„P- 'ƒ…)yQ+jwŽ%˜š@ %©£¥%t¢€ '"‹¹ª6d( }±¸™m  q'Ô£O×FŽzÚlªURÛábQK›<ã†ÝP!!ù ,  _ºÜñ0ÆF™¼OÔ}ÞöŽ(‘eà™¨eN­òÂñ ŲÚÑ­ýà_(Zéˆ>¤M9cš4¸L31ž¨ËF¡@ ½‚b½ºÄ©éyœ­%±eÝ«î½ÝmûNêdÑ_ !ù2,- H ÿ ŽdižhªŽAë¾­¬tm£pîÞ|¯ê:Ÿpˆ½d0¢ò4¶–ÐU3=åôU=YíöÙ-}%b rV&}ÃÄ1Ð8DƒÈÁDpJ #M=rl x- $}$ƒ"Ÿ{µä„9(HÒ*°4F¹ðM‹kaå왿dÀ5Ó{=¤· XÅMöix”ž)ù¥à ºÀàj \¶YLÁ½ìªÇÈñÌk'è†>w¶G02(Ûòˆ@V^Æœ{âŽl1¼ŽíBãÛ„ÐÒ©%/çBñ®‚·- ˜N„’{m¨ö/(¨’Î’1ñÄò—g œÌ£&~#k|Àap5}¶ôÊáÉÇSÏ”ñHßJ&:ÂåsïÈQ6|‚r„Âûæ;Ÿ H×ó§O}"`¾7©¾ö·¿ƒÐ†!ùŒ, ,±@ÿ„©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä"f€L*—̦ó J§ÔªõŠÍj·Ü®÷ ‹§’±ùŒN«×ì¶û _–ãôºýŽÏë÷äÿ(8H¨7Wˆ˜¨¸È¨xØ)9IÙõX‰™©¹éèÇù *êv9jzŠšúTªÚêúšÉ ;K[+(k›«»Û†Ëû ¬å+\l|œDŒ¼Ìœ«Ü ú,]m½I}­½Ý˜Íý èN^^7nž®ž†¾îþné ?OoÖ^Ÿ¯dÄßïÿ0 À <ˆ0¡Â…;8|"É+*ŒøP@D‹À;z,‚1d€$Kš¬Q£È“,[º,!ãË™4kVˆ¹Ñ¦Î<ªŒÉ3¨P—)CjŠ4iGœ•:}Š0âÏœP«ZõÇôáÕ­\…duØ5¬ØLUŽ=‹Æ×‘iÛº5±ö­Ü¹¤®¤‹7/…¢wõúý« #NÀ„ Ç-Œ8ïW‰Ïåұ䶇'[[ù²f«1§nþ\53èÑB!Ë$:¨èÔ¬_f=Ú:¶kŸƒeÛ>¹ú¶îŠFOïþÍû+ðá !ùI, L¨@ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ÈdÊh6 ¨‹3Q™Sè‹8°‚€i˜ÄIfК(ê uX \Rõ„‘9íbà9ƒ¸§={ïdÿ¼Ø{ï>Åðf ü×nŸ¾üØÊ?ÏuôÒk]xàÕƒM}öWë÷Ì+N#ø]ÿ=ùÓŽþÖ!!ù6, lø@ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ& "1Š'Š$Š#Š˜ )Š˜¢£"£¢%  %Š%¶Z¨¨ƒ½µ#ž™ o " Šª$§#‘%’$   …̘Ò % ‚ÒÖØ$ÚÜ€úûG…"¼JÁ …j=Š8Mª$âR¯åLœŠ– "‰„Dn”³DQ ×^èÿü &L€b£Èj³LØGh V/@µ{ÛH4xÐëÑ9‹D¬ë5¡m¢d’¸æ³b>~X³ö(‚€€¤0N= ÀÀp&,A)€¥È5@Ð% p—ŽPÀ—ïúòØ ¯6d|KMÀ ‚`  °«I-…œL¿€YL.‚ Í\#!΃ Qœ @Ïœ@W :€Ç&Hâ\’ç™Ïˆ=¶XÜUÜ#´éÖʽ; \`ãÉ õÓ3¸#ìhû¶)í#eK€v(¯_*´U&3òîª"вÎX#àAÚè…Âÿ_ø-ärD]ÐFkè¡€“N<‰pÍ5‰€Ï(ùçÙ ¸Ô—Â9:‰°@8#) M‡6ÔUÞÕh£ âcˆ §dPJ#­µÐoµ3B%¬x@€Å÷c°à ´¸GŒ"ÑBQ‘•t SªÀK”&ãŽjlUá –¡uÍ2Ò‡ºö.kž€â ר%\õ, gvAÝhè¡,pÁ¢€- #И->’À7ê‰À^CXùŒ""¦–TkÛ‘À`R à©ùÉÒLZzâ.~rΪ&œJ&[ ‘°N­f´ì{’Hy×Xp 7tžSj %®P¬P™¾¤HÿDÉ.K¨¤ˆvËÏd¢ ®)ÊGLº^¯—ÉiÕéH$ /óæ§ê ‡™pQ€†40(´"¸¯ §6xåƒ$àB ªÐ&m¶ÕiA!@g[Nª­ Ó ê™€•,ÆÛz«²w´€µÎ ‰TJBjV»i¢€zö—$ð‚^! ÷Œê aRK™ Èøç!´HR’½X½ ”'˜YÂ%A›AT/F†¼€p–’š4t®˜o Ÿ8k{†fØŒí¡º+×½Ï5å(ÀÃ0ÄlBj& ¹.áò@¼”T™6"‚8´¾û‰ 7Ý"àð!…X0˜ÛGµ 7`6ÿ­q}dÛ_#»ï©ÑIKÖÐò¬vÉe¢þªÅ°>7·v÷އÞzÒaß`@Tà”ß\8&D@ºôœr c¦Šë¥&¬ó¥–"pIp_~!õ íÚM¯¢?ž…°4ño&KÖ t^"á;‚ŒºµØ5÷¶ü.J@9èä»êAxœz ÌUš‰ ]WQ\Lã€Wl÷ÓTÎLP=¢u9‚8>Â=Pâ@›ûBÒÈE‚òU }œ‚($1ÔÅï`Ú*›úX6x ïs[f"¿¯É‚€L¢"0 €#MÔÆšØ1ø­"²ÙãÚŶÄ \£Hѽvȯÿjz%ø×ÒøŠ<Í`,AÂ^Ȱí Ë€š×N‘±"¢lcXÂ_žLðCåÌdû#å”ÈH6 @\è@Ü ®è?u!Ñ„ŸI@”áu¤ÎËCÊV•àvk˜Rè…ñå*“ÊÞeÔ°Œè¯¦Èœ8PçÊYø3‘÷7¹«”wuò¥ÉÌ30©Ð"Š'Êþݪ±ÒŠ<ÄÐÈ>WÓ¥ÐΆWþÉ]üË’.3g 8®`Ž ƒá9x7†ÖØ2,ÑÉ‘9FA©kƒŒ0õ42ôi,¢(ýIÏf:4 ÐøÈŠ–9ÉâqDvßhqŠdP¥­ÿˆoŸ GYr!iËY EškH³ +\Á}è(”ÖÈ µô ‚pM~ê-ê Q s‚S ”M‹“44`zùé%JU1L´{ð¢AÌ c–¤%à 8Y€*àÕ\‚›˜é”f´RÍô™qQƒ¸Ô0Æ1YÍJ19 α°/+ò"søjÔ¼5¸g .Ñ<Ñ 5©‡‚&¢®¡Æ7À‰ÄI‚¾(g°ÀІ¢3oòók‡­ªjÁ°Öd<³…AL°°µQHª‡¾b‡SP!É’à(Ñ]­z¥ðÚnB­¢‹hïðp`;¸%A`t‚ePŽ$ nWÑŠWÄ¡%ÈK¹S°¤¹ƒS„&–ô¢¼ xÅ0 ìÂiˆ «¯ÆQEðŽ`)!$<ä!"S%½ë±ŒgLãÛøÆ8αŽwÌãûøÇ@²‡Lä"ùÈHN²’—Ìä&;ùÉP޲”§Lå*[ùÊXβ–·Ìå.{ùË`³˜ÇLæ2›ùÌhN³š×Ìæ6w 'Š(€ è†mتH §ºÙ§¡UxY³ #† šÚ¤ Èÿð&ÐDkÈ@ü,HKú]"  pØ>’¦tdèì‹SJ ×°sð\#ÀÒ@0À`܃…òyñäŸópEz¬¦ ÀxTÏ4ZrÎ4Ð*<vYyi¤€bǹ’Â(O s•{n©G½—¿w^áp/£GmWNÊ&9Åà€q øoG@ã‚‚-À!"3¢ƒWÇ ÿU; UP—†4²p B åõ³$J‚ àq`!§fRw`ÒдH>0qòÖr±c€«G/& †—T$°Vq:·3mHc°{7(ÀG<è¦÷kä“S,4À|5à  ‡˜À‡ŸÒ?†ˆˆ!d¤žàp4ðƒHð‚Ýô ô!DùP Õq*eh‚G?lµUØqT¥‡T‡ÿ¸z×€€™bb †)PwS3r¸Øu¶(ŽÆ+Ú€‚Àp~Ò'‚~X|ùÄ-8=— ɀƘ °ÃóŒÓHP¸Äƒ9ÀwQ9²Ñ…P)ž4¤+·PŠ´ð€v4vÄV­±ƒ'p*GÈ[²h>Ýô[ËÈC½µ‹x@‡8÷‹nÂY|RÖ(ÃG‚YUPÇÈ‚²Wm¡¥X%RY y—ЃãVg(×ww”] ²"2cˆ}LP޲‘’$ù'ƒ”B§2P2‰P˜ lß%¡v¯q&Ð9ù$÷8%Ái©Á +2Pé"j×Ò—ÐlK¹uMÉ{IGuRŽCm}hv‰Ð×ËW‘ƒh‹:’p)â™ñšlR‚MW’á•"Ž:ÒJ¹Žás—á´`ºVPñU›5v§R^²Ñ“Ë5R‰i«Ò˜#ŠÀ÷”:‚”E•„—)½¨™Ø ŒGe‡fH©â,á—Å|.ÐŒÕf‹Aå#Fä™M›e™çÖ•è–K—(é6íðQÿÈVö8œ’¨ ö—(@©wŽ…ùœˆ;œ«±"E‰:“‚%±‚ÝÙYä Œ‰Yr–8Š8¡žsCQn·AÂG9´Rø‚kIs1ê`©…Ögnü©~—n#kžð[df)p*"yŠwŠšK$1ŠbBM´1<é"‹ä„h¹H|Â¥{a_Ø¡fð:Z¸‡O›IЉ)B‘4z‹¥x~ÕQEÚQîÉ#'ù@#t> slŠ{ŠMKµ;út= „º ¤½É‰ç3šz¤ Z~"I Ã’ âK·֚8Ã7(!‹¡ˆ‡Àø¦ĞƗ\bêqÿtE>Ɔž* W|Ô—W ÚifÓ àO£9é§Àt3Е¨Ù¸ž>w:ÛÀŸÁÐȬ)âR-P¨{g‰ý ¼ Fò:3„v!œÚ0ÏÐ/#…œ´`a®Ð%z,LÜHaT§¬ç®"ŠÏ"†-zSüsa©Jµ% ’´3cwm¢à)p† ù€ÛW-.@rÞU|G!~9w*kzù˜½ 0«]Hž·‰àþÙ­¤áúÒ$²ŸD~&`±ò°°â—=÷ š 5q°œÖ]аÔ)©¸¦©ÿÁY*°"‘:8¤Z°Ë )²3‡É°˜à°Ìpph,¢Æ ËQ|ZØ ‚5Ä©0¶Ojë( A£·áÀ·Ë¦š„:—ní/€ã¿îàŽô 0.Géßñ;­¾õÞÛx¬ªþõ9ï±›MŽñ(oG¬<ã÷îzÎñIëÏc‹¿yÔ8Ÿì@ù$o5¡sÐîŠL¾³á®˜m.ñDMp> ¾ yÚsÿñá_,pP1@¡lò¹‘ê”5Z¢O2æ(ðôÓƒ»ÅÙ]¬íI@ñ Ã8K·Ó^'ÞNâ@Oé¯A”M‚Xà6]ÐdŸ×@Oe¦JÏïsöÄ`¦’ò§ä¦ÍA@ÍVb„jvq ·eäÒ´]ò/àøÏó"ê§QÍSÆÌ ¼ûIñ-B‘Ñ.#a‡81÷C½0ƒä œ*ìo\Ú fYöâ÷“ÂÛÙµFMGo헜ɗœ‹äÂ)Ž å 0RAÊÓo§ rþ´Û0Ыr¬Õ!¬Ò°¹3·š]¯×¸J­Îê#ò)^¬ÕФunë-€ë?`±0Zè.ÿ²ÐLÁ"ŠQð ¢3 …Òµ­²ãÏ56Hi•È µ `P¿àÐ1UE–@™ÝJ²¨bB p£æ5»í~Ããò9½n¿ãmˆX€ß­YTmñ8Ô4¨&¢ 5J&È)$H") 4Â4 ÑMÜö5>ŠdNÖœªvU®¡mà5åñ"\böÑÒxÔ0øÅ<,ÈÄs1;÷ÔH]ll¼~68_4Ðlý‰PHHd`^¨g¨Ñ\Mh‹úôqŠ9C˜Uã%p Á‚",ˆÃ¯ ¼Øp€[0% €ŒFƒ$ °Q†˜ÿ4Ó'A (Ø„¢ƒ ¸ Ñ)<q†ɪ25~r9C€mnåÙ•0Nƒb\èPk^@Ψ´c‚ªÏ µ@Öl5ŽJ¤ÑƒaBŒ `l$€  FÔ© ‚eÑ(€È &¾5(ôÉ;u2åÊ–/cάy3‘¥8SFó jЦO£¶QpO£Íüêšz6íÚ¶oãæU¥йWJxP©¿#—ãb V÷ªü 29õêÖ¯cŸS¤QÛìC¦!~Ǹ÷ò¿‹t— Œ?,æßÃ/>ý*ºJ×ϯÙÂÉ4Àœ~X fFÿ‚ 2Ø ƒB!e ºH òC €ÒG†›yr¡‡†¬'¡‰'¢˜¢Š+²Ø¢‹/£Œ3ÒX£7☣Ž;òØ£?¤CY¤‘G"™¤’K2Ù¤“OB¥”SRYe|Û‘x+äBáiSäLU$€wtôÑbV²Ùæ•}dor4`ÁUjíT j:$ uÞi2[¶b”ë”@ØxøÑ6Å™t(Òîå™g<禦›&ד0"I<á5bI„ÚHê{6ˆFšmLð0ˆ}8ùI'§r¬°µ¡(*h`pÀœÔ0°¬¿Àÿœ_p°l³s" €·ßÎìˆWÇ}6ã4à:gÆ ¯¼³yJÇ?ôJs{Ð ÷æ[QdU@…¦—ôýC€ž\‡'̱ęÕ;‡_î¶qÍk"\d«L®¬sx" hp ÍÙ@|¤Ö"ɺ1ðJŽq¼¦¿ð GO\´Ñk.gÙ«1U GºÇdQ°ç’Œ ŠñLÍ# ÁHÄéW7çzH~BÍ4É&GÓ]7CÃ|¤Rk”Ž'eð ÒßYüÓpÕ"ÇhÞT[*®àX@y!ÀŠâzöé…ÿ È5̽Æø¤·Ý«³îFÒtˆ†+*‚˜±›±“ĘYø7$Œ_}0 wF4zbL혣CÄ`¬9CòªÛÝ­zë×cOºguÜ '™¯W4t9àG=„1[­´ãpxBXü"¸f†_À.oC ºÒï%Sé}G&vpê²g@ìá ÿà 0á»(fc"X ›*ં°ž„·O°~I` 5Ibwø8󨀨MgP`Ã܆YƒP ë#ÿøD1€p%lJgp¦,r–,ÔÕ^Fàj•PÜ%¤J@ÆM"SX=œƒ|&$¢` Z à N!SCð#^Ùš„pŠ´À?*8…\Ž˜4ø¢/Ékq¢œ<“iÏ`uÒ ‘`¨Ç>h“ûäˆ?O) [´r€Ì{DXÈqꙺ  :QÀNúÛ §KñO†íà€ò®_\¸@µGaìò¢ÔŠ€ôJâû®–†©Ê $’ SÙ@p‘D5• éýSºq ®w`<°ÅÀFiÛojpá{r‰¥Z¿$ [Ìr»`9iQ‹9OÀ–¶ø,p} âjí˜wì¢4ÿ¯n{%aÞŒ€˜Îi6½}Åà˜žÆéÀ¶\×:ºE6êÅô¢ †ƒ3Š«iGÙ~‘ƒÆhÐ18|ì±6Íà:r™Uai@¥KF¼pFÄù³ÇÐY\]zUUDƒ(C¸Ó¢Óæ7tôÖ›¶³%–VI·MjE­£SLæ„ 2zÀ£h1å{@ N%ˆöþÔ†ÒîVí`+¦'LL®¬Ñb“H[:„[ܸgÖ÷‘ °!p³°øbÍ G1ô¸ƒ©Öp#*@Ê- ³,·A~÷œ0&FUØ]³çYˆ¸XÑ[7ÔZâÎõâÀ”Ù€ÿ©ª1· V »C(Ý×”2µc…{cˆú´hDvËITŠïMëhuÈ>„k¨™£™¦®f-tü½ ÿh¦ÌaÊô!(à‚ÿBLzw®RÒÔÑntjö‘®¢ .…ù»xó´?Þ %ˆº ¶Põ8ôîíŽû(Ƚۂ”&'*ú#Ž~ƒ—'ÅœQä{M˜–HB¶ Äà4H¤L`?™I’4²âIê$g<¡fÀdƒH)Àn Û0îdRÒ†KÄO*åSÞSBåTReUZÿåUbeVjåVreWzåW‚eXŠåX’eYšåYÚFJÖ‡…ÌÈí\Ò_`‡'HdßT@ÐZ¦%œÈ‰¹ØÉŠ„¸ØüÁXèÙ‰¨ÅŒ¥“-rp±$HeÂèìÀ]®ÁÌLX—úð ,Pü%_ÒêÁ”¹¢•I–ù€jvYgõe"2]ÃèÔÁ4¾AR±qõœùË ™f_¢ãà™žmKŸýLK" rF!š·(Õæ&5n¡¬[øûÁlÒAwçi\£ŒZD‹„ù˜dìÆF¤L&Ýdçè&wîb_ùådÈÿcyrjJÝvA¨Çnö_dšAOƇäc0ÁF¨@.­O1–Dhfb, @NL€¸æ0d ï,Æ×´ÂDŽÀÄÌ€HF¶µ‚, ÀÀ±¡„ÊßUù‰3ü#@¨d"¥€( _€ºˆq›ºí'mvd~D‚4AqY^DÈåïE0¸Ý ¶c& ¨h•g dðc µ€#0YpÄ"xFœgÀUÁÝ\Q4›ABÀÁip¬ÿ©@’Þ ¦`’*©fœçðèMá`àP LòMR(ÕÇñ⢠HÍéƒD Õ6÷”Pd pÿM €_ˆ’_D@-€_°ÆH’SZÔ”†%tÂaZUÚQÑ ü#y£ÎBEÍ“6êehÓ.N_-ÝÎ Ô‰AæmªÈé‡ãí^@¤"#!D¦SµŽñ˜š Þg’d~ºÔÖ@» Œ[n®6)²6«e<+éÑß1jÞM]÷ôÝ%i†n+|u+³¢Áù!1k(†­ù  ÉÆ5쎺ˆ€ÀÕB»ðÏ|!ÀëLÀ ±þNzQ.ÊM©í+hô«çÍÄéqD¯¹çèÉl•…æ¸8(òÔ'n”ÀT@¾ôS/á.ªÀ(‹ø\ ¨À=4Sì\±ƒ{|ÿçDÏð…±F\NÎAž„¥$ˆÉfUqÖ€ þ‘¨€ ¶,Åh $0-dLÀ™Ä­DE_@&,X Í}ÔÃ>â<ù-ø QÞàš¦€Ït–{xl\Àkhl ðfœ.ÿ]’J@ã:”,¾Š¦Å"!ÂÚ\@@¶ídôküEÓü 8Üß.jªö0£uVi~ÐÄ\4‚l„«¤…^MlYª‚¨»4íŸàŸ©ÍÀˆnAÌÏÇÂÒ´DQø ùCÐ V®<µAuÎU ܇¶nA@ۺ̃ZDÀ¦1–.jðBHkçÁkßÁŽ·u8@f¶ZoN4q£ƒ,ñngB¦4ÀéeÂ.S£J+Œ k~©˜ÿi&ŒŽ—I‚xŽËi·djÏË -k+öÆNù‚f+ë¼bu›mRo† D@ ¨mB›®È¢áñA#B¿ yõyp¸ ‹²ìÙ³È@´0g i_@'·(²ËïBc¥vφ×¼:CoÅDCª8%eSxxMÔŸœ®Ômì’+r@qzÁz¢+$sÖVËî8Uk¥ëÝFˆ¼Òëªlm854°,¹Ü‹¼/&´LÃ=…bQ(,û³  ÐlÏÔv°énð8kOh…΂Éà„ʰ ÌV@ZÄô/ÿnÈZ2¤ElQŒ(ŠÚhÄŠë¶ÝÙŒÿø‰Sá#‰’Qk7€_Ð7@·÷`šÂÈèüÁcŸ…". dh–Áª«Eª•¤V›AxÅ`¬ÐôTº.¶ °DYPëîfü‚»8ÃO£^´Ù€™1|êò^Ã]‡b;MÇ•–I–ÖA¿â/°¡›¨s„Éž0’Öˆºó0…Èìp â•»á†Â¬CGßU Àõ ÁÈ+žùÆð5[¯qq¨Í.±`hLQ…:<[@aZójª#\wX<.šààÀ7ƒ3 (’¥\:²k±ÌVÄ€`ÜÃM­;G®0hùÁw·e"@/9D‚’s4ÿ÷™ø…ÀD:ÕÂþ%A-0…€‹ž†©þª¶ûŠw9Çù ñi\ÿpܤ"Žìî­PÓˆ§b”Øëb%DL ÌÖ ´€°XÔÁj 8»Œ;€0}r%tD#°"+Pž­6]®œ†S¼l@‰. \æ…˜‹^¬ËwÛ¦„(ÀÑͳð À!µ@0&ôïÇd~¬_ƒbxèž5™ÿØí}(€¼aávúÅé–3ûIDÿV†)ùE`=¸E¬—7|'<_Ó§>8CuK/ºzô+î ñÛÎï<ÀÓ•\¶²u˜ÍïŠx«K)ÎÐt†0í=D(Q\AÁ³;ÞIÿtŸ²"X”fIV9'Ì ñÕЦ”DÉé†ÄÒE6äħD ¢³ Š˜Æ$h¼‹¢ÄVC)xM•îw—byéˆ1ŽýH`ÐÓÃÃ`qPØ`@Ñæ‡‡P0•Àw±X2@x¢óU2¨XZ”{ÂyŠñ…ð³V¤à´PÛ9’£óÊe æ°A«cØã,=M=íZdóPb3[ ]"vu² 1]LÄp|²¼õžÈ]â› :XwòCr‚"<üˆÀŠÚ‘:”Ä3ñC]ÀENõ;1oÛ9bHìt¦[‰  ÿÐ(g’9×ìü€P-f~ –¨„ŒNâ8P ÇÆM <0ƒÏÃ@S­:Ñ"‚wÒ²L˜Æé_DÐ ¬‰#iìWdY³˜eº}û6êÔ2`³µ+¦,xÓRè=Áç*‘rç^düÓàTŽO3 -nKN¬Æ £Ä4°ÚÂ$’¤³Šp[‚k›vúÜNtÈf¥*Š¢Õ\›Ât§ë0èLGBwã¹ íÏÊE8Q$-ˆ¬ƒÿ÷o[ûb›9Ã&T0SãIÖ ;M€¤-€GY?P&ØÙ–l d p…r'X£ <ñ€](‡œl­èuô2ùnƒØ`N'¯40ì4j'ê8©ºÈÒvA KéÓäÕ{cY-( ‹Ðœ¥tjÆNÂ]íV¿ßš Ü^ÉH.î pu.CDìÐ eÄÀfíÒGê` ®£:`ÀA·HÄ@U@Š•vq ×M‚ 8…þQ6à§àÝ6P»¥@ªû›¬1Á\ WÇQ€`DëPC¤A ^Ø&øTC>Ò«¢}"ÃV¨O6ðÓõèE’oÿ°A;¼¾·Á~ A}uh@9å’N¤§P£s,@ ªÎU|›È¦!8”cCPž NqÁ4€pÚÃìÐ8Ü¡º@$mÄh¥¼I"H@èJ üÁoqòh`ôTØ"On0~8ƒ‹.óŒ ¼²bÎiÑzø_¸È9 áA'°“8X$M"ðÎvôÊC@¬˜Â8æd¢')RƒŠV¬¦|9`f¦zòº €&aLñ-‚¤y€. Ò‹m½ØS wB>@°ƒ!Ÿ $¡…$Àe„_ÃOZ 5@di2àžAÊUþÊN ¨ûtbi1К7^†H~$ÿ•|ˆI$AÑ`Ú;xÀŽ6\FŠa±g×€ ]€`Exc+Sa Là ØNWlš À„>¨Ò?Tr0À•é€õC€&Ò~H¢:!UÅM2ñÅ£ 5j½Ñºæ=kªKZŠÀÒ.Ð*q³B€ã íXUGøª†ØÙ @*,ÅÂ9.ôt€€ƒú¹Q,µ€YJýêID³üÁSÅ*u°ž`.!å ¾+,胫¦­ð: XÐ&~¹­ˆ©<0ãZ \9 3¸nqžºÒJÜäJÃVÊÅ› Ýè¹pÿÉ‚(-ã´BžLºÜ.NãÒîòª4-°¨3¨)ÞôꀺÑ-¬zß›\ö¾E–VýÁñî²IøêWfŸ€å~7Ö"óÒÂøï{CÆ]÷xÁ^Cðo² FÃ𠜈ƒ/Œáî.ÃÀup{ŸËáËD¾oià«xÅðE/‹×ŠÎ)WÁ/®1,HlãëxÇp1‰KCbÈo°vQC"'V¹àJòc`äKyÊT®²•¯Œå,kyË\î²—¿ æ0‹yÌd.³™ÏŒæ4«yÍln³›ß ç8ËyÎt®³ïŒç<ëyÏ|ÿ è@Ǥ¿ŒÊð **“ ÿƒu¬ÿ éCÛÀØë£§¬¥ Ä6 ð-Ë,p-t5 FuÔÜÔÁÞT¼z@¢ŒPÇ6}j2¦:šnö(˜@\IgYˆ!€¼ÒÜrŒ€péXn€®+(hÃy”Ž-Ôœa€ä–ÙÞ6·+LÚÒy¾„‹T ‹p©™ ~Q$ì©™·Lïpi€u¢IotÑ2§€y¢_‡N&eå!àt+ÙÓ’‰!À 2i»Ù¹ípd×ß8¶!þ‡hüÒˆ@:Ù¥ØÉ¿[ñ•pñ€l ­öN«†8À ,U.˜¦¡  „ –M(ÿàº9 ¯îå8@tb!1‰IÄŒK…/8Æpɸ†F-”D"Îð€YiÑq™¤}Ðű€û&Æ÷ݳT眺k·,ÐpO ˜;'‰ÇMž^ë½Ka‹O2À*ÌXâíÓ •b]>æðR;x@< ˆ€Ѐ°7ÀÙçyóÚ©‘ñ £Þª§E'?Wió%¨€LKòSX˜Îìž¶ëîï8‡a?óvEvûÔˆ5œ¾x,tváb`Ìbõ —5hõbß"`d €”†IAPqˆAq@ àÿD:”ìwlr@qyø ”æ€iØe×z'ð@ƒßðPŸòx ”&JˆƒXˆ@,"Wq€»ˆ‚˜†Ê( 6 ~䆆:3ƒ¢Q:¥.w(b Jÿ:8+Ó¡: GØ;ÈÇ%à"(°{Â}·œ5V $«ñ‹AÕS–F&”„°Ð}ÿe…Y•¸äFì— ÇqiÈ‘p `H(àjTf§Y"‹p†xÔ0iâlÇA Þ(Š·*ôç§§ð¬€EöH.ÀB0l€Q€!wE“&‰}¸‹‚Ve²Zè"`O7h1¤2| r „NaCu¥†nñs´° O5ôG`0:‚’á$ƒ&;ä‘Pyv 2ŽPT±Åa÷èW Þ„¢àÇÒãvšÇ­Â…§å&‚J ÿ~X“æ †ß2r¢Ai^H"] ç2þ )•æ7eXxÆz‡ ‡ ÖÈ@i@¤2"“Ëø‘ÔQ‹½2h½¸¶0Bb €‘† ˆOÍòIËà—‹ÐŒûUåX Z)T]&ѽñ–•,•(s{[a•Õ@q g”"áu: rãõ79É~Ùe–­@iPh”5 ‹¶y –ÎS3@quÀ ÀRÞ¨}£(¹ùVd ²Ír€K%>»pwY’MÀó 7„-0Y4˜Ì†x1à4Ò‰sN“íYƒã±³œˆQ™úÅ0šDÐÿ¥9 vÔa’Iå2©€4€µQÓК ~eŽƒ¥‰¸ã± †Ýàlqy9·GZ{ ¼‚ë—±²›ÉE׸4•› ¢'×G=‘)¯dNpç" ÒB‹!YÀ”ÔpxãLä±FÞAé±Pç1Y< W 7™a °n¾IâæšD0 Ô€vxrp~ñ ¦îp¸Ó×г¦&P›%ø€‚†ç â'9ЇÓ¢5 yl(Û6¨  Ì·‰øÈ¢Å™U PÎ&q—fæÐ‰µ¨,s> y3dNИ倣³(„ÿšÚc '‡ðϧž>´[k"‘§rh²d ô!C@4Û§.öbð¦þ©'&—×´€ˆî@–@œIÈ·†÷þ÷P&ž·{ZÙá~3€pBœ{È `Tè%ÄéqWÇP›j®ÅÁŸ`ð¬5Úc–¤#¯Ø)óHrª Ç13±;ÅÚA„xãnµên•¹|Cð˜i!Z:‘ù _n‚°¤yÉ 8iÏy[¨}µ‰¥öàlÂI[™­ê$[›IS0Z¹8ƒ*Л\éqh8’ì…>Û.«$gýI2Hê Ë@˰`?ÿDdF¾C %I ¯S²!×FKC5ëá>ÍSlÓ ±ïµ„x©)=F{­íPqû }X”e€­¨Y&"‡{>°y\µ#àp„:ë\t×Ç Jf'”+ìÚ.À²£Ø?¾é§S1ûÉ N€™q)_a­40“*ô+N†å´€Sb@eá&{•º™[ƒJ±¯“w^g«^) °rð´w'"wv  v@·°‡è¡­Ö¸Ïð —€L`{ ©E¸ 2ic{¤~ÐóŸ°jµÇ¶w~ ‘àTT§¸ÄÝËP9`_±[ ` cAv]‘°x­u Îg&ÿ2´5ÔK€ž6'Š¿3™v0ÉD77 K`¾HäG"x-TñD@»Î`»éõêkXi(·2!(Y°¡'ñ€Gsý0C”Æ¿;p·Íñ½5Qq¶ åç¹€ÃQCœó· @ZºàÁ×j¸V3i ÐŽÜKÄM) ¹Ûg*ùJ8š¾¢L-bOðkK{ôJBY ºÔ"¼Ô,oÓФ‹ÀL*)\üJËônÎä ³zue[»oxaÏ Ê.}8‰˜VÆD§øø”Äë²x[‡lH‚ú1ie†ÀJ´vˆ†,Û¶Õ6P’˜“†™ÌÁ~Ükœ\ÿq¨´yFÅ.‚£6¦@ÅS£&p €Cº¬±•k+ÈTNU‹Y²%çdLzºôPj\¥&»“L£U¦6ýL ,^z¼nÙ.Ùvì‰IU›j;­úP€àÄv+É0ì°ŒDp5"µ™*[˜„!Ú®™F‰zÅ21…æPìPЇ©¥…h‚õÁ³u‹¯q–ÆFÍ[jÍÝ¥Q³Í%¦-œÐ {š­g­&R,^ÖåE…+¦B kÄ’Ú\ç°] ÿi±,ýf„vª‹`‰†Çû•l\B‡Ø&¿Í剼 Ó°p ÀËAmÔ Æ¥4ÝkºbGAi+}ÔÿQ-Õa–ÔQ †VÊS­Õ[cÍÕ`@a­/üÕemÖgÖi­ÖkÍÖmíÖo ×q-×sM×um×w×y­×{Í×}í× Ø-؃Í.2b÷¹ràÕT†»c¦1u‚.âÑv ŒEœPÙqípƒe—´àî ùJ ÇæÔk²Ì]ßõjC"kŒåÚ5pk§0Sp“Ž ½ökNòUÂFl ‹=e-f²¤p’K§AÚópÎå“Ó_~mn©äÜw¥‡ƒ©Ý9Þ]h¯}ÌJ¥o_œ9ùVÅÀöU>l$‰ Æ-eÈ fRPÔÿ΀ߛ•Y¼’MI%¯*×&‡rt³rìÀô˧$ r¾IÔCN7P¿›mE «uá¾P¿K·Au^t©`¾FduQ„±”yÓ`Öß^Æ ôm¦–3" ßfbaªPÀ}Š¥tÎr¯0„CðxûÅávÀ±,Éx. á"yvŒÁ1þe3Þe¡Ô.ZN2•Ú–†[„-5Ò™K f¤£Õ@žªªU ¤êܸr´9Šã€à¹|xçv}¾jleæÆˆ 3Žp~‡Šmø¢~½ÚŠ„®©FªhŒ@FwÎ¥–ÛΰÊ-rä˜jœì1R<±êåÿ°éûÆ«ç½ óŠ2àSwÍ£ÕàÛó*õ„Ós¤•QKåç_< ·Ž}˜Šƒû3VÕÐ¥`ß/Æ:Âp_A,àdêM¼¢fLõÖ-ø‘djÒo§0ψOÙN `- ¦qË‹í1 rÅ< |v¥^étpP=i‹ÀSSPv×c{^ûx ¢ îTیǨé¹Þ¸ˆºˆÆç­8Œ`ŒC%Œ'cð«Eñ`Œ~n¶XneŸ@-Äï&l0Cr|M‡ò§@,p ­ðÇROî‹‘¨¨hs;ízÿ)/¿ÀÇ"ê§`~íöµ¥K.d׳# ÿµÄžÇ`¯4xß’‡²i©ï2µ¥p’WŸ ¼.'É:*™²¡[Ç/ɾbb`G#o$R^Ä­"ÓIrÐKs_¡Fõlj¢Y¯ñÂŽÓô…"ž÷´ç=jôÅþk>W\×ЮôNz@³xVRN.Œé˜¼Üæ!)˜Õ°ä& |°½°˜Â ÀïÒ–Kxì6éö"Ö24ÀòO«"ýÉU’û 4¤û+#{X°Àåv¾Mí®ø¤Þøcbøö˜ËP‚†ôï4äµ3QG&ŸºEàežªHjžè‰ú_áî)(Áþc!ÝåP“µßöOeÿ<@k®ö M"šª¨Q®WP¥ %.m ¨Oà€¢I&ƒŒ«'”(@4®¤Û*G ò$ «ËÔÌ Ô"L€âžÓëö;>¯ßóW ¦\_ CQƒD XŒ ¢ÓÝÍ ŠB‰KÎC¡ØÞ¢CcÑ„aJèèã ¦…؆àˆË¬í-.aÀ AÊDÀ«Ê §]‹×ϯÃMÀÄÃÑÎnï2P–¶¬ÕSs 4Ò4K—ŠçXÀ‚š·¥An½ý=~>Jê-“aU¡Ø% …” x"¥ ÔCE‚•`·‡Â‹%Š@sá ¢ mÐÿmTá\%X¸õ!ÁKL˜ÕTø* àŠbwZ$X¤LLFŠÈ Lk6ÖC#áIÐ8DH8Šô\ª0ê,VqgA‰©Uˆ`ˆiö,Z³šü»å«¬‚"ÀšPq ÀGHuQз/63ê¡ËÀݼ)îj;·äb¼O|ÑSɲO­´šûÀS¶tDÈu’ª€A­KÛ›Vyˆ5j“„¦ž® 4 u0¤QTк‚L»4f\†²–ëæäÊ—›!Áï­`p«„LIT 8¬ê`2Æ,¥™î?íÑ; í&»Gq]…zt½\9Ë%óüs\ÒpÃæ<*°¶“h´ÿìÕÛvV”0 Ä\sa·x¥‚òiÁW m-ðÌ€f†Sn¼çF0è=¡€8¦‹-ê‡Hs8P@ýY‘š.Š€#7LÛE…@ té¤F}™B7 ·H{C²&D"Vˆ±Ø’™‹aRGV×,2äVBl( ‘*`ô”"VÈw×еÅ>+Ò1aVs¢P§@ š(lXY}–òápaÅUÂbZzé ˆ `€zŠã–p°‚ ,À°!—"<@(€€˜ 0øX~š±á 4ÐÀÎÄc@Œ„pÆ¥»ÿúrkA%8à)¶3DkÔªL›–Ý&¦ùí2 ˜\£Zmk-avl®õ°¼g£Q±ku‘@+…׌a ¦°a¸PôiÕ•ëW²É(£`ö¨ÿIô€­ DpÁD°@’H€I@í¤^§ààX\ÐÁìs4)ˆ¯·MÀaH·ìôëE ÿDštx95¹–oæ€ èúö  >€@Óáñ0L°Ž1À¢ìýEöÛÛYPóªCüÆ=ú¢¨Nö†2Àìtâ`bvPàøË# )È òp—š#x÷½Õ9ÎŽ|$$#ÙÄB¾ÐvE+ZêØ³ƒ8#“œ<ã-8ÙÉ.8cdbëZ×þ(ÉU²²•®|%,c)ËYÒ²–¶¼%.s©Ë]ò²—¾ü%0ƒ)Ìa³˜Æ<&2“©Ìe2³™Î|&4£)ÍiR³šÖ¼f4£H&"Rqƒ˜yÉ4‰ Æ6îæç/²¢Þ,.Žð^00D3ÔÉd3< ºÔô±y„b2 :>4ÀûÀd' ÓÝàò„BAšÐƒtsy3À¡7wÿÇfÂkäA#õpNA¬D\ IRÆC-1P—3 —‡zjÃFDËÂT’U† ƒ…Y~Ä*m h*:À¸¤Í ÓkÉF™¹€ < å´ÅT«šd¬QaU`Ô¤àQ'2¡];(ëLA†­NÕ¦5J†2ð-`róVß!1~ÿ‡o…³@0HB0tŽý­X ¬×Ì…^Àœè_ ¨ß\‰¶€SNXÚ>HŠŒeÙÝp`nÕÞw¨IUÙ†0™Ô¥@nÌ/$˜± ;P Ô Q¨ }LNëTŸ¸­™_CôÕqÈLN‚xD¬E‚aj©‘#¨„ßÝà½P0L€²@Aý‰€ü‰€y Â Z—öAAé ›‘Š lÜ6N×q ܆ÆLt ñ@`¨¡Œ¡ãµTLÒ1N4 d€ÚÆUÁ]°ˆ ˜±[U‰œxÇTÁˆÈÃ6±îÑC G0è›C ÚÚaß%d“…ÿê*ЉÂM@G+Ê+:Ý­ œýûM×ÔL*Ò8m!`‚^⎄›èaÖ‡¬à¡€@@wÍ Ô8„XtÁ9\ÆÍö2š#rí‘!Si ÏqcdÌ^9þ®õœmH¢Xt±ã$".²¡ p pƒˆÏ(ÖA)~Ùîô¨›lñ[ЄÛI¬À†È”P´Ô¤´WûeÑE$rd¡è#1ÞëA 2ÖÌ Z3JÖJ"£Ñ"È@Pˆ´ jãë•¡ãµK0¬H 8’„ÂѺ^]IŠ#‚A„EUeGÿ‡¤áEEÙÔ­bð£¨Ù?>A@ÒÚõűMK¢•Õ&Æ ÜEø1Îa¸¥5Ø£"ä¢îbQ€¤0b‚%Ü(Áß„ã@K¶Õ€UÚèJ ôFv‡NO¦`ð@ÑP¶cµ¬ØZÌ&îä<áRˆ#6^$®Ç$B  GÁkVòA'º‰d\ (žd£¡£&=.äZÖyÜÌ.&aáK@|øf—àåè¥YHŽä0ê#\^椤ˆ%¦ue>jY€Aª\L0ÅÚW¦£¯ìÆC¦¥6hŽà_lÔ ¨aR~ÿ = žlÈ;š`S­“ýF¸àÃÿAIŠÐg¹Œã ÌŒЀÊÕV æ§:Îß¡Af`gš9¦Ù+IVKs¤(’$#²×¸,¦ag0Š$wâ£/¼æ¦9ˆç·PÎäA£ÆAFüÎáM#¿ fÆg†ìH0Øå|æ"’ÄŠ&ôˆÚ_4©ìYÊ`ÂÒõÊ>heÔ'oÔ"TôgÔx •Õ K.rNmL€ùUÜ$X³C8TЧpf§@àãt‹îÀ\!· ¦ ¶ššç÷¡eµœ‡§8–_䊴i*è¾a$XgÕÄÓuhH–ÿ*h§ÙD_¨”h‹bšÍI_y²`´‰®-¥‚ÄÁÈÅc°iÆhfƒÖ&݉n§½TÄì€kdeE€ÄÅÜ^9]·$ g ©&¤ë½Yäæõˆ6@ä[–Njæˆ_á€Ø¡@¥áÀ£žˆÎXË¡úŒÑ<ËÐd¾Š@ŠeA¸2Í¿fÌñ–FѨ ÉËXÛKú%Ž¢Â]@Ÿá§Æt^b¥ Mø«¢=ç˜1,ÂâÌš¤©´^ڠƥP@€ÎÆ&Át«BÌÙDÀY/fR ¬ÐÊ’¤´v$Àß`kÜ€ÃbÌá\À(ÿCgBŽ\ ½Sw9”¯°ÊºžÀ‚9ÆË‹)ŽÌ«8äÁÄ€Oîx]Dt€ï(”*Ö+Ø4O…},S…ëOÈ› xˆ"F§V§Â–PD0Ô3È-0cªêc`ŒéÁ½jC¢´®dOƒÁ°šè“®Ã5_wõ­…ef°B D!LnGÒõ!Ø[Úª@‹íO€ª¬é®cg†Á. E!î|éTájݹ¶Â‡~eýÖȼ] !ìj¡fÕŒôn†ðÖC}ë§©®¼h÷Љm ÛaÔàžöÆ‘öŽ ÷ž/Zh›=lÝ!‘€ÿ…EÒ¯¥hÓÐîe´o¼¯ůÈ̯ÿÆÄ÷ÖC”膨j"äWðÒ—Ë¢©çA›Ð¬øQ—ð-L!+e0¦(° ×÷0 [GR±ŒÒ®rXÒ wÒ]m†¡Þ0)©L 1±1'±/17±?1G±O1W±_1g±o1w±1‡qrð ð—îf`Âøí#!€x@£ É À{@‹ñ U€DA@iÊȬ>Y¨­ó´G?YÛëÇ e€lªAD¥ÎÏBaÁ@i€,×q¸`Otu+¯€xµ¬÷óI¼ÿw˜·Î¾7ÀH€~›÷<-µ^Ñw{@x›A,6o3‡oßßßÑÊ L"À§ìj{ŒeÕ]ß—Á ÜxðA½eWWrAOØégÅQ»YŠvƒyòޝC£@‹Ü\JûD9{ð¨Êh +¶,›ÕQy@Œ"ÆVwi”Ô†äø·UÔxƒ‹  ÎŽ7bØME0ÁCú@­bøw<è,tß]MÉtnžÅÝÉŽ@AˆÊè,$u=Tˆ-Ì·‚V@ê0@*3vQåÁ[–»s?¾q#'ùÌ·Lec®˜sI÷ U¡§ €WoùÈÀÿÊPÑ—³ÌÇA&ŒJ6œÀ™kø¼±Ç_¼ „ýç¼’“>ÊÛë›þYDIÇ·þ­à,0Át¸ud´8šK®pލƒ8ÿÙúì'|Ô"Ôò$ÿçü¯Z;þžƒ@Œdižhª®N0­0YyIlßžw˜“·˜džÈ5Péâqœ,žGì Þ®ªY Ëíz¿à°xL.›§å(H'ÄÑÄ*$ÄàNj\?(v`€%vk+{p_u/aV# ˆ$-)”– š% s,d vgfcL±+9%…%AC1Eª%J%LN&ZSQ¹*·ÓÖרÙÚÛfv;( vÄ% á{©%ã”& vøc„圽 ö h`C…}÷ò!ãI ÀÖ P¤D;ýÿ! àbÆ{!–˜‚­ÈÀâ†eV1 <˜ˆ-‡ G 0‰pb#H–‘hvÂ@g*8HÛÆ@ÀNšX³jÝÊ‹B;v\¦8 œ:°hQë³!mO$"¸µ# ‹Rh[,$q1M&;P½Ô!*f–¯ÍEeÂp°G\\»*¦˜W"ºª°)&H n9(ä0Z%‰ ¸R0ˆðàAXGX«Ìì¦'6ä0aÂgSSµyÖL¼¸ñãe,HH0 ¸'Ȧ.ÑÀ†Ì<8@²Ï Í PŽ»˜0 `@Á¢>(`pÃø.Ç @*…ñ,Ƙ ÿûõ÷ ãÔLēܜá”Ýe“\ À˜vš›å âˆ@U› 4B$ð‹  U(×LXáƒ8æ¨ãŽ<öˆB~>ŽÑ_`¦ã)1‚AŒY]äƒK&ùä”TViå•XÔ1@ü†e Hà+®8ˆ\my‰¿x¨“_jŦnÆiçxæÉÍGvH©çƒ€eYF"GÀ Ýw… LGœb裑Vj饘fª•™ÅýátSBªé¨¤–jꩨ^€©ZHg«°Æ*무þYh­¸æªë®¼öêë¯À+ì°Äkì±È&«ì²Ì6ëì³ÿÐF+í´ÔVkíµØf«í¶Üvëí·à†+î¸ä–kî¹—ò€Ÿj‘^ÜŠc‡¥ BK`Õ¢ @t!AurÓ`Áè6ì0 Zfm]4`¢¼u0ž8ìQ_¢\¬AÆk¹;×yHKæ‰ÁéqzØ‘À – *\°*³”Á6S´® Š€ †vD È7}.` p3Z~žãÖ‘Ý35XRšì–¿' Ù`f8žO½¤Á4ðó¿ip!—¢’Ub†–k;­7¹PqH¼cÀ¶ÅC;8¯‡rix8„—RH¤d=ƒcÈ‹%ÿj>c÷ m¿MÐWÔ1( s—Á-{·þð`b´Ý‘ X#Èž÷ Z¢ æ—½lœ"?ÀÁY¸ tÜWPBittPÆ9¸nýÓ.tV–†rHñ1P"} À»Lvq}ÍUÂWnÝ×6Ø'ìA™{{õÂ_s@@YÐ ª SÀò6ˆøŽ ç`×õè­¾q~»C%À†™RG~*(ßÑ„ÇHl9.ø òP.ýA*ã’›B§ ’€~$Ñ *ðR=¾¤Á1tA[xR­ d ¿; 1ÆsÝxP €Ô‰¨ fÁCò‘I&ç3ÔöV0 ø¡ÿ€…)pá`XRœäøÍE`4 m°\c ˆÎ15¢³å@, i±V€·MT_d aÇË]1xY<ñ¦x<€be‡–$,% „00ðà^ü†¶ÇVZ«Wh[&N²;0MøìZ¢Å€ì"kÓ`‘8HœIr±’ S^0¿÷p’a*f f/–<³h™!JáÊnB –7€c(fÇ ŒFâ\7Kpxåt` ¦fŒd&/•$Èä&GÀ’ <$AF ´9‚=X.lƒN1€%zó¡Æ*âô™Uº“ÿ˜EM`Ñâšï›Žè™‚.ZR™˜d¦äœ)¼¤á9bžG@P8â%2í‚»"ðCˆú”Xà´ÁGÆCEsÐÇMCm }~ÄR+Â3^òì %LI‚%OtñSé ›* ëð‹›¤›iMÿpPÏUQ§¸Y#ÊÖ_IÔ Ï)Î:†L_¦Xê ‘Ç >’PQå I±iÏ\2«” ÔåK¬o%UóêN,à¦mͬ°‚jƒš`4šECUP¹Ï~®ê©!Ÿê…ÀnEéHÁêFøÅÓžÀ‡åêmßâX T‚-±Á8Æ'EàN³ÈågÃg[Lp“ÿuH¡¦SÌcAÝ`$‡·ÅÍ–©P#ÁR´aö“5dÍ d[´E‘a˜cr盫åÂÀ$½TÛLA29’Š–ùpKŽëWÖrAs’ìnIY·‚ìÁŽC †DàŸIƒ*Â:‚ÈÖÍ€0¨ äKßËÊÃ]p bÈ»”±÷0i ^±k`.¸V+S¥$mQ@–æ$ 0wI‹^–æ€.ŠÀÕ*™¦Óc¥‰§Ü*ûÆ€^þ€\,þDQQã¨)²;Ìíg°ÆÛñ¿ ß{¤g=í)o|:6€ (méí0”yŒ8/Ê£¤² 3eå; ó 7¾–ÿAœ«¡ §Pó ']©ˆuéRaZ™¡jfo¤˜ÅZ¹À RúÔVRW ïd²_ÁààÐ6 xòÀ¤kLê^gÖàbÀ v'ë” ¯—=éD3ûÙÐn%°£Míj[ûÚØÎ¶¶·Íín{ûÛà·¸ÇMîr›ûÜèN·º×Íîv»[YªÆ4Z\}g[o£žÆ9ÚL‚\÷Ý8RZò ÐxY«ºÎ&€7­r.Æx01B]L=¸3_NŸ†7úâ¼Ñ¸×ÒÂeJ€%ô¶Á´÷È9À¡]µw ð¬,¾ÁÈïcµ´`£‹‰øƒ ­ÿ©¹ìœËÏm·5;wähÁçï6ÝÚNïq5ІU‚z³«ùq"Ñß[ƒi= ÐË} ‡8ÅÙ²«ÌÈä®´d,4΂‹ ØöÅ! œmFÒßÒŽ9å1X¹f¹^¤=xr•“»Í÷Œ°{ÄC·ƒ{ŸïDôÚ†ýG˜ßÃquÇ€ùîÐU4ã½0‹¾¢ ë•b^OÊIºÆüà¥]• srá!âg>ªýX„vJn‹+@bq@LzЂc5b&æ“1ûåýE 0/'8Š1 1andÿ؆ˆŒ¦¡bð_ùv¡©"©ÙŽúÅD¢j†2)¨ ªŠ6Šñhò©*)–4èŒý ¨É9 ™™VÀ² `4ˆ‡–cĨª]n C©¨³u¡'³_na 1dyÁR}}1%©T6‡ ¹eôHöJ‘•x¢X§=ò®)xPz¡žïêR Pvô³c;Z” &¤pL™ Ê®²5ˆ _a4ÿùŽ%H¨R×­áT›ýñm¤daJMæ -öBP ó)–ùfgX#cg’y–Cº(^–e&`®n¤Ð§D(PŒF:‹ÿc°<³ãw˜a4´Ig@[fžÐÅó°Ô 5…Ë;^¦kú£°¿È’êš;A²®3¯Vâ¯õ–¢¦¢%É’:*00N†¦r»7Z±¡‰%&‡r»*+‰,u°j£#€[+¸T#o‚’¸°¢=I+‡2Šsƒ¹“;º*'µvâx‘«Â28tsªHº°K‹x›)ôñ{»{dºµBa¡06…‹»Â;¼Ä[¼Æ{¼È›¼Ê»¼ÌÛ¼Îû¼Ð½Ò;½Ô[½Ö;*ñ–ó†¹Þb”±r¹¨Ö20u2 Á‹iøRggÔª ¡N¢ (‹ Æ1w4ÿ ×µ½Àq Ç4 7cžøŠZ=C(Z. + â5 p¾qÂ( «gvŠ)‚2³¹[É)_u5ªÂ.›Á7´DвRÙsh±t’CÂRuýr²[.X÷ºš¾±pÃú‘S˜Òz7À·2’œ™"³QFl4Å)ýÐ_Q™íƒ³o«#¥Ä Ã9…3Ї‰ãw%Ðxz(›jxëɽ’¨Ã:âÆ™bU„—+µªyk% p†‘x×:é#t ·åI¡\2p«YhÇP X³[s üÆ>|)r|¦ ŠRÁ‘â€%00 z§àzÿmÓ¶nh¥1Й’ñ{¨À}ò¦]Àœ\€|# ËÍ=ÍG‹¬ò|¬¼}k›OÌÔ1PÌ$€$ àÉ(p~ÑÄfËfàq£ ~W(íiK{µ%`K‘lþ‘, ‡ öëÌ20ý£Äbs±^ °tF¬)ÎX×ï|ÌCÃ02Iö[ÉW€³ãÁ>iñÉó‰]#{9P_Ê#@1ç€Âg'£ [º xªüãøÊO  Øœ¬IYÚ`üšlŒ'¨}µ¾‹Gd-ú_á›$PB ¦õx‚ ­ ÁºÐÌ,…¨¬‡Uª¯ÿ–CM÷nÜP öKJL Ôx†C׸w\˜Ç%ìrYõªžPpÑ¢pV0Ð XÕ@ÓGV>Í[òAà³CÅÐI‰Jy‚NÐÁ°ÑyªR„M¨6‰°ÝB:¹OJ}FU8š°lYZ•˜â‡D˜MI¦ÇŽ^§ž ëÔH:[1С‘šB¥ý½&Í¡ ºÎ¥Îùd @æ¨-ì½—=ð`ð–ÿGÇ€Qnùïí(¢âŽEÏÇñeÌs@ Ü‘ìõnêVÄ£# I ©œPëWtÒÙõý®‰Hõ®äÿù>ÉÌ- С•©®J® UM)z«T’¶>sšz*€ ÈØH ð5ñ÷ðé0`}] Ê]õ™`!Á¼ð è Eµ—G÷tžJceBíVR¼¹°\ó‘{ï-ÊR¯ƒ$¶c¦ó€ÍX°Jx€Ÿ@³ TzݱÒö®,Qñ"Þ9LäLõÈœ?õÏìŒ=W¦‘å)_Á”0ê—RÑk*÷Ø* q{ûH*ˆ›§‰¥[yPŸY‚ûYé ãyûpWÈ_Ù|e¢w~î©'µvØŽ¡1_?§àE{Þ7¿¬¥åîGsxmÓ”à 5¿ë’Î4ÒtéÒíäïÿÌíß§¤CNú‰ 0R°£$éh…;QpÐsqæ½ÿƒÂ%æ2a†£G é|³I¢¤&•€D4Åh*~ƒ®–ô•Sc‡ x¸`CO`§Üp¢)ý­l¤Ñ4 "ŽŒýŒ‘p5Œ@Ž ¸|¡ähôôБ(4á õE¬ ô1P!Pq¸TNÌ4ÉzŽ,°ìºuº|^z ¥Œö¬ éþTRˆ6E’ü*d¸üJÌÀ€UQUø4'ºf2¦8Ð÷¬hÒ|’Ò´3Ó&ÄCš‹E†¾àÚô&E.WÌñQdψŠ!W"@å•—€Y”4CcÆ-4cAÑÄui(ÀÅûhè%åq˜D‰ÀЩ°C6ÆáÄ‘3øS $÷’‰WJõ£HF“LÕÅPOm'Apq™ˆ?$d䘧Dv*´èBxrŠÕ|Z @g+j”A¤¹f`[!óŸ 6Fð@ƒnê8|°` jõ‰ À×6nXâ„v#˜ÀDàâ 6œšÂ/dæ°§«XâŠib@(M‹ #žÒЀ jÉ hXÿXZ€§ ¡±DÀP å C&b\$Э q.¢}ã²`nX] AœIâZïµXÊ­·0±4ÝL¿P𶦠¢ã’‘yø&AL¤D&ÖP»¯›h›gJ,O6`¦@\£2Œ’°‚£X€oy ÀdV€ôy¬Ø4>0@g¹¨œ‚  A´w€)Öæ \ M‚jÍÖ[µÕWc-ÌYãºÂÈi°E/×c Á)ÙC0äÙk³õ6£¤€¥¬¹9ѵ·Þ{ðÅfÞÊ·!Hð ""¬àk›½x i;¹äZ¼}Ü/ôPÿ¬f8¹çŸ»ãi;ƒ.Ä(M ~ˆâ¥×۸䳻äC'÷›}2Žá(»ï¿?vØÁ·>:ètªM¼òWW~¬hôËS_½õö®~="®G»ößF;øã“_¾àÙ›Ò–Ê9†û[ m©î£uÛëÏ?ÿð§ß¿ÿÿ0€  hÀ"0 \ èÀB0‚œ +hÁ b0ƒÜ ;èÁ‚0„"! Kh¢0…*\! [èÂÁˆŽtÕ;Ý>¬elcÁ‹Ïà m ð¡\EÑõò¡ý^èÄ×,éS¯)”0ಠôÊûˆ¢ ÿ'ç·d€Ch€h¶-wiÅŠc¸@‹UF ` k¤®æ˜‰ ++à ¯FšYÂW†€€tw„œ¸c?´TFf@Hüs”ˆ@©D\11|ˆ ! ùD Ö ž,ƒ|õ‹%!i‹KêãÀuØ $:%@ò“;,Aƒ<äÄ#Îß|¶Í‰!Å1[ñ(Ú,ãíNéK)U~;TxÿT@Ц à Ù*Ù®ZèrMGPK1 ™½µå! *if‚4¬¥ L-siË=È-ˆIÑþ(áÒ¶Ô´¥BKi7{0ž†˜ÀPç<Ô%Æ,S•!Ê»çjq.g‰Ði„€—%N¾v‰›hkJ×NÄdçÙwLSfA€äKQ4)㥧§,¯ú°¥‚ìFCÅÔn²²PîHd³EPk¸×k.EÒ>¨1|íÅþÀÂÎ3_W¬á®0't3NÞ0ly×ÐÒrÁÇmr£©‚óH žƒxÀÌ1#AI Ö!@Ÿ¦²(øý8}Õ)ÿ8â ÀÒã£7÷†$ »›ÃWæ· ð„™j†0íA&°ôº)[ ƶ¹Å `°ÏA`¶ö¡¶„ç ë+q» àN.HrÛˆèöÞžµ%Cø;¬òfê Ú½fž‹Úç$À2ÉUmsK"±U¹¼~øuºžº"zy4ˆ"ÀÍá¾Æ–hŒ½ºq@–FÌom¼ ™ØW©*³Ì¾I­æ ²…Y°3kàÂ2 v,@Ê@`Àñ˦üî  ñnm–ß7+1u›·¹åá¡öä+œóLˆÔƒÀ„(¶eS¤OÞ1öQ,}6šZ{ìµ0Š}Ub÷$¨„ÿVtè ß‹ü0%ÙÌT›4_Jô½[•…Úx@VXSh)À#!ÉöUž\ÞÞ9UŠß̓!œúуpF| p=dÂå%—ì1Å!ØÚèA“4ÒÝ) ä ¤Ÿï©Dð]Í  ÇÖDÙÎE`Ïyk€H —6”•‚P^÷•H$ábÿÍ—=àC°ÐË> Ö”Ÿ8ÚĉµÐÀ jÛmGÈ!W‰™¡FÐ!Þ€DÖMIòÑŽ8$‚–å]Õ< 'Dß 4Àö)…FmÊUá\! Ì_i!r¢bpD°¼H d‚nHSÿBg|Fh”G,j¨†ŸÍ=‚?@›üZ(Žb³ŒB-ªFp”! rz=$Áâ;äY=Àf0À-h¬€!‰,@@”àmu]" 5Ù1jbE ÔD{D (IºÌ@%D×!äxi8‰ô‰Ô_ ¡) ºØQ“ðI‚Ý`•!ð]Þã HâÄ!ǺYB›Õ‚•l¥i5iµ v£`$d8ZdA9’á¹ _q]\9 ´ €´¨º±^À‘¾ ‚–¸äоð# $NúLjd°ø¡dÛäM"Q Æ!öC"ÒDÿM †À`N½™åÖ<@òp¤"3 €R‚dYMZÏ@ZCBf×ÔÁ¥YÒåø|‘pØïNN0 (¤(Ì–Ë9¹yaÖebzÑÄeðÐÐPjS²Í•G…õÃâ^Ff*fgz¦Êå ¹¤Ýg’fiš¦‰åiªæj²æï¤fkÂflÊælÒfmÚæmâfnêænòfoúæogp çpgqçq"gr*çr2gs’P iÏcBÚ!hËüX}8:g7Ȥ ¬µÇI–X@pWZRä‰(PQNY‚¡äå‘M‘†©J)ÿbYJ}Òú%Å2äQÊ$[ÒÒ¡¡!e^ÍéMvZƒƒnç©’%”"ú=×ZÉ4#5¬gÜ9Aì ¥*ÄÒÌÒ’pœ¨-C."ÊAæh¸¥ú8âЕBIYT‘TE5&% ‘&PÉX;ŽQòÊŠ¬@Ô…¹ÔÖ•N‰Põ”L•Ö’¬”y½©Æ)qƒ`8TEåTIÿZí—ÿD•Y™ê×i€õ* jAŸ’StDà¢*†`Ä ¤žÅ] ` <Ü£0VÔÕã\©Á‹º©_ºÃQ"Âe§ lgiKæÒ ÑY]šC‘yæVèç5¤ÖfÌÑVz6†o׊êƒTë«P¬ÊçØ½RXÌ/H®JW"Z§ÂDÅõÞ°°v+—ZØüááÓ9l±è«umjKl8Ù;l˜…Á—®%$å–VAC6BDîKØDnj ‘–»ÊgǪdSŽÚ«ùà«Ôž;ìÃJ|BNPÿˆì¯,u@[YÀ±nÿ 9ñ¾hÀu怎ÉcÔÞX…ÇZÃþÀÅ6I楛˒1Y4¦¡@FU ¢Õ)M¤5< f%Þ˜nEYÕ«šm“¡-ô%YÎÂ*†`¢8ëâ À"ÃΈž^éÙlŸ¥„,¦× p&Wæþ£»®!Ê…ŸÅj)„ÇèA©UÈZ¦À¦ië øÐ…ü4€ƒ )Ç@è•5“€üaÂî=ÀnÜšàÐÎJb²Û¥ZW`0nGàË.8ª ­†Œ‚òÒY± ³Õ"pôÀ;÷F‚ü…<–oÊÔ ‘i¡¾Ò`þÚ¿›À%mX“5øoXÿSĹjYüºz€2Y“Æ üR\ïo!¯É¡î‡˜"ºi‹† -H4ÜÑFîK^Üdܲio¤ŽÜ•E@\P}ð©…0Ü_4p_”®|rÁ¹~^Ìå@Ó!aNß3ÙíYäpY`À$ÑmîîºjÕV*AÓ=ÝcÈp+0áú€lîMŽg.Å­ q 0ž½%3¦4A§AÿJN§LÔr±Ø@¸*Áó¢\I@è¶áB¼ÿaHÓ_83kÚ¡%àÙFPD%ï(dØŒÂ3Øžrlèd"®äo¦°´Ý^V t¬L3ï"³‰ÜWë4øä†äYp"ò…èB0aŒ"K5œ"Uƒ†hlidœs°o^´rù¶Ý"*,))öƳý†9ÏÂ/²3z¹CPàñÚãÑs[“løDBŽl1÷óÔô©íï;<ãbÏ5ùPË’´É8vⲂ]Éu`Ÿ1R¿ãެ˜°Ï36T A>>‰ŠçWÿcòèöfïW»ZÆ"dÛŠ6/“6X i…,l€©A¥~ýP ?€”Ì[ãÝtAhwm§OØàvtð54ÿgúÈ’ü6o÷à°¤K®Ø½T§}Ú£r O–‹N>÷ºä¤‰q)Wÿá;HkrÌÖ$#ÂJ[CK§LTêæHbÞ±mjQ*¼ö]Åv¸$%|«ø@êò@8QZ7‹Ð*œxÀŒgÐÙøŠÏµßœI`ÆÎ^ö%·Åxî &ö>Ð‘ëø’Ç"cF猴x5eFìšaf m&“kùqyu]h Boy˜‹9Žy™›¹äÄø™«ùš³y›»ù›ÃyœËùœÓyÛùãyžëùžóyŸûùŸz  ú z¡ú¡#z¢+ú¢3z£;ú£Cz¤Kú¤Sz¥[ú¥cz¦kú¦sz§{ú§ƒÿz¨‹ú¨“z©›ú©£zª«úª³z«»ú«Ãz¬Ëú¬Óz­Ûú­ãz®ëú®óz¯ûú¯{° û°{±Ã&€6Yšû²ƒN67,3{´³+»´[;ßP;R_û¶;N¶sû·· [(o²g3¸›;Ùˆû xû¹³ûÕ¤»B¹h»Óû•؃ûLÈl.P{½ûûq¨† HìíªE‘¼ÿ{¿à ¨Hº#€ór¼/‰ÂS¼DàÀ»ÿ¡³WüÆ#k ÆkÁºsüÈA‚¼<ûÈ{n‘|˯لT‚òмËÓ¼ W:À1Î|Íó|T@)Å,<ð|ÑS)XÀ@ŠüYô»Ñ}ºó4¿k¼Ó½ÃWœ6=Õ“¼µü‰ß ¼¬üh}ËØî|àRÍBÖýƧ wÅ„Lòη½ÂƒÙàûßAØ«|µ×½±Ÿ<ÖOýß|à?Cß×´¾ÝŸ¯h±ýâWüh'Ó>ä[>Ý[þߣÂgþå?~ç×}Ê(è·{!ùP, ø ÿ„© á⢬ڋ³Þ¼û†âH–扦êʶî Çr+ÕõŒçúÎ÷þ ‡Ä¢Ñ`KŽÌ¦ó J§Ôª¤´]·Ü®÷ ‹Ç«ìŒN«×ì¶= °æÈûŽÏë÷üþ&>÷Q·ägxˆ˜¨¸(H7‘Ä(9IYiy9)—¸Aèp*:JZʈ*×ñYhêú +«‚꘹j3(1ËÛëûËk«úÁ l|Œœl(܉K¨ -=}ªêHüI­½ÍÝÍ£ ¢««åm~Žžþ¡qëlF¡.?OŸÎ)ᮑDZïÿPY­aú²<ˆ0¡)fŠ)|1""a18”ˆ1£F1ÿzªa£È‘$£pPK@3‹Kº| sGœMräËÀ_¿˜<{ú<Á ÜɆ-=ŠTÃ5“:}êté»:¡Z½êS*ÑgX»zysk¯dË&mj6­Z’Tͬ} 7£ÎHqëÚ rçݽ|ûúý 8°àÁ„ >Œ8±âÅŒ;~ 9²äÉ”+[¾Œ9³æÍœ;{þ :´èѤK›>:µêÕ¬[»~ ;¶ìÙ´kÛ¾;·îݼ{ûþ <¸ðáÄ‹?Ž<¹òåÌ›;=ºôéÔ«[¿Ž=»öíÜ»{ÿ>¼øñäË›?>½úõìÛ»?¾üùôëÛ¿?¿þýüûûÿÿ`€H`ˆ`‚ .È`ƒ>a„NHa…^ˆa†nÈa‡~bˆ"ŽHb‰&žˆbŠ*®Èb‹.¾cŒ2ÎHc6ÞˆcŽ:îÈc>þdBId‘F‰d’J.Éd“N> e”RNIe•V^‰e–ZnÉe—^~ f˜bŽIf™fž‰fšj®Éf›n¾ gœrÎIgvÞ‰gžzîÉgŸ~þ h ‚Jh¡†Šh¢Š.Êh£Ž> i¤’NJi¥–^Ši¦šnÊi§ž~ j¨¢ŽJj©¦žŠjªª®Êj«®¾ k¬²ÎJk­¶ÞŠk®ºîÊk¯¾þ l°ÂKl±Æ‹l²Êÿ.Ël³Î> m´ÒNKmµÖ^‹m¶ÚnËm·Þ~ n¸âŽKn¹æž‹nºê®Ën»î¾ o¼òÎKo½öÞ‹o¾úîËo¿þþ pÀLpÁŒp /ÌpÃ? qÄOLqÅ_ŒqÆoÌqÇ rÈ"LrÉ&ŸŒrÊ*¯ÌrË.¿ sÌ2ÏLsÍ6ߌsÎ:ïÌsÏ>ÿ tÐBMtÑFtÒJ/ÍtÓN? uÔROMuÕV_uÖZoÍu×^ vØbMvÙfŸvÚj¯ÍvÛn¿ wÜrÏMwÝvßwÞzïÍwß~ÿ xà‚NxᆎxâŠ/ÎxãŽ?yä’ONyå–ÿ_ŽyæšoÎyçžzè¢Nz馟ŽzꪯÎz뮿{ì²ÏN{í¶ßŽ{îºïÎ{ï¾ÿ|ðÂO|ñÆ|òÊ/Ï|óÎ?}ôÒOO}õÖ_}öÚoÏ}÷Þ~øâO~ùæŸ~úê¯Ï~ûî¿üòÏOýößþúïÏÿþÿÀ p€, ˆÀ*p l ÁJp‚¬ /ˆÁ jpƒì ?Šp„$,¡ OˆÂªp…,l¡ _ÃÊp†4¬¡ oˆÃêp‡<ì¡Ä qˆD,¢ˆÄ$*q‰Ll¢ŸÅ(JqŠT¬¢¯ˆÅ,ejq‹\좿Æ0ŠqŒd,£ψÆ4ªqll£ßÇ8ÊqŽt¬£ïˆÇ<êq|ì£ÿÈ@ r„,¤!‰ÈD*r‘Œl¤# ÉHJr’”¬¤%/‰ÉLjr“œì¤'? ÊO!ù2,)  É Ž$œ¨€®A鎫ʮï;ßgíâ·^Þ²˜ÏÄc aEÚT›¨%Ú!:‰ÁÃÈMƒ'°‘8 N o2(z"@B†S|QÙi%~w%yUT-nŠ…Mn ‘U`bQ‡‰$‹"ƒ’x'$¦›^nªu¢d'giŒT#Y y ¡¿5 oÈw5iȯFx³g{·Ë gH3*`V e  &ÓÔOk^òÎõM!!ù,7  ‰ ŽdœÂ©®Aé’lÆoßBýÞ·îª3žÏÄc aÅÕq”T.¨æÚ<¹ Ël•öz Y³Y™sN–ÅDrCAW,ÂõFƒJ&4 T]=~(‚€U2om2=_fqRpHd%wlq†N$`”L‰S‰^K£¢hœG¦O¬¥M)§1‚²’¯U!!ù,F  wÈIi¸XટœÆaß7žWé¡§ZbèZ,7ƒõvK¹¾÷¤_ Æò$+`絤Á.±Õ ”RQQæ5Px½Á× P ÃzCä¬ÕÏVE³­Y™=ArÛöY¦x={\BUB}#;eJ‹fŽXD‡7i,"“‚†=!ù,T  U„ËÝ ‘›KÄ;½‘n®xšHJâ“+Û¾LëšœÊ èï9Ù€:¢ÌøBŠ,´J²ÙŽ Gê3ÆN±Uî5W¤jm;ëJ‰2§½ÑìOíA{ !ù,c  i Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo ‰EÙJ×*Ž<§m‰ BWÎ'´™ÜfOÔÝ÷GCG ÖFx¥SkØ”e>ÖÃ@©Wßîö­,xX|y~v…Cu;„]‚‡€=dU”[!!ù ,q  Ç Ždœhš–,©¾h+ðÜÒ§Û&¾ò®€.¥€Aß 9Rî˜Î%=$‹¡0 I”Q,Ê0ƒ@úÄhFEØÀhPš†¨ZVÓG Y{9>p% ƒN} % D/†% j•…f™$›V|Ÿ‘“8}ˆ$ ŒT4c}u§ƒc5W's wJC}ikm«„?f]_ažX@¦Ö×Õ:Úv®1qÝÏŒÝwrÚ¶âéåf!!ù.,È  W„Ë,’<°¶9­ÆÒiÆ%_*ãU'šZ¥À ÊÚË–ô#ÏtÜúõ¸Ïp„;Ò”+&¤Ô m° uymfOÎÔ ÝHÛQ×Xv…9DmûV×â§!ù,Ö  ² Ždœhš–,©¾h+ðÜÒ™6K¿=nýTEc`÷KŠŽÄ$4F @Xˆ0=ËØ -Ou ŽŽ‹„6D(‰6—H 'o8S7=H•¥Sv-g‰•El \\ "a(‹(¼”M#‹  °iTF½JÑвÕIÔuJÖ6R¦ÏAÓáS!!ùB,ó ÿ Ždižhª®lë¾j Ï4 ßx®ïy¾oH,cAßqÉlÂ’2 ÌI­ZЙuË-fm8ÇÁÐ-W¡Ò)Ž8˜ß̯v݆۽r!Ý}ïëhiJ$ "Y% ‹& ”:„ ”Š#  &Ÿd7yz" 32" Ç $ 2”2˜$š59¿ÔÂÄŒ lÕ×$³ÂâÐOI#2 Œä$l|'0Ð 0 ™Ô!b€A8,àÓ€P¿F2,ˆ0 Ö ÖP@ÁE ÿˆh0@À'GüC@ƣŠ)D „y$q#Ü`›5@äeýZð‘s63OT5!ìæˆžNwT½j£®•2ÎÎú9âWyôæ@ð¶EV¿2˜xᄦDæ²E‘¬!Q"@¥j®zØ ´['à&lŽfóI¤ää4ì­ `–F 9Î"³‹»%‘Ù/ç!®U„ äé©{IÍ#bn]°I佘çå!ÆW`4qxĬæ9W½¤ÀØ%_’ØZ¢«mNC¾ƒN½ˆµ%~IXÝe_H&~.Q3€Wï:ׂ O AÝMæ*2h&‚D`RS#4 Œx+L%BOùÓATšVl¤AûmxÛ =hÏDÅ`ðF´l$;!T’;eøX (7C)™ €2ËDðÀHŽ åz,“8‡ˆs‘9舳Žut@Í L'G „2ÀH  é$’€rÉ Ú´Ð¢nqRÂ&6ª4ÐÊ2 R¶P’ Q|áǪ°p(>úF¤+Ì‚ra)˜ª )¥Ä}jF¨)øFjJ‚˜Úª(Œ:D¥®ÖjD£¸Ö`ë®xœÉë¯ä!ù, w@ÿ„©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þŒ †Ä¢ñˆL*—̦ó J§ÔªõŠÍj·K ÷ ‹Çä²ùŒVzÓì¶û Ë¿ë¹ýŽÏë÷Ñ:ÿ(8¨åGxˆ˜¨¸g¸èø¹Õ(Yiy‰I‰¹ÉÙ¨é*:ÊJzŠšzeªÚêújÄ ;K;*[‹›[y«Ûë{Èû+<œL|ŒÜfœÌܶì-]=m}ݽÍMUÝ .ýNž<^Ž.´ÎÞîþ/?O_oŸÿÀßïï¯/ À3þõð Â… G| ¡Ä‰'øC±¢Æ¥!ä2¤B Eš#4êÕ0 !ùL, ,+ å Ždiž@ ®,‹¾°ØªÂßæ¬x/ï-_¸ª™„T$“ËQ¨z*£)juä( ƒ ¡²$Ny" 8LÀe-ÚH JÄ"nF«xXYg:"PXrhŒWQ:†[_Q˜;# g–r$ j+ BO_{>3 hªPt±©%‚*°CTF #‚ p¸Á”ÀZ"* ×oË>º6_ ÆÐ4@Vƒ²Âž|TôŽÁ%ïõ-Μôˆ!‚(ì!,a.ÈÂB!ù ,), ¢ÈIi¸8ëʧÖBÖu_yÜšZ±YèZ°8Kµ}›«>=Œìȵƒ€¢¸(ŠÆ€d XNšgTŠT2Pl꽂·d««¦¿Ù0pÓUØòÚÛ¯õögA&   ƒF 9 Š I}9C ˆ•1xhD…„%Dy%+¶±;nDBz¾½¼ŽÁ<!ù,7, ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù ,F,  Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒV‹C$\ˆ,’'X…# ›‰$ ' qS2.'ceƒ=€@Aª¢¹rµ8´¹q–¸¼rÁ³;{ǽ!!ù+,T,W ÿ Ždižhª®fà¾pÌÎtm‹qß|Ïë‚WÐå+SºäqÉLê˜Ð¢3­ÞCgÐÊMeÝ0ê»›IÂ\6@’*€JdF†Å#A/8R &„ ˆ6d/m1 #.„/' /œ$¡.‘l#n ˜"«"š$. "$w§¬i1C“£6ÂÒ# š&Ž "š¼^­“7 $å'±¸“p4kS$±žT8 FXQ0B J(˜E+W"b}KkœC Æ‘  ’)WɱöêM ô0 r„%“'¸pfäâ¤d(–‘’WS… ë©æÉˆXûN”IâèÁó꩸ÄgK 'B‚p®(€nRžÅºÓD:uIÖüL‘034 (3m8Æ.Kàà‘ Zixá&ªÛ‚ô46+"á&M”H(éB {*û)iéØ-> 0  yµD >XÝ ÂÄq¼µ¸îŒïžÅL‘Ü 5'Å÷NÞ8ó*0D—ynK$ê\Vº!ù,œ, ’ Ždœhš–,©¾h+ðÜÒ§Û&¾ò®€.¥€Aß 9Rî˜Î%=Ž €! "ªS@ÂR*ªˆ˜X» ƒ¨ÖÊòéΪê79>z3*F?"X|}Qz=NzZ‚“WY‡0‰‡‰m‹™–4C£lŠfšyS~®cSxƒ/²¯P°B„º­¸ˆ/!!ù,«, º Ž$œ¨€®A鎬ʢï;ßgíâ·^β˜ÏÄc aÅÕQ”T.›´g È#1 ‰Aƒ@BGÔà400o*ªhH8D8‡æ'3)¨š2.vsŽŠ_E–'TF>@8¢P‚©_x}. ›SUl µq ¶E`bc'Àv-# zÈKŠ=R_ØhNG<Ô€9OÖ×Ý‹ÚI!!ù ,¹, ¦ Ždœhš–,©¾§ÐίÏ-|㦮ò½€ÍtùVEÑ™Œ-“JÝðTB@&ƒAdˆ.$Çà”µ¼O‘áDè‹3@в«>Š'8_T<„`Š_2‘S:"‡‰ƒ)˜H€‚4„w{}Dj'nhŸL†cˆ·r‹UWY[n»PÁMB0SPs¥ÂÊÄ_ÈtNÏÌE‹!!ù ,È, » Ž$œhš e;¢‚*»®ËÝâ¼^ò8Ÿi¾€*£™T2o9' 9B`&ƒ„Ä1džDÍi€‚½ÑI ‚4'.ýeœÚ#Ìz‰ƒ¢z%' s^1 % '‡h-d\h‰—%d ‡~=‹$‘t9ƒw’SAx"z|“jmoq»^`dµÆg'¤)Uj[]ÄRË*~J±LÙ¬ÜtÞ63ÕÔFˆ_NÌ8!!ù ,Ö, š Ždœhš–,©¾h+ðÜÒ°ÚfŽŸ¼Nº`ĘQôÛ-›Ê'T@*,Kd¯¤ T(ªZ•˱8¬¡¤òõ†«ª3lyƒ*~m"eX|xn{M€Ž,Cceˆ”#V–&Š}@‘ GŒ¦#l‹d’—HKw?T´‰4´µ?»­¾£º¸„ù³RP!!ù,å, · Ž$œhz AéŽjŒ¾¯,ÓnÌÆxió´J@"ú©p–a1µ¾’D€1… –ÓVP)Íj†Â` 1@±¨æJë@  ×ÛR¼) "rŠÒ$'W]i6 %s2j-o% ‘Y]%™S›%gˆ o —Ÿ:3ŒŽ$~^€‚„†K“¡C% |p‘€& ¿DT-Æ¢»%¹²Ä°&³Lr -{" - ÑÝ’áÒ×rÓ-¬"Á­ÒÔ%ŒÝèe¤ìtï³ò¾êñ¨¥[‰oÊù“–/<†šP±ËB3\$†1 Ð!zd%p Úˆ]Hs<àE‚@¿8ZóBä|¦¦¥ZEb* ,3ÉDª í!¡¨Q™% {ÑÔ£;U6lØ·‚àˆ:w€ˆ€À€ ä(á)×ed¸™ À+Ý/vïB9"Dï›#ý>9$EðÞP†KÜ‘8N™!ùn,,Y@ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬Ö•éz¿à°xL.›Ïè´zÍn»ßð¸|N¿êø¼~Ïïûÿ€tw„…†‡ˆ‰Šhƒ‹Ž‘’’“–—˜™šg•›žŸ ¡¢¥¦§¨e¤©¬­®™«¯²³´„±µ¸¹ºo·»¾¿À^½ÁÄÅ²ÃÆÉÊ¢ÈËÎÏ–ÍÐÓÔˆÒÕØÙ|×ÚÝÞpÜßâãfáäçèæéìÞëíðÕïñôÎóõøÅ[ûüýþÿ H° Áƒ*\Ȱ!•#J”谢ŋ)˜(qcŒ C:äHò£È“( ÿ–䘲¥K~+'¾œI³GƒhĤX³§Ï7sÎè¸ò§Ñ£+‚êäè‘'Ò§H`ÀbìÔhª×žªJP`BU­[»~]ÛÒA€”"X€v+Û»)àt(S–xƒ,À_œKí ^\C ‡…ÊH«–±e„¨F8€Ø¯âË 2ÐqÀ2šNTºµÁÂF”ÐFZ®s¼i U¶ÓêP©[ ¶›ªæZ™¸s,r!ÖvAù¹õ* F(epöEõëà¡À` 2‚0ÿ¾½’±oÑ› !û‹å%ÝëOÒÀ  ÁÓy'Ü~"Ñ×8d&èà ÖµÓƒázÌ‘Tá†6˜XDø5ÇáˆJ¬¢S$¦˜Äw*¶h‹.ÆŒ2Ö@!ù ,)L ¢ÈIi¸8ëʧÖBÖu_yÜšZ±YèZ°8Kµ}›«>=Œìȵƒ€¢¸(ŠÆ€$¹œ4Ϩ©d:¡*Ø´kýjÇUÉ5E{±`à†›¬ã5w^ëé%lA&   fm F Š I|9C ˆ• wgD…‚%Dx%+¶±;޼´bD»?½Ã<!ù,7L ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù,FL  Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒV‹C$\ˆ,’'X…# ›‰$ ' qS2.'ceƒ=€@Aª¢¹rµ8´¹q–¸¼rÁ³;{ǽ!!ù,TLW ÿ Ždižhª®fà¾pÌÎtm‹qß|Ïë‚WÐå+SºäqÉLê˜Ð¢3­ÞCgÐÊMeÝ0ê»›IÂ\6@’*€JdF†Å#A/8R &„ ˆ6d/m1 #.„/' /œ$¡.‘l#n ˜"«"š$. "$w§¬i1C“£6ÂÒ# š&Ž "š¼^­“7 $å'±¸“p4kS$±žT8 FXQ0B J(˜E+W"b}KkœC Æ‘  ’)WɱöêM ô0 r„%“'¸pfäâ¤d(–‘’WS… ë©æÉˆXûN”IâèÁó꩸ÄgK 'B‚p®(€nRžÅºÓD:uIÖüL‘034 (3m8Æ.Kàà‘ Zixá&ªÛ‚ô46+"á&M”H(éB {*û)iéØ-> 0  yµD >XÝ ÂÄq¼µ¸îŒïžÅL‘Ü 5'Å÷NÞ8ó*0D—ynK$ê\Vº!ù ,œL ’ Ždœhš–,©¾h+ðÜÒ§Û&¾ò®€.¥€Aß 9Rî˜Î%=Ž €! "ªS@ÂR*ªˆ˜X» ƒ¨ÖÊòéΪê79>z3*F?"X|}Qz=NzZ‚“WY‡0‰‡‰m‹™–4C£lŠfšyS~®cSxƒ/²¯P°B„º­¸ˆ/!!ù,«L º Ž$œ¨€®A鎬ʢï;ßgíâ·^β˜ÏÄc aÅÕQ”T.›´g È#1 ‰Aƒ@BGÔà400o*ªhH8D8‡æ'3)¨š2.vsŽŠ_E–'TF>@8¢P‚©_x}. ›SUl µq ¶E`bc'Àv-# zÈKŠ=R_ØhNG<Ô€9OÖ×Ý‹ÚI!!ù ,¹L ¼ Ždœhš–,©ªÚÎAüªs{ß9»¿=Óï º^¶•Q4T.aÐÀ’Ù<‰ ‚’<Çê5P˜ÄŨj`  ñ–ˆÍq<¢Tbnp% gyƒ%'w7ImX% 'rCIc€$—™l" ŒŽ’<ƒ…‡‚o|"~ˆCzqz ·?cg(kQ(EƒZ\³°‰”=H«Ñ9M6c•Ö¢ÉÒܤÚ4ÜO5‰ä‚çÓ(!!ù,ÈL ˜ Ž$œhhéŽjœ¾ïÉÊ3]â²¾ó*&èÉãT‹ÝP,‚Y4¶FˆhUõ̉¦&ð&¥þ¬a¬Ù„N×0›±ìf£éb+~+ëîÏ}^`ysjuq+†o |‹ '@%Žvz$( "Vd%'¤N=>‰°)Z³mˆ:¹³­w½P>¼Àc(!!ù ,ÖL Ç Ždœh ¤gé’lŒ¾4ºÊ-íâ±¾ó)Ÿ‰uc aÀ“à8JΘgŽ) ˆJd0˜,È¢Rõ< ¸'¡)Y(Œ†ALظ¢®1¬£m:"U#[6† }v})b3 `#™›F r$˜€N%'ްI %¸™Œ=}r ©®Ã±N.ýN_¯_m¯_PŽ¿°>k ~XΠBl»-|ØÌŸ4‰!ZDÖpÞÅaÅ2šãrF<‰!KÂðh2% ”*[ž`é2¦|þdÚó¦Î ýîü‰ÁE‚@‹JÈi4)¤J› YÑ©TL§&…ªÑªÓªZríº3£°M· ýHÖèÙmi¯flk´!ùW, l+ ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽp "1› &›%›#›ª )›&ªµ¶"¶µ %  %º%[»»”ЛÉ"°«½nÕ " ›%#£%´¤%  –еæìÐd•0@^‚þFLhGâ]¤‡#J c €g¸`hÚ5!¡ˆM®H˜ €ªÚƒP&ÐÿÑò€¸MÑU󈀞-q#Ž @)bÙµ,lñ³%ZµŸÙl (ÖF8œúX¢S'ba€îÀÑàÛ.Rú^0  Ç \ªZJÂ*Õ'ÊK·îŒ=Õठzd8ÂÔ€’4ø{ì' z©2ŽP@™ò*SFÙeZÜ(—ø–€AçcL ²'²-‹5ƒÖ̳òåÌ›Gd[Œ B„M©Õd@Ase”äH½ªP•Ǹ"¾ à`®÷xÆ—0>"vr¹'Óz€ éÝXUÞP«Ý÷ðã˱lo‚Ùґ@@‹ Â"Œ„Ø9˜ñTI:ä`•Âÿ3ø©@‹d$|GÂ7äÀBPÀk`h„'%M<§t÷ÍMÐ QøÖB á$tÏŒUBg'h·B‹&,@µÖ\Œím5ß‘H&)×}"Pc_o‰Tf#€€"¤"Ð’àã ¸ f,Â7!m¯Iü°akÊ*pÜ(H<‚QæB–ËÉ–d(9ÿ‡_h~Âec«i±—þ WÍ–h‹ ¶Þ¸<ƒS\© HŸÒ)Ä®:KÀ® @P·û-øñÈ'_5¢Ã"#_ŠGÇÜGÆ€g–» 5W+° Â'@½‚éýV€çY[ôf±oA~ ⓸úp;Kœq ðÄqÚú ¯¥qÑEêTÀ­ÞÝM7,S^€ÿIcfÊ‹ 'HçaO[,˜Ý€6/Rí^ŠQ€„q)rè.@FCAüR@>Umï|òJ ›±µÒuM…_«×ü°7À2ûùÏ€´ MèBúЈN´¢ÍèF;úÑŽÿ´¤ŸœM¨7 )¾© ˆ)£ðÀG žjXwЀDଓNµªÁ@Ž< à£Af\c%§¾ÐOÐÐŒ¶F$ ò‰…J  1ò Tu£Xxÿ»À³mÇ™L@)]µ¶·MrÌÔðl-ã£ì‘ªX‹*Ü…\Ud˜Dš®§£€/î 2)˜êâ(k+qûß—9”ƒßPL¬‹Ö ÜñH*ÌÛ¤ )S_0@Âpi5m@ónCtŸ½…Û@O¹Ê)ÝNÀbß- f5èJŒs/€ÅÇsr6˜B¶yzw ,aØ•ýèCðö ÿ¾ar8å¦VbG¬}²èä;„AÌ, ˆcR Xx*@S`w5AÒTaaZÀÃvµV÷[°cî2 GÑ‘Î÷¾ç`à6,¿3ÔÄ+ÑL·“•ºsôœ– …K6ä8­]›Ð€å x¥í %ÌM x–lô»êWú–Ó i9u€÷i·Áb:¯„ÓØÕN¾:ϳþ‚–)2—©QµLÓ¤e— À® @…Ž#‡*xF¼g{Ö{ÿû@$¸ `ñ}©…ÁïdÉÃÎÎqB·^ƒÇ£Lwz¿~üݹ;›§iò tÿQâ'9ÕzN~ ¨zJW† ½€Ë L¾À§÷/µàuíÇ äÁIs^ÂçxÄç– %x Û7!Þôñ!(gº°åV0à#ѳ€8È€®7#¡i˜O·P¿Aæñ€FZŠD$‚õ7‚-` §:PtSy•kµÀ`,˜Á1XcôO)ÀP6ÐiP9x†Gx5 ¤’ )ˆ0FL]âQås(áÂxX7týC…ý²%ex! @ Z˜M<%+^d愃U{,`††”Øw Øz?%KÏ—;q¤‘£ ¢£*&—QNXÌöz}ˆ1È-åÿNbˆ/Џ&)U, †4@¿V$W‰¾¸j—8Fa9—!t—¡üörjF#@£XIòÇ„ò…S¨ŠÔ@NbÒf¸…í1‹û²\BæU±X ðø‹ê¨jÁ8B* ØWxW#‘“;Þc‹$Oz8||x¢“(¤iF‹ú˜à8F¦ ~MÈŒ8` ë‘ÖŽ2W6wxò—‰,ƒGÝAObü²!)XŠÓȇTá‡)c£/‡XßhM´XÞˆ© ƒ.z™“’¦†|Ó° £÷_Z?üòÚ ¦M À؈$Iö·(þE1Xÿ ¿€Ýrn“áh•ÃÃ~1Ð}:™–¹ƒ4P#\  NSê¶ £èj!ZQ9Si@'‰)„T«° ðŠ\Òyž· ¯–¹U)y&y‰5xg‰}jy™‡Æ“'w³g9q –k l2‰ 6?¦{)}IIU¹Šºñ{@ †‰Bà_iUat+ðs:y˜œ™É–p°š0pŠs@+*`+¿ÙšÂùœuÖj×t˜Fˆ²‡t@@‡‚;0XÙàIg•†l)‚vð ƒW<`qðßžò9ŸØI€wpTÐfj¨FŸþùŸýFÿ: j3ÎY š  º  Ú ú ¡:¡Z¡z¡š¡º¡Ú¡ú¡ Jãi“ciõ ÀiA±ž”¢8p, rËIPT€8€ðE”¢T&°6†´Ö ¤Y ¸F °k‡åk´pE!Ãö`æ‚Ç–l'ú.J0ŠpXYj[Š3 äËŸ/°”Š)=ê£RF‘2n*Æ:æv#éö~Ù1»ð|j’‚1€œ(:KUUGßóaZczeúÊII€šwt§^&§W€p ç\@ðpç\˜»w@§qÀqÿ¯09 ¨XJ¨Z:Ž`¨~°¨4ШFð¨-@“úWIA£–Še˜ú†Ñ£'“3÷]’sãçªü(¸ †Š¶Ú×*+š¼JxúyÖ—«´Z¬?Jœ10‡2„„_C?‹duÔŠžÖZ Ö `a ¥6ÆÙzÁpû •ó0 ¶4ÿ P°1€ˆ‹\1¤à°^E§Ù (až_q#`v&§U Pˆf‰eiZ!f9a Fæ “𛺑‡Á¿GoŠ0ªH†² u ®ÆÏ–WF[±®­v+Ñõ¦ÔàW8à#ÿ$Š®O¦™2PzYx?85!¥x0`œkz Cy*á‰A z:²£ŸIž‚å-¦ –wq[®+€“sSçX—ÊUå†.‘Ðy=v!ÇÆ˜Ánœà'±ŒÀbŠÃ´à!ÑdI˜£µ«q{ʹn¹ Ћ>{ yÆdq„ c4B» “Ä«ÉK&Ôô ¦,`µX»eÇ…Êb²G{-p{‚i^…Ã{Ôã{Â0›ªY¯O8a‘ €>'õ#º‡£6<˜Q t ,”@Æp·“P ¾š›#à ÷ °»u¨AÝ@vHÛ ƒ˜Áe0ÿ—Ac؆p£'P6`@Ë[Ò¹çOѺF¢`Š1‹7²?Â5°pb¿¡Pú@þ€ 0»1T»(à#ì4¼Û»Y¦µ1@~æ§ )û_Aù9µÀ~›3 z*· )R) H ŽñrHxI$ð­Q¿ÁÁRÓ%ÝÁì¬;|èð< m´Ý#XvdMAFåc$/9IóÂ+0Aɦ’¦ši F¼‘E¥HWKõk$šð«aú 8’òR†6h,¸óZ5IÃ5¬®ÈÊ•H™ ðµ%°võ`±IØ”O¹,w¨f+Æ'Võ 8zÿA{· ܵÈË86]L©f 7®"à­ÁÄJ„ÆÊx‘—’4=»NqQT‡7ümòç§åÚ'·¡2½¨* 1Œ+0£`ˆ*°[,KéÃÃŽœµì=¯1ì®û1„å!Âó×Ä ¼LwL¶/0ÊA %óà³ À˜ˆ+×)˜š¦ ³‰,GªXé¸ý×¾ñÚŒFsl5§K½ÜÂ…'=uÊLNX`ŒÌ$’&ÝD ƒ‡Ï ùÍ˨iª"+bp„S;eR´‘ýI" Ø Uã|e6<¶Vâ†(‡røÐ\Q‡¸„‡åXÄWê/HËÿ/±%ßJªóŽ+pÕ =³Ü@$2‚¦¿H=bêÕG€Ë2ð ’"m7]jac.›SA½ºJ=©Qn'»¸wc }¬K ùËSjú˨  »? \¿ËVŒÐ›F“Šv©2ɽ¦hÏ@°¨S T-%ô” 4Ww¦}¨¨= H~w¬SÖ÷ˆÆ|1æ¤Ê8P›8µ:/ûÀMÂQÚ¿8 +*ɰìÄú ²½÷QƒMÓ Á ”I|% )ŒàY ýØÙ+`ÍkmŒõÐÙ;UŒýŒ6OÝ(ýÄȆ!²È­Ý¥½×ó½¾ì±¿ Õ+ ÿn\,hlS&ÐJȽÇ@xÖ*iPõ¢`¥qSÏ­× x+ș”Š%"~CØŒÙüYÜMÎÇÍBÕ—3˜='47 é’Ê1Ú?PÊÞÅAák}Q÷5Ä*0¬ÇçÔ\¾¼Ìú@;Aº}ÃaÌ‹äjD7žéÖÍ»»ém.\ÞýÝ„IÉ•z}C‰?î}”ù@·£Î”æà”þæq¯jã>0½ã0V¬3/6 སíãDNy@vpÂÕØ³Ý }Ó.= €æ¡ R¿ p¿p؃'@þë!|®à¼ Ì*Á/Ãd!7 H¶±¿%¨Í-ÆÁÑÄÂ?éQÂ'|.…‘RºäHµù2à½ey n©Fº ¹9¯¤w9ÄzÙçG,½˜‘¶ŠY2ñ#µÙŠÕ¾@·õ`·¸·èæ¾ÈÅo §WÅvóÔb…Kz6ñžÿ ]ž¥ºk[à»­"™ `ûÕbÏ&kº?Rñxýæ(0¬©ëædq“ Ęª«Â^ܬ&°ßYò2Ìë#¯V¿yQ:šž có ¢ù¤MbšÂš­Jã0 í=œÀhǯQz²ä^4é(Ćù§Íè~른®–v+*`Áá…±\]‹!kaQn+k²0w `p< ³ûaðEL›'œê‚¹A;èÀð#·/46ª´Âü#€ËÙp+A¡·ü£Ÿ/ ò{ïæ¥¾ôìŽOgºœ$üáñ‡% 4¸ýnŽš Îe@¥-ó2«†V–Jâ#ÀDmÿ:L0 €y¢©º²­û±<Óµ}ã¹¾ó½ÿƒÂ!Q8RˆJ™áxÜøŽË)µj½â2 ¶ëm)V#1hüÊÇÈCñ}Ããò9½n¿ãóú”tïÿ²hq¾0”¨ 0!P\ (Z^bfjnrvÂ5ôyŠŽæHl‘¢¦ª®²¶º¾ÂZ…Æ.LÞNŽŒО4ááJþêÞŽ ÷.37;?CGKOSW[_cgkosw{ƒ‡‹“—›Ÿ£§«¯³·»¿ÃÇËÏÓ×Ûßãçëïó÷ûÿ (p Á‚"L¨p!C~F°Bà$Àƒ(ÒQÀ«!‹&à\à蕊ÿ5â‚Æ ˜sÒ•ˆlÄÑÀƒb(HaC„I0TBÑ€CÏ€²`3@IÈ0!@„ .RSp §ŒŒd³5`°@­Žh8tÉ/"ñXpÕGÉŠ«œì=‘àˆU¾ãàÀ\ N­(3À‰#$™ÙJÄ"L<‚ÅãÐ#h°ÁI®…Sd -sE_‹Õš€a¶[ɉVXžØ˜HÝ7& §c!@ &dV•‹ Ü®U-W†‡@K$@ÂC€??¯y3W X@€à0Y:0ï $%öì…@G$e_0ÿŸÑ©P<|uÛ5ìÆUYðß aH —\SwÍrÍsÄgœ`ßV¯¡2¢ÜÅÂcæ1‚z;À¸Þ+œíP .ä—Âw¢0&¤t –¡æ‚ƒ¶Qƒ…Ým£K¿¹`YrB„hMváLòX`l ‹¤GâvTº0Ø–)p×$(©#+<ê@gŒ1˜â— G RN©Ó=̲Š –@¢Ài&ªPAQ t€@Ž– Á‰DÈ u¥ÔV4‰K $u•/h â„H2Á7ÀHŸ>`®&¼Ôè£ÉYwÄH,túi ´:ƒl‡SR­™6ÿZ ¦f)x4fŠ~¦0‰/i0Àoj› lú†\dÖZp€ƒ4JÀ±¾ÀTá0n¿ç®,Uâ@mhÖ¢€-\Ê-°¢ B©B1꓈W¬irâédø@ç™v¦ò xCFÚÒ‘©{Âjr¶p(‰¦ÒU¹0¸V«œAV ` OL0àžtìnÔUá@.K@µ  Íl_z'”Äê Cî‹Â«Y~Ø‚Q·€[¡¾ŒÖÜ8àƒ­«Ï à4Ü4IÙ(XÌt7`Œ„¡P€Ñ!ixV1b›G ½¸ »Fí¤±Æÿ´Ó+pÄžpgƒ¸ hßßuÎÐÀÚÄ•¶ >·†Ú$xÞêÞ}7øV‘-å[X~]`± ¥!Ãx®ÅvÑFÀc ·`Ù¯7˜‰òíåÐD_JÀ›*œŠBé¢!`ê'h@Oæâ|{îœÛ*ƒ­Ë ¨ÀÌà†¥ÁWÍ«ÝÓlW°#h.TÁ!Íå­ÊˆšèĽœ­{TÁÚÖ7±ù Å dÀ$ € , 1 Ò(°!ɦFA Ú7,ª œ\äS Aó9@P›Ü"€ ƒŒp4LÑt¤“^GŽð6ˆ«$WIÿÂWîÀÏ ˆ@c,C7(@nÓRzÀ28lâØóS˜B‰‡YÅNà<÷)2‹ŠQ»Z`²®t"„øRÆ4ôEiN dTFЪÄM$W ‚á¤n^á)¼Ë´À êÍž¼eÂz± tú"eN°œ 4@ 'KMH¸P:`¶ „Èa J(5>0ÜóÑ÷ ˆWÊ`‡, Ìh–ðïFŒ%sf(’Ï«j ›§E”ŽM*˜Zä   ^£’Ì¥Óí;Á$.ÖÇÙäêÕLAš^`·aNì€j h’bÔË4’Ì\ÿNWÐ䯒›8$®$M7hªe,P€Ì¶è ÜŠ”—)Aâ‰3퀕£°L³(Q¥Œp{² zÊ/xô±‚)0‘Vg,dÛJ ¹Lª®€¨F]ÀGÜ 'IMIh£dT­g}w\¸±ŠÔ’š½KÎy‚–ÆÕµc Ѐîï†Á¸hF™JßÖÓªØÊ*PY\ u€ž á# ob“Ñå^ ÿLà¬õ¸Ám« …%…¸Æ6UP“ÊL¢8nC]0 ÒU¶œÛ—ey„å6êM©Ì8Ð$õ+É1‚z"y–ࢠ™@|ÄéÇ#J³mVuçj·ØpDZ­ ‡Ê@‚* Mm&TÆV@¥Àk,ÈÈ–Ë\65 .޵Ì{ó=œæ B­Èb0ôÕÅŸ¢N¡ÕKVk]» $F^ÁuE{Ë0¦À\0Ø•²Ú‘5>ÖaZAxI´önXßeU°ÏÔ`ÃA0eŒ dyváC5e0˜ò4… Žìšï[¼`Ë*(óµ`—Ÿv6#ðeÁñ:âÿ$ª4sŽKâKtÖýLÁræš4§4 7ËMœ_¾rÜôÇÁ}E€­(/šLn£ñðËxëÂ'Ä*“'ìdYyÊ'%ý8œš&Ö,(/§¿\ LEª+ tà ßÍñlž(­áŒÂ€PÄ™e—"¸U¢Îöý¬Wú<Ó~09!єĠÜY4†½}M,·@Ñ9`€B’€^ÓξÁROPº¹–N©öõÃ#OTÓF•ˆJn+Rú¹¨ù„øõ7žƒc†ÄÞ Œ\GÜd!e×ÛMh^ó¨æY’2*³Sr(/xÞº6A¹Í‰m€[ÿ€î^7 òë.^ÓÙÚ/° ÌÙY$ÛÖ9Àû8t)Ký„Í6¨}$Íh’“êýæc –³ç„{ÂÄ68w HÝìÙÝ wfãŒ:m…ñJ†š`ÎhxÛÄÖpìv•¯a®v <>ñÎH{SÙw™±¡—é“˧ÐA ›*½ñ-_v+ýíz˜`§õ$–‰S½è5l‚cr®Ïo'C\÷%÷†Ý¬7zÌj© Z´›`0=ÁVnçÑÃ½Ä w™l“4³Þ˜PˆJŒÖ®tÑݳ¿Áà=ñ½ÂS6¶³|g P€JKíþl7UpÑp Øÿ‡AéÄåÊ$äÏËýÛ噀ýá_Ûè_4™–þ xÍÅÀ ô\Ó¥žÿAÙé¹Þ’'%Óë!Vm HÑáÜß_@ žÚÕY lZ ¨ÇŠÞj  ê l g‘`µµÞì!É`TÈ›ª@âðÛ 5aÕuÝ LRöu‚ÜÕnÇU‚8€ˆá*ØpLy˱4@H<MÙT|­Ÿ ´_'ÀŒW®ÈÍ÷ɬ9àM-ÅœÛT-É0HâÐ ’ Ô’ å}œ‰ár€ÞHˆ!n0€ü "4Í“ ©Q˜Ò‚¦äB%ÌІXªÿ@¢NQâä¹À[0@Ç€ÆbYÆ_ݵ !ŸËâ ÕøÞ'¶S ÜÑ%_  ÑöÁ, À‘ßöR*RP£..#°`T ÄÓè ÓrLW ß3$-#B¦Ý€Ûé’™€¤LJ;.  µÆ©]D¡ªÕàŽ±FíΔ†£<TÒÒ4·ÙÒ3£Nô PM &ž@w€ ‚M ÷$›i`Dn˜Ùý‚ÜäÂל€ÝÔ£ç¡Îdb €dE”äœ îN ÄÓÏÜQ­BÆëµÀHÎVØ„ä˜/^”Ò(áÅS1ê™ÙÉÿ@2À Æ€ì8  i›ÞYx8yË<@¨˜Ù2z |”²F.PåÊ™dDLÆ <†æÉ;£haõKU$>š†> ÐUü‹`€$$CH ¤ èØ*´ZD@\<Å-AL.,Yº¬ËAÍ-Ñ“$KA1‹íaýQ…”N,WtQ HV Œdh 3äfÑ ÓÄ”RÐ x¨ÏVB«Q@QˆÁ˜YÞ¤‰xŠO,‹¥-B€dNg 4@tŠF[¶^ò˜F/eÝ ÞÎ¥Œ¦ÔM¥DZe lTî±¾P… ñ‹$ÀcžÖér*ggj§§äê½ÿãù hᢘ¹(Ð"DBX®À€ œ›øÀ.f! ¦*¤™Ìá„jh3Љõm¨ˆÀÐ5AúÝÀè|¨!Ô„ÑÔž&üÍqÄåªhŒ:º˜Œº£ qÇôéE<šÊÁC€,vBp  ûqœ"i',À±Ôd&)ˆÀäIï™Þeé“®Çebé–fB²ELur) XÀé BéÕà‹JŒi%ii›Â©,vgœÚé.A†úÃûƒ1 ÀFüã1´Å„ò)ÖàÂþC¡ö©O¬¨Ãê¢6*žJê¤Rj¥Zê¥bj¦jê¦rj§zê§‚j¨Šê¨’j©šê©¢jªªÿꪲj«ºê«Âj¬Êê¬Òê¬é•n‘’h è)—¦„§KDj­+< @d‚GáÀaDÛ–ð‡sª\€Ê°ÚAŠâ„ìÄýðgu…QÔ‘ ,ESl«yMEU4IMjÅ‹¤¥>†½­á^k¼âm†’˜6§lI¼™+zVh°¤%Tè (€¾vç¨L €è ÑÔ£µ§SÝ*iœ~Gx¨ãÊëÅÊhD@ àVfI2,@km‰%’¡ ÜØL,N¢ê<ÚÀ{$ÂÕ¼¬ì–ýG€ØM -ˆ9ylìô*–Έ ° ¿blÒ®LžŽ¢ *EÖÙBIÿb æö}“'I« ‰¶&’ÜU4¤³h\ÿX*„"Ÿ‡*íÚzÃËZèã [ Y$‰ÚVc» °& ÖÖ€ÓÑ@Ÿ €=š€ ì×¹^ÐÎÀÐFÃr, À„!ëL@Ùd«OØÊÄIŸÌGQ´!¸€¶2ç ˜BÌ OÀpœ×›ÁWÀêÏ®:‘_±míbâ‚NBWšÌŒÜjA¶Àxáïx"Àî |…½J!ÌÀVÚËÍÐ@eÖÀ›nClƒ)Ü‚z|FèpE% Q.|i.¼ ™¥Uï$¤JŸ&£}À-¬ˆ uå“íÚ/5 Øm¡Áßá€Übÿ‡A ̇ Ø2:e‘œ”åÐßàRú'š."¼ÄÏ€DPýÜÏPfÙæTÄŠÈk6ÀV°Šjt@£ý #×0 ‰z°WŒDTÀjAMèÆÑkBÚ1Ù <  - ¤çý±3ÄJÿÕ¾ë]mš©Øñ6ù@òŠÌh)‚Ö¢(u%±™Uo´†,R/¯‚°5”Nf”]*I[]Ô(‚ƒn’ÐI%<†l¦ÀEiïq‹üÂtÔ ðî‹%Õq"Ó‚–|EÜVî.ÔFd8¢;™DŰðõRÎ]±ºÎ€IuáÎÁó"ÒKÕ©e˜ÿ‹îoAl¢6aé˜äšÀ€4ÑéÞcZÑqauî’T nŽ­Ø6 '»@i)ò1WC¬@À˜Æõo&±—ýF<@8&ƒÑSW4X`ñ Ê)¶uomÝhl€noy0+o8,ÇFÈ2(¡MJN´fŽÞòHdÄH Ø“iAç=°/}àï´žQç"sCCƒÜFó3Krß5Ï0ßks0j™Ó à’m0Tú±˜‹ .èÍXÁ‚Íüº³Ù~Ã<›@=³„i9§˜wÌ?À? ó Ü`ëî4€T4)ñO¤C5,|jôFÜÆÙ˜ÀíFkÿ²"[u10ˆŽP§­ÀÔ†ZZà9™šB^+·twÀ4‘XòÝtZeD€@2îš›±/èå÷sÀEØQë5-ð²ëîCmlþor4•T[c÷ ó^Ý_{Ça³ÃÑÎÄ6×­XW4ãÊ€ãBylÄY›Ý3Ûà´Nã§$ [*)¦guÅcL^Z;”Åîul¯BäU›ð66Ôn…_ZœÝ6b ´ï(î-¸á |óð‚4Ë—$æ]pO-F9i*9òX¿sYwv.GMçu ÈZûó.CŸ)ørBóYH˜Ðo¿@õUݸ(¶l³÷–U.ÒF Ê/fž ¨ˆÙ¬³ øn¤xÿµ]aq{²ntß×zÞmØ™¨AùåwKéÓ€f?CéÐsÆ´þ[®87w›ik+ hÁÇ©U’ZAŸËÒÌ…C·m·w‹×Ær¬Æ 11®Ô%ÊÅ>a€ ”ÀTév <Æ8BMåÂ5>€*f„ôh ÷UAJ%6p‡aɖᜡ¤aⱡ*÷Jc+„;C<¿4…?ç‹\Ç$Žxlw?ox—©A̰¬ÖÚl@ ä0¼âl7›âšš¡´‹z I=¦£8¾ 0OŠ‘)^|ùë’û •Òð•% á-y4 Ðcî°“s*&½.¬?šÒŸ/.”xƒK÷ÿTø’(,¤‹‡M³yN‡½@íHTS…z—Ÿ@²U–S×ã·žz°ÏÁ±†Ä|«KQe'ºW°L®Û€)&ƒ¬`f6æ¸"ï¥Ó€ÁÔçaÎtj+cNB·²N¦È`6{¦q5p¶ ˜zª»Š4ʬæ-k8¬cîlÀ$ûp BêÀê¶€“®ã‘$ËÍP ûÂca“s‚ƒ7„-ËÀw´ˆ)£8Ãs<‰¥¨ñD„MnEº+/˜#Ä 0Á[{ Žþ÷¿áyÇÃ|ÃO®jB±ü ˜üAPü (м;M^P)~o|ÌýÑç¼A\¡ ,<¢8Aÿ»/0ÆÑS}ÕçXÒÄγÀHŒÕ{ý×ǙăýØ“}Ù›ýÙ£}Ú«ýÚ³}Û»ýÛÃ}ÜËýÜÓ}ÝÛýÝã}ÞëýÞó}߯ǭFÄDÈnÄwÜDÀ±cxÀà/„xšx€¯§ÂxGûý’D¦S ¾ Œ®Oû<•«}G.hŸ¹dµê Oø¶÷P·2Mç# Sð;éR¹ZV¤k¯ë*Ôd²16@€\˜(.,@½Ë€â3~4ä…)xÀã‡tÀD?ÉLãC¾ÀäãAýU^þ*<@ô#M÷{ÀÐsBò¯7€?Ôï X¿ê¬å  ÷ÿÚO^ 8ÀH–T€–êÊ¶î ¯L0Å1¡z€•Ë®ˆJMPgY€—#ð°ÙRÒªõŠ!CöÕx¼,Iáû“¥O Ë¥ ý¾6Ýí™9L0懑p ègà!pøwyõ`@èq©i¥¶ —¸(ÀQ•Ðài“`°š ¤U€Ò:b€Ò¡€p2€»¢;A•9!—“`€`p`H"ÛÁðìpq["Këk aí@á°1VyóPyà¡lBf–«~Ü© ¾7ò B ` v €‚…úäРÆRŠ6zôCQƒ$ÿxHàAÂG€Vºç®Q#,€!Á—f„#É+ Ü$Ñ€K’‡š”ÐvtÅ„ Œñ¼2£œ'Á^\S±¥\‰¢Q$ °ÔŠ!6ž´›cõª'h! ðÀ€‚40ÓB¾^©²q#7ñ†0x°˜ £bÅ0'[V1 ‚€Àò2Ü––+£1ÀÅ^€2xàÌ¡qO¨,!–µ*´MUÅ,†;x —< P&a€@‚ ",ÈX%kz¿­ä&€÷ÓÕ$~d’âÖO\Ñsèv—cr Ô\à-KƒÐ¨Œ€Ï{Ìÿ¦‚ôð€xð{-T°` ¥^*´ñ¼– –€c/8v[dcd#ÀÐ@:Ú´H@FûÍ8Àª`àN.ìWL‹`wDþ%@@^9xG+,€IO9Ж—Ø1" øH°_-B0` À mDøQND ŸYdeŠW €AQ\°m7ú7ÁaŽàÚ P0€ÍÄF¨ ™WLÚA›)¾P¨=Œ`˜^v<Tdâ)Ì’:™ÅÀWDŽÐ\å› ?heEpHq!yõ„Ÿ¾äãzR,WBspŠÜ¢ ð*ÉÀa,Œ6Øÿ6^Yï`hÄ®0¤Wr¶Gž xðR y€¯V4p"-^²†D°Ì+%˜¤ˆ›!&ƒà±P/i©a‡¢ð–äA‡²…ÐHO¡ÛB‰³àd,0`‡œ,$Ü PBI‰P"†"iÀ®ï*òÈУÓKwõ H(s¦< ÞB@ï¸nÐA³>`ÒÆ´¾"³ˆÅ¥”Ó•F×t‰¿#<ÇÁðáÅUL"Ä&Ug\¢hÇÅ M¦½æ´À]WÚC"Ï7{+o¾v\°AßpêJú8 d$Ôáàg'œrŠ@G 4½óN}Å^Šh»‚†¯ôŽ ÿ€ rX '*Ør©©€Ü#'x!zÄîÜX<†ÙphwÚ¢XÀ&’«’PLY¤;`º-Sߢ ~`^;êyûmî bå),ìç²Qê†P m¦u»Ú BcøÖ/<¼®ÕƒJ \‡c}Ûï @Á$à{¾0‘ Pä>À€!³Ò×.Z¹âÀÅ~!Žu:äkÁÈ|´‚¤œd( °©®P€|XДËEG^%¾<à°€ÇFp—,H É/ E»”¤¯kìÓÚ U¿/€­DèLâÊv+¥„ €@꾚ˆ6ó›@+pð?ÿ¤Ð‹,s@êJ`¾5l ¨ e qœ:™¨hÅa¼0&žá!ôÊ0—eƒôP‰Oƒ`…èQ„#”Ìà±SÎiw, ôêÏBÃ@. €n.˜AWJ°È"LƒDŽ(п}IOaÐYõâp‚²Ä!… ,AðÃ3Ð'?VpÌ¥bÆ@i€@š £¶t-~rК9%Â$àCêÊÉ«@A$‹ /Qà @Æ@8E N{ØJà˜^Âàƒ-€U€HÜåbÚc=£ ƒ>MC$¸KZìÉJ@Ñœ.˜¦Éå¡„! P:£*y¸f´ÿ&ŠxŽkäBˆC SðZ?= |`sšJ\ >„5™æ ÜSÕj€*ìˆP‡$ètàŠmŒN•~AeSˆP”,¼ÂìF`¬ç RZÎ"ªÂ ¤.Ëœ­ © U (ÈQ+0œ@[rÖ-±`?”¤uKúÑ€Põ#ka ’ €qérì3€àd@{ÄÕl` °ôpw©JÊE"¶ c/0¬t¹‚ô#}iÍ`"ôµ ôdÁ]@û”¬¬œ¶d”èú”ðÔã% >$OÂÆf±°åÆaëNˆâ4I€bÄù†P¯€ÿ`KNÎ(†¡„”0)4=À]ÌqS@Ñ,mã0ƒ¥Ô2kAN(Hx¸‰.ºjŒŸ[E˜îû¢oàG©NTšj…§ê¥vÄ£AýÀ»/T Ž,î]) –p€¿¯`Ç€yOÕÎrlƒ[ßj…ûZ@¥Vh•_õB‚Ñ &Ù HÀŠaW‚a{.+ÁØÁÂZË  {¢Ð\Db¨T2ËM_¸q Z‹Oó¢¡UF]gýiÛ“ ‹ÉÂñ€0²cVWVõÈ$n2Wô¹èiXb¬‚EÅ5òDI^FÖedz7¤{e)VÛóÆ$Ç¿Qiÿ»ÂûŸªà’T‹²2 -Eʘ©EêUAÁQSRgAžZ!Âf50¬ ’;DX)Ô¢YjÄ#†Ã;P\Íb5 štŒ-Š…‘5 T, °Tf‹fÇRhJà‹1 YË* §ŠS}üÊÈ×îrFe+"`1–OŠÜ*( ? ‹À­õ˜h6K[$-³ÆÐª&ŽÚ%O(2q½Î6À¶•%ää˜RŸ×vTaSÆ–” MÞ<èá-˜i[g0Q¤s¬;qÉL‚El|l”À…zî"xÔ—„*Ìˈa?²ªgÆŠ|7ÿtÔÈâ2ý9dÎ2¼ç¾Ò*1\lÐ7`, ´o0@ÕQ\ÍþW>ï\KmþÖ>¥ 5½9CÞ¶±xDHL6†$È€¡òPÑa˜ý§„¸<µDA0 è—w?ó}4d»–Ìw2«(f–µï0ìÇxgO00”À[á½óŒ8n< pT|bÚZ<½!ô׎ÛÙãuéHY0Ç¡㈅7+Xµ X]ÁpÖùò6€›ÞÙ[ àA²\w)‡ŸI<éÛ×@Õga|îeêÖå3Ñ€õ¬¿à ÞÃNW^̋׻kæFÛ%„’ßSÖ ÿ# k>$ÿ«‚dä>*’% ‘ `^#“wf±ô§•ew÷ dÚbrObz0 [Oóo ¡f¥L÷gjf Ø5vgŽ7zÖw¥EíòGh˜X.¤r9f0ó*˜{·  Àbqg”Ç$8‹„|,°HFÃ|ÍIVÐi’ät+€+UÅ‚X°,»u% i€š–IÜÀ}tÑ?Èñ=V‡~9¨~1°HH(abæøPtáá].XÂ…búc)âWm@Ë„c¸Yè € KÀ…xà+(!ylw‡h&üæú9qxÈf“ˆ‰»¥ˆ‡z¿u‰Ë{.áyÿl†‚±Ám$ ]*@]e‚¬™Á78n¨:"È/€ˆŠVŽ+áÀ8…¬S2 (°2Ö/– ÉȦDC7\5„ªC`XÀjYpàqeÑ:/áŒH°8 œb >ƆiÀ‹oè'°qT((ç êÂw+ Ð%ܤQ…õˆõð`}è¥y,ãK óEÔF"í4.ÅX@wçm,   )y€_H†ˆü’:úˆg†÷Oe˜Qs€‹`‘xÿŠcAyl70HÊç þ!鉅Y wQç'Uõ7 !g1ƒ# ƒ·˜‰,pqåÄ‹Žˆ”¶×‚ÿ%™’™%R1 Y«à¶…Ê„÷VÅ0`:¹Ñsã`ç \ð’;'?ÐCf70gð`¾ 8Ô;·3)³ >á €˜‰É)9p–¨`XÉÈ.PpViµV½vuñ(C»Ó0~ €^Æ+M¹)G±!ä írFÄ5¯ø™ ³#R²A^$À!ÂÐ þ±+ €˜'Èù'À‰˜ú“˜êbG ¤{#p >ãâx(¡/ Pi“: )š3@š+O- …’C¡@r1P_T A&rø‰c&Š‚š„>¾À÷·œÒ›Lù“–'ÿRtGZ°WÔ0CÁ°Q‹1(‚b¥žÜfš8æq'‰<û‘2uê š‹§è ‚ÑŠªDUiE–@qj¯ôà°à™ÖHl§¶xËâjYðY@†³ yÁUÍ÷‘'ªS'J¯äžÑs~ð˜™Wp=pðf1 ýr§0ŠpS!üÒ0Š02Gª5ÿZû) Ð5 ³0Ui„%)Uy( B‡Yã¦"§þ¹ DZ#“6)IU z#ð¤ cR:@/çö?DÓ?¨Á8èt9“§òÇf S¥õ§+À^ùrŸ 3ðøðo­‚„üÒ"  E‚ÿ¦H-°Š‘g6hÓ8D 4þa/œÒªmš°zEÚ S¥8Ùó¶¹ A•Tƒ2u4”:Ša°ª=U'p°W?°™™e\Áp @Am‘~.p:øqG¥VFEQ­ÔäØwÒA5ÒmRè;Ų­‹2$±÷1ÀO–¤U°¤_ „afW(\ç'¥tvY)&Ì× RXÊÊUB& °€Ä¦r€+Seé¦ð…¥L‚ ÕŽªÁ"."S@& à—ŠÛê±%p3Lr'!Äd2ýêA‡´Ïóðz ÿ“h1W²Çª*0Ÿ«( ²%©±_­_ÚŸÎê¯^b(Ì&‹   M1VHùK)vLÛ"N[JFp‘2{/a±ph`Q'G¢¶Å¡ v µ›`‡«¸Wq£‹›‚\7=Ž8‹¬UŠ’‹¹™«¹›ë P’zœ º™ûv¡KºÕ4 ¢UŠ‹ ÅÀyRP®ª›…_°•¥k»·‹»™;.ü”»½;gc“¾+¼2°©¸÷…a™±+™Êà™µ•;¼Õk½× P„¡Hý‡½ßë6ñ|àK¾åu˜™¤A1ÐAæë¾ï ¿sp.à%¿÷‹¿ù«¿ë¼ÿûë¿ÿ À(6>8Ò¾lÀŒÀ½Û¿ <¼Vâ2ì2oA ÁãËÀWñÀîÁLÁœb¬Á rÁ#LÂ%lÂ'ŒÂ)¬Â+ÌÂ-ìÂ/ Ã1,Ã3LÃ5lÃ7ŒÃ9¬Ã;ÌÃ=ìÃ? ÄA,ÄCLÄElÄGŒÄI¬ÄKÌÄMìÄO ÅQ,ÅSLÅUlÅWìÅ ºƒ„¯;è{¿ôˆÅY to"º¼ñ0^\õÐ j~°l¢VclÇùkJ©›H ´Ðt<Öº=pnMÈ“&‹’$˜zXÅ ¼»ƶ‹Òpb¼¹=ËÇæK‘lÆoˆÆ1^úÿáÙ„`ˆs°|DZ<¼;'S²Hˆ­@@Lfae…±ÆëÀÆ`°À¡;ÊV Éš{Ì\¦|KË\¥l²@½ÖVxîW£²¬ÍäKËVÀЀÉÔ´€ m+Ý0§S~ä`è@‘{û½Ð<-––¹÷eÀÍ|Æà§k\gá—²ÐÉÿYÌیСÛÍIH˜^AaÑKdAJ¡IuŒ–Ù†ä«ÏȌϘkÏûËÏ¢ìÏ!ÍlŽÅ}q  ‡›Ð-m½ m´†ßFƒ–WU ÏWpÐYÓ¡`ð„¯EWÁÓÔ×ÑrU~#°H‹ ÿõŠU4ø´ÏÑ£›Vtã3ÝúWá$ŠÌ•X€  Â#& kBõqÓH9pn Ô²æz®ÀDÕV½ˆäÇåö¶)~pxâ+ l²¾yR1@cÕ‚²}r‚Z6íÚ¯00çéÒ¡]º€IlM-ÔrÓÖ’ŒÙb;Ð=bÉÇ( pX½¬Ç‡Õ?¡Ä` ˜…³kÙŒ'gnlqÝ8a::–$6¤¢d4¶}(°X‹•†G͘Ò¶LAEÜ-ÜchÝu1ËâÜʽ(J(ÒÒ, ¢4ÊuˆDeåÜ$bË¢DFQ4 ÿÀ J„Z`A JŽÀkôÍ,%À°vÙbB¦kšh3ÀÒ¢-á¶ Ó0  N®ÅP¢²ðºà‚Î+F“¼uƒëbö\H±®EÀ)a1ÖÜ=ª³à—g‘ÍŽOÛ  ¼ÚÖ8é-žÅ©œèçî¸]:úåÕç ðUÛVo b=iå•y¤ Û·4U5Ò²Èë8´ÔmMöP—yQ…Ó¸k?~BÚgá'¦ %:E‡à@|¼ßtjšãÓøº º@rþ[K]f{¾Èˆë%`  •6ñkyãKð7ŽÅð¹+ðÔþ>²¥kèŽô‹«î.0aïÿwôZ a–ðaeÅ)'ï®]û~K90Îpó/7²2­ Ãa4+&aȺ‡µXÌ=ä.ëÛÓó>±×­ a8Ý‹%pT%aA‘òÂ=ô* ì ®¯4l\Á\çö¬Û«Lô¾Âê$"Ù@@JŒÑ/ Nt¡ñ=í²Èô§°‹~ÈÁcQ/bÀšÙÝѶFV¹=o~‘kÌ'šjÉGöÞ9ðL-ò?ð¹¹,…¢i•8÷˜ÚÔ÷8=¿ Æß|މã(OVâÖÔ?ÐB‡ßƳ03¬;lÉøŠžÖiœQQú(0¢%«s{òzã¾ Štqx,`,ÿ½I• À#Yš'šª+Ûº/Ë3]Û7žë;ßû8#0¹“%pAA”ˆ“!P˜0Ǩ!=˜¢çÉØè´ÚÖpP&ÒÀåMO„7 ˆ£KCÉB€DK…ÐËŠ‚‰U‰£Þ`@KTÆHB@‰Ô‘%¦ â¦ÜVÃä âÐ éNÔÀ‰\VB…äH®l"ËT‡Á@@… E¯ èk ŃrÁoe¶ö6w·÷7x¸¸NlMt)‰ñ’‰±Æc‰Øm» o$eØØŽÔø7‚;àq 0Šlà©dŒ€(Z‘H"Š…4 Šê xd t.¡”@Óú²y!(XU§*E&ÚЄO'œÅ±;R²Š0Ôjy8ÐDªEKI […1ÕÒ¢@TV…¹7Júmîü9ôèÒÕÃálw^­ó®Uá¥töS €Mön»{s žþ/À'n¦ÈU—ûi ð\Û¡ÀnÿF‚÷ýWC†˜€}L„b‚Y™ Œ&X€€(ì× ¢†&(ñ¶’eýFB ÀgÅx40d žð‹Àí¹+Ò»²$˜ŽA†#húƸYàFÑó'»÷¾A T /<À>”6°€,€—Õ ð€Òöõ…‚~ê€Û˜4·|(§8l‹—âú&Á R°‚>øß2ÇžˆY°ƒìú>È>¸³ŸD¨Â²PbD‘€ˆU/ÀÐ qSC [¨Ã†p‡ßìŽ&,Ôí@><"“Ø•"”*o×zØ•(EöpŠ•`H†îPBl0¢ÿÃ(Æ1’QseCb*#ôøI^lQ˜âðØ°¤Œfú€2ô"Døþs$ܯxræ&‰’¬ °€ÿ.`"3èœð“!tOÐ8ÿcÈ+)` ,ÁÀxƒˆN "'%1x٠졨Á@ǽap@DöÑ!½cjòfJÌz˜JЀ™M'Ò4Ù6¬¹¥&Ü4CèÅPÊÉ}ဠ°`€$¦ `@XÈ4A¦¢<š@¬lpØ mðS;&ÁA08hQ7’7Ù¸!å(tœz¥izCªYZj¾f„Nf¯Z•¤Jg î … Ýšk EÈú&«.Ðà Ƞʰùr¬½dCˆ‡²±ÏQ¬•Û Ø^) A1¦d£^6œÄ°Cº‚\ìÆ´ÈMb€ÚÿXÖ‡ Àà6å†!Î¥àâÝöçZ'DßdQxqxŽH}ØÔ/‡¸ãþ(¶ƒ€Œ*¨xÔBáÈEçµT<„rtÙ² X€¿qXÀXUÀpY\‡[Â8€ŽƒžuÇ»÷.@!CI¯Ø;Rh/˜zP‡?¬¿ Ùé¢z'<¬ÙX‘M8@Fü'•€¶m‚ qœ¸A† )¨6«„‚W“™AÝ8ÛŒm* †åå,¢èAv3ðÁ1$àw ¢mÝÅ?ÝfÁd8ƒ·{Û’W†AjäʰlŽ…]r˜„Cœ1L¸<µö T;Å?»€µñ< <9‹îyÍ%(oìλ¢=,ÃH~]Bèy—FÈ^¸ØEŽ‚gš pÑ0±rÀÈÝŽ;‚Ô¡“u~— núó@Ö#6zÐÚñ̾» wÚÄóƒt«ð(‹¸³y@q9Rj¯ˆpulaìóýæ2•êQ÷K‚›å™M˜×=xO£ÔþlB±Ûɹêéÿ‡è)Q„°@_Š”[äìpV@#lãyúaFïmžÏ ÛóÎÊ˘A8à ( –%›$!øÁì½€ô‰ÄDÁ^DÁEäŠïEJtiÈ™‘À“éôYOWïÁ@”¬ÈžW—\èÍE(€ ˜Á#  | ÈÔ^ ¼DãYÏ ÂU­ß#ÝÝ BÖ_}ôà'ð @ÝÅ`ƒ3 ž¼R*‘?&=OGèlY ÞAÀ =€ Oa`óRèGF‚W䂨 ¤` Dƒ!bœ1V®ä (¨Æ¢•=_Ê@€ç Lø,ÿE ,œÅYœ!¢ ÈGÚ!˜"wu¾eÔcNNPÁ<á‘–†$KtÏx™E Àœ2T•~!}i–ÿ5ÁU9ØXr)•¨8I4xWÎÀÇÒÀ ²ÌÀI9Þ pá ¬ y!\ŽEÍ—õ$ð°Jª¢ÇömžMÁY¢IØcÕ hTÏJÀ á ÖáPŒŽ!JÀ3C>¾ŠAj¡ ♺|„DÂPEòò„ž¿0] ÜÉ{Mäf@áHá0¡#FV ,ÊWE£Ýi$·MìT\x$Ê'˜ÁetFÅ!^Ó•Ñ`€H ±£#š_|ìÿàd™®˜‡"aLL#«("w0#0G>ì^WäP@@`$Á™DB¦„õP±ˆÞðɈËÁƒá# l#²EG†Ç‹å.êÊH>F €ˆÐ€ÀO¬ä0úW Àɳ™€3ÞV^$ Pƒ50!NBCЬƒ¤PŠð#ÊÅ=<Æh–uA¤‰ÉHBe[hdú!ùYâ8&™yå*èf#ZBzHÄW˜œýÙVAšXÈ!‰èÊB.RŒ¢ Q E"²€3(㼑TËùå"U’K úß Ôàâ0f¤Tgh^@ð©@v¶@GÞÀUÈäfBRgº€¨Ð‘¤G €ë¸ÿ…BÄ Ð…(FÖQî k&Ò I TÆåÃé" ‚!äàºXfzfnžlà&pz…È '¨½#L~Fr&Í Få“èV¦G4”ÖwR …Îb˜@.´†nÊ¢T̼à‘ìJØ#Eíc@c>Í¢ M`âGÙJfâ¬ZÓÉ•Å㺨-áòÝ9¾Ú°IU¸dê¾Åü¨% ÌXGTk’Ú¬í1é­ÒdÏ:)W"¦àD˜ù˜€|!3XñDŽóPÎXN¼©&Vè­D€¨\2¨Àý4åfþxd-F¶¨êõ”ÐÁ½]µ×ˆùN Wö/àØ*ô©>FfôÚš ˜%=”*’4Îã"ä¢.§¼ †í™7ý R¼ÿ[}ªM¸÷ÚÞõF@ö¨´áxFÿ XÿÞ”l€Ë¬×èVoÀ¢95o¹±òå„´£œ¦#^€‰á^BcýðìêòÑ®ÒKjôƒ¬ð-åÂÉ6) !¯Ëðhý¯ ¯‘8I€ri Ä™?5mÓCÔð|‘ ˜ ÑûìÀPfŸS~)G±)ѰcQ<%õõ@}‘—q(ž¯GñáîX¬¹ïצ1ǘÖ1'Qï17Ç÷±t”Zß2ÒîZ Ó ²A,h ]Xß.RwL"÷Ú1 W²%_2&g²&o2'w²'2(‡²(2)—ÿ²)Ÿ2*§²*¯2+·²+¿2,Dz,Ï2-×2 oÉ1y©g±-‡6¥@TÊ/£rî¦æ" À¼Hó!€´2H0G “í¯{Åd%Ÿ5CÏ:qB;M³Š)Õ€>ÑP?ùn3þñf:@QG¡^÷šn1ƒ²Ñ"Œã6á-JÈ.ÁKa¬•´pÊôÒ†ë|¹•RqM­âìT—(«ÎQòòW2ïs%c\ bÜ 4B´‘XyŒ‚ÜSýzœ½š†„…ÕXuóWü, ð€•X‘•%H]Z­U\ÃÉÆ¯F,]Ù7+g´VŠd!ÿ!!Hk²Õè sØ xŒËH…\^£b‰B§@ypZ£|¶kÎ~êàá<“£/÷¬Fïo™„EOµ&;ƒù¥Z¼$(E •^æÀ ÖB\Wvp „5 üu 0—+ÐŽ*œù2m 1%9üôAˆÛýPÎ(¦`ìFN1E¾WøüX!˜ˆª=ÎÔ|ØI—¡0ÔJÅHú*á¸B/D€­ž“ÿènçhõŒ˜µ 4S| ]óñc;ô‹Â€*Už÷`Ò@`'„Ú€q¥’€UÎ^—Þ†a7[ó2¾u ÑÚÚæá0ͱ©|û¯R€×JÁzLÿM¯eŸhbøòSœˆ«¾Ú@f4ŒT£@ÜÂÞiˆìôÚ€ô †Õak°Å,7›¬a+äŒä *€…Ù†¸…¥éÄ®uC•`‡ü‰†¾AëÂÀ‰‹Ž¨8 œÛ¥Û'¬›+ ÀÇ1p hA _Rάöjᵌ‹¶,PŒ«ŒÜ _^Aì¡TÀxP€ØAXg\—2æ‰@‚ŸQï0D1Ä”‚ ÇTÜÁÉε¬8g#ç,¨®†—±dØHlõ ”yÕT6åÝ|+± \·Ý¦fê ê¾€£# }[ÊW;à Hœ¾ZR·ÿµ³ZÒ—?Ÿa°jlF:â”Ü ûW†ùC^Ž<(œ ð ÈŸâ„`Ãg=1X'NÑ·1(òc`¸ :“‚œ‘Ú€1ü3…Ô”½_¯òz,²8v‹äGßòŒ‡¡¿dûWÛ)ZPâäŸHîn,+™y P6$a¨LÒœRµ„-TšŸßI2;aL–iB`Ö5 h ˆŠaÈ–Á1 âSÄ ËM.“ ¢3{K @D{êòµº[/„„¦ÇxÀ¤cCþD+9„» Œ¼ œûh¡Ç|8Ψ!ÎìºcÃ\•R÷2û¥;NÌ ¸Á¸ìgœø8Q°‹fÂ/Þÿ¢gк%$ÐB0'æ@Ü™Ül¸¢+Š´Bü›AE2Zè·[|oÞ¡WH¶ÀŒòLZ£{D‹C:ªã”=÷LÆ=—;Ib(€¨E4˜Ü‹#©/µ%uªZ˜Ã†~ÄdÙ€««¥$ ¡ÔGžþ*!nÂe Ü¡r§adä¨Ü°nk¼¹¹|¶)Ü¢½sø€Vú|À¼ 8$ïá^n;Ýwûh9@(/MŠÞ£,OªŸ#R;Å£…*%jèdËó‘¦X>~æ! ;=Pqb.æHf>ØçmÊè¦ßkèg½Ò4S0CP`Aàf±O¼·»>&7·Â ÿÿˆü\ €@@YÁe®l;Œ+"*­‰"Rï-L¼ MDZ¡T,Ô@ת-T”X†\ÍØ¿¥†L.›Ïè´šå 4X‹@Æ”u³&JɈQ~— ¢+Ó,|EM3,ÒH8Ë&Ͱ,\^³cÀûüi†ê%(+Q )ê ˆ‡*I+š-,¡h(,^Œ3QÌR,šVÿpê&PˆŒ\È`€g"'àF˜€ýrêÜɳ§ÏŸ@ƒòhƒÈP·ˆ 5Ñ€!.@¢YB5¦  š¤»05¸­ñä’Õ ªt½¸tEaª<}ùD[@s[ºÌ@¨ß^œ–0JG„|4ÔÃÓ¡ÆÄ†;¤ÍÐ’³vÆvÚ ™ÝÅôÄÊ´ Zg"-V¡PöB‡™ŽEÔ@Þ<—ÿêÞÍ»·ïßÀÉpŠ@ÂÀð(„D )ÏH¯w¡@*p²âVD)7žDgƒ ¼`×À† L¨0ûÌ·X†¾‡_‚M„éиÿTðÅ DÙH CÉq‘^ùôÜ…d4ãÃÕSG%0ðBWmP_td5´1Î  äf Œ'y!V!G•ÈRiGMå,HS%/L¶Â 8Õ \;l7†Xf©å–\n‰Àz"Ì4^rËæ™"ÀÅ šÞµÀ‡`JH†Uœé™™OÄhš7?Èòæar†›"P•Ph.BÇz`îh…±ðÕ夯*‚e‘¬÷@}v¦Š,Ö@‰¥¡hÁ"LðÀG)°¨}Ô@G>*wG'+È&¢vœ Â5Í(Š™Š-(ðÂg5TAߤÿÐF+í´Ôò‚ pW’Ù‡„ÂeÀLÐi´EÙ¢eÐidWtÚRð®dÍb»3ùË „ € Dp®Á©aÀàÈ9!>²èSí…HðÂL¤) \0À Ø æþ@ÁIÔDzxh@ ªB¢Bèð rh²&¯,T A<°ÀB¯„Z Y”ŃN¦&²wíõ×`‡-v/ÍÅU‘j­!"¾FâšÅxé¾A2qS1€Ý¨Ç.ûì´×î¶Ú¶ószî@û.„Tò.üðÄo®`ƒ¤Ö/‰(­; hÿJ€1/T€dbhýx€ž)­Œ#š©¸RB< RO"C˜["p7±@œÄƒVðÕiÈ8e[ƒø3”‰ÐðPË%{4Kf蟣ƒ¥ì~d‹x€3²ò Æ˜1.}¥.ËQ¯u”¤\ºcm<­n48ÈD«n–R­Š'D@"ÑÑ:d6Æ{ª`æ­2£8 ,Pªú„‚ A–àü v6“@À¡Caì AÑ/£ƒN5ƒ–‡5‚ᯠ(ï*R ,r Ð@L¦‹‘!= ºè,P^Šð·!$ðlPtµ°ªœ\‹@ èÿCð˜R$FWÝ&pE(!t@Ñ}€mU¨ \ ¼êú…Zà˜P˜˜eÃpá¹_¢H°ÉyC‡×ªG HÙâÊ@Àaáµmg†¥¤æ¹ÑÀtÿWUàwºF°<°D˜·+˜æ<pU40€¹ÀÍZÐÐ^…P2(1b<ðSW § ‘P™ H¬Òé1Hpqà$¼þvÕൡlj253@¶öšP¡ê´P2Üg éq0´u…/Ýà„‚ó‚Ü4X/w¬¥E<ÐÙ` „Ž*âXzQµ3Œ‰'l`Ÿq-Ks)¼F4D!œCÿÖ|g¼Ù´±kaè,BÁR†Ñ4¶s8ôNx@y†UwB˜Ëö“¼È$1‰ãÌèÖ ÓÒd°è‘Áa.¼µ È$u Ž Ð8y0°ÑÆÞSÚPw`çèŠÐsMÙ5°…cŸ1 &|€F§ ¹fs»o&µeHlxÌ;Юv<Dvqmnpn¡†¿B0#¬±ÇQ4 ˆM늜I¹uÑñ6´0É&Õ0®€\3+d3ŒÌÛ”CuºØPˆ“É2Ð)ñµ"^še¡V•¥'y©Â…GÀD5hql<@€nι—lH´TØÿh‚°t6 p÷xþ XUp¿ÌÃÀ’(MtiñÀH¡ÊI…"íÀ8ÛØ‚V½P4Ô ¼ªÄ®·ƒ t d2ì !q²éíX Ýa‰¹¶ìL`ap‰“ìk©S¦êK'@ÓŸŽßò Bõ-â)£x$Ù·!#HÈ=Òeþ î”M(€…èÊ/NDÚM°æ*¡f©ägözîýC*æÈ†‰!pp¼ãé-'lσ'7œ=1ùðÏy†³•£’ÏìO}ú«® د2ÊÓfdÛQŽ¿Dª p?J5:Ýžh@fœwÐû˜‘à!ñ¡mÂ}ÿÓ>î%`UGÁ\+€W‚E€ØÀRK-ðK$äZ­W€Z÷ÃôD×:h§v¨ÇRügïekEgJ7 €žWP‚°fE L;Rs5Px`ÀK„v Xh¯uÅÄxE}p0{L1xÉbv%x'X *d,#{ð `U–ÀKŠ‘Æ!€Æ‘cÈlàó|Ñ æÂÅWîÀk’|R eaÁpQÖT5v A•Cqà1(W¢^V”4&‡ ð!Ujpf¶Ó ³@o¸*€opK©}g€WYC!¨|%@ç$à àÆsÿ²‡T¹Ô‰SvÃY½RRN+Ð*3~_T~¶ÃÛ1‡s‚˜;Pfñ[69‰•°¼TfÉÕœˆ†‹·]!Ô ¹„nщT€–&¶ÈfB!kü7VYɘfe–·"ð cÅÖsFD2È$ö4gªžÿCa¿¥š¬ „+@—”AtøY8ѵ5•DÇRÜ9d!Ä• Q¦…˜ïø„QdU‚YX¾¹ â >ýö(ÁBª@P›I0¡ØÅ.áH¹¥i‰L‘/¸Ác¡Y|ÂpÀ¬dåp.QÌ" WÁ‚3E$U²J 4)~¹  ®°"EbDÅËikû˜Sj o¶ È„Tì¥<_KIÆW×,íÅþX*4š9”n&çY%º¾VìI0@)ÜYŸ&ÀKš› úqÚf) ¼¤Ìy ¼´'ñ‰ À ,epÄkj &dZÿæÆRô˜nèÖrâóc1SqA`„2,õ©Á ê÷X g.¹š8:C”¹") QqÆJUp¤9“’² ˆµã5)¨ à0]º“Г¼”½'LZ–‚JI *ŸØ×žeâƒÊyj*ðW<ЧbI2fQõ¡QÓe¨™®% o]¶§FÇV5.6V󩃪՗>i„¥B }5À®E‡WÚhð¶*VµføÇ ¿4Ü# Ä@XÒ4«aâ’±*Ê Ö›–é2e} ÅW;ð&CZ¬²»d­„ˆjÀ¤¨# $k帡ûÀKÿ×¥NžK Veì%™°x_€WJ: {šƒñˆ°+°oj:ºóã(̘¯ïY–v¡QR¦;p­¨ZÙÈÞº&ddh xëŠÂ¸~æ8t’c9!Ô¯³hÊ•›¦úžÔ B0i ôˆáC1¥.Vz¢ßB«L —»/´2ª2b¡‰gÁŠ5´éP`i‚r±~u¡ (éO@8˜H[:ªp®d‚t:K „ýh[&d(|·ð*£ø*Wòf€W¹ŠW™™’ëžhÑxe¯:¨¹VÙ£žH¼åV~åQuàX~?Ys^þå._>æ1ænc_Ng_ã>Aæjs[çr>çt^çv~çxžçz¾ç|Þç~þç€è‚>è„^è†~舞芾èŒÞèŽþèé’n?,î5ÔÕ·åräIž9½ã‚&BÿfÍÜ :éƒ#1ß‘å]hÒ7—-#4TCüRÙŽó0DˆsDIä×EâDÛ ÀH´ê~=ì²ê E¡h8®å“"F­’ VœÖ m$âŸ^-s”×zœTê¿aî»pêEíA7ĨîT­hp}l²à‡}`%¢™tã@1àgàIhJ„Lœ§¾lb¾þ„éd éXò{¶@K¶´í¼Ð¥;p\fe°²³Y‚î³MdÀÞïŽN5œœÀð-P¥ÀÄ… Ãfø¶AC8çt@Ú¾ÁškÀ `ì”…äÀòô¬õô"H²¡tYÿ6ÁOtc´iàðX2P·`—è§hts¾`ñ5G*Ÿ%±8<~!Ÿ ¯&õ˜ ƒsöØ% 0E¤k,OsD[åô¬4TÝÝï{]}ßTT/ó+0»”q»rHÂCûõ¼ÇîÑÒØá§"[ÕU_Õ÷QÿÛÞÍæ`/°¹3öÁQö¸pöi ±€tË$ Õoßµ\¶Å ¾dP÷ ¬Êú Æ…{B1Ê,³^Y—E‡º^Í µû®Š÷¯ÿTŒ¯Ž-Ãk h±5[P[£S21×4 vþ™Ùt0\ÅGœ‘«ƒ’‰FÙ£ÉÚÑå`ëŸÝEà5 ÿ¶}pÚÓ0êe ”Adix Y4Õ ºÐQ¥W­ *V 1ÕXLxŠh ÌF³ މ`@`”‹”PíV¼@  UOímDôÈ-Øx!€ùý16:>BFJNRVZ^bf±-LLB`69 œ|>¨ ¼©HNÌ)È*¥Ê&$ÈR\2˜\òöQRh±-5äÚl8D¦nhÈvƒ‡«ìt‚“•5ìy`°J6\x€ÍxxÐ:DllÔOa‚Ð2y)(%a€˜¨²"2¥QÎ@.U1{˜ÉA@J2G\E¡ \^8DÆs* 5¹'c¾ÊG´â* BMÑN! )bHÂCØŠ.^+«šèîP…¡D„®«çfIbÂÙD‰jÙËâ’—¬Ù%4›Ï:§M°´6÷Pa…$ [RÓI,ý[f4ðüÑÖcÃøés‚ª‰ºaÖµªh-Äž¨à¡M¨êbmêZÿ"&ž!~èRü6iSL¦`L¤Œo=¸à? Âvªï°h¶Üª »*pÜbŽ´Éi²MÀI3ƒ`Ʉ޸ôËZ¹#à·¸ŠßÓr+x÷ ±„Ë{:Òb¦êÁVe€ÅŽ˜çõºã æì?óÀ€8*r^7Þ3Ÿ»C?ðÌ{Pa»Æó>d ÿ ¬h1-n „®Y× …È\#Ýe•“Р4rQ`ôI„jN ½°Ê º—nŸSÐ —>¬ÃÊâïÒJ„‰a[€x@äœ÷·yaèê¿ê[™E°+Å6°²ô¬‚zÝëÌ^ °½P¦ë Í5ZË uÚ¹¡DQáe‰Øs’|¨ØÅò˜^8òU樓²®«ANÕÀÉ*ƒ¹V<àᨠAbÙÊBÚP›Ñ`š°{A.¤Œ€\€ j¹¨ð#>1&=¡U¯)IÒŒ~ßæà“Ú×t0Ü+‘R2Ÿ¹¢N279©PEFÞvae@Õ–ÿ`u«¿c ¾øó0À€dRp ²:ÙGã™êãF¡C!ß2€øÂÜL± N i£v!t]¾¨zïi‡&ð¶z(´ÊØ—š½E(ˆ]Adϲ·åš0Loé@šj®Óbä¬ ˜Á”Zãûºð3™ª’ŽùøB儱fñŒ)º²ÉMP‹^ĵxwÆ—\8ë[;* í;›ÂI{¤‘ôönר£ E‰VÆ#÷䮚úR_¢Å”ú9Âvû$ddR±ÿi«vUylC¨­7º%j`qøÇ.=Pp L@Q= ‰AèÜuH¹ . ±T»ðö÷p.=™ ÿ \_ô·Äý‰ÄÝKxq×|Q—ûQŘèN:™èÿUÞéñÁÔÌ>‰ìõÕC |`ŠqEQ°¼ò² Þ)Ö.ÔÅ–Þ‡Á]bКëÙà 6€Ñ\Àxí ÀäBp€@LÇl À¦hFÒ1ÂrL‡¥ ”‚t@(áP&¼V%@‡pPÚóAß.ØÑtp!’è h€pö°]Ÿq%H¤ÆS=À ô@v\CNøE™ðÀ€ŽÜPÄŸ¾ ºqÜIA @HPÄÁÀ! X„[¦`A Dc‰Œ#€ÿ¿8QÚAXâkL¢—AÅìÞ)Y®1Gý=š € €W:@taz…¢h$¼‰xFNÉ<T¨b©Ecj„O/eÂ4‚c8Š#w|a«eßo U«Ù‚F¼Ð8Âc‚Õb<îYÄ=âc>ê#$ÄJåÀše9IDÖQBîìßÒÎ>2¤!ÍcCZV<°#DRdEÞ íáŸñŒ,ä$d‚!€?á%<ÕDZäIvG ¢$"¡É­¬äKÂdL¶Ú-µZ,ð —Lê䬡ÞNúäOeP®$M eQeVôäQ*åR2eSZÖG:ÿeTJå¬áIUVå÷MeVjåVreWzåW‚eXŠåX’eYšåY¢eZªåZ²e[ºå[Âe\Êå\Òe]Úå]âe^êå^òe_úå_f` æ`faæa"fb*æÍ`$-ØFÎ!:åÒ¥F  °AB&˜ª,&EMCMÓü£S‰!hv¦ÎÄ äŒ¦4€ô!#€`Ào@®ôamÆf$a(£|H€@F¦á#ý¬æ³e˜ENTåÂef„’LŠCEÖÓJfŠÏSÅ¡$pfŸ5JøLŠIZ–@v ŠMljV°Å€ÏP‡cž&c"ßÎìR£lŽQųÌÿÅ5èJ£àÑÔÊu '&@å $¼šEƒ'ÉÈíI'IRg €ØéLüÔ•1L|&X« ÐxUüT#ÎP& ‡?qV¢§ïÅçøœJ&œ„X€Ã‰çY| 9œ°ØŒ³(s^§PXŠˆ†ÊaGJBÚ e"hrVäã€xœŒ @,¨1“2¤ˆ¾¤,LÊÀ(Dˆ^”…’O‰fu/€)&0Çq¶¨Ÿ”c$tMR1€_ÀH Cq ñ yr’BQÆãFB‚Vä)à"èÜbhé>šéJzd|Ö$™Z÷\(‰:)# ÃÊì :‚`ÿjœþÉœBÂ*Q‚…Vø€Ö'lª€ *$()f…á0ÌD„óéž²lp€ ¢â@Ào @ÓS˜À€tT¦ØOhÊ&F( 5jÕˆ¡­¸ý áZÀxÜj «…x¨,±~é±&ë$4K2á"ìÊíA˜-ü€o ÀÒ‚-,MˆFju ‰üª(€°J¡L™$šÂ= áê’X&Àn~Ï,Ü*À:!®F€®A¼ÆÞ¼~hoüFHÀ<ªÓ©œKP€€ˆ^¹ÞžX¡*5b%ª©ŠÏ‹ZB°ää¿8ƒ ”MˆX \ƒ¨ŽË€®Z:ÞØ‚bÿFF¶Bpògp1 ¥LÀ›6A¢YWÈâ,Æ‚NÇ×ò•š†)ªE -,*µv-è+*’­ÔÖɵŠZ04 ÞÊR0L Ø@ëH¦Rõq(%Ð p´ÊYäD@Np*Ü:¨,ØÆ´NœR.X@¼éÙöç )ZÛÜR‚ht¢ Œ\ê$4×ÖV£\Š'u'{}¨çú…ÓN ô4®pBnëH@¼Ðkå2PÊBÊáçØŽl¦ï0\€ànAš^ÖH!-¯ÎæLÍ6Ânì½’!#4k’ Ç’Úc@Çk>@ž#q¶Zl„ÔÆP8çº$œÓMJ¾pÿ­ÜÒcä!À ì½A¬øEƒ!ÔBëü¦Wµ6AܲL¥ …,|«ÆQ˜¹,-œiÅF“ÄoXgû/Ö«À•6A¤zs|‘‹lç¥ @øB'mÐ4a'u*Âå0Ýîo%ˆF*dCpCëJËø:éaMÆìˉ*ø û’D§X{-Ø‚®šF +¬sòl Yn@\A¼ )‰\oˆ.&ÈA.b¯ |1%¨ «ø§p}.á8J1åZ®¨B«éú(Ó*ÏT¯K|d¢A0à/ó0Ø&Æ¡ŒMO@°Ý;Ôk*yAÛ6èÛ0'+lùf„,lÿN*´)Ý^¦ CÂÓDÐJƒ¬ì ³rIp#¼°íjQüØsrK5ÁÙ€gÿ]ÏðŠF¼Ò:J‚LÍÅ)Œ™…/š‘Må±x8‚¦2sPòz1‰uF¼P‡–t&œzÁI m·Õ|º²×ÔÇ|î.ìi/ß±Kº§ë€óÉÒ¬:žøNMöÖöN«40ð6gH'€8SBlU3…#w1 ü3¡xr+tRéÀAGpDt†ñù,Öü,¨r4?(#¤‚¦‘˲iª}ìó F¥ñÅæ‹ô¹4B7qt"j0AÃ6i¬ÐÂÒVÍpn(oÏä$ Ëÿ2Jw1#i)²7ÃRNî@$¾ÃÚšó°h/#$н³z2Ç•ÄH-+,±ç8¸t jÀ PÉ=0 ë”ë4 ò#À^´^K£˜&StIƒá,•íY\Á—ÆÞ"ÄuNŽ4)pB˶S7p,™t[_lKðŒ÷óíðŸè0üCÂI¸T°Xiœ‚V£œÄÌ(#Pö»X¶)3RÍ †PÁ8,Rç$j©^7ömõ ¼1»Ú³)•Ž ªžÔ¦ÈÏ0[ÒJ3Ðá³#ÔjxJß'ÙßD2Pu…¢ó$PvFK³­w“t–-\®®üCpv¶Kl·ÄzÿAc§@ü85%È@£ô ‹©tecj-¿ôÿ4i€÷gû‰Î ´ƒ\³§RªÛb¥E´…¹€Ô7(Ͷv=øSÓ¯5ÃôR¬Í £†C?BÑAH·btõO(24ß_#õN•”)ð²oר%jŸa!K™í2‚ï¶‚Óì7m¸×*rz?6Ö6N´{2 šï\8yñà7 y8 ÀMHŸ˜-9‡8f;³_8‘ø° @s$˜Ø(Ä_xškRÅ(ˆ–û5,ë6àt8!;'vPšˆ³5¬)µ#„¸©H$@9·8b¼8£ZÏl!\;{ùD‡ní0PYÿ÷[·žËñ’ñ yÅ8÷!ÅÊCÕ&Lä$ÛÂ$`/pEkB‰óÄòâM­©·O—çutU /ô™o®Õ4R]«•‘sG“;x©³ã¸õ°¹žŸT¥ÉkÁ†Ãí ª ÄŠ'8¬¡¶#쀊þA‹éá¤/ÆqOBOŽK«X—$×”ŒiÔxøñÒÞà$·KL«§¹vš´ëŒB[›hÄ ’°-7­¯·£tÑ‹F%Ul (E÷ |8àzh·;¿"û…K‘äÂ];ÓÛu$ Fȵ´‡Q—|¤aüLçw,7s˜$*ßÀ|J5º¼á|D¤sSÑ»ÿ;9Žw“ŠÎ$š*4•¨í\ùššG¡y¿WBߨxTxUËòt#rV¨PR…¡•:†#Ï…44ë2¬À‡A<”ëSÙ³Œ  ËÉÊx®sãKƒR—·ˆÎ[Ì­¶,%¹ üïÔ<ÖCiÔ4¡Ý=ÚW‚³“ö# óÚ§€ÛA€T…·6ã·ËIΠŸ|ÕkÑâ¹¥AŽ5BÅ3ÂGgÂ/} À»$ðL˱³†ÌÌ\ç«Î9p%kÏExª‰:ŸÀÈ5œÜx„µBH° ¸@ŽAþÎ5¹{|¥ ý@Ï2ëP3ǽcûÅÌ©ØÌ±ÂÌ ÈÜxhé–¹‡NÿðõÛiX‡´Š €PÁÐŒªz̺A@ˆäAÁú~L 0D’̵S•$¬x$ÃJ1S¨³ÃÈèî3Ž38#œ×T«N°¬w„Shx¸I3ŠVa2`3Ò¶‚¥"TaSr3óâ'çôa…@@s0³ E‚Q¹b0˜„Z´&“0' pi:{‹›«»ËÛëû ¼0Œ:C5ã°R7ãì›ö,“œ€áä°!<#~t¢á¼<6“ñ ¶‚L5±ä¥“1³g”&~æpì—*ޏpD)*°Ps¦MŇÄvÀ1˜äHÂD'ÿ%{ðÀ’ap 0ˆÜlèF !ÃÅ0%Øpò@] Ô%S•ä^€ "Ô[AÉɘ&œ€óQ¡†ˆT@@&B£+zšq¢±×T÷nÊj 4•³|9Y Àá(4XIz3ã£xÍ„†ÊŒ«ñÊèP0m»»†NÌMB‚°Zü*[¾Œ9³f\\Š3@ L ù4£­á‚+G—v‰¡Å -wpó¬¸Í¼u4pÐõ€ ¤ÏX`=ÃóŠ RaP°Õ"¾3a{#€0ae„6à:‚L- ÆÃ@æ¨CŠGL|¨|…Ð×7~I`A‹ Bhpÿ€S`Å ƒüÜJtPÚ!Í ÙyØiÇ.X@@vl÷ ,àÔ í©T&<À\pÉõk çn¾úúJì¾þþ °¢Jj¸˜Œp /îÂr‚BÅJ…}GˆÄ:æð«ÿ¦Ÿñ "G<@¼ [ñÈ&ÌrË.¿ sÌ2ÏLsÍ6ߌsÎ:ïÌsÏ>ÿ tÐBMtÑFtÒJ/ÍtÓN? uÔROMuÕV_uÖZoÍu×^ vØbMv8¼°­±À>LÃe[Ö¾;@±òÛvß/± ÷œ/BnïzÔä9<à%˜Sz)LuŸeÁ+MÀ `€ÿܰû_äT4™¡ EÀ¡/5…É7Åâ]MìÐÀ²N{íÜ"€:œË’“3·RE‘`*„HM³3^Ñ/¼ç̶3Rc 4‡Œ375pâ3lÃv¨¶‡ƒ{‹€ŠÇߟ¾®CdÄúœR‘%NTDø¤ Ü¿0k@û />¼¸D8€ÿ€+@”iW‰ FBAõÏJâž°|á¶ôå‚ æÛP ªpSII$tq• < ˜ ±Ž·†“ìNQ\/h¸C° w ÂP¸ÅA:”U·Â]¬i hŠ¢¯(¸‚ÿDÙÐEzV Ä–+ˆIp½¦€‘¸ é ¡!Òvθ†:õâ›D÷`¦´ FdhÔ-nŒ~}ŒX†ãè `´j@ä4°Èþ0#À6`làKìäˆ|À¡°äd%üè #*\òúq­~ ´Â¢-oÉ‹€‡ œƒap‰öÜð?¸Ð¡.Ž”¢ä$æ /ä¸ ‡ÑD±A ’øB÷P²˜Ý€â Gö”‘=BïIFQ‹EàÉð#§A$d %3h&T@…FæhWiå4¾üT—-èYÌÔ¤à$ÕÁ@´à¿Àc‹Äÿ ‘éÕ€ QÁ¸@æcÂÐ7T „ºè¡ßðs"ŽpJ !æ€ ` 12°’8Q€lÛêV4À)ªh@¬`7hÒ™#XB£$ŒRaœ-ˆ€$Pí©@( R1—«¤ ½¤ÅçÏ3̨Jm«Ay‰"‡I8 (Páë!Nì]¦¹2q Í4u'xˆl¯sB ÁØgP!%t‹¶'ú”e¨èÀ®â2T‚x mP‡× ¡G X¥'Ÿ( ¦A çi²}žŽ 3Œ[û[3î5¡Â 2ƒ  <*ÀÿIà€’°«w +ÒÈ"—×l¯ÜÌÑ·Mlׄ×äÁ3(û% «ÿéÉN{ú AfŒE„ʧBâåuK$Q‡=èr ÷ØHÏÅ„Á¢ÄZ žƒ ŒÜK¸1i ¦ŽX bÀ @¡Õ2ÂÏ `Xj$ì®Ñ)XÄ®º«‹Ë®å…ÝçÖ mN€à ÛªÀ8æi77ûMÑwø="&2ð @¯¦1ȬF`I8äŒp )7R³Üj‚b‹¶® à‘¶ «9¸ºEn2ÿè62øpWó¸`ž\V’Ò3S׋“¤é*EÆ21fÿÇÛ†ÐV»™Me ßa…a„¬G“¡à1…¢©V¾g–MF7¹’à ¶Áœx„Â\³«qI¬4Ù•3k\õm3i³Õ {n®0@<’ÆÃN#ù†Bç¡°k®0°Uý(VÎEºòuX¥G°d@!BmžR§%ñi>4ØŽ7 "u2°&ðç«ßm˯€—¹øå<Ý­Ì\+¡‹zN£ƒè*Þq—м°· @¬Ph@Ú'H¸*  ãúƒàúéÂPaiýj»ˆ„Øæœ_pßsËÖ¸‘íÌ O!ÍÏfé„ ï˜GQ‹0€¾ÏðÅæRa§VAö†psÿ'„1½n-oqØczüÌ·Þ°“ŽÑ!x„˜•0`èÄ©o€"ãÛv~ƒ.’oú.òvBa@2ÀhÁÑGž¯À)rW@&3,ó¼sí±Œ>z àÄ.Ib"b{87ÆÊäU~3¯ï¹‹¤ç‚È`4G ¹áa°ÌÀ±cêÆ…ÌéBã„à¿Èú¿²}iŽ^à.Ù·® €p (W˜§ š›ówDÁçI¨Ì=4^\ó[ïÄ/Ûú4á¾tìèWðÓ¨PÂPÀ ¼tyJYúoFâÓ2ÿ¡dÌE“.&A T:bçâáMç ¿û!à1èºÃ÷Iã¿¶ÿ7:ÀÖ-®0×vlƒ ôc@1õð We"wÞaUOâ>ÄU^³C¿ÇdÀQ6bgý'"Å'‚cCD‹E{m 88!Á<Πlñ 'MÓpH¢ö$ws`R¿p ˜U§ñ`q× %uuk¼Pm§q©G?Ëã‚ϰ€b{ðt ±Y˜õvDµ‘±—¥#h†W£7ap›£›œ8þa^²¬ò°%ñ`fg0S+!]I²$jJ¿ yº $©P+0¨!=«Ñx±ñr—rÿÇ2[·]§z*PÿðÂi¯çiVØ^Ÿ¤9¢Ä¥´¨¤×{K—Stx†½è‹¸²ˆÈâHV6÷ xkp 5âXè(¢·Tö‹Ñ(,t™¢,§ãs¦„¦·5Æ8 Ì6Í!+¬h- 7爎‚r6,—+ä„» `7£$ p ìèP$ÕÄ=e˜ŽÿYÃZãjU&·7 ð’¨ éo³„bSNPAƒø‰‘°6É‘é‘ ’!)’#I’%i’'‰’)©’+É’-é’/ “1)“3I“5i“7‰“9©“;)ëxÏ@q8€¾’nxG.àΨ5àÿ(Và¦,àoÇ“ƒ¢7ì´†=0 ¯A<± "|q*—u´Ž$9‹T91€9ŸÃ†¾ÁoY$¶ÑF x¿ŸÂ‰×¸ÉaàH"j§ À² ”Lé/ ppàOùO¿vN©˜•á”PÉRI•~‚Œ)V‰•®ò•™6P™›‰+Œ‰”ÖAšá°|³0À–™Q‚ЛŒö ¯Q&¡n$@<~ê¨~õÖ‚ú(PaAÍUNÖ£Ùã !‚A© ‰,Dä™e™˜™ß9 J‰ÿ‚•©žä¹R¹ž i'¹ 'àÿòˆÓ›’šðS à”‡™,ãÙŸ›Ÿúù Êø zœ–q|íc‹³€;°—õ øÓn“¤’ð|¡8*Á¸x”@ÿÃ@¤}|„3%[ó¦AþÓAHxž¹°‘¨™`âp@@(~døH›ì9à7º/ §X•I]Bš®)ò0 Ú2 p•<å àVê*Š(Zê %`Ëçþ(SÙ'|G§éKÝ;cÑDùfŽ•²ƒ½D–2DóóŒŒG,¦§³0mÛ8”È#ü`•µAN ¤PâÆ£fz = Ÿè ¥°£¬I¦ÿ€¥ƒ¦“š ÕB€cZ F (§Ê @Mð@¤L*½)4woij§:Ö9k:‡‹³Ðkl4$`”: e… ‰– 7¶ügM)˜vܤ¤³ Œš‚Áà@jUG$ ÀLƒgð!- ³&·žõê¬’Ф€¤:(Tª¯³q‡ài‚¤ ¼j9Nyté)«0ÀšÊ¥é 40]àñºR°£ ë5¯+0 •šÍµk‰õF² P:Ha¯êù @ W’µU²_špcú! ¯“$—°¯Hú­™ñ¦Àõ“ÿ6;ª$†a Иÿñ±0à»ê‡0!ë%𵩳ô:³•‰¯JœÐ¥í¡©# •9;i¨¯T;oz¶8 d°~{Fà­ö&eçZÔJ¡Å LŒÇ\00'{ͺLÓ@¤:˜œ³ M» ¬ÛšDi5ÍÑ®ùv´s®Çá°+Ó¯êð r›ùùµŸ:°EQ™P·» 0 ã¹ªKyg­ùs´«Ó£žúj¼å:nLZ°LİÍu­[FÆÛ{ ±¡S™Ù›•¹¨N)¸ë½ù€Ÿ•)¾•yŒ4²ñ: ¬²¬§a•ù©¼ Š ÿ  Vy±üT±°öa³€¤ë©B°ÑÛ³R–Ÿê¹¾ë½ù)•…ÆÛ[¼+ ©¹@_Z®#«ˆ5 çKf »Êë£!ñ¦  ¿êyŒø{Þ«LE‘°@·‹©1 2P¯@Pªq!·UÂãùÁ@‡à¿6L¸s@NùÙ® ÐÃrkÿ¡P«÷ºG² ‹`IŒFùPˆNR0R¦¸ äã";.Õ'€€0ZS(qS9uŒU7¡Bé-§ øùh»¾…TÅØ w1¤œó¶ç1žÕEœ•”å˽;ðŸÒš oÊ)Ð 0ù0Á¡°Ëa®£`˜ÿ2T½ªC<¼Ø»æ›ê‹y@}pk³¿ºJ y…l"ñ{V™Wez;p©6ðD«cp©Mª}°™¦É²û%€¶T1¦5ÃL¼g°Ö[­¸™žžÅš à´Œ¨™npÅš÷Ä <»J "°<æzn>JÌ=’‡$: °0@pÈqëQ¾I€˜Ç\p­*»9h³þŠpu-àÈ)Š«d€cV§¬O*æx`È]ˆË;Q XØPÇ0p)¬¢XÕ)IŒvYØ€Ã_9Ú*&ภ̡Y+ÁAêω ¬ v*€Ï¦é唨lÊÿ;0Ã’Œt•ÙH!7 =Ú}57¸A²lâ°g±Ô‘ÍN Ê;à”Öé¼tªÁÌ@½³š â•F³ j¿È¼ÔS0×]Q™µa•¦`³Ãé¼JýÈ:ÐÔ„›Àº!¬ [dsá¼µQ®0»JË_0Íø”×gPÔ8ì€C=,Ðô'¼ç‘Ïu ¸ß¡Úìs§›-'Âå ÄÅz÷kÑp·£ ¦xÇPÆ×åÅH‚Åâ@¢sð]ÙQͰC Pc`Ôê ´ŒfŠ" Úšo½­ 4*dÀÅ·à«ìr® Aú&×í™Õ²ÐÙ-å$•š…¦«M» À:yÿ¥ý Áô;PbZ†]½¢J0ᦞà”$•°ûYì{ç- mX‡ bºk‰Ÿa˜Ÿ€%¦G×£—Óœ aíýOÖxôÖ=úªr0Î÷ËÍO ¶`ä”-ñ¦8žŒ!¦'MÖ¤èëýÃ.ãFáV K„{Á aú'¿datAßâvF—"&éSXOÖýx¿íx-E å Ã=†30cËí!pPdËS2<&˜dÈð”‡kí¥k,G`åí‚Ûjs!Þp» “ý@ •Þã™&=*bjŸ†Y™XÁùÉå$Päjý´À ÀgfÊf)ĬLÿÜ,k áÒSéº •…tF vN. Îܳ?ºÖþ¼ófßs’šš’ž «/þG3N‘—JØë½Uº w³Žeºp”Þ˜}¯N ÚCŽG>ª^oD­I0½<'çJ_^o·],GNÔµïèÛW°FCˆ ~Ö }:èÔMhÔ4bb­q_á ­¤Ñv<ºm‰Ý¨‚³Á— N,pè¾àžN™GyÏ ÕŸPë“2žÚî!b Ì¥|Ù$Vê Êk¤6+<à¥æ%/¦èž•¹ðtÅš¡é°S.=±+é+CíFí¯®ñ,¸ž5¯×vÎ\Z·É¼> V-êÿŠÕíÁµ0 ¦*ó~[7Ëþã‹:Ï>Ð* ”o9ÒÞ6^ÁV'Qœob_§Æ†Èäø$€8F)ÎÌɬÝ!yl&Ò–kl¨`­lûèíÎöuµ=zý¾úú-„A|¾êÊtú À¥N‰0ÐÙ àóô ôv‚è³ÀŠ•Xðèkà×ñ™ñÄ O"ašŒm9’/Ä•£îÙ0ïP˜3 ìõÈ|àríáK-¸ù›Í©}’Ö’àú·€¤\ÿàˆù¦<M¯GƾÀ–û O/|ÌÙì9ÚÆêÓ¾û¿@JÈ(7݆+PwOúMHÎnã÷ÿùðo$†Üí~ÇÜÝf÷  Pš@%žå$f«ä 8Á–ûÿ©a‹Æ#2¹%£)%6*Å÷4üžŽÄÓ›’˧‹gfT <Ï ñ{¸¯\ Âã¹ ‰YÒUÔ Æ_Iƒ_ …GPÕU–O#„‚b B˜Ç‡@Ñ‚#R”ÏGÆŠ!†ÉÕ§ 郦¦Dš)`“ChQXDÎÛ‚IFî™çf§ìÉ‘GѳIž‡‚‰¯èQ4·-’w6¸-E¯‰DÀ«‚ÍbÎD€%’{üQ a ƒÍ8>3ý&h  j° _ ‡þ•€€` &ÿi³!'ÇŽ1¶†+i²â:[<¼8ÙD•°Õây(v‚C—.å$â§V|X€£€T‚>®A<ᇕÎWlšxCïšÒ§Ðý€ù£Ò6T]£wÂÛ¨RGÚì;¡ ª‰:Tõ`¶‘Q‹ÐQ³b—¦DVN +2hæ s×ÄLÑ ‡U¦M‚ Ý›ÃGÏHúݰf£­¶¯°×@{I ˆ)åA€±'šÈŠÈ ê&5™ëÙ@CîK^Ƕ$ÆÐ)P¤ÝS9pB(‹îNÄœ_3§œ{ÿAÊö‰6¬pÁ•ë% ˜{€Š¢£ÎÁåkôLps-8ÎBD­yB1œ'€à¼¡'hž§P/èj¤8˜¼=8 \ š Ì%` €ß|øX=Là¾)ÉÖ›ÈCPã€5ól;À2'Ê)ÐB¡ eÅôWŠÑà×B¤*äU2"X‹äTY%WÌG €@™nÙÆöÙr:KF3”YÌ8“ ØÀ i4 ‘˜0á{Ú)€wÞðmÔƒö¢ ÿaÖ±¢áp.Ú9jÂqõŒ:ÎFÐ|´¤&=)JSªÒò‚F+})Laªž˜Ò´¦ÀA$à#›âAÇ‘ÊàQž8í¸‰ªÔ¥2µ©DEÛœ*Õ©¡_î¡*VÓD„«ö°APË@Ǭjf{KV8 R²²µ­n}+, *Dâvp½kS°€à൯~­ãPÙêŽ"ñ¯†=,bÙjh ìãkb#+ÙÉR«­,f3«ÙÍ‚ãOm4&’ÊÙÑ’¶´¦ÕÄXO«ZS⨵®ÅQL¼ùÚ×Bvµ1ílÑj[àöµM ×kCÑZÆ=.r“«Üå2ÿ·¹Î}.t£+ÝéR·ºÖ½.v³«Ýír·»Þý.xÃ+Þñ’·¼æ=/zÓ«Þõ²·½î}/|ã+ßùÒ·¾ö½/~ó«ßýò7bë*U¿Ê¸‘Ôë¸àé/8ä6uª´WMS ˆkžTà °TInɽ»!¸ÃÌíÇ2ð@&¡xÀ'€L?-Ó 5äZ8€âö­x è¢ ÀUýtÀ¸¬dcFb ˜­ 8ÀGK H@¨¤©ƒqá&°a?pÈNË`ŽÚd ¶þòi3ŠD°‰MqˆÜÚVЀª-lkÀ–ÅfepôÇ©l”›Pd²Æ¹)xrLó á…4Á"ÿoî E[bY¹ÑÈíGŸ¤°& X@P@òÊ6(´Òû±ÈÚRE›OÕÈ0 E Ô9wNlŸõ,ƒ¶ º¸)`pJkÑ[M 0ˆn`‘$ÿöÕŽ>6iÅ\†é$5PX›Ç b0–íœÍQÅNXÉ`ìÃÖú{Îj·mûg¥†[4½>‚C¢ã ö‘C×È~·j•MÜûêè £Ï0ëRË®ª>6ùL/F`‹øà(ªî%`Sß.‰=F”Ð`àu#@S3üO›ÂÿäÅ;ãò¬[h÷âÙ/¢°‹±€º…ÇÓ`xʉ@—(ÿÀ–ø Uã_ÀˆL<ã‚{Ýî!æEêàŒøÙR tïa½k\A€´}€›kËÜYœ&¼ÓžYyKa;ЦÄ9ô=m£– ×Æv­ œÕ¸¹ÀQêfODlƒÀç4| ióhÈY² mø{U(œƒ€˜`oŽÂÖâÔæ÷Yä´PÂÇwää{ï óih`Èç€ñMIA›mp6óíñµçƒ©m@ú­ù`Ü?£u½Ìõ'PØ–hƒ¼]õÇ,~m²ÒÍÈÚæqGèžÇà1Hò´Ì‘eá¸Qíæ×,¤ñHF pO?‚<ÆÒ‚Pk†6÷4¡ÿ„Ç spÁ¦ IøH¹ æ8Êâ½4Œ€ìÔi@6ÄJãÅ,õܰ^*ËFdƒ˜©AX ¨ÞãÁª@ÄV 0àÜÈÆ–EEPEâ¤ÊššïQ‚ÁùÉš¸Ô|¬Ôün Ò|àëq†›ñƒAŒ…t€¢ôœFÌÙ>Þ¤là Ä T @i¨ ÎIXôƒžÛõÂBXDí €X™t@ÚÔÒ{„ õQÜ´šl›SÙCÓ áƒå€:„FÜ,`ã™’ ô›R„EášèP©…nH‹ÄÅ~äÍ Èƒ÷…9Å#ž€ëùÿ€<¬•ELB X™‚Šº-ß&" ì\± "TbüÃ\E €A4ŸŸØ@ÿˆ@°ýZãÙb¹¡yaJL®Í 8ôƒ¦¡4þUú™Át¬§x ¹Mr<`ØÔ’RØÃH¬L߬ð\€ê‰È   m`:ÀN­I3PÞÜØÕ Žk=–@µ¢às®%fö\_v¥é¦hœèVÆÝÜl§&À„²æ`v¨ dEa¦($ôg„›:ØDÄ@Ε@HyK}ÁôQ¨™®SŽêÙŒ€Ä (—2Õi d_¶€‚Î×LÇ N H(ŒRhGY¨Wí†D®è zå¾EE E·9D¤ù—œ*¢œn<†o\©NèéŒò^*Kw&¢Mò¨,êÂŽBgGôi ÄÝuƒG¬ÀšˆùF)Nª ÿd׌`¦å§ bÛ¬‰÷u)«òÔ—r¨æöÑ缞tr »eD•fH¦.N¶M›frÇsöFê¥GêÄ`ÝÒ2þâš.‘*¢U~*2*¡ºDl$UvÖ(‹.êZÁ&›®€øùPad4k¦¸åJJǬ²(š+”>jKP ì)v((j«î+Q¨–µk’rèÔVsŸò-„ô}£©5©ÅBßßµÀ„àFŸ({²Üà ¥F¯ cÔ“š<|œØL“-ÑA;µÑ8î_Ý6øò†vÀ 1°Ÿ£(ÜÍÕͦ„èI’¤³šj €Mm±SÐ]Ðî˜hÝÜ IqÑ@¡\S´ìóE´j††¦Ø×îÚÎ%Ulèß’<$@áèÑš1סIH€ÙÒŠ%£ æHr ?}: pÏ!2Oí³¡ÿH*A pq±=ï Ÿ2®LïTíOÁâ2^Áñw©K>æò.—ˆåT½-•ª<PiG.ï²Tɲwõƒ©&*8øî-34?㹕€%±¯s4/2{nÜFPçlŒÍï3?OÖ+÷ów)ŸA ô@ï&@4B'´B/4C7´C?4DG´DO4EW´E_4Fg´Fo4Gw´G4H‡´H4I—´IÛVíjV X+Á?{r€3?³/:W”òêQMŸ¢h2‹6cH ‘¥ž´—Šü2$œØ¥ÿ<Øî†Œ!55ÅÑŽ‰OɃ½*±A+×]* hñ.€Q+•©Ï–‘²Fq€ˆŠ6ƒµN+SUÙ¹’3lÙt™P/•*‹êyoœ B¬Ý4aÄYØà+¯¶´äti9Dæþ@LÓÚáf•‰1lL ¤RÝtšÀõRÚº)¶KÏm^÷kÊ–Á¤)eªaZí“J§­)¨­®}š©¡šªimn†ïV'—cKA È´Mu T©C‰ÞT¡uIi6Qqvyx6Qc°­‰p7`o—¶Jíõ0›?•IÕÞ…ßcµ‘6ìvH26iývD6[A·TÑ¢TŒøaÿ6L17OÍñ[£÷E¥[´€Ö¶ÌdcwMi·ØYíÜ[É!DéÐw²¡5#~ûÕ»Qœ²Ž‘ú2ùRpëD½’¢eò޽Xüp2ÒéçQq¤<¡MDQ ]Àª–mX#Ç#>Ò7ÅÖ=Àk$ÌÙáÌ%@xÌR€1QÆ[LQŠxÖq PÐPaMò:Š}QŒ¨€ïy_7fñÝ…q•Âæ”ç”/A¡8 °÷ ÊàÎÿolæ¨qš@œeõÑ /€O±¥‡^+ä!ƒvhé)§ ’ò(’A;ôƒø÷Nì,íùÝíiîí¾!_Ù÷ Üç×*ñ0äºÚTw¥®Cì½úAšºîáƒ2ŽÚ˜9" ¹š›ð°k¯ìÄyo¬ÉXXDXºð#Þì9Ÿ§S$Hq¼ŸÄ2&Mýa6þ­ø%—·¢kuqà8 Àê\æ"ÊD‰y"üâ7úÀûfÚÌ J1¥¸@V ¯f,@Wu`Ü]ÈœöÜ$@LÀkJš×zÜú(ž;X‚90«r¿‡’ ÄyÄÔàÄQã=ÿ „ Hœ²7„>¥9P”ÈÇÌßq¼ÇWʸ³,W™®^p –§,è«Yñsüˆ4 IhĹ·›‡¾9Ì=YnN?3ŒÚ4ö½«æ°\ãØÂé&´‘Ü'â‡cà ÿ=‰˜ã:¾+Gø]ÙÃÛQ¾p‚ÀÐ$`Q®KA k EqÈ€‚Â$‚*¥C@"RJ¾Nv,“ªU!€‰Žå A ,´¤¡À/§€%°À„³l \5v¦ÀƒtŠðõ%q,C2Ir1n=(QKBD1F‰1(7+lf‹Y%˜ZW#•‰we12SƒZ¹Grk~ªZm{ÁÅÆÇÈÉÊËÌÍÎÏÐÑf Ê(ÄŸ›g€1 §©I@%Þ2Î(Òö÷ÅÕeK¯±8„+Áê‘44Atµ @B‡$LxÏI¢&K¨ÿHU¢¤Wúá«„0I p‚%yá¡„è¨8Aìļï4}Y/Á¡zZ@‡¢h…͸kØ2¢Äwªè0¥°ÇP:E%¡£Î(¦%3@áÖ¢®ª’˜UëÖ"W˜ª"§ç² èXÉ·¯ß¿€ ~FÍZ²xb×B]án»‹DåH`/νJhäÈS½ƒC73@…Sq¬(£M†9^¥aӦωEYsÄfXFvc¬éýÇ¢h[ÒX0¥ª+¹³N=ñ:15YÖÀ8 8ò¢˜3¦ÖÃ9EÏ:0jì7ª_­¼Þï­Ì@§“ÿ€s1!ÝEP$üCU[1`“˜ ¦ FRÉ”–ÀvÇUhá…fXaÊhd\€Ã,ÄuÅc$äB +’å‘<ž1ʆ4.Ñ€L„ÂN1ˆƒk°}MW0$Á™&-ªVM%¤× ¿XÁÍAjÎ1 Þ'HBS# Bá|[6 Pö b–À›H>ãÈ$Þ4 fý²ÕeqIy eVÌpF ¯R[8 îªÅ›ÉPðøW㦜vê©…&"Ò©AŸ® „O$PÖbHNÞtW™ŸÒÈÅ¡è=ŠÃ+íPÐHSì•% î8¸DªfÿøàÝ µ¶Ø Ð(ˆrt*šH(2ß×R‚N1·­$P#B m‡, Ê@j‹*d®é–Е~Âp…mÁ´ÁW‡&ƒ;t©"(c®0‹µZ¡M2 ècl­WlñÅÅPÓ«1t𠀊Âu‡/ˆ'ÅK©¥P. š¬Ë‹ñqv¾ ¥!á±¼Â#;ƒ ÐIÜsÊ£J¡òÎD«a•ÕÓ1]r f j0ËGøµ<Û7(l—´?K:CG‹àðõ¸•­J’~Æ›@¶‰¸Ã# ˆ•M¯[!¬8ì/ÍD9óáˆ'Nq¨•B•&7x‹üUÛÿ©éfw(Nñpg3£â€µ,ŒC4u ¹¼F }"QÃÝ1Ü«3Û{„â"òÙûÓ‹2èSðeðþá´~5ÀÍëÈPÖrä2¦v…ƒ ÐÇNf ¤Í ç 2¨Ñ=Ð9ðü‹Æ–‘áVà  €v(ÒÇ*0ÍW x  !e1Èø\ña€T€p‡4u…àBSiÀNÈ&"j‹yJÓÇýÞ×° "Ó`ÃHªUÿ´8 8PB}l Z œŒ¨Š)ÀmXע‗ܤjÖ¹ 4¡(@‡çD¦dÐ Œ@m Cí®@€( àÖjC(ž¸€ø0Xé@ß:ø1tßã&šç ¹‚§±Á+ףÚjH0 ˜ìJ@™ž•Wc™Ò wÉË^.°lÊbwŠÂ¯)¬G—|(Mn^…•³üne›K†Ì|©ŒýœÅ…sDÁ$™œ£;t @-q@G[^á_2PЂ‚‚œÅ‡h&V–¨H ˆa©fÓ„Fß 2(gò’³¼%ê§4¸S6þP/Qkhÿ'1¹T”$ÀAb Ð&žÈSŒŒ)ŠÞi ¤N¡§2 JÃÑóì ¡Íœb Ù:-³iÄ•"‹ò€\ ÈCS|äÇ —o5Ã\ÔLªR—J¦ÒàL(ð¡°¬§˜ ǦŠ/`6_Ø9cȩʸQ"0Ò PU X€Ž–F˜å7¸¾:9ƒ sZ`@TÝ+!  ìZg¢„HÀ.>«EbUG‚A³f$QP °Czq|h6+`€˜  æ¼ $å€K àYèè«Ø¸0@œ„Å€-µ „cªq©­;ÿq Ýäpç„;EΆfˆkbPHàòwý£& g]€n'@ÙÜ‘0d\­ð¯â§ÔxDÓ”¯~÷ËßÕö÷¿ÇÐGÏàÎó=5¿N°‚ïa.˜ÏpÈDÊZŒ³.øÂv ž2Ìaîøu ³„ „Úá› ™­/¡ƒ]³"øÄ0Žq`41Jïw}JSüžaLòØÆ@2‡-,ä"¹4>ò~ÙÕü¢=’§Låø¾¸ÊX¦r’³Ìå.{ùË»$2˜ÇÌ|Tž\ó Ü)Q6§ù§æš›9Ü `ÍrnæƒÉÌç>ûùÏ€´ MÿèBúЈN´¢ÍèF;úÑŽ´¤'MéJ[úҘδ¦7ÍéN{úÓ µ¨GMêR›úÔ¨NµªWÍêV'5Řñ¥IbÄŒ+»úËm¨±d[vë^SÙ«fI ̤ÁFÀx‚•ê[cgPF¨q­ÌÕ’=ËAˆ¶uë‡ €¢L7ǰ-W5XÒº0˜̒!f_3à ¨³|0Y-€ØÝøþµ2WZS3 &+ðOF¯i‡c|fôE8¢ó»fe»®DÃ&wäF½+[·4Ï”og˜ÂÚúmC{Ë'Ù~wüäö¢¾ô¡ñ4â¹Û(pAwd û0¸­bŒÿ%<À áÇÎ ™Yt€@€@Á;­uÇ&¼yG6ªs8àŠ/l¹‹9Žre|ÃÞÚò®›½¿yɈA"Ž(è1Aän$ƒÔ™¼F?/FEút·d‘–De…ØJY‰—}æì^/ï…×à×?`ñÿ¯;Ò,ˆÃUv2e`'§NQÞ1É º’-¨JÖž}Q=¯ŠÈCs+ ü6Dá‘`¾¶³2àÎ TVJ>±ë&P(  à.¾RÂ×Ú (@bo;&G'âÐê±[Ö¦ Wª')8  HöùÚ³€m'°€tP~¸ š@1Ü.4>ÿòøW\ö Áz¢½G#H1°`06îa¤×+UX§ $bM§ “ç67:$pc¥EZWR\'hNüÆ4Ü‚zàÂt cê´P$pSÊT@=@Ð<§OzbqEb`` r•1EÀãd|Upˆvcí”T8C¥T#€¼VT%³s)>¨€¶¤… xÃÖ„•wÏ1%µUÝ%²d0WBS`-;À¼w[Òæ2F5+hˆa#PCè".sÌr @ÀBFä0¯…tPŠBñ– ˆøLâ§x8 ÿâÁ‰zD:wHlØ ·U$‹€q‹ðQ`‹@¦PcŒ7€Èkp_±÷$Uø‹Š3*‹@AlNp'_ÐQ‡*õdçÀ‰d†?Ð5Ðð€È`_³ O.XÖc2×~ã3q±¦E¼È…æ;[`.â kÐ%P/ SŽ ZL¸,Äâ‰`“‘-Ž2rª` ë€e絎ù!Ò8Tc ‰Ð,`0…À8‘3¬°€S Øàñ«‚:MX>L÷cBReˆ€Õh&w n¨‘Ô†·ò„ö ³‰‘ B¾ÒBZDaÅ{\f€)S0<ㄱØþñ^ÿ*µ’8÷„_ç$ø(e-’ɇ¡g38KÖ\aQ© `àØ€~bŒy–9'0_‘‰°NÐ11B€2„T$Àf$¦O¢g/)I17ä -™ ²94©‚Mà 䀈0¨(â¼h_‡7hYÚ@?ñèRpÙMt”&PgK)c<µ§DÕ\—x°£ðr' š0±y¾B#À—¾ò~Ey-ª‰–Ä™–ïQŒ¶G+̸ÂT°„~ã>RC%Ê4¨± Øx ˆá1³À‹¡)®g/”¡IðLd#”ƒègìC†“˜5ž·ÿœ!UtQYwÌÓ.JSvf5$@›%pL?x J’Õ–´VZdTœZ1¬à1ˆ‘1ù…›CÐ À qº™ ùWÙr#0W©(‡ £F´çt%rDÙ2¿©.‚*ª B™eë‚(È”¡x­)h4EÅ— PÉ£ yEJÎ… ãJº¹°@0k01‘"œ2y¡hê)û7uýg@ï± ©vç² §•¢—Al1é”9ӦɉVI%Ù'ùY݃ySä£ë© íÆg›9uI+±ñi”°mÀ0IàŸP0´ÿ°S¥Çp¥+¥@•N2lZ± à.´0a$vi:«µâ耗§a—_È0 (Ì@Áƒœ` ¬É°Çp'££¹2#3DÙ2 ½a ´œ‘³¨ª¤XF”· v±±=nÙ0ôXq¯™vÓ©€8• "ªÆ` 0ðÒ­x ñtï¢q!8u¨‡`°…´°ø eBå5 T'ÃpiŒ=dçŸÆªrÑ¡ÚÃŽÆ£r`™™GTˆÑ3W@!£(™9-v{µÖž~6¿c°ÞêŽMÃÀztB–¹À0ß¹°IÀ/ˆáݘ ¤ú™ðRBÒ”Aÿ†q…Y—°žJ–‚9œ[µ÷ r&àE°EHN0G°Pu  Jv°BÔAPû#Ý1¢,„þcC8´më~ª&uA©AX°¶TªÝAB3à(ð8°B>+™9h…ØZë­‹¶ˆ'=ÐXœ7®¸È4€J7KŠ¢hI2À®Å`FXª•à“ ‰¹ÀÙ`¶8Œ)½CµV»»ÏPIºËƒ®ÿÆSþqSÄ;EÇZ û†¹ÊÄ«2jšoy„%¡ Ú@¤±ÌDŽqвi¥­Yöú¤qY‰;˜+ít™ÛxÆ”PDÿqÁ¼ãñ€ƒú@‚ë‹5Ê[ CË Áƒß¤QEÁ’ˆa<¹ð¢g¨”1§¼;ÁÒl!‚5 ÔÂÆ7¿eЦ@Ö—ÿû§ôZðÀ7BÞÖá×§£Qnsˆ½Ç„UQ6YËö _Õ4bõ ?ºq‡æ®EY"qYqeì×2À&]к5kC¨|Þ%“9½ò“}„Õ¤1 <ËÀPòS3ȰX• K[š^f€ ÷—/JÁp i Aà ¤*»hFšiby»}ÙqüÇ—f.ñƈƒnêÖ¸–ǘF déPòš€ÉkRŒY­•0iŠŒiÿ8¶¦Pg’e–’\ʦì.œœ‹™f02P§˲Œâ h<˸œËhÙ¨ºÜ˾üËÀÌÂ<ÌÄ\ÌÆ|ÌÈœÌʼÌÌÜÌÎüÌÐÍÒ<ÍÔ\ÍÖ|ÍØœÍÚ¼ÍÜüe”,k—ŒÈݼ¶›ÃËYr Êãœjümi¥~’59 LwL"m½çÂ×ðj#ê×{õlÝFð¬=á†Ð­QÅpnöÞSËç­L1å £.±¥ÅpH] ŸÌ„çØÎžf¢¿Ë§ß°¿YayŸyL<,].}1sœ,3mRú™'?Œ‚äzqZPÇ@L«ÿé)ÿxZ }`ø¨ ñÐx¦Ð—&­iX+™È  0C×M€ÛAãšÀIÇÊ!!È t td]@‰K‡+³p‡30Rç©´PuW7Ô} xGÝ)K] =(¾è ‹ðdÔðfSÝi‹R #u] ag©ÒœrÓ“ò%¾ë 'zKßÓ³ª@ÔøuÇhùל¢W‚΄ÝÔ §Ê{¦‹iXDvºã ØàŠèz’£g±¦·U…õ¸˜·`ÛÁИ½è1kê/ɉɉÐ×T&Ä4ø{"xÄçÅ;\RüYqÐ|„µ'‡$}ËeˆÈ»ا}Ú]ʇ AÜÚ"ÿ…¢Úv0ÐâX»¬UËE>Vwà mmpÛQ/*k2Û¶¦žjÜ€)ÛZ@±OiÙÄE(òoR¿áh¢»Ì5‹i:ª‹Ï-ÎF¾ ¼0U׿$Ã)ˆ+Hk7Åf§ðÐ4øƒmfä˜H-ñM-ñ’åÜhP`¼Æ-†5ûÍà…–¡¾ò¯€hÚLèî=Ãþ×ï•æÄMxúÀ@i˜kØ!‰h m§!oÎ(¨O‡‡j±‡¶Å\z Ýècæc¦ \$Ó‰[ÁˆÜ±H= ¨—R”h‰íoÿ ¡Ž ÒÛ67ºt…5‚zCgäSŠðYñб¨Dú=2(M+Ä”‘0¿4I[ë·®=í­ËW`ÎhÂhÄZxz°gñ‡ÃM©³ìÇçi$×LÜ™ìäø¿æ"ä»Rw“ ‚ãdIÚ|­è`æéf/ÿܹ¨ÌD’ ÷'%MÚå³€µY° WT™:`(â»qØ7‹‹˜å™àÈ0 tD™¼ßÂ>ìŠf‘EÑ£ºý’|«»”A>I %.íÕÉ'ÕN½`°ñ0Ù·ËûÙ*åí9ÙN ¸²—q(îgD9¡Gù”IÓòI'îëOj<ïyªëjíÇ@€ÿÞúSÀ•A‹E#“ÔS\Ä…$2€KA¿ ñ–6*k ¡=Ÿ ,¸ @hô—³*§¾Æ†IôŘ1Pö{+ ™åàEî—ïx™{]aÒmdê©‘:ˆ“ºêàUŽ÷ÉöV€š¹Á©¬ù©¯‰«ÊÀ+ðç”q›Qp¿Ô+ñ2È{ª[þÇñI‰0øXiDyìæóNÇ‹¦p?ÝI%mõgoG˜xîá0² ß¹^9.È­wbIPÓ‘#«2{æîeAŸýt¤˜PŸÑ‘ø èûªiïCu?S ›ïn IZ)ª ;"K=¹áC¹¾¹ÿ êCQ ú°ï«¯hb®€ú4 €8È0¤È¡ZÁ¥ÒõùŽJ«¨CEZE­XcEŒÊ˓ՂfØ©0Œ¨Ñ:¨®*ÍØ,Ó£–ºí~Ããò¹Ê< Å’¢«†ö€HI´P‰4´‘i!ªDB¨HXЉH=Ðܬ9µ%†±µ‰­¶™Í¨™:tÒÖÚÞâæêîòöúþ\H’HMÀ!´àŒª&Ô(ŸŠ"ÉŽPó!D<Ʊ`ÏQ3[CA„×T°ÓD˜Žˆ‰˜¡Ù¦ ûÿÓiB㓽ŒHLPADžB‡ŒH! ‚>‘êÿ©ägH¦M´ éá唆³JU+ [š+w¦aQÃâeš)âÌ©s'Ïž>⤠@G qJž¡„˜l˜Ì€éS7WÄ,ÒÀfÀåæ Uaê“èH¼[)õY¤Jù ÖÐgk$кþΩ(Àèže$tº§Æ[B‰03†ÆÅ"vzœH*BïÂN3ö=¥—¯bWUDnCÍHh5ÜÒPT‚À€–v_ÃŽ-{6mMQûœ¯@Ý"„R°•#ª”#€“h` ñ›?Ì-f-ÂuZÈE.OÌηJNØHñn€k½Áµï«Õ¯6û8A8—hqUÌS†4`NØÿaÚºÂRÃwñÇbRÁG5’)æšxGÇp’iqŠbUÀ JfÛÐZ ZL°¡Z• Ò(¡dí±Ø¢‹/ÂØS¼`ÀŒEH5ˆß°S‘!YÑ?‚SáR Bœ ÖT@Bá×ÕWrPãc I2Ñ‚ ‰™®%4@Œ  É) #AOŠéØ·¬£ž(f#6@¤ ­pÂsMP`e<aF4qÒ7% HB TLrßM ”Tà‚Ѥ“1ø5 8ÀHh!¢ 2ThB 8øPÀy"˜RßD%m@«¶ÖÐØ’¥XçžÿÇ"›¬²Ë–¥˜Ö`ˆŽEÊŽ+ w†xá,¶j(`Š&e5èâF¥e-Õz ɸºãb€Q:ëé[éuB³/vй-$€Î €å"²ël£¡Áb:BC¸-D°AŸ5;Qnàª^ÛÊÑ€€œ@)è(àñãºzñ ðk¯¸cÁ(¯ÀèÞÊ'YKñ- B÷¯ÒK3Ý40`À` ä«Ó²B€) Pp–.a€ÖStMÇ7(KÐZV>tÁ ”m™W¶ˆ½uÜ#Dòî³*(°€ÛçÞm Ä Ñ_ßÉON·ç@oC€ÏÁÿ‚\0À ¸Zœ0©ö§D $¤/TÜ¡Ê×öpÀß,Rƒs‘>5%y]¦hðÀJ^e¼9,°Á `‚#Xàv [зóÈ+_ÃpVÇ7|Ä͸÷߃¾øu‘¾ÝÇ‘çøíM¾¾û·HQoFÄ‘Ûû÷㟿þû‡9@ÈoYmz@BjFõñ¯.íK §1µÌ GjË«ÃÐhÁ b0ƒ¯iB üÃ,j´À€s@ q²À&P •áVU î 0†2œ! kÙÐ'Ìáúž´Â:ÄŽ‡B"‹HC‘nSH"›èÄ'B1Š@A¢«hÿÅ+b1‹ZÜ"»èÅ/‚1Œb#ËhÆ3¢1j\#ÛèÆ7Â1Žrœ#ëhÇ;â1zÜ#ûèÇ?2‚$! iÈC"2‘Fä ±–Â Ò‚Š T†åª–Áx}ŠÜ <àIO6ŠE˜$@à]mR6¨R :Ôm°K*×» ’@le Ù3 d —jh€€² tà,¬rÞ,IbS#Æv`«MH‘:!I¶Écг<@ÙÓ øÝ,ɦ9`^[–>)À“ó|MË2„²= ð)ÿaÊ€:‹s<0ÿ>Ñ•B Ù3®…qKoø°¨0ú¢òÑ.Barô®¬HèÖD{€´q=£ ôæBi(«}:(اÒ) â´x'Ó$ЦÕÓÀÈ@õé"x¡µhAýaJTzÏ͉ª#à;˜bGæHYpT6¡7@e ²€g…H;q*¬ÕÀ@¬ÕĨÆ‚ÒILc  °šA.ŠËá~h‹`Kqëé<¸  ¾a¨š<–< ÌcÕS²$ÁàÔAUª´%Nú½œD«Ñsk"”:Á+C¬rË03×Cÿ_$ ®qÙñÛÙT§ãÁ`'2×yÐ/[ ŠOºÔ YõÔ”†ÂÂÅ< ‘  èi à`;m'Q—VZÙ¢Ö耬tÊײ(¶1¢jmOù= ˜ZOP¡ª\àbMôHNiâʈâê•Ú=iªÅ2Œ ª‰æfW »AÁ1Ö0",Ÿ¦á»ýúæÇk x@{_€P9T9hÄPíüÔŒO"Ùžaøƒ ×úꢼØÂ1MD $@ˆEÅÃä¡Ì'ÉI¶ì•²<£™rG¸€¦Ã`¤¶žb]€’JbÇhBµ¼)+°Ì®†Íðÿe‚CG7hsE0+0à¶6?àp0f›{c1,·™Ës ê•þ9’-óÐgNDÍå =à¨ùP*‡ÓÊàt4È'Ë<Ù e˜ú/f¨!`ŸàuÃjŽR™j/#ƒG„ld@ÙÙðpt,šJõl&ž`ˆm˜T•ÏÉUŠVÑÄ7‡6®ÅL«•rz^BÚ­åCØ^@>'ŒmÀ58VªN€à 5” D°R<í¸ žü§'a,œ x²Íùœo àÏkÌ㟹B>µìIϦªHÆjnOVõ ©@ DP9¸\ *7¹ÿ~™QÚæ³r§J=‡¢e¾7sŒ®ÁÆÛüI¶ì“çx_2þI‹&“®ºšŽtxÞú-9Flûµ|¶šGŸtºR·ÚØzÕ•vÚPO>€×îÅz-‡&üZ(¨&ª¤2Y*:LjY´À…i³,:¦ðR *€ß%Dw“kÞ¹d†„<Ç(e“^zæàG톲=ð¾pßïA©j­·ü9™ÕÝ$È€~×$LÀkþ3]{9a2×*0¥)1àX¬“üF~<ùø8èo'ÿ’ó%¸×$l‚êCEPZP›†ÛA$•p#0@>ÔöIÕø€NYÖÏY_`3à@ŸNVLœ“`–øÙÜvx€e…_äìA”]Ä% Ê•Aßx’8¼•ÅÞÔWËy–+à›Áa°Ÿ×(F d‡„DBX¥DI°Ä"@IÆ6XYVPüÁA]ÉÁùDˆ³X ÜFrŒÀLÁsPCZ8K ÉYÐaàBiaTÊ8@O™ÕaѵÁ fD¡mC>‰PÂÅ `Ü–×gPÙÑ(\b85y’n4€«Ü—c(•8 ô˜÷ÿAË !¡E"ü)U\y€ Ô Ü_ý4B¤"´ ÍÅ"´$|¸Sxéà僼*z€%b‚Å\CUY!x’d X7 0þ…Z ØÖ Ž¡]â+â ¸†h@,bR–À¿í• €aÒ8a„ÁÁxXØ8ÊeXÌŽIÂC€‚3\!µI wy[xa¼C§ IêÔ€ˆ[´ŒKÜ5$@Þ ‡´MëÍÑPDÜ>õ—Åì#pVhA@‡Ãâ(¶\£˜’Àÿà×üO…”SÏ@•®è”oäÓ#\”V cûqãøMb@@L*AKf€/ªÿˆ@ pŽ´b`’3TxPßM˜ÒI”ÖMØYräÜÒÉDŽAâhåN`Sæ’ò)AC ÏÝÀ¼”äS—ÑÁ@†6FOÚC›9€^¾ÁH¤na IY¡ÄÀKS ðc†¡ZÄ„;®W“ÄcLµFOt$ÄTÉ- d;¶@pÀIv%‡ytˆÛ<બ”†8›sÍLí žð¢ ‰AõX‡Iò‡ÿ¥I®šÁ1À¼ "  X_.Ä_hcRý›ÇiÌŸ ã<€¢db ´[£4@% ¥æDr"˜ðETÖÀöÉ’sjŒkéÁVú_tÀömŠ'‰ˆÉ€ÿ% L¾}R•¹–luÒ–5ç¿­ß›áÈ{ñ ÃÝçÆyR••ÓhYH&éfÆÁè‚êfSúžðå¸(ÑKèVôh¢Žq‘ßÅÁÎϪCÈâÔ¦BÞ_D‡ K¬ ¨LÔ(ÆŠŒE÷Å,Ï`ÄÅx5øGdŽE–ŒZö oFc¥gåæ'9¤’ çh' `ƒvB#®ÀP~©˜!ÙUèTÝA\ ¹–p@qRãtöÄÌ #ˆ§ú‰é'aƒzBÜM@Õ{Öf»ÉO}ŠÄ'zEÆ´[x&¤Ôé'Õh<@£ ”e€Lœ¿m@¡’Àöq'Ÿe\>u`ý”—Cýÿ›ñ˜q^h†vk%FmÒé¦VQbjÛ?6^ýA"–àIE0f¦?*ˆlŽ(e„æ4ÁYÄ„¬ ¬ÀRtÁG… i„*iõU ÈÉ]ç,ª _ªåS;ÐÀ•B¥èÆ–þB9UBMR¢Z.A™ò¤›âЍ©…®ˆ)±ª0$ç²rÆœª@J.õážnßIäë´ÜŸrU´è—d4Tx¹+¢²k-˜ d)&u*†—¥¦Á'Z€;A©”Ö Ã@ù” bhPª@Â},-À5®e\Š‘«&ó} g…Å•^€&4›tTÃixCÞ8i˜8ãèl3¤ÿ(Òj´ÂÃ:ÄË„åB¢mæ mrüÓ¶îB¼C¼Õ€¸›j¨Àá-$§ &ÕsI§RV'b磶©]vç)Ö¿Vªìuržîiòy@(ÔâÝ"”ŸÖ~‘€k SÚÂlÉÉâá&F›‘À‚n¬Áaª:Ò`"˜Oée'¡l”Ɖ#0ØáÉ,@mTX±þ^dfF Ü.kÏù JÙ)Ý´às˜#¿Á¼×œ8ÿo>ù‘ë%J_ Û í"§A%Wô-–ÞV:À‹^”ˆ(€Du”ˆpÔh¢ªÅÌ ¹ü£¹PJ7waÓ»°Þ`5ÁäÒY;k.á‹<ØùÌÅ´&Ð8ÃÙùÃ"jœ'µsÊfÜL€FîÄ)Uÿ®åø(¾%£ÄÜ'uSÇdÜÔyäS,öÈ!×9´¼ªeC´dËœNSô&'‡Ê¢ÊbÀ²§#ciñ\ˆ I,gjõInrˆbaûÞt¶ÆÁ@=€kñœ.wªÉ)„k7žÔmÜOˆN1oÊnÅ1J¨:ŸÕÍ'_òŒ•VÑ.î7GÑUkT<ð0©¡ÿ ìÌžëÄ7.åÒØÈ·ÙÚ¨Í?ú˜ÕÀ6¤0³æ ל…Ä`µöHÊ ø4 ;ë¹uN%o ¶¤Víêú=Ú–ÙwÊþ’å’€8ÙP±dD+ÁC¼5pß$„C=LФý¸ ì÷Æ­t€© Æ54Vu²*L4 Ô15í¸ tÀUp4{lò=T_=ïí=tjùŽš_­u{Ù?€oÀø½“Ž’”Zf‘LðèY˜«ªØÚ– &«ÀÝé¯*0™CŽxoCªAkäà@e5®É±lÅž§Rø+ÓðõdÙÐìÐT]j£—PÁbÿú?Ü]ûn:ÓÌ„K66qS__xÉŠÖNCN~zás«Q31¬/ #]ºž Šl&ékxÁ”5,À¬Óz5l±Cß`9²3;Íú$±2Iu³ÓÐöRûµc;/„s¶sû?X{·ƒ{¸+º_‹;ykí¡»–©º…¤{»¯»øÐe»£»zó„¼§{¹ã{¾ëû¾ó{¿ûû¿|À üÀ|ÁüÁ#|Â+üÂ3|Ã;üÃC|ÄKüÄS|Å[üÅc|Æ‹­ú¸”-{‹PR¨ ‰V±ë9mÃ`ƒMk|²¬Ò«mµ†ÀØ$Íü ,Àî°C‘»]„z0õK1ÿS2…£½3õàì“h͹@6S™ºÓøº8ñÂÞ$â/¬Iž<¤ËÓ 1À§º|‹°<0¤}-|hX*óËÏXoW<ÍvˆÔ Ýc ‡ÃÆ£íHu1`µŠ„Ë8 ɼ”+â|ü¸?»²Ü”.!Oñ]/€m xÓôdeoŒ¬ý/´ýG\öН³Ü»ÇW‘¨ÝΤ‰5wêö10ÀùqÀ dpm¾ÜU^íÕrù`!€`I­aIŠ^@óÕ4Öc¹a´¦Oä+Keé‚ôMÀžÓîCæ×€;=þžt¾ iÿl„¾/ŒþrçÖB)|ø=ê§ÿs ÞkÇšÍüO;NdÞLW[â C&Ë 4A`Èë°öíÛÍ÷¬ð ‡Ä¢ñH€Oí¤ˆ I¡ñDË®)à1,ž‡÷ŒN$ž•ú {› ¹½(ßñž:œâ!Àd0 æCà±çø)9IÙsÀ7ÈÓ0p@´Ùy4‚ªðÂÅb@0 êÅ0ñö@zV`vBcsYj² ±”³T­èkçà1Àã0À­¡ñtÖ°p)0 aÑpBæÁÞÞŽ`cÐ+ð``QÙ~bÍ¢!*ø¨0/@? ¸ó§A(ÿÔ±Å1,\ ÆÐ@c°ÈÃ@ „ ™’˜0‘˜?, ™ ¨cŒHŽq™pú׊ÅàÜ^PP“kWV„ÏPPÆâ’ F0Ü ãfq Ý–䘜TÛhP–Q[/ &°+±“ƒ X{˜Ð›w\Á$ÌvË„øVZ¶ÀJœ0bÄæ?| 8Ê.‚ŒzE>BHììÀ{x|c£…EîÙx.ÿdy ì=¸—~B/°³Qv›-PFþEdÝ Mt‚% R41aØpO{·¹Õ{ú‡ŠC·e'€Iݵã*c™Å…-QAÌxCžÆc>þhG^š¼á æIX0wK¨‚X®˜® PÁfgäJØ%€lC„6Œ¢å‡8ÀÀ 0Áèçé 3Ì„ª6«šÇ ®` Ÿ X‡8ì@=@1¹yž 4‘€ Xæ Ë ° !€™>DDA›¶If‚< ¥‚ÆF¯¶ «‹}ÈTÚ ©.„úgÅ_\ñ%z½Á4<Š­,ö‚ g@ Eb&l²(dº¨‘ü0 yò‹Œ6Ìü (jªÁ4÷ ŸžÉ©aÆr\F¬Ô5ÈBK0`…6ˆVÄ"ö1i&ÐÖ[ø`ÅÜÆÚà-?×°ˆ“#¯íî¶7,ÊFÓ&X30Û¿ÅÇŽÈ6€j¯‰n›Ð¶ ý ã< „ׂ'H¸ÿuƒе£‚ ”æ²  ˆeÁÙEPô¢¹¦O L ÀX™Û+DZ ¦h¶ ü*Í{ï¾G¢ñ‡á@ HÞs–¢² ”M¹ ŽiD¦Fh€•Ô$§ h6·š='@EÐ< +1zòù†Ÿ¿«‘ è{ 4ã ¤cE —±n òQ¹؆X9š 2»±ÄQYŠ€E@m'7€Ë c„Zõ p¯`Ga6â!0Ðd>0€¨“…‰%qÐò@Lòà 0<Îq,x´Öì£ ~ëD 冈X¬²A %dÞ&€¾Ü„ÿà œð¾,jq‹KÞ^ˆ47YLéx<@À¶»4ÏcÁ(p"=\¼, Ö ÆÀç ØÑãÀЀ´ìi\4cÝe È=¾!i\<v`À¿3t`&=˜Rþœw¼Q@\¤˜ À!RP4lA©|¨…ò¤g¥ë\ŸuÖ«rÓÈq*a¢¬²7/’a c†˜ ˆ}Ûó ƒTXF Tå!*Zœ'oÐÄôèò™Âݽi‚²8IF‰;þçÊ%z€:ïQÔ…®‘ìl'…ôE'žÀ/® r‘€Ham¼N h®7p fê›§"mp™ ,ª®Qÿ<7±µ»½ e¤y†ûÜY¥{hPÀ@ÒxI5"ç€ôhƒZªclùPár4PÇȔ! |¥¤"Äeät•ÐLÛá‡< ˜.”ÉŽ8øOb³†@z!À˜>ÐOÙaÍœr†|;œ(è¨5'Ië55=Ĩ[ßz/r Œ™£ñ¨a6%tŸ*3”00Š(ÐÔ›]O`ˆÑÝ ¹ºÁ#ù73aDÄQEû4*¸öå€> ÊŒZ± ÂzÀ@̒®Ðr©d¥h Æ4³BhÂÍ| A„ó$XÔˆ6& vr¨&h‚0Çÿù𤲠m¯9JâšM•…Ue)¶*>±á˜C®N‰P¡E€ ¸-§¥Ùôª·.rUCÇÜ•¼ørvIˆ¨aP±‰Ïn/ ÛÒžÜ{X¨I±,P“În`=! ˜1'He9мM!í¢ëMäÕ@Aº°$D„Ê:OMIbP-@©‰ôk¼6Ø´²LîR7ÜHœXœÄíVQ#¤>Ru¹Ï4ÁrÐË9X:Ó^dhWJ—Íý˜ò™¤’ЇÀŽœË¨ì[á,kÙíMÃ{},ßø3–ÙóB B’ Í á̆ÝÝÉB³³ƒ†é2„š ʯ$tx0Õ(œeÿ¿`Ù (×]È0fÊõØü›uñ å(¸u½Â"\;'ߠɨ,L¯b‰<˜7N¨q0¦ˆÜp©&¸1§›Ó& ¶!;~C´îS•±ãcÕ¦¤Bk°zSÍÛ–l5tÙp(Öê*OQ‹JsNÐ -ñwJ‹êÌ_Úü†Cþ{ZÊ"Jø‚œ~By^9ë€áÚËNxŠ[¾L[€ÓÓ sÕÏFÅ6Jy Px@{P ˆÄxùSV/ UÎDâŸ@>E(øÁùcp»9|Qgên|W@ŽÔ%[-Nï$ÿ–™+Ìlô?xÿ!F.f¨¦‹ a5u¯™Mé1Ãa’9O¶ÓŸ>7HÝÁR×g20уÕ)à‘ ¨ºÈè€,€–_“U¯B\óªÙ”Òò¯•]æáþu³©=î]8ͨºßY`” ztâº3>8ëIÂŽy–“ê.H:íw “\hšåZhÙ²–‡)v0ÞÇesŽr{ ”® ³âŒ¨iƒ‚ UJqô‰ßˆa^QæÛ½‹‘À•ž`ˆ@"Rû“;&MPùWý !nù»~N@H Üs ]œ©@Ïõs•í±kÐfÍ×ölþ hU5ÃQ×àªÌŸ·ÿ ™rÓíÀŠEC}ÿÉ>{˜g$>‘%_‰vW®QGò•iÄ_ƒñv=³ =ól„õ_o`g‡@,À_aÖsðOñEY5S3e¦N~fQŽWa¢1kŽ*ß …3·q0¬#lßJÄ)Jf:§wLpãX(b{³"í‘7Û‡ƒëaîÑa&ÀSD8ùÑ)üa„íÀ'&§hDu\ÐîA~Sæ`Es·!P…×!<¨j,pâM ^"âí Py0â6 à-BWo€ £Ç‹xlþ'_øH€ñew™W-ðWbupJ'ÿnb'`ý„‰ØsÀ€ùaWj )IaÀf öEa' ‹Ê¢L×#‡(o‡l,ˆ!žx²cmŽðñ0õp£„,f#„;Ãvè< 0q'ÈqNñl (|DMÏÆqk•äÉÒ€ÞŽœ8%^xj6v\4a8ñ‰ÀðU†óaïøÞx°‹¯@0 @l²sa@V1#òpb§-ïgäø¿¸B@¢†2à3ž*E0ʺ }Õ/Áµ°Š=ð£hÀPg GGó«p<É0©‹—¡ý W¯ÈJ9„ác80`'xÂ_²=VåÓ@cV P%(_§u²°8¢&pB5vR™°‘r¬>6¡»AÉj(j'8âS‹3¢²‹;ëz‚“£PÒª³,IFˆ:«>ðeÐ [“ ×Jÿwâ¨ø:|ugIËÿÔ¨E§g@4º¤N‚Gœá'Ðê¤iÙÊQ ‚‘¨I:£ñ@‚=Ót_r!ñ.k'/ ¨P@M׃”c@32 ‰€óÕ<3· ®Ñ<ªtÆ#K5·ºp 'ô ¢ž¹ÈY8"h¦0QBpuº³§«^@P”áºiv)‰03Ü¡Gÿ¢°°—u®;òDŠ(=W’%.ó³E€°b2 eRhR`kR¨ì6 „ñŒ ŒÁG‘e›@\ —q¨=“wFAÛƒ=+ðt×CMà¦7j°Iÿã’M:g“:Ð&jMÁ0mŠ%>y,é–)ñ®‘ @‘vK:X½°˜×½p™ºq{’y½0—h³¬Í‹u¨ ÂÉÆ½° °Ë ~2•+ |2 €=%¸Ê‘¥´µå»}Å2w0Pi3gW‚ f‡ ~›ð1m€!ÌÇ[v @•E«Øff &F–p~À#`_;±úfãzgѣíHh˜wÿI Äÿ°«<ಌ‘»›`‰÷lK •5ÜN]¦&ì‰6ª‘©úH^«Š'‡˜QFwœF$>V›uæmªAƒ£&SÈÆ´©,P»7€=R¥&ÐÌÐF£½ÜÇ×̈|°‚| Ö u0` ö!QGm¡&›Á»{uÃMûFq4Ûud@Ÿì ð¦,còG¤„än(g‰¶KÐÄ·fmqÇ3› ¹'$ÑkäÍn š<·ÕÅX•É`@jR¼ÆK®B‹Ws·¹—; ˆ”ÌØÓY@øÌϬF{²·—û0Ý/#pfŒÍ=ítAkÂGÐÎÈ@§ÿ£€ž”á3@wC ïÌ: (9 n<¯~áZ—Ãs‰ €=&± KÃ}VÐGpÐ\dɯÐWwL¯9]‹çŒÖ“VC5E—ÛÕ7°ÑÈ3i†@LjR¯R«‚ÄØ m=fWªm½Ì' dž}Ø ¡ÓG½> Ù[¦ºÈdØ_Ù¤H½à‘ÛJ8㤪<Ó”Ì?©Ò…²ÒCf·X£0jÎcÀââ}îŸFªÙÐlÜrª¹Ì¢`fMLm‡½m†äîÀöíâv+‡mnÿ£õHê–ò£ª,7ÐEàD`ànõÄg¢¦_0Ň534qh½Ü‰$”7ËþÙqîçÓ^j!dú-¯¬,#1¼Øsçiz­Œ^É05 nw Ï <ÞŠ3Ííu)œ|iæU‡^w£ xmRxЗ`2ó¯·emÖŽÁ½Þà›¿5•õÀ PŒ‡pí<‰ +æNáéäŸ ñÏþÍë÷$À´‡=—XºW²ÜWÛÜÒ½€À°b3³(I¸CóÙ8o×báÿ±íÔnôŸã#=â3—$“¹…¢¦Ý3UäN˜<ò‡°ò[.G”îX‚ûÐ ø !˜<#˜¤_L<£>¥îV‹1öŸ”=h[PÍõ=c@Âío™¨ÓÌ*>C ¸ÿ´€û{òDÀ38ÑLÄŒ‘<ÜB‹Û¶2@€h¿(äT¼Á:  ã˜¯,£Kº©ÞuÄâGú’àž²À > >õÉôÙ2Üä±vVo Š£ØW¤}ŠŠÌ¯’‡ÉÅX²Zöñ%”±±Øîy æP½n@RÎN" ©rò¯ÛŸæ‚‹ŒQxŠÅDÏËx'5 _)¦eÿ0¢ jR |æ0³ŒA¡ÑL{êT`E Ð,IP"šV™<˙ʌ4”A,¯äðæ2€¨‹$CH É'4*R«Ö+6«Ýr»Þ/8,“Ëæ3:­.2“5|ê<ÀR<Ÿ5éûþ?\[A”ÝÉ â"c£ã#d¤ä$eW[ÄA¥‚ÄÃDÀ†Þ&_)jjØFÒ“ƒ““ªí-n®î.ooYÛ …/Ôìè×]Àð×é²óf›pR¡ÄTE@â³ö6w·÷7x¸©xTs9:šÅACÃÁOºü<}½ý=>Y€@>Ày?À€,hðà°d2lèð!Ĉ'ÿR¬hñ"ÆŒ7rìèñ#È"G’,iò$Ê”*W²léò%̘2gÒ¬ió&Μ:wòìéó'РB‡-jôh7`%¤q+V¢2rŽ. H@ÀU.°B2àRZ¹rñªLϲ}„à@ L"ÀØ¢ÀBˆL£@µ;sn^ŠëR† š¸4°ð`À€ ÈÀÁÆ ñP4~@2Ù ¸@ÀA‘N@­#µÏ6àaP ¸¹Œdv™¨ûØ æ7Zµet_±½»-Q …Kh=¥éÚ鸑=@„ƒ§—Èf«ÍN¦c±€ü€á)°*ñÿÝK _€2*3gEÒÀz‹‰q‡q¹=§Eo’x–/x > z\¶6sU ht?Ð €€r%ÀwDp€‰•–6pBØÐÁ| øø£…àpx_¬§<p€@0œ˜â901TY1:ÀTsã…B“¼&¦—Âd(thšUXØÕWËHHá=s–å€qhÆUn⧆]1òy¨( Ò ‰Â5°À{Hñ^¹ çÅ5³EÁ@<5 ˆÈ€]ø¡¨bŽÒ'$°à x ¨Aº5`[µ\¡ÿ§#ör€xÚC¬ÆÂ‘Ö†]äºk¯üªm) pë¡!’ÐdY%Ä‚Â{k¢0‡¥QÈÅh6p¥@ ¢g ti‰^<¸UH`H %0*)¼Gk®ºë#²"Ì…¤ „Ž $p°+çV) ÀÓ0ÀÇŒ›Âƒ8 ë¬Ù0òǨ:o+\@¶QXàAIØÊW d°”Ù"€ \P Åyð4Ô_Ź2ÑÈ‹²Ä sL:EZ7.!À@œ <}µüdg€ÿ ˆR˜%‚hÀk~x%ðq×ÙŠŠPrµÀÝ2ÔèÿA{YTlqKñÄ݆ÅêÅ`…î¤ï);_·ÛŠ ð ïxϸEÑf¡zÎQ,QM r™@2'¯·±¡¼J‰ÃcLàA¿œaðtä[hEÁWûðIÖÎ_iõt“fIõŠE,ÿ´ôÈcÍoÔ<›.…ÚÄó ¼<-Àõ¨S|ýÇOãÀD`+xù¿¨Äûœ&?˜¥å;Òò[ÁO+ÍCÁœÔæÖA­ZYVõ•÷å fqŸžvÐ0~¡1À¶¢§ÀPZÛֱЀïym ŸæŽÒ"WÛÂ`XÔ ´Œw:@—§Ó½+^¥ €ÕVUÿÝeaSáê™.c•¦»;€ÀÚ‘%ÉÀ Èd¼s oaÄ›•ö–4P @à®G1^ÀæbÀWà„h+€И§™­…Oƒ@ Úf C&r‘h$à**P¶ €Äè¾LÊZ‘€+ZÝ À^; ÐÇþÁ,H€”P<&!-|Š…žv2  ”Wq(P X€Tb‘š !dÁ+Oã@;Ú9€ àN'< ül+ãjLÏ ¦œz`‰b\ïH>ñ2‡;qJ ÀE+ì‹G$JP€ön îJWU‚zbÿ!v]ø•ZLñpÔ °»bDê;îTYÉôš† ð€3PÈРG\c´’ÎUiåd¶×ò¨I³m¦à¤:åŒV¨hL¬yÀŸ(pßO­°3Zæî’4zYŽ73ÜPY?lål&Ô´–OkB|©¨“Þ\ÛS=PÏ}0;Ë\¬iT¼RRQø{$v5yýéqµdP€Ó 'M©=…‚Ïð„ŒžÖsƒ ³²j+šÕ «µ«b¾¸Ð)(:akÿHî’ÆŒÊS¡pŽV <…‰”aޏDð•Í(@5dŽ:°º,ÿ7t惾ȉY“+X'¤è9Ïb>WvTè­r [°È…êü©n‹  •ÕqP‚&ç kRô Œƒ YxÖ ¦õ³$àÓêÕb6 «Q¸¡¢¶%T h¶J*fñÛAèçQÝmb‚"¹Lu Bª¬[é`€Àk\Ï€™ˆÐávÑ ø¬¬¸…Há)µOÐ’²";x4À¬Ø¥kÁʦ’R,¤^©#@Í|!§OV‡†J\Tvy¸{nÿôç¿§uRkëòF‡_µ †gZФ:ÙS‰m ùËŸ­61F«l 2 µ__ º«zZæ–:´¦ÀV °ÿ@Ί3ÌcbÁšEèc“ŽvëAmf䢄,a. y7?Dôa¢x€Í²A…І¤®åi­ Ù´%t^e‚7½àPˆ VÒò&ðÃ}5I$PU1ÐŒóÑöǶuÄkmøí3Éίœ)U¾isÇYW–ÁIÿº^>Q̘­ÂÎ6ÔG³ÝpÚP[ÓsgZ¨d=!b ‹´WíÞÛäç¼,&¡Q–B>I€]ó½ô<ÙŒ?”Šf… Ðßz“+]`3Bºštÿ ’ p ‰6Åf á"NÀd\³òaA{H÷`º¬îlë-êAó¶°{‚íÊKW!–ÁÎÆI7wûÝXǯ¼­–5ÀÞÄäJx¯Ö€ PÀVO£¢ž7Ëg+8kàÙ@ÎdpÃ…k ÏuöÀU´ÒÞ†.]c²¸Q8àòË%†}æW&Z!§ª $/Àµ&ƒÖ\Yðežz øœ E0õåyžêŸo¡L’àЙÿ¦ÀÉ(H÷¬}öFM¨êl¾ö—îÈòRýrV/TñÝç¼ÊΔi¯B´ë›‚9Y3ôáÌî3ßµ÷¸æˆF íZ*8ÚíO-Ó¢ÿ¾5`G÷?Š•L_…\à£$@¬Ö(›`ÐBÀ0Cè¡€ 4ÞÌÚÈäÈ =¬Xï©^@Q©_=^#¨˜hyÙîáP lÁmø\·µU]ñ’ð}¸ßñ4¼É‚ûAÁÎhYx‘…&ÅPßeAZÀ×W°È¶àømž •¾-að¹_Ù_¸=˜òiË&ÕÙ†u•Á+©ÛýíDü¨,‘`Ýæ­ÇAÁ¿œZ†y hIÆ]Á¾ìÎè Ëù,  ,…pÞî KÞÉTqÞOuмÀX»‰\mQÂ5”—ôQ¨¡L9Ž…XäÀ žJqåÿÖßðaÅ!diE¨íàE_êÁBAm•V0ŠWÀ•ˆ• ¸…— Hr¢ýÝ›øÑ×X˜¼w ·ÉÀ÷ž´a`ÚPÊÜWHbúDDɉ”u¬V¿4À¾„ø‹ FàÍ @œãˆ‹TÊ7‰@v‹ìE ÀÒ2â”–<–¨ Ì8"@×1Aˆ‘– PÈÅÄ–ö˜–É.BñX‚ÄèW\2iME !^=ZÀ4OÊH=R$QÀ$%ãÕÑ`hRŽmØQ-G “5¡Òª,­XÓÒ½òÄRá¶]øÿÒÓö S¢†8§À:lXí˜@Áì ê¼°k%³.3zÖünŒV™é¸Ø©¬V>Žki@CòŽl-b9_8CnA¥òµs4X>kwhE-‡X&-+Ó›"ÿfôÖ‚ñŽp]Ú¦ 4SKDßÎ*DT˜¯ŽX‹1o êEË (”MA?3þ^‹™ßîæ©ÊÀzàX.¦‘*0K3ñ] ÙWAÀêÄ¥@’iohÅö…qq°ˆ¢)g£ý4=§À ­$qQóõý\^crSWvAtšD{´*2—Þ$ïm–ÉÀ« €®æcìVÁ`0Ê­=A®™ŽþnC»V 7o©Ò5î&ä1‹"³°ò‡Rüœ w 6úœ™%3¦•£ ô‘c³apÓo[¶uÆ…gãϨ´ïggv;£¥Ü ¬1`ôyçq†Ñ ÍÙÿœÉa3Àì\ ß¶\[AKû Q'*~Ê~C`7MoK;ÞÜÐ$&l|0¸@·% æÓ]·„„¬¤6È…HGyYÔw? ܽ·ãŒÞ]¤…OAV¯ï·ë%A§¼^dþ1£Ììá¶Àêö,o8ÿbð´€s‹š&÷™s3wn ¹ƒ£Aýý÷„/¹<ÔwÃzZ¨½äÌÄ5Ä… XÅÒ‰À![ÇÆ†œ§úg«åHD —ì ÁËìÁʆƒB(ÉN(Thh†0¤~Î[gˆæã4À³HèÊÝà‡&žiš›|,=ü:ÈiÔ_¾¶š¼3Ð<Ú6–škÁŸ†D¡b>é#ë%<@&4jÍ®zç#ˆQªVŒøB|¥ì—¾ío¨öð-à“›SA«Õ¤jY°jHÈêí?ò“AÎ^8Æ*yò??ô ÅòG?õW?þ¾õg¿öo?÷w¿÷?ø‡¿ø?ù—¿ùŸ?ú§¿ú¯ÿ?û·¿û¿?üÇ¿üÏ?ý׿ýß?þç¿þï?ÿ÷¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA@faüÿÿÿ*@faüÿÿÿ*ÇÇÆÿÿÿÿ§Â | dþÿÿÿ*@faüÿÿÿ?ÜÁ]ÆÇLÇÇüÿÿÿ?ÜÁ] dÞÀÿÿÿÿÃÁÜ5dÆÿÿÿÿ«`ÙÀLTsæA&aüÿÿÿÜã¾Hÿ(ðû@faüÿÿÿ?ÌA ÀlÎw6dZÐÿÿÿÿ£ÁhÂÜ5dÆÿÿÿÿ£–ÁÜ5dÆÿÿÿÿ£ÞÁ]ÆÇÆÇ`ÿÿÿÿÿ‚ ¼HGÛ÷>@&öÿÿÿÿÒ|,|ÿBæ üÿÿÿ¿ÌÝØ °yÆÇÇÿÿÿÿÃÁ@ë|A&aüÿÿÿ?ÜÁ ´¸}C&aüÿÿÿ?ÜÁÖ-”}C¦Ùüÿÿÿÿ_òžÀK¿ù\~Ì üÿÿÿ?@ÜðDÖí¾9dÆÿÿÿÿ£ABœØ@°Ì5dÞÀÿÿÿÿ#9Ì^.xx²ïC&aüÿÿÿ?ÜÁ][ÐÇ@UæÿÿÿÿÃÁÜ5dÆÿÿÿÿÃÁÜ5dÆÿÿÿÿÃ!á2dîà üÿÿÿ*@¦aÿÿÿÿÿ›dÆÿÿÿÿ§Ât|Ìtüÿÿÿ*@faüÿÿÿ¿„!ù8, +€ÿ„© á!›´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öG ø ‡Ä¢ñˆL*—̦ó eôzѪõŠÍj·Ü®÷ §øŒN«×ì¶û Çvä‡üŽÏë÷ü¾ÿï50àQÇ㘨¸ÈØèøÉ&HØQ'‰™©¹ÉÙéùy0Yh‰jzŠšªºÊú3ð:øJ™ñp8ÕŠ›«»ËÛë9 <¸ahçk|Œœ¬¼\,ú:LêÃL]m}½ñ,\)­ .>NžÊ=;lKVÎÞîþïv>Z{Ÿ¯¿/ëOo‰ŸÀ Ôë´h¤:|1â;Yb6M¢Æÿ;örÖíâ7$Kš< i­‘([º| S ·ÊØ‹‰3§ÎFf©٧СD‹¢À™t5Y} 5ªÔPüUeZãÔ­\»Æ”å©›y=‹6-GQÞÔé0£6®Ü¹ùØrÐJ7¯Þ½Ùì2 È7°àÁ¼,þ}[Œ°âÅŒ‘ám 9²äSˆuL¾Œ9³£Çš;{þü†3èѤK›>:µêÕ¬[»~ ;¶ìÙ´kÛ¾;·îݼ{ûþ <¸ðáÄ‹?Ž<¹òåÌ›;=ºôéÔ«[¿Ž=»öíÜ»{ÿ>¼øñäË›?>½úõìÛ»?¾üùôëÛ¿?¿þýüûûÿÿ`€H`ˆ`‚ .È`ƒ>a„NHa…^ˆa†nÈa‡~bˆ"ŽHb‰&žˆbŠ*®Èb‹.¾cŒ2ÎHc6ÞˆcŽ:îÈc>þdBId‘F‰d’J.Éd“N> e”RNIe•V^‰e–ZnÉe—^~ f˜bŽIf™fž‰fšj®Éf›n¾ gœrÎIgvÞ‰gžzîÉgŸ~þ h ‚Jh¡†Šh¢Š.Êh£Ž> i¤’NJi¥–^Ši¦šnÊi§ž~ j¨¢ŽJj©¦žŠjªª®Êj«®¾ k¬²ÎJk­¶ÞŠk®ºîÊk¯¾þ l°ÂKl±Æ‹l²Êÿ.Ël³Î> m´ÒNKmµÖ^‹m¶ÚnËm·Þ~ n¸âŽKn¹æž‹nºê®Ën»î¾ o¼òÎKo½öÞ‹o¾úîËo¿þþ pÀLpÁŒp /ÌpÃ? qÄOLqÅ_ŒqÆoÌqÇ rÈ"LrÉ&ŸŒrÊ*¯ÌrË.¿ sÌ2ÏLsÍ6ߌsÎ:ïÌsÏ>ÿ tÐBMtÑFtÒJ/ÍtÓN? uÔROMuÕV_uÖZoÍu×^ vØbMvÙfŸvÚj¯ÍvÛn¿ wÜrÏMwÝvßwÞzïÍwß~ÿ xà‚NxᆎxâŠ/ÎxãŽ?yä’ONyå–ÿ_ŽyæšoÎyçžzè¢Nz馟ŽzꪯÎz뮿{ì²ÏN{í¶ßŽ{îºïÎ{ï¾ÿ|ðÂO|ñÆ|òÊ/Ï|óÎ?}ôÒOO}õÖ_}öÚoÏ}÷Þ~øâO~ùæŸ~úê¯Ï~ûî¿üòÏOýößþúïÏÿþÿÀ p€, ˆÀ*p l ÁJp‚¬ /ˆÁ jpƒì ?Šp„$,¡ OˆÂªp…,l¡ _ÃÊp†4¬¡ oˆÃêp‡<ì¡Ä qˆD,¢ˆÄ$*q‰Ll¢ŸÅ(JqŠT¬¢¯ˆÅ,ÿjq‹\좿Æ0ŠqŒd,£ψÆ4ªqll£ßÇ8ÊqŽt¬£ïˆÇ<êq|ì£ÿÈ@ r„,¤!‰ÈD*r‘Œl¤# ÉHJr’”¬¤%/‰ÉLjr“œì¤'? ÊPŠr”¤,¥)O‰ÊTªr•¬l¥+_ ËXÊr–´¬¥-o‰Ë\êr—¼ì¥/ Ì` s˜Ä,¦1‰Ìd*s™Ìl¦3Ÿ ÍhJsšÔ¬¦5¯‰Íljs›Üì¦7¿ ÎpŠsœä,§9ωÎtªsìl§;ß ÏxÊsžô¬§=ï‰Ï|êsŸüì§?ÿ Ѐ t -¨AŠÐ„*t¡ m¨C шJtÿ¢­¨E/ŠÑŒjt£í¨G? ÒŠt¤$-©IOŠÒ”ªt¥,m©K_ Ó˜Êt¦4­©MoŠÓœêt§<í©O Ô  u¨D-ªQŠÔ¤*u©LmªSŸ Õ¨JuªT­ªU¯ŠÕ¬ju«\íªW¿ Ö°Šu¬d-«YÏŠÖ´ªu­lm«[ß ×¸Êu®t­«]ïŠ×¼êu¯|í«_ÿ ØÀ v°„-¬a‹ØÄ*v±Œm¬c ÙÈJv²”­¬e/‹ÙÌjv³œí¬g? ÚЊv´¤-­iO‹ÚÔªvµ¬m­k_ ÛØÊv¶´­­mo‹ÛÜêv·¼í­o Üà w¸Ä-®q‹Üä*w¹Ìdm®sŸ ÝèJwºÔ­®u¯‹Ýìjw»Üí®w¿ ÞðŠw¼ä-¯yÏ‹Þôªw½ìm¯{ß ßøÊw¾ô­¯}ï‹ßüêw¿üí¯ÿ à xÀ.°Œà+xÁ n°ƒ áKz!ù ,)  £ÈIi¸8ëʧÖBÖu_yÜšZ±YèZ°8Kµ}›«>=Œìȵƒ€¢¸(ŠÆ€$¹œ4Ϩ©d:¡*Ø´kýjÇUÉ5E{±`à†›¬ã5w^ëé%fA&   ‚F Œ9 ‰ I|9C ‡”1MlD„ƒ%Dx%+·gD¼;ab½m²¿<!ù,7  ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù ,F   Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒV‹C$\ˆ,’'X…# ›‰$ ' qS2.'ceƒ=€@Aª¢¹rµ8´¹q–¸¼rÁ³;{ǽ!!ù2,T W ÿ Ždižhª®fà¾pÌÎtm‹qß|Ïë‚WÐå+SºäqÉLê˜Ð¢3­ÞCgÐÊMeÝ0ê»›IÂ\6@’*€JdF†Å#A/8R &„ ˆ6d/m1 #.„/' /œ$¡.‘l#n ˜"«"š$. "$w§¬i1C“£6ÂÒ# š&Ž "š¼^­“7 $å'±¸“p4kS$±žT8 FXQ0B J(˜E+W"b}KkœC Æ‘  ’)WɱöêM ô0 r„%“'¸pfäâ¤d(–‘’WS… ë©æÉˆXûN”IâèÁó꩸ÄgK 'B‚p®(€nRžÅºÓD:uIÖüL‘034 (3m8Æ.Kàà‘ Zixá&ªÛ‚ô46+"á&M”H(éB {*û)iéØ-> 0  yµD >XÝ ÂÄq¼µ¸îŒïžÅL‘Ü 5'Å÷NÞ8ó*0D—ynK$ê\Vº!ù ,œ  Ö Ždœhš–,™ ‚ж´lt{«BÎò7Ÿi·ŽˆE#9S.™8g †$9"ƒFA DÐ(`q ‚,‹QO"ÆéÐs6ST¬yO;T ' %g_‚U' %kŒDvp%j‹/;rb#™z(o+Ž‘“P=†ˆ$Š¢•}$ 1š£œwa#ex¡”¼"WY[j²É-’`¤A4 g¨È×c uµG7¤#'ÛÜS*#f àÐ@ŸBÁRPœÀ“!ù ,«  ‰ Ž$œÂ©®géŽl¬ ï+§qíʼ^ò2Ÿi aÅÕQ”T.›ª%€ÈµˆÆb2HPÐ+3`ˆ¬Œ°Y%ÝL É;žU< `laC€PC„I4X„{A‹y+Q?”wMCˆg@†œEš žO–G‘1VRj«¦B¬¥©¨­…K’ŽÈÓ²7-Ò’.q6KðhüV˜ÃKTZ‘ SF J›ÐŠì`·¥Øè´ÍÍ–î2ìä|™Çv•wnuž¯®à‘£"6áCœaíj×$àœ¬wláhÓN #÷LI mÕ$èc×:¤ˆ¸4×µ¼³®¼îµÇï–´[€¶¸zت¶°fWI`DŽI%ÜN=ïôÇpŽ Î5-Ê‚÷A9Õ¡·džÇßòÙÖ;~äehU8L±±œnð€ËŽú‰&ï2ÌÖÀÜúÈ¿Ç V.mÁ§ÿ êš¿Ûmoв@#Ý ájé|‡47‡ZJ÷‘J§¸=ç´`o+¤,` Ky±: ">uvàWÕ"NÀ‹ÛÑ嘻äNûľ¦@ËW5Ëó>1$«Š£–\Z#tšÀeéb8š… QÐï¬Ùò6A…uƒµ‡Vs¬F÷®xp‹K‚‰v}”’Îò¢Ñç,,tÝb= Zå4ºŠ3© |Î̼Ë8ŽwbF{Û}é#—õ"Ös„Ëñ#ð0â< @¹¤ýƒÔÏ~ŸéõÇùºõ¿ÇÉ[?±kP³wcXù‡-DkN%ç§fè±fPׂ5rk–xU¶‘ ’UüWwbFaÏÖ†"€:"n%xÿn¨zHø8»ÊVÎVl3‹*ðPh‚a¸d¨#ÄGpE»6,ówù点¨a?&1b(%$÷NózõdĈ†ѵ|xè0@â&âØ|„öd•p°ñozš•(6Gz¼ÇVh޲užGLïˆ8¶‡Žk«Âˆ('MØ}mØ8̤(øÁn ¹€xè„ç-ð|rŠk[UŠA@ˆ/·8.<˜€£~.Ö‡ä7º& Pb7 Õ†€ô’1©7 `凒mforŠÅ’Š@|%€d& ‹G"‹¿Äa%ànLiy"€”à"„¶kÿ'bBP'ý‘?—)”ä‰õvsÌhºˆ7À‘E#°{úÈy‚LY¹w\™l€W}ú4Wvyy긑›—(îèð¸eõ8……Y…h˜zN²znÕ…0À@å'‘;ftC(MRÉÃRi³sMr‡¼Cu¨‚ É‚i‘,ðˆ& 8‚ǧ,9 ™}ƒÉ€OIé]x‰‘™4oQ!#…  ¤ó¸%ˆ(—.Ñg‹þW+‚œ;(›»U©u‡lÃ@p$»7T/1mI‰'™ÉB™)n’FÔ×d49„.8Šâ¹jƒ…)Dx9xN~ ×èx‡ÇÕ!ÿè—ó±1)UƒYwçf˜†§W›¼–yXš2>7ŠŽ"h(Y÷¨/±M›y•·3{Æ‚Nè˜|èiß*‡\F@ˆ‡(’ø¦¡¶:,”›$à(»¹9ùQ7r-w#„^xéÒ0*…Τ>(8[ Ø ˜Ga§…"¹(éÆFßHxéYh7‡9ú_b.—…Œî9–ºó¢vSe]C¸uHVuÙù÷£”§„2  ý§§)`3„‚y” jµ‡éÆX¯€î†mö:PZ¡ jš( Xß3&å6Š#h´©žy¬‘f6¢ (wèù€Å'¦‘t˜ÿ+º—/€‘½'…mЄſ‘–ÄdˆOÔ› x(€mº9je I‡_+pŽó‚7÷0µ:ò¤ÐIy`u4`*ÅdÂ&¬bÆ&pVÚ#ÇšYïfnÍñ0x¨5,½™5å9”cf8øjlʤå®É†¢·"Fmf§&€xhxvU@‡„° IØ—úù1Ñ’"?Hš“Jh­a9Ðú™–‰Ž5&Û*©êJ©(1î‚yãó2Ãw!ó^'ÐpOË( Ò/ €] ÙŸ3I—ºCšòäEæ±Oˆ°2«~XLÄ5`2:ˆ¸*5Z£);&+[¦³º£ÿ™²’°©n@5ÃPd†_^Æ TxD¡èc_ |PÑ1ÓÙ¬u‰´º£´‚8“ª¨`1%1·Å·¤YÆ k­²ñ<ùâ1YôcùbhëŒp6s3Y7ø,'ZÿÌ#!æÕªDF»ª(¥.øšB›ºúu²!Kð©>¶åUð÷ t½UEZ»Ç¾^•b•a±±$Âà!!9Èulr“3eÁƒ %ð“Zò¤ªØ,׿y€56…S²1²kU½.CÁ@{õ+ŒÝT¾·&:å{çadGO-|'¨Àš’×"fW–Åæ¯OH¨Â¤Rœª°`E$‹ä–†:´Ö8@ D¸…"Âô¹sk'Â<œ¥OýX0Ôa´Â³°†bI^"tŸE¾ùy À2!gKhíúYŽR¼q¢ÿÈ`@Üg}8RR$AGc«?7!Y£Ñ³+rFú Ù„+UÉÁ´ªE|:IúA$Ç#È0¶ õaf†úáI[I&ˆ”"½|7Áì#ËEC˸h¢;Ük5à%Ê6Dm>}ÔA@Í*­ÔNí>P¼O­ÿ—<ÕV}ÕXÕZ½Õ\ÝÕ^ýÕ`Öb=Öd]Öf}ÖhÖj½ÖlÝÖnýÖp×r=×t]×v}×x×z½×|Ý×~ý׀ءÑÅõÏ€WÀ;Éõ¡_LÚý1D¦—–¢Äâ?9Q»©<ʼ Y˜ˆ,‚ڢ̈́}ó8,‘Q¿fM¤$“Y§—ô³Æé£&–d+}s×ÒÔ£ÝÛ¾=ç 0Ü^´Uy2(Ð.@²ñr²³jîâY粺§KÙ$›7 Óú&¦„Ææ" P?#ƒ8Z²¿}ÞèÝÁ}”9Ú0•3p‡µcyC–7™äŠ9»»ÆM»Ñÿñù5Ýb¯é=à낼Ó!|âßdjÓ]4‘I¡ù½˜}ø>‘OžsÌ€ÇÛÞáþ>c^^ÃuÖ³-H_ªšåT®å^ÞåO~ä[Nå–CèKè„îç`þå™'è®ä|~å€.ä9®Äç#uÛ×"ã’-.š¾&œ.Ù¼qéçQ'‚5WÿØAê¶Q'WĦ—¼Á¿›þêsë’­N,ا—RQk2,µqZæ6 7nÍ¢¼(÷æPè4 ‚FzôHb¤8þª&>Ò©—¡ë[{ëpê ´ësU',îÒÅëÝ®í´¾ÛMªîŸ½&£.Ù¦.Ù©.ï*®—lZéN êƒ›îsµíµîï³þî Íï"î¿.î×2ïø¾îð.ð îð ýé>ï, ¿&½Ž>ËôËá2_Ý¡¬íæ©IÛ9À“³Õgía²ñ¶®îïêç>î.Œêé_ñOó?Ïîßc7¯ë9¿ðßNïúþôUpàÿyÓ,XÓ•ðšoniË¡Ssucšøççéâ¾mj¥‹—¡0ÜÃmäPßön¯!~„F–©¡£Y_(Š:Ó2íúõÖº 1ŒÕÁ#BíãÆáoŸøCP.MÓ4ŒOº$‹7ÿøŽùyCºŒ?ù¤›äÿãºùº£ùŸÿùêãù˜?ú³+úÿãjUù§ïø=núŽùêóú”ïYŸ¿ú§_裟ùŽßú¶ú©ù¾ÏúYãù¢ú.÷&µs…&jžâJ|C|ç£%.oÃD?*à¹û¢?dÁ?ú ˜ü•Ÿú³ßûº ü½¿úßþšäíßùèŸû£¿þº£û«ÿÿÄ 2"ŠØ@I®â˜Šñ:£;š³ϸ\³r.Sªh<"“Ê%³é|B£Ò)µj½b³ÐA ëý,¸LÊeÃXý=§Ý^6WpìAª.çÙñÅÙ±‘ÙÁéêYèñø¹‰E5t9]0¤PÈQÅu.!t±¥%ì$Å¡1t±¦,<=º%q-4™.jÊ%ê1"âéiôé‰åÊENª‰ »¶!ÊÑ5'Û-Kz?»Ej£§«¯³·»¿3ÛQ7¢)׋ËCÇÿ8)¶ô¶¹¹g­Ÿ›pÒÊT‚²)“`¤¸*kW‘ B•:UH\ÿ!‰`‹ñeDHO&üê‚@ØA{Ùðò·`Іÿ(ý\ˆPB5׸ EZTM4oS˘ƒ§u+×®^¿‚ +v,Y±äÚÅÌšß^¥h°S…Ûo <¢’% ¶â¾<!ÀQ] ™K7€â²ŽCŽ,y2åÊ–/cάùÊÄžàR€Ö_$ƒe¦x°ÇÂN&PÀàlñÖM±7±H•·‹ÔºUBl0(€aä)ÎMüÞ,}:õêÖ¯cÏ®}»»Mj"̵âfª.;wœ'u¦”…Ä „¾¥õÂ/â·ÌòÀÜpÀ€X "˜ÿ Þy‘€°eQ*5@$°G0̵prD^°È‡ß"’WÄYxQá0ËÓ(X£7☣Ž;òØ£?¤CY¤‘G"™¤’K2Ù¤“OB¥”SRY¥•Wb™¥–[rÙ¥—_‚¦˜c’Y¦™g¢™¦šk²Ù¦›o§œsÒY§wâ™§ž{òÙ§Ÿ¨ ƒZ¨¡‡"š¨¢‹2Ú¨£B)wñ•@Âõ™FVNø•bJª¨ëP –@@qÀ&˜HDä pqðh*Eã1áÀ³U@x@€\°EM€Š P0`ÿ,4©±A+$0@ˆ%6l±ÇŽZîd¥Zz_\X{ ¬©xè_†_$Àj:¹F±À±"A¸W ö¹Z=2šúòK HQmÚ±0D'žÀæbº^ºE¼5’1W·‚ vž;ø¦ã¯l OÉ0äöÄ&%<IíÄö€Ìþ›±ÔamÜUÇO°‹ãÈtUª[~‹Ý¥Ë踜Í]¬dâ1=ÅÐMwÁmìÁÒmÕ<µÞ\åA€d‡‰P­/F] àmŒF\ZŠ)\õE…i,ƒ@‹LÐ6 8@ÿãœ/`ïç<ÀŰš\†Ôš…)•Òýï'õ‘Aý±“+©@«`xºÔËZ·VyÁ{ Ä¿÷`·¾,0@‰»ì—}‚³%_+µ p¼g[Ñ÷Äy×£_°at{G*â5Þ…óÔ…uD`~ÛCºàNòœ2 `p`ø’†@lHò "ó²^ð‰v°]LÈÀ.à¢r!-܉G¢V œ Aw›‚¦Èq“èLC¼JŒ&˜¡ 8p‚a£‚òàQŠGt`Ôž(Äâí!‹ C^Ñ€jq*,ÿ‹xö'4ùÌÏ?¹ÑSÐÄ*¨¯<h_f½:ÄŽ~Œâ`H‘‹»PàWlAÙîDÔÌ 0àÕDXÈ$dm ˜{l|F±@‹"‹ D€ ¨ÀŒP‹8šû`™`1;ŸC…Ä’Á16!€Ð(e™„f)¡lèx#Áø„]a1'ìqPsÊTªà¶‘Œ Ð?\&aÓf³ Â/ cÑ\úºx5›|ù¶Ùc¦X»¨ª‡pL¡²ô¸áÄ‘Ñ]R«@Ž – j¦û¾ ×¾úùB`Pý.оE¨Ið›ÈÞÄ ¤@!zÕ2ÙÌX´ˆ#ªI07OëÍ]x³ÁVt߬løÑñ’{l6_Á#æ¤î‹WãzÌ8»tQÐm™Xÿˆ9 B~)më)ÔÃq‹élŸP€:Ô Ê"­ŠjR‹§ù¾>‚kźÓi̸‰4~P± ·$hF §«`<04׫¦Ìrrõlæ*áºGˆnŒ¼Žê2AÙiHôv‰ÌkêÄáÉT˜tˆS´€¢” RÀ'z­"p! ¢6S£\¤F ªº6X‹0˜ß Ö³2èVlÅJØJȳ‹¶Õb‰Ý;·ó¼©X¼Ï%]1:„jöL Øg²=míÖ8‚®Ž8f$O(Äí|ÿ\ù‡i*ÐMǪ17½Ã»nDÍÓ»J _œžÆè ¿)ìÑØ,ó…yÿ ã·}¼ œ.´C9ýœ¶™ðÔ¬$>¶ðb=]€“{ôáDvî¡?ûÈŠ¿ SwFr²cwж±…§nƒ²ØK5LÇ. ÔùÍyÄ™ÀÜFß¼EÁ7†QòÀm~svw¡Ÿû£ˆà7[L䀻z¬"ƒÌ{ÁR¤»µàB¬8Q:àÄ zœ  Å6a0;¸Ÿ=\26 eJ¸%\-âÞ@Ùë 5l`¨9' k×Â( Ej‡¼¹³g…"%O– H =sMÀ؇§† \Ô˜£ 諒Ðt O·qá­ã °…Ò¬ÿÜãŠýàOpZ†ÅšåÑÖyç…•jð™JxËl€­±š, œYbÌK–Hy…ˆðž×Ð,`ƒ˜Gߦ¸HQ†8È™‘¸ÈlÀàÜÈ«ÐÍZ]€ÚνÎõÇÇј™àrE±ðÇ=R ¸W¼MLt‡TÝ€H=€_8O†uK\&JßüM†<ÀÔ€¾XO7ù×Ö)Ž´xKéôÓ>§üŒ\N6ÏdÐØêĵ‹Ît‹·üi ÝHN­°Î¤GGa¡ØX–AïiNfâÁ!|ÿÂŒ¡%èKó¨\ŽÉÈA¡^´ÈD@%–…&@cy”¦¥D€‹4™é·pŽ•!AªØ!ÁÐÊ,@x–(†4Î š‚c8vÅäˆc9šã9V‡)¸":²c;º#dП½ã<Òc=Úã=âc>êã>òc?úã?d@ ä@dAäA"dB*äB2dC:äCBdDJäDRdEZäEbdFj¤Á}AhE)š×÷àWÔVÇ'8vÄ7>FLÓF¤:¬)"vc*@¤GHŽ…GPa;¸|ÏûÜ!(^œ„4‚ÁO’ÛÊ5,@ꉨAR)ÿ&£ˆtÞ¶ËiM"Œ®1$~—)"NVZÁ#ÈcLºeâ›ìÇÐÜbð¤XÀ%:‡9Õ‘zTƒ0Y:©SšÔ ‰”Añ<òì”®9 LK¬¤–•`!]—A* M·Hã[‚f|¼]†gpîÃ]æù¬#ø…{!}f©1Æs(îŽm¾âŸ[¬Þ„Ü„n DÀú×HÀ !°Í[¤ÿˆeVåf4½ZE¨r2€rbq¤dh’g| m| "_jÉ# Ÿ pAMyD[f“á%q°Ý äød çyÿÁ'l€j.° áoÔB¤U&|‚PŠy(BAŒfyZèñ¥iÑ–…Iè„´x Ì‹4F²<­$@,B,„´$À5fW%d!h\®V…|¦lÂ+fã!2N0® ù§h6Á&e·‘FÁ-LV¬¤55ŽÌÆ|n`'!©0€1¾ŽY.Gìå…Æ$ÄÕäüBe"{VüOD­t÷” T§ $Q` ÅUCz^¶ØËÎ’Zšª)Ÿ~Îàg¡.Á~äÏ‘N¥ˆá„g(A,eN€Y“Þ¨=p O|zaÆå0˜dSÒ'˜‚ÿ¦‰)A-¨Ì €x°šRŒ0”ÞÑÜF°F\ ›å]Z‹îäý͆ÂåÞa]¶†[¬ÍŠ)@¬!6u—ÊÑ–Œ3R%„Èßa(A‘ÖÚ¼$À­V,€GlO†‚YÄÚ×}ίÂEÿ€Çç´¢b€*U¢ÂX‘«¹v"^HÀúÁˆ˜ÎÆ©êÀBª\þ…JtÂÌ%­NA Î` ŽjäQÕO&åA†œª*r\ ÈjB]"¦0Y=¦˜O~A¦€îT§Ä8ꃩ€Ð’-N©îA»()v‘âf͆Aˆž]Ä íõ@‡ë~mì†Þ]œ^ˆÇb!Yg%°„”(ìù‚ˆ¬LÚäpTpÌFÁ®€ˆTpòî¬Apš„¤@£þ©ˆD‹ƒhR~pñ²A˜Ì°ydªÑpy²ªô=ª™zðo­‡ÀnS’‚óÛkpGq¼§}ìráÆ‹£L±|l>ð ÷ô&êçõçzyèÙ91°Ü”9u~/&7ò&Cÿm?Rß.™G–ð¯ê¨~²æÙ‹ýB·Aùž`†„Må2ñOAÌ=¯­ [Á5ëªhì¤` ElBØpCÁ`¤#Aó˜-Ð6/‹ä¾-Y×`³Ç0 x$òÂT*,‡©,Á`ˆ”€¢+pþê2)ˆG¬ß.SÎ#'Y]:-ò4•špä(&ÆÒ¨È/}ê²nD{aW¥Xõé0°èÎKb’[@Pc FJrô“GÏpåyd-x¤;k¤ ßYa4€Ñæ±=à >1×ìþÅËq¡ÕA;AƒÕlÊf ×mS²ì4û¹ŸFLÿÀŒß2vy¨„¶2ÀFs<‚+BG\„«cˆ„U. Îþɲó¹BX§€Ä°ë(qèYgíÄÕ)ñLY‹Æ&.tn<ÛÂ\ [þ1ñ(ô[Êô’A]Úòàrï/ Kþ$݈$QçED!u_õØ_ò”äˆeBûÕã– \Ì,–¢ª{’´Íɲ)«Haä͆jK¦Ù•êª2§Š ×õÊÎÏ0€Z‰6ºt¸„&ö;h%"gÚåët.kâë¼Ó/†xN0r¤A;»Œâ¡ Çå…h©.úáLX@^Æà^ì}(À~Òÿ¦ðNèL@¬I‘¶JðØ «ðöœé·ìXv2Ï|Ú@$¢–*ˆªŽ¸âæõaMk°ÐM"G7F.v°tN'ÈC}éÍéŽñޏDÎdŒgääNI,ˆx9*Ú‹¿³¼ô€ä‘Hì<â/9”€ÆŠCÙ°ä‘;ù“Cy”Kù”Sy•[ù•cy–kù–sy—{ù—ƒy˜‹ù˜“y™›ù™£yš«ùš³y›»ù›ÃyœËùœÓyÛùãyžëùžóyŸûùŸz  ú z¡ú¡#z¢+ú¢3z£;ú£Cz¤Kú¤Sz¥[ú¥cz¦kú¦sz§{ú§ƒz¨‹ú¨“z©›ÿú©£zª«úª³z«»ú«Ãz¬Ëú¬Óz­Ûú­ãz®ëú®ó:$X` qa67÷²ÈáÀ+0TÂ\–ÁåäâÄŸoïAäg¯Ðî4y!ò±^„íZZ6ŽZæÚMuNì„¡¹ùP6F(?°öz>ª,°Å…°sr¬vÁ>{’]aT0 =;„qá](êoX{`âØñ±~»T": ²‚`2|‘)xî–Ã+À;ÛÎ;>Z–nÞæ½Ë;*;øô;ˆt¢üLØf»M\8Ç4GŸ'qÁ‡¨†1«0ƒqì<‡°À,Ðu2C“ç¸ójR$ÿKÝ>óg8@±°Ê´ ùÚÆg„†ÿ³§÷ÇÏ£e5ÁðÁ°›³B3òTY]¬)û-žÒm<«_ù…oíš'CA.̆\’àxtA“3:ø–ѰE4sç¡ ÄÔBÂ|õÙûRLJ½Ø»#Á•=b«W*?¨õøí²ø…Üì=ÜÁÃA_4WÏ©ø_»ØþøÓY™2Òo ÓÃ¥¬ÑfØ ú©†ìø&³Öü}½&T¾å³#Ù3¾s~|²;9>A䯋æqK [ôÝxNï6=@q0´xí¾ kÁÝG0úbgÑ _PÅ>å—<òC†ÈÛf àÿ¿sè?(âH*Ð eÙœëê¾dÛÈdl+t.âö ƒ‡Àelae œ,†@8`žKòk $¾Á¬eX „é5 4ƒ €¿Ï€iÀ5P„1dX4Èx@¨à„¥äw‚×6´”)u 4ùÙˆÂó׺“c×zRë#sû+Ó Ë³û³*èÀ£0+á @ƒ¹2Õö•l KÓJ*(ô`Å*"Om¢(l]í/Y@y9Ðä7œl€‡f«pv„$ÿAA†‘†Š0£kÒ\ÀkØHŸI¨%0Ú CQ3>?- B 5,Ûw*®Èb‹.¾cŒ2ÎØUx€ ØÓ`«`Y VÓ*¡4VZ‰ Á%”õ÷„Ò|H(T m\Æ J¨!“Å‚´4ÀYI© `À5ðsg‘ —ô!Í,ÙO.‘—"zîÉgŸ~þ)Œ* Š¡Р‚ …&Z¨‹*¡~A:¨ ŠþAi¦ƒºP频ÊŠ¤–ZÊ)£ž6*¥–.º…¡ŠnJŒ{àc•VÅ?J¦¤¶îám°de(ÐÑ@€Äôñp„YJ¦uÿ–Ì#ž…cñÈ·v3(¿~!…›(кJ —¾šh ¢>Ѝª®nñê§–j/£Ž²»j¡œ®z)ª5<é¥ÿ¼j¼öÛ ? q2Sas†SÇ1—œ5Ëá…TXQG]p}ØM=LéÅHUÒ€}oþ:Ð`—”×¥0VØ-CäØ2¾»ºìb ÜÙ´pYêý¤Û<²#Îl3ë<çv¸FR„ Ÿ`â@ˆpÑ1Žô¸Ou£T†á ÁºäfH’¦l‰¤;Â#8µwœá¼ØcŸD6ubp£®æ0L¼Ü/ßTÎÔ ·qˆ`ê’¸šäDOË_'AÏ©ɤÁ“! çX¸§“ä:)¨½òå/Žùà+µ{Í‚ÚP€´õÑ·ž™*¤›õ§#ã‚mç7°$/ŒäÞW¾¡-múæ±½ ,ĉìží'p{ð°/üøûôp@¡ À£uU”OÈ~}ÿI:K"[´•µpB%!á~ Íbp[ ŸjÑd ´A>d&#`No`‹ÇpŽp%JÆW<’ç~Ÿ¤zòç‚6Åh‘tmüGát… `Yذy?ìd}ÌñcÒÀu³‚Æ I›„ÀWgbg{v`Ñ`4‚[@dC¶0dÐ +x+-ø‚c(S°0_r‚ÐFƒB `V¼ár=´°ÐU;H NS PtPDÎÖ@ f`r³w„Ű»·„’5Yâ7~"¨rÛ@Y0'9g1H ¨ƒðã„d(Š£¨GêaÉkFŠÿ«ÈŠ8Ù5 0_¨×еh‹.¥ˆF a?·è‹¿¨R p²·jjÀˆŒÉ¨ŒËÈŒÍèŒÏÑ(ÓHÕh׈٨ÛÈÝèߎá(ŽãHŽåhŽçˆŽ•UÄH\Åùæ¨T('1ðØiŽ&TVg5'ì8 `ßDh×&l@΄&ïaƒxyHâYÚbÝ7~‰hòh7ïÔ‹|D}‡ø˜$„X/f‘–„ ’Ö!! Ð, Ù ©G–…˜µ›¥ £Ç"1:‰Ky 8 ’"´¦…Zîv?Ä X†Zð,Ä63`C¨ÄMÿ¬°ià!Ô[_pu€|2g@ æ‘/“#”¹ä“Æ”`q–C©˜ö)ò,ŠQNA%€°KØsÙ]{ÇföÈeé0„¹Gi)u‚¹tæ–xD^Ë@4ö³yT4ɤoï„…Dó¥%ù"{ß·þ¥Š«°ðp @ߥuxæ^er‹UtÀÈW`YÉ+S‡CrkH]OhÕ,ÆA =(_×$W'Ë40€Pc°yY†Š…dM à™z1››ÙL y šëÑš¨P…HV:shxˆ q– @ÿ(Ù˜à³a˰l„&LèÅl˜Y‰ V¶»' ¢¦ 2Ö—€ðÙYð,v¥ù1…/&B`FQ[Bðg! ±F$3Çø`a¥Ç&qB’C@•*ºé³šä£CqpÂr)B!: 0J,¬)¢W‚&áùAñ vq%IÀyÏB…‘ÁtÐh{õb@¡mñAY š7P–”ËðJ$0•ˆÙuŠ3 :Fg–f§‰š‹ø Yš`),=`àeÀ‡[`|6ÄC€fÛpfB $Bž,úbÐ }P„ §m:Yeã ÂZ…´£ñNAg˜ÿ`|çW *`E…Ò›Jªw¥Á-Aqÿõ~“„§. f$j²: -€† ÀŽr ›÷ƒP PuGgÉâ¤hŠ71xì9ûÄF °[?$†‡°o•ˆ{[1¦ÈU0éz^‡jÞº…ë…Ú~¤q¨rC-?Ô‹xIÒD§¢× æÅ+z!£ú$–dæ`0Æû CÙ™â C°’ƒD×o/´®×·¯O ‰D²¯Q§3(WeÔ4F iv´ª­z²kX:;!‘!É: °[ý”˜v*!0[“°}@Hú%¯c™Â€«´–uykÁr–ºX).JÿQ*q/´yz›¸–F~HPK ±i°©_0,Db׊{kž£wÌ?Y¥§MwKu„­cv´Ø²ƒ”°h±F÷;À¦î3sÑgs:;ÿƳavq¨@ppèI°“$>ç£D–U[4kÂÚĵ » E>´Á¢Z¹–+ÀC5«`˜ŽW\c¨ š´ç¸÷¥³ö`Ðs†·_°FJ×Bv¨dd¶µ±+Cc›·|ÂqŠù´I“kj?£ªw‰;u™9¬q2‡,Ò»B»}…WgzQX=˜k¸Óz¤: ºÐ±Wxš‡=H¶´»^®Ú ©* ÿeIwr»A‘½/¶½±s¾FË^ãk@Ñ0àsõ±³sf£À²ËÛ'ÂK Í»fÊb¯3ù¹õxÀ(`uX·Ø±¸Bë—BpÂ)¾7F¦D“Ð,¬'ÁëûÁÆðŸ0qïÊO`¿u{„±G,ûëjİߪ«“¶å@ÂÀ€“ ŒŸ@U "ÄO»…tü=õ{ ^\•*œÄ¡da²(;9»^´8[kë4gxDr®è¹ý‘¿Ûž'„ܰÅõÃŒ º&1§Ã”©GèºF‚¿Uð6ÉЖð¸íwÆŒwo|¢Åt [ýq@B@Hè'Áð!¶`œ7ÿpÈ{  ¡’úI„ 4–²;´¬" ’_ðz›¸K?Ô×0ÌǕ贬Ó9›Ð¾î‹^å&EÊ›È]+kŸÍK ™£·È]ç&03“t½¶ÌÀ,pk%ù”$‘óµÈܵœ¡zlÊ,B|H‚‚8ZÀY8(dUÔ;‚>Ê Ìgƒ·øUÇC }Ìð;—Âa²ú6²$†Ê°áLOG›jÃËÜ—„ø–ÆcDX˰øÖkœ±R ±íÍ ´A£Š T´©G›Œj=›°%.9U–)K{ ?Ï*Bö‡`ú‡úЋþù¹ÿbäÜ9|qò,Bò±^ÉqüàÆ6Þ‰ªÙÑçC$ 4í Дÿ»áï…_°¤pÀ—»d¯qŠbÑóà í Õ•Þ$s— ¹u¼ÍÐò5ó E  —Ü‚L;¿"_ÿ"m¿"üðß> ÃóPÐrÊD‰KQOÀ]I=¸ËœUÊ› a@Òö ÕË`–ö̰ö½„÷ Eœaª Rù³%ß™ïU I ‚;O ‹ÒW¸k^åóežM(Ã:°Â@›ª_° o  tÐsÃHáp-~æ†!ø/‚O.'ÄŸß×ÒISóàÒÔ}¤ {Ÿ¯ ¢«`^a{uqäæüÂïLù8Çx›Í¤›ÆàVv8@íÏߥdK‡OÿoŽÅ5 Ä 0Î3$¨k³LÃtC`¬7žë;¿ÁàgQjZ¯ç($'FÎ!À ©ÛOÄ( P:)5ñ8\U´#É­‹É à8HòešPÕOš CR¡ááEÇa‘ÍDÀÏCÀB¡Cã ¤ŠÂ‘ÂæQBS§Î‘ˆªë C@ÁkNh@YaÅÑŽc@­ kÂÙÐJAFÆD€F²„„ ‹% EÓgäcO‘"°ªÃÕ‘ ÍŸJDÞð)î EjO/6P÷bN‘IJ¸I8 A Â/v¬à1¶BJ†i u,@§ê€,ƒ@B²&2ÿ€Ì€nÅ£hÐ-¹Ì]Ž,M˜ Á´3ÖäÈ G r®²H!Ý?3J2…[Vgà’IÓ&a@p™2fÎ2D»‘RÐ:BUà¡´BÏ#ž–+)2É“ÞöH„QU¬£@v”צ X !á•§¶F­h‚²‚ ˜¼±âËéÇ,¾±pjÇ#2­@, ”cfhŠÌþÌ\zcÚ=»yNô 뵚P®ˆðFƒeÑ4q­c^lÄx à&¶BÐüÒ|â ¿  N±`ƒG¨H+¤§lIhà‡ª@džxèq‰&ªbnüõö¤ ~ÑRJy4`bˆC)h< Ÿ!¨"ŠŽG´·WuPöšgþ0b΃<øÔ'ºlp‘ŠÑ žV6…á û¨¹ƒ%@Ù Q@¹5 €¢=̳–öôæÜx¨ m©Q+èã!ìé  t"ÊÈ<›âä¥"~a ¨G©Â<‹ªÐ ^õ©Ã…kŽ“Z>±XP„ ²&XnwC/èÿr+¹Þ0j}<k…7äyƒ‘°ÈÚ¬ƒîÕ}Œ8@`î‘ÔMä8+¬Ê‰˜‡’YNbOP¥æfhè+ÂèjH´ò@yßo!3m›C`6‚áæC8¨¥I(Мr™¤Kg®]!ïðoÀ\jüq­ø`f ô«IM¥î2ë*«bðˆЉÃ ï É§€ô ÀLV,#Æs ˆÆGBTH¼Êö ÁevKЭàõ;'Ñc¬J»'Ëë¬@vÑZ ̈”¯è"NÛðîÝ‹Ãb   Iä;Ù ËD`ÁÕ{ïÕ€™+KšÿgN ÇTDÕØì œ8P9Ôtë@©,ˆmù+šØ¼,ë0MßUÌÐÎÞ[ŸÚ‚|\¡á‘†ÞÎ9¼+¥`À€Ðûícœ™(Œ`ô*hûL±ï:<í¡jµú9¨£7»?ß å;¼c~/0Àú·0Èü`ÀÞ¼Gi¸TÒ$ŒZ<ø[ã‚ñ@¿¥áÜrP‘ÃÜ _¤ÅLxˆyÜ¢I+ĤZÖ¾½ÁPKáÆ"ð"íØB¡‚ B¢%^"&f¢&n"'vb!4¾^žy")–¢)ž¢ÞÿšTØ€Ð@8,f*~aÍÈ",RÃvÕ"‰Ì\@üž{„8Z-£1#2&£2.#36£3>#4F£4N#5V£5^#6f£6n#7v£7~#8†£8Ž#9–£9ž#:¦£:®#;¶£;¾#<Æ£<Î#=Öã^Ä-ÎY­ƒ.ì¢=þ#@d#`€õ]-(HŽbL´ L@ Ö<€(6à1Æ-íª_9,@ 8b1p¡@–¤IÒ#œ¤A¿1B^yPÁÉŸ ”È^½Ivâd¤7àÁ$‚yÜLdÜI¥P¾£ä¸"Œ°X.%¢€hÅéÀ¸™\ .ÿ@›€€ØY%n">öF^>êXÝèߘÐÖPž%Z¦c…™çEÁ‹½×’Äœx\¨`-ÞdoèBÌW)¤$aZ¦`r#vá€$lYÁÛÈÍXl)âãXRé™)"fá¥gD˜ÄÁZ,Mš!l€€ØÛ— ŽpÙD€Á—ˆìé(r áB8€½%@D>™QÑ`î&oªBɸZÑ%ÔJfÙå!<&\>™)ÌE¶1Bü Ìä£~I^¬Ë»=#È€ÍDÇ‹XÄL@hçqPa¦ØJá9.Ì…^  ‘õ¦| ¦JB [µyF)øÙ2ÿåM0 šDURrÅ$PÆòù§sn›å`¤gDPix`;avÒM/<œL„%l$@„ AÌÂ…~ÚD(@"tÞ®T€Û¨Á(|§îŒ˜¨@Ù|Î(ò ,­Õd!¨C)õÀZœ—Üa (¢ü_<§¹Xæ^”Ñ›Øît_!¤æ[ƒ%@‚&´ÐÀ„kH’ T)9O™Eâ¹L¬Š$øc®éIÚƒJm¦Ú ÖJÖBe—ÔŽêr)u¾‚ÆdeolåÅ™N…N¡öÐe$ÌHé_BBÂЉ$Ì A,j÷Ä't÷lJ„a‡:8GP±)¨î¦¥À&Ä)0ÿF|5@Âàäz(ŽÂ ‘FN.éÙ*©7èfŒNåÀ¨*LªöüÁ<üé„Ö)¤Š)꯶ÕôT¬Ü¯º ¸[¨NkZºÌú¨*¼âüIJ.éèhäébî1 …dÚ*0”! P•Ÿò„¯ÚÔà±Â+¨«²Žý”d$F§R+Àe}œòÕi®>Ìz©*ì)â8,C°atz)™…æÀ4™!$Äë<¸úXj²Êk¾rÏ=ð+’l#˜eÀ®lIb*pÎ^" fä'@¬bEE‘{ ©ð9(_TDM)[fÞ@Â(h€ì_+¨9©m콂³úÿ‘³êý@E”!Ëfm=ç æÂ©ÖâÀL*x#–•‘da!ºÒuE!Ž5`Ó*-¥"fÂÔ­²®€ËúѦxB"´¥Ö®ZöK’EA‡é€F4'n6˜¤—+°×Ébk¬í+€êƒJë^) Ì…?î-ämÈâkµéÇxګ݆é½,S™Ê XG®íº#ŒØÀwúåèa™%DšLDz /¢8›¹™5™‚ŸÉÆ+µÀPÙÐjỹʾ’bUgò¡…Öeoáēƞî¬YBä›CB˜nÒî-($ÂüAR™¸ˆ:@[ÄÞ®þ¾ÿcJ2^?Aºðä'9„Ó}’ÔeÂQ&áÃÕ0çÜNƒ×öîƽÎbŒ[¹Òrì¬)€JDeuðÓž\  ¤ç$8{îÀFðìþÆ07"Àý=Ìmþ/B9ð' ûð®8ì4ì¸66 €íá^ReRìÑ‘N0tz.dÉ(°±òÅ'Sé­È²@«€k1ê²À|ät6ÌfmÊlø¥ ¿1#£ÏzÆò…öaŸÞƶÆ1÷q1¶í©Rí­^læ±jÁ°'²"÷¡ ö†®Rë¡!+€%„í"_2&" +#ž* bŸ #r&—ÿ²)ƒá‹cŸâSæ)¿2,WáÄÆ2-ײ-ß2.ç².ï2/÷²/ÿ20³031³132'³2/337³3?34b*G35Wó66²5g³6Oã&o³7s1N3839“â,—3:§s&v³:·³;ÓNöª ;¿3=׳gÄ3”`³=ï3?s'i$÷³@ô«h "‰3A'´B³Ô9/´C?tÍ3DO4E{ƒDW4Fg´)±ªFw´Gã¡t~´H3³ær®hôH§´3ãóH¡´J¿t2³to44L×42Ë´g\´Mï´=#4Oÿ4?Ó4PuO»4Qu:ë4R/u6ë3S?ÿ58+5TO5UWµU_5VgµVo5WwµW5X‡µX5Y—µYŸ5'TYÖ ”2aöl/ ÑZá?qRÑò3cPÄR`Ü©NúòDê,@16ï6nd¥xä\$€¹"ÇHÒWk¨Ëé¡5 ­'*±æ—Ö5"Ýõ>_çÆ•ÅnÄä; ݱ5êd“}’OªØ EW!\6Ú¶1nÓ‚v‰¶=+ og„ñšª uTJ%’@X¥p ˜45æzi X2@S¬u(\/íLÖÙb±êv1òög;®¹w=O„"ýlïÏzÐb6ð8êe¥äÆQ6ÿžfC yónÏa£"k7uï…zós{ŸKgG'×ÂÆ*ìDDÀ±Iì 8ò‚ã0g†t_KÀ\”Ü'×ÒÆ5L ¼þ7”¼­¬¾ðmrÌ÷…•Á|’ÒH ÀXA¢U/1L¢ŠF>Å&°-è¸óÜZü’)€ tǘ7¨x$1$@ F¡Ö¸‰-Ä€bÿoýÝ_‘åÀ ˆA‹ðøQÁ fÃÏa®:'x {÷sH1½À0Ã"ð)%/hði¯€2‚-Ü¡uÓ—ï€V˜@1­Kˆ…3àUNð9Šwí¥p-¸QØÉ"ä†Ì„PhnX ÿñ£ãáqúœ†ãÔ¸“÷ݦ‡Ã'à.J,N„z¢º6Ñöå®âôhÝøºW|çz¯+(§ÃX×xΧŸÁZw`ì÷7Ë9-XK!ô§b¨'„Ò–ƒf É?zç*š!˜Æ£!ôÂjT¶< Ú¤5@m ÑöÉFq«À£ÊRtŒŽ’ À<ÈYýÐ[ydL¼ó¹Ù¯„þÀ„OÀê„åKÊHMÅŸ¿»HÀ'DC ï2P„Í‹šc¸LÎ$Ó*^Êvlh‡ÒT'Å¥!àw„‡Ù&ÁѪش۳µ»|zÞ¾Cd"çyy8Ùÿ¹<—–*@ÿk»Ÿ¼…´u|Q¶”M^ñ‰²Ü;›Š‡’§Šˆ%¨ŽŽ)ôW‘GâÖÍ9W Sœµ†Ò¼Ì%tX9Ä™VnH¹!øöM¤J-„–ꈖ6=F…¡ÒŒ=rä<&í>וgØÇ.ùÂá)-ý§B ÌÐÓGhŸç@Â>®:LíÂRÙLeQ„ÕpXd ÞxsÊÁ¼ý÷Û£Íkí·7LÌÌN®ÐÁfÁ‘üdqmŠ%ЉÞÛNö8øÄZ[ù®žSÑjkõÇy¾Ó‚:ÌõW0& <àâP¦ÑÀR/vYæpΡ™!b†é® ÿ²pJ|÷€Ùƒ \bê¾p<7A"I™ pxŒÌe HbŒÕkQtVˆ¥v‹¢ô~ÁÑH ,DÍ3 =ZµP˜åå=,…ÄjŸ@ArZz@azj\"8d#*,({XGI[4”'‰žŸ ¡¢£¤¥¦§¨©K5¨WYK^ \Q ¡”o" +µ#z+ ªÈ0%•̘(ÌÇ04\I¼1q:¤”+ Ù(%1T/»É(׌(ðÍ{#M‰Mæ0H}LèƒäŒÝ zõÜ[cMC×YBA¥_—v`4 ÑcP† =.ÿbÐ’p¢D8¸¡X! •$ü˜ÈpàŽI0Üɳ§ÏŸ@w²²qêÏBTÄâÍ‚®G#|ÖÈA"+2%µ¬¤’gÑbxé°%Ê€–2¼Œ,…Àagað; ‹u;¥fAð …Z®ÙÔ2×_A|&¬ÐžÖ82²aXM„é<|Q"n°Å"IB=•òÅe¯äjk„àL+*4°t«íÛ¸së5%§2p(ýÄcí'¼"øN•€GëÝ¢®X,õG%Jò`Ÿ4e€H§€ÓQ4ùžâôNNKï`\’¯[ ¿ˆ`J‚z©,£„šÉ×ðgžÿqÌá‚ÛQ—äÀá½ A<©,â‚#od†‚rK½ÛZ4݈$–h"*z0HÊ{T½0Û8[@Ó^"z E_‹0P‚Ö‰KH‡Ê5"Zñ["Dd—Ê+«‰ç+$‰Ú€ì\ó÷ÉOEav£àÈúIP#v³ M¨BÊP|Â㙬KC'±ƒRô¢ÿͨF7š À¥ü(GGŠ‹’ô¤(M©JWÊÒ–öĤ.©LgJÓšÚô¦ÙËÉH ªáô§@ ªP‡JÔ¢õ¨HMªR—ÊÔ¦:õ©PªT§JÕªZõªXͪV·ÊÕ®zõ«` «XÇJÖ²šõ¬hM«Z×ÊÖ7JTTU7#± ´­ãàÜ*AWI¯¹C@(€'&B‰•@‹Tš!¢¶,3 «K£`T82ŽüZÀêeŒ4À—^܉`M-ØŸ£-í:92#/Œ-R=øz]vbXÙƒa¹€Ø= Å͈ç½êñ€nô >¥Îšˆ™""&\;‘ÿO"N{OéÒ“#öàî”C[¡5é¶‹  ‚âHKÚ…°4'©€}XšÒ+TÖÃV"«2 O²(ðé‚bÝ-’ž–' ˆÀ‹(o‘â®I™Ó¼ÐIRoF^-8"´¨³&!ªQû¦â|[™¼¨Ö ^ÂçcuRƒ=#@Ðk#&aÞ]¡¯> †'¶aQtx z Å+îz—`‘Ñ ñë+¸ßT€äÅ/ÈœÜî; ,ó—8@m*Ø A.XÀp™ ÁÖc@Ò‡"à›ì[ ™™Á'/ëa¢„Ó%I@ïæ/Xf ÿŠA—R’ÚÌr- œ¡f xL×*` „±S=æ× Èfîö΀§~Uy:G4˜DšóÔ×fŽseó0Gß‘ 9zHPÖ”¥PKC AE‚ B¦$è¡pC¡Ÿ %Åh=Kºw…·%¨‰ 4#Ç9"ˆ&Gnù8Ϥ‡ÒÉßñ­òœ?ˆ’䢆b§% œ¹"Œ\ê‡ÊBúÙ#@HP ‚2N…²`ª£E”%?Ʀ]…Ÿÿþ`,ùò#ÖüB íÑðЧ\0*Æc*99£0.Þ•n¢ðn‚6!¾všZ0Ì¥—Kh-¨ã€³ˆÃr¨/©¥””Îò•Éu*Õ"ЀC&\ð-àvº: {ú‹²ŠVÊ/Š-Êbð<ˆ:åÕ,^3•mÒMðnI¢Ôª©¯€CfGNMÓ2,´ŽÒ7«Ñ ö*ô°< l8¤°ñwWVs1¡4¿† _ýå'ñiˆ ÐZ´°j&Û^¡ x3S3û‡3å¨|6 ÿ'Z¶i ¸™k—4^tƒâ5åç¥Àf5³éxxM˜&p‚ÿ€c6ƒ7l“nS¬ S(ÈÔ8T¨ˆ"Z¬n™³°áD Úzr°3j¨÷!¨ ²¹·†=£1„z* Ò:¯7Žhµ³µ‚s:ŸÐ|ÀÁ‚ʱ8k3æÙ ÚÇ}´7p3¦¨d.`Dõ·v}~` Ë™jÕ[{0-™S+ôÑ åB̸ŠX’‹dÎS=3+=ýC¤’s06Ôo0HlÔ´2? ºs9ç8÷C4‚1‘@|°Ð@/j©'Hz5:¶| „÷CÁ¶dආ,¤ZÍ'B8Ä¿»tt½ÿÚu ך­tÕzÏøBiBHˆtü£t×3šªCø[)·qÀf!iþ;V kQ(-Ç6!Ú„) € Ej‹+ÍW^ø­›0b”v¤yFiDv¦ ¶ìš¤pÖâ=ÍÐ/3 ‚E©–k¡5H{`fh¦ÔåôÀFìY{I’DMËiI©VÂqfEìI”J£Dœ­(œ1@ÉâD&ª¼4 ¸FÉ÷$ÑÙ¶îºi6=bÔ#›e†˜A0Ç…j“¤k«ó“4eÁ¨±–FjV) @ v¹k½f•[0ÐÀ«Z€M¿¤ÇtTȳfuÍ3N“<9db…»ÿ¨ÐNú‡¢¼RѺ©ÜÊ®¬”, 9x õÊ-µi¶œËº¬ˆ±, Å;»Ë$µÊÂ\Ì©LÊ® R¤ÀbfÌ'…ËÎÍxeÃÒìUðÀÊÕœÍ_u Úl´}ÑeuÆ¿äj²¼uL§":,9}!PÇjDª EͼW cY2PË%v´‹Ñ8m\ #ƒõ`s_à `=+ËsóÖRxN‹y²gÿp++Ò™Q5–ÓT}w#¤š €2ñåQ”`t)ƒÀ óC1¬ ÑGD â +:vüfsÊPS]Õzíz´¨Ð×6ˆ+ˆC ÙG½R,­;=bª*­V •×{=Ùìà>õý ŒêMGzÖS©`ÒZLR¦Ò»Ì@¡½ÌŽQsÊ7뎀Æðh°@KÝ/ °·ö’‹ƒôK·´:"ìK¶4NÅ„’h]Ü<ãK††€`É'#+©¤­¶ƒB™MÙmÚ"@È €^Ê 'a  šK8nuM bl¦Áüü9 ÿTðÝÙÒ)X: @=?4#7dÔ=´|ã¨ë?Ž¿âöAÐ1ð[>ÄÂ-ÿÍ ‰¬ÒA8F½ô(6sØ Þk¥? @~…™ã,ÐS[à¹V2ÔŒCçÚdh§¥k—m7ö«³½l? Õ9ˆ9ºn§Þ‘°7½Eœy^ŠÀÃÝ 0¯(¸ b¶2i(ð 4cQ¾(7·Y¢÷yÀì/Ip:ÒÔMÈ÷xË7h1 lmâaå% s#¢=pÈg'ÚH9£ª@¬bnm߯J Æ^ÉÃ(: œn¬a^Р§Î¸¢„Ÿß.Æš¾xŠ™£ !‰Mn˜(! h“H`ŸµžV^Ög`íÎ~¿ÄF4ð‡R3ch7œ;ìÈ‚”0Ž5kN‰­ I“êõj/¯ w9 ´Z0æ%í¨)PÇã`gô…¤óÁŸTPºÞƒ9Á9ö„þ8ÞQó“äõnVvÊ禱®iÓò½0!)ümà…ÎS ÿÄ)¨]Ãs4 ˆ.¯ÀŒ°˜rCëK@^xêP¢!'\;òo`ÖÍáÀYîÆùèÁYuó‰õ°Q`¾À ¹ðî;^QJ(÷- ó"”.­q€ÊHŸãOš¹UèÒðUõÙ0õîÖò:™ä×°Úžø·‰«öº>…ÙÀŠ1vñJÒöCé4Ð÷ÈØH!!rq3!¡¼÷ï×úä 騍™J)ˆ˜øÙZÍAùâøìðùŸÀÞîEÀk’D>NÊÏñi_õ@#ë¨#ýô%G¾òÞj (/ê·[À g 'ÃåMûhEœ]ꦂÏ/?8ÿ¿/c¸Úé/‡M€8’¥y¢)j’úÂh0Äq8©T:µ°Pb£@ÀRâF\©BFJF2XŒ1œ8d– l•TT”­094ÜÄ>,0)´žLyrÂNšTfË4îÑž4ðüÂl"V\‰E0]_2¥M„’P/%¡(XŽŒú”æ¡ð¤mó©±)¾‘ÌÕ‰Œ•–4P$‡ þˆ!L¨p!ÆB<Ä#‚Q,`ÂÁ„ƒ ÿ @`”áF9P r%®]TØ‚@·B0hÐ`Á”-ØPá ‚=ÂbBƒ!‹a g4ƒïŸ,Š,U¢h€îPŠÜ¡BLÄMÙªƒLL÷$À%  ˜²N^ìV‰°@ õ½i@‰Œ´D° /$>Œ!q3çΞ?ƒíAÏž äÚÑÈ‘ kÖ º°Õºu‚Â7f?6¤à6kA—³ ¡·"¥ +¹xjŒÑ¤Àq³f%j°"·ôŒGÈ &§ÜÀûl‰­&,k˜ò ã^4\ذ! ‰¬‡¯ ¼¶½SE0FÂÿÞõ4Ô‰ÀÃR¢1Ø ƒBa"`p| 6‚cô‘ÀÜ0Àz?‰ tü Àä•úµ@y`À9¿}å@¤wÁ‹‹ÇTNI˜‚-9¨`&ì!"Z8@Hb“„,º˜áN,@(‚yç× €å… @ÐÚà@SLA††-r‡b’À!F~²$³ØE"š¨¢‹2Ú¨£ªB¤£•üwHy…9ɘrÚ©§Ÿ‚ª¨£~ÊBrÊ#!oŠÐ¦¤Â«¬³ÒZ«­£ Ói%íâŠÎóê­Ã[¬±Ç"›, Myjÿ‡† p€_®–£¬µ×b›­¶Û:ˆ· û­¸ã’[®¹Û2{®ºë²Û®»ï¯¼óÒ[¯½÷⛯¾ûòÛ¯¿ÿ°À\°Á#œ°Â 3ܰÃC±ÄS\±Åcœ±Æs|«· iµ\Ç#“\²Éˆ¤Ë'³Ü²Ë-§¬PÈ/Ó\³Í¬²È7óܳÏÇœÐÌ?]´ÑóÐÊG3Ý´Ó¹P® /ý´ÕWcýPÔ å¼PÕYƒ¶ØŒlPÒÄ =¶Úk³­o7t61_·]·Ýw#ÔµÐtãÝ·ß2µÎ€^¸á'È=IÚ‡3ÞøÝ¦:Ä·ã“S޵à^ï\¹ÿæ›ìËq‡R9磓ÞoÙA®\髳žïéÄ$®©­Ó^;¼¯s9¸¢ÛÞ»ï ëÐâ¿_|Á±K"¹ñË3Ÿ/ò ß¼ôÓË<µÔcŸ½»ÖÏÍ»ö߃- ä-}øç£Ÿ¾úë³ß¾ûïÿüóÓ_¿ý÷㟿þûóß¿ÿÿ°Ï“P4p` ! §âØžU71AR4”p dª °Àòâ#Ø@:rÙàÒ3KwÊÈA s€ÜFU%2е °*A¨… €2Ð "âÈÐÅEšÙ|Z<˜ œ,¤¤£ˆc‰­¹R÷(Ҙęa ÿB—lI¥H:XÀL p TÊRyl—3•„1מf³µ&Ȉs‡ qá-äx#6«‡é h,Ï$[¿àŸF¢/4|Îü[ƒ ¨ ÁLàP‰GÀË ðý1\4¬ã£å¢ø%U+C€Ã¢Ô DÃmmJÜ SÆ€Ld#X]döÁÉT2#<'$ˆ µOŠ2f0Œ0¼‘@P ¨±¤<ƒCðu*™ßDˆŒüR–Ÿp3ΰG$€Sÿ”n%‡ÞàÜ;ð A6ÁãÉð ¢¥ ƒ—ü)l’„unÃ"Ü ÁÒS©K€êB8x³"èÊ9USD\å,9ľÜc"ű˜Å?0Lh ¬c x@ñ*ÜÖ2!Ñ:@giA÷‰oN’cÐßørȼ[媺pàRæ¶â&w¹¿X‚Uby0xåjnjOwêת–u |Î9œ{¶ˆ´¿åàî6ÄG@áÍðÓ"qÏ–±(lŒÊšT#a»ú^šcÛ„"óbLÁÇÄ¡3-B‹Ã‰ `v,SlÇi &xCœYÐqB Á ,,gI›–çÿ•.¦‹aÑ{ãR…ý‹÷R0 ý€áXˆ*w¡ŽX‡™ß9ÄÅukC”:ŸMª{ ƒ£÷ê\ùx=ÅÂgýŒü9C—-"H»¸R1?ÌàLEŒB繎…™‚I—€&†GÁžÃ¹â¤ƒÊ£V{ }‡Žà ³~î õ”fv 6Fè ¾Ì ^o7z&ÚIp‡€Á˜'%å±Õdö+dú™sÞQ0 çl{º|»Öe€=ìc˜Ž †Ðx GÚ‡/cЃ°ïBòßívÃþ>ͶÂ×´ FUø´ÿ Z?d#‚÷ÓÅÑ4xLAú&Vÿs¸pi4k釡ý]"„Ì´L‡\Þ”QøyÞÀÛ àôÕÊ&ÉÃOmBHÛ˜š½1–‘ßÁ}…[«ÈF·áߌ‚™-Ä×IÓ2œÊ•À3tZ¿™‡5T ‰aØ7 jðŸyøÁQž ÀƒŒM ž(M´‡oðØ‚­I¦TÂðÉ5@¦tôŒ˜. aÆEœ€c×üyé] è *PfXY6Æ dXôÄOÔ×PðÃüJ"LX$¸`qÜ%¥[ ¬(… ž@l€]TTm½ItØÙ°E\¸˜Åà…^|àÃù+¸cmÿ^à,‰oíXdðÃh€'RªmHdL†'Ù‚v)ƒ,Œ×D˜&ÊUQšjœ(qüìV (ãQ}ßìÆlø†oè_× ¢ÒÀ`ŒhÁ;(ÉÏí›9ÕReGy wxGR…oˆ˜:¥€e`]°Ç àX—DÀ8},c~0wtÇ´˜€GüTXˆÇx•@vIkx @ôã8à–;²F0 #¢PC‘ „E.Ó $Àe­™‘ Jª$´” "Ùˆ¬ÝÅŽL=G7šMÐ-Ê‘#t`ž4É"Tˆ$š\‰;eˆŠp‰—€Éþ±ÿda”   Þ­I7ù;d€ Ù âø#$e`ÐΉ3]$<œ¤A-Ô ÊõE FHJ®#~äò ž¢PÊ"\Ê à…Ee^¦Ã¤_£¤J Ý#°Ya:fÁì%_þŸ(%Ày#^>ffòË2ˆ³x¤I‹Î`¦f’æ½fÀ4fiª&¾DæjºækÂflÊælÒfmÚæmâfnêænòfoúæogp gË´æpçèœæq*'çpær:'ÞçsJ'á$çtZ'àDçujçÅô!$4çv‚§Âtç#Tgxš§ÄŒ§Äñäy²'Ä@Ü×$dg{Ò§Ñ”g}âgÑÌÿg~ògÍ|g(Çüg€èÅÜg"(½° 7¢Y‚:¨¼¤g# èƒRh¶D(#D\…j¨º\è"L膂(Ьgˆ’¨a~c‰¢(ðŒhвèñ¬h‹Â(ÀdhŒÒèf¾hâhŽêèŽòhúèi éi‘é‘")ç°P"€Áâ]Ìp<žÂDT„ÂñL!ÿB'`oy¥› Ì(!PGÌ›j]ˤªÆÀ¥‚Íi*1Xà˜¥e ÌÁõ¿YÈ/¥ÀLÀ"! ÜW8€Ò ød­Þ„Tª!è*ñÉj¯*Bõ¹ÇõµžvHþ¥ƒ{ÕÀ8€o`lˆÙd)vh€3y‹4‚,l#ºm+€-‚×>uåtÕÆ\À>mÔyPÀÀjÀK ß?aG„B´ÀÀŠˆ…]k€X°ÈEŠé1ÆA\^ä ¦ÀN 외Bk‘P^D@Á2Iµš€Š´“Q–€‰àFPºì9Ý+·Ž€äÅaP¶¡ùÒ̲ ÙY¨«!$\K¹ÆmDš„=*ì¼ÿ˜_²Y´fØgš€DšÆ8L–•õD¡k@²À–Uk„ÂH6„lU]ÂÇ^I€_,X1Á ¤-kÌc 4@Ï©@…™õÄdH¶†P1A3,ÀUõœ0›ðJØ2ξÀÒVbeªï)“H˜‘pZQ¤GÊ"ДAÑb»ò[gEFhåä¶zçÓÞW¾€ÔªÀù *t…§zªÚ¨’Ÿ+¦IkFu]dW(PÀtƒ` «­ª[—x‚¨‚kjt©"@Ä'FÈáWD#lȤB}±®B–Ýpð[üc±éŸö€]¨¢IB®Œ•Á~í[ù½€º¢/-datÿ„kD@˜ìŠŽ…c -„AB‡VÇ÷щJYÓ‚"áºkQ‘¤X¬V>Î’ PÓ*¯<àÐ5–@XT/ Œq‡]uI_ÅÅÊ.žü•ëæå ¸°TÂ)¶o›‘“Ý.#2ë(œÅŠ@VQ OÁµ“'VnìfŽÜž#Àç¯îòÉÙdÆ×BóA ¡Màí†î­F°°!šmŠàžB3NcXŒf¹>Ùüuƒ¦™§±0ãiؘŒ×ñ`B.¨ €¨¥&¾~ÅœdÀmøÅ"…Êè‚é*\,ëoÆ®r°Õ Üóž¿Ç@àM‘Äÿ0 Xˆ?€”°môRŒZ=R@mJ‹‡™€I¹^Í)Ý€^‘[½Ûòž²¥-â¯N](.ÛÊî »/wæs‰H¹1ÝÕaQ802Â-1‰XGp8\¢T”E©T©àœA÷m²êΛë+aLV-žcX+s²CNÀ^•1ËídÚ‚:ßÞýYÐ!ÓÐ3øzåÐ%¡òT,E:ó.ƒ“bµÁ¯vò©ÀoÛ!É´Ð6;_7ÿƒ`EêgŒóÍDŸÀè À.¢‚!œ±¡Êó£Ê^Üy<'ÉÆ†jȲ7œXÌbqj,md4®Îñÿ23uD×€Îj.Ï`ká˜vxk• IÏYT°‚lˆÞ˜zú!ð!´ó0©.(Ç!ùŒrÎB€Ïz%AÎrP˃Oûó]‘-§†;«€ßÍ^7DßdkXçt ~Tëÿ,!ˆk++Z3W+‰W›ûѰÖmö9K t-Ý:Ã@€l† ¸>Ý`?‡é)áJ'4ëõâÍ´d§±'{Ø8F0)m1 ØGªMö²dêp3¶Óm&h'HÛ°’(ý„r§/p£€_3ŸüŽ+hÁ‚îähão'ÅáóJ÷ívß)‡C,mRé´âõW<KÿÐŽÁÏ@˜X%"”°|“’opáη|GÀj‘°ø 7 €a)ž@I YúæîP %ó±&3Ý!ÜDNС¬Y¶—e&yGñúáêJœ2"&¢WÚp Œ"}Ù®eøƒó¶Š:EœIžJðÃTjP†w Ç/õ7"dD,R¶›ñ"{ý"u?ÇOYâZ´ì‘ ©ÇZlBø931ºI¸&à×~,Ë×Y1«nðF´xpàÇ4Ž–ê’gY¤š“á²f„:‚Dâ‡ÀFÖN˜¹\/ä”F°]‹ÙN$lJ5âA?úÅÀí`Ì­nAÞ$ß²k}?ÿºx_ñ T&Ö†G˜£c\äÐY<jƒ‹Ã—ZÐHF82"Ž–òô´eì–.–G'ÐŒ @´ë]Âp\@Èi1Ðùƒ°Àç­‰E!k&¿?©IL†©l¬·P{¬ €E¤d¼JQhã?À®ç:Q3ÂN´ÓDÁžÑ¥].± oÈ…ŠT›SúWe1Í®{I|I4ÃúÚ8’‡Š 0ÌóÁ3v%¶Ûp÷꾸Ãs«,H²I1Å[…þ!ôýâ?hã—¸E >ä#è&LÁ>@jCeÝ[>ŽµÛ²$~à>€(”ƒd0­ç§>êäìÇ>~žÐþë#ôíçç¸Àî·Áé~kø>~"Á–êñ <þñ×§ó*ÅÜlç÷¾ó×gT€[ùÇg²ñ˽õã§V€èîÜå=ø‡9¼4 4?ú·gã÷7âñ»s¿yþDãKCäýìÔ?x”áã–Ð]õ÷¿v¾Gð@·÷¯þŸÿoç]ÀÀÎÉ2mâ{¿ß÷¿r ¿ùÛ~ÿ‡§ð›¿í÷x ¿ù#þlœ~ÿ·ç¶ëÿù÷?‰¶ÿƒ¨÷ÏFÜ÷‰¶ÿƒhû÷ÿt†!ù!, o ÿ„© á!›´Ú‹³Þ¼û†âH–扦êʶî Çò¬F ÑúÎ÷þ ‡Ä¢ñˆLblÌ€ò J§ÔªõŠÍj=s ‹Çä²ùŒNsš^‡@ Ëçôºý®Üf(8HXhX¦Ç×Ñæçtø)9IYy‘Ø×è`ÉÙéù *5@ºGª˜¡é&ÊÚêú {iJ‹ºÔõ%«»ËÛëk—XÊGº¡ºù‹œ¬¼Ì\„‰ÙaìØL]m}½ñ¼—©™ý .þ»m«!=ž®¾Î) ÍÁè×N_ooVú@\Ì$0 ÀFNAàwKÁ… :T Þt+Z¼ˆQA¹sÿ6äMË2¤H{Û¸%ô62¥Ê•ÔPmLeŒ¥Ì™4aQ€¹ kúü ’žZ^ð˜+¨Ò¥Låœzgtâ \›Z½Šu‹DŽ ³zý 6É5m„=‹6펭0»ª} 7n‰¨mQʽ‹7zûúýËéÀ„ > øÏáÅŒïjòÒ8²äÉ”+[¾Œ9³æÍœ;{þ :´èѤK›>:µêÕ¬[»~ ;¶ìÙ´kÛ¾;·îݼ{ûþ <¸ðáÄ‹?Ž<¹òåÌ›;=ºôéÔ«[¿Ž=»öíÜ»{ÿ>¼øñäË›?>½úõìÛ»?¾üùôëÛ¿?¿þýüûûÿÿ`€H`ˆ`‚ .È`ƒ>a„NHa…^ˆa†nÈa‡~bˆ"ŽHb‰&žˆbŠ*®Èb‹.¾cŒ2ÎHc6ÞˆcŽ:îÈc>þdBId‘F‰d’J.Éd“N> e”RNIe•V^‰e–ZnÉe—^~ f˜bŽIf™fž‰fšj®Éf›n¾ gœrÎIgvÞ‰gžzîÉgŸ~þ h ‚Jh¡†Šh¢Š.Êh£Ž> i¤’NJi¥–^Ši¦šnÊi§ž~ j¨¢ŽJj©¦žŠjªª®Êj«®¾ k¬²ÎJk­¶ÞŠk®ºîÊk¯¾þ l°ÂKl±Æ‹l²Êÿ.Ël³Î> m´ÒNKmµÖ^‹m¶ÚnËm·Þ~ n¸âŽKn¹æž‹nºê®Ën»î¾ o¼òÎKo½öÞ‹o¾úîËo¿þþ pÀLpÁŒp /ÌpÃ? qÄOLqÅ_ŒqÆoÌqÇ rÈ"LrÉ&ŸŒrÊ*¯ÌrË.¿ sÌ2ÏLsÍ6ߌsÎ:ïÌsÏ>ÿ tÐBMtÑFtÒJ/ÍtÓN? uÔROMuÕV_uÖZoÍu×^ vØbMvÙfŸvÚj¯ÍvÛn¿ wÜrÏMwÝvßwÞzïÍwß~ÿ xà‚NxᆎxâŠ/ÎxãŽ?yä’ONyå–ÿ_ŽyæšoÎyçžzè¢Nz馟ŽzꪯÎz뮿{ì²ÏN{í¶ßŽ{îºïÎ{ï¾ÿ|ðÂO|ñÆ|òÊ/Ï|óÎ?}ôÒOO}õÖ_}öÚoÏ}÷Þ~øâO~ùæŸ~úê¯Ï~ûî¿üòÏOýößþúïÏÿþÿÀ p€, ˆÀ*p l ÁJp‚¬ /ˆÁ jpƒì ?Šp„$,¡ OˆÂªp…,l¡ _ÃÊp†4¬¡ oˆÃêp‡<ì¡Ä qˆD,¢ˆÄ$*q‰Ll¢ŸÅ(JqŠT¬¢¯ˆÅ,Ðjq‹\좿Æ0ŠqŒd,£ψÆ4ªqll£ßÇ8ÊqŽt¬£ïˆÇ<êq|ì£ÿÈ@ r„,¤!‰ÈD*r‘Œl¤# ÉHJr’”¬¤%/‰ÉLjr“œì¤'? ÊPŠr”¤,¥)O‰ÊTªr•¬l¥+_ ËXÊr–´¬¥-o‰Ë\êr—¼ì¥/ Ì` s˜Ä,¦1‰Ìd*s™Ìl¦3Ÿ ÍhJsšÔ¬¦5¯‰Íljs›Üì¦7¿ ÎpŠsœä,§9ωÎtªsìl§;W!ù ,)  £ÈIi¸8ëʧÖBÖu_yÜšZ±YèZ°8Kµ}›«>=Œìȵƒ€¢¸(ŠÆ€$¹œ4Ϩ©d:¡*Ø´kýjÇUÉ5E{±`à†›¬ã5w^ëé%fA&   ‚F Œ9 ‰ I|9C ‡”1MlD„ƒ%Dx%+·gD¼;ab½m²¿<!ù,7  ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù,F   Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒV‹C$\ˆ,’'X…# ›‰$ ' qS2.'ceƒ=€@Aª¢¹rµ8´¹q–¸¼rÁ³;{ǽ!!ù$,T W ÿ Ždižhª®fà¾pÌÎtm‹qß|Ïë‚WÐå+SºäqÉLê˜Ð¢3­ÞCgÐÊMeÝ0ê»›IÂ\6@’*€JdF†Å#A/8R &„ ˆ6d/m1 #.„/' /œ$¡.‘l#n ˜"«"š$. "$w§¬i1C“£6ÂÒ# š&Ž "š¼^­“7 $å'±¸“p4kS$±žT8 FXQ0B J(˜E+W"b}KkœC Æ‘  ’)WɱöêM ô0 r„%“'¸pfäâ¤d(–‘’WS… ë©æÉˆXûN”IâèÁó꩸ÄgK 'B‚p®(€nRžÅºÓD:uIÖüL‘034 (3m8Æ.Kàà‘ Zixá&ªÛ‚ô46+"á&M”H(éB {*û)iéØ-> 0  yµD >XÝ ÂÄq¼µ¸îŒïžÅL‘Ü 5'Å÷NÞ8ó*0D—ynK$ê\Vº!ù,œ  ’ Ždœhš–,©¾h+ðÜÒ§Û&¾ò®€.¥€Aß 9Rî˜Î%=Ž €! "ªS@ÂR*ªˆ˜X» ƒ¨ÖÊòéΪê79>z3*F?"X|}Qz=NzZ‚“WY‡0‰‡‰m‹™–4C£lŠfšyS~®cSxƒ/²¯P°B„º­¸ˆ/!!ù,«  º Ž$œ¨€®A鎬ʢï;ßgíâ·^β˜ÏÄc aÅÕQ”T.›´g È#1 ‰Aƒ@BGÔà400o*ªhH8D8‡æ'3)¨š2.vsŽŠ_E–'TF>@8¢P‚©_x}. ›SUl µq ¶E`bc'Àv-# zÈKŠ=R_ØhNG<Ô€9OÖ×Ý‹ÚI!!ù ,¹  ¼ Ždœhš–,©ªÚÎAüªs{ß9»¿=Óï º^¶•Q4T.aÐÀ’Ù<‰ ‚’<Çê5P˜ÄŨj`  ñ–ˆÍq<¢Tbnp% gyƒ%'w7ImX% 'rCIc€$—™l" ŒŽ’<ƒ…‡‚o|"~ˆCzqz ·?cg(kQ(EƒZ\³°‰”=H«Ñ9M6c•Ö¢ÉÒܤÚ4ÜO5‰ä‚çÓ(!!ù ,È  » Ž$œhš e;¢‚*»®ËÝâ¼^ò8Ÿi¾€*£™T2o9' 9B`&ƒ„Ä1džDÍi€‚½ÑI ‚4'.ýeœÚ#Ìz‰ƒ¢z%' s^1 % '‡h-d\h‰j—%d ‡~=$‘t9ƒw’SAx"z|“jmoq»^`dµÆg'£)Uj[]ÄRË*~J±LÙ¬ÜtÞ63ÕÔFˆ_NÌ8!!ù,Ö  š Ždœhš–,©¾h+ðÜÒ°ÚfŽŸ¼Nº`ĘQôÛ-›Ê'T@*,Kd¯¤ T(ªZ•˱8¬¡¤òõ†«ª3lyƒ*~m"eX|xn{M€Ž,Cceˆ”#V–&Š}@‘ GŒ¦#l‹d’—HKw?T´‰4´µ?»­¾£º¸„ù³RP!!ù8,å  Ÿ Ž$œhš–쨾hÛ°ÌÒ©Ø%®Ç<n52,³!Pd ’?©ù¼Á¢§©3éËr)ŒH+H2“€&“9Æä݈ Uj%\ûˆ³µÒ¢ZU=qyCw†`Kt~zL}ƒ(XD"‰4$' ŽWY$'o/”¢# _bª„Ap“›·µd»¼Aqr·¡*¾ÂǶĬ¹!!ù", b€ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€kƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯œ.°³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄ­²ÅÈÉÊËÌÍÎÏÐÑÒÓÔÕÇÖÙÚÛÜÝÞßàáâãÉØäçèéêëìíîïð±-ñôõö÷øùúûü˜æý H° Áƒ«þ!\Ȱ¡Ã‡#ŠS(±¢Å‹3jܸ‰"Ç CŠIҞǒ(Sÿª\ɲ%¯“.cÊœI³¦MD0oêÜɳ§O„9 J´¨ÑnA*]Ê´©SZIŸJJµªÕkó®jÝʵ«Ó¨^ÊK–#زhÓª]Ëï,Û·pãÊõæv®Ý»xó««·¯ß¿€Iñ L¸°áÊ#^̸ñÝ@#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°cËžM»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØÙ`À»’ hžÐ=@† 0€çn€ÈöÔÉw?ÂAùí[ƒŸ½¿Ü'`Ì ÀÜÀAÿ<à],à@ ûÅ€z  4 d@}+8@\Ÿ , _n ð@† PÀ Šh „(ÁøQ‘Á€ÜÍø„ ¬¨B…ÿE™]€HvGÀ <ˆZÞ`A´ ÁN²á‘NHCHÀB–”‰e´°ÀäfÀz÷!°f›,$Päp'€€J:à‹+Œ)§”B×€”*%~•*à¡ pêÀe:|¦ŸJ`@ pÀjÎÀ&‰)°ù„]‡€ ¬¢Ú¢~ºúã ‚>ÚD¡dZé¦O,é²Ì–p©°0\êi­5|é¦ÿÛÍjB¯¾ÂŠ‚¨´Öy\€ (P‚¦z{B°FÐAÊ6+o¤Ï¦`‚æX&•N@BP0A†@Àm ŸÞ€æ€piw;Žp€Œ Àª 0AÄ"0@®ÌD0ºÂ½dH€°¯¦°°€Ð¢À¯€þ’p_¢"d™ ß$`rÎø½2fŸ¶ŠÀD@ðæžÀæµ*°kïÇhA“Bù® ' $ïØ©7j@È#8P@¾˜]eJ?ÌÇc­¯³tÀ@ÚkÏ+¸kõÖ× Ü)½@ˆ& ™Aw—!w <š° 0žtž3˜ÿ‘x©tJ¤È#whÆùÉ8+yw ›Ð2 ™ûÈyˆ°½Ââ˜Èà@>Bï‚Ö'ꈦ“lÂÞÝØ•}@ë'L {ìî^õ †SŽø•AÚ° ñŽPöpjßÝÜ+p$wL/ J èÀ“@Ä p<Ò¡À>ÖKœÃè$?îÐopLMáÆb@1Û:õ-m ªA•p±J$àÀ‰4E²øiáÁNä! F à^p(<0€;0WØ£»_©À„7àà Þc‚z½N<Ñ~X2!z/f~ˆQXÀî/„R3b ¬¶®ÿ` j¨@íx@¬„ {" Y«.5  ªzJ€ôj€0 rjß“b¸­ š ƒtâí0Fð‘¤ùÔ£¢¸EM¤– @$9]H$ÞTøµ(¢o†c“d HV'Бè!Éà€(*oScA(k -t@Š|K@ÇN4Lô€<¹--ã c€“äÃ¥Q@ÆêP&P%E Èc—ÂäbtË ŠU&P2EyJ–€é%0Qè›#PáŒ&&Î/ÍH…T‹Ü-—`ùPn­ƒ÷²$̈ÿ/Ö¢ WðKç@[Yª¤ÎrF§³2$›è ZDu™ š$øTP¨õ³›ïciö%m‰`;£bA7Q@¼ys˜˜ÍYT{Zµ3æ<'}H-‚n N»O+G¨&•%P¨&6#6͇“€ÈcT'0uá¾4ÑÏDEŒ¨íÎÊË.˜ DéI÷·Xðµq,L Ô€õe+ B ¬h®2xÚiˆe,t-OlŸ•ÛöH`Ÿ~’gh)Xê P8‚luŠÜÙÔ¥Z×Ú«ú63Y(wDv©¨ùS\'`š&€< œŽ–ÂiA ‹ÚŠ@…ÿ/r¨Ø$Îû!iTP€ˆ´ÍÎ{µ`i D”4“ôÉ’¶¸TIóV隀h& ”K'æ2ˆHÐMo¡eÄÑ)nCðÚ ÔùÙ9Vö!%P™•ì xSÀpù€¨µ×o ý­ˆ+\U.°Ã^š 7‚Biv^­–AOˆÐë^رÀ䮎Û,P1?3¤n¬¦y‚]²W“&x/ßâÛXúŠ ÈŸÑâ  (¬P&òM=[‚8@`ÝYã̾»ï›þa?OWáÈÖÖn™ŠËR䳟#ÎóLü¯Ûsµ ´3WY÷NÔ’µ„€¢ñ(o¬]¸•›fÿ‘Ôô% ¯@À&0k¸Z ä2y¾¨ä—ð¬HЀ Èóâíj¹8M2ÇÖÌ"”Ü­f²áºÌ=^uûèg4ֳ͡²ÿ\oÒRª…”. d5Bè~ ¿1àì šši`6ZÇQ ñ&-TѲ¶±Gœñ b|‚NûóÓŒUé†;ó©V{ÝŒ5ô¹ëZÝa«À€@°5 b”(Û¢ùÁ îç/…|‚»q~ê>Å N„÷zÙ×C³ÝiIÄÂxÞ%°OIE}×¶Ø4è­¢»Ý@œõ6AªìªC®ˆ<2¨ ~(è"«Û:õ¥ÇYz-ùÆ{8?¹ÿý@.ãîoS"/AÉ¡Ës8ºç<À ð̰®ÚÛu ~(áËÜÛYß "Îq¤¿ü¸cOvÆçn>çÔÌ ðš§tî`ÀC ˜!€OP¨`ûŸr*ć]|ûíO"Å¡bMÒÕˆTW*²ؚ̉$æ½&§§{‡^qx w›Tì@¯@/zË €H¨aª × úð‚ÏìèY?ñ ψåþ2xøêk) â+Uq ÖOò39I‚6 Übˆ“&9tÒ' ˆÓýô0YÓm¦]wÙ”$rt~¸…g à]&'>è@;‚r…<Ø9/V=ÐC7†}ë7†oÐl9£73¡·\!w#ð‚e(`7RA6Ð00~÷qU"NÓr ø~ƒ5XD^Öaõ†Ó§tx•!@|Td$Ãö†c 7kè@$``ÚÄR®çd9…!#‰Í5ù¢#!·ÿ‡ ‡RS‰ð·-p:/uN ˆ¸—† æ.,Ð?ÐJAUq¼&w!÷6'‚`J‡/DȇH"ˆ÷Ò3 p4aÈU–F†ÜØÞøàŽâ8ŽäXŽæxŽè˜Žê¸ŽìØŽîøŽðò8ôXöxø˜ú¸üØþø9Yy™ ¹ Ùù‘9‘Y‘y‘™‘¹‘Ù‘ù‘ ’"9’$Y’&y’(™’*¹’,Ù’.ù’0“29“4¹“RZÆrN8™)›¢°“”"@y,}4”ètAC‰.7 ”=™”:i”Bé”>”Ji”QC•ÿ²”;Ù”Cù”L•]‰”P9)Zi,\ù•=P–¥u–;é•[Y”Ly•I™•s –_©–fi—m —hÉxÉ“z‰“t)•Té–‚˜¥e˜kÉ—o)–wi”ly˜I”޹—“I)‘™˜•)™u¹™‹y™“‚˜9ɘ‡é™£y™U—¢I)?9˜h‰•¤¹˜¦™)Š™—³Y)«I”¨™™y¹›¹”s`7HÒ33 W"œÒ˜% ybjU".ËyybHR'È 3z47ÑSqÚyˆ2åÑœÚ Ú™'a37Ç©ERœ’žÝ ày=á67ä97Xwìyî97Ä©WâœÕ)ÿñÉâIŸZžpžU²ŸUÒŸèé: õY%yÒ@Êü™z÷Ñ Š$Wb¡2¡HR Ïy ö™ þ‰¡ ª¡ ʢà ŸJ*£)¡# £Éé¢ ª£Ø™ŸåñŸã‰¢Šcj£E ¤V⣪¢ªžÊ‰ 8z$: & ZÞiYÚº¢]JDŠZSZUÊœP¦’äZÊ£ÆÉ¦^êcz¥5:§nÚžpJDú¦aZ$vª¦°C¤%ê{Ч}ú¥ ¨ÿd§4š£H:¨JÊ £…ªŸ:¤j¥óy¢‡ê¤/Ú©‘ºzª–©hª¨g*wj©ÿ  ¦PjªªŠª‚ª©²Ú©•¤yºž+*«°žFz¢½*Ÿ¡:©;:¬¹¥7Š©:¤Z“Îú¬Ð­Ò:­Þ˜*¬‰ØÊš>yNØš­?ù­Гßê“Þê“€7®àú“J©®àª­Wٮ䚭t™®>I®B”®ìJ®Üš­õê­Y9®ñÊ®?P¯ýÚ¯áÚGݪ­ û®è¯ëš¯üz°e° Û+ÖJ¯ã*”ðÚ­?©±¯ÿj¯ œ˱×zŠ2 ²&‹­âZ®éª±k¯k­«®Q‰®Þ:³.;²0Ë® {®×±˱8‹­:Y´¬‰²1*1[®ûS±A²B˯û“°ÿk±2k°;± k²0´ì*µVK°‹³ä:¯]k¯e›¶:˶­Yµf«¯ ¶' ·M»µc‹³óê°+—S«®!;²;P;˱G[¸xë¶ÛzAW[·«µ6˸>±ƒi²Û³%Û­ÿú·æZµ#Û¯ûڴ˵n»¶‹¶w˰PÛ¹L[°^+¹5»thЪOúžËz¤ŒÊ¬¯j¬ÍÊ· ¬vÊ»»ëª¶‹ "J¥³Š¦= ¼ïi¬¼ú»¬ê©=J»/ÚŠZªvz¼fz¬«Š«ÖÛ£Ï+¥Ú©½ʼz«KÚ©Ð[§Æ«»ÍK¼é»«ÊJ¾¸{¾òÛ¢èÛ¢íë¨ý‹¼ÿ½ ¶š¿1š»÷›¢Ü»¦\»ÚÿÛ½Ò‹Zê+©Þ;ÁÛɾö[%曢ËKÀꢣ Á¼¦œ'û£ÆŠ½õ›¬s£j ü©Ã›¨+\¤ã›¢L¬ØyÃÞ;ÂZÂ›Š¥1 Ãñ+ÃLÃ3 ©œÃIܤ<¼¨ ÄïI­R<ÅT\ÅV|ÅXœÅZ¼Å\ÜÅ^üÅ`Æb<Æd\Æf|ÆhœÆj¼ÆlÜÆnüÆpÇr<Çt\Çv|ÇxœÇz¼Ç|ÜÇ~üǀȂ<È„\Ȇ|ȈœÈŠLÅ×¶Èñè§s¸IßµX3=†\‰Î$ƒ@Œ8-R‡×h9³ÿ‡[§Gw fU_ÐȎ쎟" 9ŒHBjTÀ=¸¤šÑËÝñËœ2ÂV²Üeò±^G‹Ü±Ì]€°µœŽ ðÀØjxŸ–9P=)ÕÉ%E1’Ò'ƒpVÁÜ3Ó[Šýσ&Òs[öƒ²ÃZ b"i-6/c~nÝ `%·Ê(0Óò1¾ÈUCuAù±)×5À×RGÏà·"Þ<Øvµa }T¯Û^Ôôkµu#רs"h*—ošÕ"EØ-Nt7µ„XÐòEgMZG'gN‚}§­~Áü{q$Jƒ@E$ 2C ýKzíºMrôLpdßÿp:?£Œ5ÏE÷9CceÛÏ-†Ò4Ò–ËØýR?ÔQ?tßçÔI}wj$@^ÝQé­ÞåÁÚ)Ð:â'œŒ8ÜÓÆv³Ñ&Ó501„åÓ$°¹Ì*NE³Òâ8 ü¶xË,Š€Ò Ž~çö@þqÙ>`t'o?^4m£ G½ôáë—Ú¿À-kD}|ÕG£#<ÞpÛIù­LôŒ@¢´S â ð æ'x3~e´Ìa³#D~ÌÐ-àŸR°åX áZÝXLÎ%ueYaU—HË%°u¾GÓV>†_§Qäáð]34Ò¸mæeŽæ‚¸Þ[ãÑWé$@ßÿ6ÓX¤ä`Τà|ÎàÒt8°¥ƒÞÒIô+‡Èí7hrÍE$ž[ãí$3Mê“®Ò(7¦NE-÷é2pæÄ-ˆà´€&vîc GÜ6åTÉÀêàq0ÎëçFjâÚýà¸n[ÍR-xN+æt²(Þ&€á#pìÉN†Hm¦^Ø‘Fæ®K#Ö^[ó|×YP×/üUÝ#pÝ}¦È¾Ç& 3"m+¸ë•ÄsÜCXçèMüÞïê7Óï݉¸vÓÑ^ð—&àC ŸBø¦Fý/ÿþ ì. äw^0€ò›þجÎ!ßdÿ¼îjü6Ó'dú.”Íòy&<æÅ6P°F:ÏÿEÓ¤Þé3ÀsÆ%O*01O~1ÏÑ-ö÷ Ï">OŸdOÝ1‚âàBÅæÆññ˜­ëR_IQ§ß%]£mì[Ïõ"Fp€­ÃBv)zý’Ø­BFJNâ TD$%HTŒô€|bD$ D,0á˜Nxšm8\\L,4Ð@˜ H\œ>XÈR ¶šFÄ6¡¨àXÔ¢¬fU_¯`„a1d&P 8œ_N$¥j+³·;.d+‚e€•Œ¡‘8<ߺÁ!Q¡Z|ø!(@wBŒ(q"ÅŠ/b̨q#ÇŽ?‚ )r$É’&Oÿ¢L©r%Ë–._ÂŒ)s&Íš6oâÌ©s'Ïž> *t(Ñ¢F"Mªt)Ó¦NŸB*u*ÕªV¯bͪu+×®^¿‚ +v,Ù²fÏ¢M«v-Û¶nßÂ+w.ݺvïâÍ«w/ß¾~ÿ,x0á†#N¬x1ãÆŽCŽ,y2åÊ–¿‚‘fш(Å™ }¦däÞe·Hi €A,H%™€a€ú¸@!! ]ñ”¶Bâ,™Z%8 ÿÁ) dpÀ³}‰i#¢6°Àu¼ø€Ê©F€ƒŸñsÊ=8P€) Ð p: ôbÅ@Ó–p]«·’J¹æ*wJ¾’pß?"—@@›íÉqÊÒQq14Ó*þˆ dðå%^Ãn?¼[Ågâ@®pÝ%6 :Ì]cÄ’ìiªYÜÈJ²&謰(8¸‚NSÁé xNY_ ¦àØÑzº±@ðÉhE7O©S˜GÀÐ Àõ‰½š)›:œ‚BÄ „&dFÍ §€k@ÍB(7¾ ö i“™,h ¬ó^ ÷åW€èLÿÁ>gŸëpÖ· CaDΛ£@õÈ™°sZ¨Æ9à)îᡦ ƒålŒ±JÜ·7EFsŸwù†(Æ—yýU  é‚ÔGµñ€€±ÏWÒuV—`k Ô$ÐkÛVD‹ )–N \ÀÜ Ù, ööàK“Ù˜H„9™! CÀD6˜º}ëo`@j¨G‹ÜW‰«G4Ñ€¾µêFà3`Ò‚¸DПŒµ=xôÏ%ì@¾ 9õ €·Öw¦&ø¨ëF3 ÀèUPC ¢AÚ„7¶+(ÈÀHb!ðð3)Nòÿ„êÓ€‚L`àóZ`?èÂqÕë ƒP Ç☯t~»@¿Ò=+ ê#dá#5|‚뢎-í 4@àPp0hp‚å(Á¿ A Ùñd)E}^€öpk%Ð* ¸Á)•@  ¿ˆ·‚úȇú FV¡€$lˆ€†šPÇ­€Ð+“ Ô) †F×äSMLuªÁ@ÔÓ-1½n`–æjAÆLJË©q`ÎRa ¤Ù±J@¾ÒœRéòÚkjŒVƒ¸S¡øÓÚQ³š»}3úÞ0,…0Þƒ ÈšïJ:õ›jŸë•…ÔW 4PPF² £–ì X@+7¨Wà><æˆü~l¿)|éy½U8!Ú=/´-¸ ±È\ðWÁ 62»ñÍ÷Kö!ùºû8¥ÔHõ&l`äìt- $ôÖkx¯¯ÌíƒÁWD€^~÷›Êgÿ8ØÃásÔ° ÐÆ`IšŸ` Ц›8¨+Z R/P8ÂFžóÎy§– ž‚ Lc“fô &}M"&æ¾vn ê C¡”¼Î:/|ç´bÁXpÐðA¾¼ ó>_•TñxŸœ†SBh·Aƒb4^gZÊî"qŒMŽ{¢öô&¿ç\MGe=^m r,8â ª×Yu‚µÌ`‚› ^ÍvçÃi*Ôš ɘ®YL[)ĹŒÔµ[÷fDPtJJM% MP3û€Ú¥C8B;„pÖNxiX«×9Ût*ÇÂ÷xZÀ/O¥,L¾P¤Z4ÿ²Ð*`ò<Ù Ç7Thóžuˆ¯%%R¿¿à'a}Iµ!Çã¡(ËòoOý"çd ÌZ€Ô¸YõÒr:¬Þï¢Õ2+{]Lh¢¡¤Ö(îJlÍ”;,ï…mh_Ç~'<¹í$‹aÒ?ä t±eŽ‘ØÏKd• nô¼©•þÜ=Þš/îuÓú”ZɃqþñNͦzS(àŒ'!€ŒëekL‹ TIG&Й¯p¸¨qÃõQ–Í•  #c=r§!qáÑÂÜ9;P‰GšOÁ½{ ë ìHGêEÆú —/éo'XwJ/NвÌÿ ¼‹%ðBâùÀË0L ™Ðã¹K}Ô˜$€xS,ÅÎuÞ™‹ÞÁ RÎÇÎÙ“jø,™< €-À}4ÄØ_=àë%`ÍM²Øñ‰A’åQ­ÑìTØ´ï E½uÕã‘ÀñlÁ©Õ×Ô@0 ËîMA‘A‘™Àᨆ ÈGÈ Œ!Œ_èñ9L ¬—ÄЂ ApÁœNaàN $adÞÜÇÆÔ}äMì àŒáС < ñEà”¡)@åXáä½êΊåFðL˜Ž ŽÚá5Ó™,Ç}Ù^½€Ì &æÿá!Æy‹ÀO4Xa“‰Ró Àó¡ ÈJ…%À|É&dZ 0ή€,€®„C}1]!äÂ.ôBw 1Cày3 ¤õ@BÁG5L5¾Â7Ä8\JC:¨‚aì! Ý2tȃÍT Ã.Pº¢+5R¼#k$"X,„õÀ–j<@<²B—íŒá€/ÃàŒµìJÅTÎÊ)}LÈ|B’ @@¡áÃ;žD$×IQ©>ÖL͇¾¤Ë䑸LÁ¸$ô¬Íl0eQeapØQ*åR2eS–DR:eTJåTR%;ÀÿƒèUeVjåVr%½aeW‚eXŠeSBåXšåY¢eMdÑ,&ÁåDfXNÞ´eþMÄ)´¥ßäMZêå^òe_úå_f` æ`faæa"fb*æb2fc:æcBfdJædRfeZæebffjæfº„ÍU ’DnA(p&Ä1ÀXK&QoÔ‚/YÀC&À£0qY?ÊFŽEp|cÇ]äi¦f~­G-Pamœ&nä—6€@10ož‡¶PgºÄü¤Rp IÌ™˜p[iFAŠ£D|x°Ԁ ‚ç p£Q¤'-^Az'A, |*%‚n²ƒhjÖ³­„~.Åz„ÿæ®ædyçwÒ‹ЈìÔÙÓL€<‰Šˆâ„¢ˆl'QÜ Üóœ¨ ÎTòñ_¤xI…ŠèQ6 ðEÉCMÄ—à'{ÑeIø'¨HÔèÿh Ê! KB$'@G=ˆçÅÚ DÛÝÛ§LL%@梵)CŽö@ª±„•€ŽD†FPwîh@i!ÄJ²yé*ñ'hÛ®l@ð ÃtDà ËÃyÁ˜:Aƒöžâ-GÆ&t.†!6ðã)LÀ‹8ÛoP‘I¢¤t&‚šUØP9£®È¦à nØ*àPkÚ 0§@T8H@Œ Yÿê1öA&@rÈ‚¬U€8jŽqiC*§®ð³d*¢–OÉKnÌô’€CÌÄ)¨Ìn`êôCÍk*M‰Ô9çeò©  Þ8ÝESH¶‚ч-ÞG²C·† dëíåèºú!€iÜdä**¤F øÆ¨ìiù«s”aj 9r`÷AƒjbÃz­¢ ¨*Æ8¢Ì¤Ãç<–s!ÞÇ9„ð¸€!…g¼G³m¬ßì¢ $žÉðKØ ŽHÙ‡’EÄâ €,!¢ª²˜â€Úîè"¦U‚¢O‘¦°¨Êµb«Âb³@*6¤Øÿê™6w!5h€ût€¹*C“ÑìAº:í PÃPõZÙši뙽^Ñb$S#ÜÈ0A0€èÕè÷Ý@ ¦©¬§œ),F9œ‡}Ÿ Øí—LˆèB´Æq^Ž^Ç®3­˜ME(u¢¡Ú.Óz.q"îAdGßð 9†¬‘ ôHáͬX@´•Àâ,nãV%ÁÆìR¸€¬~U©€¨ÖíÕÕÎì KTÒ6@W1mÓ6©{™|+Œ'^Öf‹‰"á+_mÜj. l«¸ëÚæ Ûm€dÀÚ"ÐIA%­G²¨ÀÈ–€.]n\ùÿÁpÞ.¢˜UNãÉ¥ï Îßîó~Âö¯ÏQa/ÕÆ‰¬!áÞqc®N_np3¢Ôœ1ØlBý}°€â€ µ jðî@m܈ò„)ù†/”)N-ÙòÙ•:ö^UD?Ýô°ï”/ÉÁÊò"ŠÒ'(èð \‡ûlŽo¢µ€A"Ä 8N!©¬ ›.Øo¹õ@jõ¢¸—?rÖËg.$'˜LÄÚãE×êNÌ1‡¢§”¥`í å%:sÜ ×c˜ñ”ÕЕR­øîè…«ZÙÑë†\É]ñ/ø2° ÙÒò™áÿ™`¡kx-^ìÕ!7hÀ ßÔ(èi܃ܘüh ?@dÍAjú޽¯ ‹/ ךƒä$¬Ç/GÖc‰ —£'|‰'ÈÚöèRù€i%@Àõ½Àsè.ÆFÖu¤]à2)?ϯÂ@+…óë1ξ9ò Gv]S(ð È,d&ÿØê€WGˆW sknÔS<²×±m¡¼@L«aŒëW‰ØÇ1LΤ*‚ûjR@Ía-´ÔFA^7¦³~Ñë°UCkHóì”@5“€¬žrñ1p_ÍàAàs ÃnÁ9û€h¾ >øÆÊÌ.´I¿žå\@óbæBCÿAÜ6‹;AMW B®š ™’µò$àâÉy[-r$›2–eR;—íïE\ér#0Øgki´€rt"ÀÄ€1eMõN¢³1ÀI〖©è)¿të C"ö+n3> ñ”„Ý5<6S÷€uœõòTböF@9QôŽJ5½ g%ÄÑÑ1ä`©°\r&«YD·Êm‹©æŽOËѳLš-ßN}´_4ÀÜBµ 8#é¶`§ôƒÒ©åVhßžÕ†1#óœ=ö°5òb×—tÁ>ãYjKvd»Ò8[íàv473%ó¹3uƒÂ €‚<{çi;A}°Ü$NÿèwöXSç}èfy„½‹}+´ÚRõY?­%Ò€ôýVaÈI#;™`W1ËŒŒÚv(òÙ6 ­6d·#„¸ÏÆtw—¬‘s—p¹(ظMȈ?Ýp[A!û"„eœáíŽûÖîØWKfùÚªÖTŽ5ƒÅ!>d¶…A²ê†`B†¢PS’V“’ž0Üñ6‡Láw‡Ù B·ÐFÝ=„£Qoƒ…¢ü&A²Ä =xyü77üޤp J¹è¯pé°NŠ·<9‘¼Ý_ñ¹¬wSóp¹ÁçïJ?1góÕ¬ôíjÃä(÷”Pxæª2½ÿ³kíSך Ëu,úfZIÛ鈤‘D¦Ê$Ópð!+C\T_…Q À´r_OD熟àïè5 ᬷùÙÅú¡P{ÈZ áÃüÙa Z_\÷… >I•7\€ >Q}÷L ÉÞjM²¼®À³oTÀh%¤ÆøÝ@©˜ù4®pÞHÀÁD®á ŽÈH[ØûÁÒû<@¿Ç iHzc[ó ®™•¤ÛÑ$wOËî ü´”l0Ð\YAÇ»QÕÝîCÞìÿ ¼° +«§‚[æBÖÀÕ:¦’|ßUC~°& ¬·ùÍxáa/âœÿ»2´§ .0¦Vƒ1Þt×BÒãt ÛÁæN+ F¶s#ØG%"\m‰ÌS^\lÛïÃ7v(³‚Ñ:LP­Ñ>!*p¢Ææk¾) ´”Ãk®л¹-à[|w~I‹{‚dÕð¸y©FPN^n~Ž®Œ¾ÎÞîþ/?O¯»]Ÿ¯¿Ïßïÿ0 Q’˜08ÀÀ… :|1¢Ä‰+Z¼ˆ1£Æ;zü2¤È‘$Kÿš<‰2¥Ê•,[º| 3¦Ì™4kÚ¼‰3§Î<{úü 4¨Ð¡D‹Ê«@‚ÑaL8UX¬—Vq–kÀ`”™8ýÚ(°NÛ0€aB’1wöåÙá€KŒÈöx³ÁT ¨å¡­ÕP\Ha]†d!)¶Æ§!2!ÁSa $dÈP™Ô.¬ô&Öô+ L ìˆ ÖµÙvdÑ—ú냹•ê’å­©é³:MxÔ» *Ç -)²ÒkЫ]ž:âÀæb@ö“ê‚ÙÉ9H@À‹Õ—Z@  ‚ùÀŒÅ0þ|±(0@€€`–4ÿ „4@@Wó=¸Ø ¨1ÜŒLP†0AyžDÀx Ô÷\Þ¹YØTGÍe d@BªhLwËlAÚ*&ç!0H±g‰{Αpß#ÿ¥`` â3Ö$ á$ŒÜ 0P!_?’À%ŽAjâ@}©ai ŒH÷¢˜Ö 2ÀXwhÆ‚›Ãè(v«¨9&/CveB•/Œõd%[LG [¡"|1ƒ顸 Ð hJr¥$ˆ` ™—eÖe$pšÁ¡ HD86 ˜Ò×_øG‚¢®½‡H`›£±)MIIB aÑÄ1¨#èÿêÚc¤•D@ŽÀ#̰°À‰iÚ]¶â XFÀÀª<€€3ÐëD ,pØ~4ç `¢¤ë@@ ·­²W+ÉhG$ðë^hE± Û:FTÜxHÖpä|ÁÁ*TçU"p9Àc„eÕŸ¬Ú¥"$©³3#:‰¢.Žìè"QLà0¡Bµ–0ÒFÏ#@¡ÀÒ$„JÌR¿p* MÁF‚–' ­'P––ÒäØ&$àµn›AžIPen4 ÐAC§ ]—¾qÐ ,L‘¼³:QSŒ2 ÄÚ‹°êg&lðÀÜUÐx8­Â63ÿu8 »Qgx–œ®HY*$ Ôe‡JûêQ Šz'D±Û ãqœæÅ6°… {ti@â&,^‰TŸ ŸBAšw xð&ô@…,4wºõ&lÊr #ŒåÈMÅ<˜Íí™pc{Ev\[‹°aè“hÇüÎN’Y† U²]„)õ–hÔ9Eó–ß¼d'HCh€†`ºItm\Û!®7, :ÁZ)f†¯ ž¡ |â (àÔhÙ1ÁßÜ0º³œ8™r€`!ƒ BÌÒ€ +z$Á†"ƒ?Ä«szsÒˆ pû•€+oè[)q*-ÿU-³jÝ#–³ -‡yRqQ¨”Ò¤¹\d` nH‚ß…wh@C»2©0†ø¡¢È€!ZB*¯‰âÌÐg!·S ¡—‘Z£Âfü)LŽÐŽ;% @> x&7F·ÛXMðrÊ꩞ʓ˜Ç²Êe¼é‰ I“” ]Ž¥bNc@[ €_›¤ð’®{±å€ðø†ŽT‡¦äV®êÑÄSU’…ë#ºö+m1]/J/ï!Á-ýS´º0Õ:=>‚È|§dÛD¡FB*ñÔN6§™*óíðqèg/ÁZÂ&K|–| R.pÏ¢´’M¢ÞÆÂ«&l–ÿPT< uÍÍ1`~~âJ 6X•ß}¬ËA¨@Ø®‚ÚÚ´IžãA¨´À.õZ€ˆ¶ÖBM¥€yõœæÒÃBš r•û «HÛ²ßò`EvUD©š¦‹®‰ípftƒåb ì·´e€—Yff–˨`@_jGà,Í™ ©Œ@,“ì`¹mEÂ)ð,ªæ›°Æ9¥¤®ìÊe‚ø 2Ž*ìÔ²{>“´¬T+'à÷ˆ–µ˜3‹@r#™ëîªNIÌ—{ñËçv´»4!QuØ Ô4–5§ô•1ðx&¯sr)0åFX@g-,U‹¸IZ.¹ó:²±¯ÿlÝР¡•“Žýb-º¦2Ìù»2Áá¤RbÒ¢øƒóÀrlüb¾ 豕“À€’Zi†iW–ílAËF& n`‘g¦dgÓ@Àª/ÐàW Ä½š œ›œår"ÍoH© ¢”ß.ê-—c>ËìÉa´ªÔÕÄX‘’Ô±ž³¾#°¶ÕÚA ÀÈ\­gRÞ‚˜róù÷@EQúîDp0Ø|¡Ê6>*é#©[¹Ø  ElÔvTð õ‰I›;œš£+‚!‹›ÔUÒÙÊ™ð.E €<ˆÐ—7‰»•CÜ}É‚¿e‹ Ê*è[Îÿ<io‚ÚnØeêpmûæŽR ‚Ý uçÌŽ,]󤼱T[Hª©ÔâáB=i€É{ ?~ï€I@`S„uÿ`c›aI´°ÂgZÙlQçdœ®sí8ÇE òD¤`C[À‹Îí¤:·ÑåÄ´³©ÝZ·D^,lÛ ÊnSóPÍ_uB%(8­±ò\pXIôÛñUøÑ‹Äo–Rv_Ú§¸K¬'Á€6*ÿÏçgZ2væç m¤fèÅNPEdç³5_"O×Ó7y~¶€/Ólät†TyÊÅrN°WL…"MR(”"6‚q>{VK!—||C3Ãp{"@%%Yçya}!Ô%u¢—êdD—eØ·Z2QG >¶b•TtæENâç5ÀWo`…F6>N¢%½¤„#ˆwá/ WM3ütg$@qP …æc…ç×ò·P*hg¼B#j§~ç(»÷˧[~–i^0_(o‹$T›G?eÓ$6²òRB73ËT -#a’T„÷x§%ås†Kñ »÷ (rhjÿ UUciÐ 00"õRVö&!R$’ö² $@d0vô@ÄÐ$AdŒ/¸P¥f`âuaYZ×$í¥B2HDpr@k@ÛuŒPp11 ±‹ñQ +Ô7Þ13@)ÉC3ô^ô<  ZMòeÐ C|EôH4>×:óDwÐ7ÅZýøô„NÝãŒu¸zË‘‚hq$Ƈ"0jéÜ`ŒLeUÎÁ)¤ /~@G9SX“dŒˆM9 !ð“!j1OÓâi‹ØCi©gv‘Ð’Qô’~¶ÛåGQ!ÿçÓ(Ä|¶+J–Š/à_‘Yã0$Œ»Bd“°| K$ÀH5à´„d—)àd6vcDI`1s—0kk“vŵ6QÀ=:Ñd_±”ŸpBÆŒ—¡°u3l %yÕ7x):ù&Y‡9BF|™9Á5”s9£™d/°†é”‘54z•@‡‹w5¾!d!‰&F’‘§;±3—0°jy[‡Çóƒ£D`<Ûá™GãÃ9 R!6Å1wÀy4umCØÓ%aro/ç–€œ0p›ñ’4†„= 0 Lå¯tL*pFf"'¡P‡Qÿå¨mI’h  þÒØåàjW„Á#?8Är"ô,kA ×:ײ!j™Ààb_s5@Bif v„¶æ¶`±e³v7c‘W]éš-Ç‘Á\âAg ²tUŸ#Ò"Ä>¼!À>ª~&ߨÂV<·oe e ƒÞ£•W ó¦n`…Zþ é ÚaÅ5\©ç¨DÁ žÒ…!£E-êR$@0 ßhBç‘ áOøÔ’pâ0Ü5:âZÌæè‰ÿ—W YO-Y²íQcA = ø¦çw‚àyDepé‰>Ì}S2D^×QžÚÁ°äö@ ">`ÛÍ”nAËA–•ÐÝœ]l•µð'ß^€ŒßÓÄ^eò^­$Pžæ0KZ~.ŸðæÊ÷¥UDaH”Î ýõ_¼ÅP”Fæ{ „ S–.³–ŽÃ>ÐL»»n ±MÖbZ¢"‚éwÎlW* 2_ÃíØ›Mâl)ñºË±DƬðQe+3N c‘·¥^AÒ}SNëH‹Ró¾A.ŽG¦Žz‡"Ëï* Ž˜™Éo@›>ÛbVuYûJ- ©ÜIÿïqöƒÄ¦½‰HÆ1,›îîOHêFÃîœh_‘Ê'ýs#Ÿu6âÑ·› Îñ5 áŠAÚA]ÆÈ!­F-6ö¨oéÞÉt&daìMÃ]ì<ä…³£P£ÚP«àrð=4². À&݇”6ùn†&}eO)í³DŽPŸ‘¿å«ˆ ­âÞA>“zÔ.âk‰ «b 8þÊCè®,íùd‘ìnUzMj§€-dUþù¶ ü6e¾ÿdÞöÔóµÐé¿OèÒ×8OMðÁ?÷ž#–ý(@$­ù2ý¶@nøŠ?ønPà”m¿M ¨ÿÚñzØÀ QÀˆ@§hË3]ÏEÀ‰ dG€`›Q˜á$`‘ J'B.Fò±xT 33C ÅÖ\)ÅÉ5¦6<.‡WºóXñÍⲆ†’Ÿßœ‹ÞIDMƒCÓÑ]¤¤ B ÙI†Ñ]ž N˜ ÆË‰ƒ]L“×KÝZIÄä,m­í-n ÎFC®\ÃB ªL३K0Œ/s™%ß• T¦ŠMåµÍETó1•DÐNW/KÒ °0MÑÂŒ™63TŸŒêWÀçP¶y Ô)È4@™79ºÅ6MN¨‡4®¼cÑà™:XL©¡ X€a{RÿäÛ7c ‹lhDZÅæP˜"긌DÓßf °NÏBrêÈb±!À"<é+A€€'œÚ è9M6HìËfŒÐ~É®áƒÓ)Ú´jã‰ðsí“c@5Æ‚¢.Qpgq“j£A’  V˜Q' ΦÄXêF™)üŠÀ  NSñ Û€27F¨Ï,ú&lÕ >%áˆí$ˆã@Ë'p,Û;›! –5n¤=P"‹èh‡hÙV?€Á™^Ḩm›MH®¼ªˆܼãØ-}Æ•‘ øÉ'i ™¯ß·óÍ·³ ˜Ï)/u éÀXO"ÿ  EÌ÷K à@… fÑ7!…¾„rP×!77æ€+" Єu£Pjºð—V0ˆÅpV(™±—áwÈÉ ÓÙ•€<˜" ¬xYÒaz,ˆóZx®y@rÑÐ"Œ±a%J1dCc `°FÒ Pô@Tq?#º±Å‰Ož dqh4ƒnwP%å‹£t‘a('8Œm¨e \~h’ ²PÏ[W”8  ¤„Xa XêB{–2Æ" ua‚P Àe6@^P@ €€$DÉøKð- Á% 4A¥Ø4Aº"EC 5I×Ä&4À7í…—@«ÿÒ‚ôt@ ᜙L°=M@x ˜‹^½ª»îâ `€¥ñ*`%.Pˆ¶Ž±ÅVªI¸ú¨ÄÍPlZƒ]åC#“ΘHÄpŽjÔ€¥|À;¯EñB%˜¥3€d° œ½Ì”3Fô²Nœ‰`/¾ÛÚuB”O*ÃL,¢@X •›9!JCkÿ¼ ›H üÚ‹ ¥ \œ'˜,Éœ2ÔyǶ ‚=&ù†Ä¼–9Ú½áÙ<Ò6|=å§.ЄOÀ0öKó$»"ăâ8žÀ©:®b1€‡"aìhˆ'> HX<Š­VÿU ýnCOˆ‹~2å,Y^,­~—¡XnëÐ!žÀRãb¡ß ::ðòýúÒ¹<ú°[ÁdXz„Bð¶$ǰµS Ï·Kjöhžé„¾Ãöú¤™¯®_ÁC`ÏÂ#Ŧ`þ Û~ž õx<´S2• 0ŠS7ººÔ•… ÂÛç"°óx‰ (à˜À \¢k'09RÐ,„Ü#YÁûæ°ëÝmKêßzd€@À0ülÀáÀäÉ$ ˆ@(ˆ  y]è‰~Q,¾õÇx@xU¸Ã­î€úÍ ´5$€7›™ÿV¶p l‘‹ À , â°Æx à WðRC€ ŠxL¡t0PÆ @€F À ’;ÒË £"W»˜‘UEQ°Å«ˆ-žìÕðVwÂZXA‘(²$0< t,€ª#²X€,Í9€ `à y”Æ®x³…tÊq–›Ô WÇ¥‘¹¯%S6PÉHéò…Ñ_ð¨hà”ty] $·Gꤗ°r(© |1 ê‘׆hp>P8¸9A  ÊxÑýaœ n ~h”¯ ëxG-a`ŽÈ@äpøÁµ ”Ÿó& ,ÿðΟåd”på$¯èh eŒ@'ÿ`R,Xñ“.})Lc*Ó™Ò´¦6½)NsJÓ`ÐN§>ý)Pƒ*Ô¡µ¨F=*R“ªT9\A’K}*T£*Õ©RµªV½*V³j¬ÄãÓ*XÃ*Ö±’µ¬f=+ZŸº¤ ¸ê]i}+\ã*×¹Òµ®v5«ÒIG^þî®~ý+`+جò!z]8lH…cX݃½Ž =î ®‘­!bI4Udv‰•},hC+ÚÑ’¶´¦=-jS«ÚÕ²¶µ®}-lc+ÛÙÒ¶¶¶½-ns«ÛÝò¶·¾ý-pƒ+Üá·¸Æ=.r“«Üå2·¹Î}.t£+ÝÿéR·ºÖ­®,ï,háºÞE«#éø§²a»àüÔÀô¢lQ^|ëvø8)ÆAvà”Y¢ô5Šj’÷»vrŠRö‘  oá²;‡ÿe Ÿ½ƒàXÿR8¦öÅBÒj`ÞÕ­Xøƒ1ÞÕn^];] _œ˜‡–D-G¿³âã“uxðêÐ][äÅ>žéµ²µ-4Ò@^ò*BKŸ"õž 0ŠÖW¬þ+XMÈp|)xÂ#ÛµKÕFäÏ  X€ªâˆ¬´ÖØ“ ¶IpÑc2ÓÙ“\IËlq§/6 ¨CEÑǬâXLœe‹+ ÿ8¶³Ë!&Î:“î,B«j>ùæ;lzs¦4¨Õ¥#€¥u¸O<ГÜäC¨–C ðÆõJS'¨Âcá>fðÐbKÊÃÀ¨•£¯R™äà¨ö¹È¸5÷Ê2A€I¹Id"U …eFu‰R+ [L°*šN>^€N'Gãû9s—P=Q–oO¡Q>Š&10¸ÑÅvêx Øc93ÄpFîß|L@¦ê…O¢Õ¶ô,u¬¦¬šQêÔ.ƒ¥ìfÖSi+ õÒ``!IžC0ªõÁö»âï¯òŒqÊn—1tnÝrÙÃÚ0&O ¹µ2ùˆKÿ–±NG,àwÌà%€¨Ò!/r\ÐÀα€kž<® Ó‹ŠyÎ$VĹE º[E´ÁP9;ÏÓÎð¹×"®X•S _Ë +pye´/aÿKÁ¸Ç[¬/.á/µ]ÀÈŠÏ*’tA@‚Œ¢àLO+¶Ì/yE™æÂ-ULΖ¶mÈÎ@¨>ר«ÁÒx¦+ï…|'=’ø —2#”¡h{º÷ç0¬Š%fÍÔ”3°*L XJá/sµ†|Î*+BóévÿûŸÛ:ÝÓ_ƒ¯ÛÎWˆ7Êóè|ðžH‹ÐÀŽ9p<‰ÿ€;ØÔª‘”l)¥c Æ}Ûä)™\ÁÉEˆ±)„uë1ÃÃ4Yİ€5dèIø¥DÐL˜kL›É€8ˆSÐ\ÁšN4ÆÕ¯ˆÃÒôÛð à—=!ɪŸ'€Ä;xB-„  lQ!ØŸ®eÐ ìŸôŸ’¸X(t€Me‡íhÁ™ÔO( C°%a ¼ÃBpáfMà̱€¤L×àÄDD _p”‰ -Jø¼IaÏÅŸ­`  C—pÙâXá$Hm$b‡D’å±ÀRªœ'¤|] düŘG%Œ êZVH,²A¬ý‹!΀Á”ý‰Gñ_6Ê \–Ý]¸4¸¡èi$€9)WŸ™c3$A&Œ’­‚ëГh¬˜t$Ð7:ɲã[¢$è—‚©Ïëœæ=MÿÚøäT$VŽG%42MâÁÂ!:B  ¡àÆå¡¬¡dj,€+ÍÏ3R èGÎ $G˜„æ­$Z2ÆÀ2R‚ ë$—.nŸ7â7øá˜ØN8š% ¥ÓD€1Ä€0P<°I£Ø‚~Uâ ì!D¥ÏeâTåM"XV¦&6RNEÒ`$Z%=ù@(`±Å?åB6Â#Œœ~‘å$÷ÑSò´Ä‹¼cJ‹ LÚÀGWð ú-Ú5VãMŠ)D¢qÖ€Èe‘~…QJäè×)B¢-|ågÆ£^ÖÀ=†I±iŠ’©¦|–%p¼å ¼ z'28œäÔÿàX l,¤â$ðèÚTd'D¤§S®NR[m~IàD 6P„WLÀ 2CÖçMîÆâ@>Üï4MÞ¡%áiØ=)òmf-0bºèèš?äÇ ‰:4Á˜‘~õ(v ÔÓ€<…×…Øg- ôI_x†êŒ %œÅvÊÀeRŸ‰ò ®$W®¨-„á±Èb‰²¡–È{0M aÄN{Ú ¡’鎒Y˜ ™ò˜è™¦' t¤»€Š¨0ê€4¬¤Æ&Ù ¼äsì LUÙ¨ªÿåc2PDf(}ŠeT™—ÎA&H¦r€¸äF¹œ àØnû €‘Eç$$Á¬ž"ºžŸÌ^x©…œB&l¼žnþ Ý\£Q ìI™žîݯÌôUÊŒF%Ç< H†ˆ,@ † Ì÷ €º*»ŽY£‚Z‹ÁdÍ\©ze…å˜iç¤éühްöJé(,±Làhb6¬X¾N‚í´dr~ÈüôަÒV9"N)ÞÂÎ…\¢fÂÙ A Ýâ!N´öÕÀñS8Ä,EÐìô0] ±h™¶¤×m_Ø-]ÒI±$@³‚eÂbj( ˆ0ÏÛ=ÊÞkA†ÿW‘—íd™ÆAG{qÑ{Í‚ yÉ‘xùë'ÅWa‹vB¬Q¬‘fŸµð-0 €›%1c&mJu¬ÇÒ“Aõ4 DQÛêu­=~cò¥”ˆj‡­‚m]"ØmÔ=ì‘}ÑÕáB+AR,&Ù 8ë hÎΟ`ö®0`V$œnˆ*ÔÆ®ìÎîºTíÞ.îæ®îÖ€íî®ïþ.ðÎçBað¯ño /ò./ó6¯w]ñ:¯ôN/õV¯õ^/öf¯ön/÷v¯÷~/ø†¯øŽ/ù–¯ùž/ú¦¯ú®/û¶¯û¾/üƯüÎ/ýÖ¯ýÞ/þæosIÿíxM¦:M@ÜŒX€â>TX ¾AEÚ.lUmïDÑ, “:%FMÅ!5ËFRB´H!e%€ ذ*XÅjê/üVl$4,âàט¥u]8‘ðU±0S8ðÛ®¢ÄØí°Òqc‚·$ßB•R¢pü>j¬ÆÁ¿Y@š¥’c\Ä|©J^¡Œ vªµìfY™ª°h‘=À0€´ÈN˜š­Ê4šÀÆ·ZØèÜ™qš¥1ˆà°T1¿¯–¶Å-F5‚ ÈŽPð§ø¨*VÙG”*é-ðñ(Äð ¡ž¸Â-݉®žˆãX­cïƒÆ)-p‚ÊƒŠŠ¥!ÓÀE¢ÿ¤¶PÒ.ÀB½”†‚ÂÙ(DøÔ&ɱ!B²)qn9[L@›CMÛh¦Ê>aÛX€¶µÑÉ €·MÓŒÛåžúÜBEsÎ*G5_80>8…Û=t€¾!nâMˆfrrµN܉Û"A¢R‚c¨óX8i `á ü_L*ßðòZ\&œ3DI^«_@29<"èùåJÖÉš­qµr3ìÐÐ?7ò„8ßã3¡ â$Ób,=¦€x£Ô)4ÑYòÕe&cØ¥¢±ÀÏbA:ÔAÖà@;£3qÙˆBžÎ‚èÓV²?‚¤#ÈÝúi8¸ÿØ»^B^ñ³Z@žrHžaþBÀ’œ0á´ñV'A- ièAHé5—AÏ$ìhí±†N² N\ÁÔÞHl ¸HË‘šï…ð•ªfƒ¶Ÿ›Ž„lÀò5ßóÙr±ÜQšØŽºªÍ pÁkUó´n±ß½ß°"ÎD/l*©Qq ØóSÛJ9ÓÔÂ;ø´$œØ9š– qì´#*4„È(uÙGL´Ÿˆ^&$¶8!6ºHŸš`QߎbrŠ À LÓð'Ã6'’À˜è ”àðŲgJÉB„¬;f>À«ˆÓØëYvœÊ$LyaèäÿÄ@×⨭v˜çTÔƒL;´YÏŸè‘Â~3×&Ć&b;⡇¦Ë ¤) ¾óƒ- õ!þ øv ¥ ̇*œ…f‹@&ø»J)Hly/'„"GãjÊí鵟 Œ¸*ƒøáùŸ‹Õâ-ÊT.ª/úç$luŸôU4Þƒ\€¹(€@@#_èMJ6 HgÛÖ“Ç5:F&XgHÀ6¶]ckNȶ:ˆ':Âh*¼´ž`¦xc@ž4˜CE@føù‹CBž¤ÇÄ-Ž• êù}DÒ }ÓÎ…m°Ku¤ÚB0LâÇÉdz}EtÇp³âðÿkóVFÛ·/ &ü 6QŸKègOJ2Ížeˆ'_QR²mŸõy g/@ÇHq…â€|zpÙvVt¥¿±í—çŵu,Fú=8Ç>^f$?Îu¾ˆ£ ¢Ž–(³Ÿ£¯k‰\Þ Waòª-¨ú ˜g&,¦z}z8öÐjŽšÛ)R’g-Üò%ƒ‹kF6B)˜@h7²qîš%KB\j 7$›>œigZ*éhñ'‘œo–§%ï‚•\œ ¤w¯ƒ¥ºq¸×s^…G£½ˆc,™Gb ¸m®OEwÊ$w{$ã÷%õ…HÆ7@›zœY%ÀñÂÿ×&K«$ ‘fhé7ÑN6ø6€N”/=³KÅoêÃGBÂbÂ%·^È‹ˆt[fõ3p°ÜI6à&Ïy¤Àáè:)jp&nÑŽ ”A–¥ðjCCtӇͤ V§ÈŸ'i£§½ànÑs0F/ÐaZE°b Lø…-¾Î^D@ë“¶AæŸôEô& j)Ãiº ‹µXÀoÒP­´ÂUÒt: ¸óeý[ÛT#QUÀX röf–ð‰…dä ¤bE_i—´R´Œ—@#, {ÁÌNt7èPñÊ[Î6(ºðMºjV¥cPÈÔú Í¯ ¤¹B³ÿ­8{ ±³¼,fÚªÙÐ)d¯¦ˆÙ˜¢·ínǵa]Èw½àUÔ–%-ÂI‹04‰\ µë­~Et;Qä LMçSÇ ¬ÆÊñ|W°éÊhÉžæ]кnÔAµ€3¦3¸bš"ÐÞ¢™·JVF{Áº¹cþ׿éIk#Ë:’ª½“/@xÂàýÚDnÎ S€ìtMõÁ¦F_-BÅ€k¤q¬»Ð¡ÆêAƒÌÒfá¹l/FrŽ-/x‰û7Æ_ ^˜y1bç šlD›_›3Dn*|hK#‹+LøÆ€æ¶ðC ’E ­¨Àÿ€×6^t&`v9à ò+Ø 0êXÈ*u eØÈëzÔ‚ÃçK``Ñ4  Èè5´A2æ:A ¦Q†@( N¨ªêéÌ+ ”Kh¬?,Uô–ƨfBöâg‡ÔxÛÛš3°C‡øp[ZˆžMn±Q >´v­$KãW.¨Æ6 Û­aƒâ¯˜Ý•yH’ÕEhÝ[B±+k”åÜΈ€…+­õâYY3” î ®²¹µî5^RìZœ–Ä×&‚÷â á¤/KQ°°®\î–KHO…!b+®ÌneÞµ8˪Ö"ZO¦å|é¢CÿÃÐg9uq'À‰ ð|68¨"ÀÖÊüY4W(  ©3jŸø[X>ÌÕº™¾yÂxª€q«õ~„©¢à ÊI*W¯mž]Î÷¾ûýM΃*Àï¿þðˆ‡ Ã'þñ<’†Kþò˜Ï<(?Ð °Ãñš½èGO"ÎoAÙ-éWÏúÖ»þõ°½ìgOûÚÛþö¸·HY­‘ûÞûþ÷WÙ½3€OüâŸoïÏüæ; *P~YŸOýêS_Ò߆õ·Ï}Í“+ì¢~÷ÇO~Äß ÂWAù×ÏþrŸß ÂW~ûçOÿ»:`±˜òî˜ôÿ×ÿÿ¸>ÛSYRAÙ7}˜€ h-òçW)d€}ÿ°€XxÒ^ó~e~hføl=—¡è x‚(X&3E‚cà ¨})ƒ2È%ðt~|Ë7ƒ<؃SR/öh‚>X„F¸$ Pù°P…ÇGø„Ph$äb j-(0…Z¸…;r~¿%.˜|\8†dH#¨üæ„e¸†l("ަR„}D؆tX‡"Yõ}pô¶/8vˆ‚Ø â¦1£ w…â7ˆŒØˆÂ)P ¬Rx9ø舘˜‰þÁ‚`8‡šø‰ øœjЦxŠ<°1Šr¸ˆ¨ØŠ®hÚB‰. ƒÃ÷жx‹î}a˜…¸Ø‹¾¨¥ø‹Â8ŒŒÄxŒÈˆ|e%}ÉØŒÉ!ù., b€ÿ„©íÿ–œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçÄ;ú ‡Ä¢ñˆL*—̦ó õzѪõŠÍj·Ü®÷ ƒ!GÙ'N«×ì¶û ËçVÞBÏë÷ü¾ÿ(¸00à1Å3¸ÈØèø)9YxØñp§8¹ÉÙéù *šR‰˜1šªºÊÚêúú5 k(k™qŠ «»ËÛëû lQ9l¸‘I†¬¼ÌÜìü<7\*»› ­½ÍÝM3]|ià]n~Žžnn[=®/?OÿÉnj6U¿ÏßïÿŸf–@|¸<ˆ0¡Â³PswLÓ‰+Z¼H¡Öƒ‡ÿÆ‘Ã2¤È‘õ¤…ë8%É•,[º\vïÖ»—4kÚ¼¹ ÜI qúü 4hZŠ4©Ò¥Kj& ÏǘZ½Š5«‹B´ 5àx!@D‰ZËš=‹VB-N5à:“6®Ü¹YK‰;J7¯Þ½5ír8u‡¯àÁ„+úu‡·°âÅŒçu;³±äÉ”ýaJT9³æÍæzrþ :40Ï¢K›>êmÔ¬[»~ ;¶ìÙ´kÛ¾;·îݼ{ûþ <¸ðáÄ‹?Ž<¹òåÌ›;=ºôéÔ«[¿Ž=»öíÜ»{ÿ>¼øñäË›?>½úõìÛ»?¾üùôëÛ¿?¿þýüûûÿÿ`€H`ˆ`‚ .È`ƒ>a„NHa…^ˆa†nÈa‡~bˆ"ŽHb‰&žˆbŠ*®Èb‹.¾cŒ2ÎHc6ÞˆcŽ:îÈc>þdBId‘F‰d’J.Éd“N> e”RNIe•V^‰e–ZnÉe—^~ f˜bŽIf™fž‰fšj®Éf›n¾ gœrÎIgvÞ‰gžzîÉgŸ~þ h ‚Jh¡†Šh¢Š.Êh£Ž> i¤’NJi¥–^Ši¦šnÊi§ž~ j¨¢ŽJj©¦žŠjªª®Êj«®¾ k¬²ÎJk­¶ÞŠk®ºîÊk¯¾þ l°ÂKl±Æ‹l²Êÿ.Ël³Î> m´ÒNKmµÖ^‹m¶ÚnËm·Þ~ n¸âŽKn¹æž‹nºê®Ën»î¾ o¼òÎKo½öÞ‹o¾úîËo¿þþ pÀLpÁŒp /ÌpÃ? qÄOLqÅ_ŒqÆoÌqÇ rÈ"LrÉ&ŸŒrÊ*¯ÌrË.¿ sÌ2ÏLsÍ6ߌsÎ:ïÌsÏ>ÿ tÐBMtÑFtÒJ/ÍtÓN? uÔROMuÕV_uÖZoÍu×^ vØbMvÙfŸvÚj¯ÍvÛn¿ wÜrÏMwÝvßwÞzïÍwß~ÿ xà‚NxᆎxâŠ/ÎxãŽ?yä’ONyå–ò_ŽyæšoÎyçžzè¢Nz馟ŽzꪯÎz뮿{ì²ÏN{í¶ßŽ{îºïÎ{ï¾ÿ|ðÂO|ñÆ|òÊ/Ï|óÎ?}ôÒOO}õÖ_}öÚoÏ}÷Þ~øâO~ùæŸ~úê¯Ï~ûî¿üòÏOýößþúïÏÿþÿÀ p€, ˆÀ*p l ÁJp‚¬ /ˆÁ jpƒì ?Šp„$,¡ OˆÂªp…,l¡ _ÃÊp†4¬¡ oˆÃêp‡<ì¡Ä qˆD,¢ˆÄ$*q‰Llb£ !ù,)  £ÈIi¸8ëʧÖBÖu_yÜšZ±YèZ°8Kµ}›«>=Œìȵƒ€¢¸(ŠÆ€$¹œ4Ϩ©d:¡*Ø´kýjÇUÉ5E{±`à†›¬ã5w^ëé%fA&   ‚F Œ9 ‰ I|9C ‡”1MlD„ƒ%Dx%+·gD¼;ab½m²¿<!ù,7  ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù,F   Ž$œ(*¤AéŽlœ¾¯lÓ®j£x¹Ç=Óo6B,µ!od ’©UôDj>sJ*Së“Ig„ÝD”]Éã$IK(älk;ïf«Îäw‡¿Úm_xuBw[~„J‚P1{ƒV‹C$\ˆ,’'X…# ›‰$ ' qS2.'ceƒ=€@Aª¢¹rµ8´¹q–¸¼rÁ³;{ǽ!!ù+,T W ÿ Ždižhª®fà¾pÌÎtm‹qß|Ïë‚WÐå+SºäqÉLê˜Ð¢3­ÞCgÐÊMeÝ0ê»›IÂ\6@’*€JdF†Å#A/8R &„ ˆ6d/m1 #.„/' /œ$¡.‘l#n ˜"«"š$. "$w§¬i1C“£6ÂÒ# š&Ž "š¼^­“7 $å'±¸“p4kS$±žT8 FXQ0B J(˜E+W"b}KkœC Æ‘  ’)WɱöêM ô0 r„%“'¸pfäâ¤d(–‘’WS… ë©æÉˆXûN”IâèÁó꩸ÄgK 'B‚p®(€nRžÅºÓD:uIÖüL‘034 (3m8Æ.Kàà‘ Zixá&ªÛ‚ô46+"á&M”H(éB {*û)iéØ-> 0  yµD >XÝ ÂÄq¼µ¸îŒïžÅL‘Ü 5'Å÷NÞ8ó*0D—ynK$ê\Vº!ù,œ  š Ždœhš–,©¾ÂÙÎoÌm«8k¿,Gàáû­JB¢Éˆb1&”b`‡¢Þz.¦ ;JYy¢BJ™ÕŽ ’Ìd(eÙ˪íMîj¯¤¤ï[£·m1,penH„vFHu":@‡Žwx#zq†yˆw"ik¥ ”'|GF¨ŠM\f²©´²^?µ¶š\•»*«–Xª½ÄZ!!ù ,«  © Ž$Aª®jéŽl|¦ï+ßµ{£l^Þ2Ÿ ØŠˆE㊧bŒGd Êrƒ< 0) €µ`UDT,Â0 €!講8r BªwHm$c)VAz †)qb(ƒ`# bcX”"–R’zœž 1Š“$¦˜™ª# —™O£«²®d¤¬K¨S›«(§RP­lT¸J½yÊÇÍÄÈË1ÅxDÔ‘!!ù,¹  ž Ždœhš–,©¾h+ðÜÒšÛ,ý¶ŒÇàTùT,Æip¹PŒ¸U©Àô¹#+0\'ÖÐk‡_`>;$ðSD’‘, Xmiü‹»}'YH{€e`[†.‚z$|‡~%‹#m,”dŒf›–GY™•x*ƒg$š)§ž«4®&§°<œ’µ¥Ž¸—¸ ´½¼½lf‰Ã/³¨»:>!!ù!,È  » Ž$œhš e;¢‚*»®ËÝâ¼^ò8Ÿi¾€*£™T2o9' 9B`&ƒ„Ä1džDÍi€‚½ÑI ‚4'.ýeœÚ#Ìz‰ƒ¢z%' s^1 % '‡h-d\h‰j—%d ‡~=‹$‘t9ƒm6=x"z|“jmo1r«`dµÆg'£)Uj[]^J’¯*~ÕÄR¼FÛÞ}3ÜÔã<7ÚÌ8!!ùd, › ÿ Ždižhª®lë¾p,Ïtmßx®ï|ïÿÀ pH,ȤrÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïq~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢}/£¦§¨©ª«¬­®¯°±²³´µ¡¥¶¹º»¼½¾¿ÀÁÂÃÄ«¸ÅÈÉÊËÌÍÎÏÐѪÇÒÕÖרÙÚÛÜÝŒÔÞáâãäåæçèŽàéìíîïðñò­ëóö÷øùúûìõüÿ H–¿‚*\Ȱ!Ÿƒ#JœH±"7ˆ3jÜȱc,ŒCŠI²¤"&Sÿª\É’"Ê–0cÊœ)ï%Í›8sê”fs§ÏŸ@ƒÒê)´¨Ñ£H1MÊ´©Ó§~–BJµªN©V³jÝ:+ׯ`Ã2ô*¶¬Ù³÷ð¨]˶­Û·pãÊK·®Ý»xóêÝË·¯ß¿€ L¸°áÈ+^̸±ãÇ#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°c¾€h`àƒd N<Ç€"  æÀXhÛÎaw‚ z9°úŠßÁ‹‹Oþ„ræ,°fo,&h¿¡|€w1 Þ¯`0Bùÿ§{ ŸîÍGÿÀ•‘`€FøŸÚ%0@Ρ^(ᇠ¾f¡,GClàÞTÐÀ¿%ðb b@Š 0‹.ŽÀÁn@À}#Xð€L°ÀŒ"€‡€9>@¤ Ê9] ?2wÀ;.Y‚{B© `aœ™\È!@…@ ‚<0ÀSVI¤ <°fpYfDF ä)à¨c˜p€‰_†Édˆ˜f:רé†]~;^Pè TÀqd©Am%(!¥î†ên÷9AŠn Á­(@‚¦žº[÷¨ã°Éa ì*{[’Ð¥AúGBÿ»N€·îJäo²9* Ê%`™@¾h ’È*K™ÇîÖ Pâ:,¯ø:¸jž ±žJæ—ªGµ@Z«é ¯…Á¡Bè‚zÌg@D>¬° N@ƒæŠÐ€\)«&<@Ú 2z8ÉîLs—Æ_´Ežš€m¸Ñz‚z Pbøª§^Y_8€ s73Þ5à€{ã’°ª›&€‡B§NÇ€{6úè3ÐÙðÝx×ñ°vÉæìÓ ¬Pߥ逻€2½\péÍÞXÕ¨2Ú.Hw¤¬Žßä&lˆÿ+— ­äîæø ’S¾ž—«0)Ìf{ˆ‚Ú&]öoè À‹ðyÞÄϘ/–¸õ Ï»‚¶ s-ô+nûN^B” 8]”ÓQXƒæ&üˆ j_‚è'hËA “FPB–e_Û¹“£ŠŸ‚r›°ø ¸+Áo4à¿'`RçAúŒÇÀŠ¡Dáùúb. 0Ào=+š&¥AíÆ‚$A~0—Ÿàê„Èöœ¾Î1g0 Ÿ¡þ%Ò¡ÎPË2ÁnÎÄ€Ý\*K&»“~¼'‚ÒKMBJà»®gÑp_X T¦¾=цÌ¢³ ÁOuÖ|7‚ÿ£y§:õ@W6FüVÒ ‡èÂ/Æ@†Ò2 °ºtfœßnÈXŸ8I;D€aå$8™PÕQâÞX'žàa´â ”C/Þp‹  ¥ 6ü$``j*C(¸€L 0™"U¢`P¯´N)¹ÃRˆÓYä ð(·N€ëÃÚ ™ºN)Ð_"©žD«\' $ãž(‚êÑ(7œ] )Êrš3èŠ#e 6¸¥­t @ Æ€¸‰‰XU¿‰È:ÂðÄA—Æ Îpò è% zA¿,?a€÷1N’ÂÃç6OÏ?RÿT}#è'ÏIÒ’æ ¡ò@Gzõp³# èæd‚B´ž¾¤c0íCž@œ{,h9÷Á/ýrÊ:±s;+ÁØ*Bz›à] @¶bŠÔ¤` + V*‚xþ³“Â*éTv¤µ}àô©@§*Ò§.ÐÖ?T–¦G™' ]JGP‘.5šv]¤¶$Æ5÷`ÚÚ§iZÝ1ΙìÈ)ÖÎz–£Ûfi@ Ìçm†3YgÚ öpß”@U–̈d8b?wzÖÈt }𶛤`iMäc›”ØÎÅ3dhJå…L` «© €ÿRm›PkÏßéq³Bý¬xÇ«2_¡ÔŠ‚¬kS1½Ú {›9€DàdD@°ò“.Ýó©½]æ 3àÞ*z|¯_üÎpí&‡E4'z\Ý«¶Ð4A–êû+ÐYÚÀ$°+&,^ó®‚ÇËbÏžW¥8­ d‰˜±&ˆç`çGcÚÜX xLVžêÝ©ën ƒ£Al“ßõ¤p‰J.5‡h‹pS—|×-!kÂ6Odt݇iê¼ÑrTßäŒÁÇ o‹çLg!¨ ¶uγž÷l„,­“Ï€´ g •mlЈN´¢÷eá .úѦÿ3é ÌEúҘδ¦7ÍéN{úÓ µ¨GMêR›úÔ¨NµªWÍêV»úհ޵¬gMëZÛúÖ¸ÎulŽó¦Lêú×À®ËyD0 `ûØq)¶D-ìf;Û úѳ§Mm7H»D¾®¶¶·ÍNaçTŸ·¨¸Mîr[añ Àîv»›Ý"{·¼g$oy‹ Þï~QðÍî}ß›ßý†U¿ñMo€ëkß/8Àãp#¼Þ ç·¾ q‚ ¼áÇEÀÂ/.qs{ {¶d¥8¾acNÉãØ›tŠ=À‹ãt]^&öpNæh2y/G•ëü=sÜè'3ºDÿMîs÷å‡Êöǧ^m%²/X9Äž®ó¦›¼åJ9ÄŠnò£›üBZ?×™žs§/½çÞ={ÒËwœ€æ»ÛÓ^¦Þ=êTü@ÓNPðˆO|ºç+þñ_)M‰Ê]`¬\¦4¾ù©qÞ;íöüç7?#ѳ[ãSÛ<‰FúÎëÛó§ï<çïúÖÃ~â¬=‰6ßùØOMd¶¯=ïiß{Ùkœø¨gýë‹oz}ñÞø§Gîa?zç'?ú©ó©/}Ú ?ù ‡=ïkŸùÈ›_xÒŸ÷÷óµÃïB;ÝÅ~(²ÇÑì8‡Ü/tý›éíB§rwwÿa‡tHwPW&^Çrxç÷€AðbdErí×€ Øv_w€÷Wwc7wxsè;×uÈ€ ($ÌAeòPé$ø×˜nˆ‚%¸u3$R:hhV;øƒ:èƒP^@X„æWæU:F¸„‰'1Æ„P…R8…TX…Vx…X˜…Z¸…\Ø…^ø…`†b8†dX†fx†h˜†j¸†l؆nø†p‡r8‡tX‡¦ö0‡‡¸¡Ve‡ZÄk9—ƒx“8¬!Zp‚nâÀlwðeÉr%cP«’ Y-`€D}(8›È_n¢-qäh7€nB=ÛE‰pr‰†ÿ©4‘hV)«¦Ö¢l´ n¦Q¤(QxÖÀ_@K4Fèrh.àdÿG̨P$À‡ebK?`ŠûGȘ0$OÓ˜Fà$óUjʦ?~È R$a©ÕA,h²Ž3ÀPbÒ܈‰)@3° Ò‰õHi .nòpîÆ4ÝÅûÆyí¦I•U»ó¸Y@ 05 Dr3¨•‡£mÓå‡Ee蓎nÁP÷q4ŽwLóD/cGÈË*ÀUú¸wF)Y+¹]Wr3ŸD:«Clƒ„j×e/@+# ‹GåA†$€ŠŽÒf~#`2‘bSÿ©C@rB'7$6ÀfJò'~d  ³ ÁÈ ²cEW®…DDâTfõÅX_&I‘:$I"`c¬øM€t‚ŠwQH ¥„ØwoGiD+TÙ8éZrm‚(¢';ÒZóC´‘X6LÃRÌÄ4¥2Ù¬Yl’/9“+Ð’-À mEGy ³¤Ì$Q2#›ÌECùg2Išæm>n¡Âœ%°¤#,pb2“Bù¸^#pbs)  2Ö9'¶S.ç"$3rsñ]9çdb,0É„g7€äC6 $ðâ&³³òUFüuÖaÿ΢B(pžóAß´¢(.pP8´©a§R=”p+ÚÂ-¼â€+Fv»‚+0´CÁ²ÓQrñˆÉ5öŸ•„Ÿ.(=„Q.5´Œ“’.ð0*9›.Ù¶ÉTDÜ(,ð›)OO¤£8É£+ šeŸÃIjÖ˜wEùA¾¢_Q$)ÀAi‰3Så6îE0*Ûy&KµQ35U3#‘¥g I•%½f¶A:=zSÁO´ó\¶Å5L##G¥'ð¥aZW+  ŒÔã¤pÅŽ(ò`!)bдՠñ ŠéZŒIì“L³–Ó‰5ðS—hr‰ÿaÃDSH¥ P¹¹] i^œó£7²8*cQ e@#ó"àB<ª}ñtë÷AzËZs åfhÂ_¤ê9(*H<ª4Ï•¬o©> •¥Úñ0ç8j!YÔ(ÃRŸ¶Ã9RgY4Z2ÉXÕ©¦»1Ü 02f=ôP=$ˆ'Ж¦—Í Õ˜ìš2…„8YöÀ(Ø3WÁÉŠ¢«ªÕ‘¶ê–@iœÀ¸ÍèNbQe'ëDF‹EPŽú¤zoÓc›*ß*Û鞽ɬ›: ZXÕN²1àR­0v®ã¢ ”(@’ïÊ5ªc§fuÒ3®WŠcÕa£ÏzQÿ4* õCñI?1 2£¢á¡)¶10Ÿ%y*LB4\zhœCŠÐóxxIDégu•IÐò @ð‹‚¡‹©±¹Hš ñÔ]5ªƒ£\0Ú8Cû/-ù« Dï¸* ÷,³8{³%0<ìD¢÷´’²¨u¹ëFÄ ÂPÁ1)µ:j$Œ‡®¶ãM™…£Ûˆu”nù«ôJŸF9rŠo¶4»1à$°5)d –Ø-ý¢»ñ£sªP~À69¤7 DÕq’mÑ©²û©^¥ƒ‹”Ú( 'B¢0óÉlÕ4b$v+âÉN¯%"k›0C¹ÿ0Ð)}rr,ɹ1 ¹‹Ù;3@·S$’­º[5À PÀƈQòDù+Ïb®kjŒG:â{UOÆTr«Œ‚:JZ@ôб&Pºð¸²*¢ËC¶Ò¸+`I" Zeã ã–(|…†ŸÀ‹# ½p•¢w+DÁ¾yA¾0¸pF]LÂ…žBÃ5&O$Rµ%P¤ƒ½&@ˆf¥¶³†K”…㯵ɹ $<Æ}h R'¹ýå© õMÕªå§ÛC”ˆƒTë4¬cl¾ž6ypRyª„y1PšµA`,·¾¶Â#ëQH¯Ë+ùa\#%7<\9%RÇ)ÆÿGC8YœE|´ ž¤|Ll'{O[b "ë:#¼Tü€ªè´" ÆuÅ2¹«0›c“ŒZ¾4ô«õ.f¼DÓlŸÎ(ÇB²³vÌlóyVzŒÍ¶ÚÇ!Y­Õ¡‘]uY~C:¼˜ÀÛMºëi-$÷ªÅqà€ƒXqä‰ ¤Z‰#ÀX@"ª ªA €j`Hì nŽžúÐê¢k¬˜˜‡ ž6ªx1ã7­&)²‚$ @²r„¶á fmöfð<IH4ô£ps5¼–LXÐÀ– ¦ºê!¦PiC`*´ @x. N*ËnµÐ@–`T] èdÕz–Ah‚®àb"ÍÇT£´ÞÐzDcé |ZB¨*À½‰¬²‚¸hò·)à ^ÃQZ¯ÐCKÁM  HD †qó(Ž$PÂ]qÁcHÀà± $¶¼V_á“lÌ ¥–ÀâX^•@q ó}¥ÂÆDcwïLD]æzÚ·»á’Ppwµ†3 HuÝõ¼maˆ9WÙCBF€q¨3Lê N‡"2â°ÿƒÕ8Ø]é×.PDö©?A£$ˆÒÔç¡wÒ³ à<@·î»q™Wd`Ä ™GŒ—Ù—¯‰áSù}†ŽàHÒßz˪#@dî.,(DW~Ÿ†‹Ñ@×ó¾Ø@oùºÆ+ÔHÂÀlü_…wL ‰ò@bQV7€ Ô`9´+‚ÄW<‡0 KªKˆ "9 ½ÖW÷•€y¹› œV'&40k €°0ºÖŽu+œ[újÈ»+Œ°+蛕 o ˆüÉO{ê! QAÜåv‘J˜âF Œ½ ÄSTèS%ðô'ù‹Þ¹|Žà¹@Uö ÿÀ/·E¢qŒxŠ㱂@ Ãi‚Âþbx²œ° yTHÿa£–塌¸À¢š‘£€ rÀÖ´@©õñ Hi Êh³žr…Ma¤ìðHŸ‰IzÖI#)]¥ÃGkA°ÝÓbED@ߣ‘°F|Q_²peĨ¹ú¡i6Ðâ娦R¦~Å«YÞ8TÓ„³£ÏI!…óóYæø2JTir9Ø^bgƒO¾HVFÐ- ‡KRÉq60§ Ð ÏÄBœÈÜ'v"0 ¨ "—Û?¿¹ƒ ÙÀ–= B,G@1ZNª|ß—yVŠKd¿ÔG¯ÿ†yÌè$šgäçî”yÍ‹4³˜$éöËš#؉x…¾7mÊéèzð¦=f4s—´iî¢Ê”$äžàä©utVx*uuª$)Uƒr¦G4‘aVÓ¦QÜe+ät )rÀ(þ” Ý1! Ì€£§ÐýͪÒͤzœÑÇRó5/dI‘7G€GÐ t ¬c¾J?™&ÖòÁé‚©¦„ÄB`8ÑX±” `–n‡¿ê4† " ^[˘ÐÅ¡ýÁVÙØPäH®@[cÉ*Q„õ¥$`Þf'*Ht/ÛJevYü¹Vwz€ÄR:ÿ‚”@q³ÍÁyH¸·ÿQV†?P€¬ß ¥6TXÕçftÜÖ§†à\‰k<\2pŸ©ÀâI ;$ñY³–!ôø`£¨pÄD5fKΕ€š0.U1›u¡àl‚½=èp ”Ñ0`fø$ELQ-±5YΚÔ-q ´¡ÛªDP¬mÿ¤wãHŽºèn$à4 X]EÚæU”®Ó­îŒÑ>L€ 7N$À pù,*ˆÀi¢Åä!YÞ‘¬A–ÔFHà‚‚ŒcR  Ø$ À5ÖÁ€-ý•~Dþ)B’®€ôzØ,QÀ(CÝ€m›½aƶ’M €$×¾Ã/îÀb´ÅŸž7+ú ØBή¹”<£õmi%0fVð£„ö­E k•K<ð@@Ô²!Ì—j(­_ F`zsáeâSYcÌ×´ÌÉKz7VD1d‹Tu@ÅGFŠl`Øo‰Õ6S¥Þáª2¬f&: ÿ ØÄ Ës/VWùì1¹å_ø›zëHùëc?ûÚß>÷»ïýïƒ?üâ?ùËoþó£?ýê_?ûÛïþ÷Ã?þòŸ?ýëoÿûã?ÿúß?ÿûïÿÿ` ÿà`à"`*à2`:àB`JàR`Zàb`jàr`zà‚`Šà’` šà ¢` úÄêÄÀ—íÖ®¥ ÑÈK0ß2N â uå L[/¬ d@€ ˜ÉI¢Ñ%$€ˆÜ‚`ƒÞàî À¸ Ò.:ÍÄ Ü™ñüÖ-P,L¡:Üî(Rž+Œ@M….ª!^¥DE™Ù%àêÎ}̡ٹ!<ÆZ`•a¢DÛ°à!ê!ݤ¡!Î[ ^AöÀÜÝDðÏ™aÀ{8€nh qÜÄq\A¡š!× Ü!4ÿŒ" 5¸GnÀ $HÉ—¼Ô#´ñqB=Ñ€mP‡¯D Ã{PÀ赇;ÄÇpt ¼PÝD8AŸ«=Õïyhä€%–†*uÇ%&#L†m Mf`›ß©Å‚Óh4GnÈY!9žslE­ lɈ-RUˆŒÈ‰˜ˆˆÈÞŒˆœÆeHth€gD„L”ÉÅÙ@”¡øÉ%ŒóXÆ ¤HÆÍ"©!ò Á#rÑÞ@€T @©ÀT‘*­HÓ±žB~Òbœ¸À¶Ìñý@ö˜K LˆÏÅÈJ¤MV_üôÌd‹œÅÂ%A#òÀ‚$²)ÿ‹Øäd9—1åÏ\ä T‘>ñc)]ë±ø™·8×p›(d‚!䌯 DPšÖ"ÆÐ(ýƒÎ!@XNl@/n%š ·.:”.îäså”𨠮èÊ·0 ØÆV) ÐÚY<Œ[À½-ˆ4–D×8@ðНK°(â˱¼S7DC¹  IÀpdž¶œÆ¢ èŠ)ÇØ$YµEOpZï}ýŒ%›MçA„}Ìßxyˆ8¼Bj€ˆM¤VJÚóD…DW°åS& f+Ýß$âžâ Õà‘UP‘@ˈ‚°L”Xò@ø$µ9ÿ Ô¸Õ-Ày@‘( À`@Ê|ò6¡g¹JA¡-§Š‰‚TÃqý7¼çßô‡0 ôG.¥ ãáw’™w*¢Ó8Pª(ö”®Ï©ÙÇz:Â>Ž‘nyT|O€CÀ€—š‘³$Ü0åX0DŽ|hçèçÄ9@— A‘ WôÁ@rX¡5—0HÞHñá…F׆&*î=á@tô‰^a]+¡(!v!‹†PŒÂ% ÌšŸáŸd™òI²ç "[Ù%  ÓZ,ã ˜Ãa™ÕBòéWFZ@DhýžôijÈ‚Ì$0Æ’0èhZtÆ ì¹Qÿ” øÒVzœ˜®' ’Ô)@*,é€0ô›^¡ÁôAN âùÔé¤Â§ äéð’¬*Ž"f ª0¦`N&e <޾%˜+Õ¢ P#ø¢¸ÈZåYP’æQë˜è’AgÕæŒZ–8µ•«VèF)+?ùî ”é]À;®>j¢¸)…´É¯&L]¢©Ïd$+©æëÎÝRW´ç³.æ¡"ë“Ý@,¨¥NLé@~lÁ·Ú\¬òœ+Ê1©ªÚá^¹‰ £Œþg“"¶K§Õ* jÄ¢‘ÖÍ@<º€šÞ€0¬¦„ÁÔ+Í©°F(^²±ÂPsñ¬z2ÿ^Jèè>),`ì Ñ ÄŽ74ª€1ÁÕ>É"œÊ¦)Æz­œR)½œÕ`ÝËMOç̬ªòh«ZlŠÂª)Nm ¡‚¨H‚ìÑnëq%— äÈ®NÑ(¸qõí‚G€C{‚ÔPdcÒKå-}À‚«¶Ùê’± ®ägò]­¾ׇfJY¤êÊÄjsa— h×nMn)î›=gϘ¯òM.ï‘„Ú(‘`6îÆ>­W¹ÅÔÇêàúHõ&B$- Ùæí©]ÆvîVñÅ£Lê„è>˜. l'¸•*h³f'é›"€Mܺ€€² &Ø–Mÿï±L.NÏ}Œ” mïº ðÚ›üCŸ}Ëw8WÑï1MÄ€Í-X…5l”J5š^˜7tkŠ$XƒøC`î nÝ€¶‚Îq…B&EXC­9ÀÞÜ1"€52.éðoðYÌÝq¡eô@ðêP@l®Ûʪj¶ð&ØAe2¨ ”ðå¨ À$BœZ³„Ký)§!Ü›üBEAö[ lár'ÅEŽ”Ì)0ôé%ÁA,pð€y 0]ÄÙ)¦'ÕÆ@¼-Íd­ ¿kf:±Íõ2€Ãäà¤MÞÒTeŒþó¤ê¿$r  Ä­q hò0ÿ¥ÆÓ‰TîUB ¬ïñÙŽGªAˆU (CË[ßD@0/{È߯)Xb߀‹í›^W4!â €âÁaßÑ`@hò¸ˆ®¡T€Záa¯fq#:R,¡*&™É'‘nw¸ƒnƒ8-‡{$@3ºÞe # Á,£Î”^ß@Ü­ Ý48†žô½°*†ß5…+7òszBßãÒtŒçóœªp óGƒtH‹ôH“tI›ôI£tJ«ôJ³tK»ôKÃtLËôLÓtMÛôMãtNëôNótOûôOuP õPuQõQ#uR+õR3uS;õSµçFÿA8ê$Ts— ´,‘òg\’D„stµt‡Zõ*`õ3«Hµ ìÈ¿‚´'ˆÁ÷>tø‰(xuÉ(ô]èòÀ€f 9g‹AQ%*‹ÿ†L–Í0 ëÐíM¿1ªl·mÇ ÞØ<È4€Eàö”%Áq”8~ùwq+Ñxî+6å1íHâÀ\÷d7ô*N4;¸lB}ç/X2C3cN8‡²„0T̹¥«ïØ•(_yŸB„ÛØ–­ áYl›6 Ô}>¹@TÖ 8Ùdë@´ãüñ‚0Km1»›@®a60Oo·:¨Lj {hö88¤XÚq{Ug'ÿ˜ˆÀ@’‚@ À‰,€©(ÌÁõŒû·Íòh¤EÄ@h ŸªÀQHUIUj¥8ã/ÏìYÀ™\y?ÑKbjhMPÂO¤„šÊ•’{Ù¥ È<´Vv¹B%YG<_s³¾ð„#(i§'´;Ûy¤}+>å‘(„¼©¹تоG\±l'̼ z@È$p©G•¾Zaaa'`~šìP5lu8‚Z(8eë a…É;}çе¦XûÀýòD€ô«ÀšT¸Ôí €gkv¬“œ{Ì×A[ïÙgÔÀ^ztâ@º=M‹à8AÝ— ¿ø‹ Tú–!RèÿEp";¢XÙˆ¢M ©È° Ì+Á‚÷o€øF”Àà` ˜×!ðHD…0ZŽQLxSZÊPdÙâ–GÀ¸<™€§ã÷÷œTÁ×c€ppVd†²$ˆâ`#óE €a"‚ÀÒÆ9ø´§a—òàUã‚R$!*r10p%±Ð+Òp!–Û  ÅûÕ:‘èË×`à%Ùüv6M01„°‡¢‰9A[œä™ÒP›Š$Rt(†¢`IþÅR‹RÀÒZß‚À£SµnÌ ‡0¡Â… “`n!‡z,A†FÍ ŠF!@¨%Nÿ )4 Gƒ †CKz+N ‘7PDÁƒ#R¹K!H‘/0;“&å O (¤â2úáSã^/£­.ís¬¨X ™†ÀcœXh €‘ €g€LõµL[¹~®ÌU¨I,"\ˆ;H ¤Wä4¨qè~”ŒÎY  Ð$k„;Ö‹£AÈF(–yéd²˜¦¿>´(ã5x#pò,&Pë`Òïløë˜ÂM‚sÝ?Ž<¹ò,ìKødø›"4ÿî1‘Š'¼Il"\¥g „¾HƒXΑ8§(¾]öaNtò®¤Ó) ‰ uè7zVAÿÁ‡÷‰âÆdˆ‡CÒ¡ÐA¨„o¶±×O\ÈOgÞ³^)ÿ £€FÙÄJ Œ‰R‚7èEÃéÑ FšhK3½ÅC>´5IMd&ŸfBIÂÂT%Œ÷™d£U'¸¡G1!AˆÃ<ò³m"؆Pnþd)BHbÀQL¦`šËÍIgv"—FEÓ‰Ef mâ†d ¨ËüB _ž—xãA [$SâZ :BœeöB„*è¡/À7Km& 2¶7iBWM 4‚W\¦’œHÚç °%¤Ô€G‘Lh’Àm±T:D†ã¹ÿ£Ùs¼˜ØfˆìÃCä³¶=òŸQ#A3ÕîºdgI¢€è4 €œÒ`„µ}À”kŠbʈ=pwÎGbÐ'9fnôO Ë ÀŸ)LyŸÞÉqÇ\Ÿž£j;æ<(XœDP²°Á %ñ„·¬ ÃÀ2·J*[,5ø‚&? ¶1²~ùPÇÊ´üž†¥r82%MU]Á1­Ð«KOøÂ”É9¥Ôúð.£žY&× À?fèB.9;ï!- `p‹}-:D€ ¿9‚ÞŠÇÚµô©Æw¦¤P–fJª€_Äÿ‰Í¾œŠß¼dùæNi´9ÿÜö5 µpøكC>\ªy]Ï¡³y8ȲÏNûqZDòÞ8[ñWpú~ÆËàYè(OÜäžB ’DЮg»OüŒ‚Q7÷à•Áóå,BD`Ðʪ.¿P ˜ö«”žmÜ ç(q}ÀpMÁLQS+và‘f;Cæía JYE ¬¥ÉqgËáòHi~MF dÙ"ðÿ'YÌîÊ„:ˆyÍ•­ŠF-ùÑ[ªt¥‰)@œYŒÛõ'ÄÔD>MJ”sð®‰g0ÅRÎ3†„=:Bà8Á“>ÎYÒì@ˆŠ/F³@£ÁE5l §U+\"—0Ò…D2u¯;ƒfÄ2¥‡‹%cœˆÒüiÔ<§žC€£èè:7LeF ¨‘8"®¸4ãMâ²?¬C «sÜ%ÉB»º F‰¡(t0€.TçBIEyÐu<ñX¡-¡eù°Ê;¶rìÝõ˜…%”¥´­m ŠÑ^ÔKO0H½îQ:bJ¦o9K€=‡¬¼PíøH˜Z”ÿˆ40— %K¸©ôìc)—ÈJöÍYæ–ÔÝ=»:Õfg¬8­¨1,`àKøÙñ(àÙ:È Íc/$Q]t»³, ¦4€ ÌÀ¡• C©ÂD` ™`XÀ=”¢EAH"à„¤ße€ €¥˜¬x}PYÐþ• P™ÓY¿x¥„]T@ÜÞ@Ì30`PX“« ;±N¤` ‰J€ÚvË?TÙz!(Ý4¸)G†&ð€¬©B &2ÅR1€pUV|® ²¨~*äIžá”¬ ,<@7BÚLŠM Œ íÿòîÜÞJ r`ò2¤*­@„° ¡ïaBVÏ úL"̨¡;ÍÄ3˜DŽÒðÚƒ¬¨3™-WB€ä‚%Þbhb}rmõüõ–>·â±ñ@&hGÚ‚ád%¼ë6`Vs wÀ0«õ ¿’‚Œ¸>Ci8œ2 ãÚ+#æ²½Yº¢/£Öhcκ¿@iq7B `ß X™«*0…¿ì¼—ˆ¡×±@ÄX+Þ¯w}V„€Ï_~¶±YÕÞ¬·Œ¤ø½²Û¤µ ñô–qrØP`xÀ¸«C Òã¨Îá[eÿygü9’-U,Ôé!Síp(OlDa 900« hœ"—‚jÑP„R3ÌÓ¢]¡ï ÷¸Ë}î³ÓBüü ¬ÓÒýÇÌ:ršbá½ ^îEÒà¯2 ~ñŒoüâ¹ÑèbL„¹Ž×‚Ë’Ê;~ó³“5Ä"uÎ^ñ¢/½éO_;Å$D 6ý1º]h@˨¯ý߇€4'`ö¶GüÛ{üà ¿ XÀÏÁ|ûnž=CüáK9XÀ†-àéËý÷Úï¾÷¿þð‹üä/¿ùÏþô«ýìo¿ûßÿøËþô¯¿ýïÿüëÿüï¿ÿÿ€ÿ(€H€h€ˆ€ ¨€ È€ è€(Hhˆ¨ȈÇM‡ÇO—@xá| ± „‘CàÊ€i”jadO[ÃE o$X[qVeµRùpy[Vpr8H°sFðD·ZÀiÖ°mF 4× 1P„ Aƒ² +è-H[1Ðz‹ƒ;èw # ðÃ…PuFxK…piðƒ=䃇—9ç† Á$Dz‡wÆÃöc,p…C7hŠÂ†‚ˆµw·w5³ ç5E‰—utyÈRr8èC(xe£‰Çq<ΡK`x ‘ÿmÈ*;àŧTÅ@u#<‚‡~¸y”XM³1ðk£XK:€ ³Âeu8x Œ{RjW†ƒ=äPçcOør‘6'µ¸wE€‡¥§‹Õx‰¢°'˜Œ²CŒõ@ºd0+œ…r?3%ÂòF à³@µàƒPnðe°u ÛD gPF| oC§©%GUq7o À…  0  +:0R!¡=_'0à‚ê§/SÓŒ{à°' uà]Åcáè7 RÀA¡p‘?‡) ‰†  /ÀQ˜àó|0Y i ÉCñ6oדŽÿ³â7[R ’pvej~D¡5 P”K*ঌTš7Žc‘CÈCBxT82FkÏñGõކte,%B²DÖ‘ ÷þ"0çÄh%tj:!‚R•ùnéPB:Yž9™½³‘o• –!‘×{¸…q—²F1‡®#¼(‹äãG%$-Þ•^Ñã¶“D(*C1@‰Y„q0×™žxNH‰Y’y¢hP L"g„x€&-Ö²¡âU;¨¡‰e‘b‰1¹p%t.= LoùC‚h4³9F ”¼‘î;K OÂÿV“Gã šÏa€ *ƒùX©_ ™)  Ç’ÝÕ¦Àœ`æø @-„1²…&ªƒ+oUE­ÐW…Èy¬I¦ðR Å™€ I{j´3/[€‹¢´EÔ‰b • 3˜Ð+F¡’Â…Ø“‰0qv 0lÏ‘Pš[P£>ð4Ê“„ ²![ªNÀ '" Sc¸+,¢€b›¿ÃŽ™16z¥îy'à ²Ô iðP}y1³“8á+0!*óË%))sL9*#Ÿr¥Tô‚ªF±(ÉSX£‘%*^~^–ö bÿ‚©¥= ‘© ;êè(E°3ûÐB㓤8@ª)àVI…uqF1ÏØ;Â\.|aÞLËwâIjç°ºdưaœ*Á½Ì´ ±œ+_@ñ9«ÍJ =S ¡©|wÁ“'µ ,öª_üÆÒ‡°/JÑz¯j·CAÇ{ð4?£ªÉ«ØHï% qaÁ 50NË‚˜L¾Ä Udü`7vªú§VJ$c©ÿ¾´C Eì¹ÊÖjºáœ­è/0† 2%[…ÔÚT&SÓ)†q¿ ³ÛÖ,h‡š·a\0 Ƨ†Ì5›\«Êf φРÐG=Y~m›šQoœéÏÐ|¾ üÊx,J’ð¢ PK€¸p†á½¢5@ –y=°p¨AÊJ¸¢³š‰Î"຃zSÅu\Û¥[Ü †Í]¶ [0` 7¥b0Ø¡y€•cà¥;mE=Ù•~ÅCg…·[ Y™¡ ‘Â}`m'9fË««Ëef ¢¦ l´À ip˜„‘˜äÑš¦¾YYÖyì*„á™:7i·åÿÖ÷Vô--¸Œz¦Š‚HdÓ&Úö¯ßóûþ?QCÂÀEÀÁßB žC!£ ‘–Bä ãæÉâg@&ŒŒ£"ÛbÖQÒÒÀCÕÆ‚ ‹‹§‰#d˜+—ï D™„L²r3F„ÈÅ\U¥ãq¹ù9zºÞÂE{@í¼tžŒÈVÁû¬‰šSïÔäSÃ…-,¶$¸Öïˆ lJPjÓ;?2d Ë0Zÿ\£€„ ŽpLy­€ôÔѬi“HJžžx1tpφ*4A¡Ò4©M -CÐâ@¦·Ì¼2êÚQ"½² #¨);V5’ÀßÄ * ×O¢¾-Q<ýãà ["äÅ{Ú¸Lë»·cÇ‹Zr©zžI¤Þ¬lù²9 ÕÖ­wÌ ° '‰ …¥ ¨pHó9ôhN¦8 `¡®¤Ñð`‚<à±òŒ„„ÿ¬Ô ãÀ»^h¶vÅ‚X,G)dRp€CÌâÇãɉ”Ñ$1…>ûQÊÀc ÇzSžzþDƒ-+ßyûÃi$Á_{ÿ\uÇ(¥4`@PÔ—G~÷]Q‘½EœpÄñ Hà–Ph €šj¬ibÖƒ{Èà+m°t]!‹EDãKŠX'dxHäyA 9ä šU²ÒJA¥S~ œ$àÚ—X—&pµ\VnlqA'€1T+Fb&$3ÈzR<ñ +F$žAê%¡zùâ“}¡D'­Üi”NI)#£°q–ØШ2 ôÂÈxhQá—õÅ"Wn>1FSFb¨'4bqà“\aæùtCw€òSž¹êŠÎJ%\B¦Šð€I “[£ ¾È0,)ÅJ’è ùÿ,UuÅŒ#h‚æuªpb±RkÏu²+º5-Páñáa€öqT 0V‹ž’ž|*E0€@8 OšB`@&Äè`Š8ù$•8ÊF»Œ8b*§c¡£`H t„+E²øî ¬RhFêCÍ‘rª\Q«­Ü’.Î9÷ñk1¢ý!ƒkþeO$/GéåjÛ¡Ì‘ì›ÇkÂîw$ˆ• ÖèM®yRÜöT :-¦iÒüh,¿­dVÅJSüšaˆ\àh†ÈÍê0*ò‘]š±^€aÁ Úð2±©;0-xÄÀÓhã­ìZYªƒ Ú€ï1{ÓÅö 6ˆë”kY˜J(EbLB[0@ß"ô-XÐ!"ÿ¢$x‚Ú”C3wCЗ„V9o‡~€‰ípNÙ·ºÃ Ï ”#ƒZ² ÉŽ÷²Òµ"n ÙÌĈÁL±‘B‚]5¢X‡ ‡Ä;Š$]CKBm RûZ,~XÍ܄ۃO–€{!A" T‡ O:²–‚3^zˆ*l1zâ1¿FÐÒšcd”f‰Äý#7ìC¦ð(½É Ê™[3‰Ì>–îtŠZ]Ády¸Û%ÒoDÈêl©N›ä‡NœX"j˜CK–B§´áì”G4 µbZfÑ”€$ã¾<4§[ek¥ :®”K•çZ'Dõ01eèòý$BmÿzGTÔdæËÀ>p…•âdcÏž™¾lN¨˜-­ã!‡{ž&ýCŸÄJ.òtsl9¥Ê…º)¢F5Ç;M ˆ`â’7œ§f\f8UŸä’2cÓ+h.¨ÛdöXéÊ7Ás*<ª³u ‹ÌaP€<&9 (ýpœs ?cä/P’ÎÔÅõ^|[ú‡¶4¶"Ž~ SŸe@/mõY2Â3¢J·Ú!Tæ0£˜w ÍTt%ò©^bw…ºÜ!BœU+lc&HPd’†À›ç< ƒ T˜MU“g‚ÐÜ& ºáí@È¢¬G<èX™˜ÿ+l§;ßyml‰džú‹0ÐQCcI…Øë²Fñ €õjaëý‚# ÈÃ]Z`%Ü!À::cr2 ÁÌ´FT`€êÈ-Z“&ðZ:Ùïî£ÀN3dð€ÞæÀh ‘9Rœ…¾*kºZ2PÍù ɟ".ÀY)e·Æ[iV;\N!@âpoûTñ!.@ò’(­ÅôŒå¹lIgV Ò´€lu¨`îiã!퉻\ƒ+bÞ,üƒ ÓÚƒ^LÒž€+®8òå"+¹"ؽBÌC1Lt ø}W^©9áèU6uk9@œcÿ(бò™9´0€Dà \çwD`äÞ4 aEäÏm¡N€«¼’Ð-³ºµ¹\ì™_Ø4áž 5P,p‘ϳØ…Zšä:€‚Êz8J5ÄÖÄ$RyÙ‚€úÓjt…ÅË׳¹j- è`ÑDEjË7»â €À68½€.já Ã¥ ßñ€âFB®)$€s&Z |k"ˆnÍ£„íIïwÎ ¸ur}çXÜõïˆCœÑío×ááËÈ€pDR—j¨lN§-ò‘÷¡~$9ÊSþ‡kª<]ŠPs-YÞò8{xæ69tnzóÏ|<Ç“n ]KÝZmçÿ­`îÏ“ÑRéNW¹PÔ§GS_§¯ns# “ê^w¤.öòõ±“½ì~È‘ÖÍ^BÀÚj;ž¸2qýîv¿;Þó®÷½ó½ï~ÿ;à/øÁ¾ð†?<â¯øÅ3¾ñŽ<ä#/ùÉS¾ò–¿<æ3¯ùÍs¾óžÿ<èC/úÑ“¾ô¦?=êS¯úÕ³¾õoÇòÙÆ“˜»¾ö#wÛÒ»ú£è 0¡=Dô?¯íëÞ{ñÌÞôÓ†œ…y€°OzQD·$¤óAJ½—„0”²ò!ê0Dõ­gkD ØÄˆ Û§êtム°¼e0 ø +Hÿ¿'XuU@lИÑEÓñÁ(÷åü|… LغB†Ñ÷ñËÛl™ˆ vXP„Üe4_é!Nôý Æ‹0@™m±ýAš© Å0 ¶ÅeZc”ÃÑ ŸYL5€à¢¹‚–Í €ÔÇ~pÁFBEd`²ÁÞAúìM“Y9e ÀÈ”ã@Z}  ´BüåŠ Z† ’ì_䃻íÁ`€€p8ÀJ€XêŒ4@ŒDaÑݬ!´¡öøÁtÀÖ¡!à¡$È@È×¹ù!l“"!_0XG—M•#BbÁE‚" ––< ÿŒ¶™Ö(àí¬,*@âdÙEl¢áÈÉ+Æ" ¦Ë%L†‰á ÚÚ”áœae¤áè¡AB`â=ÔÆ5ØNÍí)yBB¼¡É8GBì†:p6’Ÿ&¬Äuã,Ú ¢!,¡0½ÃÂ]a¬8j‚]©Zzo1H½02¾AH[3Lßÿ=ÔGÔ@t€ßßmW9ÜäÞV>ÈŽ•H"(‚?êPš4b„c9z…ãfòA¬apBh&¥¦ÙÁ:–Ã&#cÅ&=Za­m†!cä`ÂR]†ÅVÚ쀇v´ZÝ +€ `œ-Ø5Œ Àä8g8@ç«°(R?€BœäCÝ9’`uå×u%ÇÐ@kŽBq1\8¦ßA&1t¦¾Ø¡m@e.ÿ¶•œªæÞ8W$ÀE„L@€XÊ;ÖAcÞg!F‚‚åÃy (;È¥DBP0§P!¥&LáÔ_ÀnžÀ zT‚Ô\F‰þ&Á| y:‘J¹Æ`€ QÁ=~Dv‰ ¬À,&„)2SÜQLi ùM¶äeÉðgWô$(Œ!­”ÎYÕ‰  äÄú¤}öÝ'BhiÊ\€[˜Qø i`G5î~¶ãÀ’Zâ ¾C/Þd2B¾CQÉio€”š"½¦'¸¥€„^€„0~rÒ¬hÁƒØLlM‚ið Ô0@Š€(ˆ¦ÔúÏÉQA´ÒdÜIÀÒjB`¦%ùMì¥MPÀo^µˆ )êå©üä@BÆÒ0ȪÙEH•ƒí„idÈ쬬êt‰05i8+(qÜ3nÁÐf•}`ÿ—‰x‚S–Ã6((ºâ¦ÕdÍ È:—e §sð jl1,B‰lœ«õѨ/p…c `¼mv†.ÝI>TBØŠlÈ¡VÕ¨BTZJäKÔ|Ë’Ìj‚h?@)#°˜òU­T‡CpšÞf†˜³j‚Ëb.©^iù±Lm$x:X Z~’ÏâA£þ㤃‚­ …ì¥Þ- X‰$­ÌQP m¡ ´T•ߺ|\x<˜@Q×xC¸ËÉ-âòííŠí„ܹ®l)hA‹ž@¾oú*æ-®&Hg3 [Ì›éíJ06ëëÒö舴–¨"ÍküRÿŠÆä" $dÔ.kºÊ`âz‚‚ÉåoÄ®ðTÚ.Hà®ÀÖèÈԚ隀Ì.±ìÙ¹½êÐSZ#È•MÙÁÞò&ÀZ¯„œ89Ó tîT}/K¹ìé‘/»%ž%Šm.¶~n$€Á10°´taª5+Òú”BhHA>ܯiJo‡²£¹Ú©:‚cšÖ×ÖwáA gMõ¦‰Ù&éî^°“f±åih+28Z™ÌÀP},+|°aRo³0Añ1¹„ÙCInjíH„I¯ª·“–Љ©ÖFB"—ïCÍä 8pw™—&à0î%ÿ(éòá­‚íHÿ%#DHëZi*ßcëF*c°õ–ñ %ï•Z%,•Õñ€Âµ^tœ³n”;þ |ìå‚TY²ïÂÀø1ƒ^ŒNmˆoÞ±ÖZ“8ŽÑ\¥I„ ÑÉ«`ñRzüÊÑ\ V8ÿÕè˜3¨af¶ C$€)º (Ø<· Û òŒrGB}\­ÎóÖNV}ˆ.„qßæ®[0§Ž×Ú/¯ïÖïÁlÂ!oÚ'g ÿñYG#®ÔG쳇@Å‚ÝC/³lÊuÅŽuóbu[:SQ¸à>0ž}"0,f#,ªÚë" ‡Ð×Ù8Àz*â~&ÿ-·VP‡,RÆ}ýM|!5ˆ[H µÀJ”k4ó)Ãb+ÀPoÚŸ1ft"öô „ÆWs…Xë³ñÏzñÒzm³ §î´R·BÎöYÛŸ vXÄzñÙ_wâÀ (ó“ñÀÖòO4i4²#ÑÖ’äê(P£Aª¸YÁP(ÎM}HZ§E@^’[£±t,/’Èšš€¤ï±2ÄânwÁ!Žþ=èâ}iSl†cˆ*ÃÔÅÈ›nó„å-Uƒc\õ#wý*ÄÇ*µ¼ïs/ŠZ_Á¹Â™ v\À©}H¢®Aƒ&0vÏ’2ÈkÆ”(EWƒIô™jEvlKpòqÿDXàG„Ì𮪹ñ±1'˜òÜ€t›úΫQ‚‹@ p(Ú8¯/U€ÈÃ_¬Þ7ç|ÜÁ€€dꀤ޲¤âU[ê÷' 0`,Àt[„ödÝž£¡Æ8tKÁ(üYR$ÁYÏ]èŸûÙ·SJ‡ÏŸE]¬P7S’@Ž &;Áf4è{‚p@æ-²-«Úßf˜ÄýM¹=ðÛH¶ —ñhÅ_02Þ]aÛžžïuò\öî'$±'3ºüyÙÁšÖ]'ï9£çAÕΜR>¥Ö„jæL¤×­ú€‚{7º§£ÀtïÍqÿÀ07«qB§×Û°­M„º©Ï×ýÝ…Òô§×º­W†ˆú­{Û­7Õ=·ùú®;±»±;²'»²/;³7»³?;´G»´O;µW»µ_;¶g»¶o;·w»·;¸‡»¸;¹—»¹Ÿ;º§»ê ³#!›Ó²-«Þ«{ÎÄ;½“‡ðQËþ²{#)Ò\x•½[Þ)4«çIEX˜Wk·ÕB† ÓÃósG ÀG¸TDˆ+±Ê ü½_†ÌöÁÄ:’2fWnÔõä¼HÀ{žš›®AÁ0Ýr ÓkÔ[ÕÙ_ä‡<ªÍiab~üxŒ|Àò¿Û@½°ÿ|«Á~­,@mŒn {z6è€uãìF °Lõð"|3ýÝ,?â×—ÐÉ«½l„«U\^@‡Q°Ñvåô}½QN„d´Ü^ÛOÂþ671]:¥ÀH2ŠRäH¤oruBh]L¤Dô87cóð8ÆÝ´ìB@‹ð¡(_œÕò»ÿ¡©ÒÉãÈ!ÿYéÀU_$¸ðÈdP wsÙ’WÈW)Üè%O\J,ò‘sfÂáÑ,á!¯Üð„|õó#)TÈ 4±X‚ ø" Ö(×HàâÆ ñéð'œèß’L6é¤>ç^À„€Üpb£LƘ@C}\ðW‚*B iÂT ’ÞÔj© H‚N¦; ¨ÃE¸ŽàNGÉ!A·¸Pî›â­‚Ò$¬´%P°+ ™$Ô%ˆX,¨ï•°Œ`YT–;j %íÆ hˆKm èGB¦•šà޵×âÚ)0ŸúxAªˆ‹ ¬rªÉvÀgíÍèæ!6ì@é½™@·è cÄ \ œ›­›ïºCãâ0‘c<$ÄTWmunjø”qÅÆyÓ³ÁýÑ(Ua2t#‚-† 2S¼;£Êä2ŠÚgxÉg m \ÛÔzŸÀÕÓóªwÔÕˆ÷ÀUƒ(øÔ#d ÃÆ”†X‹Ü±¤Â ÿ#gN¶{|šXêç¢×Û…`7{EÆžýÃØ|úQ™:j?ÍUsÏLía?=B ÍY¡§°%nüñÈ[Á¸ó6\À<êV¤ …ãWÃ!0[1„Ù$P¬xÍ'¬9OÆÊµÍ½†tEt` nû]œœàáÛ—ÐpòUËVàf,‡˜@r“GÇ’r7CL!MMËçø¢³ÎÂ_þ£ Òµ+ø€qÁР Ìp.ÉEv$˜J¼×Ž@+ÔðàÓÁ7 €8Ì¡´œ@·(i)pX ´å·êÀ}'¸øÌEÀ±ˆ‹æ“J 5p¬ì‚]ÊS&T5¼¹ÁÿÂcUÿææ;:KQ†pœ nwÀâQ@q•-¦"#[õ°‰«( vÆ_0‚£ÁÜ<†pÃ~ü² ʤ»+\¢º›B!«¹;Õè1£&7ù$º8Œ¼Ö |`4'êì H4GØD?âõ[… @ŠŽhé”VH%!Y£âè±On#ûÈÈIg pâc!$K@°ù°éQD–Á»°õ†w›Â×F0•IB›g æ<è3ˆŒÙ’š Be|A6JMwì,ıÑEÎ¥¤˜øÌgn@©Èk"TònžY4d`Ϲì™EPa¡’ÀÈžá6‚úò ÿïÓ/í§rÖ¨…[õYC``…@c!Ô¸•Jºp·Š”åS䬴ÂpR¨ÝMJ À5 úÍŸ?)Î2äK„Rž¨#1(S£4Íiî$AîªzÂàbš–ü› Ž/#’ô¬hmdÖ†X5HæÄ€l£Þ ÀçƒÇ9`&è€ê´‡Ç“”b–²°Á<ÑHà®vX*pŠÓÜS—l QLãß…tn~L+!Ñ@œéU¨M­äÃRG¹TcŠ–23Ë¥B\ä b2,ÓÏÕ µù1jÙÑÙ(ôà­Ô«òãvv³Zÿ@k&‚²R ãp€D C+”ZáH…2p˜ä`'X€W\ÛBØî¬çE…z5Cz^®µAö*Úþ¦u¢ð¤<ê‘lhÃgT„W|•Z1 ò&Ö\¤+¦HFΉ·&ä­”á’,f€Ae°KK›«š¼¡7+Ž1n#õo8KÛ>ºùéX "€ Ä„+Û<™{@a§Xn$Ä1tE¨Ò¶‡„?­iŠœaÒ€¿¨ ²w…¢6ÐÊFê–±àd,Èw˜ðëØ»Ìý¼£n½øÕ b,-rÉØ›'ã>ŸUÀ òf×JyÛr)`°Aÿ `%é2WÊ-A2KPvadÉj€zo°å+¸#–Ä@´¢¨GÏÉHtT1 —¦¨­QpHÀ.ï|¶Z1ö3œ, ºÙ(jÓÛÌ `5 Q p¢ÄEL>¯;Z;%`@ÖÀÀÀÜeýb[Û±hlªeÝŠœÈã>v0-ÅI €ÀÆœ @«@Ã~çœ)Pï{¬”îaÅ(BîlV×O¸ÂÎð†;üá%u/Ä'NñŠ[üâϸÆá\nüã ¹ÈGNò’û¦„¦£J=“»üå0¹Ìg¾p=O€  ÍwÎóžûüç@gºýÿpýèHOºÒ—Îô¦;ýéPºÔ§Nõª[ýêXϺַÎõ®{ýë`»ØÇNö²›ýìhO»Ú×Îö¶»ýíp»ÜçN÷ºÛýîuÞ™N®½ûýïýùÌP¼]ÒX7¨ à>PÇÂÐùâ'wÂ_ƒÏŒÐ{o4Où³öýCxvçGÏv?üc’oÄásSEÒ÷÷óö½ëgÿvÔ@Ö±àüntO{M¾²ï½ðÑŽ{÷‹0½[1åË:ŒÑA@ô  å¾¢Û0 Gçc#dƒ Ñ'`n>øXÖ^XÀgâU×ç}ø…øý2Ðà‚SšGŒtó8ü÷/õÿ\àÿ5ð´òú§Q‹ÃCq•AÔðDss²FÀ.4°J#Ü1/´q•}5à9§=6àÕA6ÓPßxÓ °‡)â’§>¦Ñc.p@ÃüwƒVÇ=B‚‚:1*9A0Z ^S [~àe£ò~ dù1DÁ4&P€CpNÁÅ6÷‘1¸Bša]—‚±ðy˰#ó¢zE8¸†W#`À`¾s„çq8’æ^0H­§ùÑHSpªQ7‚!~#8†¾…}Ç‚§ÔLöÄa$|lX‰Tgu JV6pùq‡ŒDuˆØYHÿ‚Bsð(a(á0(PÅòU·S=• ä‚=Arè³õC‰–ŒN§‰Õâx=ˆGÃr± ˆ³5œ·0TFªöЊƒw1³`IóA#M#ŒÀ4 vxŸe/ÓŒäØŽG—5‘SX¦¥@!‚'I!:øåWŠLøb â;,øëB^˜‹Û(vXMGk8xa&CXKy%zîX‘/·<ÍS ÐUÒÓrXc„un†’ª²‡èè¤ð4 à h²¥îá0*d‘I…¹¥*Y>kS&‰“Br¨6mʼn±Êh8‡$N…”)9Lÿ067›Š2yöá0CðTy“s16EqÒì8”fYr€ÆOqX9Ïô†‘æ+Rf È5(i)R "¡E„†F(49 Ãq‰“×?9Kijx–Œ)rj™bvc9SFFÀ•q¦d¶àq·ööÔ:ñX‹ô—vV5G w&ÕiW{¯Ð’CQWð ‚Ö˜¶iqÙ[©)™lÉ@^ÄP„bA÷,¸BSðòÑ™¤ZÅ€u°rcb„Oãñeóõw’z­i-C°Úsˆ5¥Àš·™ž çv޹כ X 7 3ù€*°œM°"ÿ h8¾c=òùSñÔIš¾S‚ÀC‘évb¸ ¿w[Oµa‚@d40𠪞*Zi)N«0™m‰ôV ð†Ž ¶Ð <8 æè>Ì鞀ñÇö"0 WYY©ü¦n¬†‚‹x¿GS…¥gÆxyS€š¤Jº¤LÚ¤Nú¤P¥R:¥TZ¥Vz¥Xš¥Zº¥\Ú¥^ú¥`¦b:¦dZ¦fz¦hš¦jº¦lÚ¦nú¦p§r:§tZ§vz§xš§W V ›¨§NR_€:¨‚'FÇÇ|ÊeЉ‡žiš^À`$‰WÄ”jµ¨?;ˆ& Ħ[JÅ` Fœ»ÈµUß+Áa"Fжa¥sY! .ÅV XœÅ$B–À½%Ÿ¨¨³ùëfD¼×™t—t¼¼k¼°Ö<;ÇY…¾ÿeaä«sÈË"¤ª‹È ‡‘γ‘Ò#ž…„%ÿ[’„ •|8·Kª™,¦@|nܰ !Çði1AöR¨¨ÁF¶øÛÁ,sx̲›¹Ä€b b¶°üqQÛØÌHh É„?60I• Ì:ÀŒ`¤ÆW#ÆŒyÂZJK9Á5Âè*dOEÊÄ#H2¡{%+¥û^~ÄAa3Î߬pŠ™„ðÂB¢Ë†P4:Pžý(Ì&#SZ{¥ä Ì7eºƒ%Œ«%ìÏÎ|y)¬…åÂŒ,„5ƒÀòN%àµ#pGÖÐ÷˜ÔLgã4^ã6~ã8žã:¾ã<Þã>þã@äB>äD^äF~äHžäJ¾äLÞäNþäSZ¨–åT¦S®­Užå\ª­Üªå^Ž¥‹É_>æQ:²ÃJæh¾¡gk 9€l›æp¾¡¯6±çv>”÷;ú{ç|îŽùÛÂ}茹Å4eŒ‚~蕨È[ƒèŒN޲¬‘^Ë{Þè”Nyá| ]éšþw½éžÎ<ýÒÿŸ>êt×ÖlEê¨îz¬ h©Þê‹§Þ®ë²>ë´^ë¶~븞뺾ë¼Þë¾þëÀìÂ>ìÄ^ìÆ~ìÈžìʾìÌÞìÎþìÐíôà§÷Ð}3‘V­%íh*ågŽtÔ^dö7“8°©—íÚ^¦WNÏMÇ·j6Ce9.àé¾å˜×åj‡Ñ4ï÷.§aîv£K5þþïpjæ}Ph ðߺuulpÓGà™Í„;ºW £ þ´Bán ðŠgmQ‚³ +‹»à|Ì—ÁjdÕ8‹æq6Z /÷ Àé·~%?0~ûèÔjc†bÓ×# }ÿÑòÆöòo›k¾¶nþÕáÂ&ùo®Æ²s‚sN œjµgW!a’üXoŸŒƒ$¶`¥Q™ËòøºÝ"‡Y.ºh‚^Ó‹S‚ô#Lz?‚Oh ‘Ð-.05¨0U-jÁNdr/ÅQƒsîˆp?h ¦¬á$ñ íé|Çù5*€s°Xƒ‡d„µ é¥3CtUë÷Î &g’ÚGq P}S1÷6ð22 AÀ…¨H…¨p…Ñìªèþ›D˜€q²û@è¡—o–÷Ë«Ðá}Ç;rÍ¢»6Ü¡r[Ã@®îÎ ÷¾óÑÿV yÌÒÍFü*€A"2&£ëñDpÐù09D^“ÀtYT¹%³é|B£Ò)µj½b³Ú-·ëý‚Ãâ1¹lžEàq ,¯Çíu€#–¥Ñ1Ú¨1Ô½HTü\< %~í¹åÄÈ”,ÅÌÐ`°¼\*..•H–‘´9Ñù½Øà<íôÐ qØPº\žõúþ #'‡±IîYÁmŽtRÜ¢æ,dÐÐ=ü´4iIdd”K$ ÄH8ä-ý ,nEfò¸°„ÒhÊAÖˆÑ^Â@JUª "0|!B 8p¹xE ƒ2^ÿ¤À”k߈~÷”¡L©r%Ë–._ÂŒ9Å™ˆ³ªày‘­À-žK:…Ë 6±¨T©7*šÀ ­$8TÊ’oÒÇ’pþ½H+@’#eýİÔÈ *Nx AB Œ#4Æ2Ë.箯#§ö+s0á†#N¬˜L„ Ô%pãÂ… '¡t±óVµŸž\ ½{´‰Ç©MX  .À€›.@¨ªMK…ˆa»ŠœCiCÒŠˆáÚ…D°Uuâ‰(š`Ž/ €ŽÜopÜ< ^,~<ùòæÏ£u©ÒðO2O ÐyÄù4²Ÿ³ND'ŸLb´2…ÿC\“ƒÙ [•w·õ@7/”†Y9”_rË­ˆ EÖ¹PákpÜ#Vn¦×¢‹/£Œ*„J D½¢BŸ|LRV€€\RT\R$hMUQ›$ òÃâ_9¥Vv¢gÉlÊ1Ä¡S¶q‰ F‰¸ÄÃù€-.ÜQ ŠkH9£œsÒY§w®€c6hJGØ™vGP4`§ `5C™`íqåuN$é!LRÁ „Q ä›Š  ]'F'&†[nˆË'¸ðƒŽü–Ÿ?€:ŽÝ9èž·âš«®»¶´§t¸×'¨Oúh'¬Í€ÿ:GŠÀ üƒiÑ‘€‚ÐÉ=À·<æ7ÂÄÓÀÞUa©µ;N„ ±Aê¡`¨Yn§a—¸ôCìwÙèòB h·‰.`GA( Õ默Ë«Åcœ±ÆPðJY Ç8&$ @}¤ñÈZE‰ Êp¬ùPÊ&(õ­E T„ð  °ZhUpŽC pŽ9)z§”æl´g­ªå6©Hâ¥É7Ãtü¬W7!PŽ\1D`tZ²f‘¾o*½±Ûo÷ÂÓTàáE <—Ãɤ@(I8_eA‘¤ÃÚ h§@j 0ÀÓÀÀÿ@VŸPÅžEHÃËÕ¼Êa°Cï,±µZS—Z Tþ€„ð‹Àájï%zÖŸ¨Ö3½±§ÜÇ#Ÿ¼òwòµ¼óÏC½ôÓ[Ü<õ×cŸ½öÛsŸŒõ݃¾øã“Oþ÷壟¾ú볯ëùíÿüóÓ_¿ý÷㟿þûóß¿ÿÿ0€  hÀ"0 \ èÀB0‚œ +hÁ b0ƒÜ ;èÁ‚0„"! K脞mgP&\! [¨½t& ür! kh÷ÉP68Ý {èÃÒi‡"À‹hÄ#ˆˆ\R!›èÄ'ºd”ÙÁ(£Ž*^@_PÜ"ÿ»è‹NøÎ"3ìˆÊhÆ3–Q @Ñ(ˆ6¶17p<£0Ç2ÚQŽwT@ñ8Ç7îñvÜ# ÷¨Æ@ö1z¼c"¹È?~‘„ã! IEz1“ìÄ&(W8&\"Œ!„([Ê0Î`=¢“CD9€îˆRë ã+Oé»2Œ¦åAré»´’–° #+yùJ¨’=rð¥èvÉK\òÒ™¢ä¡&«éÀ4pijâåGlPÊT<™¼”¥1‡é;9HË•àœf ¢¹NT¶ó›ÁôÝ1“¹rªSœ±Œ§.ßyK~þÒŸ¢£¦5 Š@ˆ4c?](Cšš|C/(E»Øÿ˜Ç˜@2‹pLÅ–€€~´Œl ©C:RŒ”I)QŠÒxˆ´¥ mie Ò—¦q &uéMû(Sœºô!<ýéGK:Ô“ªT91 )OKzÓ¡òñ;;EjRºTøÔ¦;Í K©ZS¤¾”‚¸iJczȲu¬ViEÛú?{.¥£4°å@ÚL²'•ãÀƒªÚ 0 õ"è8Ù< ‡whÿmDg=|!j“¾'íA Oá_ø!fjû«Šxi|5iá$¶Áÿ¬&öüæ»)%@ÙHTŸ<õI ä’¢,ÁSXÄ,àñŒù­×EA†FU†ePAñØJà©P'È™ûÅìžü‰H¤˜Èç‰]T hôŸóñŠÀ´F_àCXÀî0‹… Bm졤ÆjÜ`«Õžž—dY„\W| _-ž Å_ ªÃ?ôÞ‰“8ÝZ@^dƒ6À„\^@óÇX(ñˆç`«BÛÍURà"áy}W N‚Û½PaîÁŸ tã)ò=^ B‘ÜÆ­qÙÿµœ JT'äà\¡ˆ dáבœ–” ÜTà¦s9—ðá¤ÿÀ€Å%¢8é^ [ÖõH£”̳ÕÜ"<¡ÿiA' ßo0L T¢•”.NE‘Ðz˜ž„|"(ž—sm@.v`ú=a¢°@€à¬âûI"ïÁÁÄA kF¶l r`€‡`¢"B%¢x½À#jÁÁ¤^6$À& 0²I¸ŒËõ £âq` ê#rK¾í›˜‘ €9ãye. _錀Ë`›ŽD¶"!@ÄÀÈHÔ²Q_Í`É(€µUÄΦ\tÍ| ;!0ž ›ÜLÎ$L“!À8ÌÊ,É]ARAHˆN.¤u}"BA)² å\À¡1œ8ÄEÊÿŸ@¨5Z0Î=Nɀؑñ%”Àr§oz'˜Á†ÿPH„ËG1@߬€T€]„Ä¡ L¾übçÁÀÆç¸§]}" øÂmvQlbè'í€Q†…ðHÅòmœÒEh™YNf-…šb‹á ßZàTÎ@œ†6Æ©(t(nNWVÑŽÞj&bÒÀºÜÃñ½@Åù‡5ÚÝŠP¬Q­aÑ’j†n~Ÿ¹ÙG(©Y„µíäTÜfB¶ ~–9T…’T›Uì$t €Ð¨Ã˜Ã9@(íå•ÒÀ%<œ Tœ‰*T H–6PÀS`è'€Ÿ!ˆvŒ4t‹vœf‚›¾é††‰’dÿªmj|g*$šîh€å ¨t²\µ¬A6t]²4ÀÔ(Z:ª$Ì'l¥h¨v~‡ °Ì Ö¦õ)I²BA‡Ъ^X²­Œ\}¾$ Á †òˆº € þ*þ`3dÁ¤>A6@ 5hg0+Þ¨b‡’Àë´ò¦-u2dÔãë¥\|j0GʇvÅ8ð( ÐṺìÖï1ºÐÎRØG£`€¸,„|(è¤êiØ'.~¬ŠRk­†k<\áÐcÂ4€Q e€Qè ²N kJ”Äþùõì6Q(ÃìÀ" ß(KÀZx© 8ÿ©H«Évb½)ÅÒ.ÁÊrÐ4êŠ-öF6¨¾% ˆªÏÒf”[RÆ?Vèv‚FLÅßì‚éÑ$ÍE -Éîkï|Ò¦ùõ¥Ön”ËHhÑ©q…¾4Š  Ø»¡­ÿ(¡ñÄáDšSÞ)n0x!¥d¤ZPèæ …ï„dÝ rÏhÝÐè"PÀéHŸð ÉHµY;UDP¤]À ]tÞtRš‹Þ¬À¨R´sii­]ÀÙ32kLE hžÊŠZ…UôìHÀœÒ®ºEž › ðŒÏH®K~äP<µô¦ ¸tÿTA/ûÞF¶*E"`n›©8íä°Á§›E w¿aT/…¾P7T<ͤ(sÏiÿ³MÀ’¥pt?®©Ãp(€ŠvoÊJ¯@,@9Dãõ¡C€À\쀈›”I4ÌLè®S™j‘ìåËDoz[wd‰Í’ºi€vWkŒÌM÷ÚÂE]‚gÀ‚oAêkI=–£î8-Š<Ž Îâóñòn„µvlÃ×ÝCX@Ìé38ÛwØÃ8ǽ8Ë2?²OF2J‚+ \ï8ÌD t8àÃì7€fù Yéq?€ ÓÁóŽè½¬‹‚Ø@Q+ÇœŸÈ ¨{zÈ-•[„ äëÔF;¸LJ´×Íÿ¬Û KÈQÀ,L%ÎÐ  » ¥¾·•Ãá;ô‘YÍ€Q¸†ô-EõñŸ0ZŸ\˜[qw´q>¸†ÒhàSb˜<€¹™J†þ`3É™Œ!~®`C»I€‚~Dæ÷ù-hӨ U|Ú_t%'< °næÀÆ*…}ðHmb‡\ Ÿ\`xÙ‘^¼°[ı/AHÜGD´8ûÙúSÐv±@ˆ’AÁqÉáØÁ|WHÿ>å+ž DÀ\àì3 A”∦S¶î ÇòL×öçúÎ÷ï°ÈƒK1R”#Äë¤[ÄF)°žT)Ö/(+8¯Èªe¾ˆŽ–øP>N0B^â[t3à`ÖæBdÔ‚åÂ`#2ðâ#YcPPc8ƒp1rñ ‘!Já‚E(ÓÈÕ¤Ã@0ñ!AT±S©³yYÂ@ð0éó -=M]]61•€Mt ‰“q—³uè¢g½4îVTbç_rÐìeœ7îÒ77’0 ÀqˆÐÀ®;DIJ$ ħ¡W²TTÒφ¤„-ìÿq1¨Å0käðÇ‹«:ûYðäß ;p˜ Hø‰¡"ZÆt֢Ѱ˜glêD£É ;Ì w¬…†¬05#׌#€X(@ nŽ_Á,µ(µeÌŠ| 7®\¶^¡XtƒB 8`w!¡^¾éþp´sH½^dQrÔ‘-#™þvνŒ9sA;0‡,t(±Á§\AšR¢ÊÅÊxipž!æ#ª-^¾ý%H9P¾ì±³Œå•.-ª¤Ó?­%µŽè€0«@e­¡4nÒk“—0³'s¯c4ºùb¤Ø¦_p–Ó ½Á…W׌?¿~¢‡5ª¿ÿ=à ×1=y7Ï-ÆRbr0V‘=%¬•@ ï½PŒ[lìÇa‡¶ðÇWÊ!#É–à€©¥XœF› !.5FJjCDº‰$nN´Ç….dƒ!¢üè¢I¥•XB{²Ž Ç©øÂš v€ÈÀàni°V–4l(c3"¶PAð‘HRfa¤9Ôw’ù1܇zî9Ð%‡$ôrÛW• àdª£ œéf”/ˆá šØ&Š^uÏ–µ ·ÖAÊg©û-P@¤æÐݘŸÈ"ÉÔ‰i}¨MÉ‹Þ2ê ­Òˆ"¦ö¸òÕZuÆfc b èÿÊ'|eFt%$Ä1Ø™eK±ª-pe3÷ÁP •2dÛ.T‚Üd¯nN¨½º ‚UHïëý™*¤fÈ©éÃf€Œ®jj ۨ>ÏåpÜDÀ س)+i"*å/aq ‚Jêbï<(Çq bÀDà«ON4Ìp›npH °ÁÂ>ã'λ;(“gNÅ â^ÁªÇ+RaQ’lú@Î;÷ŒHÑ1 »›„#m03=Àõlïc>!óVØbÕ¹WÏVØ‚×q_^k‰@­÷ŒK”È%  ƒÌìÀDØkÇ@b@Õ aÿùV;×I´Ð:a`EgÚBФ•À®Z˜8 A€D@„ÁÙþsDÑè5‚ã(Øäj·‚uÞJ΀.¥BéÉ–Ê€ÚÂ'&ÌšªÇE—vðu­©{ú™ =bΠ5ÒÄ%BU·êšä"å73Õè?…¥ìÈNB@ÿÔö¤’Õ¨kùj"@?¨íâËÓl<õ¿¨€]‹xçÜ…‚Cp•±AÐH±ðƒ´°…òÔt{5zŽ@Sö7þÏ}5>Fžì ,£‘ÁZø7 f|(xÀZp7¾<‚ê«¢©|·$€ù€ÿÀÂ"€sÐ#­Ñ  @/FÌ“Ašì"‡êeÃ@ø€ˆÀ{šêâÀ›À@  ] `„Yq‘=èÉo®6ÆIsèb.@ÒܪEøsÈð2Dv m|Cª¢)Œd@%ÙÈ#T:€vxT€Öƒ?F œ‚ÁqH¸À±Òò“N°VÐÒ+B¡Ž h6’hˆ‹„0'°€ÐÃ^¨+€6€$BÒ΢ü)màPþ± =!Ô Ø'd€€¤@AlÒìN/°À8ÄÈ€ t —i&AZª4™+}åÊÚhÐXn¢ÿp%B¢Ð‹jt£íè Ž3MŠ´ fp§úJú³Î)¤qS$ *a­‘Z¥2­©Moº'"ì:NêàZñ!‰Zª0`jËzÂN‰£5‡8@J¡"«\íªW©áŠüsˆ_-«Yç­ˆâ" ë?ƒ…Ïà¹ô¬t­«]ï:Š=à›WÅ«_ÿŠN ¸ì‹ÙL×'ù ƒµ °Œm¬c ÙÈJv²”­¬e/‹ÙÌjv³œí¬g? ÚЊv´¤-­iO‹ÚÔªvµ¬m­k_ ÛØÊv¶´­­mo‹ÛÜêv·¼í­o Üà w¸£ê4Ž”.Ìí›x_ÿºT&i7}Pá“È*¤1x?ÍD°àS€0”#@ @¼›íjïgÆ=mÙ¨‘Ã{ìíír3X `A…Wr. [+M3Ú¤e&}P]¸Â¿äÀÀ8/G\×M¶H€7ns€ ¼Œ>u@¦’€V&sÎýƒ]ø¨©B:. XÕ¦È×ËDÕ–üâVwÇ!ºb¸7s€F,\ UA¯ , Î p˜K¾ð ¼ÜØ `-g—„8€¢ ìs껃hÚe®ÏH§ã€J¿fG´ ¡ÔÌï!ÀÁ|_‰]~p¹RÖŠ¢²‰<Ÿë‘Ï(ÀÂÿ[½,×ib°€HIwÀi@´R`Q$ X«£ö ɽ@ˆ9 Gë´³ó¡`=m®ËKЀh–ŽäG]ê7àÁ˜p7ïºPP—,¢Í¯ð©@ ;¨ ¦ƒ».‚W›º¨ìJÁ’=$@DÐN;h˜‚m¿ ˆÒ3Ð#bOp|Ÿº 2Ê.ÎU·y]0á4.x(h[?Ib2z ŠÖAsç"`JÇE±,ø›™x°éÞB>ìÐËŠš¸ ¼ñ'>˜Š96ÆŽˆÕ10>4þé{äƒ#sc fÏ©‹`Dþ ¡¼TË#°ßÀŸáA¸Gà Ò 0#‚î0ç)j¶¶xlÿ"jŠñœÁwf†0K9´4Cr{ÓÂO[w¹æ‘PŽ#pp¢çm\¢K6gAœÈçâPVöP¡vd *‡o€ {´à`áãcêW=ñ?Bd»°XÂaÕQ~/ ²!Z´‰÷Jð‚5 ²8@0|¼w.£O0 :#qDå|)ò¼v0G÷Æv#xfüu»×løÄc…uØ¡¦ >áA¬ þÕ#~·\£Q€ p€ßR`HØô0/&Ú§gá3P ÑH>U˜4¯ò,4°„VM0@w2à$Fˆƒb¤‚¿æ ÿ ÐckÕc^ÔcÑÒÄoøðÉ à<ŽÄ<®Oô3§Çò$УÙÖ @´èŽDƒØr•¨x#€@§Öô`hÍ` !Õ0‘„Ða¸¦„µ¦xð2Þ¸¦X0æxo¢{ &ÇÓ†—°2~“‘tLÖ3ì~øŠÒkÐ#<°…p(É2 $Ä! 9а\$‡¶ l.j¬èÐ4é:™X%º _—Œ 9‰¤q‡- *4%»ÑÀ÷z¡55ãB±l¶0ê‡-t£j™òlÀö<•'s8÷H )c8÷'aÈAÿuQÙ1kòn\ h%±Jð“u‚ÈÀO.p_Y'“éò8Z-h]ZÁ63£kÈHðÔ@Ä0ŸAjG9ÿ†ŽÀ莰v@àh­(ÇB10”[Ñ4r}0@’c÷%'°J@H—Ô&˜¾h—ôÛ$:¢€G¢FÀ<VÀS ãû÷ 0ª²““4€,(t—— ´BÀó´NDÑš¥Q;Q!þ”C&–—G,šrk‘°öƒ pìfà2$¦‘Œ"!¶@•™jub°TÁäv⑉’™&@(™#vÿiñKK#qy%pˆ6Л5 xg$×6 à$N³·É8ŽÃ AA09ÉnæÐ•ù‚;Âb‰c9š¼r9„ù_$aiÇè– ŒÏàŸ 2Nðƒ3`dbSNR{ÇA(õn8 úJ,´˜1™·á$á6eÒ“ÍatC(u¸|úŽ`ÂÓ ¤ÑÉ…Ð0R¹‹òŽ”ˆ@vwçQˆPÑKƒòŠí¢¥¤ •àDkê›styüh@¡·Ÿui÷¹$Ú’j\R^¹Pz’üfH kDÀ_ÝÇ™~À-»’®Àr)PJ C;za„$÷AÊaj ÿ§ã2•=> ¨£6–ÅÐr´(a¹©0ÑT-%@õªsëL)­-wÈ´òú#L°&•À±ô¥$³x{²èª1«šh©+ò#gø|$z2³ÿ)*ÂÚ8Hᯕ´V)ôP{M¨xöЬÚD^)ðj*zªÒºhç!¤²úlƒÜÉ:®£°¶4ægHÔB´ ~Ó8–YÚ) a1B·AyÆT5Òv™–Ìf4Vµ(¯Áƒî€»oô? Ç±CŠ&W1CÀôSê²ΨÕ °› b(¥·sJ¦0 ø›iŽ Éº‹!¡0Np 2€·Y•±¶{Lߨ©Pj¶-° ‡Ëv^ª³ ØW­ø.X­ú•<’‹EKMïR>`ú Bá´ÖТãfbóE·x¬ç Ø_šK°VÿRd ¨ –¢Ò”Ár‡!«@€"f”«-×i1¿ƒ®qÈ‚GÄm2©(‚  êêbÛH;"%М ¬á*ážP A¹,Û§”SÁ=Ñì¢rÅ‹ƒäá§-,K¹’‰09á40ຼ@ÚÎûÌjàì*ÈQ™Šã(7áyÎÌsÒ9`–å•´ï\éÉ–kÖ%—=Àpš9á oï뇰Ýë_ŠãxYÍegv-¨&eñŸSJ®°¢8Öb©$74ÀÞ¿ÿ?À€,hð „ 2lèð!Ĉ'R¬hÑÑ… .ÿrpäÁ) $€³ ÒŒ\"IvlÙê ¸Ê¸qÍ[@X F’ƒ}\úúANM+AaprMСJRâZº † $0ì$ÚP&M"‹´*0AêÔh=‰,P‰@€^}1˜cÌJ¸ý´`Y3påš¡z«ÂÈ«N\$è:7áXp×Ö2 ªm¥1„Ë»—åªÁk,ײš*™&áÌp2 ¼H{âÀ÷m\×Y|n%º°Z•‰S °FÝ e@ÖÑ :ìDàä'ÄSÈtq3†í9.'r`%À…:c¬ÏÙfo¨ßÑÝ}€Ÿ–°P`ÿP De5`Á±@!(,ÐZ dô C´’pá÷Æ üõv1å1€ "G ¸ƒ0…Üá—{j@€*â@WPð] d0‡‡%bf%@€Ž”Œ±âð)7Ðhù„–h¢!c°ÐÞR1Àq+üd€X$¸ÉÂnÊé_#M±  P€›¬i §œÄ`ǘ-D€gsmfàÄHÐ&ûõÇE ,öœ@°å! –(;¡#`˜Â“²¶j Èù “ºywd¶À©G-(8@S+‚†^f®“žÿ# ÈyÞ„JP)+I" X` RµñD{Ûaš(°Ã¥ ©D˜áip°¶™ƒn\9ž3ª«Èƒ 80c$Р·¡@«•aØmŒ WA ø†m}…AÁbj¸Æð[–À(N`€§0 … Bë}@+§P%šf…×k  `4À€†6»þ‰Z+# b;†Ÿ(4uòƹ¬ˆü\ì‹ UœÍ¡VFÃDó;*ŠrÄå_áQÆ®Êf4@c÷ÀóÔT¬9‚ZÀp €mäÃÁ£µ b°Â±d"žeÿ(uÇÀßÇ ³°xA)CrÄ Ël\ "]ЀáMc*¹}¼™Ñ¯r$±Š{.°"v€ @Fkµu §E6 "ÝÞˆÚh±žj7ÇÂwÇ^pÒÐcŽBª§ úߟÀr—ê-küªêˆmÂë}^ $œkpî0ÿŽè%B9"sw¾ƒñî§9Î59ØÂRpÀCØádC Ü÷€1H, ‘ƒƒå2·$ Ì);°ƒ° q¬§È/,ü)Öž‡ÖÈOÝqDS*¨À}P‚) ³@(£äM&ËÛÁP€åSþ ºCÄóÙƒ?:ñ ij}@lAQÿÐ838!nE ˆ1 R`íicX¨‚š¬™@–h'DÀV”˜e=-ðff@ÎYð€g¹ |+€ÓƒB9`èAx+ìØàÁ5¨‡Œç@–ÔÀËŸ»âªÔtEЈ„D„¼£ì0Aà à$Jd"@ È½ä4‚V3B^ Þxˆ-jp8cL`Ó(Á‘‚h“…Ò¸=J%“1°Z @ûuÄ^“Œbòc?†!ƒ±³×Fü‡bö/gˆ@ý0Â0 o…ˬQ3Û¨ˆëÀáLJ òÄ—:s9rF “ c 6MÂòèœÀ&`Fô\@wŠB'1Ø-ÿC¤Óq^–ôjòï™, D 8Àw®1žÿ+œ0Àdq"â|hö bE3¼°›©\ƒ>Ïe.E°ü±@Nj¶“’$µ$O:OmÊô‡:uQNQÐ>VíôþÃNq Ê3Έ pƒôàÐ' aupàeZ.Z¹±…¡£T•¡/Ñ’bO©;@€†äQ"ÂzNpÝë$ŠÂozµFØId#Úà9ൠ!OQ¡õ2Îd'yÓxæ’±2>I‘‘N>ÈEZÕÇÜÈ&<"w‰  <å½ •™™èÎâÈ™“A¤Q›klhÉ5yfŽšKXi:ƒ¼ÿð‚:Û¬aWvMèˆ@V²cý±sºrµ(&‰‹ˆ)}-v(kšWж1¨Òiù±Úx7T4ÚA@v&œîw¨¨Xã_HàV G0m h¡Q9¦)ɽát5Ä(ÐyV (ÀGçÛ†-x’©ŠÀ?¹9à 'Ø ‹Ûƒ®·;"B&˜kÑД٢ ²ap0x-+ÞC4O ŠÞ*l½ óî¿6œa.œáG¨í8Ô‹ï>tZŽis€ïô7HOÀVm£&&âÓ¼jBØjªpxmc”‡­ €¬;@{…±86k  ó>à ZéëbÿMiЇ ÑÖOÄJÈãWÐ2ü¬«RÑŒ†6G´ç&+,T¸9ǤUv§Ö.6iôi “W٥阖YI@€"5ACblüe+”õ¶Abz‚w Ì+¸¬ ŽA=!xÀ©•©pa‹]¸6¼uƒ4xs‹™Àµ¤€Å´ 8zŽæ¼ð=‚Û“ Ñcjå…d)å´8G h¼2™Î¸qq«\Š4„…ð¤'©P`RpÂl•Üu³ R –©¡v@AQ=öb€–â4˜ hÿÂÔïir„A~Xë œç «ªë6 =2«Ň¡n†Mh÷FP¢Ëú,¥6 AÔj^C¢U¸B’Àñˆæ OÇvWsÝonXÁ“, I<Œ€ºµòLÕ0v‹— ûú}‘òGðè °Ÿ0n¤nŽHIUmŽJG`—­)Á–jŸ!DP§ç¼õ®=ìc/ûÙÓ¾ö¶¿=îs¯ûÝó¾÷¾ÿ=ðƒ/üá¿øÆ?>ò“¯üå3¿ùÎ>ô£/ýéS¿úÖ¿>ö³¯ýís¿ûÞÿ>øÃ/þñ“¿ü®_) 2PŒÃg"Ìæ?ü;“$ÎdqÿÔO ö§H(ˆp?,5ÀØÀ“œÞ¤ÞVV@˜ @4 P–eY@­@ È$ÈL@Ú…—{DR¬!Q|@F–ؑ ²^ü¹†LÜEdt‰¬ßç)B%í€xMÎ5À¨¸€¼é ãÝœÔK (].Ͳš{¸ÎÑÌÆÑ8Þ[ ¹G™,A2U [ † æ >Ü!Üàì5EmNÖ°à9¥F¡ÆÂ !à“ÅÀµA€€ ÐÜø<ô¡$Eá $b"’™L¬Ô@8"€8 ÀœÎ8@2Ôמ2ÇŠÿá.¸• ÕìNK…AqlÁšÑ!²ÄÀHa d¨ák¡vÕÌøÎE@d“}iaÀ€Ø'Æs8$Dzp… †þ…RÌp@Þ<á ÀÖÍhÅþH7u€“@ 瞘¢DÍÈšÌýØÆ`À:€àÈÀI®€®šA Å€k1y½ÖTL”›MÖk­×!ÚNä1‚lÆKU‚žÝ@,Žc€˜c l…&c7dÉ–ÀxÉüàFÓ˜P†4®¢  ,J xŠ<â¤p Íž,†PLöIo‘Kâ ÆIÿ °ÉUî4Ü µ4ˆŒÊ䤎ÛåIU±—"ŒÖ¹È™ÌUq‘B"k çÑ[ṵ́@ÁÝ£´ˆ%ðà˜ð‰æˆEQÞË,ÆVšJ¶âG.&Y€lM¿ÈâÔ¤PÌP`ŒH»<€(À ÈŒfRÚϱÈG±Í±<ÎéPÀÙК@¢"ãü¤TÝ¢ !­|­l€ËÀÌÚE#ЊÒ€Ñè¦!¤eÝ(!UqHºÑQá¢!(䔉ŠäC®ÔP@ŒÁ d•ÎÔ…cN%jjÙ3v¥òôAÝ@c ¨ÍfTNÜDÉð]a®߸Ñ?*Œn¢ÿÆ´¡dVaÆÖ—Žr¦€x¢‘%a÷L¥i!‡R•C¶æ;Î"(<YŽé¬@W†ÃW2»L(ÑqLîÎ Ï@9Mb¨ÍFð¦e€¹ÀLÛG¤ŠONú 'Ý…vÞÕ¨\‰Aj æ6oÁk4„ÆKhR¶Åg9¤ÏôLã"èÖû%”0¦€§ðʃTkägìÔ§ŒüPz‰$á-º&âLÒ±(H<…D”§xé;Ñ’aDnØÒF°€œ>—Zýul9ÒIØ…ÌZ†ú!6!M^Î @Pâbì„^&AŽÖWƤtdÂ#Ìÿ˜`õP€´fƒ2é: Áy×B&€üÛL¥À~vSÎÁ ³S5…TÌ0=Á³ “-­ÑaÕ`"˜iBÚÏ:ùåS´ipM€8 ¤5DEz7NAä!Â*µÒŸ&l!À·éÀ*ÂsÒ jʪ EȄŠHϲ֥ÎÜ!`Ìt!ºâ{ØY[ë«¢’np¢ª;ÈR„¢)"Ø~Há š1ÕÑœt6 Í`’ªJØP•½‚nNÖ°æ™>h³NÒu¡€5µ¢@°hHc1¢E‰†Úç©h”ë!x …v¤ ¦@ªüÌü‹º,>ŽžtÅ©À èÈôÿ~B\ì;TB-TC9T"xÊ©.j•R–™¬ÄÅB'*,”nipê&ÿ!È&«Øa8«v±ÖEVÁèh_ž-Ëæhi)£­h½jÖPW_ªÎ6¥ÒüD¦®Aª<‡#]N*bE*â-J@Lb |îŽ 'ŸðøP€&*®ÂMäÐØ2!UTe“§®¨.Èy®¼ò­rŒp\{RZ œ±9PÙïÚâæÂ[ PSiÞ€¾Ê^’ùêI¼í@4±Ûöú嘜QŒ°œµÜ®È-ƵEs³’>> YÀ#ýFòì6̽•\¾ÕÆz±òj¶}2‘ᤸ”ؤ³Œj.ðàGrÁ\9kxð(ðòôX¡—[¸àM²Ûä$œÌ¦¯Œ 5“CöÊÁ +ÂÏBS4¢_~þEÉm·2ÓqãZ0€ß]Á4ýQè‘€-÷Јÿž±&B¿°› {(Ýü2«~ö36hAnÞ­/@têˆ# oä^xÚLIA<´xÜš|¨ ×øZcµiõÛÇ<@ Î4¶T@IIW¢€c€V€ãè-I M¯tAÅ)dO6eÄU6fgö¼y°fw¶gÃd¶h6:ÐÊž’6j§¶j¯6k·¶k¿6lǶlÏ6m×¶mß6nç¶nï6o÷¶oÿ6p·p·'ˆ/qÿÞƒœ¶B`'GÌX$COÀ¤¨•ŸšQFBb' YƒQcœ,[­$&ºn=i ZS#®Þv3 3`šƒí\ÿ2/ÈEùÆà1¨#†ùé%Ô[.t ¦UŸÉq[%ä}˜xŒô#x:ïc4˜x¤ó1¤ŠxãD)ÃPYDrµ0¤í'šáFà-/ÂØ¨°o)Ï¡öèà«a³q¨¬€ÅÁô:)ߌ£ÀŠ'kŒòGù8ÂC¬À×B^,9/ÈA D(–1ð÷'ª"€Ú¸fI¬kÇj“í BBªÄw)9¹—G .…y³üxÆ<1ø"bðŠ/à˜2$yîFÄ2Ž0÷È µw6µ{Û–ŽAdêÎHXÁÈäPq++%@D1 “åÂ^þ$weóŠðÿ¤ˆâî d½t"4Åã:Bµ_)BñŠ¥¨WˆÿjNkkQÛ51V\÷H€¸Ác;­øWFIx*«îHIV¨`ˆã$<-#ŒQ ¤Êöûräâxˆ >Àž"AdÉ ò›7–hIF0”K†¨e‘Ü`ŃDO2‹Ç¨ùŸÈ‰ HK'Ê£°j^àdÖœ\Q)”e²"$å7±^ ïYš³&|1‹††O_Öí",|t%$ijq åª³:™¤Q¦‹ëÀ¹›ï.B\ޤVòåD±kbši ¦PR»?‚´óìûÌÊ£‘}è Ø9×½Z²í€s=„‹ÿdžTªqïžœ€jμ?‚•8¿‹˜lDªPH¾0¦¿4¸k|"P¼on´ZùO8ÙÞÂÚqa§ÚC#K” Ô¥ @4ÅÖÂÞ6GtèïjÓpÊ«‡çßk¹Q}¦Ï„¦Ý¯ÍG4ß„ÛÁg"ØÎ¨Èdš§‰zb˜³%ÁÏê"Œ•ˆ‚mð µïF'‘æ7‡ 2Ð 4×åNཱིã.ØÄ|˜.¾Nƒ˜òsÊÔ;‰×ØÕ/å—Ï]ï*÷¼ˆ=[æFÝè"Э„›»Š¢Òaÿú¼¬#þ˜;8ÎI<ÏΉŠÌ‚?H¼ÿ,÷?™Ì."§B(’*)$€ÀH@išT°œliCsfÁq^Óî|ož°Ä Xä”Z 1F#h®†a «íz¿à°xLæMbD Cî ÃLz= Y“⪠ÿàZnN'/A/.kD#-re‘’“”•–Z e 5W:W`jx W /œ)G"*iX©u­¯c‰dsSra)p³+¶%§»‡W¯ËÍ·b¥=/h„T7Ÿ–P¸;ëZ&§¾àâ—8øbEG'IKL¸r'ωk,®`ðâiߥ‡#>TcØ 0ðlÿ‘Ãæ=Oì ÐgÌŸ.P.*2T()HxABMp†$êÜɳ§NO6 ( ƒ”).¬èóMš 8uƒ– €¤K’'oØœè@¦Ì)¨R½U͂՚«¦pÎF­¥ ¥Óvü¡fß™uJŒ4H‰@€…<€f ƒÇ%ä@@¼”€U)#ÇŸ €'c`¼ãÔ›lfy0œ]}ÊžÍÓb‰$:Æ4ŒåÄ.ƒ¬óñã4-/:¶Ì%,”ªçW„ÑžN½ºOp*ý"ÉP:ž°û c%ÅLÙLFq Ò½@™l‚¼K«ç‡˜ßÿÂb0 8Ã4VÂ,Ð=רG–P¨ÁéÍ£<¨ÊNŠ‘ôƒ„,D…æ$ø\n&pÑ<X'ãŒ/N0' ØxTÈkÕUÂo á'Üw&7„ -$·’KÂØ¢TVi¥öy䢻8äÞLÐvCng—cH z%¾†b²@&»°XšpŽ™Žz(ž6JöÀ`%)°Ãƒ „uÅõ”`˜ j”#EŸªÐ'9>òè~$"—ÉTøÒÊZi±Û•¨ZªŠªTØ8Sò ŸUù\U®~q’qÙ½Ùrjã`ªÄ‹*)ÿ6ª±'À `0ËBžc“ëQF–à_ÑN‹¬×†yæ QKF³àóC|< vIž Ñ€P‡µL""ºƒí–aXvaìŠB§‰Ýñß C”:Äv+±N©3Ńb Ûƒxw‚'v²™¤¥gŽrnËȳ·ìòNÄH Yeb·÷Æ\,à,F ÿu²'w8¤…yмÅó >#í–²ct3ÈÎBXk 1ðñCN&4Pó00 5 ð`¼C\í…ÂÂýòÜkv*BØ_CØ&|°Í ˜ €aHŠ Ë=4Ñä"Ö¢rU±u½-Ý”ÿϘIP{€ÛCâ@°€·1¾œb'<†¦°A~JW…÷Ñr‹‘D&ļmèõž€:¬~në¦ë.d Y“!õ àøÍ "$Ðèä]œ’i\Ä9-LüÕ-i+j;â&xaN¯lì-¬WùúdÜ]Â…aØ4ÆÀÉAEúÛ)‚XtZ¨ 7„V¼î)YÊŒ¾]á%AÀp@öY°'¶èVÆ` ¤`P›E³Lp%dbЀômÁÈ‚R8äŽlw @p‡ðm]úz` _(<‚†¿c¡ E1†  Kì–1(ð X`Bÿ¾ñDrs¯â}áV' 0Ãá™ ‚3_ŽyA`ƒ×ŒÀ‰ö0Œ ãbµ9 @tÕÓNë„Я R ¡èCÅ$Ñ\Á[Ap°*µ)’ªP ‡àÈ Dà±¢ÀL$à‰ ¨1Nj”xw ¬ª‚‡Œ¥%éF04Ð1Zd®¢Ò€ TÎk‰T>`ò‘™³—'jù‹=`z?”VÉ ¾>>'˜m¢&6„Éðýà X•JÉp‚3 ÜA€Égò—Pã&1É ™J è €ƺñHP¹“ålç´’)`R]í\ ÝÚ"·»à ¯xÇ;1<‘ž8€ÁtÉ;–½¶-$|çKßúÚ—JIÀFïËßþú÷¿°€LàøÀN°‚Ìà;øÁް„'Lá [øÂΰ†7Ìá{øÃ ±ˆGLâ›øÄ(N±ŠWÌâ»øÅ0ޱŒg Œ@B„3N•-Ö‰^V›•†Yåªdf§"n8±€Ç–@TQ©Tc!HY8^0\296$›V/(a·<¥Àd˜w„„£à ä*q /ΡáL%Ã<—Á/ðÇûÿ²8îÄ`©bÀ¬[Dg ˆ &2à&1GÓò€œÐÁf$J+bØX'YŽ¥&-†LÀÒÓ9mBªå\xÐŽšóÄ4 k8šr·«Œ `t½©ÄÖÈPB"‘ SøtDˆäŒ*–ÃÍg €"ËæÙÄâô… “‡ŠVÎÐ:)©é–k0ìzÁÙ°Dh W*F"„æ ³W é ªžÍ¹­$†NØÛ¹ø²ÊN„í©MÜX„ë—0E i£`ÐzB>šY‚œ¬*Aþö‚Ã0¡<ä{»xE¯ÐT;4ä`)_êwÆ9x•Š Nwf ןÿ5‚iù"ƒœ•U6NQåL«ÀÊÌb´·ê¨ NRSž¿×„SËP8v`úâ:6ÑŠ.ý6Á锽\2 ‘‰-÷ÌÎp«×J˜B‚VX”ɼ݈QAM ¢š²S%YOâ€Tô çÁ5@ÊNœÓk§Ò’̼€ xž÷DR/°v”; "Œb`IÜÁßøN“Á¤æ4BᆢS(p-Z¾(ÀM*Ó—¾\ª¨è<³ÌCaO÷±ð3@IÔH`„2gKŽoª‚vÆ)%ba Ô6ь؃úvÐvüÕn@=2w0oD]ÿ?33ÂüTqtè´g(ú#û3vðq«` à*wY^°8à³6ú†Ò~#e'&LPów,`ÇWðÀ"â–xÐ €g?V`(h¤}ñ°X€Kª ÚB›WïaD¦"ñ¦ó“V%À`§ CàAêårÐ}`LAçzµ8øã¡P/ @.iy' w’à P Pƒ`Á5uiw'㣛Âúƒ"‡@Ç× P \g&¶•A¨ÖäG ˜"GFÁ 2€&b _âc)/`Y¿S iplµÃ8;p+»{AAK˜ƒ¤Ò¤@i`ÿˆc °à€÷Óðo@# j2 uÆEÀN!¾POæÐ‰ÐÂK2 {Å‚'x0d‚0€‰ €‹‹cmM"¨8$³p>o0O†1—­ÈqS‚iäƒøȶ%Cb P/à€1w?À'@kÌ {wPä†a]åÆWà€ýÆn„ž&Ñs4Bé>¼Ãh«Å‡„²†ÓšÃ¡@"#4Àg§P!Ýð4ÁÃõ7‰Ý"u»$m&à iˆm]Piȱ(“3l]n"ŵ,& ‡pǃ3x’ýבZr“ÂŒÜ8‚öp“·(¹8ÿ¼ØĘ.µ&\Ã’; I2°Ê6P0nȳ}8¯—""ÉLcÓ3;ÉZÁ@ pYù‘›hÂ0\ŒÈ‘sVe>ð†ç²ƒ)B0™[™° é•a)fÆÒ@ ¬à[BAHBêÒƒNà ÛX!Ù÷W8ëÈÙ!ŒC Ñ S6(ªõn•Y³ø…Ïk!8”{cþæ™%Ð ñ暌ÀŽƒÓ*Ù"ào"ui¥RšnèE ¦•lÈ]CÀ…<@$¬c 8”¹nZ”´×žr@`ØcÁ`P³ 2` : žA´•݉w—4>roö‡’°‘…É”ÿqù#SÖ5Ç‹Æð?wN×™™R9"ÅToˆÙe\­@@gI™|¦9óX ©IxmÈ)£ŸŠ b ™"D›ZŒjY=†µ‹uB…â"bÝ¡¸Ea¶qB ^ØeÓ EB$érµD ¬Ò™WÐ-0X†I`p,?lQQYÑr粕Hº²Y@õ6Æù_ðYrÖ‡¥!Ž …aaZ"ÐáB‹)‰ÍVj¡“v¢ûÙe&´Gkñ¶o¡a.KȘCfz£Œ0§S‘¦}Ú”ð.:VF Æh¨ʨó^@kæbJÿq2tvŠ  6‚#:ÂsP˜§.º‰< §#I¦%àŽ’W…þIÐó–_p/`ƒòàuz¨S*zÙ!‡¢ù±¥þÕ¥ôôŸ‚x£†9 Câš3zŽ ’’ˆ™³Z8"òÈêÍé 8w3i©ºY–Çút+i«ƒŠ7åj=j?âЃ½ø®E5"*‚$ʹC§IÓ†q„'ð]?4]!ñ—ô秆€*R“&Àœ('¦ýÙ£"A«PWkœ£ä…yI˜d3?¾ c?Ð) KxéËj£&«€t­ý%­bmÖV£–£øÙ¸1Qðúœådÿ—I…„‘‘rj L©W•‘)ŽÙ’˜Ú&  i+‹„ éi£ ¥ŸF›qê@!z¶ÜØ,=¶k³«APpCŒ ZK=–PSc’Š“,§,@¯€wš(Ç,—Ô®ÞJ­•0G,,ÀŠ9P³nøtÑ»6A`:g# )`)>ãsÍê1 ¨A¹7ÝàoÀ ¥¯©Røw¯hWMj‰Õs {ºšÎç<0ÀªC°n•@©X°È)ì’‚ˆ)¦Wº¼ ¸ŠÓ59I»6j»D9”T›w‚4]‹ˆ¼O ½¶·€Ò³éó©’æx¨‚‹E¥DÇn`W¹ÿ{ f žÐqy¼›¬UU¿,PÙS§ùѹ¯• p˜Bð¹`  U*i6Ú%H¼0ä‘9)»uÙ¡p„“Ôû¶Eׯ>¢‰»Û1ïp= ©ðøZ¨P[Œ,<L¨ÎéŸ\óM•ÃA¹-#QS4P) +ìÀæ>c±‘:DxWxJÈ„²'«>ê±wY¡MlP` Àw0°ëäÛ$PU”G £Wp_qóµ%)‡\\‡YÚ¦µ%~^ª `ÀÇJ¬ÁÀû"ÁPG¨k¤º°Á0µA´}¿XBju®õ?å)@³»†o‹¿y •ÿÿ–æð®;0€cÌ¡`”^k¯›ò¶ri  ¾øˆxÌ®MÆ UBa¦n{®šìZðð¯ËžzŸ8™ÁÙ3¡Š4ËaЂI„A Ôz@Ú±ñ“4`÷I¹gƒÇ´ zšEÙIŸ¡ã Oz˜&¹B ëà _´7=â J- ‰T*ÜwÇ8ûY V$Uzê´S8Nóçt † É÷H̤?ì¤ÅqLápÉ–Z•ôIõ2€ÝÀ •=4ÈÎÇ—…Y|µ‡ŠE½úôªm"”Ì„F % W°%h¡ÆëC³@rP/0}€ˆ-BÌÖ,ÊÏš·ÿ%µP™Q8¤ÈUT€SâZÅ×\„Š"7@J²¾` $£7Ùgœ¶äàX<yÞÑ7ŒÐ$•+…5Ö†s‰e »æž¹¥Çê×ψ¼€–U8 T lElÌ¡‘tdFPW¤ Á…0°Q?ºË>Ô¨h À^ETtqÂ^%dð ‘`Ð*ò !l¸¸t@AUJbw(+šw  U0¬ÔRÚ•Í—8QJGXÚ<æÙ<o96ÜÄ­§k%p$ÒF•c0Â2ÆÜ(N\ÜÔ=b}4ØÔ!)`­ŒNà;cÿ:E œÕ]Þ'†([K,pÔs†´–Þ^ÀÿOVÝR¸ÝCRQ mÞú½ß<ÁóM`Lü5­æUÊžà Îað0J¸àlá^á~ážá¾áÞáþá â">â$^â&~â(žâ*¾â,Þâ.þâ0ã2>ã4^ã6~ã8žã:¾ã¦dÖ°ž<^ `¿º#/åÐxátS#Ú ò®ôu2Ø?k=Bº(Nä\/€ °ÖåóµzÐAhN® †ræÏ¡ˆ´–Kbà9ÅÌE/'æt.l ÌmuÎ^ @`©Èû¼„° Š\|#ÈŠž¸ûÐG§øçPÊUþMøÐ%-Ä ) Çy¾éÿC€çø{µœ.^[È˼­ Xêùí³{¢„Ö%0´Â¡ë<(MjäeyµìHE×x §Ö/£NÞ½›,µtí¹w JD×ká´hîâ:×t·«†Ýe0'Æ ®F)ë²ÞyŸ7z¢çyþ\$Ê÷¬·'1¸*ÁÁ:Á3yåHŽÉgÏˆÙæìôH ®×”ÇÍ)ì}ÌRÀ¨ù x®Ý®F¤îœþƒ bßâjÒ¼ÉvFÎø ã0}”óëv•aЍ¨ŠÿÔ ±!AaÀ<$+ÕïŸ*t¹ýòt‚šHÎl‰“¼Þy[…ݰÒG¼Õ혨ŸçPÿgê²Ê ?L'ý˶É?Ð#Ñ&ñXÊs“ÇU£éîïcàc0°µDðÜ&]&Ð0¦ OQ4· "ÕCÿö%€•¹ð¦ó¼wPw¨§Ù ÀÀ3éª}:ð;À&¾€9“àc˜ØÏ‘]η‰h20Co“ÏrY® íp㑜c÷²Ú´f kÑÊcMšöhD} ðŒ<_—ô0®÷s —Å n`D±?Á™~üø$Ía³ðdØ¿é5Š¡om¢¯É ’^Ëž8À[Ò|îV–ȵ³*2íFNw%æ¶@Þ"ðtž„Ê(<ÄÎ8}Ð ÿ\&®:;Éê¦z#Tª<¢ÄÏCÐ@(%DFYõÒRH´¾ó€hz4„…p <äq d„Ò)µj½b³Ú-·ë¥2€ÓÆÍµsÜRºÅm·Âd/C !‚Óȇî@| "&*.26:Š%ÅŠHD ˆ¬§ªÕ  Ñ€‰m%êi!;;cê ¶z) h›…z3p4ðˆcáÔ$ÝãqKPb c0´Cà$ªôÜ`vN8‘1 QR!Ct$U*<õ>“¹•‘É>ü ¢ w½y¯_Ôû¹Ê°ÁŒÖ È¡/N—OeÁJ—JÂ<¸c"Ð-s%Ø™ ~AÅô&f\ f¶#·X³qÖÁœÑˆ!'›øJÊÿ-AŠ_ yYÙGUú t$Àüc­„h#˜… ·¤Çí‚IDÔ„$ÅÈ í*2W%WC¤¸Ñ`´µVWš¶5tkìXŠzðÔ-!¤­ƒzÛ/Ãi6uc§䢺y³¹ §bç$t p‚¨Âì!(¶É„õˆՙ›A€âæ>fOIë žšmpê,|Õ :>G)_àã%ªù‰N õš3h…n£z¤ÌÏ‘_9´ù 9Ýü‚ô/•MŠm¢r=# аŠfÖ#!ÐDm˜Im«PxqÍW¨+ ¹ð=òäç… ÉßmS“XйXÖÕlsÓàÅk€‚ÿŒw wÿzàé­i¿–V žÀRO†}Ü5àÔ¨JÂ…Vê "ÊÜA뵑ŦÍ„x7ìäP¸Ñ® WѽyÀõ\e1¨ÞÐñ.(û Ì Q¡ @÷ tDÀMó}žˆ ‹FwÅß܉‰Ñà'ÄÅ{ïÈ¢gúx›æA±=^Æ/âþ¦¨¥þ«Ÿ¤ 0Å6oœX™ôÅÏ8}]few=ë›gœs‘W]R(=¨ˆb”.ôí hÜ*2ù-„âÇJ>4˜éuwjñS†á/ä¤u‹ÌŠ׈V WÝ ‚ø~¦§CàÍÿ8é/¸ ÄaÿËO¡¦ÿGêp²¡S,9Ö]PDD‚» Ò¿ìÒB@$4ìÌ‹€y\“ V¸š±AüÆD‚Š| |$y§(x±y”íí@h@¬IÁfÙ Ùt ?=M'!Äœy‡ð•—Ìž÷É„/€M$,^£9‰ô$ ЂÍ}Á¥ÑÅ °üá›ü‘ßF© ‚þÅ`žíß50Õ]]åáÑxÄP$XGDåZy@„ã‘Å =¦î Á| RHWØ_T¼Pð¡SH<ö]Š<[½lÌF˜œÏ=ǾxžIBÊð€T‚+hÅøpßÌyÿÜÑx8C^©Zâ éUÔÔ\#rš²iˆte€+ À•];tÞšé‹z„Òx¼z…a5P]XÞ4DðA…@ŒˆÈÎ À À0À4e ¶P€áP`¸`ÀPÔèÕA4vX6"Š‹ßôÀþD‚v-b¶e½¤ºp\ ÂÀ=ÁΔË=B‹$#F½Z(6À¸îôÖØÙvBýÈË4‰zÁÃí£,N!] Ò¾TB/šVlÐxàãƒM—Û c1*ÎBÜK¢‰àíøtÖ#À‡Ë=ÂਠØ¡Lš…KRUååšô ‡YÕÿ‚Ú]õ¨I]^Q‡P‰C,JåƒøÎó=øÐ#Ä@TZƒ@Ô} ¸eåeP¥D™E‚N¦e®0d,Â"} YÂ`\zÄZfüŽIš%_&Œ=ÁPVa*æb2fc:æcBfdJædRfeZæebffjæfrfgzæg‚fhŠæh’fišæi¢fjª&@¼Ýû¡’” €ÐO®¦„üe€$¦ZÈÁ` Â0ìfm´ø@:}Ak6ÞkŠ B(Ðæe–‹Ibå*"éÒ|H¤ÔN<€E‚ å-èæ P6ôæ@ÐS @% '!4 `¡_ ç äÿ nÂfÓQÕÀ¥eZ¢$àX»Û<¢DΡ$„gÙ'6Œg tS6x Ì$Ë  e{*BÐÀÜÈ'°ýsR(¤ Øpáh_óE0lµà IAà8oNÂ~ÁT‰D„ BñÜd‡†rNúi(Ùá§Ž^â@ƒ†}OÒUtŒ_ ¤!¨CJnƒŒ"_ˆ†„ ÂOü§rAªCu’ž5F@ì¨YaÉPäm€îM[Díe LÂr!€Ì¤GÐLC„NŒ•d™ ÔbñÝ2Èc8¥ˆ-é<¼)X–3öOÆ1¤ûLû ÉœUèh@ Ï¯t†eÿÁ ¤‹A ©DØ€Im.iD Ý“ !€x—A‚Š #vÊ­éöÜ~J4ÚM dÜ£úÍGÞÀU$M«ŠžÛâ„ìÆ´N@>}#y+€d§)瀒bQ@Bô‘«ö‘ ÄG>+´ ­Â*±¸.`'|d´Ý Ö'ÀžŠ]7ü„²zÁl" àdQ} ǵD,ÕAé¨=ÀH©†È:Fɽ€•&:€LE,Â(ÄNÁJé‡RìihÆ"^²u è]ÄJ" ÁG•À`ÉÚ_‘Ó';£D{·7‚dX;¬T?ƒ{Ÿ|û¹«ûº³{»»û»Ã{¼Ëû¼Ó{½Ûû½ã{¾ëû¾ó{¿ûû¿|À üÀ|ÁüÁ#|Â+üÂ3|Ã;üÃC|ÄKüÄS|Å[üÅc|ÆküÆs|Ç{üǃ|È‹üÈ“|É›üÉ£|Ê«üʳ|Ë»üËÃ|ÌËüÌÓ|ÍÛüÍã|ÎëüÎó|ÏûüÏ}Ð ýÐÿ}ÑýÑ#}Ò+ýÒ3}Ó;=H‚°ÒÓSý¨”³$T}ÖÊÕÓ¶Ö{½¦°’Ôwýדý­O‚ØOBÙ«=ŸÁ£}9¯}ÜãIÛ—aØÿ¨ÜãýšÐýpýÝçýß“IÑšŽ»ž—³Ô~⧉GÁ‡·Ôw|õ½âK~à£!Ýfô=æNþæ»Çxî½<ÁÛÓç“þ„äøçc~ä—þê»G( ê׳þì'nDZAæÓþî‡?¡ì€~ˆ¾ðc=ïÿZ4À!IBµÅþÕÿó«@\OóßÀðk>ôk¿@нóX?}ˆýö‹¿HX~B¾ìúÿC%Ðý<|{?ñ§½úË6€ÑöhD­2ªþüó?5Ü‘T„«Ynî_?Ü÷ÿã‚»‹±Ðê?ú÷ÿ#î'Öþ÷ÿOî'üG}ñ÷ÿ#î'Öþ÷ÿWÐ?ú÷ÿ£…î÷ÿ§×#~ÿ÷Zè~ÿ÷Zœý¾ôÿßB;uftrace-0.9.3/doc/uftrace-live.md000066400000000000000000000766461351236475300166650ustar00rootroot00000000000000% UFTRACE-LIVE(1) Uftrace User Manuals % Namhyung Kim % Sep, 2018 NAME ==== uftrace-live - Trace functions in a command during live execution SYNOPSIS ======== uftrace [live] [*options*] COMMAND [*command-options*] DESCRIPTION =========== This command runs COMMAND and prints its functions with time and thread info. This is basically the same as running the `uftrace record` and `uftrace replay` commands in turn, but it does not save a data file. This command accepts most options that are accepted by the record or replay commands. COMMON OPTIONS ============== -F *FUNC*, \--filter=*FUNC* : Set filter to trace selected functions only. This option can be used more than once. See *FILTERS*. -N *FUNC*, \--notrace=*FUNC* : Set filter not to trace selected functions (or the functions called underneath them). This option can be used more than once. See *FILTERS*. -C *FUNC*, \--caller-filter=*FUNC* : Set filter to trace callers of selected functions only. This option can be used more than once. See *FILTERS*. -T *TRG*, \--trigger=*TRG* : Set trigger on selected functions. This option can be used more than once. See *TRIGGERS*. -D *DEPTH*, \--depth=*DEPTH* : Set global trace limit in nesting level. See *FILTERS*. -t *TIME*, \--time-filter=*TIME* : Do not show functions which run under the time threshold. If some functions explicitly have the 'trace' trigger applied, those are always traced regardless of execution time. See *FILTERS*. \--no-libcall : Do not record library function invocations. Library calls are normally traced by hooking the dynamic linker's resolve function in the PLT. One can disable it with this option. \--no-event : Disable event recording which is used by default. Note that explicit event tracing by `--event` option is not affected by this. \--match=*TYPE* : Use pattern match using TYPE. Possible types are `regex` and `glob`. Default is `regex`. \--disable : Start uftrace with tracing disabled. This is only meaningful when used with a `trace_on` trigger. LIVE OPTIONS ============ \--list-event : Show available events in the process. \--report : Show live-report before replay. RECORD OPTIONS ============== -A *SPEC*, \--argument=*SPEC* : Record function arguments. This option can be used more than once. See *ARGUMENTS*. -R *SPEC*, \--retval=*SPEC* : Record function return values. This option can be used more than once. See *ARGUMENTS*. -P *FUNC*, \--patch=*FUNC* : Patch FUNC dynamically. This is only applicable binaries built by gcc with `-pg -mfentry -mnop-mcount` or clang with `-fxray-instrument`. This option can be used more than once. See *DYNAMIC TRACING*. -E *EVENT*, \--event=*EVENT* : Enable event tracing. The event should be available on the system. -S *SCRIPT_PATH*, \--script=*SCRIPT_PATH* : Run a given script to do additional work at the entry and exit of function during target program execution. The type of script is detected by the postfix such as '.py' for python. See *SCRIPT EXECUTION*. -W, \--watch=*POINT* : Add watch point to display POINT if the value is changed. See *WATCH POINT*. -a, \--auto-args : Automatically record arguments and return values of known functions. These are usually functions in standard (C language or system) libraries but if debug info is available it includes functions in the user program. -l, \--nest-libcall : Trace function calls between libraries. By default, uftrace only record library call from the main executable. Implies `--force`. -k, \--kernel : Trace kernel functions as well as user functions. Only kernel entry/exit functions will be traced by default. Use the `--kernel-depth` option to override this. -K *DEPTH*, \--kernel-depth=*DEPTH* : Set kernel max function depth separately. Implies `--kernel`. \--signal=*TRG* : Set trigger on selected signals rather than functions. But there are restrictions so only a few of trigger actions are support for signals. The available actions are: trace_on, trace_off, finish. This option can be used more than once. See *TRIGGERS*. \--nop : Do not record and replay any functions. This is a no-op and only meaningful for performance comparisons. \--force : Allow running uftrace even if some problems occur. When `uftrace record` finds no mcount symbol (which is generated by compiler) in the executable, it quits with an error message since uftrace can not trace the program. However, it is possible that the user is only interested in functions within a dynamically-linked library, in which case this option can be used to cause uftrace to run the program regardless. Also, the `-A`/`--argument` and `-R`/`--retval` options work only for binaries built with `-pg`, so uftrace will normally exit when it tries to run binaries built without that option. This option ignores the warning and goes on tracing without the argument and/or return value. \--time : Print running time of children in `time`(1)-style. RECORD CONFIG OPTIONS ===================== -L *PATH*, \--library-path=*PATH* : Load necessary internal libraries from this path. This is mostly for testing purposes. -b *SIZE*, \--buffer=*SIZE* : Size of internal buffer in which trace data will be saved. Default size is 128k. \--kernel-buffer=*SIZE* : Set kernel tracing buffer size. The default value (in the kernel) is 1408k. \--no-pltbind : Do not bind dynamic symbol address. This option uses the `LD_BIND_NOT` environment variable to trace library function calls which might be missing due to concurrent (first) accesses. It is not meaningful to use this option with the `--no-libcall` option. \--max-stack=*DEPTH* : Set the max function stack depth for tracing. Default is 1024. \--num-thread=*NUM* : Use NUM threads to record trace data. Default is 1/4 of online CPUs (but when full kernel tracing is enabled, it will use the full number of CPUs). \--libmcount-single : Use single thread version of libmcount for faster recording. This is ignored if the target program links with the pthread library. \--rt-prio=*PRIO* : Boost priority of recording threads to real-time (FIFO) with priority of *PRIO*. This is particularly useful for high-volume data such as full kernel tracing. \--keep-pid : Retain same pid for traced program. For some daemon processes, it is important to have same pid when forked. Running under uftrace normally changes pid as it calls fork() again internally. Note that it might corrupt terminal setting so it'd be better using it with `--no-pager` option. \--no-randomize-addr : Disable ASLR (Address Space Layout Randomization). It makes the target process fix its address space layout. REPLAY OPTIONS ============== -f *FIELD*, \--output-fields=*FIELD* : Customize field in the output. Possible values are: duration, tid, time, delta, elapsed and addr. Multiple fields can be set by using comma. Special field of 'none' can be used (solely) to hide all fields. Default is 'duration,tid'. See *FIELDS*. \--flat : Print flat format rather than C-like format. This is usually for debugging and testing purpose. \--column-view : Show each task in separate column. This makes easy to distinguish functions in different tasks. \--column-offset=*DEPTH* : When `--column-view` option is used, this option specifies the amount of offset between each task. Default is 8. \--task-newline : Interleave a new line when task is changed. This makes easy to distinguish functions in different tasks. \--no-comment : Do not show comments of returned functions. \--libname : Show library name along with function name. COMMON ANALYSIS OPTIONS ======================= \--kernel-full : Show all kernel functions called outside of user functions. \--kernel-only : Show kernel functions only without user functions. \--event-full : Show all (user) events outside of user functions. \--demangle=*TYPE* : Demangle C++ symbol names. Possible values are "full", "simple" and "no". Default is "simple" which ignores function arguments and template parameters. -r *RANGE*, \--time-range=*RANGE* : Only show functions executed within the time RANGE. The RANGE can be \~\ (separated by "~") and one of \ and \ can be omitted. The \ and \ are timestamp or elapsed time if they have \ postfix, for example '100us'. However, it is highly recommended to use only elapsed time because there is no way to know the timestamp before actually running the program. The timestamp or elapsed time can be shown with `-f time` or `-f elapsed` option respectively. FILTERS ======= The uftrace tool supports filtering out uninteresting functions. Filtering is highly recommended since it helps users focus on the interesting functions and reduces the data size. When uftrace is called it receives two types of function filter; an opt-in filter with `-F`/`--filter` and an opt-out filter with `-N`/`--notrace`. These filters can be applied either at record time or replay time. The first one is an opt-in filter. By default, it doesn't trace anything. But when one of the specified functions is executed, tracing is started. When the function returns, tracing is stopped again. For example, consider a simple program which calls `a()`, `b()` and `c()` in turn. $ cat abc.c void c(void) { /* do nothing */ } void b(void) { c(); } void a(void) { b(); } int main(void) { a(); return 0; } $ gcc -pg -o abc abc.c Normally uftrace will trace all the functions from `main()` to `c()`. $ uftrace live ./abc # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { [ 1234] | b() { 3.880 us [ 1234] | c(); 5.475 us [ 1234] | } /* b */ 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ In the above example, the command name `live` is explicitly used, but it can be omitted because uftrace uses `live` command by default. So the above command can be reused as `uftrace ./abc` in short. But when the `-F b` filter option is used, it will not trace `main()` or `a()` but only `b()` and `c()`. $ uftrace -F b ./abc # DURATION TID FUNCTION [ 1234] | b() { 3.880 us [ 1234] | c(); 5.475 us [ 1234] | } /* b */ The second type of filter is opt-out. By default, everything is traced, but when one of the specified functions is executed, tracing stops. When the excluded function returns, tracing is started again. In the above example, you can omit the function `b()` and all calls it makes with the `-N` option. $ uftrace -N b ./abc # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { 6.448 us [ 1234] | a(); 8.631 us [ 1234] | } /* main */ If users only care about specific functions and want to know how they are called, one can use the caller filter. It makes the function as leaf and records the parent functions to the function. $ uftrace -C b ./abc # DURATION TID FUNCTION [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ In the above example, functions not in the calling path were not shown. Also the function 'c' - which is a child of the function 'b' - is also hidden. In addition, you can limit the nesting level of functions with the `-D` option. $ uftrace -D 3 ./abc # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ In the above example, uftrace only prints functions up to a depth of 3, so leaf function `c()` was omitted. Note that the `-D` option works with `-F`. Sometimes it's useful to see long-running functions only. This is good because there are usually many tiny functions that are not interesting. The `-t`/`--time-filter` option implements the time-based filter that only records functions which run longer than the given threshold. In the above example, the user might want to see functions running more than 5 micro-seconds like below: $ uftrace -t 5us ./abc # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ You can also set triggers on filtered functions. See *TRIGGERS* section below for details. When kernel function tracing is enabled, you can also set the filters on kernel functions by marking the symbol with the `@kernel` modifier. The following example will show all user functions and the (kernel) page fault handler. $ sudo uftrace -k -F '.*page_fault@kernel' ./abc # DURATION TID FUNCTION [14721] | main() { 7.713 us [14721] | __do_page_fault(); 6.600 us [14721] | __do_page_fault(); 6.544 us [14721] | __do_page_fault(); [14721] | a() { [14721] | b() { [14721] | c() { 0.860 us [14721] | getpid(); 2.346 us [14721] | } /* c */ 2.956 us [14721] | } /* b */ 3.340 us [14721] | } /* a */ 79.086 us [14721] | } /* main */ TRIGGERS ======== The uftrace tool supports triggering actions on selected function calls (with or without filters) and/or signals. Currently supported triggers are listed below. The BNF for trigger specification is as follows: := "@" := | "," := "depth=" | "backtrace" | "trace" | "trace_on" | "trace_off" | "recover" | "color=" | "time=" | "read=" | "finish" | "filter" | "notrace" := [ ] := "ns" | "nsec" | "us" | "usec" | "ms" | "msec" | "s" | "sec" | "m" | "min" := "proc/statm" | "page-fault" | "pmu-cycle" | "pmu-cache" | "pmu-branch" The `depth` trigger is to change filter depth during execution of the function. It can be used to apply different filter depths for different functions. And the `backtrace` trigger is used to print a stack backtrace at replay time. The color trigger is to change the color of the function in replay output. The supported colors are `red`, `green`, `blue`, `yellow`, `magenta`, `cyan`, `bold`, and `gray`. The following example shows how triggers work. The global filter maximum depth is 5, but when function `b()` is called, it is changed to 1, so functions below `b()` will not shown. $ uftrace -D 5 -T 'b@depth=1' ./abc # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ The `backtrace` trigger is only meaningful in the replay command. The `trace_on` and `trace_off` actions (the `_` can be omitted as `traceon` and `traceoff`) control whether uftrace records the specified functions or not. The 'recover' trigger is for some corner cases in which the process accesses the callstack directly. During tracing of the v8 javascript engine, for example, it kept getting segfaults in the garbage collection stage. It was because v8 incorporates the return address into compiled code objects(?). The `recover` trigger restores the original return address at the function entry point and resets to the uftrace return hook address again at function exit. I was managed to work around the segfault by setting the `recover` trigger on the related function (specifically `ExitFrame::Iterate`). The 'time' trigger is to change time filter setting during execution of the function. It can be used to apply different time filter for different functions. The `read` trigger is to read some information at runtime. The result will be recorded as (builtin) events at the beginning and the end of a given function. As of now, following events are supported: * "proc/statm": process memory stat from /proc filesystem * "page-fault": number of page faults using getrusage(2) * "pmu-cycle": cpu cycles and instructions using Linux perf-event syscall * "pmu-cache": (cpu) cache-references and misses using Linux perf-event syscall * "pmu-branch": branch instructions and misses using Linux perf-event syscall The results are printed as events (comments) like below. $ uftrace -T a@read=proc/statm ./abc # DURATION TID FUNCTION [ 1234] | main() { [ 1234] | a() { [ 1234] | /* read:proc/statm (size=6808KB, rss=776KB, shared=712KB) */ [ 1234] | b() { [ 1234] | c() { 1.448 us [ 1234] | getpid(); 10.270 us [ 1234] | } /* c */ 11.250 us [ 1234] | } /* b */ [ 1234] | /* diff:proc/statm (size=+4KB, rss=+0KB, shared=+0KB) */ 18.380 us [ 1234] | } /* a */ 19.537 us [ 1234] | } /* main */ The 'finish' trigger is to end recording. The process still can run and this can be useful to trace unterminated processes like daemon. The 'filter' and 'notrace' triggers have same effect as `-F`/`--filter` and `-N`/`--notrace` options respectively. Triggers only work for user-level functions for now. The trigger can be used for signals as well. This is done by signal trigger with \--signal option. The syntax is similar to function trigger but only "trace_on", "trace_off" and "finish" trigger actions are supported. $ uftrace --signal 'SIGUSR1@finish' ./some-daemon ARGUMENTS ========= The uftrace tool supports recording function arguments and/or return values using the -A/\--argument and -R/\--retval options respectively. The syntax is very similar to that of triggers: := [ "@" ] := | "," := ( | | ) := "arg" N [ "/" [ ] ] [ "%" ( | ) ] := "fparg" N [ "/" ( | "80" ) ] [ "%" ( | ) ] := "retval" [ "/" [ ] ] := "d" | "i" | "u" | "x" | "s" | "c" | "f" | "S" | "p" := "8" | "16" | "32" | "64" := # "rdi", "xmm0", "r0", ... := "stack" [ "+" ] The -A/\--argument option takes a symbol name pattern and its optional specs. The spec is started by argN where N is an index of the arguments. The index starts from 1 and corresponds to the argument passing order of the calling convention on the system. Note that the indexes of arguments are separately counted for integer (or pointer) and floating-point type, and they can interfere depending on the calling convention. The argN is for integer arguments and fpargN is for floating-point arguments. Users can optionally specify a format and size for the arguments and/or return values. The "d" format or without format field, uftrace treats them as 'long int' type for integers and 'double' for floating-point numbers. The "i" format makes it signed integer type and "u" format is for unsigned type. Both are printed as decimal while "x" format makes it printed as hexadecimal. The "s" format is for null-terminated string type and "c" format is for character type. The "f" format is for floating-point type and is meaningful only for return value (generally). Note that fpargN doesn't take the format field since it's always floating-point. The "S" format is for std::string, but it only supports libstdc++ library as of yet. Finally, the "p" format is for function pointer. Once the target address is recorded, it will be displayed as function name. Please beware when using string type arguments since it can crash the program if the (pointer) value is invalid. Actually uftrace tries to keep track of valid ranges of process address space but it might miss some corner cases. It is also possible to specify a certain register name or stack offset for arguments (but not for return value). The following register names can be used for argument: * x86: rdi, rsi, rdx, rcx, r8, r9 (for integer), xmm[0-7] (for floating-point) * arm: r[0-3] (for integer), s[0-15] or d[0-7] (for floating-point) Examples are below: $ uftrace -A main@arg1/x -R main@retval/i32 ./abc # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main(0x1) { [ 1234] | a() { [ 1234] | b() { 3.880 us [ 1234] | c(); 5.475 us [ 1234] | } /* b */ 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } = 0; /* main */ $ uftrace -A puts@arg1/s -R puts@retval ./hello Hello world # DURATION TID FUNCTION 1.457 us [21534] | __monstartup(); 0.997 us [21534] | __cxa_atexit(); [21534] | main() { 7.226 us [21534] | puts("Hello world") = 12; 8.708 us [21534] | } /* main */ Note that these arguments and return value are recorded only if the executable was built with the `-pg` option. Executables built with `-finstrument-functions` will ignore it except for library calls. Recording of arguments and return values only works with user-level functions for now. If the target program is built with debug info like DWARF, uftrace can identify number of arguments and their types automatically (when built with libdw). Also arguments and return value of some well-known library functions are provided even if the debug info is not available. In these cases user don't need to specify spec of the arguments and return value manually - just a function name (or pattern) is enough. In fact, manual argspec will suppress the automatic argspec. For example, the above example can be written like below: $ uftrace -A . -R main -F main ./hello Hello world # DURATION TID FUNCTION [ 18948] | main(1, 0x7ffeeb7590b8) { 7.183 us [ 18948] | puts("Hello world"); 9.832 us [ 18948] | } = 0; /* main */ Note that argument pattern (".") matches to any character so it recorded all (supported) functions. It shows two arguments for "main" and a single string argument for "puts". If you simply want to see all arguments and return values of every functions (if supported), use -a/\--auto-args option. FIELDS ====== The uftrace allows for user to customize the replay output with a couple of fields. Here the field means info on the left side of the pipe (|) character. By default it uses duration and tid fields, but you can use other fields in any order like: $ uftrace -f time,delta,duration,tid,addr ./abc # TIMESTAMP TIMEDELTA DURATION TID ADDRESS FUNCTION 75059.205379813 1.374 us [27804] 4004d0 | __monstartup(); 75059.205384184 4.371 us 0.737 us [27804] 4004f0 | __cxa_atexit(); 75059.205386655 2.471 us [27804] 4006b1 | main() { 75059.205386838 0.183 us [27804] 400656 | a() { 75059.205386961 0.123 us [27804] 400669 | b() { 75059.205387078 0.117 us [27804] 40067c | c() { 75059.205387264 0.186 us 0.643 us [27804] 4004b0 | getpid(); 75059.205388501 1.237 us 1.423 us [27804] 40067c | } /* c */ 75059.205388724 0.223 us 1.763 us [27804] 400669 | } /* b */ 75059.205388878 0.154 us 2.040 us [27804] 400656 | } /* a */ 75059.205389030 0.152 us 2.375 us [27804] 4006b1 | } /* main */ Each field has following meaning: * tid: task id (obtained by gettid(2)) * duration: function execution time * time: timestamp at the execution * delta: difference between two timestamp in a task * elapsed: elapsed time from the first timestamp * addr: address of the function * task: task name (comm) * module: library or executable name of the function The default value is 'duration,tid'. If given field name starts with "+", then it'll be appended to the default fields. So "-f +time" is as same as "-f duration,tid,time". And it also accepts a special field name of 'none' which disables the field display and shows function output only. DYNAMIC TRACING =============== The uftrace tool supports dynamic function tracing which can be enabled at runtime (load-time, to be precise) on x86_64. Before recording functions, normally you need to build the target program with `-pg` (or `-finstrument-functions`), then it has some performance impact because all funtions call `mcount()`. With dynamic tracing, you can trace specific functions only given by the `-P`/`--patch` option. With capstone disassembly engine you even don't need to (re)compile the target with the option above. Now uftrace can analyze the instructions and (if possible) it can copy them to a different place and rewrite it to call `mcount()` function) so that it can be traced by uftrace. After that the control is passed to the copied instructions and then returned back to the remaining instructions. If the capstone is not available, you need to add some more compiler (gcc) options when building the target program. The gcc 5.1 or more recent versions provide `-mfentry` and `-mnop-mcount` options which add instrumentation code (i.e. calling `mcount()` function) at the very beginning of a function and convert the instruction to a NOP. Then it has almost zero performance overhead when running in a normal condition. The uftrace can selectively convert it back to call `mcount()` using `-P` option. The following example shows an error message when normally running uftrace. Because the binary doesn't call any instrumentation code (i.e. 'mcount'). $ gcc -o abc -pg -mfentry -mnop-mcount tests/s-abc.c $ uftrace abc uftrace: /home/namhyung/project/uftrace/cmd-record.c:1305:check_binary ERROR: Can't find 'mcount' symbol in the 'abc'. It seems not to be compiled with -pg or -finstrument-functions flag which generates traceable code. Please check your binary file. But when the `-P a` patch option is used, and then only it can dynamically trace `a()`. $ uftrace --no-libcall -P a abc # DURATION TID FUNCTION 0.923 us [19379] | a(); In addition, you can enable all functions using '.' (for glob, '*') that matches to any character in a regex pattern with `P` option. $ uftrace --no-libcall -P . abc # DURATION TID FUNCTION [19387] | main() { [19387] | a() { [19387] | b() { 0.940 us [19387] | c(); 2.030 us [19387] | } /* b */ 2.451 us [19387] | } /* a */ 3.289 us [19387] | } /* main */ Clang/LLVM 4.0 provides a dynamic instrumentation technique called [X-ray](http://llvm.org/docs/XRay.html). It's similar to a combination of `gcc -mfentry -mnop-mcount` and `-finstrument-functions`. The uftrace also supports dynamic tracing on the excutables built with the `X-ray`. For example, you can build the target program by clang with the below option and equally use `-P` option for dynamic tracing like below: $ clang -fxray-instrument -fxray-instruction-threshold=1 -o abc-xray tests/s-abc.c $ uftrace -P main abc-xray # DURATION TID FUNCTION [11093] | main() { 1.659 us [11093] | getpid(); 5.963 us [11093] | } /* main */ $ uftrace -P . abc-xray # DURATION TID FUNCTION [11098] | main() { [11098] | a() { [11098] | b() { [11098] | c() { 0.753 us [11098] | getpid(); 1.430 us [11098] | } /* c */ 1.915 us [11098] | } /* b */ 2.405 us [11098] | } /* a */ 3.005 us [11098] | } /* main */ SCRIPT EXECUTION ================ The uftrace tool supports script execution for each function entry and exit. The supported script is only Python 2.7 as of now. The user can write four functions. 'uftrace_entry' and 'uftrace_exit' are executed whenever each function is executed at the entry and exit. However 'uftrace_begin' and 'uftrace_end' are only executed once when the target program begins and ends. $ cat scripts/simple.py def uftrace_begin(ctx): print("program begins...") def uftrace_entry(ctx): func = ctx["name"] print("entry : " + func + "()") def uftrace_exit(ctx): func = ctx["name"] print("exit : " + func + "()") def uftrace_end(): print("program is finished") The above script can be executed in record time as follows: $ uftrace -S scripts/simple.py -F main tests/t-abc program begins... entry : main() entry : a() entry : b() entry : c() entry : getpid() exit : getpid() exit : c() exit : b() exit : a() exit : main() program is finished # DURATION TID FUNCTION [10929] | main() { [10929] | a() { [10929] | b() { [10929] | c() { 4.293 us [10929] | getpid(); 19.017 us [10929] | } /* c */ 27.710 us [10929] | } /* b */ 37.007 us [10929] | } /* a */ 55.260 us [10929] | } /* main */ The 'ctx' variable is a dictionary type that contains the below information. /* context information passed to uftrace_entry(ctx) and uftrace_exit(ctx) */ script_context = { int tid; int depth; long timestamp; long duration; # exit only long address; string name; list args; # entry only (if available) value retval; # exit only (if available) }; /* context information passed to uftrace_begin(ctx) */ script_context = { bool record; # True if it runs at record time, otherwise False string version; # uftrace version info list cmds; # execution commands }; Each field in 'script_context' can be read inside the script. Please see `uftrace-script`(1) for details about scripting. WATCH POINT =========== The uftrace watch point is to display certain value only if it's changed. It's conceptually same as debugger's but only works at function entry and exit so it might miss some updates. As of now, following watch points are supported: * "cpu" : cpu number current task is running on Like read triggers, the result is displayed as event (comment): $ uftrace -W cpu tests/t-abc # DURATION TID FUNCTION [ 19060] | main() { [ 19060] | /* watch:cpu (cpu=8) */ [ 19060] | a() { [ 19060] | b() { [ 19060] | c() { 2.365 us [ 19060] | getpid(); 8.002 us [ 19060] | } /* c */ 8.690 us [ 19060] | } /* b */ 9.350 us [ 19060] | } /* a */ 12.479 us [ 19060] | } /* main */ SEE ALSO ======== `uftrace-record`(1), `uftrace-replay`(1), `uftrace-report`(1), `uftrace-script`(1) uftrace-0.9.3/doc/uftrace-record.md000066400000000000000000000661331351236475300171720ustar00rootroot00000000000000% UFTRACE-RECORD(1) Uftrace User Manuals % Namhyung Kim % Sep, 2018 NAME ==== uftrace-record - Run a command and record its trace data SYNOPSIS ======== uftrace record [*options*] COMMAND [*command-options*] DESCRIPTION =========== This command runs COMMAND and gathers function trace data from it, and saves it into files under the uftrace data directory - without displaying anything. This data can then be inspected later on, using `uftrace replay` or `uftrace report`. RECORD OPTIONS ============== -A *SPEC*, \--argument=*SPEC* : Record function arguments. This option can be used more than once. Implies \--srcline. See *ARGUMENTS*. -R *SPEC*, \--retval=*SPEC* : Record function return values. This option can be used more than once. Implies \--srcline. See *ARGUMENTS*. -P *FUNC*, \--patch=*FUNC* : Patch FUNC dynamically. This option can be used more than once. See *DYNAMIC TRACING*. -Z *SIZE*, \--size-filter=*SIZE* : Patch functions bigger than SIZE bytes dynamically. See *DYNAMIC TRACING*. -E *EVENT*, \--event=*EVENT* : Enable event tracing. The event should be available on the system. -S *SCRIPT_PATH*, \--script=*SCRIPT_PATH* : Run a given script to do additional work at the entry and exit of function during target program execution. The type of script is detected by the postfix such as '.py' for python. See *SCRIPT EXECUTION*. -W, \--watch=*POINT* : Add watch point to display POINT if the value is changed. See *WATCH POINT*. -a, \--auto-args : Automatically record arguments and return values of known functions. These are usually functions in standard (C language or system) libraries but if debug info is available it includes functions in the user program. Implies \--srcline. -l, \--nest-libcall : Trace function calls between libraries. By default, uftrace only record library call from the main executable. Implies `--force`. -k, \--kernel : Trace kernel functions as well as user functions. Only kernel entry/exit functions will be traced by default. Use the `--kernel-depth` option to override this. -K *DEPTH*, \--kernel-depth=*DEPTH* : Set kernel max function depth separately. Implies `--kernel`. -H *HOST*, \--host=*HOST* : Send trace data to given host via the network, not writing to files. The `uftrace recv` command should be run on the destination host to receive the data. \--port=*PORT* : When sending data to the network (with `-H`), use the given port instead of the default (8090). \--signal=*TRG* : Set trigger on selected signals rather than functions. But there are restrictions so only a few of trigger actions are support for signals. The available actions are: trace_on, trace_off, finish. This option can be used more than once. See *TRIGGERS*. \--nop : Do not record any functions. This is a no-op and only meaningful for performance comparisons. \--force : Allow running uftrace even if some problems occur. When `uftrace record` finds no mcount symbol (which is generated by compiler) in the executable, it quits with an error message since uftrace can not trace the program. However, it is possible that the user is only interested in functions within a dynamically-linked library, in which case this option can be used to cause uftrace to run the program regardless. Also, the `-A`/`--argument` and `-R`/`--retval` options work only for binaries built with `-pg`, so uftrace will normally exit when it tries to run binaries built without that option. This option ignores the warning and goes on tracing without the argument and/or return value. \--time : Print running time of children in `time`(1)-style. COMMON OPTIONS ============== -F *FUNC*, \--filter=*FUNC* : Set filter to trace selected functions only. This option can be used more than once. See *FILTERS*. -N *FUNC*, \--notrace=*FUNC* : Set filter not to trace selected functions (or the functions called underneath them). This option can be used more than once. See *FILTERS*. -C *FUNC*, \--caller-filter=*FUNC* : Set filter to trace callers of selected functions only. This option can be used more than once. See *FILTERS*. -T *TRG*, \--trigger=*TRG* : Set trigger on selected functions. This option can be used more than once. See *TRIGGERS*. -D *DEPTH*, \--depth=*DEPTH* : Set global trace limit in nesting level. See *FILTERS*. -t *TIME*, \--time-filter=*TIME* : Do not show functions which run under the time threshold. If some functions explicitly have the 'trace' trigger applied, those are always traced regardless of execution time. See *FILTERS*. \--no-libcall : Do not record library function invocations. Library calls are normally traced by hooking the dynamic linker's resolve function in the PLT. One can disable it with this option. \--no-event : Disable event recording which is used by default. Note that explicit event tracing by `--event` option is not affected by this. \--match=*TYPE* : Use pattern match using TYPE. Possible types are `regex` and `glob`. Default is `regex`. \--disable : Start uftrace with tracing disabled. This is only meaningful when used with a `trace_on` trigger. RECORD CONFIG OPTIONS ===================== -L *PATH*, \--library-path=*PATH* : Load necessary internal libraries from this path. This is mostly for testing purposes. -b *SIZE*, \--buffer=*SIZE* : Size of internal buffer in which trace data will be saved. Default size is 128k. \--kernel-buffer=*SIZE* : Set kernel tracing buffer size. The default value (in the kernel) is 1408k. \--no-pltbind : Do not bind dynamic symbol address. This option uses the `LD_BIND_NOT` environment variable to trace library function calls which might be missing due to concurrent (first) accesses. It is not meaningful to use this option with the `--no-libcall` option. \--max-stack=*DEPTH* : Set the max function stack depth for tracing. Default is 1024. \--num-thread=*NUM* : Use NUM threads to record trace data. Default is 1/4 of online CPUs (but when full kernel tracing is enabled, it will use the full number of CPUs). \--libmcount-single : Use single thread version of libmcount for faster recording. This is ignored if the target program links with the pthread library. \--rt-prio=*PRIO* : Boost priority of recording threads to real-time (FIFO) with priority of *PRIO*. This is particularly useful for high-volume data such as full kernel tracing. \--keep-pid : Retain same pid for traced program. For some daemon processes, it is important to have same pid when forked. Running under uftrace normally changes pid as it calls fork() again internally. \--no-randomize-addr : Disable ASLR (Address Space Layout Randomization). It makes the target process fix its address space layout. \--srcline : Enable recording source line in the debug info. FILTERS ======= The uftrace tool supports filtering out uninteresting functions. Filtering is highly recommended since it helps users focus on the interesting functions and reduces the data size. When uftrace is called it receives two types of function filter; an opt-in filter with `-F`/`--filter` and an opt-out filter with `-N`/`--notrace`. These filters can be applied either at record time or replay time. The first one is an opt-in filter. By default, it doesn't trace anything. But when one of the specified functions is executed, tracing is started. When the function returns, tracing is stopped again. For example, consider a simple program which calls `a()`, `b()` and `c()` in turn. $ cat abc.c void c(void) { /* do nothing */ } void b(void) { c(); } void a(void) { b(); } int main(void) { a(); return 0; } $ gcc -pg -o abc abc.c Normally uftrace will trace all the functions from `main()` to `c()`. $ uftrace record ./abc $ uftrace replay # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { [ 1234] | b() { 3.880 us [ 1234] | c(); 5.475 us [ 1234] | } /* b */ 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ But when the `-F b` filter option is used, it will not trace `main()` or `a()` but only `b()` and `c()`. $ uftrace record -F b ./abc $ uftrace replay # DURATION TID FUNCTION [ 1234] | b() { 3.880 us [ 1234] | c(); 5.475 us [ 1234] | } /* b */ The second type of filter is opt-out. By default, everything is traced, but when one of the specified functions is executed, tracing stops. When the excluded function returns, tracing is started again. In the above example, you can omit the function `b()` and all calls it makes with the `-N` option. $ uftrace record -N b ./abc $ uftrace replay # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { 6.448 us [ 1234] | a(); 8.631 us [ 1234] | } /* main */ If users only care about specific functions and want to know how they are called, one can use the caller filter. It makes the function as leaf and records the parent functions to the function. $ uftrace record -C b ./abc $ uftrace replay # DURATION TID FUNCTION [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ In the above example, functions not in the calling path were not shown. Also the function 'c' - which is a child of the function 'b' - is also hidden. In addition, you can limit the nesting level of functions with the `-D` option. $ uftrace record -D 3 ./abc $ uftrace replay # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ In the above example, uftrace only records functions up to a depth of 3, so leaf function `c()` was omitted. Note that the `-D` option works with `-F`. Sometimes it's useful to see long-running functions only. This is good because there are usually many tiny functions that are not interesting. The `-t`/`--time-filter` option implements the time-based filter that only records functions which run longer than the given threshold. In the above example, the user might want to see functions running more than 5 micro-seconds like below: $ uftrace record -t 5us ./abc $ uftrace replay # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ The `-t`/`--time-filter` option works for user-level functions only. It does not work for recording kernel functions, but they can be hidden in replay, report, dump and graph commands with `-t`/`--time-filter` option. You can also set triggers on filtered functions. See *TRIGGERS* section below for details. When kernel function tracing is enabled, you can also set the filters on kernel functions by marking the symbol with the `@kernel` modifier. The following example will show all user functions and the (kernel) page fault handler. $ sudo uftrace -k -F '.*page_fault@kernel' ./abc # DURATION TID FUNCTION [14721] | main() { 7.713 us [14721] | __do_page_fault(); 6.600 us [14721] | __do_page_fault(); 6.544 us [14721] | __do_page_fault(); [14721] | a() { [14721] | b() { [14721] | c() { 0.860 us [14721] | getpid(); 2.346 us [14721] | } /* c */ 2.956 us [14721] | } /* b */ 3.340 us [14721] | } /* a */ 79.086 us [14721] | } /* main */ TRIGGERS ======== The uftrace tool supports triggering actions on selected function calls (with or without filters) and/or signals. Currently supported triggers are listed below. The BNF for trigger specification is as follows: := "@" := | "," := "depth=" | "trace" | "trace_on" | "trace_off" | "time=" | "read=" | "finish" | "filter" | "notrace" | "recover" := [ ] := "ns" | "nsec" | "us" | "usec" | "ms" | "msec" | "s" | "sec" | "m" | "min" := "proc/statm" | "page-fault" | "pmu-cycle" | "pmu-cache" | "pmu-branch" The `depth` trigger is to change filter depth during execution of the function. It can be used to apply different filter depths for different functions. The following example shows how triggers work. The global filter maximum depth is 5, but when function `b()` is called, it is changed to 1, so functions below `b()` will not shown. $ uftrace record -D 5 -T 'b@depth=1' ./abc $ uftrace replay # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ The `backtrace` trigger is only meaningful in the replay command. The `trace_on` and `trace_off` actions (the `_` can be omitted as `traceon` and `traceoff`) control whether uftrace records the specified functions or not. The 'recover' trigger is for some corner cases in which the process accesses the callstack directly. For now it's not necessary to call it as uftrace does the job automatically. The 'time' trigger is to change time filter setting during execution of the function. It can be used to apply different time filter for different functions. The `read` trigger is to read some information at runtime. The result will be recorded as (builtin) events at the beginning and the end of a given function. As of now, following events are supported: * "proc/statm": process memory stat from /proc filesystem * "page-fault": number of page faults using getrusage(2) * "pmu-cycle": cpu cycles and instructions using Linux perf-event syscall * "pmu-cache": (cpu) cache-references and misses using Linux perf-event syscall * "pmu-branch": branch instructions and misses using Linux perf-event syscall The results are printed as events (comments) like below. $ uftrace record -T a@read=proc/statm ./abc $ uftrace replay # DURATION TID FUNCTION [ 1234] | main() { [ 1234] | a() { [ 1234] | /* read:proc/statm (size=6808KB, rss=776KB, shared=712KB) */ [ 1234] | b() { [ 1234] | c() { 1.448 us [ 1234] | getpid(); 10.270 us [ 1234] | } /* c */ 11.250 us [ 1234] | } /* b */ [ 1234] | /* diff:proc/statm (size=+4KB, rss=+0KB, shared=+0KB) */ 18.380 us [ 1234] | } /* a */ 19.537 us [ 1234] | } /* main */ The 'finish' trigger is to end recording. The process still can run and this can be useful to trace unterminated processes like daemon. The 'filter' and 'notrace' triggers have same effect as `-F`/`--filter` and `-N`/`--notrace` options respectively. Triggers only work for user-level functions for now. The trigger can be used for signals as well. This is done by signal trigger with \--signal option. The syntax is similar to function trigger but only "trace_on", "trace_off" and "finish" trigger actions are supported. $ uftrace record --signal 'SIGUSR1@finish' ./some-daemon ARGUMENTS ========= The uftrace tool supports recording function arguments and/or return values using the -A/\--argument and -R/\--retval options respectively. The syntax is very similar to that of triggers: := [ "@" ] := | "," := ( | | ) := "arg" N [ "/" [ ] ] [ "%" ( | ) ] := "fparg" N [ "/" ( | "80" ) ] [ "%" ( | ) ] := "retval" [ "/" [ ] ] := "d" | "i" | "u" | "x" | "s" | "c" | "f" | "S" | "p" := "8" | "16" | "32" | "64" := # "rdi", "xmm0", "r0", ... := "stack" [ "+" ] The -A/\--argument option takes a symbol name pattern and its optional specs. The spec is started by argN where N is an index of the arguments. The index starts from 1 and corresponds to the argument passing order of the calling convention on the system. Note that the indexes of arguments are separately counted for integer (or pointer) and floating-point type, and they can interfere depending on the calling convention. The argN is for integer arguments and fpargN is for floating-point arguments. Users can optionally specify a format and size for the arguments and/or return values. The "d" format or without format field, uftrace treats them as 'long int' type for integers and 'double' for floating-point numbers. The "i" format makes it signed integer type and "u" format is for unsigned type. Both are printed as decimal while "x" format makes it printed as hexadecimal. The "s" format is for null-terminated string type and "c" format is for character type. The "f" format is for floating-point type and is meaningful only for return value (generally). Note that fpargN doesn't take the format field since it's always floating-point. The "S" format is for std::string, but it only supports libstdc++ library as of yet. Finally, the "p" format is for function pointer. Once the target address is recorded, it will be displayed as function name. Please beware when using string type arguments since it can crash the program if the (pointer) value is invalid. Actually uftrace tries to keep track of valid ranges of process address space but it might miss some corner cases. It is also possible to specify a certain register name or stack offset for arguments (but not for return value). The following register names can be used for argument: * x86: rdi, rsi, rdx, rcx, r8, r9 (for integer), xmm[0-7] (for floating-point) * arm: r[0-3] (for integer), s[0-15] or d[0-7] (for floating-point) Examples are below: $ uftrace record -A main@arg1/x -R main@retval/i32 ./abc $ uftrace replay # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main(0x1) { [ 1234] | a() { [ 1234] | b() { 3.880 us [ 1234] | c(); 5.475 us [ 1234] | } /* b */ 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } = 0; /* main */ $ uftrace record -A puts@arg1/s -R puts@retval ./hello Hello world $ uftrace replay # DURATION TID FUNCTION 1.457 us [21534] | __monstartup(); 0.997 us [21534] | __cxa_atexit(); [21534] | main() { 7.226 us [21534] | puts("Hello world") = 12; 8.708 us [21534] | } /* main */ Note that these arguments and return value are recorded only if the executable was built with the `-pg` option. Executables built with `-finstrument-functions` will ignore it except for library calls. Recording of arguments and return values only works with user-level functions for now. If the target program is built with debug info like DWARF, uftrace can identify number of arguments and their types automatically (when built with libdw). Also arguments and return value of some well-known library functions are provided even if the debug info is not available. In these cases user don't need to specify spec of the arguments and return value manually - just a function name (or pattern) is enough. In fact, manual argspec will suppress the automatic argspec. For example, the above example can be written like below: $ uftrace record -A . -R main ./hello Hello world $ uftrace replay -F main # DURATION TID FUNCTION [ 18948] | main(1, 0x7ffeeb7590b8) { 7.183 us [ 18948] | puts("Hello world"); 9.832 us [ 18948] | } = 0; /* main */ Note that argument pattern (".") matches to any character so it recorded all (supported) functions. It shows two arguments for "main" and a single string argument for "puts". If you simply want to see all arguments and return values of every functions (if supported), use -a/\--auto-args option. DYNAMIC TRACING =============== The uftrace tool supports dynamic function tracing which can be enabled at runtime (load-time, to be precise) on x86_64. Before recording functions, normally you need to build the target program with `-pg` (or `-finstrument-functions`), then it has some performance impact because all funtions call `mcount()`. With dynamic tracing, you can trace specific functions only given by the `-P`/`--patch` option. With capstone disassembly engine you even don't need to (re)compile the target with the option above. Now uftrace can analyze the instructions and (if possible) it can copy them to a different place and rewrite it to call `mcount()` function) so that it can be traced by uftrace. After that the control is passed to the copied instructions and then returned back to the remaining instructions. If the capstone is not available, you need to add some more compiler (gcc) options when building the target program. The gcc 5.1 or more recent versions provide `-mfentry` and `-mnop-mcount` options which add instrumentation code (i.e. calling `mcount()` function) at the very beginning of a function and convert the instruction to a NOP. Then it has almost zero performance overhead when running in a normal condition. The uftrace can selectively convert it back to call `mcount()` using `-P` option. The following example shows an error message when normally running uftrace. Because the binary doesn't call any instrumentation code (i.e. 'mcount'). $ gcc -o abc tests/s-abc.c $ uftrace abc uftrace: /home/namhyung/project/uftrace/cmd-record.c:1305:check_binary ERROR: Can't find 'mcount' symbol in the 'abc'. It seems not to be compiled with -pg or -finstrument-functions flag which generates traceable code. Please check your binary file. But when the `-P a` patch option is used, and then only it can dynamically trace `a()`. $ uftrace record --no-libcall -P a abc $ uftrace replay # DURATION TID FUNCTION 0.923 us [19379] | a(); In addition, you can enable all functions using '.' (for glob, '*') that matches to any character in a regex pattern with `P` option. $ uftrace record --no-libcall -P . abc $ uftrace replay # DURATION TID FUNCTION [19387] | main() { [19387] | a() { [19387] | b() { 0.940 us [19387] | c(); 2.030 us [19387] | } /* b */ 2.451 us [19387] | } /* a */ 3.289 us [19387] | } /* main */ Clang/LLVM 4.0 provides a dynamic instrumentation technique called [X-ray](http://llvm.org/docs/XRay.html). It's similar to a combination of `gcc -mfentry -mnop-mcount` and `-finstrument-functions`. The uftrace also supports dynamic tracing on the excutables built with the `X-ray`. For example, you can build the target program by clang with the below option and equally use `-P` option for dynamic tracing like below: $ clang -fxray-instrument -fxray-instruction-threshold=1 -o abc-xray tests/s-abc.c $ uftrace record -P main abc-xray $ uftrace replay # DURATION TID FUNCTION [11093] | main() { 1.659 us [11093] | getpid(); 5.963 us [11093] | } /* main */ $ uftrace record -P . abc-xray $ uftrace replay # DURATION TID FUNCTION [11098] | main() { [11098] | a() { [11098] | b() { [11098] | c() { 0.753 us [11098] | getpid(); 1.430 us [11098] | } /* c */ 1.915 us [11098] | } /* b */ 2.405 us [11098] | } /* a */ 3.005 us [11098] | } /* main */ SCRIPT EXECUTION ================ The uftrace tool supports script execution for each function entry and exit. The supported script is only Python 2.7 as of now. The user can write four functions. 'uftrace_entry' and 'uftrace_exit' are executed whenever each function is executed at the entry and exit. However 'uftrace_begin' and 'uftrace_end' are only executed once when the target program begins and ends. $ cat scripts/simple.py def uftrace_begin(ctx): print("program begins...") def uftrace_entry(ctx): func = ctx["name"] print("entry : " + func + "()") def uftrace_exit(ctx): func = ctx["name"] print("exit : " + func + "()") def uftrace_end(): print("program is finished") The above script can be executed in record time as follows: $ uftrace record -S scripts/simple.py -F main tests/t-abc program begins... entry : main() entry : a() entry : b() entry : c() entry : getpid() exit : getpid() exit : c() exit : b() exit : a() exit : main() program is finished The 'ctx' variable is a dictionary type that contains the below information. /* context information passed to uftrace_entry(ctx) and uftrace_exit(ctx) */ script_context = { int tid; int depth; long timestamp; long duration; # exit only long address; string name; list args; # entry only (if available) value retval; # exit only (if available) }; /* context information passed to uftrace_begin(ctx) */ script_context = { bool record; # True if it runs at record time, otherwise False string version; # uftrace version info list cmds; # execution commands }; Each field in 'script_context' can be read inside the script. Please see `uftrace-script`(1) for details about scripting. WATCH POINT =========== The uftrace watch point is to display certain value only if it's changed. It's conceptually same as debugger's but only works at function entry and exit so it might miss some updates. As of now, following watch points are supported: * "cpu" : cpu number current task is running on Like read triggers, the result is displayed as event (comment): $ uftrace -W cpu tests/t-abc # DURATION TID FUNCTION [ 19060] | main() { [ 19060] | /* watch:cpu (cpu=8) */ [ 19060] | a() { [ 19060] | b() { [ 19060] | c() { 2.365 us [ 19060] | getpid(); 8.002 us [ 19060] | } /* c */ 8.690 us [ 19060] | } /* b */ 9.350 us [ 19060] | } /* a */ 12.479 us [ 19060] | } /* main */ SEE ALSO ======== `uftrace`(1), `uftrace-replay`(1), `uftrace-report`(1), `uftrace-recv`(1), `uftrace-graph`(1), `uftrace-script`(1), `uftrace-tui`(1) uftrace-0.9.3/doc/uftrace-recv.md000066400000000000000000000036271351236475300166520ustar00rootroot00000000000000% UFTRACE-RECV(1) Uftrace User Manuals % Namhyung Kim % Sep, 2018 NAME ==== uftrace-recv - Receive tracing data from socket and save it to files SYNOPSIS ======== uftrace recv [*options*] DESCRIPTION =========== This command receives tracing data from the network and saves it to files. Data will be sent using `uftrace-record` with -H/\--host option. OPTIONS ======= -d *DATA*, \--data=*DATA* : Specify directory name to save received data. \--port=*PORT* : Use given port instead of the default (8090). \--run-cmd=*COMMAND* : Run given (shell) command as soon as receive data. For example, one can run `uftrace replay` for received data. EXAMPLE ======= The uftrace recv command should be run before sending data by record command. # HOST $ uftrace recv -d recv_data --port 1234 Above command starts a server with port by given (default `8090`) to receive data from remote client. # CLIENT : $ uftrace record -H localhost -d example_data --port 1234 example Above command sends the trace data to a remote server that pointed by given -H option (`localhost` in this case) after running the example program. And as you see, you can choose save directory by using `-d` option (sending data will save to `example_data` in this case). # HOST : Check received data $ uftrace replay -d recv_data/example_data # DURATION TID FUNCTION [17308] | main() { [17308] | a() { [17308] | b() { [17308] | c() { 1.058 us [17308] | getpid(); 4.356 us [17308] | } /* c */ 4.664 us [17308] | } /* b */ 4.845 us [17308] | } /* a */ 5.076 us [17308] | } /* main */ You can find saved trace data of example from `recv_data`'s subdirectory `example_data`. Obviously, you should check at `HOST`. SEE ALSO ======== `uftrace`(1), `uftrace-record`(1) uftrace-0.9.3/doc/uftrace-replay.md000066400000000000000000000323411351236475300172020ustar00rootroot00000000000000% UFTRACE-REPLAY(1) Uftrace User Manuals % Namhyung Kim % Sep, 2018 NAME ==== uftrace-replay - Print recorded function trace SYNOPSIS ======== uftrace replay [*options*] DESCRIPTION =========== This command prints trace data recorded using the `uftrace-record`(1) command. The traced functions are printed like a C program in time order. REPLAY OPTIONS ============== -f *FIELD*, \--output-fields=*FIELD* : Customize field in the output. Possible values are: duration, tid, addr, time, delta, elapsed, task and module. Multiple fields can be set by using comma. Special field of 'none' can be used (solely) to hide all fields. Default is 'duration,tid'. See *FIELDS*. \--flat : Print flat format rather than C-like format. This is usually for debugging and testing purpose. \--column-view : Show each task in separate column. This makes easy to distinguish functions in different tasks. \--column-offset=*DEPTH* : When `--column-view` option is used, this option specifies the amount of offset between each task. Default is 8. \--task-newline : Interleave a new line when task is changed. This makes easy to distinguish functions in different tasks. \--no-comment : Do not show comments of returned functions. \--libname : Show libname name along with function name. COMMON OPTIONS ============== -F *FUNC*, \--filter=*FUNC* : Set filter to trace selected functions only. This option can be used more than once. See *FILTERS*. -N *FUNC*, \--notrace=*FUNC* : Set filter not to trace selected functions (or the functions called underneath them). This option can be used more than once. See *FILTERS*. -C *FUNC*, \--caller-filter=*FUNC* : Set filter to trace callers of selected functions only. This option can be used more than once. See *FILTERS*. -T *TRG*, \--trigger=*TRG* : Set trigger on selected functions. This option can be used more than once. See *TRIGGERS*. -D *DEPTH*, \--depth *DEPTH* : Set trace limit in nesting level. See *FILTERS*. -t *TIME*, \--time-filter=*TIME* : Do not show functions which run under the time threshold. If some functions explicitly have the 'trace' trigger applied, those are always traced regardless of execution time. See *FILTERS*. \--no-libcall : Do not show library calls. \--no-event : Do not show any events. \--match=*TYPE* : Use pattern match using TYPE. Possible types are `regex` and `glob`. Default is `regex`. \--disable : Start replay with tracing disabled. This is only meaningful when used with a `trace_on` trigger. COMMON ANALYSIS OPTIONS ======================= \--kernel-full : Show all kernel functions and events occurred outside of user functions. \--kernel-only : Show kernel functions only without user functions. \--event-full : Show all (user) events outside of user functions. \--tid=*TID*[,*TID*,...] : Only print functions called by the given threads. To see the list of threads in the data file, you can use `uftrace report --threads` or `uftrace info`. This option can also be used more than once. \--demangle=*TYPE* : Use demangled C++ symbol names for filters, triggers, arguments and/or return values. Possible values are "full", "simple" and "no". Default is "simple" which ignores function arguments and template parameters. -r *RANGE*, \--time-range=*RANGE* : Only show functions executed within the time RANGE. The RANGE can be \~\ (separated by "~") and one of \ and \ can be omitted. The \ and \ are timestamp or elapsed time if they have \ postfix, for example '100us'. The timestamp or elapsed time can be shown with `-f time` or `-f elapsed` option respectively. See *FILTERS*. FILTERS ======= The uftrace tool supports filtering out uninteresting functions. When uftrace is called it receives two types of function filter; an opt-in filter with `-F`/`--filter` and an opt-out filter with `-N`/`--notrace`. These filters can be applied either at record time or replay time. The first one is an opt-in filter. By default, it doesn't show anything. But when one of the specified functions is met, printing is started. When the function returns, printing is stopped again. For example, consider a simple program which calls `a()`, `b()` and `c()` in turn. $ cat abc.c void c(void) { /* do nothing */ } void b(void) { c(); } void a(void) { b(); } int main(void) { a(); return 0; } $ gcc -pg -o abc abc.c Normally uftrace replay will show all the functions from `main()` to `c()`. $ uftrace ./abc # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { [ 1234] | b() { 3.880 us [ 1234] | c(); 5.475 us [ 1234] | } /* b */ 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ But when the `-F b` filter option is used, it will not show `main()` or `a()` but only `b()` and `c()`. Note that the filter was set on `uftrace replay`, not at record time. $ uftrace record ./abc $ uftrace replay -F b # DURATION TID FUNCTION [ 1234] | b() { 3.880 us [ 1234] | c(); 5.475 us [ 1234] | } /* b */ The second type of filter is opt-out. When used, everything is shown by default, but printing stops once one of the specified functions is met. When the given function returns, printing is started again. In the above example, you can omit the function `b()` and all calls it makes with the `-N` option. $ uftrace record ./abc $ uftrace replay -N b # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { 6.448 us [ 1234] | a(); 8.631 us [ 1234] | } /* main */ If users only care about specific functions and want to know how they are called, one can use the caller filter. It makes the function as leaf and prints the parent functions to the function. $ uftrace record -C b ./abc $ uftrace replay # DURATION TID FUNCTION [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ In the above example, functions not in the calling path were not shown. Also the function 'c' - which is a child of the function 'b' - is also hidden. In addition, you can limit the print nesting level with -D option. $ uftrace record ./abc $ uftrace replay -D 3 # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ In the above example, uftrace only prints functions up to a depth of 3, so leaf function `c()` was omitted. Note that the `-D` option also works with `-F`. Sometimes it's useful to see long-running functions only. This is good because there are usually many tiny functions that are not interesting. The `-t`/`--time-filter` option implements the time-based filter that only records functions which run longer than the given threshold. In the above example, the user might want to see functions running more than 5 microseconds like below: $ uftrace record ./abc $ uftrace replay -t 5us # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { [ 1234] | a() { 5.475 us [ 1234] | b(); 6.448 us [ 1234] | } /* a */ 8.631 us [ 1234] | } /* main */ You can also see replay output with different time threshold for the same recorded data. $ uftrace replay -t 6us # DURATION TID FUNCTION 138.494 us [ 1234] | __cxa_atexit(); [ 1234] | main() { 6.448 us [ 1234] | a(); 8.631 us [ 1234] | } /* main */ In addition, The `-r` option can show functions executed within the given time range. When using this option, you can see TIMESTAMP or ELAPSED fields as well as DURATION and TID. $ uftrace replay -r 502716.387320101~502716.387322389 # TIMESTAMP DURATION TID FUNCTION 502716.387320101 0.289 us [ 6126] | fgets(); 502716.387320584 [ 6126] | get_values_from() { 502716.387320709 0.245 us [ 6126] | strdup(); 502716.387321172 0.144 us [ 6126] | strsep(); 502716.387321542 0.223 us [ 6126] | atoi(); 502716.387321983 0.239 us [ 6126] | atoi(); 502716.387322389 1.805 us [ 6126] | } /* get_values_from */ $ uftrace replay -r 40us~ | head -10 # ELAPSED DURATION TID FUNCTION 40.141 us [ 6126] | get_values_from() { 40.269 us 0.249 us [ 6126] | strdup(); 40.756 us 0.149 us [ 6126] | strsep(); 41.119 us 0.235 us [ 6126] | atoi(); 41.578 us 0.211 us [ 6126] | atoi(); 41.957 us 1.816 us [ 6126] | } /* get_values_from */ 42.124 us 0.220 us [ 6126] | fgets(); 42.529 us [ 6126] | get_values_from() { 42.645 us 0.236 us [ 6126] | strdup(); You can also set triggers on filtered functions. See *TRIGGERS* section below for details. TRIGGERS ======== The uftrace tool supports triggering actions on selected function calls with or without filters. Currently supported triggers are `depth`, `backtrace`, `trace_on` and `trace_off`. The BNF for trigger specifications is like below: := "@" := | "," := "depth=" | "backtrace" | "trace_on" | "trace_off" | "color=" | "time=" | "filter" | "notrace" := [ ] := "ns" | "nsec" | "us" | "usec" | "ms" | "msec" | "s" | "sec" | "m" | "min" The `depth` trigger is to change filter depth during execution of the function. It can be used to apply different filter depths for different functions. And the `backtrace` trigger is used to print a stack backtrace at replay time. The color trigger is to change the color of the function in replay output. The supported colors are `red`, `green`, `blue`, `yellow`, `magenta`, `cyan`, `bold`, and `gray`. The following example shows how triggers work. We set a filter on function `b()` with the `backtrace` action and change the maximum filter depth under `b()` to 2. $ uftrace record ./abc $ uftrace replay -T 'b@filter,backtrace,depth=2' # DURATION TID FUNCTION backtrace [ 1234] | /* [ 0] main */ backtrace [ 1234] | /* [ 1] a */ [ 1234] | b { 3.880 us [ 1234] | c(); 5.475 us [ 1234] | } /* b */ The `trace_on` and `trace_off` actions (the `_` can be omitted as `traceon` and `traceoff`) control whether uftrace shows functions or not. The trigger runs at replay time, not run time, so it can handle kernel functions as well. Contrast this with triggers used under `uftrace record`. The 'time' trigger is to change time filter setting during execution of the function. It can be used to apply different time filter for different functions. The 'filter' and 'notrace' triggers have same effect as -F/--filter and -N/--notrace options respectively. FIELDS ====== The uftrace allows for user to customize the replay output with a couple of fields. Here the field means info on the left side of the pipe (|) character. By default it uses duration and tid fields, but you can use other fields in any order like: $ uftrace replay -f time,delta,duration,addr # TIMESTAMP TIMEDELTA DURATION ADDRESS FUNCTION 74469.340757350 1.583 us 4004d0 | __monstartup(); 74469.340762221 4.871 us 0.766 us 4004f0 | __cxa_atexit(); 74469.340764847 2.626 us 4006b1 | main() { 74469.340765061 0.214 us 400656 | a() { 74469.340765195 0.134 us 400669 | b() { 74469.340765344 0.149 us 40067c | c() { 74469.340765524 0.180 us 0.742 us 4004b0 | getpid(); 74469.340766935 1.411 us 1.591 us 40067c | } /* c */ 74469.340767195 0.260 us 2.000 us 400669 | } /* b */ 74469.340767372 0.177 us 2.311 us 400656 | } /* a */ 74469.340767541 0.169 us 2.694 us 4006b1 | } /* main */ Each field has following meaning: * tid: task id (obtained by gettid(2)) * duration: function execution time * time: timestamp at the execution * delta: difference between two timestamp in a task * elapsed: elapsed time from the first timestamp * addr: address of the function * task: task name (comm) * module: library or executable name of the function The default value is 'duration,tid'. If given field name starts with "+", then it'll be appended to the default fields. So "-f +time" is as same as "-f duration,tid,time". And it also accepts a special field name of 'none' which disables the field display and shows function output only. SEE ALSO ======== `uftrace`(1), `uftrace-record`(1), `uftrace-report`(1), `uftrace-info`(1) uftrace-0.9.3/doc/uftrace-report.md000066400000000000000000000221031351236475300172140ustar00rootroot00000000000000% UFTRACE-REPORT(1) Uftrace User Manuals % Namhyung Kim % Sep, 2018 NAME ==== uftrace-report - Print statistics and summary for trace data SYNOPSIS ======== uftrace report [*options*] DESCRIPTION =========== This command collects trace data from a given data file and prints statistics and summary information. It shows function statistics by default, but can show thread statistics with the `--threads` option and show differences between traces with the `--diff` option. REPORT OPTIONS ============== -s *KEYS*[,*KEYS*,...], \--sort=*KEYS*[,*KEYS*,...] : Sort functions by given KEYS. Multiple KEYS can be given, separated by comma (,). Possible keys are `total` (time), `self` (time), `call`, `avg`, `min`, `max`, `func`. Note that the first 3 keys should be used when neither of `--avg-total` nor `--avg-self` is used. Likewise, the last 3 keys should be used when either of those options is used. \--avg-total : Show average, min, max of each function's total time. \--avg-self : Show average, min, max of each function's self time. \--threads : Report thread summary information rather than function statistics. \--diff=*DATA* : Report differences between the input trace data and the given DATA. \--diff-policy=*POLICY* : Apply custom diff policy. Available values are: "abs", "no-abs", "percent", "no-percent", "compact" and "full". The "abs" is to sort diff result using absolute value so positvie and negative entries can be shown together while "no-abs" will show positive entries first and then negative ones. The "percent" is to show diff in percentage while "no-percent" is to show the values. The "full" is to show all three columns of baseline, new data and difference while "compact" only shows the difference. The default is "abs", "compact" and "no-percent". \--sort-column=*IDX* : When `--diff` is used with "full" policy, 3 columns will be shown for each total time, self time and call count. This option selects the index of the column to be used as a sort key. Index 0 is for original data given by the `--data` option, index 1 is for data given by the `--diff` option, and index 2 is for (percentage) differences between the two data. COMMON OPTIONS ============== -F *FUNC*, \--filter=*FUNC* : Set filter to trace selected functions only. This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -N *FUNC*, \--notrace=*FUNC* : Set filter not to trace selected functions (or the functions called underneath them). This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -C *FUNC*, \--caller-filter=*FUNC* : Set filter to trace callers of selected functions only. This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -T *TRG*, \--trigger=*TRG* : Set trigger on selected functions. This option can be used more than once. See `uftrace-replay`(1) for an explanation of triggers. -D *DEPTH*, \--depth *DEPTH* : Set trace limit in nesting level. -t *TIME*, \--time-filter=*TIME* : Do not account functions which run under the time threshold. If some functions explicitly have the 'trace' trigger applied, those are always accounted regardless of execution time. \--no-libcall : Do not show library calls. \--no-event : Do not show any events. \--match=*TYPE* : Use pattern match using TYPE. Possible types are `regex` and `glob`. Default is `regex`. COMMON ANALYSIS OPTIONS ======================= \--kernel-full : Show all kernel functions, including those called outside of user functions. \--kernel-only : Show kernel functions only without user functions. \--event-full : Show all (user) events outside of user functions. \--tid=*TID*[,*TID*,...] : Only print functions called by the given threads. To see the list of threads in the data file, you can use `uftrace report --threads` or `uftrace info`. This option can also be used more than once. \--demangle=*TYPE* : Use demangled C++ symbol names for filters, triggers, arguments and/or return values. Possible values are "full", "simple" and "no". Default is "simple" which ignores function arguments and template parameters. -r *RANGE*, \--time-range=*RANGE* : Only show functions executed within the time RANGE. The RANGE can be \~\ (separated by "~") and one of \ and \ can be omitted. The \ and \ are timestamp or elapsed time if they have \ postfix, for example '100us'. The timestamp or elapsed time can be shown with `-f time` or `-f elapsed` option respectively in `uftrace replay`(1). EXAMPLE ======= This command shows information like the following: $ uftrace record abc $ uftrace report Total time Self time Calls Function ========== ========== ========== ==================== 150.829 us 150.829 us 1 __cxa_atexit 27.289 us 1.243 us 1 main 26.046 us 0.939 us 1 a 25.107 us 0.934 us 1 b 24.173 us 1.715 us 1 c 22.458 us 22.458 us 1 getpid $ uftrace report -s call,self Total time Self time Calls Function ========== ========== ========== ==================== 150.829 us 150.829 us 1 __cxa_atexit 22.458 us 22.458 us 1 getpid 24.173 us 1.715 us 1 c 27.289 us 1.243 us 1 main 26.046 us 0.939 us 1 a 25.107 us 0.934 us 1 b $ uftrace report --avg-self Avg self Min self Max self Function ========== ========== ========== ==================== 150.829 us 150.829 us 150.829 us __cxa_atexit 22.458 us 22.458 us 22.458 us getpid 1.715 us 1.715 us 1.715 us c 1.243 us 1.243 us 1.243 us main 0.939 us 0.939 us 0.939 us a 0.934 us 0.934 us 0.934 us b $ uftrace report --threads TID Run time Num funcs Start function ===== ========== ========== ========================= 21959 178.118 us 6 main To see a difference between two data: $ uftrace record abc $ uftrace report --diff uftrace.data.old # # uftrace diff # [0] base: uftrace.data (from uftrace record abc ) # [1] diff: uftrace.data.old (from uftrace record abc ) # Total time Self time Calls Function ========== ========== ========== ==================== -0.301 us -0.038 us +0 main -0.263 us -0.070 us +0 a -0.193 us -0.042 us +0 b -0.151 us -0.090 us +0 c -0.131 us -0.131 us +0 __cxa_atexit -0.061 us -0.061 us +0 getpid The above example shows difference sorted by absolute value of total time. The following changes it to use (non-absolute) value of self time. $ uftrace report --diff uftrace.data.old -s self --diff-policy no-abs # # uftrace diff # [0] base: uftrace.data (from uftrace record abc ) # [1] diff: uftrace.data.old (from uftrace record abc ) # Total time Self time Calls Function ========== ========== ========== ==================== -0.301 us -0.038 us +0 main -0.193 us -0.042 us +0 b -0.061 us -0.061 us +0 getpid -0.263 us -0.070 us +0 a -0.151 us -0.090 us +0 c -0.131 us -0.131 us +0 __cxa_atexit By using "full" policy, user can see raw data as well like below. Also it's possible to sort by different column (for raw data). The example below will sort output by total time of the base data. $ uftrace report --diff uftrace.data.old --sort-column 0 --diff-policy full,percent # # uftrace diff # [0] base: uftrace.data (from uftrace record abc ) # [1] diff: uftrace.data.old (from uftrace record abc ) # Total time (diff) Self time (diff) Nr. called (diff) Function ================================ ================================ ================================ ==================== 2.812 us 2.511 us -10.70% 0.403 us 0.365 us -9.43% 1 1 +0 main 2.409 us 2.146 us -10.92% 0.342 us 0.272 us -20.47% 1 1 +0 a 2.067 us 1.874 us -9.34% 0.410 us 0.368 us -10.24% 1 1 +0 b 1.657 us 1.506 us -9.11% 0.890 us 0.800 us -10.11% 1 1 +0 c 0.920 us 0.789 us -14.24% 0.920 us 0.789 us -14.24% 1 1 +0 __cxa_atexit 0.767 us 0.706 us -7.95% 0.767 us 0.706 us -7.95% 1 1 +0 getpid SEE ALSO ======== `uftrace`(1), `uftrace-record`(1), `uftrace-replay`(1), `uftrace-tui`(1) uftrace-0.9.3/doc/uftrace-script.md000066400000000000000000000157741351236475300172250ustar00rootroot00000000000000% UFTRACE-SCRIPT(1) Uftrace User Manuals % Honggyu Kim , Namhyung Kim % Sep, 2018 NAME ==== uftrace-script - Run a script for recorded function trace SYNOPSIS ======== uftrace script [*options*] DESCRIPTION =========== This command runs a script for trace data recorded using the `uftrace-record`(1) command. SCRIPT OPTIONS ============== -S *SCRIPT_PATH*, \--script=*SCRIPT_PATH* : Run a given script to do additional work at the entry and exit of function while processing recorded trace data. The type of script is detected by the postfix such as '.py' for python. See *SCRIPT EXECUTION*. \--record COMMAND [*command-options*] : Record a new trace before running a given script. COMMON OPTIONS ============== -F *FUNC*, \--filter=*FUNC* : Set filter to trace selected functions only. This option can be used more than once. See 'uftrace-replay' for details. -N *FUNC*, \--notrace=*FUNC* : Set filter not to trace selected functions (or the functions called underneath them). This option can be used more than once. See `uftrace-replay` for details. -C *FUNC*, \--caller-filter=*FUNC* : Set filter to trace callers of selected functions only. This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -T *TRG*, \--trigger=*TRG* : Set trigger on selected functions. This option can be used more than once. See 'uftrace-replay' for details. -D *DEPTH*, \--depth *DEPTH* : Set trace limit in nesting level. -t *TIME*, \--time-filter=*TIME* : Do not run script for functions which run under the time threshold. If some functions explicitly have the 'trace' trigger applied, those are always traced regardless of execution time. \--no-libcall : Do not run script for library calls. \--match=*TYPE* : Use pattern match using TYPE. Possible types are `regex` and `glob`. Default is `regex`. COMMON ANALYSIS OPTIONS ======================= \--kernel-full : Run script all kernel functions and events occurred outside of user functions. \--kernel-only : Run script kernel functions only without user functions. \--tid=*TID*[,*TID*,...] : Run script only for functions called by the given threads. To see the list of threads in the data file, you can use `uftrace report --threads` or `uftrace info`. This option can also be used more than once. \--demangle=*TYPE* : Use demangled C++ symbol names for filters, triggers, arguments and/or return values. Possible values are "full", "simple" and "no". Default is "simple" which ignores function arguments and template parameters. -r *RANGE*, \--time-range=*RANGE* : Run script only for functions executed within the time RANGE. The RANGE can be \~\ (separated by "~") and one of \ and \ can be omitted. The \ and \ are timestamp or elapsed time if they have \ postfix, for example '100us'. The timestamp or elapsed time can be shown with `-f time` or `-f elapsed` option respectively in `uftrace replay`(1). SCRIPT EXECUTION ================ The uftrace tool supports script execution for each function entry and exit. The supported script is only Python 2.7 as of now. The user can write four functions. 'uftrace_entry' and 'uftrace_exit' are executed whenever each function is executed at the entry and exit. However 'uftrace_begin' and 'uftrace_end' are only executed once when the target program begins and ends. $ cat scripts/simple.py def uftrace_begin(ctx): print("program begins...") def uftrace_entry(ctx): func = ctx["name"] print("entry : " + func + "()") def uftrace_exit(ctx): func = ctx["name"] print("exit : " + func + "()") def uftrace_end(): print("program is finished") The 'ctx' variable is a dictionary type that contains the below information. /* context information passed to uftrace_entry(ctx) and uftrace_exit(ctx) */ script_context = { int tid; int depth; long timestamp; long duration; # exit only long address; string name; list args; # entry only (if available) value retval; # exit only (if available) }; /* context information passed to uftrace_begin(ctx) */ script_context = { bool record; # True if it runs at record time, otherwise False string version; # uftrace version info list cmds; # execution commands }; The above script can be executed while reading the recorded data. The usage is as follows: $ uftrace record -F main tests/t-abc $ uftrace script -S scripts/simple.py program begins... entry : main() entry : a() entry : b() entry : c() entry : getpid() exit : getpid() exit : c() exit : b() exit : a() exit : main() program is finished The below is another example that shows the different output compared to previous one for the same recorded data. The output looks similar to `uftrace replay` this time. $ uftrace script -S scripts/replay.py # DURATION TID FUNCTION [25794] | main() { [25794] | a() { [25794] | b() { [25794] | c() { [25794] | getpid() { 11.037 us [25794] | } /* getpid */ 44.752 us [25794] | } /* c */ 70.924 us [25794] | } /* b */ 98.191 us [25794] | } /* a */ 124.329 us [25794] | } /* main */ The python script above can be modified to do more output customization. The python script can have an optional "UFTRACE_FUNCS" list which can have name (or pattern depending on the --match option) of functions to run the script. If it exists, only matched functions will run the script. For example, if you add following lines to the script, it will run only for functions with a single letter name. $ echo 'UFTRACE_FUNCS = [ "^.$" ]' >> replay.py $ uftrace script -S replay.py # DURATION TID FUNCTION [25794] | a() { [25794] | b() { [25794] | c() { 44.752 us [25794] | } /* c */ 70.924 us [25794] | } /* b */ 98.191 us [25794] | } /* a */ Also script can have options for record if it requires some form of data (i.e. function argument or return value). A comment line started with "uftrace-option:" will provide (a part of) such options when recording. $ cat arg.py # # uftrace-option: -A a@arg1 -R b@retval # def uftrace_entry(ctx): if "args" in ctx: print(ctx["name"] + " has args") def uftrace_exit(ctx): if "retval" in ctx: print(ctx["name"] + " has retval") $ uftrace record -S arg.py abc a has args b has retval $ uftrace script -S arg.py a has args b has retval SEE ALSO ======== `uftrace`(1), `uftrace-record`(1), `uftrace-replay`(1), `uftrace-live`(1) uftrace-0.9.3/doc/uftrace-tui.md000066400000000000000000000136621351236475300165140ustar00rootroot00000000000000% UFTRACE-TUI(1) Uftrace User Manuals % Namhyung Kim % Jun, 2018 NAME ==== uftrace-tui - (Interactive) Text-based User Interface SYNOPSIS ======== uftrace tui [*options*] DESCRIPTION =========== This command starts an interactive window on a terminal which can show same output of other commands like graph, report and info. Users can navigate the result easily with key presses. The command line options are used to limit the initial data loading. TUI OPTIONS =========== -f *FIELD*, \--output-fields=*FIELD* : Customize field in the output. Possible values are: total, self and addr. Multiple fields can be set by using comma. Special field of 'none' can be used (solely) to hide all fields. Default is 'total'. See `uftrace-graph`(1) for an explanation of fields. COMMON OPTIONS ============== -F *FUNC*, \--filter=*FUNC* : Set filter to trace selected functions only. This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -N *FUNC*, \--notrace=*FUNC* : Set filter not to trace selected functions (or the functions called underneath them). This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -C *FUNC*, \--caller-filter=*FUNC* : Set filter to trace callers of selected functions only. This option can be used more than once. See `uftrace-replay`(1) for an explanation of filters. -T *TRG*, \--trigger=*TRG* : Set trigger on selected functions. This option can be used more than once. See `uftrace-replay`(1) for an explanation of triggers. -D *DEPTH*, \--depth *DEPTH* : Set trace limit in nesting level. -t *TIME*, \--time-filter=*TIME* : Do not show functions which run under the time threshold. If some functions explicitly have the 'trace' trigger applied, those are always traced regardless of execution time. \--no-libcall : Do not show library calls. \--no-event : Do not show any events. \--match=*TYPE* : Use pattern match using TYPE. Possible types are `regex` and `glob`. Default is `regex`. COMMON ANALYSIS OPTIONS ======================= \--kernel-full : Show all kernel functions called outside of user functions. \--kernel-only : Show kernel functions only without user functions. \--event-full : Show all (user) events outside of user functions. \--tid=*TID*[,*TID*,...] : Only print functions called by the given threads. To see the list of threads in the data file, you can use `uftrace report --threads` or `uftrace info`. This option can also be used more than once. \--demangle=*TYPE* : Use demangled C++ symbol names for filters, triggers, arguments and/or return values. Possible values are "full", "simple" and "no". Default is "simple" which ignores function arguments and template parameters. -r *RANGE*, \--time-range=*RANGE* : Only show functions executed within the time RANGE. The RANGE can be \~\ (separated by "~") and one of \ and \ can be omitted. The \ and \ are timestamp or elapsed time if they have \ postfix, for example '100us'. The timestamp or elapsed time can be shown with `-f time` or `-f elapsed` option respectively in `uftrace replay`(1). OUTLINE ======= If there's only one session (the usual case) it'll start with the graph mode to show a full (function) call graph of the session. Users can change to different mode by pressing some keys. The `h` key always is available for help. The current line (marked with '>' below) is displayed with inverted color and arrow keys are used to move the cursor to a different location. TOTAL TIME : FUNCTION > 7.548 us : (1) t-abc 1.811 us : ├─(1) __monstartup : │ 1.266 us : ├─(1) __cxa_atexit : │ 4.471 us : └─(1) main 3.743 us : (1) a 3.194 us : (1) b 2.454 us : (1) c 1.000 us : (1) getpid uftrace graph: session 2a22812ebbd06f40 (/tmp/uftrace/tests/t-abc) If there're more than one session, it'll start with session selection mode. The graph mode is separated for each session but report mode is merged for the whole sessions. Key uftrace command > G call Graph for session #1: t-forkexec call Graph for session #2: t-abc R Report functions I uftrace Info h Help message q quit session a27acff69aec5c9c: exe image: /tmp/uftrace/tests/t-forkexec KEYS ==== Following keys can be used in the TUI window: * `Up`, `Down`: Move cursor up/down * `PageUp`, `PageDown`: Move page up/down * `Home`, `End`: Move to the first/last entry * `Enter`: Fold/unfold graph or Select session * `G`: Show full graph of the current session * `g`: Show backtrace and call graph of the current function * `R`: Show uftrace report * `r`: Show uftrace report of the current function * `I`: Show uftrace info * `S`: Show session list * `O`: Open editor for current function * `c`/`e`: Collapse/Expand direct children graph node * `C`/`E`: Collapse/Expand all descendant graph node * `n`/`p`: Move to next/prev sibling (in graph mode) * `u`: Move up to parent (in graph mode) * `l`: Move to the longest executed child (in graph mode) * `j`/`k`: Move cursor up/down (like vi) * `z`: Set current line to the center of screen * `/`: Start search * `<`/`P`: Search previous match * `>`/`N`: Search next match * `v`: Show debug message * `h`/`?`: Show help window * `q`: Quit SEE ALSO ======== `uftrace`(1), `uftrace-graph`(1), `uftrace-report`(1), `uftrace-info`(1), `uftrace-replay`(1) uftrace-0.9.3/doc/uftrace.html000066400000000000000000003555251351236475300162700ustar00rootroot00000000000000 uftrace uftrace-0.9.3/doc/uftrace.md000066400000000000000000000073541351236475300157160ustar00rootroot00000000000000% UFTRACE(1) Uftrace User Manuals % Namhyung Kim % Sep, 2018 NAME ==== uftrace - Function graph tracer for userspace SYNOPSIS ======== uftrace [*record*|*replay*|*live*|*report*|*info*|*dump*|*recv*|*graph*|*script*|*tui*] [*options*] COMMAND [*command-options*] DESCRIPTION =========== The uftrace tool is a function tracer that traces the execution of given `COMMAND` at the function level. `COMMAND` should be a C or C++ executable built with compiler instrumentation (`-pg` or `-finstrument-functions`). COMMAND needs to have an ELF symbol table (i.e. not be `strip`(1)-ed) in order for the names of traced functions to be available. The uftrace command consists of a number of sub-commands, in the manner of `git`(1) or `perf`(1). Below is a short description of each sub-command. For more detailed information, see the respective manual pages. The options in this page can be given to any sub-command also. For convenience, if no sub-command is given, uftrace acts as though the `live` sub-command was specified, which runs the `record` and `replay` sub-commands in turn. See `uftrace-live`(1) for options belonging to the `live` sub-command. For more detailed analysis, it is better to use `uftrace-record`(1) to save trace data, and then analyze it with other uftrace commands like `uftrace-replay`(1), `uftrace-report`(1), `uftrace-info`(1), `uftrace-dump`(1), `uftrace-script`(1) or `uftrace-tui`(1). SUB-COMMANDS ============ record : Run a given command and save trace data in a data file or directory. replay : Print recorded function trace data with time durations. live : Do live tracing. Print function trace of the given command. report : Print various statistics and summary of the recorded trace data. info : Print side-band information like OS version, CPU info, command line and so on. dump : Print raw tracing data in the data files. recv : Save tracing data sent to network graph : Print function call graph script : Run a script for recorded function trace tui : Show text user interface for graph and report OPTIONS ======= -?, \--help : Print help message and list of options with description -h, \--help : Print help message and list of options with description \--usage : Print usage string -V, \--version : Print program version -v, \--verbose : Print verbose messages. This option increases a debug level and can be used at most 3 times. \--debug : Print debug messages. This option is same as `-v`/`--verbose` and is provided only for backward compatibility. \--debug-domain=*DOMAIN*[,*DOMAIN*, ...] : Limit the printing of debug messages to those belonging to one of the DOMAINs specified. Available domains are: uftrace, symbol, demangle, filter, fstack, session, kernel, mcount, dynamic, event, script and dwarf. The domains can have an their own debug level optionally (preceded by a colon). For example, `-v --debug-domain=filter:2` will apply debug level of 2 to the "filter" domain and apply debug level of 1 to others. -d *DATA*, \--data=*DATA* : Specify name of trace data (directory). Default is `uftrace.data`. \--logfile=*FILE* : Save warning and debug messages into this file instead of stderr. \--color=*VAL* : Enable or disable color on the output. Possible values are "yes"(= "true" | "1" | "on" ), "no"(= "false" | "0" | "off" ) and "auto". The "auto" value is default and turns on coloring if stdout is a terminal. \--no-pager : Do not use a pager. \--opt-file=*FILE* : Read command-line options from the FILE. SEE ALSO ======== `uftrace-live`(1), `uftrace-record`(1), `uftrace-replay`(1), `uftrace-report`(1), `uftrace-info`(1), `uftrace-dump`(1), `uftrace-recv`(1), `uftrace-graph`(1), `uftrace-script`(1), `uftrace-tui(1)` uftrace-0.9.3/gdb/000077500000000000000000000000001351236475300137215ustar00rootroot00000000000000uftrace-0.9.3/gdb/uftrace/000077500000000000000000000000001351236475300153525ustar00rootroot00000000000000uftrace-0.9.3/gdb/uftrace/lists.py000066400000000000000000000071271351236475300170710ustar00rootroot00000000000000# # gdb helper commands and functions for uftrace debugging # copied from the Linux kernel source # # list tools # # Copyright (c) Thiebaud Weksteen, 2015 # # Authors: # Thiebaud Weksteen # # This work is licensed under the terms of the GNU GPL version 2. # import gdb from uftrace import utils list_head = utils.CachedType("struct list_head") def list_for_each(head): if head.type == list_head.get_type().pointer(): head = head.dereference() elif head.type != list_head.get_type(): raise gdb.GdbError("Must be struct list_head not {}" .format(head.type)) node = head['next'].dereference() while node.address != head.address: yield node.address node = node['next'].dereference() def list_for_each_entry(head, gdbtype, member): for node in list_for_each(head): if node.type != list_head.get_type().pointer(): raise TypeError("Type {} found. Expected struct list_head *." .format(node.type)) yield utils.container_of(node, gdbtype, member) def list_check(head): nb = 0 if (head.type == list_head.get_type().pointer()): head = head.dereference() elif (head.type != list_head.get_type()): raise gdb.GdbError('argument must be of type (struct list_head [*])') c = head try: gdb.write("Starting with: {}\n".format(c)) except gdb.MemoryError: gdb.write('head is not accessible\n') return while True: p = c['prev'].dereference() n = c['next'].dereference() try: if p['next'] != c.address: gdb.write('prev.next != current: ' 'current@{current_addr}={current} ' 'prev@{p_addr}={p}\n'.format( current_addr=c.address, current=c, p_addr=p.address, p=p, )) return except gdb.MemoryError: gdb.write('prev is not accessible: ' 'current@{current_addr}={current}\n'.format( current_addr=c.address, current=c )) return try: if n['prev'] != c.address: gdb.write('next.prev != current: ' 'current@{current_addr}={current} ' 'next@{n_addr}={n}\n'.format( current_addr=c.address, current=c, n_addr=n.address, n=n, )) return except gdb.MemoryError: gdb.write('next is not accessible: ' 'current@{current_addr}={current}\n'.format( current_addr=c.address, current=c )) return c = n nb += 1 if c == head: gdb.write("list is consistent: {} node(s)\n".format(nb)) return class UftListChk(gdb.Command): """Verify a list consistency""" def __init__(self): super(UftListChk, self).__init__("uft-list-check", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION) def invoke(self, arg, from_tty): argv = gdb.string_to_argv(arg) if len(argv) != 1: raise gdb.GdbError("uft-list-check takes one argument") list_check(gdb.parse_and_eval(argv[0])) UftListChk() uftrace-0.9.3/gdb/uftrace/mcount.py000066400000000000000000000067661351236475300172500ustar00rootroot00000000000000# # gdb helper commands and functions for uftrace debugging # # mcount tools # # Copyright (c) LG Electronics, 2018 # # Authors: # Namhyung Kim # # This work is licensed under the terms of the GNU GPL version 2. # import gdb from uftrace import utils from uftrace import rbtree from uftrace import trigger filter_type = utils.CachedType("struct uftrace_filter") def get_symbol_name(addr): try: block = gdb.block_for_pc(int(addr)) except: try: return gdb.execute('info symbol ' + hex(addr), False, True).split(' ')[0] except: return '' while block and not block.function: block = block.superblock if block is None: return '' return block.function.print_name class UftMcountData(gdb.Command): """Find mcount thread data of current thread and show return stacks.""" def __init__(self): super(UftMcountData, self).__init__("uft-mcount-data", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): mtd = utils.gdb_eval_or_none("mtd") if mtd is None: gdb.write("no mtd found\n") return mtd_idx = mtd['idx'] gdb.write("mtd: tid = {tid}, idx = {idx}\n".format( tid=mtd['tid'], idx=mtd_idx)) rstack = mtd['rstack'] for i in range(0, mtd_idx): cip = rstack[i]['child_ip'] pip = rstack[i]['parent_ip'] csym = get_symbol_name(cip) psym = get_symbol_name(pip) gdb.write("[{ind}] {child} <== {parent}\n".format( ind=i, child=csym, parent=psym)) UftMcountData() class UftMcountFilter(gdb.Command): """List mcount filters.""" def __init__(self): super(UftMcountFilter, self).__init__("uft-mcount-filters", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): tr = utils.gdb_eval_or_none("mcount_triggers") if tr is None: gdb.write("no filter/trigger found\n") return filter_ptr_type = filter_type.get_type().pointer() trigger.filter_print(None) for filt in rbtree.rb_for_each_entry(tr, filter_ptr_type, "node"): trigger.filter_print(filt) UftMcountFilter() class UftMcountTrigger(gdb.Command): """List mcount triggers.""" def __init__(self): super(UftMcountTrigger, self).__init__("uft-mcount-triggers", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): tr = utils.gdb_eval_or_none("mcount_triggers") if tr is None: gdb.write("no filter/trigger found\n") return verbose = len(arg) > 0 filter_ptr_type = filter_type.get_type().pointer() trigger.trigger_print(None, False) for filt in rbtree.rb_for_each_entry(tr, filter_ptr_type, "node"): trigger.trigger_print(filt, verbose) UftMcountTrigger() class UftMcountArgspec(gdb.Command): """List mcount arguments and return values.""" def __init__(self): super(UftMcountArgspec, self).__init__("uft-mcount-args", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): tr = utils.gdb_eval_or_none("mcount_triggers") if tr is None: gdb.write("no filter/trigger found\n") return verbose = len(arg) > 0 filter_ptr_type = filter_type.get_type().pointer() trigger.argspec_print(None, False) for filt in rbtree.rb_for_each_entry(tr, filter_ptr_type, "node"): trigger.argspec_print(filt, verbose) UftMcountArgspec() uftrace-0.9.3/gdb/uftrace/plthook.py000066400000000000000000000030751351236475300174110ustar00rootroot00000000000000# # gdb helper commands and functions for uftrace debugging # copied from the Linux kernel source (module tools) # # plthook tools # # Copyright (c) Siemens AG, 2013 # Copyright (c) LG Electronics, 2018 # # Authors: # Jan Kiszka # Namhyung Kim # # This work is licensed under the terms of the GNU GPL version 2. # import gdb import os from uftrace import utils, lists plthook_data_type = utils.CachedType("struct plthook_data") def plthook_list(): plthook_modules = utils.gdb_eval_or_none("plthook_modules") if plthook_modules is None: return pd_ptr_type = plthook_data_type.get_type().pointer() for module in lists.list_for_each_entry(plthook_modules, pd_ptr_type, "list"): yield module def find_module_by_name(name): for module in plthook_list(): if os.path.basename(module['mod_name'].string()) == name: return module return None class UftPlthookData(gdb.Command): """List currently loaded plthook modules.""" def __init__(self): super(UftPlthookData, self).__init__("uft-plthook-data", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): gdb.write("{id:>16} {addr:>16} {name:<32}\n".format( id="Module Id", name="Name", addr="Base Address")) for module in plthook_list(): gdb.write("{id:>16} {addr:>16} {name:<32}\n".format( id=hex(module['module_id']), addr=hex(module['base_addr']), name=os.path.basename(module['mod_name'].string()))) UftPlthookData() uftrace-0.9.3/gdb/uftrace/rbtree.py000066400000000000000000000076401351236475300172160ustar00rootroot00000000000000# # gdb helper commands and functions for uftrace debugging # # rbtree tools # # Copyright (c) LG Electronics, 2018 # # Authors: # Namhyung Kim # # This work is licensed under the terms of the GNU GPL version 2. # import gdb from uftrace import utils rb_root = utils.CachedType("struct rb_root") rb_node = utils.CachedType("struct rb_node") def rb_first(root): if root.type == rb_root.get_type().pointer(): root = root.dereference() elif root.type != rb_root.get_type(): raise gdb.GdbError("Must be struct rb_root not {}" .format(root.type)) node = root['rb_node'].dereference() if node.address == 0: return None if node.type != rb_node.get_type(): raise gdb.GdbError("Must be struct rb_ndoe not {}" .format(node.type)) left = node['rb_left'].dereference() while left.address != 0: node = left left = node['rb_left'].dereference() return node def rb_last(root): if root.type == rb_root.get_type().pointer(): root = root.dereference() elif root.type != rb_root.get_type(): raise gdb.GdbError("Must be struct rb_root not {}" .format(root.type)) node = root['rb_node'].dereference() if node.address == 0: return None right = node['rb_right'].dereference() while right.address != 0: node = right right = node['rb_right'].dereference() return node def rb_parent(node): addr = int(node['rb_parent_color']) addr &= ~3 # clear color bit if addr == 0: return None # Value.address is read-only, just create a new value # using Value.cast() after changing its address node = gdb.Value(addr) p = node.cast(rb_node.get_type().pointer()) return p.dereference() def rb_next(node): if node.type == rb_node.get_type().pointer(): node = node.dereference() elif node.type != rb_node.get_type(): raise gdb.GdbError("Must be struct rb_node not {}" .format(node.type)) parent = rb_parent(node) if parent is not None and parent.address == node.address: return None r = node['rb_right'].dereference() if r.address != 0: node = r left = node['rb_left'].dereference() while left.address != 0: node = left left = node['rb_left'].dereference() return node while parent is not None: right_child = parent['rb_right'].dereference() if node.address != right_child.address: break node = parent parent = rb_parent(node) return parent def rb_prev(node): if node.type == rb_node.get_type().pointer(): node = node.dereference() elif node.type != rb_node.get_type(): raise gdb.GdbError("Must be struct rb_node not {}" .format(node.type)) parent = rb_parent(node) if parent is not None and parent.address == node.address: return None l = node['rb_left'].dereference() if l.address != 0: node = l right = node['rb_right'].dereference() while right.address != 0: node = right right = node['rb_right'].dereference() return node while parent is not None: left_child = parent['rb_left'].dereference() if node.address != left_child.address: break node = parent parent = rb_parent(node) return parent def rb_for_each(root): node = rb_first(root) while node is not None: yield node.address node = rb_next(node) def rb_for_each_entry(head, gdbtype, member): for node in rb_for_each(head): if node.type != rb_node.get_type().pointer(): raise TypeError("Type {} found. Expected struct rb_node *." .format(node.type)) yield utils.container_of(node, gdbtype, member) uftrace-0.9.3/gdb/uftrace/trigger.py000066400000000000000000000077631351236475300174040ustar00rootroot00000000000000# # gdb helper commands and functions for uftrace debugging # # filter and trigger tools # # Copyright (c) LG Electronics, 2018 # # Authors: # Namhyung Kim # # This work is licensed under the terms of the GNU GPL version 2. # import gdb from uftrace import utils from uftrace import lists filter_type = utils.CachedType("struct uftrace_filter") trigger_type = utils.CachedType("struct uftrace_trigger") argspec_type = utils.CachedType("struct uftrace_arg_spec") TRIGGER_FLAGS = [ "DEPTH", "FILTER", "BACKTRACE", "TRACE", "TRACE_ON", "TRACE_OFF", "ARGUMENT", "RECOVER", "RETVAL", "COLOR", "TIME_FILTER", "READ", "FINISH", "AUTO_ARGS" ] TR_FLAG_FILTERS = 1 + 2 + 1024 # DEPTH | FILTER | TIME_FILTER TR_FLAG_ARGS = 64 + 256 + 8192 # ARGUMENT | RETVAL | AUTO_ARGS TR_FLAG_READ = 2048 ARG_TYPE_INDEX = 0 ARG_TYPE_FLOAT = 1 ARG_TYPE_REG = 2 ARG_TYPE_STACK = 3 ARG_FMT_AUTO = 0 ARG_FMT_STR = "diuxscfSpe" def filter_flag(tr): flag = tr['flags'] fmode = tr['fmode'] f = 'D' if flag & 1 else ' ' if flag & 2: f += 'F' if fmode == 1 else 'N' f += 't' if flag >= 1024 else ' ' return f def filter_print(filt): if filt is None: gdb.write("{start:>16} {end:<16} {flag:4} {name}\n". format(start="Start", end="End", flag="Flag", name="Name")) return tr = filt['trigger'] flags = tr['flags'] if (flags & TR_FLAG_FILTERS) == 0: return gdb.write("{start:>16} - {end:<16} : {flag:4} {name}\n". format(start=hex(filt['start']), end=hex(filt['end']), flag=filter_flag(tr), name=filt['name'].string())) def trigger_flag(tr): flags = tr['flags'] s = [] for bit, flag in enumerate(TRIGGER_FLAGS): if flags & (1 << bit): s.append(flag) return '|'.join(s) def trigger_print(filt, verbose): if filt is None: gdb.write("{start:>16} {end:<16} {flag:>6} {name}\n". format(start="Start", end="End", flag="Flags", name="Name")) return tr = filt['trigger'] gdb.write("{start:>16} - {end:<16} : {flag:>6} {name}\n". format(start=hex(filt['start']), end=hex(filt['end']), flag=hex(tr['flags']), name=filt['name'].string())) if verbose: gdb.write(" triggers = {flags}\n".format(flags=trigger_flag(tr))) def trigger_argspec(tr): argspec_ptr_type = argspec_type.get_type().pointer() s = [] for arg in lists.list_for_each_entry(tr['pargs'], argspec_ptr_type, 'list'): t = arg['type'] if t == ARG_TYPE_INDEX: idx = int(arg['idx']) if idx == 0: a = 'retval' else: a = 'arg{i}'.format(i=int(arg['idx'])) elif t == ARG_TYPE_FLOAT: a = 'fparg{i}'.format(i=int(arg['idx'])) elif t == ARG_TYPE_REG: a = 'reg{i}'.format(i=int(arg['reg_idx'])) elif t == ARG_TYPE_STACK: a = 'stack+{i}'.format(i=int(arg['stack_ofs'])) f = arg['fmt'] if f != ARG_FMT_AUTO: a += "/{fmt}{sz}".format(fmt=ARG_FMT_STR[f], sz=arg['size']*8) s.append(a) return ','.join(s) def argspec_flag(flags): if flags >= 8192: # AUTO_ARGS return "AA" f = 'A' if flags & 64 else ' ' f += 'R' if flags & 256 else ' ' return f def argspec_print(filt, verbose): if filt is None: gdb.write("{start:>16} {end:<16} {flag:4} {name}\n". format(start="Start", end="End", flag="Flag", name="Name")) return tr = filt['trigger'] flags = tr['flags'] if (flags & TR_FLAG_ARGS) == 0: return gdb.write("{start:>16} - {end:<16} : {flag:4} {name}\n". format(start=hex(filt['start']), end=hex(filt['end']), flag=argspec_flag(flags), name=filt['name'].string())) if verbose: gdb.write(" argspec = {spec}\n".format(spec=trigger_argspec(tr))) uftrace-0.9.3/gdb/uftrace/utils.py000066400000000000000000000044571351236475300170760ustar00rootroot00000000000000# # gdb helper commands and functions for uftrace debugging # copied from the Linux kernel source # # common utilities # # Copyright (c) Siemens AG, 2011-2013 # # Authors: # Jan Kiszka # # This work is licensed under the terms of the GNU GPL version 2. # import gdb class CachedType: def __init__(self, name): self._type = None self._name = name def _new_objfile_handler(self, event): self._type = None gdb.events.new_objfile.disconnect(self._new_objfile_handler) def get_type(self): if self._type is None: self._type = gdb.lookup_type(self._name) if self._type is None: raise gdb.GdbError( "cannot resolve type '{0}'".format(self._name)) if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'): gdb.events.new_objfile.connect(self._new_objfile_handler) return self._type long_type = CachedType("long") def get_long_type(): global long_type return long_type.get_type() def offset_of(typeobj, field): element = gdb.Value(0).cast(typeobj) return int(str(element[field].address).split()[0], 16) def container_of(ptr, typeobj, member): return (ptr.cast(get_long_type()) - offset_of(typeobj, member)).cast(typeobj) class ContainerOf(gdb.Function): """Return pointer to containing data structure. $container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the data structure of the type TYPE in which PTR is the address of ELEMENT. Note that TYPE and ELEMENT have to be quoted as strings.""" def __init__(self): super(ContainerOf, self).__init__("container_of") def invoke(self, ptr, typename, elementname): return container_of(ptr, gdb.lookup_type(typename.string()).pointer(), elementname.string()) ContainerOf() def gdb_eval_or_none(expresssion): try: return gdb.parse_and_eval(expresssion) except: return None class UftTest(gdb.Command): """test gdb python scripting""" def __init__(self): super(UftTest, self).__init__("uft-test", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION) def invoke(self, arg, from_tty): gdb.write("python scripting test\n") UftTest() uftrace-0.9.3/libmcount/000077500000000000000000000000001351236475300151615ustar00rootroot00000000000000uftrace-0.9.3/libmcount/dynamic.c000066400000000000000000000215521351236475300167560ustar00rootroot00000000000000#include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "dynamic" #define PR_DOMAIN DBG_DYNAMIC #include "libmcount/mcount.h" #include "libmcount/internal.h" #include "utils/utils.h" #include "utils/symbol.h" #include "utils/filter.h" #include "utils/rbtree.h" #include "utils/list.h" static struct mcount_dynamic_info *mdinfo; static struct mcount_dynamic_stats { int total; int failed; int skipped; int nomatch; } stats; #define PAGE_SIZE 4096 #define CODE_CHUNK (PAGE_SIZE * 8) struct code_page { struct list_head list; void *page; int pos; }; static LIST_HEAD(code_pages); static struct rb_root code_tree = RB_ROOT; static struct mcount_orig_insn *lookup_code(struct rb_root *root, unsigned long addr, bool create) { struct rb_node *parent = NULL; struct rb_node **p = &root->rb_node; struct mcount_orig_insn *iter; while (*p) { parent = *p; iter = rb_entry(parent, struct mcount_orig_insn, node); if (iter->addr == addr) return iter; if (iter->addr > addr) p = &parent->rb_left; else p = &parent->rb_right; } if (!create) return NULL; iter = xmalloc(sizeof(*iter)); iter->addr = addr; rb_link_node(&iter->node, parent, p); rb_insert_color(&iter->node, root); return iter; } struct mcount_orig_insn *mcount_save_code(unsigned long addr, unsigned insn_size, void *jmp_insn, unsigned jmp_size) { struct code_page *cp = NULL; struct mcount_orig_insn *orig; const int patch_size = ALIGN(insn_size + jmp_size, 32); if (!list_empty(&code_pages)) cp = list_last_entry(&code_pages, struct code_page, list); if (cp == NULL || (cp->pos + patch_size > CODE_CHUNK)) { cp = xmalloc(sizeof(*cp)); cp->page = mmap(NULL, CODE_CHUNK, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (cp->page == MAP_FAILED) pr_err("mmap code page failed"); cp->pos = 0; list_add_tail(&cp->list, &code_pages); } orig = lookup_code(&code_tree, addr, true); orig->insn = cp->page + cp->pos; memcpy(orig->insn, (void *)addr, insn_size); memcpy(orig->insn + insn_size, jmp_insn, jmp_size); cp->pos += patch_size; return orig; } void mcount_freeze_code(void) { struct code_page *cp; list_for_each_entry(cp, &code_pages, list) mprotect(cp->page, CODE_CHUNK, PROT_EXEC); } void *mcount_find_code(unsigned long addr) { struct mcount_orig_insn *orig; orig = lookup_code(&code_tree, addr, false); if (orig == NULL) return NULL; return orig->insn; } /* dummy functions (will be overridden by arch-specific code) */ __weak int mcount_setup_trampoline(struct mcount_dynamic_info *mdi) { return -1; } __weak void mcount_cleanup_trampoline(struct mcount_dynamic_info *mdi) { } __weak int mcount_patch_func(struct mcount_dynamic_info *mdi, struct sym *sym, struct mcount_disasm_engine *disasm, unsigned min_size) { return -1; } __weak void mcount_arch_find_module(struct mcount_dynamic_info *mdi, struct symtab *symtab) { mdi->arch = NULL; } __weak void mcount_arch_dynamic_recover(struct mcount_dynamic_info *mdi, struct mcount_disasm_engine *disasm) { } __weak void mcount_disasm_init(struct mcount_disasm_engine *disasm) { } __weak void mcount_disasm_finish(struct mcount_disasm_engine *disasm) { } struct find_module_data { struct symtabs *symtabs; bool needs_modules; }; /* callback for dl_iterate_phdr() */ static int find_dynamic_module(struct dl_phdr_info *info, size_t sz, void *data) { struct mcount_dynamic_info *mdi; struct find_module_data *fmd = data; struct symtabs *symtabs = fmd->symtabs; struct uftrace_mmap *map; bool base_addr_set = false; unsigned i; mdi = xzalloc(sizeof(*mdi)); for (i = 0; i < info->dlpi_phnum; i++) { if (info->dlpi_phdr[i].p_type != PT_LOAD) continue; if (!base_addr_set) { mdi->base_addr = info->dlpi_phdr[i].p_vaddr; base_addr_set = true; } if (!(info->dlpi_phdr[i].p_flags & PF_X)) continue; /* find address and size of code segment */ mdi->text_addr = info->dlpi_phdr[i].p_vaddr; mdi->text_size = info->dlpi_phdr[i].p_memsz; break; } mdi->base_addr += info->dlpi_addr; mdi->text_addr += info->dlpi_addr; map = find_map(symtabs, mdi->base_addr); if (map && map->mod) { mdi->map = map; mcount_arch_find_module(mdi, &map->mod->symtab); mdi->next = mdinfo; mdinfo = mdi; } else { free(mdi); } return !fmd->needs_modules; } static void prepare_dynamic_update(struct mcount_disasm_engine *disasm, struct symtabs *symtabs, bool needs_modules) { struct find_module_data fmd = { .symtabs = symtabs, .needs_modules = needs_modules, }; mcount_disasm_init(disasm); dl_iterate_phdr(find_dynamic_module, &fmd); } struct mcount_dynamic_info *setup_trampoline(struct uftrace_mmap *map) { struct mcount_dynamic_info *mdi; for (mdi = mdinfo; mdi != NULL; mdi = mdi->next) { if (map == mdi->map) break; } if (mdi != NULL && mdi->trampoline == 0) { if (mcount_setup_trampoline(mdi) < 0) mdi = NULL; } return mdi; } static int do_dynamic_update(struct symtabs *symtabs, char *patch_funcs, enum uftrace_pattern_type ptype, struct mcount_disasm_engine *disasm, unsigned min_size) { struct symtab *symtab; struct strv funcs = STRV_INIT; char *name; int j; /* skip special startup (csu) functions */ const char *csu_skip_syms[] = { "_start", "__libc_csu_init", "__libc_csu_fini", }; if (patch_funcs == NULL) return 0; strv_split(&funcs, patch_funcs, ";"); strv_for_each(&funcs, name, j) { bool found = false; bool csu_skip; char *modname, *delim; unsigned i, k; struct sym *sym; struct uftrace_pattern patt; struct uftrace_mmap *map; struct mcount_dynamic_info *mdi = NULL; delim = strchr(name, '@'); if (delim == NULL) { /* first of uftrace_mmap is main module always. */ map = symtabs->maps; symtab = &symtabs->maps->mod->symtab; } else { *delim = '\0'; modname = ++delim; map = find_map_by_name(symtabs, modname); if (map == NULL || map->mod == NULL) { pr_dbg("Failed to find map of %s\n", modname); continue; } symtab = &map->mod->symtab; } mdi = setup_trampoline(map); if (mdi == NULL) { pr_warn("Failed to set the trampoline into %s\n", map->libname); continue; } init_filter_pattern(ptype, &patt, name); for (i = 0; i < symtab->nr_sym; i++) { sym = &symtab->sym[i]; csu_skip = false; for (k = 0; k < ARRAY_SIZE(csu_skip_syms); k++) { if (!strcmp(sym->name, csu_skip_syms[k])) { csu_skip = true; break; } } if (csu_skip) continue; if (sym->type != ST_LOCAL_FUNC && sym->type != ST_GLOBAL_FUNC) continue; if (!match_filter_pattern(&patt, sym->name)) continue; found = true; switch (mcount_patch_func(mdi, sym, disasm, min_size)) { case INSTRUMENT_FAILED: stats.failed++; break; case INSTRUMENT_SKIPPED: stats.skipped++; break; case INSTRUMENT_SUCCESS: default: break; } stats.total++; } if (!found) stats.nomatch++; free_filter_pattern(&patt); } if (stats.failed + stats.skipped + stats.nomatch == 0) { pr_dbg("patched all (%d) functions in '%s'\n", stats.total, basename(symtabs->filename)); } strv_free(&funcs); return 0; } static void finish_dynamic_update(struct mcount_disasm_engine *disasm) { struct mcount_dynamic_info *mdi, *tmp; mdi = mdinfo; while (mdi) { tmp = mdi->next; mcount_arch_dynamic_recover(mdi, disasm); mcount_cleanup_trampoline(mdi); free(mdi); mdi = tmp; } mcount_disasm_finish(disasm); mcount_freeze_code(); } /* do not use floating-point in libmcount */ static int calc_percent(int n, int total, int *rem) { int quot = 100 * n / total; *rem = (100 * n - quot * total) * 100 / total; return quot; } int mcount_dynamic_update(struct symtabs *symtabs, char *patch_funcs, enum uftrace_pattern_type ptype, struct mcount_disasm_engine *disasm) { int ret = 0; char *size_filter; unsigned min_size = 0; bool needs_modules = !!strchr(patch_funcs, '@'); prepare_dynamic_update(disasm, symtabs, needs_modules); size_filter = getenv("UFTRACE_PATCH_SIZE"); if (size_filter != NULL) min_size = strtoul(size_filter, NULL, 0); ret = do_dynamic_update(symtabs, patch_funcs, ptype, disasm, min_size); if (stats.total && stats.failed) { int success = stats.total - stats.failed - stats.skipped; int r, q; pr_dbg("dynamic patch stats for '%s'\n", basename(symtabs->filename)); pr_dbg(" total: %8d\n", stats.total); q = calc_percent(success, stats.total, &r); pr_dbg(" patched: %8d (%2d.%02d%%)\n", success, q, r); q = calc_percent(stats.failed, stats.total, &r); pr_dbg(" failed: %8d (%2d.%02d%%)\n", stats.failed, q, r); q = calc_percent(stats.skipped, stats.total, &r); pr_dbg(" skipped: %8d (%2d.%02d%%)\n", stats.skipped, q, r); pr_dbg("no match: %8d\n", stats.nomatch); } finish_dynamic_update(disasm); return ret; } uftrace-0.9.3/libmcount/event.c000066400000000000000000000127261351236475300164560ustar00rootroot00000000000000#include #include #include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "event" #define PR_DOMAIN DBG_EVENT #include "libmcount/mcount.h" #include "libmcount/internal.h" #include "utils/utils.h" #include "utils/list.h" #include "utils/filter.h" #define SDT_SECT ".note.stapsdt" #define SDT_NAME "stapsdt" #define SDT_TYPE 3 /* systemtap SDT data structure */ struct stapsdt { unsigned long probe_addr; unsigned long link_addr; unsigned long sema_addr; char vea[]; /* vendor + event + arguments */ }; /* user-given event specifier (may contains patterns) */ struct event_spec { struct list_head list; struct uftrace_pattern provider; struct uftrace_pattern event; }; /* list of event spec */ static LIST_HEAD(events); /* event id which is allocated dynamically */ static unsigned event_id = EVENT_ID_USER; __weak int mcount_arch_enable_event(struct mcount_event_info *mei) { return 0; } static int search_sdt_event(struct dl_phdr_info *info, size_t sz, void *data) { const char *name = info->dlpi_name; struct mcount_event_info *mei; struct list_head *spec_list = data; struct uftrace_elf_data elf; struct uftrace_elf_iter iter; bool found_sdt = false; int ret = -1; if (name[0] == '\0') name = read_exename(); if (elf_init(name, &elf) < 0) { pr_dbg("error during open file: %s: %m\n", name); return -1; } elf_for_each_shdr(&elf, &iter) { char *shstr; if (iter.shdr.sh_type != SHT_NOTE) continue; /* there can be more than one note sections */ shstr = elf_get_name(&elf, &iter, iter.shdr.sh_name); if (strcmp(shstr, SDT_SECT) == 0) { found_sdt = true; break; } } if (!found_sdt) { ret = 0; goto out; } pr_dbg2("loading sdt notes from %s\n", name); elf_for_each_note(&elf, &iter) { struct stapsdt *sdt; struct event_spec *spec; char *vendor, *event, *args; if (strncmp(iter.note_name, SDT_NAME, iter.nhdr.n_namesz)) continue; if (iter.nhdr.n_type != SDT_TYPE) continue; sdt = iter.note_desc; vendor = sdt->vea; event = vendor + strlen(vendor) + 1; args = event + strlen(event) + 1; if (list_empty(spec_list)) { /* just listing available events */ pr_out("[SDT event] %s:%s %s\n", vendor, event, args); continue; } list_for_each_entry(spec, spec_list, list) { if (!match_filter_pattern(&spec->provider, vendor)) continue; if (!match_filter_pattern(&spec->event, event)) continue; break; } if (list_no_entry(spec, spec_list, list)) continue; mei = xmalloc(sizeof(*mei)); mei->id = event_id++; mei->addr = info->dlpi_addr + sdt->probe_addr; mei->module = xstrdup(name); mei->provider = xstrdup(vendor); mei->event = xstrdup(event); mei->arguments = xstrdup(args); pr_dbg("adding SDT event (%s:%s) from %s at %#lx\n", mei->provider, mei->event, mei->module, mei->addr); list_add_tail(&mei->list, &events); } ret = 0; out: elf_finish(&elf); return ret; } int mcount_setup_events(char *dirname, char *event_str, enum uftrace_pattern_type ptype) { int ret = 0; FILE *fp; char *filename = NULL; struct mcount_event_info *mei; struct strv strv = STRV_INIT; LIST_HEAD(specs); struct event_spec *es, *tmp; char *spec; int i; strv_split(&strv, event_str, ";"); strv_for_each(&strv, spec, i) { char *sep = strchr(spec, ':'); char *kernel; if (sep) { *sep++ = '\0'; kernel = has_kernel_filter(sep); if (kernel) continue; es = xmalloc(sizeof(*es)); init_filter_pattern(ptype, &es->provider, spec); init_filter_pattern(ptype, &es->event, sep); list_add_tail(&es->list, &specs); } else { pr_dbg("ignore invalid event spec: %s\n", spec); } } dl_iterate_phdr(search_sdt_event, &specs); list_for_each_entry_safe(es, tmp, &specs, list) { list_del(&es->list); free_filter_pattern(&es->provider); free_filter_pattern(&es->event); free(es); } strv_free(&strv); if (list_empty(&events)) { pr_dbg("cannot find any event for %s\n", event_str); goto out; } xasprintf(&filename, "%s/events.txt", dirname); fp = fopen(filename, "w"); if (fp == NULL) pr_err("cannot open file: %s", filename); list_for_each_entry(mei, &events, list) { fprintf(fp, "EVENT: %u %s:%s\n", mei->id, mei->provider, mei->event); } fclose(fp); free(filename); list_for_each_entry(mei, &events, list) { /* ignore failures */ mcount_arch_enable_event(mei); } out: return ret; } struct mcount_event_info * mcount_lookup_event(unsigned long addr) { struct mcount_event_info *mei; list_for_each_entry(mei, &events, list) { if (mei->addr == addr) return mei; } return NULL; } void mcount_list_events(void) { LIST_HEAD(list); dl_iterate_phdr(search_sdt_event, &list); } /* save an asynchronous event */ int mcount_save_event(struct mcount_event_info *mei) { struct mcount_thread_data *mtdp; if (unlikely(mcount_should_stop())) return -1; mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) return -1; if (mtdp->nr_events < MAX_EVENT) { int i = mtdp->nr_events++; mtdp->event[i].id = mei->id; mtdp->event[i].time = mcount_gettime(); mtdp->event[i].dsize = 0; mtdp->event[i].idx = ASYNC_IDX; } return 0; } void mcount_finish_events(void) { struct mcount_event_info *mei, *tmp; list_for_each_entry_safe(mei, tmp, &events, list) { list_del(&mei->list); free(mei->module); free(mei->provider); free(mei->event); free(mei->arguments); free(mei); } } uftrace-0.9.3/libmcount/internal.h000066400000000000000000000306731351236475300171570ustar00rootroot00000000000000/* * internal routines and data structures for handling mcount records * * Copyright (C) 2014-2018, LG Electronics, Namhyung Kim * * Released under the GPL v2. */ #ifndef UFTRACE_MCOUNT_INTERNAL_H #define UFTRACE_MCOUNT_INTERNAL_H #include #include #include #include #include #include #include #ifdef HAVE_LIBCAPSTONE # include #endif #include "uftrace.h" #include "mcount-arch.h" #include "utils/rbtree.h" #include "utils/symbol.h" #include "utils/filter.h" #include "utils/compiler.h" /* could be defined in mcount-arch.h */ #ifndef ARCH_SUPPORT_AUTO_RECOVER # define ARCH_SUPPORT_AUTO_RECOVER 0 #endif /* plt_hooker has return address to hook */ #ifndef ARCH_CAN_RESTORE_PLTHOOK # define ARCH_CAN_RESTORE_PLTHOOK 0 #endif enum filter_result { FILTER_RSTACK = -1, FILTER_OUT, FILTER_IN, }; #ifndef DISABLE_MCOUNT_FILTER struct filter_control { int in_count; int out_count; uint16_t depth; uint16_t saved_depth; uint64_t time; uint64_t saved_time; }; #else struct filter_control {}; #endif struct mcount_shmem { unsigned seqnum; int losts; int curr; int nr_buf; int max_buf; bool done; struct mcount_shmem_buffer **buffer; }; /* first 4 byte saves the actual size of the argbuf */ #define ARGBUF_SIZE 1024 #define EVTBUF_SIZE (ARGBUF_SIZE - 16) #define EVTBUF_HDR (offsetof(struct mcount_event, data)) struct mcount_event { uint64_t time; uint32_t id; uint16_t dsize; uint16_t idx; uint8_t data[EVTBUF_SIZE]; }; #define ASYNC_IDX 0xffff #define MAX_EVENT 4 enum mcount_watch_item { MCOUNT_WATCH_NONE = 0, MCOUNT_WATCH_CPU = (1 << 0), }; struct mcount_watchpoint { bool inited; /* per-thread watch points */ int cpu; /* global watch points */ }; #ifndef DISABLE_MCOUNT_FILTER struct mcount_mem_regions { struct rb_root root; unsigned long heap; unsigned long brk; }; void finish_mem_region(struct mcount_mem_regions *regions); #else struct mcount_mem_regions {}; static inline void finish_mem_region(struct mcount_mem_regions *regions) {} #endif /* * The idx and record_idx are to save current index of the rstack. * In general, both will have same value but in case of cygprof * functions, it may differ if filters applied. * * This is because how cygprof handles filters - cygprof_exit() should * be called for filtered functions while mcount_exit() is not. The * mcount_record_idx is only increased/decreased when the function is * not filtered out so that we can keep proper depth in the output. */ struct mcount_thread_data { int tid; int idx; int record_idx; bool recursion_marker; bool in_exception; bool dead; unsigned long cygprof_dummy; struct mcount_ret_stack *rstack; void *argbuf; struct filter_control filter; bool enable_cached; struct mcount_shmem shmem; struct mcount_event event[MAX_EVENT]; int nr_events; struct mcount_mem_regions mem_regions; struct mcount_watchpoint watch; struct mcount_arch_context arch; }; #ifdef HAVE_MCOUNT_ARCH_CONTEXT extern void mcount_save_arch_context(struct mcount_arch_context *ctx); extern void mcount_restore_arch_context(struct mcount_arch_context *ctx); #else static inline void mcount_save_arch_context(struct mcount_arch_context *ctx) {} static inline void mcount_restore_arch_context(struct mcount_arch_context *ctx) {} #endif #ifdef SINGLE_THREAD # define TLS # define get_thread_data() &mtd # define check_thread_data(mtdp) (mtdp->rstack == NULL) #else # define TLS __thread # define get_thread_data() pthread_getspecific(mtd_key) # define check_thread_data(mtdp) (mtdp == NULL) #endif extern TLS struct mcount_thread_data mtd; void __mcount_guard_recursion(struct mcount_thread_data *mtdp); void __mcount_unguard_recursion(struct mcount_thread_data *mtdp); bool mcount_guard_recursion(struct mcount_thread_data *mtdp); void mcount_unguard_recursion(struct mcount_thread_data *mtdp); extern uint64_t mcount_threshold; /* nsec */ extern pthread_key_t mtd_key; extern int shmem_bufsize; extern int pfd; extern char *mcount_exename; extern int page_size_in_kb; extern bool kernel_pid_update; extern bool mcount_auto_recover; enum mcount_global_flag { MCOUNT_GFL_SETUP = (1U << 0), MCOUNT_GFL_FINISH = (1U << 1), }; extern unsigned long mcount_global_flags; static inline bool mcount_should_stop(void) { return mcount_global_flags != 0UL; } #ifdef DISABLE_MCOUNT_FILTER static inline void mcount_filter_setup(struct mcount_thread_data *mtdp) {} static inline void mcount_filter_release(struct mcount_thread_data *mtdp) {} static inline void mcount_watch_init(void) {} static inline void mcount_watch_setup(struct mcount_thread_data *mtdp) {} static inline void mcount_watch_release(struct mcount_thread_data *mtdp) {} #endif /* DISABLE_MCOUNT_FILTER */ static inline uint64_t mcount_gettime(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (uint64_t)ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec; } static inline int mcount_gettid(struct mcount_thread_data *mtdp) { if (!mtdp->tid) mtdp->tid = syscall(SYS_gettid); return mtdp->tid; } /* * calling memcpy or memset in libmcount might clobber some registers. */ static inline void mcount_memset1(void *dst, unsigned char d, int len) { unsigned char *p = dst; while (len-- > 0) *p++ = d; } static inline void mcount_memcpy1(void * restrict dst, const void * restrict src, int len) { unsigned char * restrict p = dst; const unsigned char * restrict q = src; while (len-- > 0) *p++ = *q++; } static inline void mcount_memset4(void *dst, unsigned int d, int len) { unsigned int *p = dst; int len4 = len / 4; while (len4-- > 0) *p++ = d; } static inline void mcount_memcpy4(void * restrict dst, const void * restrict src, int len) { unsigned int * restrict p = dst; const unsigned int * restrict q = src; int len4 = len / 4; while (len4-- > 0) *p++ = *q++; } extern void mcount_return(void); extern void dynamic_return(void); extern unsigned long plthook_return(void); extern unsigned long mcount_return_fn; extern struct mcount_thread_data * mcount_prepare(void); extern void update_kernel_tid(int tid); extern const char *mcount_session_name(void); extern void uftrace_send_message(int type, void *data, size_t len); extern void build_debug_domain(char *dbg_domain_str); extern void mcount_rstack_restore(struct mcount_thread_data *mtdp); extern void mcount_rstack_reset(struct mcount_thread_data *mtdp); extern void mcount_rstack_reset_exception(struct mcount_thread_data *mtdp, unsigned long frame_addr); extern void mcount_auto_restore(struct mcount_thread_data *mtdp); extern void mcount_auto_reset(struct mcount_thread_data *mtdp); extern bool mcount_rstack_has_plthook(struct mcount_thread_data *mtdp); extern void prepare_shmem_buffer(struct mcount_thread_data *mtdp); extern void clear_shmem_buffer(struct mcount_thread_data *mtdp); extern void shmem_finish(struct mcount_thread_data *mtdp); enum plthook_special_action { PLT_FL_SKIP = 1U << 0, PLT_FL_LONGJMP = 1U << 1, PLT_FL_SETJMP = 1U << 2, PLT_FL_VFORK = 1U << 3, PLT_FL_FLUSH = 1U << 4, PLT_FL_EXCEPT = 1U << 5, PLT_FL_RESOLVE = 1U << 6, PLT_FL_DLSYM = 1U << 7, }; struct plthook_special_func { unsigned idx; unsigned flags; /* enum plthook_special_action */ }; struct plthook_skip_symbol { const char *name; void *addr; }; struct plthook_data { /* links to the 'plthook_modules' list */ struct list_head list; /* full path of this module */ const char *mod_name; /* used by dynamic linker (PLT resolver), saved in GOT[1] */ unsigned long module_id; /* base address where this module is loaded */ unsigned long base_addr; /* start address of PLT code (PLT0) */ unsigned long plt_addr; /* symbol table for PLT functions */ struct symtab dsymtab; /* address of global offset table (GOT) used for PLT */ unsigned long *pltgot_ptr; /* original address of each function (resolved by dynamic linker) */ unsigned long *resolved_addr; /* array of function that needs special care (see above) */ struct plthook_special_func *special_funcs; int nr_special; /* architecture-specific info */ void *arch; }; unsigned long setup_pltgot(struct plthook_data *pd, int got_idx, int sym_idx, void *data); extern void mcount_setup_plthook(char *exename, bool nest_libcall); extern void setup_dynsym_indexes(struct plthook_data *pd); extern void destroy_dynsym_indexes(void); extern unsigned long mcount_arch_plthook_addr(struct plthook_data *pd, int idx); extern unsigned long plthook_resolver_addr; extern const struct plthook_skip_symbol plt_skip_syms[]; extern size_t plt_skip_nr; struct uftrace_trigger; struct uftrace_arg_spec; struct mcount_regs; struct mcount_arg_context { struct mcount_regs *regs; unsigned long *stack_base; long *retval; union { unsigned long i; void *p; double f; struct { long lo; long hi; } ll; unsigned char v[16]; } __align(16) val; struct mcount_mem_regions *regions; struct mcount_arch_context *arch; }; extern void mcount_arch_get_arg(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec); extern void mcount_arch_get_retval(struct mcount_arg_context *ctx, struct uftrace_arg_spec *spec); extern enum filter_result mcount_entry_filter_check(struct mcount_thread_data *mtdp, unsigned long child, struct uftrace_trigger *tr); extern void mcount_entry_filter_record(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, struct uftrace_trigger *tr, struct mcount_regs *regs); extern void mcount_exit_filter_record(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, long *retval); extern int record_trace_data(struct mcount_thread_data *mtdp, struct mcount_ret_stack *mrstack, long *retval); extern void record_proc_maps(char *dirname, const char *sess_id, struct symtabs *symtabs); #ifndef DISABLE_MCOUNT_FILTER extern void save_argument(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, struct list_head *args_spec, struct mcount_regs *regs); void save_retval(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, long *retval); void save_trigger_read(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, enum trigger_read_type type, bool diff); #endif /* DISABLE_MCOUNT_FILTER */ void save_watchpoint(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, unsigned long watchpoints); struct mcount_dynamic_info { struct mcount_dynamic_info *next; struct uftrace_mmap *map; unsigned long base_addr; unsigned long text_addr; int text_size; unsigned long trampoline; void *arch; }; struct mcount_disasm_engine { #ifdef HAVE_LIBCAPSTONE csh engine; #endif }; #define INSTRUMENT_SUCCESS 0 #define INSTRUMENT_FAILED -1 #define INSTRUMENT_SKIPPED -2 int mcount_dynamic_update(struct symtabs *symtabs, char *patch_funcs, enum uftrace_pattern_type ptype, struct mcount_disasm_engine *disasm); struct mcount_orig_insn { struct rb_node node; unsigned long addr; void *insn; }; struct mcount_orig_insn *mcount_save_code(unsigned long addr, unsigned insn_size, void *jmp_insn, unsigned jmp_size); void *mcount_find_code(unsigned long addr); void mcount_freeze_code(void); /* these should be implemented for each architecture */ int mcount_setup_trampoline(struct mcount_dynamic_info *adi); void mcount_cleanup_trampoline(struct mcount_dynamic_info *mdi); int mcount_patch_func(struct mcount_dynamic_info *mdi, struct sym *sym, struct mcount_disasm_engine *disasm, unsigned min_size); void mcount_disasm_init(struct mcount_disasm_engine *disasm); void mcount_disasm_finish(struct mcount_disasm_engine *disasm); struct mcount_event_info { char *module; char *provider; char *event; char *arguments; unsigned id; unsigned long addr; struct list_head list; }; int mcount_setup_events(char *dirname, char *event_str, enum uftrace_pattern_type ptype); struct mcount_event_info * mcount_lookup_event(unsigned long addr); int mcount_save_event(struct mcount_event_info *mei); void mcount_finish_events(void); void mcount_list_events(void); int mcount_arch_enable_event(struct mcount_event_info *mei); void mcount_hook_functions(void); int prepare_pmu_event(enum uftrace_event_id id); int read_pmu_event(enum uftrace_event_id id, void *buf); void finish_pmu_event(void); #endif /* UFTRACE_MCOUNT_INTERNAL_H */ uftrace-0.9.3/libmcount/mcount-nop.c000066400000000000000000000013541351236475300174270ustar00rootroot00000000000000/* * dummy mcount() routine for uftrace * * Copyright (C) 2015-2017, LG Electronics, Namhyung Kim * * Released under the GPL v2. */ #include "utils/compiler.h" void __visible_default mcount(void) { } void __visible_default _mcount(void) { } void __visible_default __gnu_mcount_nc(void) { } void __visible_default __fentry__(void) { } void __visible_default __cyg_profile_func_enter(void *child, void *parent) { } void __visible_default __cyg_profile_func_exit(void *child, void *parent) { } void __visible_default __monstartup(unsigned long low, unsigned long high) { } void __visible_default _mcleanup(void) { } void __visible_default mcount_restore(void) { } void __visible_default mcount_reset(void) { } uftrace-0.9.3/libmcount/mcount.c000066400000000000000000001320261351236475300166360ustar00rootroot00000000000000/* * mcount() handling routines for uftrace * * Copyright (C) 2014-2018, LG Electronics, Namhyung Kim * * Released under the GPL v2. */ #include #include #include #include #include #include #include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "mcount" #define PR_DOMAIN DBG_MCOUNT #include "libmcount/mcount.h" #include "libmcount/internal.h" #include "mcount-arch.h" #include "version.h" #include "utils/utils.h" #include "utils/symbol.h" #include "utils/filter.h" #include "utils/script.h" /* time filter in nsec */ uint64_t mcount_threshold; /* symbol table of main executable */ struct symtabs symtabs = { .flags = SYMTAB_FL_DEMANGLE | SYMTAB_FL_ADJ_OFFSET, }; /* size of shmem buffer to save uftrace_record */ int shmem_bufsize = SHMEM_BUFFER_SIZE; /* recover return address of parent automatically */ bool mcount_auto_recover = ARCH_SUPPORT_AUTO_RECOVER; /* global flag to control mcount behavior */ unsigned long mcount_global_flags = MCOUNT_GFL_SETUP; /* TSD key to save mtd below */ pthread_key_t mtd_key = (pthread_key_t)-1; /* thread local data to trace function execution */ TLS struct mcount_thread_data mtd; /* pipe file descriptor to communite to uftrace */ int pfd = -1; /* maximum depth of mcount rstack */ static int mcount_rstack_max = MCOUNT_RSTACK_MAX; /* name of main executable */ char *mcount_exename; /* whether it should update pid filter manually */ bool kernel_pid_update; /* system page size */ int page_size_in_kb; /* call depth to filter */ static int __maybe_unused mcount_depth = MCOUNT_DEFAULT_DEPTH; /* boolean flag to turn on/off recording */ static bool __maybe_unused mcount_enabled = true; /* function filtering mode - inclusive or exclusive */ static enum filter_mode __maybe_unused mcount_filter_mode = FILTER_MODE_NONE; /* tree of trigger actions */ static struct rb_root __maybe_unused mcount_triggers = RB_ROOT; /* bitmask of active watch points */ static unsigned long __maybe_unused mcount_watchpoints; /* whether caller filter is activated */ static bool __maybe_unused mcount_has_caller; /* address of function will be called when a function returns */ unsigned long mcount_return_fn; /* disassembly engine for dynamic code patch */ static struct mcount_disasm_engine disasm; __weak void dynamic_return(void) { } #ifdef DISABLE_MCOUNT_FILTER static void mcount_filter_init(enum uftrace_pattern_type ptype, char *dirname, bool force) { if (getenv("UFTRACE_SRCLINE") == NULL) return; symtabs.maps->mod = load_module_symtab(&symtabs, symtabs.maps->libname); /* use debug info if available */ prepare_debug_info(&symtabs, ptype, NULL, NULL, false, force); save_debug_info(&symtabs, dirname); } static void mcount_filter_finish(void) { finish_debug_info(&symtabs); } #else static void prepare_pmu_trigger(struct rb_root *root) { struct rb_node *node = rb_first(root); struct uftrace_filter *entry; while (node) { entry = rb_entry(node, typeof(*entry), node); if (entry->trigger.flags & TRIGGER_FL_READ) { if (entry->trigger.read & TRIGGER_READ_PMU_CYCLE) if (prepare_pmu_event(EVENT_ID_READ_PMU_CYCLE) < 0) break; if (entry->trigger.read & TRIGGER_READ_PMU_CACHE) if (prepare_pmu_event(EVENT_ID_READ_PMU_CACHE) < 0) break; if (entry->trigger.read & TRIGGER_READ_PMU_BRANCH) if (prepare_pmu_event(EVENT_ID_READ_PMU_BRANCH) < 0) break; } node = rb_next(node); } } /* be careful: this can be called from signal handler */ static void mcount_finish_trigger(void) { if (mcount_global_flags & MCOUNT_GFL_FINISH) return; /* mark other threads can see the finish flag */ mcount_global_flags |= MCOUNT_GFL_FINISH; } static LIST_HEAD(siglist); struct signal_trigger_item { struct list_head list; int sig; struct uftrace_trigger tr; }; static struct uftrace_trigger * get_signal_trigger(int sig) { struct signal_trigger_item *item; list_for_each_entry(item, &siglist, list) { if (item->sig == sig) return &item->tr; } return NULL; } static void add_signal_trigger(int sig, const char *name, struct uftrace_trigger *tr) { struct signal_trigger_item *item; item = xmalloc(sizeof(*item)); item->sig = sig; memcpy(&item->tr, tr, sizeof(*tr)); pr_dbg("add signal trigger: %s (%d), flags = %lx\n", name, sig, (unsigned long)tr->flags); list_add(&item->list, &siglist); } static void mcount_signal_trigger(int sig) { struct uftrace_trigger *tr; tr = get_signal_trigger(sig); if (tr == NULL) return; pr_dbg("got signal %d\n", sig); if (tr->flags & TRIGGER_FL_TRACE_ON) { mcount_enabled = true; } if (tr->flags & TRIGGER_FL_TRACE_OFF) { mcount_enabled = false; } if (tr->flags & TRIGGER_FL_FINISH) { mcount_finish_trigger(); } } #define SIGTABLE_ENTRY(s) { #s, s } static const struct sigtable { const char *name; int sig; } sigtable[] = { SIGTABLE_ENTRY(SIGHUP), SIGTABLE_ENTRY(SIGINT), SIGTABLE_ENTRY(SIGQUIT), SIGTABLE_ENTRY(SIGILL), SIGTABLE_ENTRY(SIGTRAP), SIGTABLE_ENTRY(SIGABRT), SIGTABLE_ENTRY(SIGBUS), SIGTABLE_ENTRY(SIGFPE), SIGTABLE_ENTRY(SIGKILL), SIGTABLE_ENTRY(SIGUSR1), SIGTABLE_ENTRY(SIGSEGV), SIGTABLE_ENTRY(SIGUSR2), SIGTABLE_ENTRY(SIGPIPE), SIGTABLE_ENTRY(SIGALRM), SIGTABLE_ENTRY(SIGTERM), SIGTABLE_ENTRY(SIGSTKFLT), SIGTABLE_ENTRY(SIGCHLD), SIGTABLE_ENTRY(SIGCONT), SIGTABLE_ENTRY(SIGSTOP), SIGTABLE_ENTRY(SIGTSTP), SIGTABLE_ENTRY(SIGTTIN), SIGTABLE_ENTRY(SIGTTOU), SIGTABLE_ENTRY(SIGURG), SIGTABLE_ENTRY(SIGXCPU), SIGTABLE_ENTRY(SIGXFSZ), SIGTABLE_ENTRY(SIGVTALRM), SIGTABLE_ENTRY(SIGPROF), SIGTABLE_ENTRY(SIGWINCH), SIGTABLE_ENTRY(SIGIO), SIGTABLE_ENTRY(SIGPWR), SIGTABLE_ENTRY(SIGSYS), }; #undef SIGTABLE_ENTRY static int parse_sigspec(char *spec, struct uftrace_filter_setting *setting) { char *pos, *tmp; unsigned i; int sig = -1; int off = 0; const char *signame = NULL; bool num_spec = false; char num_spec_str[16]; struct uftrace_trigger tr = { .flags = 0, }; struct sigaction old_sa; struct sigaction sa = { .sa_handler = mcount_signal_trigger, .sa_flags = SA_RESTART, }; const char *sigrtm = "SIGRTM"; const char *sigrtmin = "SIGRTMIN"; const char *sigrtmax = "SIGRTMAX"; pos = strchr(spec, '@'); if (pos == NULL) return -1; *pos = '\0'; if (isdigit(spec[0])) num_spec = true; else if (strncmp(spec, "SIG", 3)) off = 3; /* skip "SIG" prefix */ for (i = 0; i < ARRAY_SIZE(sigtable); i++) { if (num_spec) { int num = strtol(spec, &tmp, 0); if (num == sigtable[i].sig) { sig = num; signame = sigtable[i].name; break; } continue; } if (!strcmp(sigtable[i].name + off, spec)) { sig = sigtable[i].sig; signame = sigtable[i].name; break; } } /* real-time signals */ if (!strncmp(spec, sigrtm + off, 6 - off)) { if (!strncmp(spec, sigrtmin + off, 8 - off)) sig = SIGRTMIN + strtol(&spec[8 - off], NULL, 0); if (!strncmp(spec, sigrtmax + off, 8 - off)) sig = SIGRTMAX + strtol(&spec[8 - off], NULL, 0); signame = spec; } if (sig == -1 && num_spec) { int sigrtmid = (SIGRTMIN + SIGRTMAX) / 2; sig = strtol(spec, &tmp, 0); /* SIGRTMIN/MAX might not be constant, avoid switch/case */ if (sig == SIGRTMIN) { strcpy(num_spec_str, "SIGRTMIN"); } else if (SIGRTMIN < sig && sig <= sigrtmid) { snprintf(num_spec_str, sizeof(num_spec_str), "%s+%d", "SIGRTMIN", sig - SIGRTMIN); } else if (sigrtmid < sig && sig < SIGRTMAX) { snprintf(num_spec_str, sizeof(num_spec_str), "%s-%d", "SIGRTMAX", SIGRTMAX - sig); } else if (sig == SIGRTMAX) { strcpy(num_spec_str, "SIGRTMAX"); } else { sig = -1; } signame = num_spec_str; } if (sig == -1) { pr_use("failed to parse signal: %s\n", spec); return -1; } /* setup_trigger_action() requires the '@' sign */ *pos = '@'; tmp = NULL; if (setup_trigger_action(spec, &tr, &tmp, TRIGGER_FL_SIGNAL, setting) < 0) return -1; if (tmp != NULL) { pr_warn("invalid signal action: %s\n", tmp); free(tmp); return -1; } add_signal_trigger(sig, signame, &tr); if (sigaction(sig, &sa, &old_sa) < 0) { pr_warn("cannot overwrite signal handler for %s\n", spec); sigaction(sig, &old_sa, NULL); return -1; } return 0; } static int mcount_signal_init(char *sigspec, struct uftrace_filter_setting *setting) { struct strv strv = STRV_INIT; char *spec; int i; int ret = 0; if (sigspec == NULL) return 0; strv_split(&strv, sigspec, ";"); strv_for_each(&strv, spec, i) { if (parse_sigspec(spec, setting) < 0) ret = -1; } strv_free(&strv); return ret; } static void mcount_signal_finish(void) { struct signal_trigger_item *item; while (!list_empty(&siglist)) { item = list_first_entry(&siglist, typeof(*item), list); list_del(&item->list); free(item); } } static void mcount_filter_init(enum uftrace_pattern_type ptype, char *dirname, bool force) { char *filter_str = getenv("UFTRACE_FILTER"); char *trigger_str = getenv("UFTRACE_TRIGGER"); char *argument_str = getenv("UFTRACE_ARGUMENT"); char *retval_str = getenv("UFTRACE_RETVAL"); char *autoargs_str = getenv("UFTRACE_AUTO_ARGS"); char *caller_str = getenv("UFTRACE_CALLER"); struct uftrace_filter_setting filter_setting = { .ptype = ptype, .auto_args = false, .allow_kernel = false, .lp64 = host_is_lp64(), .arch = host_cpu_arch(), }; bool needs_debug_info = false; load_module_symtabs(&symtabs); mcount_signal_init(getenv("UFTRACE_SIGNAL"), &filter_setting); /* setup auto-args only if argument/return value is used */ if (argument_str || retval_str || autoargs_str || (trigger_str && (strstr(trigger_str, "arg") || strstr(trigger_str, "retval")))) { setup_auto_args(&filter_setting); needs_debug_info = true; } if (getenv("UFTRACE_SRCLINE")) needs_debug_info = true; /* use debug info if available */ if (needs_debug_info) { prepare_debug_info(&symtabs, ptype, argument_str, retval_str, !!autoargs_str, force); save_debug_info(&symtabs, dirname); } uftrace_setup_filter(filter_str, &symtabs, &mcount_triggers, &mcount_filter_mode, &filter_setting); uftrace_setup_trigger(trigger_str, &symtabs, &mcount_triggers, &mcount_filter_mode, &filter_setting); uftrace_setup_argument(argument_str, &symtabs, &mcount_triggers, &filter_setting); uftrace_setup_retval(retval_str, &symtabs, &mcount_triggers, &filter_setting); if (caller_str) { uftrace_setup_caller_filter(caller_str, &symtabs, &mcount_triggers, &filter_setting); if (uftrace_count_filter(&mcount_triggers, TRIGGER_FL_CALLER) != 0) mcount_has_caller = true; } if (autoargs_str) { char *autoarg = "."; char *autoret = "."; if (ptype == PATT_GLOB) autoarg = autoret = "*"; filter_setting.auto_args = true; uftrace_setup_argument(autoarg, &symtabs, &mcount_triggers, &filter_setting); uftrace_setup_retval(autoret, &symtabs, &mcount_triggers, &filter_setting); } if (getenv("UFTRACE_DEPTH")) mcount_depth = strtol(getenv("UFTRACE_DEPTH"), NULL, 0); if (getenv("UFTRACE_DISABLED")) mcount_enabled = false; prepare_pmu_trigger(&mcount_triggers); } static void mcount_filter_setup(struct mcount_thread_data *mtdp) { mtdp->filter.depth = mcount_depth; mtdp->filter.time = mcount_threshold; mtdp->enable_cached = mcount_enabled; mtdp->argbuf = xmalloc(mcount_rstack_max * ARGBUF_SIZE); } static void mcount_filter_release(struct mcount_thread_data *mtdp) { free(mtdp->argbuf); mtdp->argbuf = NULL; } static void mcount_filter_finish(void) { uftrace_cleanup_filter(&mcount_triggers); finish_auto_args(); finish_debug_info(&symtabs); finish_pmu_event(); mcount_signal_finish(); } static void mcount_watch_init(void) { char *watch_str = getenv("UFTRACE_WATCH"); struct strv watch = STRV_INIT; char *str; int i; if (watch_str == NULL) return; strv_split(&watch, watch_str, ";"); strv_for_each(&watch, str, i) { if (!strcasecmp(str, "cpu")) mcount_watchpoints = MCOUNT_WATCH_CPU; } strv_free(&watch); } static void mcount_watch_setup(struct mcount_thread_data *mtdp) { mtdp->watch.cpu = -1; } static void mcount_watch_release(struct mcount_thread_data *mtdp) { } #endif /* DISABLE_MCOUNT_FILTER */ static void send_session_msg(struct mcount_thread_data *mtdp, const char *sess_id) { struct uftrace_msg_sess sess = { .task = { .time = mcount_gettime(), .pid = getpid(), .tid = mcount_gettid(mtdp), }, .namelen = strlen(mcount_exename), }; struct uftrace_msg msg = { .magic = UFTRACE_MSG_MAGIC, .type = UFTRACE_MSG_SESSION, .len = sizeof(sess) + sess.namelen, }; struct iovec iov[3] = { { .iov_base = &msg, .iov_len = sizeof(msg), }, { .iov_base = &sess, .iov_len = sizeof(sess), }, { .iov_base = mcount_exename, .iov_len = sess.namelen, }, }; int len = sizeof(msg) + msg.len; if (pfd < 0) return; mcount_memcpy4(sess.sid, sess_id, sizeof(sess.sid)); if (writev(pfd, iov, 3) != len) { if (!mcount_should_stop()) pr_err("write tid info failed"); } } static void mcount_trace_finish(bool send_msg) { static pthread_mutex_t finish_lock = PTHREAD_MUTEX_INITIALIZER; static bool trace_finished = false; pthread_mutex_lock(&finish_lock); if (trace_finished) goto unlock; /* dtor for script support */ if (SCRIPT_ENABLED && script_str) script_uftrace_end(); /* notify to uftrace that we're finished */ if (send_msg) uftrace_send_message(UFTRACE_MSG_FINISH, NULL, 0); if (pfd != -1) { close(pfd); pfd = -1; } trace_finished = true; pr_dbg("mcount trace finished\n"); unlock: pthread_mutex_unlock(&finish_lock); } /* to be used by pthread_create_key() */ void mtd_dtor(void *arg) { struct mcount_thread_data *mtdp = arg; struct uftrace_msg_task tmsg; if (mtdp->dead) return; if (mcount_should_stop()) mcount_trace_finish(true); /* this thread is done, do not enter anymore */ mtdp->recursion_marker = true; mtdp->dead = true; mcount_rstack_restore(mtdp); if (ARCH_CAN_RESTORE_PLTHOOK || !mcount_rstack_has_plthook(mtdp)) { free(mtdp->rstack); mtdp->rstack = NULL; mtdp->idx = 0; } mcount_filter_release(mtdp); mcount_watch_release(mtdp); finish_mem_region(&mtdp->mem_regions); shmem_finish(mtdp); tmsg.pid = getpid(), tmsg.tid = mcount_gettid(mtdp), tmsg.time = mcount_gettime(); uftrace_send_message(UFTRACE_MSG_TASK_END, &tmsg, sizeof(tmsg)); } void __mcount_guard_recursion(struct mcount_thread_data *mtdp) { mtdp->recursion_marker = true; } void __mcount_unguard_recursion(struct mcount_thread_data *mtdp) { mtdp->recursion_marker = false; } bool mcount_guard_recursion(struct mcount_thread_data *mtdp) { if (unlikely(mtdp->recursion_marker)) return false; if (unlikely(mcount_should_stop())) { mtd_dtor(mtdp); return false; } mtdp->recursion_marker = true; return true; } void mcount_unguard_recursion(struct mcount_thread_data *mtdp) { mtdp->recursion_marker = false; if (unlikely(mcount_should_stop())) mtd_dtor(mtdp); } static struct sigaction old_sigact[2]; static const struct { int code; char *msg; } sigsegv_codes[] = { { SEGV_MAPERR, "address not mapped" }, { SEGV_ACCERR, "invalid permission" }, #ifdef SEGV_BNDERR { SEGV_BNDERR, "bound check failed" }, #endif #ifdef SEGV_PKUERR { SEGV_PKUERR, "protection key check failed" }, #endif }; static void segv_handler(int sig, siginfo_t *si, void *ctx) { struct mcount_thread_data *mtdp; struct mcount_ret_stack *rstack; int idx; /* set line buffer mode not to discard crash message */ setlinebuf(outfp); mtdp = get_thread_data(); if (check_thread_data(mtdp)) goto out; if (mtdp->idx <= 0) goto out; mcount_rstack_restore(mtdp); idx = mtdp->idx - 1; /* flush current rstack on crash */ rstack = &mtdp->rstack[idx]; record_trace_data(mtdp, rstack, NULL); if (dbg_domain[PR_DOMAIN]) { int i; for (i = 0; i < (int)ARRAY_SIZE(sigsegv_codes); i++) { if (sig != SIGSEGV) break; if (si->si_code == sigsegv_codes[i].code) { pr_red("Segmentation fault: %s (addr: %p)\n", sigsegv_codes[i].msg, si->si_addr); break; } } if (sig != SIGSEGV || i == (int)ARRAY_SIZE(sigsegv_codes)) { pr_red("process crashed by signal %d: %s (si_code: %d)\n", sig, strsignal(sig), si->si_code); } pr_red("Backtrace from uftrace:\n"); pr_red("=====================================\n"); while (rstack >= mtdp->rstack) { struct sym *parent, *child; char *pname, *cname; parent = find_symtabs(&symtabs, rstack->parent_ip); pname = symbol_getname(parent, rstack->parent_ip); child = find_symtabs(&symtabs, rstack->child_ip); cname = symbol_getname(child, rstack->child_ip); pr_red("[%d] (%s[%lx] <= %s[%lx])\n", idx--, cname, rstack->child_ip, pname, rstack->parent_ip); symbol_putname(parent, pname); symbol_putname(child, cname); rstack--; } } out: sigaction(sig, &old_sigact[(sig == SIGSEGV)], NULL); raise(sig); } static void mcount_init_file(void) { struct sigaction sa = { .sa_sigaction = segv_handler, .sa_flags = SA_SIGINFO, }; send_session_msg(&mtd, mcount_session_name()); pr_dbg("new session started: %.*s: %s\n", SESSION_ID_LEN, mcount_session_name(), basename(mcount_exename)); sigemptyset(&sa.sa_mask); sigaction(SIGABRT, &sa, &old_sigact[0]); sigaction(SIGSEGV, &sa, &old_sigact[1]); } struct mcount_thread_data * mcount_prepare(void) { static pthread_once_t once_control = PTHREAD_ONCE_INIT; struct mcount_thread_data *mtdp = &mtd; struct uftrace_msg_task tmsg; if (unlikely(mcount_should_stop())) return NULL; /* * If an executable implements its own malloc(), * following recursion could occur * * mcount_entry -> mcount_prepare -> xmalloc -> mcount_entry -> ... */ if (!mcount_guard_recursion(mtdp)) return NULL; compiler_barrier(); mcount_filter_setup(mtdp); mcount_watch_setup(mtdp); mtdp->rstack = xmalloc(mcount_rstack_max * sizeof(*mtd.rstack)); pthread_once(&once_control, mcount_init_file); prepare_shmem_buffer(mtdp); pthread_setspecific(mtd_key, mtdp); /* time should be get after session message sent */ tmsg.pid = getpid(), tmsg.tid = mcount_gettid(mtdp), tmsg.time = mcount_gettime(); uftrace_send_message(UFTRACE_MSG_TASK_START, &tmsg, sizeof(tmsg)); update_kernel_tid(tmsg.tid); return mtdp; } static void mcount_finish(void) { if (!mcount_should_stop()) mcount_trace_finish(false); mcount_global_flags |= MCOUNT_GFL_FINISH; } static bool mcount_check_rstack(struct mcount_thread_data *mtdp) { if (mtdp->idx >= mcount_rstack_max) { static bool warned = false; if (!warned) { pr_warn("too deeply nested calls: %d\n", mtdp->idx); warned = true; } return true; } return false; } #ifndef DISABLE_MCOUNT_FILTER extern void * get_argbuf(struct mcount_thread_data *, struct mcount_ret_stack *); /* update filter state from trigger result */ enum filter_result mcount_entry_filter_check(struct mcount_thread_data *mtdp, unsigned long child, struct uftrace_trigger *tr) { pr_dbg3("<%d> enter %lx\n", mtdp->idx, child); if (mcount_check_rstack(mtdp)) return FILTER_RSTACK; /* save original depth and time to restore at exit time */ mtdp->filter.saved_depth = mtdp->filter.depth; mtdp->filter.saved_time = mtdp->filter.time; /* already filtered by notrace option */ if (mtdp->filter.out_count > 0) return FILTER_OUT; uftrace_match_filter(child, &mcount_triggers, tr); pr_dbg3(" tr->flags: %x, filter mode: %d, count: %d/%d, depth: %d\n", tr->flags, tr->fmode, mtdp->filter.in_count, mtdp->filter.out_count, mtdp->filter.depth); if (tr->flags & TRIGGER_FL_FILTER) { if (tr->fmode == FILTER_MODE_IN) mtdp->filter.in_count++; else if (tr->fmode == FILTER_MODE_OUT) mtdp->filter.out_count++; /* apply default filter depth when match */ mtdp->filter.depth = mcount_depth; } else { /* not matched by filter */ if (mcount_filter_mode == FILTER_MODE_IN && mtdp->filter.in_count == 0) return FILTER_OUT; } #define FLAGS_TO_CHECK (TRIGGER_FL_DEPTH | TRIGGER_FL_TRACE_ON | \ TRIGGER_FL_TRACE_OFF | TRIGGER_FL_TIME_FILTER) if (tr->flags & FLAGS_TO_CHECK) { if (tr->flags & TRIGGER_FL_DEPTH) mtdp->filter.depth = tr->depth; if (tr->flags & TRIGGER_FL_TRACE_ON) mcount_enabled = true; if (tr->flags & TRIGGER_FL_TRACE_OFF) mcount_enabled = false; if (tr->flags & TRIGGER_FL_TIME_FILTER) mtdp->filter.time = tr->time; } #undef FLAGS_TO_CHECK if (mtdp->filter.depth == 0) return FILTER_OUT; mtdp->filter.depth--; return FILTER_IN; } static int script_save_context(struct script_context *sc_ctx, struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, char *symname, bool has_arg_retval, struct list_head *pargs) { if (!script_match_filter(symname)) return -1; sc_ctx->tid = mcount_gettid(mtdp); sc_ctx->depth = rstack->depth; sc_ctx->address = rstack->child_ip; sc_ctx->name = symname; sc_ctx->timestamp = rstack->start_time; if (rstack->end_time) sc_ctx->duration = rstack->end_time - rstack->start_time; if (has_arg_retval) { unsigned *argbuf = get_argbuf(mtdp, rstack); sc_ctx->arglen = argbuf[0]; sc_ctx->argbuf = &argbuf[1]; sc_ctx->argspec = pargs; } else { /* prevent access to arguments */ sc_ctx->arglen = 0; } return 0; } static void script_hook_entry(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, struct uftrace_trigger *tr) { struct script_context sc_ctx; unsigned long entry_addr = rstack->child_ip; struct sym *sym = find_symtabs(&symtabs, entry_addr); char *symname = symbol_getname(sym, entry_addr); if (script_save_context(&sc_ctx, mtdp, rstack, symname, tr->flags & TRIGGER_FL_ARGUMENT, tr->pargs) < 0) goto skip; /* accessing argument in script might change arch-context */ mcount_save_arch_context(&mtdp->arch); script_uftrace_entry(&sc_ctx); mcount_restore_arch_context(&mtdp->arch); skip: symbol_putname(sym, symname); } static void script_hook_exit(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack) { struct script_context sc_ctx; unsigned long entry_addr = rstack->child_ip; struct sym *sym = find_symtabs(&symtabs, entry_addr); char *symname = symbol_getname(sym, entry_addr); if (script_save_context(&sc_ctx, mtdp, rstack, symname, rstack->flags & MCOUNT_FL_RETVAL, rstack->pargs) < 0) goto skip; /* accessing argument in script might change arch-context */ mcount_save_arch_context(&mtdp->arch); script_uftrace_exit(&sc_ctx); mcount_restore_arch_context(&mtdp->arch); skip: symbol_putname(sym, symname); } /* save current filter state to rstack */ void mcount_entry_filter_record(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, struct uftrace_trigger *tr, struct mcount_regs *regs) { if (mtdp->filter.out_count > 0 || (mtdp->filter.in_count == 0 && mcount_filter_mode == FILTER_MODE_IN)) rstack->flags |= MCOUNT_FL_NORECORD; rstack->filter_depth = mtdp->filter.saved_depth; rstack->filter_time = mtdp->filter.saved_time; #define FLAGS_TO_CHECK (TRIGGER_FL_FILTER | TRIGGER_FL_RETVAL | \ TRIGGER_FL_TRACE | TRIGGER_FL_FINISH | \ TRIGGER_FL_CALLER) if (tr->flags & FLAGS_TO_CHECK) { if (tr->flags & TRIGGER_FL_FILTER) { if (tr->fmode == FILTER_MODE_IN) rstack->flags |= MCOUNT_FL_FILTERED; else rstack->flags |= MCOUNT_FL_NOTRACE; } /* check if it has to keep arg_spec for retval */ if (tr->flags & TRIGGER_FL_RETVAL) { rstack->pargs = tr->pargs; rstack->flags |= MCOUNT_FL_RETVAL; } if (tr->flags & TRIGGER_FL_TRACE) rstack->flags |= MCOUNT_FL_TRACE; if (tr->flags & TRIGGER_FL_CALLER) rstack->flags |= MCOUNT_FL_CALLER; if (tr->flags & TRIGGER_FL_FINISH) { record_trace_data(mtdp, rstack, NULL); mcount_finish_trigger(); return; } } #undef FLAGS_TO_CHECK if (!(rstack->flags & MCOUNT_FL_NORECORD)) { mtdp->record_idx++; if (!mcount_enabled) { rstack->flags |= MCOUNT_FL_DISABLED; /* * Flush existing rstack when mcount_enabled is off * (i.e. disabled). Note that changing to enabled is * already handled in record_trace_data() on exit path * using the MCOUNT_FL_DISALBED flag. */ if (unlikely(mtdp->enable_cached)) record_trace_data(mtdp, rstack, NULL); } else { if (tr->flags & TRIGGER_FL_ARGUMENT) save_argument(mtdp, rstack, tr->pargs, regs); if (tr->flags & TRIGGER_FL_READ) { save_trigger_read(mtdp, rstack, tr->read, false); rstack->flags |= MCOUNT_FL_READ; } if (mcount_watchpoints) save_watchpoint(mtdp, rstack, mcount_watchpoints); if (mtdp->nr_events) { bool flush = false; int i; /* * Flush rstacks if async event was recorded * as it only has limited space for the events. */ for (i = 0; i < mtdp->nr_events; i++) if (mtdp->event[i].idx == ASYNC_IDX) flush = true; if (flush) record_trace_data(mtdp, rstack, NULL); } } /* script hooking for function entry */ if (SCRIPT_ENABLED && script_str) script_hook_entry(mtdp, rstack, tr); #define FLAGS_TO_CHECK (TRIGGER_FL_RECOVER | TRIGGER_FL_TRACE_ON | TRIGGER_FL_TRACE_OFF) if (tr->flags & FLAGS_TO_CHECK) { if (tr->flags & TRIGGER_FL_RECOVER) { mcount_rstack_restore(mtdp); *rstack->parent_loc = mcount_return_fn; rstack->flags |= MCOUNT_FL_RECOVER; } if (tr->flags & (TRIGGER_FL_TRACE_ON | TRIGGER_FL_TRACE_OFF)) mtdp->enable_cached = mcount_enabled; } } #undef FLAGS_TO_CHECK } /* restore filter state from rstack */ void mcount_exit_filter_record(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, long *retval) { uint64_t time_filter = mtdp->filter.time; pr_dbg3("<%d> exit %lx\n", mtdp->idx, rstack->child_ip); #define FLAGS_TO_CHECK (MCOUNT_FL_FILTERED | MCOUNT_FL_NOTRACE | MCOUNT_FL_RECOVER) if (rstack->flags & FLAGS_TO_CHECK) { if (rstack->flags & MCOUNT_FL_FILTERED) mtdp->filter.in_count--; else if (rstack->flags & MCOUNT_FL_NOTRACE) mtdp->filter.out_count--; if (rstack->flags & MCOUNT_FL_RECOVER) mcount_rstack_reset(mtdp); } #undef FLAGS_TO_CHECK mtdp->filter.depth = rstack->filter_depth; mtdp->filter.time = rstack->filter_time; if (!(rstack->flags & MCOUNT_FL_NORECORD)) { if (mtdp->record_idx > 0) mtdp->record_idx--; if (!mcount_enabled) return; if (!(rstack->flags & MCOUNT_FL_RETVAL)) retval = NULL; if (rstack->flags & MCOUNT_FL_READ) { struct uftrace_trigger tr; /* there's a possibility of overwriting by return value */ uftrace_match_filter(rstack->child_ip, &mcount_triggers, &tr); save_trigger_read(mtdp, rstack, tr.read, true); } if (mcount_watchpoints) save_watchpoint(mtdp, rstack, mcount_watchpoints); if (((rstack->end_time - rstack->start_time > time_filter) && (!mcount_has_caller || rstack->flags & MCOUNT_FL_CALLER)) || rstack->flags & (MCOUNT_FL_WRITTEN | MCOUNT_FL_TRACE)) { if (record_trace_data(mtdp, rstack, retval) < 0) pr_err("error during record"); } else if (mtdp->nr_events) { bool flush = false; int i, k; /* * Record rstacks if async event was recorded * in the middle of the function. Otherwise * update event count to drop filtered ones. */ for (i = 0, k = 0; i < mtdp->nr_events; i++) { if (mtdp->event[i].idx == ASYNC_IDX) flush = true; if (mtdp->event[i].idx < mtdp->idx) k = i + 1; } if (flush) record_trace_data(mtdp, rstack, retval); else mtdp->nr_events = k; /* invalidate sync events */ } /* script hooking for function exit */ if (SCRIPT_ENABLED && script_str) script_hook_exit(mtdp, rstack); } } #else /* DISABLE_MCOUNT_FILTER */ enum filter_result mcount_entry_filter_check(struct mcount_thread_data *mtdp, unsigned long child, struct uftrace_trigger *tr) { if (mcount_check_rstack(mtdp)) return FILTER_RSTACK; return FILTER_IN; } void mcount_entry_filter_record(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, struct uftrace_trigger *tr, struct mcount_regs *regs) { mtdp->record_idx++; } void mcount_exit_filter_record(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, long *retval) { mtdp->record_idx--; if (rstack->end_time - rstack->start_time > mcount_threshold || rstack->flags & MCOUNT_FL_WRITTEN) { if (record_trace_data(mtdp, rstack, NULL) < 0) pr_err("error during record"); } } #endif /* DISABLE_MCOUNT_FILTER */ #ifndef FIX_PARENT_LOC static inline unsigned long * mcount_arch_parent_location(struct symtabs *symtabs, unsigned long *parent_loc, unsigned long child_ip) { return parent_loc; } #endif static int __mcount_entry(unsigned long *parent_loc, unsigned long child, struct mcount_regs *regs) { enum filter_result filtered; struct mcount_thread_data *mtdp; struct mcount_ret_stack *rstack; struct uftrace_trigger tr; /* Access the mtd through TSD pointer to reduce TLS overhead */ mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) { mtdp = mcount_prepare(); if (mtdp == NULL) return -1; } else { if (!mcount_guard_recursion(mtdp)) return -1; } tr.flags = 0; filtered = mcount_entry_filter_check(mtdp, child, &tr); if (filtered != FILTER_IN) { mcount_unguard_recursion(mtdp); return -1; } if (unlikely(mtdp->in_exception)) { unsigned long frame_addr; /* same as __builtin_frame_addr(2) but avoid warning */ frame_addr = parent_loc[-1]; /* basic sanity check */ if (frame_addr < (unsigned long)parent_loc) frame_addr = (unsigned long)(parent_loc - 1); mcount_rstack_reset_exception(mtdp, frame_addr); mtdp->in_exception = false; } /* fixup the parent_loc in an arch-dependant way (if needed) */ parent_loc = mcount_arch_parent_location(&symtabs, parent_loc, child); rstack = &mtdp->rstack[mtdp->idx++]; rstack->depth = mtdp->record_idx; rstack->dyn_idx = MCOUNT_INVALID_DYNIDX; rstack->parent_loc = parent_loc; rstack->parent_ip = *parent_loc; rstack->child_ip = child; rstack->start_time = mcount_gettime(); rstack->end_time = 0; rstack->flags = 0; rstack->nr_events = 0; rstack->event_idx = ARGBUF_SIZE; /* hijack the return address of child */ *parent_loc = mcount_return_fn; /* restore return address of parent */ if (mcount_auto_recover) mcount_auto_restore(mtdp); mcount_entry_filter_record(mtdp, rstack, &tr, regs); mcount_unguard_recursion(mtdp); return 0; } int mcount_entry(unsigned long *parent_loc, unsigned long child, struct mcount_regs *regs) { int saved_errno = errno; int ret = __mcount_entry(parent_loc, child, regs); errno = saved_errno; return ret; } static unsigned long __mcount_exit(long *retval) { struct mcount_thread_data *mtdp; struct mcount_ret_stack *rstack; unsigned long *ret_loc; unsigned long retaddr; mtdp = get_thread_data(); assert(mtdp != NULL); assert(!mtdp->dead); /* * it's only called when mcount_entry() was succeeded * no need to check recursion here. But still needs to * prevent recursion during this call. */ __mcount_guard_recursion(mtdp); rstack = &mtdp->rstack[mtdp->idx - 1]; rstack->end_time = mcount_gettime(); mcount_exit_filter_record(mtdp, rstack, retval); ret_loc = rstack->parent_loc; retaddr = rstack->parent_ip; /* re-hijack return address of parent */ if (mcount_auto_recover) mcount_auto_reset(mtdp); __mcount_unguard_recursion(mtdp); if (unlikely(mcount_should_stop())) { mtd_dtor(mtdp); /* * mtd_dtor() will free rstack but current ret_addr * might be plthook_return() when it was a tailcall. * reload the return address after mtd_dtor() restored * all the parent locations. */ retaddr = *ret_loc; } compiler_barrier(); mtdp->idx--; return retaddr; } unsigned long mcount_exit(long *retval) { int saved_errno = errno; unsigned long ret = __mcount_exit(retval); errno = saved_errno; return ret; } static int __cygprof_entry(unsigned long parent, unsigned long child) { enum filter_result filtered; struct mcount_thread_data *mtdp; struct mcount_ret_stack *rstack; struct uftrace_trigger tr = { .flags = 0, }; /* Access the mtd through TSD pointer to reduce TLS overhead */ mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) { mtdp = mcount_prepare(); if (mtdp == NULL) return -1; } else { if (!mcount_guard_recursion(mtdp)) return -1; } filtered = mcount_entry_filter_check(mtdp, child, &tr); if (unlikely(mtdp->in_exception)) { unsigned long *frame_ptr; unsigned long frame_addr; frame_ptr = __builtin_frame_address(0); frame_addr = *frame_ptr; /* XXX: probably dangerous */ /* basic sanity check */ if (frame_addr < (unsigned long)frame_ptr) frame_addr = (unsigned long)frame_ptr; mcount_rstack_reset_exception(mtdp, frame_addr); mtdp->in_exception = false; } /* * recording arguments and return value is not supported. * also 'recover' trigger is only work for -pg entry. */ tr.flags &= ~(TRIGGER_FL_ARGUMENT | TRIGGER_FL_RETVAL | TRIGGER_FL_RECOVER); rstack = &mtdp->rstack[mtdp->idx++]; /* * even if it already exceeds the rstack max, it needs to increase idx * since the cygprof_exit() will be called anyway */ if (filtered == FILTER_RSTACK) { mcount_unguard_recursion(mtdp); return 0; } rstack->depth = mtdp->record_idx; rstack->dyn_idx = MCOUNT_INVALID_DYNIDX; rstack->parent_loc = &mtdp->cygprof_dummy; rstack->parent_ip = parent; rstack->child_ip = child; rstack->end_time = 0; rstack->nr_events = 0; rstack->event_idx = ARGBUF_SIZE; if (filtered == FILTER_IN) { rstack->start_time = mcount_gettime(); rstack->flags = 0; } else { rstack->start_time = 0; rstack->flags = MCOUNT_FL_NORECORD; } mcount_entry_filter_record(mtdp, rstack, &tr, NULL); mcount_unguard_recursion(mtdp); return 0; } static int cygprof_entry(unsigned long parent, unsigned long child) { int saved_errno = errno; int ret = __cygprof_entry(parent, child); errno = saved_errno; return ret; } static void __cygprof_exit(unsigned long parent, unsigned long child) { struct mcount_thread_data *mtdp; struct mcount_ret_stack *rstack; mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) return; if (!mcount_guard_recursion(mtdp)) return; /* * cygprof_exit() can be called beyond rstack max. * it cannot use mcount_check_rstack() here * since we didn't decrease the idx yet. */ if (mtdp->idx > mcount_rstack_max) goto out; rstack = &mtdp->rstack[mtdp->idx - 1]; if (!(rstack->flags & MCOUNT_FL_NORECORD)) rstack->end_time = mcount_gettime(); mcount_exit_filter_record(mtdp, rstack, NULL); out: mcount_unguard_recursion(mtdp); compiler_barrier(); mtdp->idx--; } static void cygprof_exit(unsigned long parent, unsigned long child) { int saved_errno = errno; __cygprof_exit(parent, child); errno = saved_errno; } static void _xray_entry(unsigned long parent, unsigned long child, struct mcount_regs *regs) { enum filter_result filtered; struct mcount_thread_data *mtdp; struct mcount_ret_stack *rstack; struct uftrace_trigger tr = { .flags = 0, }; /* Access the mtd through TSD pointer to reduce TLS overhead */ mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) { mtdp = mcount_prepare(); if (mtdp == NULL) return; } else { if (!mcount_guard_recursion(mtdp)) return; } filtered = mcount_entry_filter_check(mtdp, child, &tr); if (unlikely(mtdp->in_exception)) { unsigned long *frame_ptr; unsigned long frame_addr; frame_ptr = __builtin_frame_address(0); frame_addr = *frame_ptr; /* XXX: probably dangerous */ /* basic sanity check */ if (frame_addr < (unsigned long)frame_ptr) frame_addr = (unsigned long)frame_ptr; mcount_rstack_reset_exception(mtdp, frame_addr); mtdp->in_exception = false; } /* 'recover' trigger is only for -pg entry */ tr.flags &= ~TRIGGER_FL_RECOVER; rstack = &mtdp->rstack[mtdp->idx++]; rstack->depth = mtdp->record_idx; rstack->dyn_idx = MCOUNT_INVALID_DYNIDX; rstack->parent_loc = &mtdp->cygprof_dummy; rstack->parent_ip = parent; rstack->child_ip = child; rstack->end_time = 0; rstack->nr_events = 0; rstack->event_idx = ARGBUF_SIZE; if (filtered == FILTER_IN) { rstack->start_time = mcount_gettime(); rstack->flags = 0; } else { rstack->start_time = 0; rstack->flags = MCOUNT_FL_NORECORD; } mcount_entry_filter_record(mtdp, rstack, &tr, regs); mcount_unguard_recursion(mtdp); } void xray_entry(unsigned long parent, unsigned long child, struct mcount_regs *regs) { int saved_errno = errno; _xray_entry(parent, child, regs); errno = saved_errno; } static void _xray_exit(long *retval) { struct mcount_thread_data *mtdp; struct mcount_ret_stack *rstack; mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) return; if (!mcount_guard_recursion(mtdp)) return; /* * cygprof_exit() can be called beyond rstack max. * it cannot use mcount_check_rstack() here * since we didn't decrease the idx yet. */ if (mtdp->idx > mcount_rstack_max) goto out; rstack = &mtdp->rstack[mtdp->idx - 1]; if (!(rstack->flags & MCOUNT_FL_NORECORD)) rstack->end_time = mcount_gettime(); mcount_exit_filter_record(mtdp, rstack, retval); out: mcount_unguard_recursion(mtdp); compiler_barrier(); mtdp->idx--; } void xray_exit(long *retval) { int saved_errno = errno; _xray_exit(retval); errno = saved_errno; } static void atfork_prepare_handler(void) { struct uftrace_msg_task tmsg = { .time = mcount_gettime(), .pid = getpid(), }; /* call script atfork preparation routine */ if (SCRIPT_ENABLED && script_str) script_atfork_prepare(); uftrace_send_message(UFTRACE_MSG_FORK_START, &tmsg, sizeof(tmsg)); /* flush remaining contents in the stream */ fflush(outfp); fflush(logfp); } static void atfork_child_handler(void) { struct mcount_thread_data *mtdp; struct uftrace_msg_task tmsg = { .time = mcount_gettime(), .pid = getppid(), .tid = getpid(), }; int i; mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) { mtdp = mcount_prepare(); if (mtdp == NULL) return; } else { if (!mcount_guard_recursion(mtdp)) return; } /* update tid cache */ mtdp->tid = tmsg.tid; /* flush event data */ mtdp->nr_events = 0; clear_shmem_buffer(mtdp); prepare_shmem_buffer(mtdp); uftrace_send_message(UFTRACE_MSG_FORK_END, &tmsg, sizeof(tmsg)); update_kernel_tid(tmsg.tid); /* do not record parent's functions */ for (i = 0; i < mtdp->idx; i++) mtdp->rstack[i].flags |= MCOUNT_FL_WRITTEN; mcount_unguard_recursion(mtdp); } static void mcount_script_init(enum uftrace_pattern_type patt_type) { struct script_info info = { .name = script_str, .version = UFTRACE_VERSION, .record = true, }; char *cmds_str; cmds_str = getenv("UFTRACE_ARGS"); if (cmds_str) strv_split(&info.cmds, cmds_str, "\n"); if (script_init(&info, patt_type) < 0) script_str = NULL; strv_free(&info.cmds); } static __used void mcount_startup(void) { char *pipefd_str; char *logfd_str; char *debug_str; char *bufsize_str; char *maxstack_str; char *threshold_str; char *color_str; char *demangle_str; char *plthook_str; char *patch_str; char *event_str; char *dirname; char *pattern_str; struct stat statbuf; bool nest_libcall; enum uftrace_pattern_type patt_type = PATT_REGEX; if (!(mcount_global_flags & MCOUNT_GFL_SETUP)) return; mtd.recursion_marker = true; outfp = stdout; logfp = stderr; if (pthread_key_create(&mtd_key, mtd_dtor)) pr_err("cannot create mtd key"); pipefd_str = getenv("UFTRACE_PIPE"); logfd_str = getenv("UFTRACE_LOGFD"); debug_str = getenv("UFTRACE_DEBUG"); bufsize_str = getenv("UFTRACE_BUFFER"); maxstack_str = getenv("UFTRACE_MAX_STACK"); color_str = getenv("UFTRACE_COLOR"); threshold_str = getenv("UFTRACE_THRESHOLD"); demangle_str = getenv("UFTRACE_DEMANGLE"); plthook_str = getenv("UFTRACE_PLTHOOK"); patch_str = getenv("UFTRACE_PATCH"); event_str = getenv("UFTRACE_EVENT"); script_str = getenv("UFTRACE_SCRIPT"); nest_libcall = !!getenv("UFTRACE_NEST_LIBCALL"); pattern_str = getenv("UFTRACE_PATTERN"); page_size_in_kb = getpagesize() / KB; if (logfd_str) { int fd = strtol(logfd_str, NULL, 0); /* minimal sanity check */ if (!fstat(fd, &statbuf)) { logfp = fdopen(fd, "a"); if (logfp == NULL) pr_err("opening log file failed"); setvbuf(logfp, NULL, _IOLBF, 1024); } } if (debug_str) { debug = strtol(debug_str, NULL, 0); build_debug_domain(getenv("UFTRACE_DEBUG_DOMAIN")); } if (demangle_str) demangler = strtol(demangle_str, NULL, 0); if (color_str) setup_color(strtol(color_str, NULL, 0), NULL); else setup_color(COLOR_AUTO, NULL); pr_dbg("initializing mcount library\n"); dirname = getenv("UFTRACE_DIR"); if (dirname == NULL) dirname = UFTRACE_DIR_NAME; if (pipefd_str) { pfd = strtol(pipefd_str, NULL, 0); /* minimal sanity check */ if (fstat(pfd, &statbuf) < 0 || !S_ISFIFO(statbuf.st_mode)) { pr_dbg("ignore invalid pipe fd: %d\n", pfd); pfd = -1; } } else { char *channel = NULL; xasprintf(&channel, "%s/%s", dirname, ".channel"); pfd = open(channel, O_WRONLY); free(channel); } if (getenv("UFTRACE_LIST_EVENT")) { mcount_list_events(); exit(0); } if (bufsize_str) shmem_bufsize = strtol(bufsize_str, NULL, 0); mcount_exename = read_exename(); symtabs.dirname = dirname; symtabs.filename = mcount_exename; record_proc_maps(dirname, mcount_session_name(), &symtabs); if (pattern_str) patt_type = parse_filter_pattern(pattern_str); if (patch_str) mcount_return_fn = (unsigned long)dynamic_return; else mcount_return_fn = (unsigned long)mcount_return; mcount_filter_init(patt_type, dirname, !!patch_str); mcount_watch_init(); if (maxstack_str) mcount_rstack_max = strtol(maxstack_str, NULL, 0); if (threshold_str) mcount_threshold = strtoull(threshold_str, NULL, 0); if (patch_str) mcount_dynamic_update(&symtabs, patch_str, patt_type, &disasm); if (event_str) mcount_setup_events(dirname, event_str, patt_type); if (plthook_str) mcount_setup_plthook(mcount_exename, nest_libcall); if (getenv("UFTRACE_KERNEL_PID_UPDATE")) kernel_pid_update = true; pthread_atfork(atfork_prepare_handler, NULL, atfork_child_handler); mcount_hook_functions(); /* initialize script binding */ if (SCRIPT_ENABLED && script_str) mcount_script_init(patt_type); compiler_barrier(); pr_dbg("mcount setup done\n"); mcount_global_flags &= ~MCOUNT_GFL_SETUP; mtd.recursion_marker = false; } static void mcount_cleanup(void) { mcount_finish(); destroy_dynsym_indexes(); #if 0 /* * This mtd_key deletion sometimes makes other thread get crashed * because they may try to get mtdp based on this mtd_key after being * deleted. Since this key deletion is not mandatory, it'd be better * not to delete it until we find a better solution. */ pthread_key_delete(mtd_key); mtd_key = -1; #endif mcount_filter_finish(); if (SCRIPT_ENABLED && script_str) script_finish(); unload_module_symtabs(); pr_dbg("exit from libmcount\n"); } /* * external interfaces */ #define UFTRACE_ALIAS(_func) void uftrace_##_func(void*, void*) __alias(_func) void __visible_default __monstartup(unsigned long low, unsigned long high) { } void __visible_default _mcleanup(void) { } void __visible_default mcount_restore(void) { struct mcount_thread_data *mtdp; mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) return; mcount_rstack_restore(mtdp); } void __visible_default mcount_reset(void) { struct mcount_thread_data *mtdp; mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) return; mcount_rstack_reset(mtdp); } void __visible_default __cyg_profile_func_enter(void *child, void *parent) { cygprof_entry((unsigned long)parent, (unsigned long)child); } UFTRACE_ALIAS(__cyg_profile_func_enter); void __visible_default __cyg_profile_func_exit(void *child, void *parent) { cygprof_exit((unsigned long)parent, (unsigned long)child); } UFTRACE_ALIAS(__cyg_profile_func_exit); #ifndef UNIT_TEST /* * Initializer and Finalizer */ static void __attribute__((constructor)) mcount_init(void) { mcount_startup(); } static void __attribute__((destructor)) mcount_fini(void) { mcount_cleanup(); } #else /* UNIT_TEST */ static void setup_mcount_test(void) { mcount_exename = read_exename(); pthread_key_create(&mtd_key, mtd_dtor); mcount_global_flags = 0; } TEST_CASE(mcount_thread_data) { struct mcount_thread_data *mtdp; setup_mcount_test(); mtdp = get_thread_data(); TEST_EQ(check_thread_data(mtdp), true); mtdp = mcount_prepare(); TEST_EQ(check_thread_data(mtdp), false); TEST_EQ(get_thread_data(), mtdp); TEST_EQ(check_thread_data(mtdp), false); mcount_cleanup(); return TEST_OK; } TEST_CASE(mcount_signal_setup) { struct signal_trigger_item *item; struct uftrace_filter_setting setting = { .ptype = PATT_NONE, }; /* it signal triggers are maintained in a stack (LIFO) */ mcount_signal_init("SIGUSR1@traceon;USR2@traceoff;RTMIN+3@finish", &setting); item = list_first_entry(&siglist, typeof(*item), list); TEST_EQ(item->sig, SIGRTMIN + 3); TEST_EQ(item->tr.flags, TRIGGER_FL_FINISH); item = list_next_entry(item, list); TEST_EQ(item->sig, SIGUSR2); TEST_EQ(item->tr.flags, TRIGGER_FL_TRACE_OFF); item = list_next_entry(item, list); TEST_EQ(item->sig, SIGUSR1); TEST_EQ(item->tr.flags, TRIGGER_FL_TRACE_ON); mcount_signal_finish(); TEST_EQ(list_empty(&siglist), true); return TEST_OK; } #endif /* UNIT_TEST */ uftrace-0.9.3/libmcount/mcount.h000066400000000000000000000037661351236475300166530ustar00rootroot00000000000000/* * data structures for handling mcount records * * Copyright (C) 2014-2018, LG Electronics, Namhyung Kim * * Released under the GPL v2. */ #ifndef UFTRACE_MCOUNT_H #define UFTRACE_MCOUNT_H #include #include #include #define UFTRACE_DIR_NAME "uftrace.data" #define MCOUNT_RSTACK_MAX OPT_RSTACK_DEFAULT #define MCOUNT_DEFAULT_DEPTH OPT_DEPTH_DEFAULT #define MCOUNT_NOTRACE_IDX 0x10000 #define MCOUNT_INVALID_DYNIDX 0xefefefef enum mcount_rstack_flag { MCOUNT_FL_SETJMP = (1U << 0), MCOUNT_FL_LONGJMP = (1U << 1), MCOUNT_FL_NORECORD = (1U << 2), MCOUNT_FL_NOTRACE = (1U << 3), MCOUNT_FL_FILTERED = (1U << 4), MCOUNT_FL_VFORK = (1U << 5), MCOUNT_FL_WRITTEN = (1U << 6), MCOUNT_FL_DISABLED = (1U << 7), MCOUNT_FL_RECOVER = (1U << 8), MCOUNT_FL_RETVAL = (1U << 9), MCOUNT_FL_TRACE = (1U << 10), MCOUNT_FL_ARGUMENT = (1U << 11), MCOUNT_FL_READ = (1U << 12), MCOUNT_FL_CALLER = (1U << 13), }; struct plthook_data; struct list_head; struct mcount_ret_stack { unsigned long *parent_loc; unsigned long parent_ip; unsigned long child_ip; enum mcount_rstack_flag flags; /* time in nsec (CLOCK_MONOTONIC) */ uint64_t start_time; uint64_t end_time; int tid; unsigned dyn_idx; uint64_t filter_time; unsigned short depth; unsigned short filter_depth; unsigned short nr_events; unsigned short event_idx; struct plthook_data *pd; /* set arg_spec at function entry and use it at exit */ struct list_head *pargs; }; void __monstartup(unsigned long low, unsigned long high); void _mcleanup(void); void mcount_restore(void); void mcount_reset(void); #define SHMEM_BUFFER_SIZE (128 * 1024) enum shmem_buffer_flags { SHMEM_FL_NEW = (1U << 0), SHMEM_FL_WRITTEN = (1U << 1), SHMEM_FL_RECORDING = (1U << 2), }; struct mcount_shmem_buffer { unsigned size; unsigned flag; unsigned unused[2]; char data[]; }; /* must be in sync with enum debug_domain (bits) */ #define DBG_DOMAIN_STR "TSDFfsKMpPERW" #endif /* UFTRACE_MCOUNT_H */ uftrace-0.9.3/libmcount/misc.c000066400000000000000000000137531351236475300162710ustar00rootroot00000000000000#include #include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "mcount" #define PR_DOMAIN DBG_MCOUNT #include "libmcount/mcount.h" #include "libmcount/internal.h" #include "utils/utils.h" /* old kernel never updates pid filter for a forked child */ void update_kernel_tid(int tid) { static const char TRACING_DIR[] = "/sys/kernel/debug/tracing"; char *filename = NULL; char buf[8]; int fd; ssize_t len; if (!kernel_pid_update) return; /* update pid filter for function tracing */ xasprintf(&filename, "%s/set_ftrace_pid", TRACING_DIR); fd = open(filename, O_WRONLY | O_APPEND); if (fd < 0) return; snprintf(buf, sizeof(buf), "%d", tid); len = strlen(buf); if (write(fd, buf, len) != len) pr_dbg("update kernel ftrace tid filter failed\n"); close(fd); free(filename); /* update pid filter for event tracing */ xasprintf(&filename, "%s/set_event_pid", TRACING_DIR); fd = open(filename, O_WRONLY | O_APPEND); if (fd < 0) return; snprintf(buf, sizeof(buf), "%d", tid); len = strlen(buf); if (write(fd, buf, len) != len) pr_dbg("update kernel ftrace tid filter failed\n"); close(fd); free(filename); } const char *mcount_session_name(void) { static char session[SESSION_ID_LEN + 1]; static uint64_t session_id; int fd; if (!session_id) { fd = open("/dev/urandom", O_RDONLY); if (fd >= 0) { if (read(fd, &session_id, sizeof(session_id)) != 8) pr_err("reading from urandom"); close(fd); } else { srandom(time(NULL)); session_id = random(); session_id <<= 32; session_id |= random(); } snprintf(session, sizeof(session), "%0*"PRIx64, SESSION_ID_LEN, session_id); } return session; } void uftrace_send_message(int type, void *data, size_t len) { struct uftrace_msg msg = { .magic = UFTRACE_MSG_MAGIC, .type = type, .len = len, }; struct iovec iov[2] = { { .iov_base = &msg, .iov_len = sizeof(msg), }, { .iov_base = data, .iov_len = len, }, }; if (pfd < 0) return; len += sizeof(msg); if (writev(pfd, iov, 2) != (ssize_t)len) { if (!mcount_should_stop()) pr_err("writing shmem name to pipe"); } } void build_debug_domain(char *dbg_domain_str) { int i, len; if (dbg_domain_str == NULL) return; len = strlen(dbg_domain_str); for (i = 0; i < len; i += 2) { const char *pos; char domain = dbg_domain_str[i]; int level = dbg_domain_str[i+1] - '0'; int d; pos = strchr(DBG_DOMAIN_STR, domain); if (pos == NULL) continue; d = pos - DBG_DOMAIN_STR; dbg_domain[d] = level; } } bool mcount_rstack_has_plthook(struct mcount_thread_data *mtdp) { int idx; for (idx = 0; idx < mtdp->idx; idx++) { if (mtdp->rstack[idx].dyn_idx != MCOUNT_INVALID_DYNIDX) return true; } return false; } /* restore saved original return address */ void mcount_rstack_restore(struct mcount_thread_data *mtdp) { int idx; struct mcount_ret_stack *rstack; /* reverse order due to tail calls */ for (idx = mtdp->idx - 1; idx >= 0; idx--) { rstack = &mtdp->rstack[idx]; if (rstack->parent_ip == mcount_return_fn || rstack->parent_ip == (unsigned long)plthook_return) continue; if (!ARCH_CAN_RESTORE_PLTHOOK && rstack->dyn_idx != MCOUNT_INVALID_DYNIDX) continue; *rstack->parent_loc = rstack->parent_ip; } } /* hook return address again (used after mcount_rstack_restore) */ void mcount_rstack_reset(struct mcount_thread_data *mtdp) { int idx; struct mcount_ret_stack *rstack; for (idx = mtdp->idx - 1; idx >= 0; idx--) { rstack = &mtdp->rstack[idx]; if (rstack->dyn_idx == MCOUNT_INVALID_DYNIDX) *rstack->parent_loc = mcount_return_fn; else if (ARCH_CAN_RESTORE_PLTHOOK) *rstack->parent_loc = (unsigned long)plthook_return; } } void mcount_auto_restore(struct mcount_thread_data *mtdp) { struct mcount_ret_stack *curr_rstack; struct mcount_ret_stack *prev_rstack; /* auto recover is meaningful only if parent rstack is hooked */ if (mtdp->idx < 2) return; if (mtdp->in_exception) return; curr_rstack = &mtdp->rstack[mtdp->idx - 1]; prev_rstack = &mtdp->rstack[mtdp->idx - 2]; if (!ARCH_CAN_RESTORE_PLTHOOK && prev_rstack->dyn_idx != MCOUNT_INVALID_DYNIDX) return; /* ignore tail calls */ if (curr_rstack->parent_loc == prev_rstack->parent_loc) return; while (prev_rstack >= mtdp->rstack) { unsigned long parent_ip = prev_rstack->parent_ip; /* parent also can be tail-called; skip */ if (parent_ip == mcount_return_fn || parent_ip == (unsigned long)plthook_return) { prev_rstack--; continue; } *prev_rstack->parent_loc = parent_ip; return; } } void mcount_auto_reset(struct mcount_thread_data *mtdp) { struct mcount_ret_stack *curr_rstack; struct mcount_ret_stack *prev_rstack; /* auto recover is meaningful only if parent rstack is hooked */ if (mtdp->idx < 2) return; if (mtdp->in_exception) return; curr_rstack = &mtdp->rstack[mtdp->idx - 1]; prev_rstack = &mtdp->rstack[mtdp->idx - 2]; if (!ARCH_CAN_RESTORE_PLTHOOK && prev_rstack->dyn_idx != MCOUNT_INVALID_DYNIDX) return; /* ignore tail calls */ if (curr_rstack->parent_loc == prev_rstack->parent_loc) return; if (prev_rstack->dyn_idx == MCOUNT_INVALID_DYNIDX) *prev_rstack->parent_loc = mcount_return_fn; else *prev_rstack->parent_loc = (unsigned long)plthook_return; } #ifdef UNIT_TEST TEST_CASE(mcount_debug_domain) { int i; char dbg_str[DBG_DOMAIN_MAX * 2 + 1]; /* ensure domain string matches to current domain bit */ TEST_EQ(DBG_DOMAIN_MAX, (int)strlen(DBG_DOMAIN_STR)); for (i = 0; i < DBG_DOMAIN_MAX; i++) { if (i != PR_DOMAIN) TEST_EQ(dbg_domain[i], 0); } for (i = 0; i < DBG_DOMAIN_MAX; i++) { dbg_str[i * 2] = DBG_DOMAIN_STR[i]; dbg_str[i * 2 + 1] = '1'; } dbg_str[i * 2] = '\0'; build_debug_domain(dbg_str); for (i = 0; i < DBG_DOMAIN_MAX; i++) TEST_EQ(dbg_domain[i], 1); /* increase mcount debug domain to 2 */ strcpy(dbg_str, "M2"); build_debug_domain(dbg_str); TEST_EQ(dbg_domain[PR_DOMAIN], 2); return TEST_OK; } #endif /* UNIT_TEST */ uftrace-0.9.3/libmcount/plthook.c000066400000000000000000000621261351236475300170140ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "plthook" #define PR_DOMAIN DBG_PLTHOOK #include "libmcount/mcount.h" #include "libmcount/internal.h" #include "mcount-arch.h" #include "utils/utils.h" #include "utils/filter.h" #include "utils/script.h" #include "utils/symbol.h" #ifndef PT_GNU_RELRO # define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ #endif /* global symbol tables for libmcount */ extern struct symtabs symtabs; /* address of dynamic linker's resolver routine (copied from GOT[2]) */ unsigned long plthook_resolver_addr; /* referenced by arch/.../plthook.S */ /* list of plthook_data for each library (module) */ static LIST_HEAD(plthook_modules); /* check getenv("LD_BIND_NOT") */ static bool plthook_no_pltbind; static void overwrite_pltgot(struct plthook_data *pd, int idx, void *data) { /* overwrite it - might be write-protected */ pd->pltgot_ptr[idx] = (unsigned long)data; } unsigned long setup_pltgot(struct plthook_data *pd, int got_idx, int sym_idx, void *data) { unsigned long real_addr = pd->pltgot_ptr[got_idx]; pd->resolved_addr[sym_idx] = real_addr; overwrite_pltgot(pd, got_idx, data); return real_addr; } static void resolve_pltgot(struct plthook_data *pd, int idx) { if (pd->resolved_addr[idx] == 0) { unsigned long addr; struct sym *sym; sym = &pd->dsymtab.sym[idx]; addr = (unsigned long) dlsym(RTLD_DEFAULT, sym->name); /* On ARM dlsym(DEFAULT) returns the address of PLT */ if (unlikely(pd->base_addr <= addr && addr < sym->addr + sym->size)) { void *real_addr = dlsym(RTLD_NEXT, sym->name); if (real_addr) addr = (unsigned long)real_addr; } pr_dbg2("resolved addr of %s = %#lx\n", sym->name, addr); pd->resolved_addr[idx] = addr; } } /* use weak reference for non-defined (arch-dependent) symbols */ #define ALIAS_DECL(_sym) extern __weak void (*uftrace_##_sym)(void); ALIAS_DECL(mcount); ALIAS_DECL(_mcount); ALIAS_DECL(__fentry__); ALIAS_DECL(__gnu_mcount_nc); ALIAS_DECL(__cyg_profile_func_enter); ALIAS_DECL(__cyg_profile_func_exit); #define SKIP_SYM(func) { #func, &uftrace_ ## func } const struct plthook_skip_symbol plt_skip_syms[] = { SKIP_SYM(mcount), SKIP_SYM(_mcount), SKIP_SYM(__fentry__), SKIP_SYM(__gnu_mcount_nc), SKIP_SYM(__cyg_profile_func_enter), SKIP_SYM(__cyg_profile_func_exit), }; size_t plt_skip_nr = ARRAY_SIZE(plt_skip_syms); #undef SKIP_SYM #undef ALIAS_DECL /* * The `mcount` (and its friends) are part of uftrace itself, * so no need to use PLT hook for them. */ static void restore_plt_functions(struct plthook_data *pd) { unsigned i, k; struct symtab *dsymtab = &pd->dsymtab; for (i = 0; i < dsymtab->nr_sym; i++) { /* * GOT[0], GOT[1], and GOT[2] are reserved. * GOT[2] initially points to the runtime resolver, but updated * to plt_hooker for library tracing by uftrace. * The addresses from GOT[3] are supposed to point the resolved * addresses for each library function. */ int got_idx = 3 + i; bool skipped = false; unsigned long plthook_addr; unsigned long resolved_addr; struct sym *sym = dsymtab->sym_names[i]; for (k = 0; k < plt_skip_nr; k++) { const struct plthook_skip_symbol *skip_sym; skip_sym = &plt_skip_syms[k]; if (strcmp(sym->name, skip_sym->name)) continue; overwrite_pltgot(pd, got_idx, skip_sym->addr); pr_dbg2("overwrite GOT[%d] to %p (%s)\n", got_idx, skip_sym->addr, skip_sym->name); skipped = true; break; } if (skipped) continue; resolved_addr = pd->pltgot_ptr[got_idx]; plthook_addr = mcount_arch_plthook_addr(pd, i); if (resolved_addr != plthook_addr) { /* save already resolved address and hook it */ pd->resolved_addr[i] = resolved_addr; overwrite_pltgot(pd, got_idx, (void *)plthook_addr); pr_dbg2("restore GOT[%d] from \"%s\"(%#lx) to PLT(base + %#lx)\n", got_idx, sym->name, resolved_addr, plthook_addr - pd->base_addr); } } } extern void __weak plt_hooker(void); extern unsigned long plthook_return(void); __weak struct plthook_data *mcount_arch_hook_no_plt(struct uftrace_elf_data *elf, const char *modname, unsigned long offset) { return NULL; } __weak void mcount_arch_plthook_setup(struct plthook_data *pd, struct uftrace_elf_data *elf) { pd->arch = NULL; } static int find_got(struct uftrace_elf_data *elf, struct uftrace_elf_iter *iter, const char *modname, unsigned long offset) { bool plt_found = false; unsigned long pltgot_addr = 0; unsigned long plt_addr = 0; struct plthook_data *pd; elf_for_each_shdr(elf, iter) { if (iter->shdr.sh_type == SHT_DYNAMIC) break; } elf_for_each_dynamic(elf, iter) { switch (iter->dyn.d_tag) { case DT_PLTGOT: pltgot_addr = (unsigned long)iter->dyn.d_un.d_val + offset; break; case DT_JMPREL: plt_found = true; break; default: break; } } if (!plt_found) { pd = mcount_arch_hook_no_plt(elf, modname, offset); if (pd == NULL) pr_dbg2("no PLTGOT found.. ignoring...\n"); else list_add_tail(&pd->list, &plthook_modules); return 0; } elf_for_each_shdr(elf, iter) { char *shstr = elf_get_name(elf, iter, iter->shdr.sh_name); if (strcmp(shstr, ".plt") == 0) { plt_addr = iter->shdr.sh_addr + offset; break; } } if (plt_addr == 0) { pr_dbg("cannot find PLT address\n"); return 0; } pd = xmalloc(sizeof(*pd)); pd->mod_name = xstrdup(modname); pd->pltgot_ptr = (void *)pltgot_addr; pd->module_id = pd->pltgot_ptr[1]; pd->base_addr = offset; pd->plt_addr = plt_addr; pr_dbg2("\"%s\" is loaded at %#lx\n", basename(pd->mod_name), pd->base_addr); memset(&pd->dsymtab, 0, sizeof(pd->dsymtab)); load_elf_dynsymtab(&pd->dsymtab, elf, pd->base_addr, SYMTAB_FL_DEMANGLE); pd->resolved_addr = xcalloc(pd->dsymtab.nr_sym, sizeof(long)); pd->special_funcs = NULL; pd->nr_special = 0; mcount_arch_plthook_setup(pd, elf); list_add_tail(&pd->list, &plthook_modules); if (plt_found) { if (plthook_resolver_addr == 0) plthook_resolver_addr = pd->pltgot_ptr[2]; /* * BIND_NOW (+ RELRO) makes module id not used and resets to 0. * but we still need it to find pd from plthook_enter(). */ if (pd->module_id == 0) { pr_dbg2("update module id to %p\n", pd); overwrite_pltgot(pd, 1, pd); pd->module_id = (unsigned long)pd; } pr_dbg2("found GOT at %p (base_addr + %#lx)\n", pd->pltgot_ptr, (unsigned long)pd->pltgot_ptr - pd->base_addr); pr_dbg2("module id = %#lx, PLT resolver = %#lx\n", pd->module_id, plthook_resolver_addr); restore_plt_functions(pd); } overwrite_pltgot(pd, 2, plt_hooker); if (getenv("LD_BIND_NOT")) plthook_no_pltbind = true; return 0; } static int hook_pltgot(const char *modname, unsigned long offset) { int ret = -1; bool relro = false; unsigned long relro_start = 0; unsigned long relro_size = 0; unsigned long page_size; struct uftrace_elf_data elf; struct uftrace_elf_iter iter; bool found_dynamic = false; pr_dbg2("opening executable image: %s\n", modname); if (elf_init(modname, &elf) < 0) return -1; elf_for_each_phdr(&elf, &iter) { if (iter.phdr.p_type == PT_DYNAMIC) found_dynamic = true; if (iter.phdr.p_type == PT_GNU_RELRO) { relro_start = iter.phdr.p_vaddr + offset; relro_size = iter.phdr.p_memsz; page_size = getpagesize(); relro_start &= ~(page_size - 1); relro_size = ALIGN(relro_size, page_size); relro = true; } } if (found_dynamic) { if (relro) { mprotect((void *)relro_start, relro_size, PROT_READ | PROT_WRITE); } ret = find_got(&elf, &iter, modname, offset); if (relro) mprotect((void *)relro_start, relro_size, PROT_READ); } elf_finish(&elf); return ret; } /* functions should skip PLT hooking */ static const char *skip_syms[] = { "_mcleanup", "__libc_start_main", "__cxa_throw", "__cxa_rethrow", "__cxa_begin_catch", "__cxa_end_catch", "__cxa_finalize", "_Unwind_Resume", }; static const char *setjmp_syms[] = { "setjmp", "_setjmp", "sigsetjmp", "__sigsetjmp", }; static const char *longjmp_syms[] = { "longjmp", "siglongjmp", "__longjmp_chk", }; static const char *vfork_syms[] = { "vfork", }; static const char *dlsym_syms[] = { "dlsym", "dlvsym", }; static const char *flush_syms[] = { "fork", "vfork", "daemon", "exit", "longjmp", "siglongjmp", "__longjmp_chk", "execl", "execlp", "execle", "execv", "execve", "execvp", "execvpe", "fexecve", "posix_spawn", "posix_spawnp", }; static const char *except_syms[] = { "_Unwind_RaiseException", }; static const char *resolve_syms[] = { "execl", "execlp", "execle", "execv", "execve", "execvp", "execvpe", "fexecve", "posix_spawn", "posix_spawnp", "pthread_exit", }; static void add_special_func(struct plthook_data *pd, unsigned idx, unsigned flags) { int i; struct plthook_special_func *func; for (i = 0; i < pd->nr_special; i++) { func = &pd->special_funcs[i]; if (func->idx == idx) { func->flags |= flags; return; } } pd->special_funcs = xrealloc(pd->special_funcs, (pd->nr_special + 1) * sizeof(*func)); func = &pd->special_funcs[pd->nr_special++]; func->idx = idx; func->flags = flags; } static void build_special_funcs(struct plthook_data *pd, const char *syms[], unsigned nr_sym, unsigned flag) { unsigned i; struct dynsym_idxlist idxlist; build_dynsym_idxlist(&pd->dsymtab, &idxlist, syms, nr_sym); for (i = 0; i < idxlist.count; i++) add_special_func(pd, idxlist.idx[i], flag); destroy_dynsym_idxlist(&idxlist); } static int idxsort(const void *a, const void *b) { const struct plthook_special_func *func_a = a; const struct plthook_special_func *func_b = b; if (func_a->idx > func_b->idx) return 1; if (func_a->idx < func_b->idx) return -1; return 0; } static int idxfind(const void *a, const void *b) { unsigned idx = (unsigned long) a; const struct plthook_special_func *func = b; if (func->idx == idx) return 0; return (idx > func->idx) ? 1 : -1; } void setup_dynsym_indexes(struct plthook_data *pd) { build_special_funcs(pd, skip_syms, ARRAY_SIZE(skip_syms), PLT_FL_SKIP); build_special_funcs(pd, longjmp_syms, ARRAY_SIZE(longjmp_syms), PLT_FL_LONGJMP); build_special_funcs(pd, setjmp_syms, ARRAY_SIZE(setjmp_syms), PLT_FL_SETJMP); build_special_funcs(pd, vfork_syms, ARRAY_SIZE(vfork_syms), PLT_FL_VFORK); build_special_funcs(pd, dlsym_syms, ARRAY_SIZE(dlsym_syms), PLT_FL_DLSYM); build_special_funcs(pd, flush_syms, ARRAY_SIZE(flush_syms), PLT_FL_FLUSH); build_special_funcs(pd, except_syms, ARRAY_SIZE(except_syms), PLT_FL_EXCEPT); build_special_funcs(pd, resolve_syms, ARRAY_SIZE(resolve_syms), PLT_FL_RESOLVE); /* built all table, now sorting */ qsort(pd->special_funcs, pd->nr_special, sizeof(*pd->special_funcs), idxsort); } void destroy_dynsym_indexes(void) { struct plthook_data *pd; pr_dbg2("destroy plthook special function index\n"); list_for_each_entry(pd, &plthook_modules, list) { free(pd->special_funcs); pd->special_funcs = NULL; pd->nr_special = 0; } } static int setup_mod_plthook_data(struct dl_phdr_info *info, size_t sz, void *arg) { const char *exename = info->dlpi_name; unsigned long offset = info->dlpi_addr; static const char * const skip_libs[] = { /* uftrace internal libraries */ "libmcount.so", "libmcount-fast.so", "libmcount-single.so", "libmcount-fast-single.so", /* system base libraries */ "libc.so.6", "libc-2.*.so", "libgcc_s.so.1", "libpthread.so.0", "libpthread-2.*.so", "linux-vdso.so.1", "linux-gate.so.1", "ld-linux-*.so.*", "libdl.so.2", "libdl-2.*.so", }; size_t k; static bool exe_once = true; if (exename[0] == '\0') { if (!exe_once) return 0; exename = arg; exe_once = false; } for (k = 0; k < ARRAY_SIZE(skip_libs); k++) { if (!fnmatch(skip_libs[k], basename(exename), 0)) return 0; } pr_dbg2("setup plthook data for %s (offset: %lx)\n", exename, offset); if (hook_pltgot(exename, offset) < 0) pr_dbg("error when hooking plt: skipping...\n"); return 0; } static int setup_exe_plthook_data(struct dl_phdr_info *info, size_t sz, void *arg) { const char *exename = arg; unsigned long offset = info->dlpi_addr; pr_dbg2("setup plthook data for %s (offset: %lx)\n", exename, offset); hook_pltgot(exename, offset); return 1; } void mcount_setup_plthook(char *exename, bool nest_libcall) { struct plthook_data *pd; pr_dbg("setup %sPLT hooking \"%s\"\n", nest_libcall ? "nested " : "", exename); if (!nest_libcall) dl_iterate_phdr(setup_exe_plthook_data, exename); else dl_iterate_phdr(setup_mod_plthook_data, exename); list_for_each_entry(pd, &plthook_modules, list) setup_dynsym_indexes(pd); } struct mcount_jmpbuf_rstack { struct list_head list; unsigned long addr; int count; int record_idx; struct mcount_ret_stack rstack[MCOUNT_RSTACK_MAX]; }; static LIST_HEAD(jmpbuf_list); static void setup_jmpbuf_rstack(struct mcount_thread_data *mtdp, unsigned long addr) { int i; struct mcount_jmpbuf_rstack *jbstack; list_for_each_entry(jbstack, &jmpbuf_list, list) { if (jbstack->addr == addr) break; } if (list_no_entry(jbstack, &jmpbuf_list, list)) { jbstack = xmalloc(sizeof(*jbstack)); jbstack->addr = addr; list_add(&jbstack->list, &jmpbuf_list); } pr_dbg2("setup jmpbuf rstack at %lx (%d entries)\n", addr, mtdp->idx); /* currently, only saves a single jmpbuf */ jbstack->count = mtdp->idx; jbstack->record_idx = mtdp->record_idx; for (i = 0; i < jbstack->count; i++) jbstack->rstack[i] = mtdp->rstack[i]; } static void restore_jmpbuf_rstack(struct mcount_thread_data *mtdp, unsigned long addr) { int i; struct mcount_jmpbuf_rstack *jbstack; list_for_each_entry(jbstack, &jmpbuf_list, list) { if (jbstack->addr == addr) break; } assert(!list_no_entry(jbstack, &jmpbuf_list, list)); pr_dbg2("restore jmpbuf rstack at %lx (%d entries)\n", addr, jbstack->count); mtdp->idx = jbstack->count; mtdp->record_idx = jbstack->record_idx; for (i = 0; i < jbstack->count; i++) { mtdp->rstack[i] = jbstack->rstack[i]; /* setjmp() already wrote rstacks */ mtdp->rstack[i].flags |= MCOUNT_FL_WRITTEN; } } /* it's crazy to call vfork() concurrently */ static int vfork_parent; static int vfork_rstack_idx; static int vfork_record_idx; static struct mcount_ret_stack vfork_rstack; static struct mcount_shmem vfork_shmem; static void prepare_vfork(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack) { /* save original parent info */ vfork_parent = getpid(); vfork_rstack_idx = mtdp->idx; vfork_record_idx = mtdp->record_idx; mcount_memcpy4(&vfork_rstack, rstack, sizeof(*rstack)); /* it will be force flushed */ vfork_rstack.flags |= MCOUNT_FL_WRITTEN; } /* this function will be called in child */ static void setup_vfork(struct mcount_thread_data *mtdp) { struct uftrace_msg_task tmsg = { .pid = getppid(), .tid = getpid(), .time = mcount_gettime(), }; /* update tid cache */ mtdp->tid = tmsg.tid; mcount_memcpy4(&vfork_shmem, &mtdp->shmem, sizeof(vfork_shmem)); /* setup new shmem buffer for child */ mcount_memset4(&mtdp->shmem, 0, sizeof(mtdp->shmem)); prepare_shmem_buffer(mtdp); uftrace_send_message(UFTRACE_MSG_FORK_START, &tmsg, sizeof(tmsg)); uftrace_send_message(UFTRACE_MSG_FORK_END, &tmsg, sizeof(tmsg)); update_kernel_tid(tmsg.tid); } /* this function detects whether child finished */ static struct mcount_ret_stack * restore_vfork(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack) { /* * On vfork, parent sleeps until child exec'ed or exited. * So if it sees parent pid, that means child was done. */ if (getpid() == vfork_parent) { /* flush tid cache */ mtdp->tid = 0; mtdp->idx = vfork_rstack_idx; mtdp->record_idx = vfork_record_idx; rstack = &mtdp->rstack[mtdp->idx - 1]; vfork_parent = 0; mcount_memcpy4(&mtdp->shmem, &vfork_shmem, sizeof(vfork_shmem)); mcount_memcpy4(rstack, &vfork_rstack, sizeof(*rstack)); } return rstack; } /* * mcount_arch_plthook_addr() returns the address of GOT entry. * The initial value for each GOT entry redirects the execution to * the runtime resolver. (_dl_runtime_resolve in ld-linux.so) * * The GOT entry is updated by the runtime resolver to the resolved address of * the target library function for later reference. * * However, uftrace gets this address to update it back to the initial value. * Even if the GOT entry is resolved by runtime resolver, uftrace restores the * address back to the initial value to watch library function calls. * * Before doing this work, GOT[2] is updated from the address of runtime * resolver(_dl_runtime_resolve) to uftrace hooking routine(plt_hooker). * * This address depends on the PLT structure of each architecture so this * function is implemented differently for each architecture. */ __weak unsigned long mcount_arch_plthook_addr(struct plthook_data *pd, int idx) { struct sym *sym; sym = &pd->dsymtab.sym[idx]; return sym->addr + ARCH_PLTHOOK_ADDR_OFFSET; } static void update_pltgot(struct mcount_thread_data *mtdp, struct plthook_data *pd, int dyn_idx) { if (unlikely(plthook_no_pltbind)) return; if (!pd->resolved_addr[dyn_idx]) { unsigned long plthook_addr; #ifndef SINGLE_THREAD static pthread_mutex_t resolver_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&resolver_mutex); #endif if (!pd->resolved_addr[dyn_idx]) { int got_idx = 3 + dyn_idx; plthook_addr = mcount_arch_plthook_addr(pd, dyn_idx); setup_pltgot(pd, got_idx, dyn_idx, (void*)plthook_addr); } #ifndef SINGLE_THREAD pthread_mutex_unlock(&resolver_mutex); #endif } } __weak unsigned long mcount_arch_child_idx(unsigned long child_idx) { return child_idx; } static unsigned long __plthook_entry(unsigned long *ret_addr, unsigned long child_idx, unsigned long module_id, struct mcount_regs *regs) { struct sym *sym; struct mcount_thread_data *mtdp = NULL; struct mcount_ret_stack *rstack; struct uftrace_trigger tr = { .flags = 0, }; bool skip = false; bool recursion = true; enum filter_result filtered; struct plthook_data *pd; struct plthook_special_func *func; unsigned long special_flag = 0; unsigned long real_addr = 0; // if necessary, implement it by architecture. child_idx = mcount_arch_child_idx(child_idx); list_for_each_entry(pd, &plthook_modules, list) { if (module_id == pd->module_id) break; } if (list_no_entry(pd, &plthook_modules, list)) { pr_dbg("cannot find pd for module id: %lx\n", module_id); pd = NULL; goto out; } mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) { mtdp = mcount_prepare(); if (mtdp == NULL) goto out; } else { if (!mcount_guard_recursion(mtdp)) goto out; } recursion = false; func = bsearch((void *)child_idx, pd->special_funcs, pd->nr_special, sizeof(*func), idxfind); if (func) special_flag |= func->flags; if (unlikely(special_flag & PLT_FL_SKIP)) goto out; if (likely(child_idx < pd->dsymtab.nr_sym)) { sym = &pd->dsymtab.sym[child_idx]; pr_dbg3("[idx: %4d] enter %"PRIx64": %s@plt (mod: %lx)\n", (int)child_idx, sym->addr, sym->name, module_id); } else { sym = NULL; pr_err_ns("invalid function idx found! (idx: %lu/%zu, module: %s)\n", child_idx, pd->dsymtab.nr_sym, pd->mod_name); } filtered = mcount_entry_filter_check(mtdp, sym->addr, &tr); if (filtered != FILTER_IN) { /* * Skip recording but still hook the return address, * otherwise it cannot trace further invocations due to * the overwritten PLT entry by the resolver function. */ skip = true; /* but if we don't have rstack, just bail out */ if (filtered == FILTER_RSTACK) goto out; } rstack = &mtdp->rstack[mtdp->idx++]; rstack->depth = mtdp->record_idx; rstack->pd = pd; rstack->dyn_idx = child_idx; rstack->parent_loc = ret_addr; rstack->parent_ip = *ret_addr; rstack->child_ip = sym->addr; rstack->start_time = skip ? 0 : mcount_gettime(); rstack->end_time = 0; rstack->flags = skip ? MCOUNT_FL_NORECORD : 0; rstack->nr_events = 0; rstack->event_idx = ARGBUF_SIZE; /* hijack the return address of child */ *ret_addr = (unsigned long)plthook_return; /* restore return address of parent */ if (mcount_auto_recover) mcount_auto_restore(mtdp); mcount_entry_filter_record(mtdp, rstack, &tr, regs); if (unlikely(special_flag)) { /* force flush rstack on some special functions */ if (special_flag & PLT_FL_FLUSH) { record_trace_data(mtdp, rstack, NULL); } if (special_flag & PLT_FL_SETJMP) { setup_jmpbuf_rstack(mtdp, ARG1(regs)); } else if (special_flag & PLT_FL_LONGJMP) { rstack->flags |= MCOUNT_FL_LONGJMP; /* abuse end-time for the jmpbuf addr */ rstack->end_time = ARG1(regs); } else if (special_flag & PLT_FL_VFORK) { rstack->flags |= MCOUNT_FL_VFORK; prepare_vfork(mtdp, rstack); } else if (special_flag & PLT_FL_DLSYM) { /* * Using RTLD_NEXT in a shared library caused * an infinite loop since libdl thinks it's * called from libmcount due to the return address. */ if (ARG1(regs) == (unsigned long)RTLD_NEXT && strcmp(pd->mod_name, mcount_exename)) { *ret_addr = rstack->parent_ip; if (mcount_auto_recover) mcount_auto_reset(mtdp); /* * as its return address was recovered, * we need to manually resolve the function * not to overwrite PLT entry by the linker. */ special_flag |= PLT_FL_RESOLVE; if (!(rstack->flags & MCOUNT_FL_NORECORD)) rstack->end_time = mcount_gettime(); mcount_exit_filter_record(mtdp, rstack, NULL); mtdp->idx--; } } else if (special_flag & PLT_FL_EXCEPT) { /* exception handling requires stack unwind */ mcount_rstack_restore(mtdp); } if (special_flag & PLT_FL_RESOLVE) { /* some functions don't have a chance to resolve */ resolve_pltgot(pd, child_idx); } } out: if (likely(pd && child_idx < pd->dsymtab.nr_sym) && pd->resolved_addr[child_idx] != 0) real_addr = pd->resolved_addr[child_idx]; if (!recursion) mcount_unguard_recursion(mtdp); return real_addr; } unsigned long plthook_entry(unsigned long *ret_addr, unsigned long child_idx, unsigned long module_id, struct mcount_regs *regs) { int saved_errno = errno; unsigned long ret; ret = __plthook_entry(ret_addr, child_idx, module_id, regs); errno = saved_errno; return ret; } void mtd_dtor(void *arg); static unsigned long __plthook_exit(long *retval) { unsigned dyn_idx; struct mcount_thread_data *mtdp; struct mcount_ret_stack *rstack; unsigned long *ret_loc; unsigned long ret_addr = 0; mtdp = get_thread_data(); assert(!check_thread_data(mtdp)); /* * it's only called when mcount_entry() was succeeded * no need to check recursion here. But still needs to * prevent recursion during this call. */ __mcount_guard_recursion(mtdp); again: if (likely(mtdp->idx > 0)) rstack = &mtdp->rstack[mtdp->idx - 1]; else rstack = restore_vfork(mtdp, NULL); /* FIXME! */ if (unlikely(rstack->flags & (MCOUNT_FL_LONGJMP | MCOUNT_FL_VFORK))) { if (rstack->flags & MCOUNT_FL_LONGJMP) { update_pltgot(mtdp, rstack->pd, rstack->dyn_idx); rstack->flags &= ~MCOUNT_FL_LONGJMP; restore_jmpbuf_rstack(mtdp, rstack->end_time); goto again; } if (rstack->flags & MCOUNT_FL_VFORK) setup_vfork(mtdp); } if (unlikely(vfork_parent)) rstack = restore_vfork(mtdp, rstack); dyn_idx = rstack->dyn_idx; if (unlikely(dyn_idx == MCOUNT_INVALID_DYNIDX || dyn_idx >= rstack->pd->dsymtab.nr_sym)) pr_err_ns("<%d> invalid dynsym idx: %d\n", mtdp->idx, dyn_idx); if (!ARCH_CAN_RESTORE_PLTHOOK && unlikely(mtdp->dead)) { ret_addr = rstack->parent_ip; /* make sure it doesn't have plthook below */ mtdp->idx--; if (!mcount_rstack_has_plthook(mtdp)) { free(mtdp->rstack); mtdp->rstack = NULL; mtdp->idx = 0; } return ret_addr; } if (!(rstack->flags & MCOUNT_FL_NORECORD)) rstack->end_time = mcount_gettime(); mcount_exit_filter_record(mtdp, rstack, retval); /* * Since dynamic linker calls fixup routine to patch this GOT entry * to the resolved address, it needs to restore GOT entry back to the * initial value so that it can go to plt_hooker again. * Otherwise, it will directly jump to the resolved address and there's * no way to trace it in the next reference. */ update_pltgot(mtdp, rstack->pd, dyn_idx); ret_loc = rstack->parent_loc; ret_addr = rstack->parent_ip; pr_dbg3("[idx: %4d] exit %lx: %s (resolved addr: %lx)\n", dyn_idx, ret_addr, rstack->pd->dsymtab.sym[dyn_idx].name, rstack->pd->resolved_addr[dyn_idx]); /* re-hijack return address of parent */ if (mcount_auto_recover) mcount_auto_reset(mtdp); __mcount_unguard_recursion(mtdp); if (unlikely(mcount_should_stop())) { mtd_dtor(mtdp); /* * mtd_dtor() will free rstack but current ret_addr * might be plthook_return() when it was a tailcall. * reload the return address after mtd_dtor() restored * all the parent locations. */ if (ARCH_CAN_RESTORE_PLTHOOK) ret_addr = *ret_loc; } compiler_barrier(); mtdp->idx--; return ret_addr; } unsigned long plthook_exit(long *retval) { int saved_errno = errno; unsigned long ret = __plthook_exit(retval); errno = saved_errno; return ret; } uftrace-0.9.3/libmcount/pmu.c000066400000000000000000000103401351236475300161240ustar00rootroot00000000000000#include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "mcount" #define PR_DOMAIN DBG_MCOUNT #include "libmcount/mcount.h" #include "libmcount/internal.h" #include "utils/utils.h" #include "utils/list.h" /* PMU management data for given event */ struct pmu_data { struct list_head list; enum uftrace_event_id evt_id; int n_members; int fd[]; }; /* list of pmu_data */ static LIST_HEAD(pmu_fds); /* attribute for perf_event_open(2) */ struct pmu_config { uint32_t type; uint64_t config; char *name; }; static const struct pmu_config cycle[] = { { PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES, "cycles", }, { PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, "instructions", }, }; static const struct pmu_config cache[] = { { PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES, "cache-references", }, { PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES, "cache-misses", }, }; static const struct pmu_config branch[] = { { PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS, "branches", }, { PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES, "branch-misses", }, }; static const struct pmu_info { enum uftrace_event_id event_id; unsigned n_members; const struct pmu_config *const setting; } pmu_configs[] = { { EVENT_ID_READ_PMU_CYCLE, ARRAY_SIZE(cycle), cycle }, { EVENT_ID_READ_PMU_CACHE, ARRAY_SIZE(cache), cache }, { EVENT_ID_READ_PMU_BRANCH, ARRAY_SIZE(branch), branch }, }; #ifndef PERF_FLAG_FD_CLOEXEC # define PERF_FLAG_FD_CLOEXEC 0 #endif static int open_perf_event(uint32_t type, uint64_t config, int group_fd) { struct perf_event_attr attr = { .size = sizeof(attr), .type = type, .config = config, .exclude_kernel = 1, .read_format = PERF_FORMAT_GROUP, }; unsigned long flag = PERF_FLAG_FD_CLOEXEC; int fd; fd = syscall(SYS_perf_event_open, &attr, 0, -1, group_fd, flag); if (fd >= 0 && flag == 0) { if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) pr_dbg("setting FD_CLOEXEC failed: %m\n"); } return fd; } static void read_perf_event(int fd, void *buf, ssize_t len) { if (read(fd, buf, len) != len) pr_dbg("reading perf_event failed: %m\n"); } int prepare_pmu_event(enum uftrace_event_id id) { struct pmu_data *pd; const struct pmu_info *info; unsigned i, k; int group_fd; list_for_each_entry(pd, &pmu_fds, list) { if (pd->evt_id == id) return 0; } pr_dbg("setup PMU event (%d) using perf syscall\n", id); for (i = 0; i < ARRAY_SIZE(pmu_configs); i++) { info = &pmu_configs[i]; if (id != info->event_id) continue; pd = xmalloc(sizeof(*pd) + info->n_members * sizeof(int)); pd->evt_id = id; group_fd = open_perf_event(info->setting[0].type, info->setting[0].config, -1); if (group_fd < 0) { pr_warn("failed to open '%s' perf event: %m\n", info->setting[0].name); free(pd); return -1; } pd->fd[0] = group_fd; for (k = 1; k < info->n_members; k++) { pd->fd[k] = open_perf_event(info->setting[k].type, info->setting[k].config, group_fd); if (pd->fd[k] < 0) { pr_warn("failed to open '%s' perf event: %m\n", info->setting[k].name); free(pd); return -1; } } pd->n_members = info->n_members; break; } if (i == ARRAY_SIZE(pmu_configs)) pr_dbg("unknown pmu event: %d - ignoring\n", id); else list_add_tail(&pd->list, &pmu_fds); return 0; } int read_pmu_event(enum uftrace_event_id id, void *buf) { struct pmu_data *pd; struct { uint64_t nr_members; uint64_t data[2]; } read_buf; list_for_each_entry(pd, &pmu_fds, list) { if (pd->evt_id == id) break; } if (list_no_entry(pd, &pmu_fds, list)) { /* unsupported pmu events */ return -1; } /* read group events at once */ read_perf_event(pd->fd[0], &read_buf, sizeof(read_buf)); mcount_memcpy4(buf, read_buf.data, sizeof(*read_buf.data) * read_buf.nr_members); return 0; } void finish_pmu_event(void) { struct pmu_data *pd, *tmp; list_for_each_entry_safe(pd, tmp, &pmu_fds, list) { list_del(&pd->list); switch (pd->evt_id) { case EVENT_ID_READ_PMU_CYCLE: case EVENT_ID_READ_PMU_CACHE: case EVENT_ID_READ_PMU_BRANCH: close(pd->fd[0]); close(pd->fd[1]); break; default: break; } free(pd); } } uftrace-0.9.3/libmcount/record.c000066400000000000000000000657341351236475300166220ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "mcount" #define PR_DOMAIN DBG_MCOUNT #include "libmcount/mcount.h" #include "libmcount/internal.h" #include "mcount-arch.h" #include "utils/utils.h" #include "utils/filter.h" #define SHMEM_SESSION_FMT "/uftrace-%s-%d-%03d" /* session-id, tid, seq */ #define ARG_STR_MAX 98 static struct mcount_shmem_buffer *allocate_shmem_buffer(char *sess_id, size_t size, int tid, int idx) { int fd; int saved_errno = 0; struct mcount_shmem_buffer *buffer = NULL; snprintf(sess_id, size, SHMEM_SESSION_FMT, mcount_session_name(), tid, idx); fd = shm_open(sess_id, O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd < 0) { saved_errno = errno; pr_dbg("failed to open shmem buffer: %s\n", sess_id); goto out; } if (ftruncate(fd, shmem_bufsize) < 0) { saved_errno = errno; pr_dbg("failed to resizing shmem buffer: %s\n", sess_id); goto out; } buffer = mmap(NULL, shmem_bufsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (buffer == MAP_FAILED) { saved_errno = errno; pr_dbg("failed to mmap shmem buffer: %s\n", sess_id); buffer = NULL; goto out; } close(fd); out: errno = saved_errno; return buffer; } void prepare_shmem_buffer(struct mcount_thread_data *mtdp) { char buf[128]; int idx; int tid = mcount_gettid(mtdp); struct mcount_shmem *shmem = &mtdp->shmem; pr_dbg2("preparing shmem buffers: tid = %d\n", tid); shmem->nr_buf = 2; shmem->max_buf = 2; shmem->buffer = xcalloc(sizeof(*shmem->buffer), 2); for (idx = 0; idx < shmem->nr_buf; idx++) { shmem->buffer[idx] = allocate_shmem_buffer(buf, sizeof(buf), tid, idx); if (shmem->buffer[idx] == NULL) pr_err("mmap shmem buffer"); } /* set idx 0 as current buffer */ snprintf(buf, sizeof(buf), SHMEM_SESSION_FMT, mcount_session_name(), tid, 0); uftrace_send_message(UFTRACE_MSG_REC_START, buf, strlen(buf)); shmem->done = false; shmem->curr = 0; shmem->buffer[0]->flag = SHMEM_FL_RECORDING | SHMEM_FL_NEW; } static void get_new_shmem_buffer(struct mcount_thread_data *mtdp) { char buf[128]; struct mcount_shmem *shmem = &mtdp->shmem; struct mcount_shmem_buffer *curr_buf = NULL; struct mcount_shmem_buffer **new_buffer; int idx; /* always use first buffer available */ for (idx = 0; idx < shmem->nr_buf; idx++) { curr_buf = shmem->buffer[idx]; if (!(curr_buf->flag & SHMEM_FL_RECORDING)) goto reuse; } new_buffer = realloc(shmem->buffer, sizeof(*new_buffer) * (idx + 1)); if (new_buffer) { /* * it already free'd the old buffer, keep the new buffer * regardless of allocation failure. */ shmem->buffer = new_buffer; curr_buf = allocate_shmem_buffer(buf, sizeof(buf), mcount_gettid(mtdp), idx); } if (new_buffer == NULL || curr_buf == NULL) { shmem->losts++; shmem->curr = -1; return; } shmem->buffer[idx] = curr_buf; shmem->nr_buf++; if (shmem->nr_buf > shmem->max_buf) shmem->max_buf = shmem->nr_buf; reuse: /* * Start a new buffer and mark it recording data. * See cmd-record.c::writer_thread(). */ __sync_fetch_and_or(&curr_buf->flag, SHMEM_FL_RECORDING); shmem->seqnum++; shmem->curr = idx; curr_buf->size = 0; /* shrink unused buffers */ if (idx + 3 <= shmem->nr_buf) { int i; int count = 0; struct mcount_shmem_buffer *b; for (i = idx + 1; i < shmem->nr_buf; i++) { b = shmem->buffer[i]; if (b->flag == SHMEM_FL_WRITTEN) count++; } /* if 3 or more buffers are unused, free the last one */ if (count >= 3 && b->flag == SHMEM_FL_WRITTEN) { shmem->nr_buf--; munmap(b, shmem_bufsize); } } snprintf(buf, sizeof(buf), SHMEM_SESSION_FMT, mcount_session_name(), mcount_gettid(mtdp), idx); pr_dbg2("new buffer: [%d] %s\n", idx, buf); uftrace_send_message(UFTRACE_MSG_REC_START, buf, strlen(buf)); if (shmem->losts) { struct uftrace_record *frstack = (void *)curr_buf->data; frstack->time = 0; frstack->type = UFTRACE_LOST; frstack->magic = RECORD_MAGIC; frstack->more = 0; frstack->addr = shmem->losts; uftrace_send_message(UFTRACE_MSG_LOST, &shmem->losts, sizeof(shmem->losts)); curr_buf->size = sizeof(*frstack); shmem->losts = 0; } } static void finish_shmem_buffer(struct mcount_thread_data *mtdp, int idx) { char buf[64]; snprintf(buf, sizeof(buf), SHMEM_SESSION_FMT, mcount_session_name(), mcount_gettid(mtdp), idx); uftrace_send_message(UFTRACE_MSG_REC_END, buf, strlen(buf)); } void clear_shmem_buffer(struct mcount_thread_data *mtdp) { struct mcount_shmem *shmem = &mtdp->shmem; int i; pr_dbg2("releasing all shmem buffers for task %d\n", mcount_gettid(mtdp)); for (i = 0; i < shmem->nr_buf; i++) munmap(shmem->buffer[i], shmem_bufsize); free(shmem->buffer); shmem->buffer = NULL; shmem->nr_buf = 0; } void shmem_finish(struct mcount_thread_data *mtdp) { struct mcount_shmem *shmem = &mtdp->shmem; struct mcount_shmem_buffer *curr_buf; int curr = shmem->curr; if (curr >= 0 && shmem->buffer) { curr_buf = shmem->buffer[curr]; if (curr_buf->flag & SHMEM_FL_RECORDING) finish_shmem_buffer(mtdp, curr); } shmem->done = true; shmem->curr = -1; pr_dbg("%s: tid: %d seqnum = %u curr = %d, nr_buf = %d max_buf = %d\n", __func__, mcount_gettid(mtdp), shmem->seqnum, curr, shmem->nr_buf, shmem->max_buf); clear_shmem_buffer(mtdp); } static struct mcount_event * get_event_pointer(void *base, unsigned idx) { size_t len = 0; struct mcount_event *event = base; while (idx--) { len += EVTBUF_HDR + event->dsize; event = base + len; } return event; } #ifndef DISABLE_MCOUNT_FILTER void *get_argbuf(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack) { ptrdiff_t idx = rstack - mtdp->rstack; return mtdp->argbuf + (idx * ARGBUF_SIZE); } #define HEAP_REGION_UNIT 128*MB #define STACK_REGION_UNIT 8*MB struct mem_region { struct rb_node node; unsigned long start; unsigned long end; }; static void add_mem_region(struct rb_root *root, unsigned long start, unsigned long end, bool update_end) { struct rb_node *parent = NULL; struct rb_node **p = &root->rb_node; struct mem_region *iter, *entry; while (*p) { parent = *p; iter = rb_entry(parent, struct mem_region, node); if (update_end) { if (iter->start == start) { if (iter->end != end) iter->end = end; return; } } else { if (iter->end == end) { if (iter->start != start) iter->start = start; return; } } if (iter->start > start) p = &parent->rb_left; else p = &parent->rb_right; } entry = xmalloc(sizeof(*entry)); entry->start = start; entry->end = end; pr_dbg3("mem region: %lx - %lx\n", start, end); rb_link_node(&entry->node, parent, p); rb_insert_color(&entry->node, root); } static void update_mem_regions(struct mcount_mem_regions *regions) { FILE *fp; char buf[PATH_MAX]; fp = fopen("/proc/self/maps", "r"); if (fp == NULL) return; while (fgets(buf, sizeof(buf), fp) != NULL) { char *p = buf, *next; unsigned long start, end; bool is_stack = false; /* XXX: cannot use *scanf() due to crash (SSE alignment?) */ start = strtoul(p, &next, 16); if (*next != '-') pr_warn("invalid /proc/map format\n"); p = next + 1; end = strtoul(p, &next, 16); if (strstr(next, "[heap]")) { end = ROUND_UP(end, HEAP_REGION_UNIT); if (end > regions->brk) regions->brk = end; regions->heap = start; } if (strstr(next, "[stack")) { start = ROUND_DOWN(start, STACK_REGION_UNIT); is_stack = true; } add_mem_region(®ions->root, start, end, !is_stack); } fclose(fp); } static bool find_mem_region(struct rb_root *root, unsigned long addr) { struct rb_node *parent = NULL; struct rb_node **p = &root->rb_node; struct mem_region *iter; while (*p) { parent = *p; iter = rb_entry(parent, struct mem_region, node); if (iter->start <= addr && addr < iter->end) return true; if (iter->start > addr) p = &parent->rb_left; else p = &parent->rb_right; } pr_dbg2("cannot find mem region: %lx\n", addr); return false; } static bool check_mem_region(struct mcount_arg_context *ctx, unsigned long addr) { bool update = true; struct mcount_mem_regions *regions = ctx->regions; retry: if (regions->heap <= addr && addr < regions->brk) return true; if (find_mem_region(®ions->root, addr)) return true; if (update) { mcount_save_arch_context(ctx->arch); update_mem_regions(regions); mcount_restore_arch_context(ctx->arch); update = false; goto retry; } return false; } void finish_mem_region(struct mcount_mem_regions *regions) { struct rb_root *root = ®ions->root; struct rb_node *node; struct mem_region *mr; while (!RB_EMPTY_ROOT(root)) { node = rb_first(root); mr = rb_entry(node, typeof(*mr), node); rb_erase(node, root); free(mr); } } static unsigned save_to_argbuf(void *argbuf, struct list_head *args_spec, struct mcount_arg_context *ctx) { struct uftrace_arg_spec *spec; unsigned size, total_size = 0; unsigned max_size = ARGBUF_SIZE - sizeof(size); bool is_retval = !!ctx->retval; void *ptr; ptr = argbuf + sizeof(total_size); list_for_each_entry(spec, args_spec, list) { if (is_retval != (spec->idx == RETVAL_IDX)) continue; if (is_retval) mcount_arch_get_retval(ctx, spec); else mcount_arch_get_arg(ctx, spec); if (spec->fmt == ARG_FMT_STR || spec->fmt == ARG_FMT_STD_STRING) { unsigned short len; char *str = ctx->val.p; if (spec->fmt == ARG_FMT_STD_STRING) { /* * This is libstdc++ implementation dependent. * So doesn't work on others such as libc++. */ long *base = ctx->val.p; long *_M_string_length = base + 1; char *_M_dataplus = (char*)(*base); len = *_M_string_length; str = _M_dataplus; } if (str) { unsigned i; char *dst = ptr + 2; char buf[32]; if (!check_mem_region(ctx, ctx->val.i)) { len = snprintf(buf, sizeof(buf), "<%p>", str); str = buf; } /* * Calling strlen() might clobber floating-point * registers (on x86) depends on the internal * implementation. Do it manually. */ len = 0; for (i = 0; i < max_size - total_size; i++) { dst[i] = str[i]; /* truncate long string */ if (i == ARG_STR_MAX) { dst[i-3] = '.'; dst[i-2] = '.'; dst[i-1] = '.'; dst[i] = '\0'; } if (!dst[i]) break; len++; } /* store 2-byte length before string */ *(unsigned short *)ptr = len; } else { const char null_str[4] = { 'N', 'U', 'L', 'L' }; len = sizeof(null_str); mcount_memcpy1(ptr, &len, sizeof(len)); mcount_memcpy1(ptr + 2, null_str, len); } size = ALIGN(len + 2, 4); } else { size = ALIGN(spec->size, 4); mcount_memcpy4(ptr, ctx->val.v, size); } ptr += size; total_size += size; } if (total_size > max_size) return -1U; return total_size; } void save_argument(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, struct list_head *args_spec, struct mcount_regs *regs) { void *argbuf = get_argbuf(mtdp, rstack); unsigned size; struct mcount_arg_context ctx = { .regs = regs, .stack_base = rstack->parent_loc, .regions = &mtdp->mem_regions, .arch = &mtdp->arch, }; size = save_to_argbuf(argbuf, args_spec, &ctx); if (size == -1U) { pr_warn("argument data is too big\n"); return; } *(unsigned *)argbuf = size; rstack->flags |= MCOUNT_FL_ARGUMENT; } void save_retval(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, long *retval) { struct list_head *args_spec = rstack->pargs; void *argbuf = get_argbuf(mtdp, rstack); unsigned size; struct mcount_arg_context ctx = { .retval = retval, .regions = &mtdp->mem_regions, .arch = &mtdp->arch, }; size = save_to_argbuf(argbuf, args_spec, &ctx); if (size == -1U) { pr_warn("retval data is too big\n"); rstack->flags &= ~MCOUNT_FL_RETVAL; return; } *(uint32_t *)argbuf = size; } static int save_proc_statm(void *buf) { FILE *fp; struct uftrace_proc_statm *statm = buf; fp = fopen("/proc/self/statm", "r"); if (fp == NULL) pr_err("failed to open /proc/self/statm"); if (fscanf(fp, "%"SCNu64" %"SCNu64" %"SCNu64, &statm->vmsize, &statm->vmrss, &statm->shared) != 3) pr_err("failed to scan /proc/self/statm"); /* Since /proc/[pid]/statm prints the number of pages for each field, * it'd be better to keep the memory size in KB. */ statm->vmsize *= page_size_in_kb; statm->vmrss *= page_size_in_kb; statm->shared *= page_size_in_kb; fclose(fp); return 0; } static void diff_proc_statm(void *dst, void *src) { struct uftrace_proc_statm *dst_statm = dst; struct uftrace_proc_statm *src_statm = src; dst_statm->vmsize -= src_statm->vmsize; dst_statm->vmrss -= src_statm->vmrss; dst_statm->shared -= src_statm->shared; } static int save_page_fault(void *buf) { struct rusage ru; struct uftrace_page_fault *page_fault = buf; /* getrusage provides faults info in a single syscall */ if (getrusage(RUSAGE_SELF, &ru) < 0) return -1; page_fault->major = ru.ru_majflt; page_fault->minor = ru.ru_minflt; return 0; } static void diff_page_fault(void *dst, void *src) { struct uftrace_page_fault *dst_pgflt = dst; struct uftrace_page_fault *src_pgflt = src; dst_pgflt->major -= src_pgflt->major; dst_pgflt->minor -= src_pgflt->minor; } static int save_pmu_cycle(void *buf) { return read_pmu_event(EVENT_ID_READ_PMU_CYCLE, buf); } static void diff_pmu_cycle(void *dst, void *src) { struct uftrace_pmu_cycle *dst_cycle = dst; struct uftrace_pmu_cycle *src_cycle = src; dst_cycle->cycles -= src_cycle->cycles; dst_cycle->instrs -= src_cycle->instrs; } static int save_pmu_cache(void *buf) { return read_pmu_event(EVENT_ID_READ_PMU_CACHE, buf); } static void diff_pmu_cache(void *dst, void *src) { struct uftrace_pmu_cache *dst_cache = dst; struct uftrace_pmu_cache *src_cache = src; dst_cache->refers -= src_cache->refers; dst_cache->misses -= src_cache->misses; } static int save_pmu_branch(void *buf) { return read_pmu_event(EVENT_ID_READ_PMU_BRANCH, buf); } static void diff_pmu_branch(void *dst, void *src) { struct uftrace_pmu_branch *dst_branch = dst; struct uftrace_pmu_branch *src_branch = src; dst_branch->branch -= src_branch->branch; dst_branch->misses -= src_branch->misses; } /* above functions should follow the name convention to use below macro */ #define TR_ID(_evt) TRIGGER_READ_##_evt, EVENT_ID_READ_##_evt, EVENT_ID_DIFF_##_evt #define TR_DS(_evt) sizeof(struct uftrace_##_evt) #define TR_FN(_evt) save_##_evt, diff_##_evt static struct read_event_data { enum trigger_read_type type; enum uftrace_event_id id_read; enum uftrace_event_id id_diff; size_t size; int (*save)(void *buf); void (*diff)(void *dst, void *src); } read_events[] = { { TR_ID(PROC_STATM), TR_DS(proc_statm), TR_FN(proc_statm) }, { TR_ID(PAGE_FAULT), TR_DS(page_fault), TR_FN(page_fault) }, { TR_ID(PMU_CYCLE), TR_DS(pmu_cycle), TR_FN(pmu_cycle) }, { TR_ID(PMU_CACHE), TR_DS(pmu_cache), TR_FN(pmu_cache) }, { TR_ID(PMU_BRANCH), TR_DS(pmu_branch), TR_FN(pmu_branch) }, }; #undef TR_ID #undef TR_DS #undef TR_FN void save_trigger_read(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, enum trigger_read_type type, bool diff) { void *ptr = get_argbuf(mtdp, rstack) + rstack->event_idx; struct mcount_event *event; unsigned short evsize; void *arg_data = get_argbuf(mtdp, rstack); size_t i; if (rstack->flags & (MCOUNT_FL_ARGUMENT | MCOUNT_FL_RETVAL)) arg_data += *(uint32_t *)ptr; for (i = 0; i < ARRAY_SIZE(read_events); i++) { struct read_event_data *red = &read_events[i]; if (!(type & red->type)) continue; evsize = EVTBUF_HDR + red->size; event = ptr - evsize; /* do not overwrite argument data */ if ((void *)event < arg_data) continue; event->id = red->id_read; event->time = rstack->end_time ?: rstack->start_time; event->dsize = red->size; event->idx = mtdp->idx; if (red->save(event->data) < 0) continue; if (diff) { struct mcount_event *old_event = NULL; unsigned idx; for (idx = 0; idx < rstack->nr_events; idx++) { old_event = get_event_pointer(ptr, idx); if (old_event->id == event->id) break; } if (old_event) { event->id = red->id_diff; red->diff(event->data, old_event->data); } } ptr = event; rstack->nr_events++; rstack->event_idx -= evsize; } } void save_watchpoint(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, unsigned long watchpoints) { uint64_t timestamp; ptrdiff_t rstack_idx; bool init_watch; timestamp = rstack->end_time ?: rstack->start_time; rstack_idx = rstack - mtdp->rstack; init_watch = !mtdp->watch.inited; if (init_watch) { /* * Normally watch point event comes before the rstack (record) * in order to indicate where it's changed precisely. * But first watch point event needs to come after the first * record otherwise it'd not shown since 'event-skip' mechanism. * so add 2(nsec) so that it can be 1 nsec later. */ timestamp += 2; mtdp->watch.inited = true; } /* save watch event before normal record */ timestamp -= 1; if (watchpoints & MCOUNT_WATCH_CPU) { int cpu = sched_getcpu(); if ((mtdp->watch.cpu != cpu || init_watch) && mtdp->nr_events < MAX_EVENT) { struct mcount_event *event; event = &mtdp->event[mtdp->nr_events++]; event->id = EVENT_ID_WATCH_CPU; event->time = timestamp; event->idx = rstack_idx; event->dsize = sizeof(cpu); mcount_memcpy4(event->data, &cpu, sizeof(cpu)); } mtdp->watch.cpu = cpu; } } #else void *get_argbuf(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack) { return NULL; } void save_retval(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, long *retval) { } void save_trigger_read(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, enum trigger_read_type type) { } void save_watchpoint(struct mcount_thread_data *mtdp, struct mcount_ret_stack *rstack, unsigned long watchpoints) { } #endif static struct mcount_shmem_buffer * get_shmem_buffer(struct mcount_thread_data *mtdp, size_t size) { struct mcount_shmem *shmem = &mtdp->shmem; struct mcount_shmem_buffer *curr_buf = shmem->buffer[shmem->curr]; size_t maxsize = (size_t)shmem_bufsize - sizeof(**shmem->buffer); if (unlikely(shmem->curr == -1 || curr_buf->size + size > maxsize)) { if (shmem->done) return NULL; if (shmem->curr > -1) finish_shmem_buffer(mtdp, shmem->curr); get_new_shmem_buffer(mtdp); if (shmem->curr == -1) { shmem->losts++; return NULL; } curr_buf = shmem->buffer[shmem->curr]; } return curr_buf; } static int record_event(struct mcount_thread_data *mtdp, struct mcount_event *event) { struct mcount_shmem_buffer *curr_buf; struct { uint64_t time; uint64_t data; } *rec; size_t size = sizeof(*rec); uint16_t data_size = event->dsize; if (data_size) size += ALIGN(data_size + 2, 8); curr_buf = get_shmem_buffer(mtdp, size); if (curr_buf == NULL) return mtdp->shmem.done ? 0 : -1; rec = (void *)(curr_buf->data + curr_buf->size); /* * instead of set bitfields, do the bit operations manually. * this would be good both for performance and portability. */ rec->data = UFTRACE_EVENT | RECORD_MAGIC << 3; rec->data += (uint64_t)event->id << 16; rec->time = event->time; if (data_size) { void *ptr = rec + 1; rec->data += 4; /* set 'more' bit in uftrace_record */ *(uint16_t *)ptr = data_size; memcpy(ptr + 2, event->data, data_size); } curr_buf->size += size; return 0; } static int record_ret_stack(struct mcount_thread_data *mtdp, enum uftrace_record_type type, struct mcount_ret_stack *mrstack) { struct uftrace_record *frstack; uint64_t timestamp = mrstack->start_time; struct mcount_shmem_buffer *curr_buf; size_t size = sizeof(*frstack); void *argbuf = NULL; uint64_t *buf; uint64_t rec; if (type == UFTRACE_EXIT) timestamp = mrstack->end_time; if (unlikely(mtdp->nr_events)) { /* save async events first (if any) */ while (mtdp->nr_events && mtdp->event[0].time < timestamp) { record_event(mtdp, &mtdp->event[0]); mtdp->nr_events--; mcount_memcpy4(&mtdp->event[0], &mtdp->event[1], sizeof(*mtdp->event) * mtdp->nr_events); } } if (type == UFTRACE_EXIT && unlikely(mrstack->nr_events)) { int i; unsigned evidx; struct mcount_event *event; argbuf = get_argbuf(mtdp, mrstack) + mrstack->event_idx; for (i = 0; i < mrstack->nr_events; i++) { evidx = mrstack->nr_events - i - 1; event = get_event_pointer(argbuf, evidx); if (event->time != timestamp) continue; /* save read2 trigger before exit record */ record_event(mtdp, event); } mrstack->nr_events = 0; argbuf = NULL; } if ((type == UFTRACE_ENTRY && mrstack->flags & MCOUNT_FL_ARGUMENT) || (type == UFTRACE_EXIT && mrstack->flags & MCOUNT_FL_RETVAL)) { argbuf = get_argbuf(mtdp, mrstack); if (argbuf) size += *(unsigned *)argbuf; } curr_buf = get_shmem_buffer(mtdp, size); if (curr_buf == NULL) return mtdp->shmem.done ? 0 : -1; #if 0 frstack = (void *)(curr_buf->data + curr_buf->size); frstack->time = timestamp; frstack->type = type; frstack->magic = RECORD_MAGIC; frstack->more = !!argbuf; frstack->depth = mrstack->depth; frstack->addr = mrstack->child_ip; #else /* * instead of set bitfields, do the bit operations manually. * this would be good both for performance and portability. */ rec = type | RECORD_MAGIC << 3; rec += argbuf ? 4 : 0; rec += mrstack->depth << 6; rec += (uint64_t)mrstack->child_ip << 16; buf = (void *)(curr_buf->data + curr_buf->size); buf[0] = timestamp; buf[1] = rec; #endif curr_buf->size += sizeof(*frstack); mrstack->flags |= MCOUNT_FL_WRITTEN; if (argbuf) { unsigned int *ptr = (void *)curr_buf->data + curr_buf->size; size -= sizeof(*frstack); mcount_memcpy4(ptr, argbuf + 4, size); curr_buf->size += ALIGN(size, 8); } pr_dbg3("rstack[%d] %s %lx\n", mrstack->depth, type == UFTRACE_ENTRY? "ENTRY" : "EXIT ", mrstack->child_ip); if (unlikely(mrstack->nr_events) && type == UFTRACE_ENTRY) { int i; unsigned evidx; struct mcount_event *event; argbuf = get_argbuf(mtdp, mrstack) + mrstack->event_idx; for (i = 0; i < mrstack->nr_events; i++) { evidx = mrstack->nr_events - i - 1; event = get_event_pointer(argbuf, evidx); if (event->time != timestamp) break; /* save read trigger after entry record */ record_event(mtdp, event); } } return 0; } int record_trace_data(struct mcount_thread_data *mtdp, struct mcount_ret_stack *mrstack, long *retval) { struct mcount_ret_stack *non_written_mrstack = NULL; struct uftrace_record *frstack; size_t size = 0; int count = 0; #define SKIP_FLAGS (MCOUNT_FL_NORECORD | MCOUNT_FL_DISABLED) if (mrstack < mtdp->rstack) return 0; if (!(mrstack->flags & MCOUNT_FL_WRITTEN)) { non_written_mrstack = mrstack; if (!(non_written_mrstack->flags & SKIP_FLAGS)) count++; while (non_written_mrstack > mtdp->rstack) { struct mcount_ret_stack *prev = non_written_mrstack - 1; if (prev->flags & MCOUNT_FL_WRITTEN) break; if (!(prev->flags & SKIP_FLAGS)) { count++; if (prev->flags & MCOUNT_FL_ARGUMENT) { unsigned *argbuf_size; argbuf_size = get_argbuf(mtdp, prev); if (argbuf_size) size += *argbuf_size; } } non_written_mrstack = prev; } } if (mrstack->end_time) count++; /* for exit */ size += count * sizeof(*frstack); pr_dbg3("task %d recorded %zd bytes (record count = %d)\n", mcount_gettid(mtdp), size, count); while (non_written_mrstack && non_written_mrstack < mrstack) { if (!(non_written_mrstack->flags & SKIP_FLAGS)) { if (record_ret_stack(mtdp, UFTRACE_ENTRY, non_written_mrstack)) { mtdp->shmem.losts += count - 1; return 0; } count--; } non_written_mrstack++; } if (!(mrstack->flags & (MCOUNT_FL_WRITTEN | SKIP_FLAGS))) { if (record_ret_stack(mtdp, UFTRACE_ENTRY, mrstack)) return 0; count--; } if (mrstack->end_time) { if (retval) save_retval(mtdp, mrstack, retval); else mrstack->flags &= ~MCOUNT_FL_RETVAL; if (record_ret_stack(mtdp, UFTRACE_EXIT, mrstack)) return 0; count--; } assert(count == 0); return 0; } static void write_map(FILE *out, struct uftrace_mmap *map, unsigned char major, unsigned char minor, uint32_t ino, uint64_t off) { /* write prev_map when it finds a new map */ fprintf(out, "%"PRIx64"-%"PRIx64" %.4s %08"PRIx64" %02x:%02x %-26u %s\n", map->start, map->end, map->prot, off, major, minor, ino, map->libname); } void record_proc_maps(char *dirname, const char *sess_id, struct symtabs *symtabs) { FILE *ifp, *ofp; char buf[PATH_MAX]; struct uftrace_mmap *prev_map = NULL; bool prev_written = false; ifp = fopen("/proc/self/maps", "r"); if (ifp == NULL) pr_err("cannot open proc maps file"); snprintf(buf, sizeof(buf), "%s/sid-%s.map", dirname, sess_id); ofp = fopen(buf, "w"); if (ofp == NULL) pr_err("cannot open for writing maps file"); symtabs->kernel_base = -1ULL; while (fgets(buf, sizeof(buf), ifp)) { unsigned long start, end; char prot[5]; unsigned char major, minor; unsigned char prev_major = 0, prev_minor = 0; uint32_t ino, prev_ino = 0; uint64_t off, prev_off = 0; char path[PATH_MAX]; size_t namelen; struct uftrace_mmap *map; /* skip anon mappings */ if (sscanf(buf, "%lx-%lx %s %"SCNx64" %hhx:%hhx %u %s\n", &start, &end, prot, &off, &major, &minor, &ino, path) != 8) continue; /* * skip special mappings like [heap], [vdso] etc. * but [stack] is still needed to get kernel base address. */ if (path[0] == '[') { if (prev_map && !prev_written) { write_map(ofp, prev_map, prev_major, prev_minor, prev_ino, prev_off); prev_written = true; } if (strncmp(path, "[stack", 6) == 0) { symtabs->kernel_base = guess_kernel_base(buf); fprintf(ofp, "%s", buf); } continue; } if (prev_map != NULL) { /* extend prev_map to have all segments */ if (!strcmp(path, prev_map->libname)) { prev_map->end = end; if (prot[2] == 'x') mcount_memcpy1(prev_map->prot, prot, 4); continue; } /* write prev_map when it finds a new map */ if (!prev_written) { write_map(ofp, prev_map, prev_major, prev_minor, prev_ino, prev_off); prev_written = true; } } /* save map for the executable */ namelen = ALIGN(strlen(path) + 1, 4); map = xzalloc(sizeof(*map) + namelen); map->start = start; map->end = end; map->len = namelen; mcount_memcpy1(map->prot, prot, 4); mcount_memcpy1(map->libname, path, namelen); map->libname[strlen(path)] = '\0'; /* still need to write the map for executable */ if (!strcmp(path, symtabs->filename)) symtabs->exec_base = start; if (prev_map) prev_map->next = map; else symtabs->maps = map; map->next = NULL; prev_map = map; prev_off = off; prev_ino = ino; prev_major = major; prev_minor = minor; prev_written = false; } fclose(ifp); fclose(ofp); } uftrace-0.9.3/libmcount/wrap.c000066400000000000000000000314761351236475300163110ustar00rootroot00000000000000#include #include #include #include #include #include #include /* This should be defined before #include "utils.h" */ #define PR_FMT "mcount" #define PR_DOMAIN DBG_MCOUNT #include "libmcount/mcount.h" #include "libmcount/internal.h" #include "utils/utils.h" #include "utils/compiler.h" extern struct symtabs symtabs; struct dlopen_base_data { struct mcount_thread_data *mtdp; uint64_t timestamp; }; static const char *simple_basename(const char *pathname) { const char *p = strrchr(pathname, '/'); return p ? p + 1 : pathname; } static void send_dlopen_msg(struct mcount_thread_data *mtdp, const char *sess_id, uint64_t timestamp, uint64_t base_addr, const char *libname) { struct uftrace_msg_dlopen dlop = { .task = { .time = timestamp, .pid = getpid(), .tid = mcount_gettid(mtdp), }, .base_addr = base_addr, .namelen = strlen(libname), }; struct uftrace_msg msg = { .magic = UFTRACE_MSG_MAGIC, .type = UFTRACE_MSG_DLOPEN, .len = sizeof(dlop) + dlop.namelen, }; struct iovec iov[3] = { { .iov_base = &msg, .iov_len = sizeof(msg), }, { .iov_base = &dlop, .iov_len = sizeof(dlop), }, { .iov_base = (void *)libname, .iov_len = dlop.namelen, }, }; int len = sizeof(msg) + msg.len; if (pfd < 0) return; mcount_memcpy4(dlop.sid, sess_id, sizeof(dlop.sid)); if (writev(pfd, iov, 3) != len) { if (!mcount_should_stop()) pr_err("write tid info failed"); } } static int dlopen_base_callback(struct dl_phdr_info *info, size_t size, void *arg) { struct dlopen_base_data *data = arg; char buf[PATH_MAX]; char *p; if (info->dlpi_name[0] == '\0') return 0; if (!strcmp("linux-vdso.so.1", info->dlpi_name)) return 0; p = realpath(info->dlpi_name, buf); if (p == NULL) p = buf; if (find_map_by_name(&symtabs, simple_basename(p))) return 0; /* report a library not found in the session maps */ send_dlopen_msg(data->mtdp, mcount_session_name(), data->timestamp, info->dlpi_addr, info->dlpi_name); return 0; } void mcount_rstack_reset_exception(struct mcount_thread_data *mtdp, unsigned long frame_addr) { int idx; struct mcount_ret_stack *rstack; /* it needs to find how much stack frame was unwinded */ for (idx = mtdp->idx - 1; idx >= 0; idx--) { rstack = &mtdp->rstack[idx]; pr_dbg2("[%d] parent at %p\n", idx, rstack->parent_loc); if (rstack->parent_loc == &mtdp->cygprof_dummy) break; if ((unsigned long)rstack->parent_loc > frame_addr) { /* * there might be tail call optimizations in the * middle of the exception handling path. * in that case, we need to keep the original * mtdp->idx but update parent address of the * first rstack of the tail call chain. */ int orig_idx = idx; while (idx > 0) { struct mcount_ret_stack *tail_call; tail_call = &mtdp->rstack[idx - 1]; if (rstack->parent_loc != tail_call->parent_loc) break; idx--; rstack = tail_call; pr_dbg2("exception in tail call at [%d]\n", idx + 1); } idx = orig_idx; /* do not overwrite current return address */ rstack->parent_ip = *rstack->parent_loc; break; } /* record unwinded functions */ if (!(rstack->flags & MCOUNT_FL_NORECORD)) rstack->end_time = mcount_gettime(); mcount_exit_filter_record(mtdp, rstack, NULL); } /* we're in ENTER state, so add 1 to the index */ mtdp->idx = idx + 1; pr_dbg2("exception returned to [%d]\n", mtdp->idx); mcount_rstack_reset(mtdp); } static char ** collect_uftrace_envp(void) { size_t n = 0; size_t i, k; char **envp; #define ENV(_name) "UFTRACE_" #_name const char *const uftrace_env[] = { ENV(FILTER), ENV(TRIGGER), ENV(ARGUMENT), ENV(RETVAL), ENV(AUTO_ARGS), ENV(DEPTH), ENV(DISABLED), ENV(PIPE), ENV(LOGFD), ENV(DEBUG), ENV(BUFFER), ENV(MAX_STACK), ENV(COLOR), ENV(THRESHOLD), ENV(DEMANGLE), ENV(PLTHOOK), ENV(PATCH), ENV(EVENT), ENV(SCRIPT), ENV(NEST_LIBCALL), ENV(DEBUG_DOMAIN), ENV(LIST_EVENT), ENV(DIR), ENV(KERNEL_PID_UPDATE), ENV(PATTERN), /* not uftrace-specific, but necessary to run */ "LD_PRELOAD", "LD_LIBRARY_PATH", }; #undef ENV for (i = 0; i < ARRAY_SIZE(uftrace_env); i++) { if (getenv(uftrace_env[i])) n++; } envp = xcalloc(sizeof(*envp), n + 2); for (i = k = 0; i < ARRAY_SIZE(uftrace_env); i++) { char *env_str; char *env_val; env_val = getenv(uftrace_env[i]); if (env_val == NULL) continue; xasprintf(&env_str, "%s=%s", uftrace_env[i], env_val); envp[k++] = env_str; } return envp; } static char ** merge_envp(char *const *env1, char **env2) { int i, n = 0; char **envp; for (i = 0; env1 && env1[i]; i++) n++; for (i = 0; env2 && env2[i]; i++) n++; envp = xcalloc(sizeof(*envp), n + 1); n = 0; for (i = 0; env1 && env1[i]; i++) envp[n++] = env1[i]; for (i = 0; env2 && env2[i]; i++) envp[n++] = env2[i]; return envp; } /* * hooking functions */ static int (*real_backtrace)(void **buffer, int sz); static void (*real_cxa_throw)(void *exc, void *type, void *dest); static void (*real_cxa_rethrow)(void); static void * (*real_cxa_begin_catch)(void *exc); static void (*real_cxa_end_catch)(void); static void * (*real_dlopen)(const char *filename, int flags); static __noreturn void (*real_pthread_exit)(void *retval); static void (*real_unwind_resume)(void *exc); static int (*real_posix_spawn)(pid_t *pid, const char *path, const posix_spawn_file_actions_t *actions, const posix_spawnattr_t *attr, char *const argv[], char *const envp[]); static int (*real_posix_spawnp)(pid_t *pid, const char *file, const posix_spawn_file_actions_t *actions, const posix_spawnattr_t *attr, char *const argv[], char *const envp[]); /* TODO: support execle() */ static int (*real_execve)(const char *path, char *const argv[], char *const envp[]); static int (*real_execvpe)(const char *file, char *const argv[], char *const envp[]); static int (*real_fexecve)(int fd, char *const argv[], char *const envp[]); void mcount_hook_functions(void) { real_backtrace = dlsym(RTLD_NEXT, "backtrace"); real_cxa_throw = dlsym(RTLD_NEXT, "__cxa_throw"); real_cxa_rethrow = dlsym(RTLD_NEXT, "__cxa_rethrow"); real_cxa_begin_catch = dlsym(RTLD_NEXT, "__cxa_begin_catch"); real_cxa_end_catch = dlsym(RTLD_NEXT, "__cxa_end_catch"); real_dlopen = dlsym(RTLD_NEXT, "dlopen"); real_pthread_exit = dlsym(RTLD_NEXT, "pthread_exit"); real_unwind_resume = dlsym(RTLD_NEXT, "_Unwind_Resume"); real_posix_spawn = dlsym(RTLD_NEXT, "posix_spawn"); real_posix_spawnp = dlsym(RTLD_NEXT, "posix_spawnp"); real_execve = dlsym(RTLD_NEXT, "execve"); real_execvpe = dlsym(RTLD_NEXT, "execvpe"); real_fexecve = dlsym(RTLD_NEXT, "fexecve"); } __visible_default int backtrace(void **buffer, int sz) { int ret; struct mcount_thread_data *mtdp; if (unlikely(real_backtrace == NULL)) mcount_hook_functions(); mtdp = get_thread_data(); if (!check_thread_data(mtdp)) mcount_rstack_restore(mtdp); ret = real_backtrace(buffer, sz); if (!check_thread_data(mtdp)) mcount_rstack_reset(mtdp); return ret; } __visible_default void __cxa_throw(void *exception, void *type, void *dest) { struct mcount_thread_data *mtdp; if (unlikely(real_cxa_throw == NULL)) mcount_hook_functions(); mtdp = get_thread_data(); if (!check_thread_data(mtdp)) { pr_dbg("exception thrown from [%d]\n", mtdp->idx); mtdp->in_exception = true; /* * restore return addresses so that it can unwind stack * frames safely during the exception handling. * It pairs to mcount_rstack_reset_exception(). */ mcount_rstack_restore(mtdp); } real_cxa_throw(exception, type, dest); } __visible_default void __cxa_rethrow(void) { struct mcount_thread_data *mtdp; if (unlikely(real_cxa_rethrow == NULL)) mcount_hook_functions(); mtdp = get_thread_data(); if (!check_thread_data(mtdp)) { pr_dbg("exception rethrown from [%d]\n", mtdp->idx); mtdp->in_exception = true; /* * restore return addresses so that it can unwind stack * frames safely during the exception handling. * It pairs to mcount_rstack_reset_exception() */ mcount_rstack_restore(mtdp); } real_cxa_rethrow(); } __visible_default void _Unwind_Resume(void *exception) { struct mcount_thread_data *mtdp; if (unlikely(real_unwind_resume == NULL)) mcount_hook_functions(); mtdp = get_thread_data(); if (!check_thread_data(mtdp)) { pr_dbg2("exception resumed on [%d]\n", mtdp->idx); mtdp->in_exception = true; /* * restore return addresses so that it can unwind stack * frames safely during the exception handling. * It pairs to mcount_rstack_reset_exception(). */ mcount_rstack_restore(mtdp); } real_unwind_resume(exception); } __visible_default void * __cxa_begin_catch(void *exception) { struct mcount_thread_data *mtdp; void *obj; if (unlikely(real_cxa_begin_catch == NULL)) mcount_hook_functions(); obj = real_cxa_begin_catch(exception); mtdp = get_thread_data(); if (!check_thread_data(mtdp) && unlikely(mtdp->in_exception)) { unsigned long *frame_ptr; unsigned long frame_addr; frame_ptr = __builtin_frame_address(0); frame_addr = *frame_ptr; /* XXX: probably dangerous */ /* basic sanity check */ if (frame_addr < (unsigned long)frame_ptr) frame_addr = (unsigned long)frame_ptr; mcount_rstack_reset_exception(mtdp, frame_addr); mtdp->in_exception = false; } return obj; } __visible_default void __cxa_end_catch(void) { if (unlikely(real_cxa_end_catch == NULL)) mcount_hook_functions(); real_cxa_end_catch(); } __visible_default void * dlopen(const char *filename, int flags) { struct mcount_thread_data *mtdp; struct dlopen_base_data data = { .timestamp = mcount_gettime(), }; void *ret; /* * get timestamp before calling dlopen() so that * it can have symbols in static initializers which * called during the dlopen. */ if (unlikely(real_dlopen == NULL)) mcount_hook_functions(); ret = real_dlopen(filename, flags); if (filename == NULL) return ret; mtdp = get_thread_data(); if (unlikely(check_thread_data(mtdp))) { mtdp = mcount_prepare(); if (mtdp == NULL) return ret; } else { if (!mcount_guard_recursion(mtdp)) return ret; } data.mtdp = mtdp; dl_iterate_phdr(dlopen_base_callback, &data); mcount_unguard_recursion(mtdp); return ret; } __visible_default __noreturn void pthread_exit(void *retval) { struct mcount_thread_data *mtdp; struct mcount_ret_stack *rstack; if (unlikely(real_pthread_exit == NULL)) mcount_hook_functions(); mtdp = get_thread_data(); if (!check_thread_data(mtdp)) { rstack = &mtdp->rstack[mtdp->idx - 1]; /* record the final call */ mcount_exit_filter_record(mtdp, rstack, NULL); /* * it won't return to the caller ("noreturn"), * do not try to restore the address.. */ mtdp->idx--; mcount_rstack_restore(mtdp); } real_pthread_exit(retval); } __visible_default int posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_actions_t *actions, const posix_spawnattr_t *attr, char *const argv[], char *const envp[]) { char **uftrace_envp; char **new_envp; if (unlikely(real_posix_spawn == NULL)) mcount_hook_functions(); uftrace_envp = collect_uftrace_envp(); new_envp = merge_envp(envp, uftrace_envp); return real_posix_spawn(pid, path, actions, attr, argv, new_envp); } __visible_default int posix_spawnp(pid_t *pid, const char *file, const posix_spawn_file_actions_t *actions, const posix_spawnattr_t *attr, char *const argv[], char *const envp[]) { char **uftrace_envp; char **new_envp; if (unlikely(real_posix_spawnp == NULL)) mcount_hook_functions(); uftrace_envp = collect_uftrace_envp(); new_envp = merge_envp(envp, uftrace_envp); return real_posix_spawnp(pid, file, actions, attr, argv, new_envp); } __visible_default int execve(const char *path, char *const argv[], char *const envp[]) { char **uftrace_envp; char **new_envp; if (unlikely(real_execve == NULL)) mcount_hook_functions(); uftrace_envp = collect_uftrace_envp(); new_envp = merge_envp(envp, uftrace_envp); return real_execve(path, argv, new_envp); } __visible_default int execvpe(const char *file, char *const argv[], char *const envp[]) { char **uftrace_envp; char **new_envp; if (unlikely(real_execvpe == NULL)) mcount_hook_functions(); uftrace_envp = collect_uftrace_envp(); new_envp = merge_envp(envp, uftrace_envp); return real_execvpe(file, argv, new_envp); } __visible_default int fexecve(int fd, char *const argv[], char *const envp[]) { char **uftrace_envp; char **new_envp; if (unlikely(real_fexecve == NULL)) mcount_hook_functions(); uftrace_envp = collect_uftrace_envp(); new_envp = merge_envp(envp, uftrace_envp); return real_fexecve(fd, argv, new_envp); } #ifdef UNIT_TEST TEST_CASE(mcount_wrap_dlopen) { void *handle; TEST_EQ(real_dlopen, NULL); handle= dlopen(NULL, RTLD_LAZY); TEST_NE(handle, NULL); TEST_NE(real_dlopen, NULL); return TEST_OK; } #endif /* UNIT_TEST */ uftrace-0.9.3/libtraceevent/000077500000000000000000000000001351236475300160145ustar00rootroot00000000000000uftrace-0.9.3/libtraceevent/.gitignore000066400000000000000000000000631351236475300200030ustar00rootroot00000000000000TRACEEVENT-CFLAGS libtraceevent.a *.so .*.cmd .*.d uftrace-0.9.3/libtraceevent/Makefile000066400000000000000000000147211351236475300174610ustar00rootroot00000000000000# trace-cmd version EP_VERSION = 1 EP_PATCHLEVEL = 1 EP_EXTRAVERSION = 0 # file format version FILE_VERSION = 6 MAKEFLAGS += --no-print-directory # Makefiles suck: This macro sets a default value of $(2) for the # variable named by $(1), unless the variable has been set by # environment or command line. This is necessary for CC and AR # because make sets default values, so the simpler ?= approach # won't work as expected. define allow-override $(if $(or $(findstring environment,$(origin $(1))),\ $(findstring command line,$(origin $(1)))),,\ $(eval $(1) = $(2))) endef # Allow setting CC and AR, or setting CROSS_COMPILE as a prefix. $(call allow-override,CC,$(CROSS_COMPILE)gcc) $(call allow-override,AR,$(CROSS_COMPILE)ar) EXT = -std=gnu99 INSTALL = install # Use DESTDIR for installing into a different root directory. # This is useful for building a package. The program will be # installed in this directory as if it was the root directory. # Then the build tool can move it later. DESTDIR ?= DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' prefix ?= /usr/local bindir_relative = bin bindir = $(prefix)/$(bindir_relative) man_dir = $(prefix)/share/man man_dir_SQ = '$(subst ','\'',$(man_dir))' export man_dir man_dir_SQ INSTALL export DESTDIR DESTDIR_SQ include $(if $(BUILD_SRC),$(BUILD_SRC)/)../Makefile.include # copy a bit from Linux kbuild ifeq ("$(origin V)", "command line") VERBOSE = $(V) endif ifndef VERBOSE VERBOSE = 0 endif ifeq ("$(origin O)", "command line") BUILD_OUTPUT := $(O) endif ifeq ($(BUILD_SRC),) ifneq ($(BUILD_OUTPUT),) define build_output $(if $(VERBOSE:1=),@)+$(MAKE) -C $(BUILD_OUTPUT) \ BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1 endef all: sub-make $(MAKECMDGOALS): sub-make sub-make: force $(call build_output, $(MAKECMDGOALS)) # Leave processing to above invocation of make skip-makefile := 1 endif # BUILD_OUTPUT endif # BUILD_SRC # We process the rest of the Makefile if this is the final invocation of make ifeq ($(skip-makefile),) srctree := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR)) objtree := $(if $(BUILD_OUTPUT),$(BUILD_OUTPUT),$(CURDIR)) src := $(srctree) obj := $(objtree) export prefix bindir src obj # Shell quotes bindir_SQ = $(subst ','\'',$(bindir)) bindir_relative_SQ = $(subst ','\'',$(bindir_relative)) LIB_FILE = $(obj)/libtraceevent.a # $(obj)/libtraceevent.so CONFIG_INCLUDES = CONFIG_LIBS = CONFIG_FLAGS = VERSION = $(EP_VERSION) PATCHLEVEL = $(EP_PATCHLEVEL) EXTRAVERSION = $(EP_EXTRAVERSION) OBJ = $@ N = export Q VERBOSE EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) INCLUDES = -I $(srctree)/include $(CONFIG_INCLUDES) # Set compile option CFLAGS if not set elsewhere CFLAGS ?= -g -Wall # Append required CFLAGS override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) override CFLAGS += $(udis86-flags) -D_GNU_SOURCE ifeq ($(VERBOSE),1) Q = else Q = @ endif do_compile_shared_library = \ ($(print_shared_lib_compile) \ $(CC) --shared $^ -o $@) do_build_static_lib = \ ($(print_static_lib_build) \ $(RM) $@; $(AR) rcs $@ $^) do_compile = $(QUIET_CC)$(CC) -c $(CFLAGS) $(EXT) $< -o $@; $(obj)/%.o: $(src)/%.c $(call do_compile) PEVENT_LIB_OBJS = $(obj)/event-parse.o PEVENT_LIB_OBJS += $(obj)/event-plugin.o PEVENT_LIB_OBJS += $(obj)/trace-seq.o PEVENT_LIB_OBJS += $(obj)/parse-filter.o PEVENT_LIB_OBJS += $(obj)/parse-utils.o PEVENT_LIB_OBJS += $(obj)/kbuffer-parse.o ALL_OBJS = $(PEVENT_LIB_OBJS) $(PLUGIN_OBJS) CMD_TARGETS = $(LIB_FILE) $(PLUGINS) TARGETS = $(CMD_TARGETS) all: all_cmd all_cmd: $(CMD_TARGETS) $(obj)/libtraceevent.so: $(PEVENT_LIB_OBJS) $(QUIET_LINK)$(CC) --shared $^ -o $@ $(obj)/libtraceevent.a: $(PEVENT_LIB_OBJS) $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ $(PEVENT_LIB_OBJS): $(obj)/%.o: $(src)/%.c $(obj)/TRACEEVENT-CFLAGS $(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) $(EXT) $< -o $@ define make_version.h (echo '/* This file is automatically generated. Do not modify. */'; \ echo \#define VERSION_CODE $(shell \ expr $(VERSION) \* 256 + $(PATCHLEVEL)); \ echo '#define EXTRAVERSION ' $(EXTRAVERSION); \ echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \ echo '#define FILE_VERSION '$(FILE_VERSION); \ ) > $1 endef define update_version.h ($(call make_version.h, $@.tmp); \ if [ -r $@ ] && cmp -s $@ $@.tmp; then \ rm -f $@.tmp; \ else \ echo ' UPDATE $@'; \ mv -f $@.tmp $@; \ fi); endef ep_version.h: force $(Q)$(N)$(call update_version.h) VERSION_FILES = ep_version.h define update_dir (echo $1 > $@.tmp; \ if [ -r $@ ] && cmp -s $@ $@.tmp; then \ rm -f $@.tmp; \ else \ echo ' UPDATE $@'; \ mv -f $@.tmp $@; \ fi); endef ## make deps all_objs := $(sort $(ALL_OBJS)) all_deps := $(all_objs:$(obj)/%.o=$(obj)/.%.d) # let .d file also depends on the source and header files define check_deps @set -e; $(RM) $@; \ $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ $(RM) $@.$$$$ endef $(all_deps): $(obj)/.%.d: $(src)/%.c $(Q)$(call check_deps) $(all_objs) : $(obj)/%.o : $(obj)/.%.d dep_includes := $(wildcard $(all_deps)) ifneq ($(dep_includes),) include $(dep_includes) endif ### Detect environment changes TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE) $(obj)/TRACEEVENT-CFLAGS: force @FLAGS='$(TRACK_CFLAGS)'; \ if test x"$$FLAGS" != x"`cat $(obj)/TRACEEVENT-CFLAGS 2>/dev/null`" ; then \ echo 1>&2 " FLAGS: * new build flags or cross compiler"; \ echo "$$FLAGS" > $(obj)/TRACEEVENT-CFLAGS; \ fi tags: force $(RM) tags find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' TAGS: force $(RM) TAGS find . -name '*.[ch]' | xargs etags \ --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' define do_install if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ fi; \ $(INSTALL) $1 '$(DESTDIR_SQ)$2' endef install_lib: all_cmd $(call QUIET_INSTALL, $(LIB_FILE)) \ $(call do_install,$(LIB_FILE),$(bindir_SQ)) install: install_lib clean: $(call QUIET_CLEAN, libtraceevent) \ $(RM) $(obj)/*.o $(obj)/*~ $(TARGETS) $(obj)/*.a $(obj)/*.so \ $(VERSION_FILES) $(obj)/.*.d $(RM) $(obj)/TRACEEVENT-CFLAGS tags TAGS endif # skip-makefile PHONY += force force: # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable so we can use it in if_changed and friends. .PHONY: $(PHONY) uftrace-0.9.3/libtraceevent/event-parse.c000066400000000000000000004004331351236475300204150ustar00rootroot00000000000000/* * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License (not later!) * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * The parts for function graph printing was taken and modified from the * Linux Kernel that were written by * - Copyright (C) 2009 Frederic Weisbecker, * Frederic Weisbecker gave his permission to relicense the code to * the Lesser General Public License. */ #include #include #include #include #include #include #include #include #include "event-parse.h" #include "event-utils.h" static const char *input_buf; static unsigned long long input_buf_ptr; static unsigned long long input_buf_siz; static int is_flag_field; static int is_symbolic_field; static int show_warning = 1; #define do_warning(fmt, ...) \ do { \ if (show_warning) \ warning(fmt, ##__VA_ARGS__); \ } while (0) #define do_warning_event(event, fmt, ...) \ do { \ if (!show_warning) \ continue; \ \ if (event) \ warning("[%s:%s] " fmt, event->system, \ event->name, ##__VA_ARGS__); \ else \ warning(fmt, ##__VA_ARGS__); \ } while (0) static void init_input_buf(const char *buf, unsigned long long size) { input_buf = buf; input_buf_siz = size; input_buf_ptr = 0; } const char *pevent_get_input_buf(void) { return input_buf; } unsigned long long pevent_get_input_buf_ptr(void) { return input_buf_ptr; } struct event_handler { struct event_handler *next; int id; const char *sys_name; const char *event_name; pevent_event_handler_func func; void *context; }; struct pevent_func_params { struct pevent_func_params *next; enum pevent_func_arg_type type; }; struct pevent_function_handler { struct pevent_function_handler *next; enum pevent_func_arg_type ret_type; char *name; pevent_func_handler func; struct pevent_func_params *params; int nr_args; }; static unsigned long long process_defined_func(struct trace_seq *s, void *data, int size, struct event_format *event, struct print_arg *arg); static void free_func_handle(struct pevent_function_handler *func); /** * pevent_buffer_init - init buffer for parsing * @buf: buffer to parse * @size: the size of the buffer * * For use with pevent_read_token(), this initializes the internal * buffer that pevent_read_token() will parse. */ void pevent_buffer_init(const char *buf, unsigned long long size) { init_input_buf(buf, size); } void breakpoint(void) { static int x; x++; } struct print_arg *alloc_arg(void) { return calloc(1, sizeof(struct print_arg)); } struct cmdline { char *comm; int pid; }; static int cmdline_cmp(const void *a, const void *b) { const struct cmdline *ca = a; const struct cmdline *cb = b; if (ca->pid < cb->pid) return -1; if (ca->pid > cb->pid) return 1; return 0; } struct cmdline_list { struct cmdline_list *next; char *comm; int pid; }; static int cmdline_init(struct pevent *pevent) { struct cmdline_list *cmdlist = pevent->cmdlist; struct cmdline_list *item; struct cmdline *cmdlines; int i; cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count); if (!cmdlines) return -1; i = 0; while (cmdlist) { cmdlines[i].pid = cmdlist->pid; cmdlines[i].comm = cmdlist->comm; i++; item = cmdlist; cmdlist = cmdlist->next; free(item); } qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp); pevent->cmdlines = cmdlines; pevent->cmdlist = NULL; return 0; } static const char *find_cmdline(struct pevent *pevent, int pid) { const struct cmdline *comm; struct cmdline key; if (!pid) return ""; if (!pevent->cmdlines && cmdline_init(pevent)) return ""; key.pid = pid; comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, sizeof(*pevent->cmdlines), cmdline_cmp); if (comm) return comm->comm; return "<...>"; } /** * pevent_pid_is_registered - return if a pid has a cmdline registered * @pevent: handle for the pevent * @pid: The pid to check if it has a cmdline registered with. * * Returns 1 if the pid has a cmdline mapped to it * 0 otherwise. */ int pevent_pid_is_registered(struct pevent *pevent, int pid) { const struct cmdline *comm; struct cmdline key; if (!pid) return 1; if (!pevent->cmdlines && cmdline_init(pevent)) return 0; key.pid = pid; comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, sizeof(*pevent->cmdlines), cmdline_cmp); if (comm) return 1; return 0; } /* * If the command lines have been converted to an array, then * we must add this pid. This is much slower than when cmdlines * are added before the array is initialized. */ static int add_new_comm(struct pevent *pevent, const char *comm, int pid) { struct cmdline *cmdlines = pevent->cmdlines; const struct cmdline *cmdline; struct cmdline key; if (!pid) return 0; /* avoid duplicates */ key.pid = pid; cmdline = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, sizeof(*pevent->cmdlines), cmdline_cmp); if (cmdline) { errno = EEXIST; return -1; } cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (pevent->cmdline_count + 1)); if (!cmdlines) { errno = ENOMEM; return -1; } cmdlines[pevent->cmdline_count].comm = strdup(comm); if (!cmdlines[pevent->cmdline_count].comm) { free(cmdlines); errno = ENOMEM; return -1; } cmdlines[pevent->cmdline_count].pid = pid; if (cmdlines[pevent->cmdline_count].comm) pevent->cmdline_count++; qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp); pevent->cmdlines = cmdlines; return 0; } /** * pevent_register_comm - register a pid / comm mapping * @pevent: handle for the pevent * @comm: the command line to register * @pid: the pid to map the command line to * * This adds a mapping to search for command line names with * a given pid. The comm is duplicated. */ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid) { struct cmdline_list *item; if (pevent->cmdlines) return add_new_comm(pevent, comm, pid); item = malloc(sizeof(*item)); if (!item) return -1; item->comm = strdup(comm); if (!item->comm) { free(item); return -1; } item->pid = pid; item->next = pevent->cmdlist; pevent->cmdlist = item; pevent->cmdline_count++; return 0; } void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock) { pevent->trace_clock = trace_clock; } struct func_map { unsigned long long addr; char *func; char *mod; }; struct func_list { struct func_list *next; unsigned long long addr; char *func; char *mod; }; static int func_cmp(const void *a, const void *b) { const struct func_map *fa = a; const struct func_map *fb = b; if (fa->addr < fb->addr) return -1; if (fa->addr > fb->addr) return 1; return 0; } /* * We are searching for a record in between, not an exact * match. */ static int func_bcmp(const void *a, const void *b) { const struct func_map *fa = a; const struct func_map *fb = b; if ((fa->addr == fb->addr) || (fa->addr > fb->addr && fa->addr < (fb+1)->addr)) return 0; if (fa->addr < fb->addr) return -1; return 1; } static int func_map_init(struct pevent *pevent) { struct func_list *funclist; struct func_list *item; struct func_map *func_map; int i; func_map = malloc(sizeof(*func_map) * (pevent->func_count + 1)); if (!func_map) return -1; funclist = pevent->funclist; i = 0; while (funclist) { func_map[i].func = funclist->func; func_map[i].addr = funclist->addr; func_map[i].mod = funclist->mod; i++; item = funclist; funclist = funclist->next; free(item); } qsort(func_map, pevent->func_count, sizeof(*func_map), func_cmp); /* * Add a special record at the end. */ func_map[pevent->func_count].func = NULL; func_map[pevent->func_count].addr = 0; func_map[pevent->func_count].mod = NULL; pevent->func_map = func_map; pevent->funclist = NULL; return 0; } static struct func_map * find_func(struct pevent *pevent, unsigned long long addr) { struct func_map *func; struct func_map key; if (!pevent->func_map) func_map_init(pevent); key.addr = addr; func = bsearch(&key, pevent->func_map, pevent->func_count, sizeof(*pevent->func_map), func_bcmp); return func; } /** * pevent_find_function - find a function by a given address * @pevent: handle for the pevent * @addr: the address to find the function with * * Returns a pointer to the function stored that has the given * address. Note, the address does not have to be exact, it * will select the function that would contain the address. */ const char *pevent_find_function(struct pevent *pevent, unsigned long long addr) { struct func_map *map; map = find_func(pevent, addr); if (!map) return NULL; return map->func; } /** * pevent_find_function_address - find a function address by a given address * @pevent: handle for the pevent * @addr: the address to find the function with * * Returns the address the function starts at. This can be used in * conjunction with pevent_find_function to print both the function * name and the function offset. */ unsigned long long pevent_find_function_address(struct pevent *pevent, unsigned long long addr) { struct func_map *map; map = find_func(pevent, addr); if (!map) return 0; return map->addr; } /** * pevent_register_function - register a function with a given address * @pevent: handle for the pevent * @function: the function name to register * @addr: the address the function starts at * @mod: the kernel module the function may be in (NULL for none) * * This registers a function name with an address and module. * The @func passed in is duplicated. */ int pevent_register_function(struct pevent *pevent, char *func, unsigned long long addr, char *mod) { struct func_list *item = malloc(sizeof(*item)); if (!item) return -1; item->next = pevent->funclist; item->func = strdup(func); if (!item->func) goto out_free; if (mod) { item->mod = strdup(mod); if (!item->mod) goto out_free_func; } else item->mod = NULL; item->addr = addr; pevent->funclist = item; pevent->func_count++; return 0; out_free_func: free(item->func); item->func = NULL; out_free: free(item); errno = ENOMEM; return -1; } /** * pevent_print_funcs - print out the stored functions * @pevent: handle for the pevent * * This prints out the stored functions. */ void pevent_print_funcs(struct pevent *pevent) { int i; if (!pevent->func_map) func_map_init(pevent); for (i = 0; i < (int)pevent->func_count; i++) { printf("%016llx %s", pevent->func_map[i].addr, pevent->func_map[i].func); if (pevent->func_map[i].mod) printf(" [%s]\n", pevent->func_map[i].mod); else printf("\n"); } } struct printk_map { unsigned long long addr; char *printk; }; struct printk_list { struct printk_list *next; unsigned long long addr; char *printk; }; static int printk_cmp(const void *a, const void *b) { const struct printk_map *pa = a; const struct printk_map *pb = b; if (pa->addr < pb->addr) return -1; if (pa->addr > pb->addr) return 1; return 0; } static int printk_map_init(struct pevent *pevent) { struct printk_list *printklist; struct printk_list *item; struct printk_map *printk_map; int i; printk_map = malloc(sizeof(*printk_map) * (pevent->printk_count + 1)); if (!printk_map) return -1; printklist = pevent->printklist; i = 0; while (printklist) { printk_map[i].printk = printklist->printk; printk_map[i].addr = printklist->addr; i++; item = printklist; printklist = printklist->next; free(item); } qsort(printk_map, pevent->printk_count, sizeof(*printk_map), printk_cmp); pevent->printk_map = printk_map; pevent->printklist = NULL; return 0; } static struct printk_map * find_printk(struct pevent *pevent, unsigned long long addr) { struct printk_map *printk; struct printk_map key; if (!pevent->printk_map && printk_map_init(pevent)) return NULL; key.addr = addr; printk = bsearch(&key, pevent->printk_map, pevent->printk_count, sizeof(*pevent->printk_map), printk_cmp); return printk; } /** * pevent_register_print_string - register a string by its address * @pevent: handle for the pevent * @fmt: the string format to register * @addr: the address the string was located at * * This registers a string by the address it was stored in the kernel. * The @fmt passed in is duplicated. */ int pevent_register_print_string(struct pevent *pevent, const char *fmt, unsigned long long addr) { struct printk_list *item = malloc(sizeof(*item)); char *p; if (!item) return -1; item->next = pevent->printklist; item->addr = addr; /* Strip off quotes and '\n' from the end */ if (fmt[0] == '"') fmt++; item->printk = strdup(fmt); if (!item->printk) goto out_free; p = item->printk + strlen(item->printk) - 1; if (*p == '"') *p = 0; p -= 2; if (strcmp(p, "\\n") == 0) *p = 0; pevent->printklist = item; pevent->printk_count++; return 0; out_free: free(item); errno = ENOMEM; return -1; } /** * pevent_print_printk - print out the stored strings * @pevent: handle for the pevent * * This prints the string formats that were stored. */ void pevent_print_printk(struct pevent *pevent) { int i; if (!pevent->printk_map) printk_map_init(pevent); for (i = 0; i < (int)pevent->printk_count; i++) { printf("%016llx %s\n", pevent->printk_map[i].addr, pevent->printk_map[i].printk); } } static struct event_format *alloc_event(void) { return calloc(1, sizeof(struct event_format)); } static int add_event(struct pevent *pevent, struct event_format *event) { int i; struct event_format **events = realloc(pevent->events, sizeof(event) * (pevent->nr_events + 1)); if (!events) return -1; pevent->events = events; for (i = 0; i < pevent->nr_events; i++) { if (pevent->events[i]->id > event->id) break; } if (i < pevent->nr_events) memmove(&pevent->events[i + 1], &pevent->events[i], sizeof(event) * (pevent->nr_events - i)); pevent->events[i] = event; pevent->nr_events++; event->pevent = pevent; return 0; } static int event_item_type(enum event_type type) { switch (type) { case EVENT_ITEM ... EVENT_SQUOTE: return 1; case EVENT_ERROR ... EVENT_DELIM: default: return 0; } } static void free_flag_sym(struct print_flag_sym *fsym) { struct print_flag_sym *next; while (fsym) { next = fsym->next; free(fsym->value); free(fsym->str); free(fsym); fsym = next; } } static void free_arg(struct print_arg *arg) { struct print_arg *farg; if (!arg) return; switch (arg->type) { case PRINT_ATOM: free(arg->atom.atom); break; case PRINT_FIELD: free(arg->field.name); break; case PRINT_FLAGS: free_arg(arg->flags.field); free(arg->flags.delim); free_flag_sym(arg->flags.flags); break; case PRINT_SYMBOL: free_arg(arg->symbol.field); free_flag_sym(arg->symbol.symbols); break; case PRINT_HEX: free_arg(arg->hex.field); free_arg(arg->hex.size); break; case PRINT_TYPE: free(arg->typecast.type); free_arg(arg->typecast.item); break; case PRINT_STRING: case PRINT_BSTRING: free(arg->string.string); break; case PRINT_BITMASK: free(arg->bitmask.bitmask); break; case PRINT_DYNAMIC_ARRAY: free(arg->dynarray.index); break; case PRINT_OP: free(arg->op.op); free_arg(arg->op.left); free_arg(arg->op.right); break; case PRINT_FUNC: while (arg->func.args) { farg = arg->func.args; arg->func.args = farg->next; free_arg(farg); } break; case PRINT_NULL: default: break; } free(arg); } static enum event_type get_type(int ch) { if (ch == '\n') return EVENT_NEWLINE; if (isspace(ch)) return EVENT_SPACE; if (isalnum(ch) || ch == '_') return EVENT_ITEM; if (ch == '\'') return EVENT_SQUOTE; if (ch == '"') return EVENT_DQUOTE; if (!isprint(ch)) return EVENT_NONE; if (ch == '(' || ch == ')' || ch == ',') return EVENT_DELIM; return EVENT_OP; } static int __read_char(void) { if (input_buf_ptr >= input_buf_siz) return -1; return input_buf[input_buf_ptr++]; } static int __peek_char(void) { if (input_buf_ptr >= input_buf_siz) return -1; return input_buf[input_buf_ptr]; } /** * pevent_peek_char - peek at the next character that will be read * * Returns the next character read, or -1 if end of buffer. */ int pevent_peek_char(void) { return __peek_char(); } static int extend_token(char **tok, char *buf, int size) { char *newtok = realloc(*tok, size); if (!newtok) { free(*tok); *tok = NULL; return -1; } if (!*tok) strcpy(newtok, buf); else strcat(newtok, buf); *tok = newtok; return 0; } static enum event_type force_token(const char *str, char **tok); static enum event_type __read_token(char **tok) { char buf[BUFSIZ]; int ch, last_ch, quote_ch, next_ch; int i = 0; int tok_size = 0; enum event_type type; *tok = NULL; ch = __read_char(); if (ch < 0) return EVENT_NONE; type = get_type(ch); if (type == EVENT_NONE) return type; buf[i++] = ch; switch (type) { case EVENT_NEWLINE: case EVENT_DELIM: if (asprintf(tok, "%c", ch) < 0) return EVENT_ERROR; return type; case EVENT_OP: switch (ch) { case '-': next_ch = __peek_char(); if (next_ch == '>') { buf[i++] = __read_char(); break; } /* fall through */ case '+': case '|': case '&': case '>': case '<': last_ch = ch; ch = __peek_char(); if (ch != last_ch) goto test_equal; buf[i++] = __read_char(); switch (last_ch) { case '>': case '<': goto test_equal; default: break; } break; case '!': case '=': goto test_equal; default: /* what should we do instead? */ break; } buf[i] = 0; *tok = strdup(buf); return type; test_equal: ch = __peek_char(); if (ch == '=') buf[i++] = __read_char(); goto out; case EVENT_DQUOTE: case EVENT_SQUOTE: /* don't keep quotes */ i--; quote_ch = ch; last_ch = 0; concat: do { if (i == (BUFSIZ - 1)) { buf[i] = 0; tok_size += BUFSIZ; if (extend_token(tok, buf, tok_size) < 0) return EVENT_NONE; i = 0; } last_ch = ch; ch = __read_char(); buf[i++] = ch; /* the '\' '\' will cancel itself */ if (ch == '\\' && last_ch == '\\') last_ch = 0; } while (ch != quote_ch || last_ch == '\\'); /* remove the last quote */ i--; /* * For strings (double quotes) check the next token. * If it is another string, concatinate the two. */ if (type == EVENT_DQUOTE) { unsigned long long save_input_buf_ptr = input_buf_ptr; do { ch = __read_char(); } while (isspace(ch)); if (ch == '"') goto concat; input_buf_ptr = save_input_buf_ptr; } goto out; case EVENT_ERROR ... EVENT_SPACE: case EVENT_ITEM: default: break; } while (get_type(__peek_char()) == type) { if (i == (BUFSIZ - 1)) { buf[i] = 0; tok_size += BUFSIZ; if (extend_token(tok, buf, tok_size) < 0) return EVENT_NONE; i = 0; } ch = __read_char(); buf[i++] = ch; } out: buf[i] = 0; if (extend_token(tok, buf, tok_size + i + 1) < 0) return EVENT_NONE; if (type == EVENT_ITEM) { /* * Older versions of the kernel has a bug that * creates invalid symbols and will break the mac80211 * parsing. This is a work around to that bug. * * See Linux kernel commit: * 811cb50baf63461ce0bdb234927046131fc7fa8b */ if (strcmp(*tok, "LOCAL_PR_FMT") == 0) { free(*tok); *tok = NULL; return force_token("\"\%s\" ", tok); } else if (strcmp(*tok, "STA_PR_FMT") == 0) { free(*tok); *tok = NULL; return force_token("\" sta:%pM\" ", tok); } else if (strcmp(*tok, "VIF_PR_FMT") == 0) { free(*tok); *tok = NULL; return force_token("\" vif:%p(%d)\" ", tok); } } return type; } static enum event_type force_token(const char *str, char **tok) { const char *save_input_buf; unsigned long long save_input_buf_ptr; unsigned long long save_input_buf_siz; enum event_type type; /* save off the current input pointers */ save_input_buf = input_buf; save_input_buf_ptr = input_buf_ptr; save_input_buf_siz = input_buf_siz; init_input_buf(str, strlen(str)); type = __read_token(tok); /* reset back to original token */ input_buf = save_input_buf; input_buf_ptr = save_input_buf_ptr; input_buf_siz = save_input_buf_siz; return type; } static void free_token(char *tok) { if (tok) free(tok); } static enum event_type read_token(char **tok) { enum event_type type; for (;;) { type = __read_token(tok); if (type != EVENT_SPACE) return type; free_token(*tok); } /* not reached */ *tok = NULL; return EVENT_NONE; } /** * pevent_read_token - access to utilites to use the pevent parser * @tok: The token to return * * This will parse tokens from the string given by * pevent_init_data(). * * Returns the token type. */ enum event_type pevent_read_token(char **tok) { return read_token(tok); } /** * pevent_free_token - free a token returned by pevent_read_token * @token: the token to free */ void pevent_free_token(char *token) { free_token(token); } /* no newline */ static enum event_type read_token_item(char **tok) { enum event_type type; for (;;) { type = __read_token(tok); if (type != EVENT_SPACE && type != EVENT_NEWLINE) return type; free_token(*tok); *tok = NULL; } /* not reached */ *tok = NULL; return EVENT_NONE; } static int test_type(enum event_type type, enum event_type expect) { if (type != expect) { do_warning("Error: expected type %d but read %d", expect, type); return -1; } return 0; } static int test_type_token(enum event_type type, const char *token, enum event_type expect, const char *expect_tok) { if (type != expect) { do_warning("Error: expected type %d but read %d", expect, type); return -1; } if (strcmp(token, expect_tok) != 0) { do_warning("Error: expected '%s' but read '%s'", expect_tok, token); return -1; } return 0; } static int __read_expect_type(enum event_type expect, char **tok, int newline_ok) { enum event_type type; if (newline_ok) type = read_token(tok); else type = read_token_item(tok); return test_type(type, expect); } static int read_expect_type(enum event_type expect, char **tok) { return __read_expect_type(expect, tok, 1); } static int __read_expected(enum event_type expect, const char *str, int newline_ok) { enum event_type type; char *token; int ret; if (newline_ok) type = read_token(&token); else type = read_token_item(&token); ret = test_type_token(type, token, expect, str); free_token(token); return ret; } static int read_expected(enum event_type expect, const char *str) { return __read_expected(expect, str, 1); } static int read_expected_item(enum event_type expect, const char *str) { return __read_expected(expect, str, 0); } static char *event_read_name(void) { char *token; if (read_expected(EVENT_ITEM, "name") < 0) return NULL; if (read_expected(EVENT_OP, ":") < 0) return NULL; if (read_expect_type(EVENT_ITEM, &token) < 0) goto fail; return token; fail: free_token(token); return NULL; } static int event_read_id(void) { char *token; int id; if (read_expected_item(EVENT_ITEM, "ID") < 0) return -1; if (read_expected(EVENT_OP, ":") < 0) return -1; if (read_expect_type(EVENT_ITEM, &token) < 0) goto fail; id = strtoul(token, NULL, 0); free_token(token); return id; fail: free_token(token); return -1; } static int field_is_string(struct format_field *field) { if ((field->flags & FIELD_IS_ARRAY) && (strstr(field->type, "char") || strstr(field->type, "u8") || strstr(field->type, "s8"))) return 1; return 0; } static int field_is_dynamic(struct format_field *field) { if (strncmp(field->type, "__data_loc", 10) == 0) return 1; return 0; } static int field_is_long(struct format_field *field) { /* includes long long */ if (strstr(field->type, "long")) return 1; return 0; } static unsigned int type_size(const char *name) { /* This covers all FIELD_IS_STRING types. */ static struct { const char *type; unsigned int size; } table[] = { { "u8", 1 }, { "u16", 2 }, { "u32", 4 }, { "u64", 8 }, { "s8", 1 }, { "s16", 2 }, { "s32", 4 }, { "s64", 8 }, { "char", 1 }, { }, }; int i; for (i = 0; table[i].type; i++) { if (!strcmp(table[i].type, name)) return table[i].size; } return 0; } static int event_read_fields(struct event_format *event, struct format_field **fields) { struct format_field *field = NULL; enum event_type type; char *token; char *last_token; int count = 0; do { unsigned int size_dynamic = 0; type = read_token(&token); if (type == EVENT_NEWLINE) { free_token(token); return count; } count++; if (test_type_token(type, token, EVENT_ITEM, "field")) goto fail; free_token(token); type = read_token(&token); /* * The ftrace fields may still use the "special" name. * Just ignore it. */ if (event->flags & EVENT_FL_ISFTRACE && type == EVENT_ITEM && strcmp(token, "special") == 0) { free_token(token); type = read_token(&token); } if (test_type_token(type, token, EVENT_OP, ":") < 0) goto fail; free_token(token); if (read_expect_type(EVENT_ITEM, &token) < 0) goto fail; last_token = token; field = calloc(1, sizeof(*field)); if (!field) goto fail; field->event = event; /* read the rest of the type */ for (;;) { type = read_token(&token); if (type == EVENT_ITEM || (type == EVENT_OP && strcmp(token, "*") == 0) || /* * Some of the ftrace fields are broken and have * an illegal "." in them. */ (event->flags & EVENT_FL_ISFTRACE && type == EVENT_OP && strcmp(token, ".") == 0)) { if (strcmp(token, "*") == 0) field->flags |= FIELD_IS_POINTER; if (field->type) { char *new_type; new_type = realloc(field->type, strlen(field->type) + strlen(last_token) + 2); if (!new_type) { free(last_token); goto fail; } field->type = new_type; strcat(field->type, " "); strcat(field->type, last_token); free(last_token); } else field->type = last_token; last_token = token; continue; } break; } if (!field->type) { do_warning_event(event, "%s: no type found", __func__); goto fail; } field->name = last_token; if (test_type(type, EVENT_OP)) goto fail; if (strcmp(token, "[") == 0) { enum event_type last_type = type; char *brackets = token; char *new_brackets; int len; field->flags |= FIELD_IS_ARRAY; type = read_token(&token); if (type == EVENT_ITEM) field->arraylen = strtoul(token, NULL, 0); else field->arraylen = 0; while (strcmp(token, "]") != 0) { if (last_type == EVENT_ITEM && type == EVENT_ITEM) len = 2; else len = 1; last_type = type; new_brackets = realloc(brackets, strlen(brackets) + strlen(token) + len); if (!new_brackets) { free(brackets); goto fail; } brackets = new_brackets; if (len == 2) strcat(brackets, " "); strcat(brackets, token); /* We only care about the last token */ field->arraylen = strtoul(token, NULL, 0); free_token(token); type = read_token(&token); if (type == EVENT_NONE) { do_warning_event(event, "failed to find token"); goto fail; } } free_token(token); new_brackets = realloc(brackets, strlen(brackets) + 2); if (!new_brackets) { free(brackets); goto fail; } brackets = new_brackets; strcat(brackets, "]"); /* add brackets to type */ type = read_token(&token); /* * If the next token is not an OP, then it is of * the format: type [] item; */ if (type == EVENT_ITEM) { char *new_type; new_type = realloc(field->type, strlen(field->type) + strlen(field->name) + strlen(brackets) + 2); if (!new_type) { free(brackets); goto fail; } field->type = new_type; strcat(field->type, " "); strcat(field->type, field->name); size_dynamic = type_size(field->name); free_token(field->name); strcat(field->type, brackets); field->name = token; type = read_token(&token); } else { char *new_type; new_type = realloc(field->type, strlen(field->type) + strlen(brackets) + 1); if (!new_type) { free(brackets); goto fail; } field->type = new_type; strcat(field->type, brackets); } free(brackets); } if (field_is_string(field)) field->flags |= FIELD_IS_STRING; if (field_is_dynamic(field)) field->flags |= FIELD_IS_DYNAMIC; if (field_is_long(field)) field->flags |= FIELD_IS_LONG; if (test_type_token(type, token, EVENT_OP, ";")) goto fail; free_token(token); if (read_expected(EVENT_ITEM, "offset") < 0) goto fail_expect; if (read_expected(EVENT_OP, ":") < 0) goto fail_expect; if (read_expect_type(EVENT_ITEM, &token)) goto fail; field->offset = strtoul(token, NULL, 0); free_token(token); if (read_expected(EVENT_OP, ";") < 0) goto fail_expect; if (read_expected(EVENT_ITEM, "size") < 0) goto fail_expect; if (read_expected(EVENT_OP, ":") < 0) goto fail_expect; if (read_expect_type(EVENT_ITEM, &token)) goto fail; field->size = strtoul(token, NULL, 0); free_token(token); if (read_expected(EVENT_OP, ";") < 0) goto fail_expect; type = read_token(&token); if (type != EVENT_NEWLINE) { /* newer versions of the kernel have a "signed" type */ if (test_type_token(type, token, EVENT_ITEM, "signed")) goto fail; free_token(token); if (read_expected(EVENT_OP, ":") < 0) goto fail_expect; if (read_expect_type(EVENT_ITEM, &token)) goto fail; if (strtoul(token, NULL, 0)) field->flags |= FIELD_IS_SIGNED; free_token(token); if (read_expected(EVENT_OP, ";") < 0) goto fail_expect; if (read_expect_type(EVENT_NEWLINE, &token)) goto fail; } free_token(token); if (field->flags & FIELD_IS_ARRAY) { if (field->arraylen) field->elementsize = field->size / field->arraylen; else if (field->flags & FIELD_IS_DYNAMIC) field->elementsize = size_dynamic; else if (field->flags & FIELD_IS_STRING) field->elementsize = 1; else if (field->flags & FIELD_IS_LONG) field->elementsize = event->pevent ? event->pevent->long_size : (int)sizeof(long); } else field->elementsize = field->size; *fields = field; fields = &field->next; } while (1); return 0; fail: free_token(token); fail_expect: if (field) { free(field->type); free(field->name); free(field); } return -1; } static int event_read_format(struct event_format *event) { char *token; int ret; if (read_expected_item(EVENT_ITEM, "format") < 0) return -1; if (read_expected(EVENT_OP, ":") < 0) return -1; if (read_expect_type(EVENT_NEWLINE, &token)) goto fail; free_token(token); ret = event_read_fields(event, &event->format.common_fields); if (ret < 0) return ret; event->format.nr_common = ret; ret = event_read_fields(event, &event->format.fields); if (ret < 0) return ret; event->format.nr_fields = ret; return 0; fail: free_token(token); return -1; } static enum event_type process_arg_token(struct event_format *event, struct print_arg *arg, char **tok, enum event_type type); static enum event_type process_arg(struct event_format *event, struct print_arg *arg, char **tok) { enum event_type type; char *token; type = read_token(&token); *tok = token; return process_arg_token(event, arg, tok, type); } static enum event_type process_op(struct event_format *event, struct print_arg *arg, char **tok); /* * For __print_symbolic() and __print_flags, we need to completely * evaluate the first argument, which defines what to print next. */ static enum event_type process_field_arg(struct event_format *event, struct print_arg *arg, char **tok) { enum event_type type; type = process_arg(event, arg, tok); while (type == EVENT_OP) { type = process_op(event, arg, tok); } return type; } static enum event_type process_cond(struct event_format *event, struct print_arg *top, char **tok) { struct print_arg *arg, *left, *right; enum event_type type; char *token = NULL; arg = alloc_arg(); left = alloc_arg(); right = alloc_arg(); if (!arg || !left || !right) { do_warning_event(event, "%s: not enough memory!", __func__); /* arg will be freed at out_free */ free_arg(left); free_arg(right); goto out_free; } arg->type = PRINT_OP; arg->op.left = left; arg->op.right = right; *tok = NULL; type = process_arg(event, left, &token); again: /* Handle other operations in the arguments */ if (type == EVENT_OP && strcmp(token, ":") != 0) { type = process_op(event, left, &token); goto again; } if (test_type_token(type, token, EVENT_OP, ":")) goto out_free; arg->op.op = token; type = process_arg(event, right, &token); top->op.right = arg; *tok = token; return type; out_free: /* Top may point to itself */ top->op.right = NULL; free_token(token); free_arg(arg); return EVENT_ERROR; } static enum event_type process_array(struct event_format *event, struct print_arg *top, char **tok) { struct print_arg *arg; enum event_type type; char *token = NULL; arg = alloc_arg(); if (!arg) { do_warning_event(event, "%s: not enough memory!", __func__); /* '*tok' is set to top->op.op. No need to free. */ *tok = NULL; return EVENT_ERROR; } *tok = NULL; type = process_arg(event, arg, &token); if (test_type_token(type, token, EVENT_OP, "]")) goto out_free; top->op.right = arg; free_token(token); type = read_token_item(&token); *tok = token; return type; out_free: free_token(token); free_arg(arg); return EVENT_ERROR; } static int get_op_prio(char *op) { if (!op[1]) { switch (op[0]) { case '~': case '!': return 4; case '*': case '/': case '%': return 6; case '+': case '-': return 7; /* '>>' and '<<' are 8 */ case '<': case '>': return 9; /* '==' and '!=' are 10 */ case '&': return 11; case '^': return 12; case '|': return 13; case '?': return 16; default: do_warning("unknown op '%c'", op[0]); return -1; } } else { if (strcmp(op, "++") == 0 || strcmp(op, "--") == 0) { return 3; } else if (strcmp(op, ">>") == 0 || strcmp(op, "<<") == 0) { return 8; } else if (strcmp(op, ">=") == 0 || strcmp(op, "<=") == 0) { return 9; } else if (strcmp(op, "==") == 0 || strcmp(op, "!=") == 0) { return 10; } else if (strcmp(op, "&&") == 0) { return 14; } else if (strcmp(op, "||") == 0) { return 15; } else { do_warning("unknown op '%s'", op); return -1; } } } static int set_op_prio(struct print_arg *arg) { /* single ops are the greatest */ if (!arg->op.left || arg->op.left->type == PRINT_NULL) arg->op.prio = 0; else arg->op.prio = get_op_prio(arg->op.op); return arg->op.prio; } /* Note, *tok does not get freed, but will most likely be saved */ static enum event_type process_op(struct event_format *event, struct print_arg *arg, char **tok) { struct print_arg *left, *right = NULL; enum event_type type; char *token; /* the op is passed in via tok */ token = *tok; if (arg->type == PRINT_OP && !arg->op.left) { /* handle single op */ if (token[1]) { do_warning_event(event, "bad op token %s", token); goto out_free; } switch (token[0]) { case '~': case '!': case '+': case '-': break; default: do_warning_event(event, "bad op token %s", token); goto out_free; } /* make an empty left */ left = alloc_arg(); if (!left) goto out_warn_free; left->type = PRINT_NULL; arg->op.left = left; right = alloc_arg(); if (!right) goto out_warn_free; arg->op.right = right; /* do not free the token, it belongs to an op */ *tok = NULL; type = process_arg(event, right, tok); } else if (strcmp(token, "?") == 0) { left = alloc_arg(); if (!left) goto out_warn_free; /* copy the top arg to the left */ *left = *arg; arg->type = PRINT_OP; arg->op.op = token; arg->op.left = left; arg->op.prio = 0; /* it will set arg->op.right */ type = process_cond(event, arg, tok); } else if (strcmp(token, ">>") == 0 || strcmp(token, "<<") == 0 || strcmp(token, "&") == 0 || strcmp(token, "|") == 0 || strcmp(token, "&&") == 0 || strcmp(token, "||") == 0 || strcmp(token, "-") == 0 || strcmp(token, "+") == 0 || strcmp(token, "*") == 0 || strcmp(token, "^") == 0 || strcmp(token, "/") == 0 || strcmp(token, "<") == 0 || strcmp(token, ">") == 0 || strcmp(token, "<=") == 0 || strcmp(token, ">=") == 0 || strcmp(token, "==") == 0 || strcmp(token, "!=") == 0) { left = alloc_arg(); if (!left) goto out_warn_free; /* copy the top arg to the left */ *left = *arg; arg->type = PRINT_OP; arg->op.op = token; arg->op.left = left; arg->op.right = NULL; if (set_op_prio(arg) == -1) { event->flags |= EVENT_FL_FAILED; /* arg->op.op (= token) will be freed at out_free */ arg->op.op = NULL; goto out_free; } type = read_token_item(&token); *tok = token; /* could just be a type pointer */ if ((strcmp(arg->op.op, "*") == 0) && type == EVENT_DELIM && (strcmp(token, ")") == 0)) { char *new_atom; if (left->type != PRINT_ATOM) { do_warning_event(event, "bad pointer type"); goto out_free; } new_atom = realloc(left->atom.atom, strlen(left->atom.atom) + 3); if (!new_atom) goto out_warn_free; left->atom.atom = new_atom; strcat(left->atom.atom, " *"); free(arg->op.op); *arg = *left; free(left); return type; } right = alloc_arg(); if (!right) goto out_warn_free; type = process_arg_token(event, right, tok, type); arg->op.right = right; } else if (strcmp(token, "[") == 0) { left = alloc_arg(); if (!left) goto out_warn_free; *left = *arg; arg->type = PRINT_OP; arg->op.op = token; arg->op.left = left; arg->op.prio = 0; /* it will set arg->op.right */ type = process_array(event, arg, tok); } else { do_warning_event(event, "unknown op '%s'", token); event->flags |= EVENT_FL_FAILED; /* the arg is now the left side */ goto out_free; } if (type == EVENT_OP && strcmp(*tok, ":") != 0) { int prio; /* higher prios need to be closer to the root */ prio = get_op_prio(*tok); if (prio > arg->op.prio) return process_op(event, arg, tok); return process_op(event, right, tok); } return type; out_warn_free: do_warning_event(event, "%s: not enough memory!", __func__); out_free: free_token(token); *tok = NULL; return EVENT_ERROR; } static enum event_type process_entry(struct event_format *event __maybe_unused, struct print_arg *arg, char **tok) { enum event_type type; char *field; char *token; if (read_expected(EVENT_OP, "->") < 0) goto out_err; if (read_expect_type(EVENT_ITEM, &token) < 0) goto out_free; field = token; arg->type = PRINT_FIELD; arg->field.name = field; if (is_flag_field) { arg->field.field = pevent_find_any_field(event, arg->field.name); arg->field.field->flags |= FIELD_IS_FLAG; is_flag_field = 0; } else if (is_symbolic_field) { arg->field.field = pevent_find_any_field(event, arg->field.name); arg->field.field->flags |= FIELD_IS_SYMBOLIC; is_symbolic_field = 0; } type = read_token(&token); *tok = token; return type; out_free: free_token(token); out_err: *tok = NULL; return EVENT_ERROR; } static char *arg_eval (struct print_arg *arg); static unsigned long long eval_type_str(unsigned long long val, const char *type, int pointer) { int sign = 0; char *ref; int len; len = strlen(type); if (pointer) { if (type[len-1] != '*') { do_warning("pointer expected with non pointer type"); return val; } ref = malloc(len); if (!ref) { do_warning("%s: not enough memory!", __func__); return val; } memcpy(ref, type, len); /* chop off the " *" */ ref[len - 2] = 0; val = eval_type_str(val, ref, 0); free(ref); return val; } /* check if this is a pointer */ if (type[len - 1] == '*') return val; /* Try to figure out the arg size*/ if (strncmp(type, "struct", 6) == 0) /* all bets off */ return val; if (strcmp(type, "u8") == 0) return val & 0xff; if (strcmp(type, "u16") == 0) return val & 0xffff; if (strcmp(type, "u32") == 0) return val & 0xffffffff; if (strcmp(type, "u64") == 0 || strcmp(type, "s64")) return val; if (strcmp(type, "s8") == 0) return (unsigned long long)(char)val & 0xff; if (strcmp(type, "s16") == 0) return (unsigned long long)(short)val & 0xffff; if (strcmp(type, "s32") == 0) return (unsigned long long)(int)val & 0xffffffff; if (strncmp(type, "unsigned ", 9) == 0) { sign = 0; type += 9; } if (strcmp(type, "char") == 0) { if (sign) return (unsigned long long)(char)val & 0xff; else return val & 0xff; } if (strcmp(type, "short") == 0) { if (sign) return (unsigned long long)(short)val & 0xffff; else return val & 0xffff; } if (strcmp(type, "int") == 0) { if (sign) return (unsigned long long)(int)val & 0xffffffff; else return val & 0xffffffff; } return val; } /* * Try to figure out the type. */ static unsigned long long eval_type(unsigned long long val, struct print_arg *arg, int pointer) { if (arg->type != PRINT_TYPE) { do_warning("expected type argument"); return 0; } return eval_type_str(val, arg->typecast.type, pointer); } static int arg_num_eval(struct print_arg *arg, long long *val) { long long left, right; int ret = 1; switch (arg->type) { case PRINT_ATOM: *val = strtoll(arg->atom.atom, NULL, 0); break; case PRINT_TYPE: ret = arg_num_eval(arg->typecast.item, val); if (!ret) break; *val = eval_type(*val, arg, 0); break; case PRINT_OP: switch (arg->op.op[0]) { case '|': ret = arg_num_eval(arg->op.left, &left); if (!ret) break; ret = arg_num_eval(arg->op.right, &right); if (!ret) break; if (arg->op.op[1]) *val = left || right; else *val = left | right; break; case '&': ret = arg_num_eval(arg->op.left, &left); if (!ret) break; ret = arg_num_eval(arg->op.right, &right); if (!ret) break; if (arg->op.op[1]) *val = left && right; else *val = left & right; break; case '<': ret = arg_num_eval(arg->op.left, &left); if (!ret) break; ret = arg_num_eval(arg->op.right, &right); if (!ret) break; switch (arg->op.op[1]) { case 0: *val = left < right; break; case '<': *val = left << right; break; case '=': *val = left <= right; break; default: do_warning("unknown op '%s'", arg->op.op); ret = 0; } break; case '>': ret = arg_num_eval(arg->op.left, &left); if (!ret) break; ret = arg_num_eval(arg->op.right, &right); if (!ret) break; switch (arg->op.op[1]) { case 0: *val = left > right; break; case '>': *val = left >> right; break; case '=': *val = left >= right; break; default: do_warning("unknown op '%s'", arg->op.op); ret = 0; } break; case '=': ret = arg_num_eval(arg->op.left, &left); if (!ret) break; ret = arg_num_eval(arg->op.right, &right); if (!ret) break; if (arg->op.op[1] != '=') { do_warning("unknown op '%s'", arg->op.op); ret = 0; } else *val = left == right; break; case '!': ret = arg_num_eval(arg->op.left, &left); if (!ret) break; ret = arg_num_eval(arg->op.right, &right); if (!ret) break; switch (arg->op.op[1]) { case '=': *val = left != right; break; default: do_warning("unknown op '%s'", arg->op.op); ret = 0; } break; case '-': /* check for negative */ if (arg->op.left->type == PRINT_NULL) left = 0; else ret = arg_num_eval(arg->op.left, &left); if (!ret) break; ret = arg_num_eval(arg->op.right, &right); if (!ret) break; *val = left - right; break; case '+': if (arg->op.left->type == PRINT_NULL) left = 0; else ret = arg_num_eval(arg->op.left, &left); if (!ret) break; ret = arg_num_eval(arg->op.right, &right); if (!ret) break; *val = left + right; break; default: do_warning("unknown op '%s'", arg->op.op); ret = 0; } break; case PRINT_NULL: case PRINT_FIELD ... PRINT_SYMBOL: case PRINT_STRING: case PRINT_BSTRING: case PRINT_BITMASK: default: do_warning("invalid eval type %d", arg->type); ret = 0; } return ret; } static char *arg_eval (struct print_arg *arg) { long long val; static char buf[20]; switch (arg->type) { case PRINT_ATOM: return arg->atom.atom; case PRINT_TYPE: return arg_eval(arg->typecast.item); case PRINT_OP: if (!arg_num_eval(arg, &val)) break; sprintf(buf, "%lld", val); return buf; case PRINT_NULL: case PRINT_FIELD ... PRINT_SYMBOL: case PRINT_STRING: case PRINT_BSTRING: case PRINT_BITMASK: default: do_warning("invalid eval type %d", arg->type); break; } return NULL; } static enum event_type process_fields(struct event_format *event, struct print_flag_sym **list, char **tok) { enum event_type type; struct print_arg *arg = NULL; struct print_flag_sym *field; char *token = *tok; char *value; do { free_token(token); type = read_token_item(&token); if (test_type_token(type, token, EVENT_OP, "{")) break; arg = alloc_arg(); if (!arg) goto out_free; free_token(token); type = process_arg(event, arg, &token); if (type == EVENT_OP) type = process_op(event, arg, &token); if (type == EVENT_ERROR) goto out_free; if (test_type_token(type, token, EVENT_DELIM, ",")) goto out_free; field = calloc(1, sizeof(*field)); if (!field) goto out_free; value = arg_eval(arg); if (value == NULL) goto out_free_field; field->value = strdup(value); if (field->value == NULL) goto out_free_field; free_arg(arg); arg = alloc_arg(); if (!arg) goto out_free; free_token(token); type = process_arg(event, arg, &token); if (test_type_token(type, token, EVENT_OP, "}")) goto out_free_field; value = arg_eval(arg); if (value == NULL) goto out_free_field; field->str = strdup(value); if (field->str == NULL) goto out_free_field; free_arg(arg); arg = NULL; *list = field; list = &field->next; free_token(token); type = read_token_item(&token); } while (type == EVENT_DELIM && strcmp(token, ",") == 0); *tok = token; return type; out_free_field: free_flag_sym(field); out_free: free_arg(arg); free_token(token); *tok = NULL; return EVENT_ERROR; } static enum event_type process_flags(struct event_format *event, struct print_arg *arg, char **tok) { struct print_arg *field; enum event_type type; char *token = NULL; memset(arg, 0, sizeof(*arg)); arg->type = PRINT_FLAGS; field = alloc_arg(); if (!field) { do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } type = process_field_arg(event, field, &token); /* Handle operations in the first argument */ while (type == EVENT_OP) type = process_op(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) goto out_free_field; free_token(token); arg->flags.field = field; type = read_token_item(&token); if (event_item_type(type)) { arg->flags.delim = token; type = read_token_item(&token); } if (test_type_token(type, token, EVENT_DELIM, ",")) goto out_free; type = process_fields(event, &arg->flags.flags, &token); if (test_type_token(type, token, EVENT_DELIM, ")")) goto out_free; free_token(token); type = read_token_item(tok); return type; out_free_field: free_arg(field); out_free: free_token(token); *tok = NULL; return EVENT_ERROR; } static enum event_type process_symbols(struct event_format *event, struct print_arg *arg, char **tok) { struct print_arg *field; enum event_type type; char *token = NULL; memset(arg, 0, sizeof(*arg)); arg->type = PRINT_SYMBOL; field = alloc_arg(); if (!field) { do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } type = process_field_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) goto out_free_field; arg->symbol.field = field; type = process_fields(event, &arg->symbol.symbols, &token); if (test_type_token(type, token, EVENT_DELIM, ")")) goto out_free; free_token(token); type = read_token_item(tok); return type; out_free_field: free_arg(field); out_free: free_token(token); *tok = NULL; return EVENT_ERROR; } static enum event_type process_hex(struct event_format *event, struct print_arg *arg, char **tok) { struct print_arg *field; enum event_type type; char *token = NULL; memset(arg, 0, sizeof(*arg)); arg->type = PRINT_HEX; field = alloc_arg(); if (!field) { do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) goto out_free; arg->hex.field = field; free_token(token); field = alloc_arg(); if (!field) { do_warning_event(event, "%s: not enough memory!", __func__); *tok = NULL; return EVENT_ERROR; } type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ")")) goto out_free; arg->hex.size = field; free_token(token); type = read_token_item(tok); return type; out_free: free_arg(field); free_token(token); *tok = NULL; return EVENT_ERROR; } static enum event_type process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) { struct format_field *field; enum event_type type; char *token; memset(arg, 0, sizeof(*arg)); arg->type = PRINT_DYNAMIC_ARRAY; /* * The item within the parenthesis is another field that holds * the index into where the array starts. */ type = read_token(&token); *tok = token; if (type != EVENT_ITEM) goto out_free; /* Find the field */ field = pevent_find_field(event, token); if (!field) goto out_free; arg->dynarray.field = field; arg->dynarray.index = 0; if (read_expected(EVENT_DELIM, ")") < 0) goto out_free; free_token(token); type = read_token_item(&token); *tok = token; if (type != EVENT_OP || strcmp(token, "[") != 0) return type; free_token(token); arg = alloc_arg(); if (!arg) { do_warning_event(event, "%s: not enough memory!", __func__); *tok = NULL; return EVENT_ERROR; } type = process_arg(event, arg, &token); if (type == EVENT_ERROR) goto out_free_arg; if (!test_type_token(type, token, EVENT_OP, "]")) goto out_free_arg; free_token(token); type = read_token_item(tok); return type; out_free_arg: free_arg(arg); out_free: free_token(token); *tok = NULL; return EVENT_ERROR; } static enum event_type process_paren(struct event_format *event, struct print_arg *arg, char **tok) { struct print_arg *item_arg; enum event_type type; char *token; type = process_arg(event, arg, &token); if (type == EVENT_ERROR) goto out_free; if (type == EVENT_OP) type = process_op(event, arg, &token); if (type == EVENT_ERROR) goto out_free; if (test_type_token(type, token, EVENT_DELIM, ")")) goto out_free; free_token(token); type = read_token_item(&token); /* * If the next token is an item or another open paren, then * this was a typecast. */ if (event_item_type(type) || (type == EVENT_DELIM && strcmp(token, "(") == 0)) { /* make this a typecast and contine */ /* prevous must be an atom */ if (arg->type != PRINT_ATOM) { do_warning_event(event, "previous needed to be PRINT_ATOM"); goto out_free; } item_arg = alloc_arg(); if (!item_arg) { do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } arg->type = PRINT_TYPE; arg->typecast.type = arg->atom.atom; arg->typecast.item = item_arg; type = process_arg_token(event, item_arg, &token, type); } *tok = token; return type; out_free: free_token(token); *tok = NULL; return EVENT_ERROR; } static enum event_type process_str(struct event_format *event __maybe_unused, struct print_arg *arg, char **tok) { enum event_type type; char *token; if (read_expect_type(EVENT_ITEM, &token) < 0) goto out_free; arg->type = PRINT_STRING; arg->string.string = token; arg->string.offset = -1; if (read_expected(EVENT_DELIM, ")") < 0) goto out_err; type = read_token(&token); *tok = token; return type; out_free: free_token(token); out_err: *tok = NULL; return EVENT_ERROR; } static enum event_type process_bitmask(struct event_format *event __maybe_unused, struct print_arg *arg, char **tok) { enum event_type type; char *token; if (read_expect_type(EVENT_ITEM, &token) < 0) goto out_free; arg->type = PRINT_BITMASK; arg->bitmask.bitmask = token; arg->bitmask.offset = -1; if (read_expected(EVENT_DELIM, ")") < 0) goto out_err; type = read_token(&token); *tok = token; return type; out_free: free_token(token); out_err: *tok = NULL; return EVENT_ERROR; } static struct pevent_function_handler * find_func_handler(struct pevent *pevent, char *func_name) { struct pevent_function_handler *func; if (!pevent) return NULL; for (func = pevent->func_handlers; func; func = func->next) { if (strcmp(func->name, func_name) == 0) break; } return func; } static void remove_func_handler(struct pevent *pevent, char *func_name) { struct pevent_function_handler *func; struct pevent_function_handler **next; next = &pevent->func_handlers; while ((func = *next)) { if (strcmp(func->name, func_name) == 0) { *next = func->next; free_func_handle(func); break; } next = &func->next; } } static enum event_type process_func_handler(struct event_format *event, struct pevent_function_handler *func, struct print_arg *arg, char **tok) { struct print_arg **next_arg; struct print_arg *farg; enum event_type type; char *token; int i; arg->type = PRINT_FUNC; arg->func.func = func; *tok = NULL; next_arg = &(arg->func.args); for (i = 0; i < func->nr_args; i++) { farg = alloc_arg(); if (!farg) { do_warning_event(event, "%s: not enough memory!", __func__); return EVENT_ERROR; } type = process_arg(event, farg, &token); if (i < (func->nr_args - 1)) { if (type != EVENT_DELIM || strcmp(token, ",") != 0) { do_warning_event(event, "Error: function '%s()' expects %d arguments but event %s only uses %d", func->name, func->nr_args, event->name, i + 1); goto err; } } else { if (type != EVENT_DELIM || strcmp(token, ")") != 0) { do_warning_event(event, "Error: function '%s()' only expects %d arguments but event %s has more", func->name, func->nr_args, event->name); goto err; } } *next_arg = farg; next_arg = &(farg->next); free_token(token); } type = read_token(&token); *tok = token; return type; err: free_arg(farg); free_token(token); return EVENT_ERROR; } static enum event_type process_function(struct event_format *event, struct print_arg *arg, char *token, char **tok) { struct pevent_function_handler *func; if (strcmp(token, "__print_flags") == 0) { free_token(token); is_flag_field = 1; return process_flags(event, arg, tok); } if (strcmp(token, "__print_symbolic") == 0) { free_token(token); is_symbolic_field = 1; return process_symbols(event, arg, tok); } if (strcmp(token, "__print_hex") == 0) { free_token(token); return process_hex(event, arg, tok); } if (strcmp(token, "__get_str") == 0) { free_token(token); return process_str(event, arg, tok); } if (strcmp(token, "__get_bitmask") == 0) { free_token(token); return process_bitmask(event, arg, tok); } if (strcmp(token, "__get_dynamic_array") == 0) { free_token(token); return process_dynamic_array(event, arg, tok); } func = find_func_handler(event->pevent, token); if (func) { free_token(token); return process_func_handler(event, func, arg, tok); } do_warning_event(event, "function %s not defined", token); free_token(token); return EVENT_ERROR; } static enum event_type process_arg_token(struct event_format *event, struct print_arg *arg, char **tok, enum event_type type) { char *token; char *atom; token = *tok; switch (type) { case EVENT_ITEM: if (strcmp(token, "REC") == 0) { free_token(token); type = process_entry(event, arg, &token); break; } atom = token; /* test the next token */ type = read_token_item(&token); /* * If the next token is a parenthesis, then this * is a function. */ if (type == EVENT_DELIM && strcmp(token, "(") == 0) { free_token(token); token = NULL; /* this will free atom. */ type = process_function(event, arg, atom, &token); break; } /* atoms can be more than one token long */ while (type == EVENT_ITEM) { char *new_atom; new_atom = realloc(atom, strlen(atom) + strlen(token) + 2); if (!new_atom) { free(atom); *tok = NULL; free_token(token); return EVENT_ERROR; } atom = new_atom; strcat(atom, " "); strcat(atom, token); free_token(token); type = read_token_item(&token); } arg->type = PRINT_ATOM; arg->atom.atom = atom; break; case EVENT_DQUOTE: case EVENT_SQUOTE: arg->type = PRINT_ATOM; arg->atom.atom = token; type = read_token_item(&token); break; case EVENT_DELIM: if (strcmp(token, "(") == 0) { free_token(token); type = process_paren(event, arg, &token); break; } /* fall through */ case EVENT_OP: /* handle single ops */ arg->type = PRINT_OP; arg->op.op = token; arg->op.left = NULL; type = process_op(event, arg, &token); /* On error, the op is freed */ if (type == EVENT_ERROR) arg->op.op = NULL; /* return error type if errored */ break; case EVENT_ERROR ... EVENT_NEWLINE: default: do_warning_event(event, "unexpected type %d", type); return EVENT_ERROR; } *tok = token; return type; } static int event_read_print_args(struct event_format *event, struct print_arg **list) { enum event_type type = EVENT_ERROR; struct print_arg *arg; char *token; int args = 0; do { if (type == EVENT_NEWLINE) { type = read_token_item(&token); continue; } arg = alloc_arg(); if (!arg) { do_warning_event(event, "%s: not enough memory!", __func__); return -1; } type = process_arg(event, arg, &token); if (type == EVENT_ERROR) { free_token(token); free_arg(arg); return -1; } *list = arg; args++; if (type == EVENT_OP) { type = process_op(event, arg, &token); free_token(token); if (type == EVENT_ERROR) { *list = NULL; free_arg(arg); return -1; } list = &arg->next; continue; } if (type == EVENT_DELIM && strcmp(token, ",") == 0) { free_token(token); *list = arg; list = &arg->next; continue; } break; } while (type != EVENT_NONE); if (type != EVENT_NONE && type != EVENT_ERROR) free_token(token); return args; } static int event_read_print(struct event_format *event) { enum event_type type; char *token; int ret; if (read_expected_item(EVENT_ITEM, "print") < 0) return -1; if (read_expected(EVENT_ITEM, "fmt") < 0) return -1; if (read_expected(EVENT_OP, ":") < 0) return -1; if (read_expect_type(EVENT_DQUOTE, &token) < 0) goto fail; concat: event->print_fmt.format = token; event->print_fmt.args = NULL; /* ok to have no arg */ type = read_token_item(&token); if (type == EVENT_NONE) return 0; /* Handle concatenation of print lines */ if (type == EVENT_DQUOTE) { char *cat; if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0) goto fail; free_token(token); free_token(event->print_fmt.format); event->print_fmt.format = NULL; token = cat; goto concat; } if (test_type_token(type, token, EVENT_DELIM, ",")) goto fail; free_token(token); ret = event_read_print_args(event, &event->print_fmt.args); if (ret < 0) return -1; return ret; fail: free_token(token); return -1; } /** * pevent_find_common_field - return a common field by event * @event: handle for the event * @name: the name of the common field to return * * Returns a common field from the event by the given @name. * This only searchs the common fields and not all field. */ struct format_field * pevent_find_common_field(struct event_format *event, const char *name) { struct format_field *format; for (format = event->format.common_fields; format; format = format->next) { if (strcmp(format->name, name) == 0) break; } return format; } /** * pevent_find_field - find a non-common field * @event: handle for the event * @name: the name of the non-common field * * Returns a non-common field by the given @name. * This does not search common fields. */ struct format_field * pevent_find_field(struct event_format *event, const char *name) { struct format_field *format; for (format = event->format.fields; format; format = format->next) { if (strcmp(format->name, name) == 0) break; } return format; } /** * pevent_find_any_field - find any field by name * @event: handle for the event * @name: the name of the field * * Returns a field by the given @name. * This searchs the common field names first, then * the non-common ones if a common one was not found. */ struct format_field * pevent_find_any_field(struct event_format *event, const char *name) { struct format_field *format; format = pevent_find_common_field(event, name); if (format) return format; return pevent_find_field(event, name); } /** * pevent_read_number - read a number from data * @pevent: handle for the pevent * @ptr: the raw data * @size: the size of the data that holds the number * * Returns the number (converted to host) from the * raw data. */ unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size) { switch (size) { case 1: return *(unsigned char *)ptr; case 2: return data2host2(pevent, ptr); case 4: return data2host4(pevent, ptr); case 8: return data2host8(pevent, ptr); default: /* BUG! */ return 0; } } /** * pevent_read_number_field - read a number from data * @field: a handle to the field * @data: the raw data to read * @value: the value to place the number in * * Reads raw data according to a field offset and size, * and translates it into @value. * * Returns 0 on success, -1 otherwise. */ int pevent_read_number_field(struct format_field *field, const void *data, unsigned long long *value) { if (!field) return -1; switch (field->size) { case 1: case 2: case 4: case 8: *value = pevent_read_number(field->event->pevent, data + field->offset, field->size); return 0; default: return -1; } } static int get_common_info(struct pevent *pevent, const char *type, int *offset, int *size) { struct event_format *event; struct format_field *field; /* * All events should have the same common elements. * Pick any event to find where the type is; */ if (!pevent->events) { do_warning("no event_list!"); return -1; } event = pevent->events[0]; field = pevent_find_common_field(event, type); if (!field) return -1; *offset = field->offset; *size = field->size; return 0; } static int __parse_common(struct pevent *pevent, void *data, int *size, int *offset, const char *name) { int ret; if (!*size) { ret = get_common_info(pevent, name, offset, size); if (ret < 0) return ret; } return pevent_read_number(pevent, data + *offset, *size); } static int trace_parse_common_type(struct pevent *pevent, void *data) { return __parse_common(pevent, data, &pevent->type_size, &pevent->type_offset, "common_type"); } static int parse_common_pid(struct pevent *pevent, void *data) { return __parse_common(pevent, data, &pevent->pid_size, &pevent->pid_offset, "common_pid"); } static int parse_common_pc(struct pevent *pevent, void *data) { return __parse_common(pevent, data, &pevent->pc_size, &pevent->pc_offset, "common_preempt_count"); } static int parse_common_flags(struct pevent *pevent, void *data) { return __parse_common(pevent, data, &pevent->flags_size, &pevent->flags_offset, "common_flags"); } static int parse_common_lock_depth(struct pevent *pevent, void *data) { return __parse_common(pevent, data, &pevent->ld_size, &pevent->ld_offset, "common_lock_depth"); } static int parse_common_migrate_disable(struct pevent *pevent, void *data) { return __parse_common(pevent, data, &pevent->ld_size, &pevent->ld_offset, "common_migrate_disable"); } static int events_id_cmp(const void *a, const void *b); /** * pevent_find_event - find an event by given id * @pevent: a handle to the pevent * @id: the id of the event * * Returns an event that has a given @id. */ struct event_format *pevent_find_event(struct pevent *pevent, int id) { struct event_format **eventptr; struct event_format key; struct event_format *pkey = &key; /* Check cache first */ if (pevent->last_event && pevent->last_event->id == id) return pevent->last_event; key.id = id; eventptr = bsearch(&pkey, pevent->events, pevent->nr_events, sizeof(*pevent->events), events_id_cmp); if (eventptr) { pevent->last_event = *eventptr; return *eventptr; } return NULL; } /** * pevent_find_event_by_name - find an event by given name * @pevent: a handle to the pevent * @sys: the system name to search for * @name: the name of the event to search for * * This returns an event with a given @name and under the system * @sys. If @sys is NULL the first event with @name is returned. */ struct event_format * pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name) { struct event_format *event = NULL; int i; if (pevent->last_event && strcmp(pevent->last_event->name, name) == 0 && (!sys || strcmp(pevent->last_event->system, sys) == 0)) return pevent->last_event; for (i = 0; i < pevent->nr_events; i++) { event = pevent->events[i]; if (strcmp(event->name, name) == 0) { if (!sys) break; if (strcmp(event->system, sys) == 0) break; } } if (i == pevent->nr_events) event = NULL; pevent->last_event = event; return event; } static unsigned long long eval_num_arg(void *data, int size, struct event_format *event, struct print_arg *arg) { struct pevent *pevent = event->pevent; unsigned long long val = 0; unsigned long long left, right; struct print_arg *typearg = NULL; struct print_arg *larg; unsigned long offset; unsigned int field_size; switch (arg->type) { case PRINT_NULL: /* ?? */ return 0; case PRINT_ATOM: return strtoull(arg->atom.atom, NULL, 0); case PRINT_FIELD: if (!arg->field.field) { arg->field.field = pevent_find_any_field(event, arg->field.name); if (!arg->field.field) goto out_warning_field; } /* must be a number */ val = pevent_read_number(pevent, data + arg->field.field->offset, arg->field.field->size); break; case PRINT_FLAGS: case PRINT_SYMBOL: case PRINT_HEX: break; case PRINT_TYPE: val = eval_num_arg(data, size, event, arg->typecast.item); return eval_type(val, arg, 0); case PRINT_STRING: case PRINT_BSTRING: case PRINT_BITMASK: return 0; case PRINT_FUNC: { struct trace_seq s; trace_seq_init(&s); val = process_defined_func(&s, data, size, event, arg); trace_seq_destroy(&s); return val; } case PRINT_OP: if (strcmp(arg->op.op, "[") == 0) { /* * Arrays are special, since we don't want * to read the arg as is. */ right = eval_num_arg(data, size, event, arg->op.right); /* handle typecasts */ larg = arg->op.left; while (larg->type == PRINT_TYPE) { if (!typearg) typearg = larg; larg = larg->typecast.item; } /* Default to long size */ field_size = pevent->long_size; switch (larg->type) { case PRINT_DYNAMIC_ARRAY: offset = pevent_read_number(pevent, data + larg->dynarray.field->offset, larg->dynarray.field->size); if (larg->dynarray.field->elementsize) field_size = larg->dynarray.field->elementsize; /* * The actual length of the dynamic array is stored * in the top half of the field, and the offset * is in the bottom half of the 32 bit field. */ offset &= 0xffff; offset += right; break; case PRINT_FIELD: if (!larg->field.field) { larg->field.field = pevent_find_any_field(event, larg->field.name); if (!larg->field.field) { arg = larg; goto out_warning_field; } } field_size = larg->field.field->elementsize; offset = larg->field.field->offset + right * larg->field.field->elementsize; break; default: goto default_op; /* oops, all bets off */ } val = pevent_read_number(pevent, data + offset, field_size); if (typearg) val = eval_type(val, typearg, 1); break; } else if (strcmp(arg->op.op, "?") == 0) { left = eval_num_arg(data, size, event, arg->op.left); arg = arg->op.right; if (left) val = eval_num_arg(data, size, event, arg->op.left); else val = eval_num_arg(data, size, event, arg->op.right); break; } default_op: left = eval_num_arg(data, size, event, arg->op.left); right = eval_num_arg(data, size, event, arg->op.right); switch (arg->op.op[0]) { case '!': switch (arg->op.op[1]) { case 0: val = !right; break; case '=': val = left != right; break; default: goto out_warning_op; } break; case '~': val = ~right; break; case '|': if (arg->op.op[1]) val = left || right; else val = left | right; break; case '&': if (arg->op.op[1]) val = left && right; else val = left & right; break; case '<': switch (arg->op.op[1]) { case 0: val = left < right; break; case '<': val = left << right; break; case '=': val = left <= right; break; default: goto out_warning_op; } break; case '>': switch (arg->op.op[1]) { case 0: val = left > right; break; case '>': val = left >> right; break; case '=': val = left >= right; break; default: goto out_warning_op; } break; case '=': if (arg->op.op[1] != '=') goto out_warning_op; val = left == right; break; case '-': val = left - right; break; case '+': val = left + right; break; case '/': val = left / right; break; case '*': val = left * right; break; default: goto out_warning_op; } break; case PRINT_DYNAMIC_ARRAY: /* Without [], we pass the address to the dynamic data */ offset = pevent_read_number(pevent, data + arg->dynarray.field->offset, arg->dynarray.field->size); /* * The actual length of the dynamic array is stored * in the top half of the field, and the offset * is in the bottom half of the 32 bit field. */ offset &= 0xffff; val = (unsigned long long)((unsigned long)data + offset); break; default: /* not sure what to do there */ return 0; } return val; out_warning_op: do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op); return 0; out_warning_field: do_warning_event(event, "%s: field %s not found", __func__, arg->field.name); return 0; } struct flag { const char *name; unsigned long long value; }; static const struct flag flags[] = { { "HI_SOFTIRQ", 0 }, { "TIMER_SOFTIRQ", 1 }, { "NET_TX_SOFTIRQ", 2 }, { "NET_RX_SOFTIRQ", 3 }, { "BLOCK_SOFTIRQ", 4 }, { "BLOCK_IOPOLL_SOFTIRQ", 5 }, { "TASKLET_SOFTIRQ", 6 }, { "SCHED_SOFTIRQ", 7 }, { "HRTIMER_SOFTIRQ", 8 }, { "RCU_SOFTIRQ", 9 }, { "HRTIMER_NORESTART", 0 }, { "HRTIMER_RESTART", 1 }, }; static unsigned long long eval_flag(const char *flag) { int i; /* * Some flags in the format files do not get converted. * If the flag is not numeric, see if it is something that * we already know about. */ if (isdigit(flag[0])) return strtoull(flag, NULL, 0); for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) if (strcmp(flags[i].name, flag) == 0) return flags[i].value; return 0; } static void print_str_to_seq(struct trace_seq *s, const char *format, int len_arg, const char *str) { if (len_arg >= 0) trace_seq_printf(s, format, len_arg, str); else trace_seq_printf(s, format, str); } static void print_bitmask_to_seq(struct pevent *pevent, struct trace_seq *s, const char *format, int len_arg, const void *data, int size) { int nr_bits = size * 8; int str_size = (nr_bits + 3) / 4; int len = 0; char buf[3]; char *str; int index; int i; /* * The kernel likes to put in commas every 32 bits, we * can do the same. */ str_size += (nr_bits - 1) / 32; str = malloc(str_size + 1); if (!str) { do_warning("%s: not enough memory!", __func__); return; } str[str_size] = 0; /* Start out with -2 for the two chars per byte */ for (i = str_size - 2; i >= 0; i -= 2) { /* * data points to a bit mask of size bytes. * In the kernel, this is an array of long words, thus * endianess is very important. */ if (pevent->file_bigendian) index = size - (len + 1); else index = len; snprintf(buf, 3, "%02x", *((unsigned char *)data + index)); memcpy(str + i, buf, 2); len++; if (!(len & 3) && i > 0) { i--; str[i] = ','; } } if (len_arg >= 0) trace_seq_printf(s, format, len_arg, str); else trace_seq_printf(s, format, str); free(str); } static void print_str_arg(struct trace_seq *s, void *data, int size, struct event_format *event, const char *format, int len_arg, struct print_arg *arg) { struct pevent *pevent = event->pevent; struct print_flag_sym *flag; struct format_field *field; struct printk_map *printk; unsigned long long val, fval; unsigned long addr; char *str; unsigned char *hex; int print; int i, len; switch (arg->type) { case PRINT_NULL: /* ?? */ return; case PRINT_ATOM: print_str_to_seq(s, format, len_arg, arg->atom.atom); return; case PRINT_FIELD: field = arg->field.field; if (!field) { field = pevent_find_any_field(event, arg->field.name); if (!field) { str = arg->field.name; goto out_warning_field; } arg->field.field = field; } /* Zero sized fields, mean the rest of the data */ len = field->size ? : size - field->offset; /* * Some events pass in pointers. If this is not an array * and the size is the same as long_size, assume that it * is a pointer. */ if (!(field->flags & FIELD_IS_ARRAY) && field->size == pevent->long_size) { addr = *(unsigned long *)(data + field->offset); /* Check if it matches a print format */ printk = find_printk(pevent, addr); if (printk) trace_seq_puts(s, printk->printk); else trace_seq_printf(s, "%lx", addr); break; } str = malloc(len + 1); if (!str) { do_warning_event(event, "%s: not enough memory!", __func__); return; } memcpy(str, data + field->offset, len); str[len] = 0; print_str_to_seq(s, format, len_arg, str); free(str); break; case PRINT_FLAGS: val = eval_num_arg(data, size, event, arg->flags.field); print = 0; for (flag = arg->flags.flags; flag; flag = flag->next) { fval = eval_flag(flag->value); if (!val && !fval) { print_str_to_seq(s, format, len_arg, flag->str); break; } if (fval && (val & fval) == fval) { if (print && arg->flags.delim) trace_seq_puts(s, arg->flags.delim); print_str_to_seq(s, format, len_arg, flag->str); print = 1; val &= ~fval; } } break; case PRINT_SYMBOL: val = eval_num_arg(data, size, event, arg->symbol.field); for (flag = arg->symbol.symbols; flag; flag = flag->next) { fval = eval_flag(flag->value); if (val == fval) { print_str_to_seq(s, format, len_arg, flag->str); break; } } break; case PRINT_HEX: if (arg->hex.field->type == PRINT_DYNAMIC_ARRAY) { unsigned long offset; offset = pevent_read_number(pevent, data + arg->hex.field->dynarray.field->offset, arg->hex.field->dynarray.field->size); hex = data + (offset & 0xffff); } else { field = arg->hex.field->field.field; if (!field) { str = arg->hex.field->field.name; field = pevent_find_any_field(event, str); if (!field) goto out_warning_field; arg->hex.field->field.field = field; } hex = data + field->offset; } len = eval_num_arg(data, size, event, arg->hex.size); for (i = 0; i < len; i++) { if (i) trace_seq_putc(s, ' '); trace_seq_printf(s, "%02x", hex[i]); } break; case PRINT_TYPE: break; case PRINT_STRING: { int str_offset; if (arg->string.offset == -1) { struct format_field *f; f = pevent_find_any_field(event, arg->string.string); arg->string.offset = f->offset; } str_offset = data2host4(pevent, data + arg->string.offset); str_offset &= 0xffff; print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset); break; } case PRINT_BSTRING: print_str_to_seq(s, format, len_arg, arg->string.string); break; case PRINT_BITMASK: { int bitmask_offset; int bitmask_size; if (arg->bitmask.offset == -1) { struct format_field *f; f = pevent_find_any_field(event, arg->bitmask.bitmask); arg->bitmask.offset = f->offset; } bitmask_offset = data2host4(pevent, data + arg->bitmask.offset); bitmask_size = bitmask_offset >> 16; bitmask_offset &= 0xffff; print_bitmask_to_seq(pevent, s, format, len_arg, data + bitmask_offset, bitmask_size); break; } case PRINT_OP: /* * The only op for string should be ? : */ if (arg->op.op[0] != '?') return; val = eval_num_arg(data, size, event, arg->op.left); if (val) print_str_arg(s, data, size, event, format, len_arg, arg->op.right->op.left); else print_str_arg(s, data, size, event, format, len_arg, arg->op.right->op.right); break; case PRINT_FUNC: process_defined_func(s, data, size, event, arg); break; default: /* well... */ break; } return; out_warning_field: do_warning_event(event, "%s: field %s not found", __func__, arg->field.name); } static unsigned long long process_defined_func(struct trace_seq *s, void *data, int size, struct event_format *event, struct print_arg *arg) { struct pevent_function_handler *func_handle = arg->func.func; struct pevent_func_params *param; unsigned long long *args; unsigned long long ret; struct print_arg *farg; struct trace_seq str; struct save_str { struct save_str *next; char *str; } *strings = NULL, *string; int i; if (!func_handle->nr_args) { ret = (*func_handle->func)(s, NULL); goto out; } farg = arg->func.args; param = func_handle->params; ret = ULLONG_MAX; args = malloc(sizeof(*args) * func_handle->nr_args); if (!args) goto out; for (i = 0; i < func_handle->nr_args; i++) { switch (param->type) { case PEVENT_FUNC_ARG_INT: case PEVENT_FUNC_ARG_LONG: case PEVENT_FUNC_ARG_PTR: args[i] = eval_num_arg(data, size, event, farg); break; case PEVENT_FUNC_ARG_STRING: trace_seq_init(&str); print_str_arg(&str, data, size, event, "%s", -1, farg); trace_seq_terminate(&str); string = malloc(sizeof(*string)); if (!string) { do_warning_event(event, "%s(%d): malloc str", __func__, __LINE__); goto out_free; } string->next = strings; string->str = strdup(str.buffer); if (!string->str) { free(string); do_warning_event(event, "%s(%d): malloc str", __func__, __LINE__); goto out_free; } args[i] = (uintptr_t)string->str; strings = string; trace_seq_destroy(&str); break; default: /* * Something went totally wrong, this is not * an input error, something in this code broke. */ do_warning_event(event, "Unexpected end of arguments\n"); goto out_free; } farg = farg->next; param = param->next; } ret = (*func_handle->func)(s, args); out_free: free(args); while (strings) { string = strings; strings = string->next; free(string->str); free(string); } out: /* TBD : handle return type here */ return ret; } static void free_args(struct print_arg *args) { struct print_arg *next; while (args) { next = args->next; free_arg(args); args = next; } } static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event) { struct pevent *pevent = event->pevent; struct format_field *field, *ip_field; struct print_arg *args, *arg, **next; unsigned long long ip, val; char *ptr; void *bptr; int vsize; field = pevent->bprint_buf_field; ip_field = pevent->bprint_ip_field; if (!field) { field = pevent_find_field(event, "buf"); if (!field) { do_warning_event(event, "can't find buffer field for binary printk"); return NULL; } ip_field = pevent_find_field(event, "ip"); if (!ip_field) { do_warning_event(event, "can't find ip field for binary printk"); return NULL; } pevent->bprint_buf_field = field; pevent->bprint_ip_field = ip_field; } ip = pevent_read_number(pevent, data + ip_field->offset, ip_field->size); /* * The first arg is the IP pointer. */ args = alloc_arg(); if (!args) { do_warning_event(event, "%s(%d): not enough memory!", __func__, __LINE__); return NULL; } arg = args; arg->next = NULL; next = &arg->next; arg->type = PRINT_ATOM; if (asprintf(&arg->atom.atom, "%lld", ip) < 0) goto out_free; /* skip the first "%pf: " */ for (ptr = fmt + 5, bptr = data + field->offset; bptr < data + size && *ptr; ptr++) { int ls = 0; if (*ptr == '%') { process_again: ptr++; switch (*ptr) { case '%': break; case 'l': ls++; goto process_again; case 'L': ls = 2; goto process_again; case '0' ... '9': goto process_again; case '.': goto process_again; case 'p': ls = 1; /* fall through */ case 'd': case 'u': case 'x': case 'i': switch (ls) { case 0: vsize = 4; break; case 1: vsize = pevent->long_size; break; case 2: vsize = 8; break; default: vsize = ls; /* ? */ break; } /* fall through */ case '*': if (*ptr == '*') vsize = 4; /* the pointers are always 4 bytes aligned */ bptr = (void *)(((unsigned long)bptr + 3) & ~3); val = pevent_read_number(pevent, bptr, vsize); bptr += vsize; arg = alloc_arg(); if (!arg) { do_warning_event(event, "%s(%d): not enough memory!", __func__, __LINE__); goto out_free; } arg->next = NULL; arg->type = PRINT_ATOM; if (asprintf(&arg->atom.atom, "%lld", val) < 0) { free(arg); goto out_free; } *next = arg; next = &arg->next; /* * The '*' case means that an arg is used as the length. * We need to continue to figure out for what. */ if (*ptr == '*') goto process_again; break; case 's': arg = alloc_arg(); if (!arg) { do_warning_event(event, "%s(%d): not enough memory!", __func__, __LINE__); goto out_free; } arg->next = NULL; arg->type = PRINT_BSTRING; arg->string.string = strdup(bptr); if (!arg->string.string) goto out_free; bptr += strlen(bptr) + 1; *next = arg; next = &arg->next; default: break; } } } return args; out_free: free_args(args); return NULL; } static char * get_bprint_format(void *data, int size __maybe_unused, struct event_format *event) { struct pevent *pevent = event->pevent; unsigned long long addr; struct format_field *field; struct printk_map *printk; char *format; field = pevent->bprint_fmt_field; if (!field) { field = pevent_find_field(event, "fmt"); if (!field) { do_warning_event(event, "can't find format field for binary printk"); return NULL; } pevent->bprint_fmt_field = field; } addr = pevent_read_number(pevent, data + field->offset, field->size); printk = find_printk(pevent, addr); if (!printk) { if (asprintf(&format, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0) return NULL; return format; } if (asprintf(&format, "%s: %s", "%pf", printk->printk) < 0) return NULL; return format; } static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, struct event_format *event, struct print_arg *arg) { unsigned char *buf; const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"; if (arg->type == PRINT_FUNC) { process_defined_func(s, data, size, event, arg); return; } if (arg->type != PRINT_FIELD) { trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type); return; } if (mac == 'm') fmt = "%.2x%.2x%.2x%.2x%.2x%.2x"; if (!arg->field.field) { arg->field.field = pevent_find_any_field(event, arg->field.name); if (!arg->field.field) { do_warning_event(event, "%s: field %s not found", __func__, arg->field.name); return; } } if (arg->field.field->size != 6) { trace_seq_printf(s, "INVALIDMAC"); return; } buf = data + arg->field.field->offset; trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); } static int is_printable_array(char *p, unsigned int len) { unsigned int i; for (i = 0; i < len && p[i]; i++) if (!isprint(p[i]) && !isspace(p[i])) return 0; return 1; } static void print_event_fields(struct trace_seq *s, void *data, int size __maybe_unused, struct event_format *event) { struct format_field *field; unsigned long long val; unsigned int offset, len, i; field = event->format.fields; while (field) { trace_seq_printf(s, " %s=", field->name); if (field->flags & FIELD_IS_ARRAY) { offset = field->offset; len = field->size; if (field->flags & FIELD_IS_DYNAMIC) { val = pevent_read_number(event->pevent, data + offset, len); offset = val; len = offset >> 16; offset &= 0xffff; } if (field->flags & FIELD_IS_STRING && is_printable_array(data + offset, len)) { trace_seq_printf(s, "%s", (char *)data + offset); } else { trace_seq_puts(s, "ARRAY["); for (i = 0; i < len; i++) { if (i) trace_seq_puts(s, ", "); trace_seq_printf(s, "%02x", *((unsigned char *)data + offset + i)); } trace_seq_putc(s, ']'); field->flags &= ~FIELD_IS_STRING; } } else { val = pevent_read_number(event->pevent, data + field->offset, field->size); if (field->flags & FIELD_IS_POINTER) { trace_seq_printf(s, "0x%llx", val); } else if (field->flags & FIELD_IS_SIGNED) { switch (field->size) { case 4: /* * If field is long then print it in hex. * A long usually stores pointers. */ if (field->flags & FIELD_IS_LONG) trace_seq_printf(s, "0x%x", (int)val); else trace_seq_printf(s, "%d", (int)val); break; case 2: trace_seq_printf(s, "%2d", (short)val); break; case 1: trace_seq_printf(s, "%1d", (char)val); break; default: trace_seq_printf(s, "%lld", val); } } else { if (field->flags & FIELD_IS_LONG) trace_seq_printf(s, "0x%llx", val); else trace_seq_printf(s, "%llu", val); } } field = field->next; } } static void pretty_print(struct trace_seq *s, void *data, int size, struct event_format *event) { struct pevent *pevent = event->pevent; struct print_fmt *print_fmt = &event->print_fmt; struct print_arg *arg = print_fmt->args; struct print_arg *args = NULL; const char *ptr = print_fmt->format; unsigned long long val; struct func_map *func; const char *saveptr; struct trace_seq p; char *bprint_fmt = NULL; char format[32]; int show_func; int len_as_arg; int len_arg = 0; int len; int ls; if (event->flags & EVENT_FL_FAILED) { trace_seq_printf(s, "[FAILED TO PARSE]"); print_event_fields(s, data, size, event); return; } if (event->flags & EVENT_FL_ISBPRINT) { bprint_fmt = get_bprint_format(data, size, event); args = make_bprint_args(bprint_fmt, data, size, event); arg = args; ptr = bprint_fmt; } for (; *ptr; ptr++) { ls = 0; if (*ptr == '\\') { ptr++; switch (*ptr) { case 'n': trace_seq_putc(s, '\n'); break; case 't': trace_seq_putc(s, '\t'); break; case 'r': trace_seq_putc(s, '\r'); break; case '\\': trace_seq_putc(s, '\\'); break; default: trace_seq_putc(s, *ptr); break; } } else if (*ptr == '%') { saveptr = ptr; show_func = 0; len_as_arg = 0; cont_process: ptr++; switch (*ptr) { case '%': trace_seq_putc(s, '%'); break; case '#': /* FIXME: need to handle properly */ goto cont_process; case 'h': ls--; goto cont_process; case 'l': ls++; goto cont_process; case 'L': ls = 2; goto cont_process; case '*': /* The argument is the length. */ if (!arg) { do_warning_event(event, "no argument match"); event->flags |= EVENT_FL_FAILED; goto out_failed; } len_arg = eval_num_arg(data, size, event, arg); len_as_arg = 1; arg = arg->next; goto cont_process; case '.': case 'z': case 'Z': case '0' ... '9': goto cont_process; case 'p': if (pevent->long_size == 4) ls = 1; else ls = 2; if (*(ptr+1) == 'F' || *(ptr+1) == 'f') { ptr++; show_func = *ptr; } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { print_mac_arg(s, *(ptr+1), data, size, event, arg); ptr++; arg = arg->next; break; } /* fall through */ case 'd': case 'i': case 'x': case 'X': case 'u': if (!arg) { do_warning_event(event, "no argument match"); event->flags |= EVENT_FL_FAILED; goto out_failed; } len = ((unsigned long)ptr + 1) - (unsigned long)saveptr; /* should never happen */ if (len > 31) { do_warning_event(event, "bad format!"); event->flags |= EVENT_FL_FAILED; len = 31; } memcpy(format, saveptr, len); format[len] = 0; val = eval_num_arg(data, size, event, arg); arg = arg->next; if (show_func) { func = find_func(pevent, val); if (func) { trace_seq_puts(s, func->func); if (show_func == 'F') trace_seq_printf(s, "+0x%llx", val - func->addr); break; } } if (pevent->long_size == 8 && ls && sizeof(long) != 8) { char *p; ls = 2; /* make %l into %ll */ p = strchr(format, 'l'); if (p) memmove(p+1, p, strlen(p)+1); else if (strcmp(format, "%p") == 0) strcpy(format, "0x%llx"); } switch (ls) { case -2: if (len_as_arg) trace_seq_printf(s, format, len_arg, (char)val); else trace_seq_printf(s, format, (char)val); break; case -1: if (len_as_arg) trace_seq_printf(s, format, len_arg, (short)val); else trace_seq_printf(s, format, (short)val); break; case 0: if (len_as_arg) trace_seq_printf(s, format, len_arg, (int)val); else trace_seq_printf(s, format, (int)val); break; case 1: if (len_as_arg) trace_seq_printf(s, format, len_arg, (long)val); else trace_seq_printf(s, format, (long)val); break; case 2: if (len_as_arg) trace_seq_printf(s, format, len_arg, (long long)val); else trace_seq_printf(s, format, (long long)val); break; default: do_warning_event(event, "bad count (%d)", ls); event->flags |= EVENT_FL_FAILED; } break; case 's': if (!arg) { do_warning_event(event, "no matching argument"); event->flags |= EVENT_FL_FAILED; goto out_failed; } len = ((unsigned long)ptr + 1) - (unsigned long)saveptr; /* should never happen */ if (len > 31) { do_warning_event(event, "bad format!"); event->flags |= EVENT_FL_FAILED; len = 31; } memcpy(format, saveptr, len); format[len] = 0; if (!len_as_arg) len_arg = -1; /* Use helper trace_seq */ trace_seq_init(&p); print_str_arg(&p, data, size, event, format, len_arg, arg); trace_seq_terminate(&p); trace_seq_puts(s, p.buffer); trace_seq_destroy(&p); arg = arg->next; break; default: trace_seq_printf(s, ">%c<", *ptr); } } else trace_seq_putc(s, *ptr); } if (event->flags & EVENT_FL_FAILED) { out_failed: trace_seq_printf(s, "[FAILED TO PARSE]"); } if (args) { free_args(args); free(bprint_fmt); } } /** * pevent_data_lat_fmt - parse the data for the latency format * @pevent: a handle to the pevent * @s: the trace_seq to write to * @record: the record to read from * * This parses out the Latency format (interrupts disabled, * need rescheduling, in hard/soft interrupt, preempt count * and lock depth) and places it into the trace_seq. */ void pevent_data_lat_fmt(struct pevent *pevent, struct trace_seq *s, struct pevent_record *record) { static int check_lock_depth = 1; static int check_migrate_disable = 1; static int lock_depth_exists; static int migrate_disable_exists; unsigned int lat_flags; unsigned int pc; int lock_depth = -1; int migrate_disable = 0; int hardirq; int softirq; void *data = record->data; lat_flags = parse_common_flags(pevent, data); pc = parse_common_pc(pevent, data); /* lock_depth may not always exist */ if (lock_depth_exists) lock_depth = parse_common_lock_depth(pevent, data); else if (check_lock_depth) { lock_depth = parse_common_lock_depth(pevent, data); if (lock_depth < 0) check_lock_depth = 0; else lock_depth_exists = 1; } /* migrate_disable may not always exist */ if (migrate_disable_exists) migrate_disable = parse_common_migrate_disable(pevent, data); else if (check_migrate_disable) { migrate_disable = parse_common_migrate_disable(pevent, data); if (migrate_disable < 0) check_migrate_disable = 0; else migrate_disable_exists = 1; } hardirq = lat_flags & TRACE_FLAG_HARDIRQ; softirq = lat_flags & TRACE_FLAG_SOFTIRQ; trace_seq_printf(s, "%c%c%c", (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' : '.', (lat_flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.', (hardirq && softirq) ? 'H' : hardirq ? 'h' : softirq ? 's' : '.'); if (pc) trace_seq_printf(s, "%x", pc); else trace_seq_putc(s, '.'); if (migrate_disable_exists) { if (migrate_disable < 0) trace_seq_putc(s, '.'); else trace_seq_printf(s, "%d", migrate_disable); } if (lock_depth_exists) { if (lock_depth < 0) trace_seq_putc(s, '.'); else trace_seq_printf(s, "%d", lock_depth); } trace_seq_terminate(s); } /** * pevent_data_type - parse out the given event type * @pevent: a handle to the pevent * @rec: the record to read from * * This returns the event id from the @rec. */ int pevent_data_type(struct pevent *pevent, struct pevent_record *rec) { return trace_parse_common_type(pevent, rec->data); } /** * pevent_data_event_from_type - find the event by a given type * @pevent: a handle to the pevent * @type: the type of the event. * * This returns the event form a given @type; */ struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type) { return pevent_find_event(pevent, type); } /** * pevent_data_pid - parse the PID from raw data * @pevent: a handle to the pevent * @rec: the record to parse * * This returns the PID from a raw data. */ int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec) { return parse_common_pid(pevent, rec->data); } /** * pevent_data_comm_from_pid - return the command line from PID * @pevent: a handle to the pevent * @pid: the PID of the task to search for * * This returns a pointer to the command line that has the given * @pid. */ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid) { const char *comm; comm = find_cmdline(pevent, pid); return comm; } /** * pevent_data_comm_from_pid - parse the data into the print format * @s: the trace_seq to write to * @event: the handle to the event * @record: the record to read from * * This parses the raw @data using the given @event information and * writes the print format into the trace_seq. */ void pevent_event_info(struct trace_seq *s, struct event_format *event, struct pevent_record *record) { int print_pretty = 1; if (event->pevent->print_raw || (event->flags & EVENT_FL_PRINTRAW)) print_event_fields(s, record->data, record->size, event); else { if (event->handler && !(event->flags & EVENT_FL_NOHANDLE)) print_pretty = event->handler(s, record, event, event->context); if (print_pretty) pretty_print(s, record->data, record->size, event); } trace_seq_terminate(s); } static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock) { if (!use_trace_clock) return true; if (!strcmp(trace_clock, "local") || !strcmp(trace_clock, "global") || !strcmp(trace_clock, "uptime") || !strcmp(trace_clock, "perf")) return true; /* trace_clock is setting in tsc or counter mode */ return false; } void pevent_print_event(struct pevent *pevent, struct trace_seq *s, struct pevent_record *record, bool use_trace_clock) { static const char *spaces = " "; /* 20 spaces */ struct event_format *event; unsigned long secs; unsigned long usecs; unsigned long nsecs; const char *comm; void *data = record->data; int type; int pid; int len; int p; bool use_usec_format; use_usec_format = is_timestamp_in_us(pevent->trace_clock, use_trace_clock); if (use_usec_format) { secs = record->ts / NSECS_PER_SEC; nsecs = record->ts - secs * NSECS_PER_SEC; } if (record->size < 0) { do_warning("ug! negative record size %d", record->size); return; } type = trace_parse_common_type(pevent, data); event = pevent_find_event(pevent, type); if (!event) { do_warning("ug! no event found for type %d", type); return; } pid = parse_common_pid(pevent, data); comm = find_cmdline(pevent, pid); if (pevent->latency_format) { trace_seq_printf(s, "%8.8s-%-5d %3d", comm, pid, record->cpu); pevent_data_lat_fmt(pevent, s, record); } else trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu); if (use_usec_format) { if (pevent->flags & PEVENT_NSEC_OUTPUT) { usecs = nsecs; p = 9; } else { usecs = (nsecs + 500) / NSECS_PER_USEC; p = 6; } trace_seq_printf(s, " %5lu.%0*lu: %s: ", secs, p, usecs, event->name); } else trace_seq_printf(s, " %12llu: %s: ", record->ts, event->name); /* Space out the event names evenly. */ len = strlen(event->name); if (len < 20) trace_seq_printf(s, "%.*s", 20 - len, spaces); pevent_event_info(s, event, record); } static int events_id_cmp(const void *a, const void *b) { struct event_format * const * ea = a; struct event_format * const * eb = b; if ((*ea)->id < (*eb)->id) return -1; if ((*ea)->id > (*eb)->id) return 1; return 0; } static int events_name_cmp(const void *a, const void *b) { struct event_format * const * ea = a; struct event_format * const * eb = b; int res; res = strcmp((*ea)->name, (*eb)->name); if (res) return res; res = strcmp((*ea)->system, (*eb)->system); if (res) return res; return events_id_cmp(a, b); } static int events_system_cmp(const void *a, const void *b) { struct event_format * const * ea = a; struct event_format * const * eb = b; int res; res = strcmp((*ea)->system, (*eb)->system); if (res) return res; res = strcmp((*ea)->name, (*eb)->name); if (res) return res; return events_id_cmp(a, b); } struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type sort_type) { struct event_format **events; int (*sort)(const void *a, const void *b); events = pevent->sort_events; if (events && pevent->last_type == sort_type) return events; if (!events) { events = malloc(sizeof(*events) * (pevent->nr_events + 1)); if (!events) return NULL; memcpy(events, pevent->events, sizeof(*events) * pevent->nr_events); events[pevent->nr_events] = NULL; pevent->sort_events = events; /* the internal events are sorted by id */ if (sort_type == EVENT_SORT_ID) { pevent->last_type = sort_type; return events; } } switch (sort_type) { case EVENT_SORT_ID: sort = events_id_cmp; break; case EVENT_SORT_NAME: sort = events_name_cmp; break; case EVENT_SORT_SYSTEM: sort = events_system_cmp; break; default: return events; } qsort(events, pevent->nr_events, sizeof(*events), sort); pevent->last_type = sort_type; return events; } static struct format_field ** get_event_fields(const char *type, const char *name, int count, struct format_field *list) { struct format_field **fields; struct format_field *field; int i = 0; fields = malloc(sizeof(*fields) * (count + 1)); if (!fields) return NULL; for (field = list; field; field = field->next) { fields[i++] = field; if (i == count + 1) { do_warning("event %s has more %s fields than specified", name, type); i--; break; } } if (i != count) do_warning("event %s has less %s fields than specified", name, type); fields[i] = NULL; return fields; } /** * pevent_event_common_fields - return a list of common fields for an event * @event: the event to return the common fields of. * * Returns an allocated array of fields. The last item in the array is NULL. * The array must be freed with free(). */ struct format_field **pevent_event_common_fields(struct event_format *event) { return get_event_fields("common", event->name, event->format.nr_common, event->format.common_fields); } /** * pevent_event_fields - return a list of event specific fields for an event * @event: the event to return the fields of. * * Returns an allocated array of fields. The last item in the array is NULL. * The array must be freed with free(). */ struct format_field **pevent_event_fields(struct event_format *event) { return get_event_fields("event", event->name, event->format.nr_fields, event->format.fields); } static void print_fields(struct trace_seq *s, struct print_flag_sym *field) { trace_seq_printf(s, "{ %s, %s }", field->value, field->str); if (field->next) { trace_seq_puts(s, ", "); print_fields(s, field->next); } } /* for debugging */ static void print_args(struct print_arg *args) { int print_paren = 1; struct trace_seq s; switch (args->type) { case PRINT_NULL: printf("null"); break; case PRINT_ATOM: printf("%s", args->atom.atom); break; case PRINT_FIELD: printf("REC->%s", args->field.name); break; case PRINT_FLAGS: printf("__print_flags("); print_args(args->flags.field); printf(", %s, ", args->flags.delim); trace_seq_init(&s); print_fields(&s, args->flags.flags); trace_seq_do_printf(&s); trace_seq_destroy(&s); printf(")"); break; case PRINT_SYMBOL: printf("__print_symbolic("); print_args(args->symbol.field); printf(", "); trace_seq_init(&s); print_fields(&s, args->symbol.symbols); trace_seq_do_printf(&s); trace_seq_destroy(&s); printf(")"); break; case PRINT_HEX: printf("__print_hex("); print_args(args->hex.field); printf(", "); print_args(args->hex.size); printf(")"); break; case PRINT_STRING: case PRINT_BSTRING: printf("__get_str(%s)", args->string.string); break; case PRINT_BITMASK: printf("__get_bitmask(%s)", args->bitmask.bitmask); break; case PRINT_TYPE: printf("(%s)", args->typecast.type); print_args(args->typecast.item); break; case PRINT_OP: if (strcmp(args->op.op, ":") == 0) print_paren = 0; if (print_paren) printf("("); print_args(args->op.left); printf(" %s ", args->op.op); print_args(args->op.right); if (print_paren) printf(")"); break; default: /* we should warn... */ return; } if (args->next) { printf("\n"); print_args(args->next); } } static void parse_header_field(const char *field, int *offset, int *size, int mandatory) { unsigned long long save_input_buf_ptr; unsigned long long save_input_buf_siz; char *token; int type; save_input_buf_ptr = input_buf_ptr; save_input_buf_siz = input_buf_siz; if (read_expected(EVENT_ITEM, "field") < 0) return; if (read_expected(EVENT_OP, ":") < 0) return; /* type */ if (read_expect_type(EVENT_ITEM, &token) < 0) goto fail; free_token(token); /* * If this is not a mandatory field, then test it first. */ if (mandatory) { if (read_expected(EVENT_ITEM, field) < 0) return; } else { if (read_expect_type(EVENT_ITEM, &token) < 0) goto fail; if (strcmp(token, field) != 0) goto discard; free_token(token); } if (read_expected(EVENT_OP, ";") < 0) return; if (read_expected(EVENT_ITEM, "offset") < 0) return; if (read_expected(EVENT_OP, ":") < 0) return; if (read_expect_type(EVENT_ITEM, &token) < 0) goto fail; *offset = atoi(token); free_token(token); if (read_expected(EVENT_OP, ";") < 0) return; if (read_expected(EVENT_ITEM, "size") < 0) return; if (read_expected(EVENT_OP, ":") < 0) return; if (read_expect_type(EVENT_ITEM, &token) < 0) goto fail; *size = atoi(token); free_token(token); if (read_expected(EVENT_OP, ";") < 0) return; type = read_token(&token); if (type != EVENT_NEWLINE) { /* newer versions of the kernel have a "signed" type */ if (type != EVENT_ITEM) goto fail; if (strcmp(token, "signed") != 0) goto fail; free_token(token); if (read_expected(EVENT_OP, ":") < 0) return; if (read_expect_type(EVENT_ITEM, &token)) goto fail; free_token(token); if (read_expected(EVENT_OP, ";") < 0) return; if (read_expect_type(EVENT_NEWLINE, &token)) goto fail; } fail: free_token(token); return; discard: input_buf_ptr = save_input_buf_ptr; input_buf_siz = save_input_buf_siz; *offset = 0; *size = 0; free_token(token); } /** * pevent_parse_header_page - parse the data stored in the header page * @pevent: the handle to the pevent * @buf: the buffer storing the header page format string * @size: the size of @buf * @long_size: the long size to use if there is no header * * This parses the header page format for information on the * ring buffer used. The @buf should be copied from * * /sys/kernel/debug/tracing/events/header_page */ int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size, int long_size) { int ignore; if (!size) { /* * Old kernels did not have header page info. * Sorry but we just use what we find here in user space. */ pevent->header_page_ts_size = sizeof(long long); pevent->header_page_size_size = long_size; pevent->header_page_data_offset = sizeof(long long) + long_size; pevent->old_format = 1; return -1; } init_input_buf(buf, size); parse_header_field("timestamp", &pevent->header_page_ts_offset, &pevent->header_page_ts_size, 1); parse_header_field("commit", &pevent->header_page_size_offset, &pevent->header_page_size_size, 1); parse_header_field("overwrite", &pevent->header_page_overwrite, &ignore, 0); parse_header_field("data", &pevent->header_page_data_offset, &pevent->header_page_data_size, 1); return 0; } static int event_matches(struct event_format *event, int id, const char *sys_name, const char *event_name) { if (id >= 0 && id != event->id) return 0; if (event_name && (strcmp(event_name, event->name) != 0)) return 0; if (sys_name && (strcmp(sys_name, event->system) != 0)) return 0; return 1; } static void free_handler(struct event_handler *handle) { free((void *)handle->sys_name); free((void *)handle->event_name); free(handle); } static int find_event_handle(struct pevent *pevent, struct event_format *event) { struct event_handler *handle, **next; for (next = &pevent->handlers; *next; next = &(*next)->next) { handle = *next; if (event_matches(event, handle->id, handle->sys_name, handle->event_name)) break; } if (!(*next)) return 0; // pr_stat("overriding event (%d) %s:%s with new print handler", // event->id, event->system, event->name); event->handler = handle->func; event->context = handle->context; *next = handle->next; free_handler(handle); return 1; } /** * __pevent_parse_format - parse the event format * @buf: the buffer storing the event format string * @size: the size of @buf * @sys: the system the event belongs to * * This parses the event format and creates an event structure * to quickly parse raw data for a given event. * * These files currently come from: * * /sys/kernel/debug/tracing/events/.../.../format */ enum pevent_errno __pevent_parse_format(struct event_format **eventp, struct pevent *pevent, const char *buf, unsigned long size, const char *sys) { struct event_format *event; int ret; init_input_buf(buf, size); *eventp = event = alloc_event(); if (!event) return PEVENT_ERRNO__MEM_ALLOC_FAILED; event->name = event_read_name(); if (!event->name) { /* Bad event? */ ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; goto event_alloc_failed; } if (strcmp(sys, "ftrace") == 0) { event->flags |= EVENT_FL_ISFTRACE; if (strcmp(event->name, "bprint") == 0) event->flags |= EVENT_FL_ISBPRINT; } event->id = event_read_id(); if (event->id < 0) { ret = PEVENT_ERRNO__READ_ID_FAILED; /* * This isn't an allocation error actually. * But as the ID is critical, just bail out. */ goto event_alloc_failed; } event->system = strdup(sys); if (!event->system) { ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; goto event_alloc_failed; } /* Add pevent to event so that it can be referenced */ event->pevent = pevent; ret = event_read_format(event); if (ret < 0) { ret = PEVENT_ERRNO__READ_FORMAT_FAILED; goto event_parse_failed; } /* * If the event has an override, don't print warnings if the event * print format fails to parse. */ if (pevent && find_event_handle(pevent, event)) show_warning = 0; ret = event_read_print(event); show_warning = 1; if (ret < 0) { ret = PEVENT_ERRNO__READ_PRINT_FAILED; goto event_parse_failed; } if (!ret && (event->flags & EVENT_FL_ISFTRACE)) { struct format_field *field; struct print_arg *arg, **list; /* old ftrace had no args */ list = &event->print_fmt.args; for (field = event->format.fields; field; field = field->next) { arg = alloc_arg(); if (!arg) { event->flags |= EVENT_FL_FAILED; return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; } arg->type = PRINT_FIELD; arg->field.name = strdup(field->name); if (!arg->field.name) { event->flags |= EVENT_FL_FAILED; free_arg(arg); return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; } arg->field.field = field; *list = arg; list = &arg->next; } return 0; } return 0; event_parse_failed: event->flags |= EVENT_FL_FAILED; return ret; event_alloc_failed: free(event->system); free(event->name); free(event); *eventp = NULL; return ret; } static enum pevent_errno __pevent_parse_event(struct pevent *pevent, struct event_format **eventp, const char *buf, unsigned long size, const char *sys) { int ret = __pevent_parse_format(eventp, pevent, buf, size, sys); struct event_format *event = *eventp; if (event == NULL) return ret; if (pevent && add_event(pevent, event)) { ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; goto event_add_failed; } #define PRINT_ARGS 0 if (PRINT_ARGS && event->print_fmt.args) print_args(event->print_fmt.args); return 0; event_add_failed: pevent_free_format(event); return ret; } /** * pevent_parse_format - parse the event format * @pevent: the handle to the pevent * @eventp: returned format * @buf: the buffer storing the event format string * @size: the size of @buf * @sys: the system the event belongs to * * This parses the event format and creates an event structure * to quickly parse raw data for a given event. * * These files currently come from: * * /sys/kernel/debug/tracing/events/.../.../format */ enum pevent_errno pevent_parse_format(struct pevent *pevent, struct event_format **eventp, const char *buf, unsigned long size, const char *sys) { return __pevent_parse_event(pevent, eventp, buf, size, sys); } /** * pevent_parse_event - parse the event format * @pevent: the handle to the pevent * @buf: the buffer storing the event format string * @size: the size of @buf * @sys: the system the event belongs to * * This parses the event format and creates an event structure * to quickly parse raw data for a given event. * * These files currently come from: * * /sys/kernel/debug/tracing/events/.../.../format */ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, unsigned long size, const char *sys) { struct event_format *event = NULL; return __pevent_parse_event(pevent, &event, buf, size, sys); } #undef _PE #define _PE(code, str) str static const char * const pevent_error_str[] = { PEVENT_ERRORS }; #undef _PE int pevent_strerror(struct pevent *pevent __maybe_unused, enum pevent_errno errnum, char *buf, size_t buflen) { int idx; const char *msg; if (errnum >= 0) { msg = strerror_r(errnum, buf, buflen); if (msg != buf) { size_t len = strlen(msg); memcpy(buf, msg, min(buflen - 1, len)); *(buf + min(buflen - 1, len)) = '\0'; } return 0; } if (errnum <= __PEVENT_ERRNO__START || errnum >= __PEVENT_ERRNO__END) return -1; idx = errnum - __PEVENT_ERRNO__START - 1; msg = pevent_error_str[idx]; snprintf(buf, buflen, "%s", msg); return 0; } int get_field_val(struct trace_seq *s, struct format_field *field, const char *name, struct pevent_record *record, unsigned long long *val, int err) { if (!field) { if (err) trace_seq_printf(s, "", name); return -1; } if (pevent_read_number_field(field, record->data, val)) { if (err) trace_seq_printf(s, " %s=INVALID", name); return -1; } return 0; } /** * pevent_get_field_raw - return the raw pointer into the data field * @s: The seq to print to on error * @event: the event that the field is for * @name: The name of the field * @record: The record with the field name. * @len: place to store the field length. * @err: print default error if failed. * * Returns a pointer into record->data of the field and places * the length of the field in @len. * * On failure, it returns NULL. */ void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event, const char *name, struct pevent_record *record, int *len, int err) { struct format_field *field; void *data = record->data; unsigned offset; int dummy; if (!event) return NULL; field = pevent_find_field(event, name); if (!field) { if (err) trace_seq_printf(s, "", name); return NULL; } /* Allow @len to be NULL */ if (!len) len = &dummy; offset = field->offset; if (field->flags & FIELD_IS_DYNAMIC) { offset = pevent_read_number(event->pevent, data + offset, field->size); *len = offset >> 16; offset &= 0xffff; } else *len = field->size; return data + offset; } /** * pevent_get_field_val - find a field and return its value * @s: The seq to print to on error * @event: the event that the field is for * @name: The name of the field * @record: The record with the field name. * @val: place to store the value of the field. * @err: print default error if failed. * * Returns 0 on success -1 on field not found. */ int pevent_get_field_val(struct trace_seq *s, struct event_format *event, const char *name, struct pevent_record *record, unsigned long long *val, int err) { struct format_field *field; if (!event) return -1; field = pevent_find_field(event, name); return get_field_val(s, field, name, record, val, err); } /** * pevent_get_common_field_val - find a common field and return its value * @s: The seq to print to on error * @event: the event that the field is for * @name: The name of the field * @record: The record with the field name. * @val: place to store the value of the field. * @err: print default error if failed. * * Returns 0 on success -1 on field not found. */ int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event, const char *name, struct pevent_record *record, unsigned long long *val, int err) { struct format_field *field; if (!event) return -1; field = pevent_find_common_field(event, name); return get_field_val(s, field, name, record, val, err); } /** * pevent_get_any_field_val - find a any field and return its value * @s: The seq to print to on error * @event: the event that the field is for * @name: The name of the field * @record: The record with the field name. * @val: place to store the value of the field. * @err: print default error if failed. * * Returns 0 on success -1 on field not found. */ int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event, const char *name, struct pevent_record *record, unsigned long long *val, int err) { struct format_field *field; if (!event) return -1; field = pevent_find_any_field(event, name); return get_field_val(s, field, name, record, val, err); } /** * pevent_print_num_field - print a field and a format * @s: The seq to print to * @fmt: The printf format to print the field with. * @event: the event that the field is for * @name: The name of the field * @record: The record with the field name. * @err: print default error if failed. * * Returns: 0 on success, -1 field not found, or 1 if buffer is full. */ int pevent_print_num_field(struct trace_seq *s, const char *fmt, struct event_format *event, const char *name, struct pevent_record *record, int err) { struct format_field *field = pevent_find_field(event, name); unsigned long long val; if (!field) goto failed; if (pevent_read_number_field(field, record->data, &val)) goto failed; return trace_seq_printf(s, fmt, val); failed: if (err) trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name); return -1; } /** * pevent_print_func_field - print a field and a format for function pointers * @s: The seq to print to * @fmt: The printf format to print the field with. * @event: the event that the field is for * @name: The name of the field * @record: The record with the field name. * @err: print default error if failed. * * Returns: 0 on success, -1 field not found, or 1 if buffer is full. */ int pevent_print_func_field(struct trace_seq *s, const char *fmt, struct event_format *event, const char *name, struct pevent_record *record, int err) { struct format_field *field = pevent_find_field(event, name); struct pevent *pevent = event->pevent; unsigned long long val; struct func_map *func; char tmp[128]; if (!field) goto failed; if (pevent_read_number_field(field, record->data, &val)) goto failed; func = find_func(pevent, val); if (func) snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val); else sprintf(tmp, "0x%08llx", val); return trace_seq_printf(s, fmt, tmp); failed: if (err) trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name); return -1; } static void free_func_handle(struct pevent_function_handler *func) { struct pevent_func_params *params; free(func->name); while (func->params) { params = func->params; func->params = params->next; free(params); } free(func); } /** * pevent_register_print_function - register a helper function * @pevent: the handle to the pevent * @func: the function to process the helper function * @ret_type: the return type of the helper function * @name: the name of the helper function * @parameters: A list of enum pevent_func_arg_type * * Some events may have helper functions in the print format arguments. * This allows a plugin to dynamically create a way to process one * of these functions. * * The @parameters is a variable list of pevent_func_arg_type enums that * must end with PEVENT_FUNC_ARG_VOID. */ int pevent_register_print_function(struct pevent *pevent, pevent_func_handler func, enum pevent_func_arg_type ret_type, char *name, ...) { struct pevent_function_handler *func_handle; struct pevent_func_params **next_param; struct pevent_func_params *param; enum pevent_func_arg_type type; va_list ap; int ret; func_handle = find_func_handler(pevent, name); if (func_handle) { /* * This is most like caused by the users own * plugins updating the function. This overrides the * system defaults. */ pr_stat("override of function helper '%s'", name); remove_func_handler(pevent, name); } func_handle = calloc(1, sizeof(*func_handle)); if (!func_handle) { do_warning("Failed to allocate function handler"); return PEVENT_ERRNO__MEM_ALLOC_FAILED; } func_handle->ret_type = ret_type; func_handle->name = strdup(name); func_handle->func = func; if (!func_handle->name) { do_warning("Failed to allocate function name"); free(func_handle); return PEVENT_ERRNO__MEM_ALLOC_FAILED; } next_param = &(func_handle->params); va_start(ap, name); for (;;) { type = va_arg(ap, enum pevent_func_arg_type); if (type == PEVENT_FUNC_ARG_VOID) break; if (type >= PEVENT_FUNC_ARG_MAX_TYPES) { do_warning("Invalid argument type %d", type); ret = PEVENT_ERRNO__INVALID_ARG_TYPE; goto out_free; } param = malloc(sizeof(*param)); if (!param) { do_warning("Failed to allocate function param"); ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; goto out_free; } param->type = type; param->next = NULL; *next_param = param; next_param = &(param->next); func_handle->nr_args++; } va_end(ap); func_handle->next = pevent->func_handlers; pevent->func_handlers = func_handle; return 0; out_free: va_end(ap); free_func_handle(func_handle); return ret; } /** * pevent_unregister_print_function - unregister a helper function * @pevent: the handle to the pevent * @func: the function to process the helper function * @name: the name of the helper function * * This function removes existing print handler for function @name. * * Returns 0 if the handler was removed successfully, -1 otherwise. */ int pevent_unregister_print_function(struct pevent *pevent, pevent_func_handler func, char *name) { struct pevent_function_handler *func_handle; func_handle = find_func_handler(pevent, name); if (func_handle && func_handle->func == func) { remove_func_handler(pevent, name); return 0; } return -1; } static struct event_format *pevent_search_event(struct pevent *pevent, int id, const char *sys_name, const char *event_name) { struct event_format *event; if (id >= 0) { /* search by id */ event = pevent_find_event(pevent, id); if (!event) return NULL; if (event_name && (strcmp(event_name, event->name) != 0)) return NULL; if (sys_name && (strcmp(sys_name, event->system) != 0)) return NULL; } else { event = pevent_find_event_by_name(pevent, sys_name, event_name); if (!event) return NULL; } return event; } /** * pevent_register_event_handler - register a way to parse an event * @pevent: the handle to the pevent * @id: the id of the event to register * @sys_name: the system name the event belongs to * @event_name: the name of the event * @func: the function to call to parse the event information * @context: the data to be passed to @func * * This function allows a developer to override the parsing of * a given event. If for some reason the default print format * is not sufficient, this function will register a function * for an event to be used to parse the data instead. * * If @id is >= 0, then it is used to find the event. * else @sys_name and @event_name are used. */ int pevent_register_event_handler(struct pevent *pevent, int id, const char *sys_name, const char *event_name, pevent_event_handler_func func, void *context) { struct event_format *event; struct event_handler *handle; event = pevent_search_event(pevent, id, sys_name, event_name); if (event == NULL) goto not_found; // pr_stat("overriding event (%d) %s:%s with new print handler", // event->id, event->system, event->name); event->handler = func; event->context = context; return 0; not_found: /* Save for later use. */ handle = calloc(1, sizeof(*handle)); if (!handle) { do_warning("Failed to allocate event handler"); return PEVENT_ERRNO__MEM_ALLOC_FAILED; } handle->id = id; if (event_name) handle->event_name = strdup(event_name); if (sys_name) handle->sys_name = strdup(sys_name); if ((event_name && !handle->event_name) || (sys_name && !handle->sys_name)) { do_warning("Failed to allocate event/sys name"); free((void *)handle->event_name); free((void *)handle->sys_name); free(handle); return PEVENT_ERRNO__MEM_ALLOC_FAILED; } handle->func = func; handle->next = pevent->handlers; pevent->handlers = handle; handle->context = context; return -1; } static int handle_matches(struct event_handler *handler, int id, const char *sys_name, const char *event_name, pevent_event_handler_func func, void *context) { if (id >= 0 && id != handler->id) return 0; if (event_name && (strcmp(event_name, handler->event_name) != 0)) return 0; if (sys_name && (strcmp(sys_name, handler->sys_name) != 0)) return 0; if (func != handler->func || context != handler->context) return 0; return 1; } /** * pevent_unregister_event_handler - unregister an existing event handler * @pevent: the handle to the pevent * @id: the id of the event to unregister * @sys_name: the system name the handler belongs to * @event_name: the name of the event handler * @func: the function to call to parse the event information * @context: the data to be passed to @func * * This function removes existing event handler (parser). * * If @id is >= 0, then it is used to find the event. * else @sys_name and @event_name are used. * * Returns 0 if handler was removed successfully, -1 if event was not found. */ int pevent_unregister_event_handler(struct pevent *pevent, int id, const char *sys_name, const char *event_name, pevent_event_handler_func func, void *context) { struct event_format *event; struct event_handler *handle; struct event_handler **next; event = pevent_search_event(pevent, id, sys_name, event_name); if (event == NULL) goto not_found; if (event->handler == func && event->context == context) { pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.", event->id, event->system, event->name); event->handler = NULL; event->context = NULL; return 0; } not_found: for (next = &pevent->handlers; *next; next = &(*next)->next) { handle = *next; if (handle_matches(handle, id, sys_name, event_name, func, context)) break; } if (!(*next)) return -1; *next = handle->next; free_handler(handle); return 0; } /** * pevent_alloc - create a pevent handle */ struct pevent *pevent_alloc(void) { struct pevent *pevent = calloc(1, sizeof(*pevent)); if (pevent) pevent->ref_count = 1; return pevent; } void pevent_ref(struct pevent *pevent) { pevent->ref_count++; } static void free_format_fields(struct format_field *field) { struct format_field *next; while (field) { next = field->next; free(field->type); free(field->name); free(field); field = next; } } static void free_formats(struct format *format) { free_format_fields(format->common_fields); free_format_fields(format->fields); } void pevent_free_format(struct event_format *event) { free(event->name); free(event->system); free_formats(&event->format); free(event->print_fmt.format); free_args(event->print_fmt.args); free(event); } /** * pevent_free - free a pevent handle * @pevent: the pevent handle to free */ void pevent_free(struct pevent *pevent) { struct cmdline_list *cmdlist, *cmdnext; struct func_list *funclist, *funcnext; struct printk_list *printklist, *printknext; struct pevent_function_handler *func_handler; struct event_handler *handle; int i; if (!pevent) return; cmdlist = pevent->cmdlist; funclist = pevent->funclist; printklist = pevent->printklist; pevent->ref_count--; if (pevent->ref_count) return; if (pevent->cmdlines) { for (i = 0; i < pevent->cmdline_count; i++) free(pevent->cmdlines[i].comm); free(pevent->cmdlines); } while (cmdlist) { cmdnext = cmdlist->next; free(cmdlist->comm); free(cmdlist); cmdlist = cmdnext; } if (pevent->func_map) { for (i = 0; i < (int)pevent->func_count; i++) { free(pevent->func_map[i].func); free(pevent->func_map[i].mod); } free(pevent->func_map); } while (funclist) { funcnext = funclist->next; free(funclist->func); free(funclist->mod); free(funclist); funclist = funcnext; } while (pevent->func_handlers) { func_handler = pevent->func_handlers; pevent->func_handlers = func_handler->next; free_func_handle(func_handler); } if (pevent->printk_map) { for (i = 0; i < (int)pevent->printk_count; i++) free(pevent->printk_map[i].printk); free(pevent->printk_map); } while (printklist) { printknext = printklist->next; free(printklist->printk); free(printklist); printklist = printknext; } for (i = 0; i < pevent->nr_events; i++) pevent_free_format(pevent->events[i]); while (pevent->handlers) { handle = pevent->handlers; pevent->handlers = handle->next; free_handler(handle); } free(pevent->events); free(pevent->sort_events); free(pevent); } void pevent_unref(struct pevent *pevent) { pevent_free(pevent); } uftrace-0.9.3/libtraceevent/event-parse.h000066400000000000000000000576231351236475300204330ustar00rootroot00000000000000/* * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License (not later!) * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #ifndef _PARSE_EVENTS_H #define _PARSE_EVENTS_H #include #include #include #include #ifndef __maybe_unused #define __maybe_unused __attribute__((unused)) #endif /* ----------------------- trace_seq ----------------------- */ #ifndef TRACE_SEQ_BUF_SIZE #define TRACE_SEQ_BUF_SIZE 4096 #endif #ifndef DEBUG_RECORD #define DEBUG_RECORD 0 #endif struct pevent_record { unsigned long long ts; unsigned long long offset; long long missed_events; /* buffer dropped events before */ int record_size; /* size of binary record */ int size; /* size of data */ void *data; int cpu; int ref_count; int locked; /* Do not free, even if ref_count is zero */ void *priv; #if DEBUG_RECORD struct pevent_record *prev; struct pevent_record *next; long alloc_addr; #endif }; enum trace_seq_fail { TRACE_SEQ__GOOD, TRACE_SEQ__BUFFER_POISONED, TRACE_SEQ__MEM_ALLOC_FAILED, }; /* * Trace sequences are used to allow a function to call several other functions * to create a string of data to use (up to a max of PAGE_SIZE). */ struct trace_seq { char *buffer; unsigned int buffer_size; unsigned int len; unsigned int readpos; enum trace_seq_fail state; }; void trace_seq_init(struct trace_seq *s); void trace_seq_reset(struct trace_seq *s); void trace_seq_destroy(struct trace_seq *s); extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); extern int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) __attribute__ ((format (printf, 2, 0))); extern int trace_seq_puts(struct trace_seq *s, const char *str); extern int trace_seq_putc(struct trace_seq *s, unsigned char c); extern void trace_seq_terminate(struct trace_seq *s); extern int trace_seq_do_printf(struct trace_seq *s); /* ----------------------- pevent ----------------------- */ struct pevent; struct event_format; typedef int (*pevent_event_handler_func)(struct trace_seq *s, struct pevent_record *record, struct event_format *event, void *context); typedef int (*pevent_plugin_load_func)(struct pevent *pevent); typedef int (*pevent_plugin_unload_func)(struct pevent *pevent); struct pevent_plugin_option { struct pevent_plugin_option *next; void *handle; char *file; char *name; char *plugin_alias; char *description; char *value; void *priv; int set; }; /* * Plugin hooks that can be called: * * PEVENT_PLUGIN_LOADER: (required) * The function name to initialized the plugin. * * int PEVENT_PLUGIN_LOADER(struct pevent *pevent) * * PEVENT_PLUGIN_UNLOADER: (optional) * The function called just before unloading * * int PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) * * PEVENT_PLUGIN_OPTIONS: (optional) * Plugin options that can be set before loading * * struct pevent_plugin_option PEVENT_PLUGIN_OPTIONS[] = { * { * .name = "option-name", * .plugin_alias = "overide-file-name", (optional) * .description = "description of option to show users", * }, * { * .name = NULL, * }, * }; * * Array must end with .name = NULL; * * * .plugin_alias is used to give a shorter name to access * the vairable. Useful if a plugin handles more than one event. * * PEVENT_PLUGIN_ALIAS: (optional) * The name to use for finding options (uses filename if not defined) */ #define PEVENT_PLUGIN_LOADER pevent_plugin_loader #define PEVENT_PLUGIN_UNLOADER pevent_plugin_unloader #define PEVENT_PLUGIN_OPTIONS pevent_plugin_options #define PEVENT_PLUGIN_ALIAS pevent_plugin_alias #define _MAKE_STR(x) #x #define MAKE_STR(x) _MAKE_STR(x) #define PEVENT_PLUGIN_LOADER_NAME MAKE_STR(PEVENT_PLUGIN_LOADER) #define PEVENT_PLUGIN_UNLOADER_NAME MAKE_STR(PEVENT_PLUGIN_UNLOADER) #define PEVENT_PLUGIN_OPTIONS_NAME MAKE_STR(PEVENT_PLUGIN_OPTIONS) #define PEVENT_PLUGIN_ALIAS_NAME MAKE_STR(PEVENT_PLUGIN_ALIAS) #define NSECS_PER_SEC 1000000000ULL #define NSECS_PER_USEC 1000ULL enum format_flags { FIELD_IS_ARRAY = 1, FIELD_IS_POINTER = 2, FIELD_IS_SIGNED = 4, FIELD_IS_STRING = 8, FIELD_IS_DYNAMIC = 16, FIELD_IS_LONG = 32, FIELD_IS_FLAG = 64, FIELD_IS_SYMBOLIC = 128, }; struct format_field { struct format_field *next; struct event_format *event; char *type; char *name; int offset; int size; unsigned int arraylen; unsigned int elementsize; unsigned long flags; }; struct format { int nr_common; int nr_fields; struct format_field *common_fields; struct format_field *fields; }; struct print_arg_atom { char *atom; }; struct print_arg_string { char *string; int offset; }; struct print_arg_bitmask { char *bitmask; int offset; }; struct print_arg_field { char *name; struct format_field *field; }; struct print_flag_sym { struct print_flag_sym *next; char *value; char *str; }; struct print_arg_typecast { char *type; struct print_arg *item; }; struct print_arg_flags { struct print_arg *field; char *delim; struct print_flag_sym *flags; }; struct print_arg_symbol { struct print_arg *field; struct print_flag_sym *symbols; }; struct print_arg_hex { struct print_arg *field; struct print_arg *size; }; struct print_arg_dynarray { struct format_field *field; struct print_arg *index; }; struct print_arg; struct print_arg_op { char *op; int prio; struct print_arg *left; struct print_arg *right; }; struct pevent_function_handler; struct print_arg_func { struct pevent_function_handler *func; struct print_arg *args; }; enum print_arg_type { PRINT_NULL, PRINT_ATOM, PRINT_FIELD, PRINT_FLAGS, PRINT_SYMBOL, PRINT_HEX, PRINT_TYPE, PRINT_STRING, PRINT_BSTRING, PRINT_DYNAMIC_ARRAY, PRINT_OP, PRINT_FUNC, PRINT_BITMASK, }; struct print_arg { struct print_arg *next; enum print_arg_type type; union { struct print_arg_atom atom; struct print_arg_field field; struct print_arg_typecast typecast; struct print_arg_flags flags; struct print_arg_symbol symbol; struct print_arg_hex hex; struct print_arg_func func; struct print_arg_string string; struct print_arg_bitmask bitmask; struct print_arg_op op; struct print_arg_dynarray dynarray; }; }; struct print_fmt { char *format; struct print_arg *args; }; struct event_format { struct pevent *pevent; char *name; int id; int flags; struct format format; struct print_fmt print_fmt; char *system; pevent_event_handler_func handler; void *context; }; enum { EVENT_FL_ISFTRACE = 0x01, EVENT_FL_ISPRINT = 0x02, EVENT_FL_ISBPRINT = 0x04, EVENT_FL_ISFUNCENT = 0x10, EVENT_FL_ISFUNCRET = 0x20, EVENT_FL_NOHANDLE = 0x40, EVENT_FL_PRINTRAW = 0x80, EVENT_FL_FAILED = 0x80000000 }; enum event_sort_type { EVENT_SORT_ID, EVENT_SORT_NAME, EVENT_SORT_SYSTEM, }; enum event_type { EVENT_ERROR, EVENT_NONE, EVENT_SPACE, EVENT_NEWLINE, EVENT_OP, EVENT_DELIM, EVENT_ITEM, EVENT_DQUOTE, EVENT_SQUOTE, }; typedef unsigned long long (*pevent_func_handler)(struct trace_seq *s, unsigned long long *args); enum pevent_func_arg_type { PEVENT_FUNC_ARG_VOID, PEVENT_FUNC_ARG_INT, PEVENT_FUNC_ARG_LONG, PEVENT_FUNC_ARG_STRING, PEVENT_FUNC_ARG_PTR, PEVENT_FUNC_ARG_MAX_TYPES }; enum pevent_flag { PEVENT_NSEC_OUTPUT = 1, /* output in NSECS */ PEVENT_DISABLE_SYS_PLUGINS = 1 << 1, PEVENT_DISABLE_PLUGINS = 1 << 2, }; #define PEVENT_ERRORS \ _PE(MEM_ALLOC_FAILED, "failed to allocate memory"), \ _PE(PARSE_EVENT_FAILED, "failed to parse event"), \ _PE(READ_ID_FAILED, "failed to read event id"), \ _PE(READ_FORMAT_FAILED, "failed to read event format"), \ _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \ _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\ _PE(INVALID_ARG_TYPE, "invalid argument type"), \ _PE(INVALID_EXP_TYPE, "invalid expression type"), \ _PE(INVALID_OP_TYPE, "invalid operator type"), \ _PE(INVALID_EVENT_NAME, "invalid event name"), \ _PE(EVENT_NOT_FOUND, "no event found"), \ _PE(SYNTAX_ERROR, "syntax error"), \ _PE(ILLEGAL_RVALUE, "illegal rvalue"), \ _PE(ILLEGAL_LVALUE, "illegal lvalue for string comparison"), \ _PE(INVALID_REGEX, "regex did not compute"), \ _PE(ILLEGAL_STRING_CMP, "illegal comparison for string"), \ _PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer"), \ _PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \ _PE(REPARENT_FAILED, "failed to reparent filter OP"), \ _PE(BAD_FILTER_ARG, "bad arg in filter tree"), \ _PE(UNEXPECTED_TYPE, "unexpected type (not a value)"), \ _PE(ILLEGAL_TOKEN, "illegal token"), \ _PE(INVALID_PAREN, "open parenthesis cannot come here"), \ _PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \ _PE(UNKNOWN_TOKEN, "unknown token"), \ _PE(FILTER_NOT_FOUND, "no filter found"), \ _PE(NOT_A_NUMBER, "must have number field"), \ _PE(NO_FILTER, "no filters exists"), \ _PE(FILTER_MISS, "record does not match to filter") #undef _PE #define _PE(__code, __str) PEVENT_ERRNO__ ## __code enum pevent_errno { PEVENT_ERRNO__SUCCESS = 0, PEVENT_ERRNO__FILTER_MATCH = PEVENT_ERRNO__SUCCESS, /* * Choose an arbitrary negative big number not to clash with standard * errno since SUS requires the errno has distinct positive values. * See 'Issue 6' in the link below. * * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html */ __PEVENT_ERRNO__START = -100000, PEVENT_ERRORS, __PEVENT_ERRNO__END, }; #undef _PE struct plugin_list; #define INVALID_PLUGIN_LIST_OPTION ((char **)((unsigned long)-1)) struct plugin_list *traceevent_load_plugins(struct pevent *pevent); void traceevent_unload_plugins(struct plugin_list *plugin_list, struct pevent *pevent); char **traceevent_plugin_list_options(void); void traceevent_plugin_free_options_list(char **list); int traceevent_plugin_add_options(const char *name, struct pevent_plugin_option *options); void traceevent_plugin_remove_options(struct pevent_plugin_option *options); void traceevent_print_plugins(struct trace_seq *s, const char *prefix, const char *suffix, const struct plugin_list *list); struct cmdline; struct cmdline_list; struct func_map; struct func_list; struct event_handler; struct pevent { int ref_count; int header_page_ts_offset; int header_page_ts_size; int header_page_size_offset; int header_page_size_size; int header_page_data_offset; int header_page_data_size; int header_page_overwrite; int file_bigendian; int host_bigendian; int latency_format; int old_format; int cpus; int long_size; int page_size; struct cmdline *cmdlines; struct cmdline_list *cmdlist; int cmdline_count; struct func_map *func_map; struct func_list *funclist; unsigned int func_count; struct printk_map *printk_map; struct printk_list *printklist; unsigned int printk_count; struct event_format **events; int nr_events; struct event_format **sort_events; enum event_sort_type last_type; int type_offset; int type_size; int pid_offset; int pid_size; int pc_offset; int pc_size; int flags_offset; int flags_size; int ld_offset; int ld_size; int print_raw; int test_filters; int flags; struct format_field *bprint_ip_field; struct format_field *bprint_fmt_field; struct format_field *bprint_buf_field; struct event_handler *handlers; struct pevent_function_handler *func_handlers; /* cache */ struct event_format *last_event; char *trace_clock; }; static inline void pevent_set_flag(struct pevent *pevent, int flag) { pevent->flags |= flag; } static inline unsigned short __data2host2(struct pevent *pevent, unsigned short data) { unsigned short swap; if (pevent->host_bigendian == pevent->file_bigendian) return data; swap = ((data & 0xffULL) << 8) | ((data & (0xffULL << 8)) >> 8); return swap; } static inline unsigned int __data2host4(struct pevent *pevent, unsigned int data) { unsigned int swap; if (pevent->host_bigendian == pevent->file_bigendian) return data; swap = ((data & 0xffULL) << 24) | ((data & (0xffULL << 8)) << 8) | ((data & (0xffULL << 16)) >> 8) | ((data & (0xffULL << 24)) >> 24); return swap; } static inline unsigned long long __data2host8(struct pevent *pevent, unsigned long long data) { unsigned long long swap; if (pevent->host_bigendian == pevent->file_bigendian) return data; swap = ((data & 0xffULL) << 56) | ((data & (0xffULL << 8)) << 40) | ((data & (0xffULL << 16)) << 24) | ((data & (0xffULL << 24)) << 8) | ((data & (0xffULL << 32)) >> 8) | ((data & (0xffULL << 40)) >> 24) | ((data & (0xffULL << 48)) >> 40) | ((data & (0xffULL << 56)) >> 56); return swap; } #define data2host2(pevent, ptr) __data2host2(pevent, *(unsigned short *)(ptr)) #define data2host4(pevent, ptr) __data2host4(pevent, *(unsigned int *)(ptr)) #define data2host8(pevent, ptr) \ ({ \ unsigned long long __val; \ \ memcpy(&__val, (ptr), sizeof(unsigned long long)); \ __data2host8(pevent, __val); \ }) static inline int traceevent_host_bigendian(void) { unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 }; unsigned int val; memcpy(&val, str, 4); return val == 0x01020304; } /* taken from kernel/trace/trace.h */ enum trace_flag_type { TRACE_FLAG_IRQS_OFF = 0x01, TRACE_FLAG_IRQS_NOSUPPORT = 0x02, TRACE_FLAG_NEED_RESCHED = 0x04, TRACE_FLAG_HARDIRQ = 0x08, TRACE_FLAG_SOFTIRQ = 0x10, }; int pevent_register_comm(struct pevent *pevent, const char *comm, int pid); void pevent_register_trace_clock(struct pevent *pevent, char *trace_clock); int pevent_register_function(struct pevent *pevent, char *name, unsigned long long addr, char *mod); int pevent_register_print_string(struct pevent *pevent, const char *fmt, unsigned long long addr); int pevent_pid_is_registered(struct pevent *pevent, int pid); void pevent_print_event(struct pevent *pevent, struct trace_seq *s, struct pevent_record *record, bool use_trace_clock); int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size, int long_size); enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, unsigned long size, const char *sys); enum pevent_errno pevent_parse_format(struct pevent *pevent, struct event_format **eventp, const char *buf, unsigned long size, const char *sys); void pevent_free_format(struct event_format *event); void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event, const char *name, struct pevent_record *record, int *len, int err); int pevent_get_field_val(struct trace_seq *s, struct event_format *event, const char *name, struct pevent_record *record, unsigned long long *val, int err); int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event, const char *name, struct pevent_record *record, unsigned long long *val, int err); int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event, const char *name, struct pevent_record *record, unsigned long long *val, int err); int pevent_print_num_field(struct trace_seq *s, const char *fmt, struct event_format *event, const char *name, struct pevent_record *record, int err); int pevent_print_func_field(struct trace_seq *s, const char *fmt, struct event_format *event, const char *name, struct pevent_record *record, int err); int pevent_register_event_handler(struct pevent *pevent, int id, const char *sys_name, const char *event_name, pevent_event_handler_func func, void *context); int pevent_unregister_event_handler(struct pevent *pevent, int id, const char *sys_name, const char *event_name, pevent_event_handler_func func, void *context); int pevent_register_print_function(struct pevent *pevent, pevent_func_handler func, enum pevent_func_arg_type ret_type, char *name, ...); int pevent_unregister_print_function(struct pevent *pevent, pevent_func_handler func, char *name); struct format_field *pevent_find_common_field(struct event_format *event, const char *name); struct format_field *pevent_find_field(struct event_format *event, const char *name); struct format_field *pevent_find_any_field(struct event_format *event, const char *name); const char *pevent_find_function(struct pevent *pevent, unsigned long long addr); unsigned long long pevent_find_function_address(struct pevent *pevent, unsigned long long addr); unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size); int pevent_read_number_field(struct format_field *field, const void *data, unsigned long long *value); struct event_format *pevent_find_event(struct pevent *pevent, int id); struct event_format * pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name); void pevent_data_lat_fmt(struct pevent *pevent, struct trace_seq *s, struct pevent_record *record); int pevent_data_type(struct pevent *pevent, struct pevent_record *rec); struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type); int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec); const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid); void pevent_event_info(struct trace_seq *s, struct event_format *event, struct pevent_record *record); int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, char *buf, size_t buflen); struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type); struct format_field **pevent_event_common_fields(struct event_format *event); struct format_field **pevent_event_fields(struct event_format *event); static inline int pevent_get_cpus(struct pevent *pevent) { return pevent->cpus; } static inline void pevent_set_cpus(struct pevent *pevent, int cpus) { pevent->cpus = cpus; } static inline int pevent_get_long_size(struct pevent *pevent) { return pevent->long_size; } static inline void pevent_set_long_size(struct pevent *pevent, int long_size) { pevent->long_size = long_size; } static inline int pevent_get_page_size(struct pevent *pevent) { return pevent->page_size; } static inline void pevent_set_page_size(struct pevent *pevent, int _page_size) { pevent->page_size = _page_size; } static inline int pevent_is_file_bigendian(struct pevent *pevent) { return pevent->file_bigendian; } static inline void pevent_set_file_bigendian(struct pevent *pevent, int endian) { pevent->file_bigendian = endian; } static inline int pevent_is_host_bigendian(struct pevent *pevent) { return pevent->host_bigendian; } static inline void pevent_set_host_bigendian(struct pevent *pevent, int endian) { pevent->host_bigendian = endian; } static inline int pevent_is_latency_format(struct pevent *pevent) { return pevent->latency_format; } static inline void pevent_set_latency_format(struct pevent *pevent, int lat) { pevent->latency_format = lat; } struct pevent *pevent_alloc(void); void pevent_free(struct pevent *pevent); void pevent_ref(struct pevent *pevent); void pevent_unref(struct pevent *pevent); /* access to the internal parser */ void pevent_buffer_init(const char *buf, unsigned long long size); enum event_type pevent_read_token(char **tok); void pevent_free_token(char *token); int pevent_peek_char(void); const char *pevent_get_input_buf(void); unsigned long long pevent_get_input_buf_ptr(void); /* for debugging */ void pevent_print_funcs(struct pevent *pevent); void pevent_print_printk(struct pevent *pevent); /* ----------------------- filtering ----------------------- */ enum filter_boolean_type { FILTER_FALSE, FILTER_TRUE, }; enum filter_op_type { FILTER_OP_AND = 1, FILTER_OP_OR, FILTER_OP_NOT, }; enum filter_cmp_type { FILTER_CMP_NONE, FILTER_CMP_EQ, FILTER_CMP_NE, FILTER_CMP_GT, FILTER_CMP_LT, FILTER_CMP_GE, FILTER_CMP_LE, FILTER_CMP_MATCH, FILTER_CMP_NOT_MATCH, FILTER_CMP_REGEX, FILTER_CMP_NOT_REGEX, }; enum filter_exp_type { FILTER_EXP_NONE, FILTER_EXP_ADD, FILTER_EXP_SUB, FILTER_EXP_MUL, FILTER_EXP_DIV, FILTER_EXP_MOD, FILTER_EXP_RSHIFT, FILTER_EXP_LSHIFT, FILTER_EXP_AND, FILTER_EXP_OR, FILTER_EXP_XOR, FILTER_EXP_NOT, }; enum filter_arg_type { FILTER_ARG_NONE, FILTER_ARG_BOOLEAN, FILTER_ARG_VALUE, FILTER_ARG_FIELD, FILTER_ARG_EXP, FILTER_ARG_OP, FILTER_ARG_NUM, FILTER_ARG_STR, }; enum filter_value_type { FILTER_NUMBER, FILTER_STRING, FILTER_CHAR }; struct fliter_arg; struct filter_arg_boolean { enum filter_boolean_type value; }; struct filter_arg_field { struct format_field *field; }; struct filter_arg_value { enum filter_value_type type; union { char *str; unsigned long long val; }; }; struct filter_arg_op { enum filter_op_type type; struct filter_arg *left; struct filter_arg *right; }; struct filter_arg_exp { enum filter_exp_type type; struct filter_arg *left; struct filter_arg *right; }; struct filter_arg_num { enum filter_cmp_type type; struct filter_arg *left; struct filter_arg *right; }; struct filter_arg_str { enum filter_cmp_type type; struct format_field *field; char *val; char *buffer; regex_t reg; }; struct filter_arg { enum filter_arg_type type; union { struct filter_arg_boolean boolean; struct filter_arg_field field; struct filter_arg_value value; struct filter_arg_op op; struct filter_arg_exp exp; struct filter_arg_num num; struct filter_arg_str str; }; }; struct filter_type { int event_id; struct event_format *event; struct filter_arg *filter; }; #define PEVENT_FILTER_ERROR_BUFSZ 1024 struct event_filter { struct pevent *pevent; int filters; struct filter_type *event_filters; char error_buffer[PEVENT_FILTER_ERROR_BUFSZ]; }; struct event_filter *pevent_filter_alloc(struct pevent *pevent); /* for backward compatibility */ #define FILTER_NONE PEVENT_ERRNO__NO_FILTER #define FILTER_NOEXIST PEVENT_ERRNO__FILTER_NOT_FOUND #define FILTER_MISS PEVENT_ERRNO__FILTER_MISS #define FILTER_MATCH PEVENT_ERRNO__FILTER_MATCH enum filter_trivial_type { FILTER_TRIVIAL_FALSE, FILTER_TRIVIAL_TRUE, FILTER_TRIVIAL_BOTH, }; enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, const char *filter_str); enum pevent_errno pevent_filter_match(struct event_filter *filter, struct pevent_record *record); int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err, char *buf, size_t buflen); int pevent_event_filtered(struct event_filter *filter, int event_id); void pevent_filter_reset(struct event_filter *filter); int pevent_filter_clear_trivial(struct event_filter *filter, enum filter_trivial_type type); void pevent_filter_free(struct event_filter *filter); char *pevent_filter_make_string(struct event_filter *filter, int event_id); int pevent_filter_remove_event(struct event_filter *filter, int event_id); int pevent_filter_event_has_trivial(struct event_filter *filter, int event_id, enum filter_trivial_type type); int pevent_filter_copy(struct event_filter *dest, struct event_filter *source); int pevent_update_trivial(struct event_filter *dest, struct event_filter *source, enum filter_trivial_type type); int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2); #endif /* _PARSE_EVENTS_H */ uftrace-0.9.3/libtraceevent/event-plugin.c000066400000000000000000000222521351236475300206000ustar00rootroot00000000000000/* * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License (not later!) * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include #include #include #include #include #include #include #include #include "event-parse.h" #include "event-utils.h" #define LOCAL_PLUGIN_DIR ".traceevent/plugins" static struct registered_plugin_options { struct registered_plugin_options *next; struct pevent_plugin_option *options; } *registered_options; static struct trace_plugin_options { struct trace_plugin_options *next; char *plugin; char *option; char *value; } *trace_plugin_options; struct plugin_list { struct plugin_list *next; char *name; void *handle; }; /** * traceevent_plugin_list_options - get list of plugin options * * Returns an array of char strings that list the currently registered * plugin options in the format of :